2 * Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
4 * Jansson is free software; you can redistribute it and/or modify
5 * it under the terms of the MIT license. See LICENSE for details.
12 #include <curl/curl.h>
14 #define BUFFER_SIZE (256 * 1024) /* 256 KB */
16 #define URL_FORMAT "https://api.github.com/repos/%s/%s/commits"
19 /* Return the offset of the first newline in text or the length of
20 text if there's no newline */
21 static int newline_offset(const char *text)
23 const char *newline = strchr(text, '\n');
27 return (int)(newline - text);
36 static size_t write_response(void *ptr, size_t size, size_t nmemb, void *stream)
38 struct write_result *result = (struct write_result *)stream;
40 if(result->pos + size * nmemb >= BUFFER_SIZE - 1)
42 fprintf(stderr, "error: too small buffer\n");
46 memcpy(result->data + result->pos, ptr, size * nmemb);
47 result->pos += size * nmemb;
52 static char *request(const char *url)
59 curl = curl_easy_init();
60 data = malloc(BUFFER_SIZE);
64 struct write_result write_result = {
69 curl_easy_setopt(curl, CURLOPT_URL, url);
70 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_response);
71 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &write_result);
73 status = curl_easy_perform(curl);
76 fprintf(stderr, "error: unable to request data from %s:\n", url);
77 fprintf(stderr, "%s\n", curl_easy_strerror(status));
81 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
84 fprintf(stderr, "error: server responded with code %ld\n", code);
88 curl_easy_cleanup(curl);
89 curl_global_cleanup();
91 /* zero-terminate the result */
92 data[write_result.pos] = '\0';
97 int main(int argc, char *argv[])
108 fprintf(stderr, "usage: %s USER REPOSITORY\n\n", argv[0]);
109 fprintf(stderr, "List commits at USER's REPOSITORY.\n\n");
113 snprintf(url, URL_SIZE, URL_FORMAT, argv[1], argv[2]);
119 root = json_loads(text, 0, &error);
124 fprintf(stderr, "error: on line %d: %s\n", error.line, error.text);
128 if(!json_is_array(root))
130 fprintf(stderr, "error: root is not an array\n");
134 for(i = 0; i < json_array_size(root); i++)
136 json_t *data, *sha, *commit, *message;
137 const char *message_text;
139 data = json_array_get(root, i);
140 if(!json_is_object(data))
142 fprintf(stderr, "error: commit data %d is not an object\n", i + 1);
146 sha = json_object_get(data, "sha");
147 if(!json_is_string(sha))
149 fprintf(stderr, "error: commit %d: sha is not a string\n", i + 1);
153 commit = json_object_get(data, "commit");
154 if(!json_is_object(commit))
156 fprintf(stderr, "error: commit %d: commit is not an object\n", i + 1);
160 message = json_object_get(commit, "message");
161 if(!json_is_string(message))
163 fprintf(stderr, "error: commit %d: message is not a string\n", i + 1);
167 message_text = json_string_value(message);
168 printf("%.8s %.*s\n",
169 json_string_value(sha),
170 newline_offset(message_text),