#include #include #include #include #include #include #include #include "config.h" #define ARRLEN(a) (sizeof (a) / sizeof *(a)) #define BUF_SIZE 256 * ARRLEN(WALLET) // {"bitcoin":{"usd":69420.69}} static int get_next_symbol(char *buf, float *price) { static const char output[] = "\"%*[a-z]\":{\"" VS "\":%f}"; char *tmp = strtok(buf, ","); if (!tmp) { return 1; } return !sscanf(tmp, output, price); } static size_t write_callback(char *response, size_t s, size_t n, void *buf) { return snprintf(buf, MIN(s * n, BUF_SIZE), response); } static char *build_url(void) { const char base[] = "https://api.coingecko.com/api/v3/simple/price?ids=%s&vs_currencies=" VS; size_t ids_size = 0; char *url; char ids[BUF_SIZE] = {0}; for (size_t i = 0; WALLET[i].id; i++) { strcpy(ids + ids_size, WALLET[i].id); ids_size += strlen(WALLET[i].id); ids[ids_size++] = ','; } ids[ids_size - 1] = '\0'; url = malloc(sizeof base + ids_size * (sizeof *url)); if (!url) { return NULL; } sprintf(url, base, ids); return url; } static int perform_request(char *response) { char *url = build_url(); CURL *curl = curl_easy_init(); if (!url || !curl) { free(url); curl_easy_cleanup(curl); return 1; } curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, response); curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_perform(curl); curl_easy_cleanup(curl); free(url); return 0; } int main(void) { char response[BUF_SIZE]; int err = perform_request(response); float price, current, sum = 0; if (err) { error(1, errno, "cannot init curl"); } err = get_next_symbol(response + 1, &price); for (size_t i = 0; !err && WALLET[i].id; i++) { current = price * WALLET[i].value; printf(FMT " ", WALLET[i].fmt, current); sum += current; err = get_next_symbol(NULL, &price); } printf(FMT, "TOT", sum); return 0; }