int request(Config *c, Data *d) { int urllen; char *url; CURLcode r; curl_global_init(CURL_GLOBAL_DEFAULT); urllen = snprintf(NULL, 0, "https://api.forecast.io/forecast/%s/%f,%f", c->apikey, c->location.latitude, c->location.longitude) + 1; url = malloc(urllen); GUARD_MALLOC(url); snprintf(url, urllen, "https://api.forecast.io/forecast/%s/%f,%f", c->apikey, c->location.latitude, c->location.longitude); CURL *curl = curl_easy_init(); curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, request_curl_callback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, d); r = curl_easy_perform(curl); if(r != CURLE_OK) printf("cURL error: %s\n", curl_easy_strerror(r)); curl_easy_cleanup(curl); curl_global_cleanup(); free(url); return r == CURLE_OK ? 0 : -1; };
void compress_data(Data *d) { int slen = d->datalen; int olen = LZ4_COMPRESSBOUND(slen); char cbuf[olen]; #if LZ4_VERSION_MINOR >= 7 int ocnt = LZ4_compress_default((const char*)d->data, cbuf, slen, olen); #else /* In this API version, $cbuf is required to be large enough to handle * up to LZ4_COMPRESSBOUND($slen) bytes. Since we already allocate * this large of a buffer anyway, we just drop $olen. * * This is required for building against the liblz4 version in Debian * Jessie. */ int ocnt = LZ4_compress((const char*)d->data, cbuf, slen); #endif if(ocnt == 0) /* should never happen */ LERROR(EXIT_FAILURE, 0, "LZ4_compress_default() failed"); free(d->data); d->data = malloc(ocnt); GUARD_MALLOC(d->data); d->datalen = (size_t)ocnt; memcpy(d->data, (const void*)cbuf, d->datalen); }
void decompress_data(Data *d) { int obuflen = 0; int ocnt = 0; int lz4tries = 3; /* abort */ char *obuf = NULL; do { obuflen += 0xFA00; if(obuf) free(obuf); obuf = malloc(obuflen); GUARD_MALLOC(obuf); } while((ocnt = LZ4_decompress_safe((const char*)d->data, obuf, d->datalen, obuflen)) < 0 && (lz4tries-- > 0)); free(d->data); d->datalen = ocnt; d->data = malloc(d->datalen); GUARD_MALLOC(d->data); memcpy(d->data, (const void*) obuf, d->datalen); free(obuf); }
size_t request_curl_callback(void *ptr, size_t size, size_t nmemb, void *data) { Data *d = (Data*) data; size_t ptrlen = size * nmemb; if(d->data == NULL) { d->data = malloc(ptrlen); GUARD_MALLOC(d->data); d->datalen = ptrlen; memcpy(d->data, ptr, ptrlen); } else { d->data = realloc(d->data, d->datalen + ptrlen); memcpy(&d->data[d->datalen], ptr, ptrlen); d->datalen += ptrlen; } return ptrlen; }
int load_cache(const Config *c, Data *d) { FILE *cf; long cflen; if(check_cache_file(c) != 0) return -1; if((cf = fopen(c->cache_file, "rb")) == NULL) { LERROR(0, errno, "fopen()"); return -1; } fseek(cf, 0, SEEK_END); cflen = ftell(cf); fseek(cf, 0, SEEK_SET); d->data = malloc(cflen + 1); GUARD_MALLOC(d->data); d->datalen = cflen; fread(d->data, cflen, 1, cf); fclose(cf); return 0; }
void copy_data(const Data* d1, Data *d2) { d2->data = malloc(d1->datalen); GUARD_MALLOC(d2->data); memcpy(d2->data, (const void*) d1->data, d1->datalen); d2->datalen = d1->datalen; }