crypto/crypto.c
2023-06-22 14:48:26 +02:00

91 lines
2.1 KiB
C

#include <curl/curl.h>
#include <errno.h>
#include <error.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#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;
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++) {
if (i) {
printf(" ");
}
printf(FMT, WALLET[i].fmt, price);
err = get_next_symbol(NULL, &price);
}
printf("\n");
return 0;
}