Home » Cloud Technologies » Download file to directory using curl – C program

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
#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;
}

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 
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

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

Create Your Own Cloud Download Site...
Create Your Own Cloud Download Site and Store Downloaded Files to Cloud Drive - Part 1

Leave a Comment