Created
July 8, 2013 18:34
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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