Skip to content

Instantly share code, notes, and snippets.

@rfc-2549
Last active October 31, 2022 08:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rfc-2549/f0fc519ff87fb957952a0de3975cefa5 to your computer and use it in GitHub Desktop.
Save rfc-2549/f0fc519ff87fb957952a0de3975cefa5 to your computer and use it in GitHub Desktop.
Simple URL fetcher in C using libcurl, can be used as a replacement for curl, if you only use it to download files.
/* compile with cc `pkg-config --cflags --libs libcurl fetch.c -o fetch` */
/* by http://suragu.net, licensed under the public domain. */
#include <stdio.h>
#include <getopt.h>
#include <curl/curl.h>
#include <stdbool.h>
#include <errno.h>
#include <string.h>
struct __options
{
bool verbose;
bool quiet;
char *output;
};
struct __options options;
void
init_options(struct __options *options)
{
options->output = NULL;
options->quiet = 1;
options->verbose = 0;
return;
}
int
download_url(char *url, char *dest_file)
{
CURL *handle = curl_easy_init();
if(handle == NULL) {
fprintf(stderr, "Error creating CURL handle\n");
}
curl_easy_setopt(handle, CURLOPT_URL, url);
if(!strcmp("-", dest_file)) {
curl_easy_setopt(handle, CURLOPT_WRITEDATA, stdout);
} else {
FILE *fp = fopen(dest_file, "w+");
if(fp == NULL) {
fprintf(stderr, "Error opening file: %s\n", strerror(errno));
return -1;
}
curl_easy_setopt(handle, CURLOPT_WRITEDATA, fp);
}
if(options.verbose) {
printf("Fetching URL: %s\n",url);
}
int res = curl_easy_perform(handle);
if(res != CURLE_OK) {
fprintf(
stderr, "Error during request: %s\n", curl_easy_strerror(res));
curl_easy_cleanup(handle);
return -1;
}
curl_easy_cleanup(handle);
if(options.verbose) {
printf("Done, saved to %s\n",dest_file);
}
return 0;
}
void
usage(void)
{
printf("USAGE: fetch [-q|-v] -o [FILE] URL\n");
return;
}
int
main(int argc, char **argv)
{
/* Init the options */
init_options(&options);
/* USAGE */
if(argc <= 1) {
usage();
return -1;
}
/* Process arguments */
int c;
options.output = "generic_file";
while((c = getopt(argc, argv, "vo:q")) != -1) {
switch(c) {
case 'v':
options.verbose = true;
options.quiet = false;
break;
case 'q':
options.quiet = true;
options.verbose = false;
break;
case 'o':
options.output = optarg;
break;
}
}
download_url(argv[argc - 1], options.output);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment