Pobcurl/pobcurl.c


Home Back

#include <curl/curl.h>
#include <pthread.h>
#include <unistd.h>
#include <stdbool.h>
#include <string.h>

#include <sys/stat.h> //upload
#include <fcntl.h>

typedef struct {
    int id;
    char*  url;
    char*  dest;
    char*  upsrc;
    char* userPass;
    int port;     
    double dltotal;
    double dlnow;
    double percent;
    int percentInt;
    char errbuf[CURL_ERROR_SIZE];
    bool end ;
    long http_code ;
    int abort;
    double  total_time;
} pobInfo;


//Questa callback scrive il file scaricato
size_t writecallback(void *buffer, size_t size, size_t nmemb, void *stream){
 
    int written = fwrite(buffer, size, nmemb, (FILE *)stream);
       return written;
}

//Questa callback scrive il progresso sulla variabile "progress" 
int progressDownload(pobInfo *inf,
                     double t, /* dltotal */ 
                     double d, /* dlnow */ 
                     double ultotal,
                     double ulnow) 
{
 
    inf->dltotal=t;
    inf->dlnow=d;
    inf->percent= d*100/t;
    inf->percentInt=(int)inf->percent;
    
    return inf->abort;
 
}

void *pobCurlDownload(pobInfo* inf)
{
    CURL *curl;
    CURLcode res;
    
    
    inf->end=false;
    inf->http_code=0;
    inf->abort=0;

    curl = curl_easy_init();
    if(curl) {

        curl_easy_setopt(curl, CURLOPT_URL, inf->url);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writecallback);
        curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
        //curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progressDownload);
        curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, progressDownload);
        curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, inf);
        curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, inf->errbuf);
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
        
        
        
        FILE *f = fopen(inf->dest,"w");
        if (f == NULL) {
            curl_easy_cleanup(curl);
            inf->end=true;
        }

        curl_easy_setopt(curl,CURLOPT_WRITEDATA, f);
        res = curl_easy_perform(curl);
        if(res != CURLE_OK)
        {
                strcpy(inf->errbuf,curl_easy_strerror(res));
                
        }
        
        //Http code return
        curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &inf->http_code);
        if (inf->http_code == 200 && res != CURLE_ABORTED_BY_CALLBACK)
        {
                 //Succeeded
        }else{
                 //Failed
        }
        
        curl_easy_cleanup(curl);
        fclose(f);
        inf->end=true;
    }
      
    
}

void pobCurlCleanErr(pobInfo* inf )
{
    strcpy(inf->errbuf,"");
}

void pobCurlClean(pobInfo* inf)
{
    strcpy(inf->errbuf,"");
    inf->http_code=0;
    inf->abort=0;
}


int pobCurlStartDownload(pobInfo* inf)
{
    pobCurlDownload(inf);
    
}

int pobCurlStartDownloadThread(pobInfo* inf)
{
    pthread_t pobThread;
    int  res;

    res = pthread_create( &pobThread, NULL, (void *)pobCurlDownload,  inf);
    if(res)
    {
         fprintf(stderr,"Error - pthread_create() return code: %d\n",res);
         return -1;
    }
    
    return 0;
}


int upload_callback (pobInfo *inf, double dltotal, double dlnow,
double ultotal, double ulnow)
{
    inf->dltotal=ultotal;
    inf->dlnow=ulnow;
    inf->percent= ulnow*100/ultotal;
    inf->percentInt=(int)inf->percent;
    
    return inf->abort;
}


void *pobCurlUpload(pobInfo* inf)
{
    CURL *curl;
    CURLcode res;
    inf->end=false;
    inf->http_code=0;
    inf->abort=0;
    inf->total_time=0;
    
    
    
    struct stat file_info;
    
    FILE *fd;

    fd = fopen(inf->upsrc, "rb"); /* open file to upload */ 
    if(!fd)
    {
        
        return NULL; /* can't continue */ 
    }
    
    /* to get the file size */ 
    if(fstat(fileno(fd), &file_info) != 0)
    {
        return NULL; /* can't continue */ 
    }
    
    curl = curl_easy_init();
    if(curl) 
    {
        curl_easy_setopt(curl, CURLOPT_URL,     inf->url);

        curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
        
        curl_easy_setopt(curl, CURLOPT_PORT, inf->port);
        
        curl_easy_setopt(curl,CURLOPT_USERPWD,inf->userPass);
        
        curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
        curl_easy_setopt(curl,CURLOPT_XFERINFOFUNCTION,upload_callback);
        curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, inf);
        curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, inf->errbuf);

        curl_easy_setopt(curl, CURLOPT_READDATA, fd);

        curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size);

        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

        res = curl_easy_perform(curl);
        /* Check for errors */ 
        if(res != CURLE_OK) 
        {
          //fprintf(stderr, "curl_easy_perform() failed: %s\n",  curl_easy_strerror(res));
          strcpy(inf->errbuf,curl_easy_strerror(res));

        }else {
          curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &inf->total_time);


        }
        /* always cleanup */ 
        curl_easy_cleanup(curl);
    }
    fclose(fd);
    inf->end=true;
}


int pobCurlStartUpload(pobInfo* inf)
{
    pobCurlUpload(inf);
    
}

int pobCurlStartUploadThread(pobInfo* inf)
{
    pthread_t pobThread;
    int  res;

    res = pthread_create( &pobThread, NULL, (void *)pobCurlUpload,  inf);
    if(res)
    {
         fprintf(stderr,"Error - pthread_create() return code: %d\n",res);
         return -1;
    }
    
    return 0;
}

Powered by Code, a simple repository browser by Fabio Di Matteo