Source Code File 05-04_ftpfile2.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>

#define BUFFER_SIZE 2048

struct data_chunk {
    char *buf;
    size_t size;
};

static size_t read_callback(
    void *ptr,
    size_t size,
    size_t nmemb,
    void *user_data)
{
    struct data_chunk *upload;
    size_t max;
    
    upload = (struct data_chunk *)user_data;
    max = size*nmemb;
    if(max<1)
        return(0);
    
    if(upload->size)
    {
        if(max > upload->size)
            max = upload->size;
        memcpy(ptr, upload->buf,max);
        upload->buf += max;
        upload->size -= max;

        return(max);
    }
    
    return(0);
}

int main()
{
    char address[] = "ftp://127.0.0.0/test.txt";
    char user_pass[] = "username:password";
    char filename[] = "test.txt";
    char in[BUFFER_SIZE];
    CURL *curl;
    CURLcode r;
    struct data_chunk ftp;
    FILE *fp;
    int c;

    /* read file */
    fp = fopen( filename, "r");
    if( fp==NULL)
    {
        fprintf(stderr,
            "Unable to read %s\n",
            filename);
        exit(1);
    }

    /* initialize buffer */
    ftp.buf = malloc(1);
    ftp.size = 0;
    if( ftp.buf==NULL )
    {
        fprintf(stderr, "Can't init buffer\n");
        /* close the file */
        fclose(fp);
        exit(1);
    }

    /* read data from the file
       into the buffer */
    while(1)
    {
        c=fread(in,sizeof(char),BUFFER_SIZE,fp);
        ftp.buf=realloc( ftp.buf, ftp.size+c+1);
        if( ftp.buf==NULL )
        {
            fprintf(stderr,"Mem resize error\n");
            exit(1);
        }
        memcpy( &ftp.buf[ftp.size], in, c );
        ftp.size += c;
        ftp.buf[ftp.size] = 0;
        if( c < BUFFER_SIZE)
        {
            if( feof(fp) )
                break;
            else
            {
                fprintf(stderr,"File read error\n");
                fclose(fp);
                exit(1);
            }
        }
    }
    fclose(fp);

    /* initialize curl */
    curl = curl_easy_init();
    
    printf("Preparing FTP...");
    /* set options for FPT upload */
    curl_easy_setopt(curl,
        CURLOPT_URL, address);
    curl_easy_setopt(curl,
        CURLOPT_FOLLOWLOCATION, 1L);
    curl_easy_setopt(curl,
        CURLOPT_USERPWD, user_pass);
    curl_easy_setopt(curl,
        CURLOPT_UPLOAD, 1L);
    curl_easy_setopt(curl,
        CURLOPT_READFUNCTION, read_callback);
    curl_easy_setopt(curl,
        CURLOPT_READDATA, &ftp);
    curl_easy_setopt(curl,
        CURLOPT_INFILESIZE_LARGE,
        (curl_off_t)ftp.size);
    
    /* request-send upload */
    r = curl_easy_perform(curl);
    if( r!=CURLE_OK )
    {
        fprintf(stderr,"curl upload failed: %s\n",
                curl_easy_strerror(r));
        exit(1);
    }

    /* cleanup */
    curl_easy_cleanup(curl);
    /* inform the user */
    puts("FTP upload complete");
    
    return(0);
}

Notes

* The URL, password, and files shown in the main() function are placedholders.

* Wide version of this code (statements not split)