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:
M | geoloc/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", ®ion);
+ 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", ¤cy);
+ 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", ®ion);
- /* json_object_object_get_ex(parsed_json, "region_code",
- ®ion_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", ¤cy);
- // 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;
}