Download file to directory using curl – C program

Following C program download some file from remote location to the directory mentioned in program. As an example we are trying to download curl source code from https://curl.haxx.se/download/curl-7.69.1.tar.gz to /tmp directory as /tmp/curl-7.69.1.tar.gz

$ vim download_file_to_directory.c 
[bash] #include <stdio.h> #include <string.h> #include <errno.h> #include <stdlib.h> #include <unistd.h> #include <stdbool.h> #include <getopt.h> #include <fcntl.h> #include <sys/statvfs.h> #include <sys/mount.h> #include <openssl/md5.h> #include <curl/curl.h> struct fileptr { const char *filename; FILE *stream; }; static size_t file_fwrite(void *buffer, size_t size, size_t nmemb, void *stream) { struct fileptr *out=(struct fileptr *)stream; if(out && !out->stream) { /* open file for writing */ out->stream = fopen(out->filename, "wb"); if(!out->stream) return -1; /* failure, can’t open file to write */ } return fwrite(buffer, size, nmemb, out->stream); } int curl_download_file_to_directory(char *url, char *filename) { CURL *curl = NULL; CURLcode res; struct fileptr file; curl_global_init(CURL_GLOBAL_DEFAULT); curl = curl_easy_init(); if(curl) { printf("url is %s, filename:%s\n", url, filename); curl_easy_setopt(curl, CURLOPT_URL, url); file.filename = filename; file.stream = NULL; /* Define our callback to get called when there’s data to be written */ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, file_fwrite); /* Set a pointer to our struct to pass to the callback */ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &file); /* Switch on full protocol/debug output */ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); res = curl_easy_perform(curl); /* always cleanup */ curl_easy_cleanup(curl); if(CURLE_OK != res) { /* we failed */ fprintf(stderr, "curl told us %d\n", res); if(file.stream) fclose(file.stream); /* close the local file */ return -1; } } if(file.stream) fclose(file.stream); /* close the local file */ curl_global_cleanup(); return 0; } int main(int argc, char **argv) { curl_download_file_to_directory("https://curl.haxx.se/download/curl-7.69.1.tar.gz","/tmp/curl-7.69.1.tar.gz"); return 0; } [/bash]

This c program passes two arguments to function curl_download_file_to_directory,

  • Remote file to download – example https://curl.haxx.se/download/curl-7.69.1.tar.gz
  • Local File & directory where to save – example : /tmp/curl-7.69.1.tar.gz
$ gcc -o download_file_to_directory download_file_to_directory.c -lcurl 
 $ ./download_file_to_directory 
[bash] url is https://curl.haxx.se/download/curl-7.69.1.tar.gz, filename:/tmp/curl-7.69.1.tar.gz * Trying 151.101.2.49… * TCP_NODELAY set * Connected to curl.haxx.se (151.101.2.49) port 443 (#0) * found 133 certificates in /etc/ssl/certs/ca-certificates.crt * found 402 certificates in /etc/ssl/certs * ALPN, offering http/1.1 * SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256 * server certificate verification OK * server certificate status verification SKIPPED * common name: j2.shared.global.fastly.net (matched) * server certificate expiration date OK * server certificate activation date OK * certificate public key: RSA * certificate version: #3 * subject: C=US,ST=California,L=San Francisco,O=Fastly\, Inc.,CN=j2.shared.global.fastly.net * start date: Thu, 12 Mar 2020 19:08:12 GMT * expire date: Sun, 07 Mar 2021 17:48:32 GMT * issuer: C=BE,O=GlobalSign nv-sa,CN=GlobalSign CloudSSL CA – SHA256 – G3 * compression: NULL * ALPN, server accepted to use http/1.1 > GET /download/curl-7.69.1.tar.gz HTTP/1.1 Host: curl.haxx.se Accept: */* < HTTP/1.1 200 OK < Connection: keep-alive < Content-Length: 4131634 < Server: Apache < X-Frame-Options: SAMEORIGIN < Last-Modified: Wed, 11 Mar 2020 06:39:38 GMT < ETag: "3f0b32-5a08e8020433f" < Cache-Control: max-age=31536000 < Expires: Thu, 11 Mar 2021 06:42:23 GMT < X-Content-Type-Options: nosniff < Content-Security-Policy: default-src ‘self’ www.fastly-insights.com; style-src ‘unsafe-inline’ ‘self’ < Strict-Transport-Security: max-age=31536000; includeSubDomains; < Content-Type: application/x-gzip < Via: 1.1 varnish < Accept-Ranges: bytes < Date: Fri, 10 Apr 2020 17:00:45 GMT < Via: 1.1 varnish < Age: 2629102 < X-Served-By: cache-bma1630-BMA, cache-bom18223-BOM < X-Cache: HIT, HIT < X-Cache-Hits: 1, 1 < X-Timer: S1586538045.387868,VS0,VE8 < * Connection #0 to host curl.haxx.se left intact [/bash]

Once the program execution is completed, i.e. download from remote location to local file is done, we will the file got downloaded at /tmp as,

$ file /tmp/curl-7.69.1.tar.gz 
/tmp/curl-7.69.1.tar.gz: gzip compressed data, max compression, from Unix

Reference – https://curl.haxx.se/libcurl/c/ftpget.html

Leave a Comment