utils

small programs, scripts and utils
git clone https://git.e1e0.net/utils.git
Log | Files | Refs

commit 5ed335c62b6b4e992175853600c7c38279abcc5d
parent 4d5c07f297213ba08c70659584a275b97d757bbd
Author: Paco Esteban <paco@e1e0.net>
Date:   Thu,  6 Aug 2020 18:00:43 +0200

refactor as if there's no tomorrow

Diffstat:
Mgeoloc/geoloc.c | 217+++++++++++++++++++++++++++++++++++++------------------------------------------
1 file changed, 102 insertions(+), 115 deletions(-)

diff --git a/geoloc/geoloc.c b/geoloc/geoloc.c @@ -20,6 +20,11 @@ struct MemoryStruct { size_t size; }; +static size_t write_memory_callback(void *, size_t, size_t, void *); +void usage(void); +int make_api_call(char *); +int print_data(void *); + // Usage function void usage(void) @@ -31,7 +36,7 @@ usage(void) // libcurl callback to write contents to memory static size_t -WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) +write_memory_callback(void *contents, size_t size, size_t nmemb, void *userp) { size_t realsize = size * nmemb; struct MemoryStruct *mem = (struct MemoryStruct *)userp; @@ -52,45 +57,104 @@ WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) } int +make_api_call(char *url) { + CURL *curl_handle; + CURLcode res; + struct MemoryStruct *chunk = malloc(sizeof(struct MemoryStruct)); + + chunk->memory = malloc(1); /* will be grown as needed */ + chunk->size = 0; /* no data at this point */ + + curl_global_init(CURL_GLOBAL_ALL); + curl_handle = curl_easy_init(); + curl_easy_setopt(curl_handle, CURLOPT_URL, url); + curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, + write_memory_callback); /* send all data to this function */ + /* we pass our 'chunk' struct to the callback function */ + curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)chunk); + curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0"); + + res = curl_easy_perform(curl_handle); + + if(res != CURLE_OK) + return -1; + + /* + * Now, our chunk.memory points to a memory block that is + * chunk.size bytes big and contains the remote file. + * We'll now parse the json response and print the data. + */ + if (print_data(chunk->memory) == -1) + return -1; + + /* cleanup curl stuff */ + curl_easy_cleanup(curl_handle); + curl_global_cleanup(); + + free(chunk->memory); + free(chunk); + + return 0; +} + +int +print_data(void *json_data) { + struct json_object *parsed_json = NULL, *ip = NULL, *city = NULL, + *region = NULL, *country_name = NULL, + *continent_code = NULL, *postal = NULL, + *latitude = NULL, *longitude = NULL, + *timezone = NULL, *utc_offset = NULL, + *currency = NULL, *asn = NULL, *org = NULL; + + /* Parse json data */ + parsed_json = json_tokener_parse(json_data); + + json_object_object_get_ex(parsed_json, "ip", &ip); + json_object_object_get_ex(parsed_json, "city", &city); + json_object_object_get_ex(parsed_json, "region", &region); + json_object_object_get_ex(parsed_json, "country_name", &country_name); + json_object_object_get_ex(parsed_json, "continent_code", + &continent_code); + json_object_object_get_ex(parsed_json, "postal", &postal); + json_object_object_get_ex(parsed_json, "latitude", &latitude); + json_object_object_get_ex(parsed_json, "longitude", &longitude); + json_object_object_get_ex(parsed_json, "timezone", &timezone); + json_object_object_get_ex(parsed_json, "utc_offset", &utc_offset); + json_object_object_get_ex(parsed_json, "currency", &currency); + json_object_object_get_ex(parsed_json, "org", &org); + + /* and print the requested info */ + printf("Requested ip:\t%s\n", json_object_get_string(ip)); + printf("Location:\t%s - %s\n", json_object_get_string(postal), + json_object_get_string(city)); + printf("\t\t%s - %s (%s)\n", json_object_get_string(region), + json_object_get_string(country_name), + json_object_get_string(continent_code)); + printf("\t\t%s (%s)\n", json_object_get_string(timezone), + json_object_get_string(utc_offset)); + printf("\t\t%s\n", + json_object_get_string(currency)); + printf("Org:\t\t%s (%s)\n", json_object_get_string(org), + json_object_get_string(asn)); + printf("Coordinates:\t%f, %f\n", json_object_get_double(latitude), + json_object_get_double(longitude)); + printf( + "See on map:\t" + "https://www.openstreetmap.org/search?query=%f%%2C%f#map=12/%f/%f\n", + json_object_get_double(latitude), json_object_get_double(longitude), + json_object_get_double(latitude), json_object_get_double(longitude)); + return 0; +} + +int main(int argc, char *argv[]) { - int ch; - int f_help = 0; - int f_version = 0; - - int is_v4, is_v6; + int ch, f_help = 0, f_version = 0, is_v4 = 0, is_v6 = 0; void *inet_dst; // we do not actually use this. Only to check valid ip - CURL *curl_handle; - CURLcode res; - struct MemoryStruct chunk; char *url = NULL; - // we get back a json object in key/value pairs, nothing complex - struct json_object *parsed_json; - struct json_object *ip; - struct json_object *city; - struct json_object *region; - // struct json_object *region_code; - // struct json_object *country; - struct json_object *country_name; - struct json_object *continent_code; - // struct json_object *in_eu; - struct json_object *postal; - struct json_object *latitude; - struct json_object *longitude; - struct json_object *timezone; - struct json_object *utc_offset; - // struct json_object *country_calling_code; - struct json_object *currency; - // struct json_object *languages; - struct json_object *asn; - struct json_object *org; - - chunk.memory = malloc(1); /* will be grown as needed by the realloc above */ - chunk.size = 0; /* no data at this point */ - - while ((ch = getopt(argc, argv, "fv")) != -1) { + while ((ch = getopt(argc, argv, "v")) != -1) { switch (ch) { case 'v': f_version = 1; @@ -116,94 +180,17 @@ main(int argc, char *argv[]) // validate ip input is_v4 = inet_pton(AF_INET, argv[0], inet_dst); is_v6 = inet_pton(AF_INET6, argv[0], inet_dst); - if ((is_v4 != 1) && (is_v6 != 1)) { - fprintf(stderr, "Not a valid IP address\n"); - return 3; - } + if ((is_v4 != 1) && (is_v6 != 1)) + err(1, "invalid IP"); // if ip is ok, create the API url we'll call if (asprintf(&url, "%s/%s/%s", BASE_URL, argv[0], JSON_ENDPOINT) == -1) err(1, "url creation"); - curl_global_init(CURL_GLOBAL_ALL); - curl_handle = curl_easy_init(); - curl_easy_setopt(curl_handle, CURLOPT_URL, url); - curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, - WriteMemoryCallback); /* send all data to this function */ - /* we pass our 'chunk' struct to the callback function */ - curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk); - curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0"); - - res = curl_easy_perform(curl_handle); - - if(res != CURLE_OK) { - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(res)); - } - else { - /* - * Now, our chunk.memory points to a memory block that is - * chunk.size bytes big and contains the remote file. - * We'll now parse the json response. - */ - - parsed_json = json_tokener_parse(chunk.memory); - json_object_object_get_ex(parsed_json, "ip", &ip); - json_object_object_get_ex(parsed_json, "city", &city); - json_object_object_get_ex(parsed_json, "region", &region); - /* json_object_object_get_ex(parsed_json, "region_code", - &region_code); */ - // json_object_object_get_ex(parsed_json, "country", &country); - json_object_object_get_ex(parsed_json, "country_name", - &country_name); - json_object_object_get_ex(parsed_json, "continent_code", - &continent_code); - // json_object_object_get_ex(parsed_json, "in_eu", &in_eu); - json_object_object_get_ex(parsed_json, "postal", &postal); - json_object_object_get_ex(parsed_json, "latitude", &latitude); - json_object_object_get_ex(parsed_json, "longitude", &longitude); - json_object_object_get_ex(parsed_json, "timezone", &timezone); - json_object_object_get_ex(parsed_json, "utc_offset", - &utc_offset); - /* json_object_object_get_ex(parsed_json, "country_calling_code", - &country_calling_code); */ - json_object_object_get_ex(parsed_json, "currency", &currency); - // json_object_object_get_ex(parsed_json, "languages", &languages); - json_object_object_get_ex(parsed_json, "asn", &asn); - json_object_object_get_ex(parsed_json, "org", &org); - - // and print the requested info - printf("Requested ip:\t%s\n", json_object_get_string(ip)); - printf("Location:\t%s - %s\n", - json_object_get_string(postal), - json_object_get_string(city)); - printf("\t\t%s - %s (%s)\n", - json_object_get_string(region), - json_object_get_string(country_name), - json_object_get_string(continent_code)); - printf("\t\t%s (%s)\n", - json_object_get_string(timezone), - json_object_get_string(utc_offset)); - printf("\t\t%s\n", - json_object_get_string(currency)); - printf("Org:\t\t%s (%s)\n", json_object_get_string(org), - json_object_get_string(asn)); - printf("Coordinates:\t%f, %f\n", json_object_get_double(latitude), - json_object_get_double(longitude)); - printf( - "See on map:\thttps://www.openstreetmap.org/search?query=%f%%2C%f#map=12/%f/%f\n", - json_object_get_double(latitude), json_object_get_double(longitude), - json_object_get_double(latitude), json_object_get_double(longitude)); - } - - /* cleanup curl stuff */ - curl_easy_cleanup(curl_handle); + if (make_api_call(url) == -1) + err(1, "api call"); - free(chunk.memory); free(url); - /* we're done with libcurl, so clean it up */ - curl_global_cleanup(); - return 0; }