0

I'm using C/C++ in Linux Environment to practicing and trying to download file from the internet, then print percent downloaded while downloading file.

I determine 2 main steps for this problem.

  1. Get the file size before download.
  2. Get number of bytes downloaded.

I solved 2. by lib cURL, but stuck in 1: I tried cURL with CURLOPT_XFERINFOFUNCTION option but it doesn't work for file .deb. In addition, it print data in file that I can't control it. I don't know where was the mistake. And if we can't solve it by cURL please tell me what should I use instead for number 1.

here's what I've done:

#include <stdio.h>
#include <curl/curl.h>
 
#define STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES         6000


FILE *fp = fopen("file.txt", "w");

struct myprogress {
    curl_off_t lastruntime; /* type depends on version, see above */
    CURL *curl;
};
 
/* this is how the CURLOPT_XFERINFOFUNCTION callback works */
static int xferinfo(void *p,
                    curl_off_t dltotal, curl_off_t dlnow,
                    curl_off_t ultotal, curl_off_t ulnow)
{
    struct myprogress *myp = (struct myprogress *)p;
    CURL *curl = myp->curl;
    curl_off_t curtime = 0;
 
    curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME_T, &curtime);
 
  /* under certain circumstances it may be desirable for certain functionality
     to only run every N seconds, in order to do this the transaction time can
     be used */
    if((curtime - myp->lastruntime) >= MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL) {
        myp->lastruntime = curtime;
        fprintf(fp, "TOTAL TIME: %lu.%06lu\n",
                (unsigned long)(curtime / 1000000),
                (unsigned long)(curtime % 1000000));
    }
 
    fprintf(fp, "UP: %lu of %lu  DOWN: %lu of %lu\n",
            (unsigned long)ulnow, (unsigned long)ultotal,
            (unsigned long)dlnow, (unsigned long)dltotal);
 
    if(dlnow >= dltotal)
        return 1;
    return 0;
}
 
int main(void)
{
    CURL *curl;
    CURLcode res = CURLE_OK;
    struct myprogress prog;

    curl = curl_easy_init();
    if(curl) {
        prog.lastruntime = 0;
        prog.curl = curl;

        curl_easy_setopt(curl, CURLOPT_URL, "https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb");
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
        curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xferinfo);
        /* pass the struct pointer into the xferinfo function */
        curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &prog);

        // curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
        // curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
        
        res = curl_easy_perform(curl);

        if(res != CURLE_OK){
            printf("Fail\n");
            // fprintf(stderr, "%s\n", curl_easy_strerror(res));
        }
        /* always cleanup */
        curl_easy_cleanup(curl);
    }

    fclose(fp);
    return (int)res;
}

To run it: g++ -o runfile main.cpp -lcurl && ./runfile

0 Answers0