Skip to content

Instantly share code, notes, and snippets.

@tschoonj
Created July 8, 2013 18:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tschoonj/5951294 to your computer and use it in GitHub Desktop.
Save tschoonj/5951294 to your computer and use it in GitHub Desktop.
Some code I wrote to have my software package XMI-MSIM check on github for available updates, by looking if git tags were pushed to the repository and comparing the version numbers
#include <curl/curl.h>
#include <json-glib/json-glib.h>
#include <string.h>
#include <stdlib.h>
/*
*
* This code allows for the checking of available updates by parsing the JSON output obtained
* through requesting the tags from the GitHub repo of XMI-MSIM
*
*
* compile with gcc -o github-updater `pkg-config --cflags json-glib-1.0 libcurl` github-updater.c `pkg-config --libs json-glib-1.0 libcurl`
*
*
*/
#define XMIMSIM_GITHUB_TAGS_LOCATION "https://api.github.com/repos/tschoonj/xmimsim/git/refs/tags"
#define XMIMSIM_DOWNLOADS_LOCATION "http://lvserver.ugent.be/xmi-msim"
#define PACKAGE_VERSION "1.0"
enum {
XMIMSIM_UPDATES_ERROR,
XMIMSIM_UPDATES_AVAILABLE,
XMIMSIM_UPDATES_NONE
};
struct MemoryStruct {
char *memory;
size_t size;
};
static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) {
size_t realsize = size * nmemb;
struct MemoryStruct *mem = (struct MemoryStruct *)userp;
mem->memory = realloc(mem->memory, mem->size + realsize + 1);
memcpy(&(mem->memory[mem->size]), contents, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;
return realsize;
}
static void check_version_of_tag(JsonArray *array, guint index, JsonNode *node, char **max_version) {
JsonObject *object = json_node_get_object(node);
if (!json_object_has_member(object,"ref")) {
return;
}
const gchar *ref_string = json_object_get_string_member(object, "ref");
//discard old tag...
if (strncmp(ref_string,"refs/tags/XMI-MSIM-",strlen("refs/tags/XMI-MSIM-")) != 0)
return;
char *tag_version_str = strrchr(ref_string,'-')+1;
gdouble tag_version = g_ascii_strtod(tag_version_str,NULL);
if (tag_version > g_ascii_strtod(*max_version,NULL)) {
free(*max_version);
*max_version = strdup(tag_version_str);
}
return;
}
int check_for_updates(char **max_version_rv) {
GError *error = NULL;
JsonParser *parser;
char curlerrors[CURL_ERROR_SIZE];
CURL *curl;
CURLcode res;
struct MemoryStruct chunk;
chunk.memory = malloc(1);
chunk.size = 0;
fprintf(stdout,"checking for updates...\n");
curl = curl_easy_init();
if (!curl) {
fprintf(stderr,"Could not initialize cURL\n");
return XMIMSIM_UPDATES_ERROR;
}
curl_easy_setopt(curl, CURLOPT_URL,XMIMSIM_GITHUB_TAGS_LOCATION);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curlerrors);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 4L);
res = curl_easy_perform(curl);
if (res != 0) {
fprintf(stderr,"check_for_updates: %s\n",curlerrors);
return XMIMSIM_UPDATES_ERROR;
}
curl_easy_cleanup(curl);
parser = json_parser_new();
if (json_parser_load_from_data(parser, chunk.memory, -1,&error) == FALSE) {
if (error) {
fprintf(stderr,"check_for_updates: %s\n",error->message);
return XMIMSIM_UPDATES_ERROR;
}
}
JsonNode *rootNode = json_parser_get_root(parser);
if(json_node_get_node_type(rootNode) != JSON_NODE_ARRAY) {
fprintf(stderr,"check_for_updates: rootNode is not an Array\n");
return XMIMSIM_UPDATES_ERROR;
}
JsonArray *rootArray = json_node_get_array(rootNode);
char *max_version = g_strdup(PACKAGE_VERSION);
char *current_version = g_strdup(max_version);
json_array_foreach_element(rootArray, (JsonArrayForeach) check_version_of_tag, &max_version);
int rv;
if (g_ascii_strtod(max_version, NULL) > g_ascii_strtod(current_version, NULL))
rv = XMIMSIM_UPDATES_AVAILABLE;
else
rv = XMIMSIM_UPDATES_NONE;
*max_version_rv = strdup(g_strstrip(max_version));
g_object_unref(parser);
fprintf(stdout,"done checking for updates\n");
return rv;
}
int main (int argc, char *argv[]) {
char *max_version;
int check = check_for_updates(&max_version);
if (check == XMIMSIM_UPDATES_AVAILABLE) {
fprintf(stdout, "Update available: now write some code to download the damn update\n");
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment