Annotation of embedaddon/curl/docs/examples/ftpuploadresume.c, revision 1.1.1.1

1.1       misho       1: /***************************************************************************
                      2:  *                                  _   _ ____  _
                      3:  *  Project                     ___| | | |  _ \| |
                      4:  *                             / __| | | | |_) | |
                      5:  *                            | (__| |_| |  _ <| |___
                      6:  *                             \___|\___/|_| \_\_____|
                      7:  *
                      8:  * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
                      9:  *
                     10:  * This software is licensed as described in the file COPYING, which
                     11:  * you should have received as part of this distribution. The terms
                     12:  * are also available at https://curl.haxx.se/docs/copyright.html.
                     13:  *
                     14:  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
                     15:  * copies of the Software, and permit persons to whom the Software is
                     16:  * furnished to do so, under the terms of the COPYING file.
                     17:  *
                     18:  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
                     19:  * KIND, either express or implied.
                     20:  *
                     21:  ***************************************************************************/
                     22: /* <DESC>
                     23:  * Upload to FTP, resuming failed transfers.
                     24:  * </DESC>
                     25:  */
                     26: 
                     27: #include <stdlib.h>
                     28: #include <stdio.h>
                     29: #include <curl/curl.h>
                     30: 
                     31: /* parse headers for Content-Length */
                     32: static size_t getcontentlengthfunc(void *ptr, size_t size, size_t nmemb,
                     33:                                    void *stream)
                     34: {
                     35:   int r;
                     36:   long len = 0;
                     37: 
                     38:   r = sscanf(ptr, "Content-Length: %ld\n", &len);
                     39:   if(r)
                     40:     *((long *) stream) = len;
                     41: 
                     42:   return size * nmemb;
                     43: }
                     44: 
                     45: /* discard downloaded data */
                     46: static size_t discardfunc(void *ptr, size_t size, size_t nmemb, void *stream)
                     47: {
                     48:   (void)ptr;
                     49:   (void)stream;
                     50:   return size * nmemb;
                     51: }
                     52: 
                     53: /* read data to upload */
                     54: static size_t readfunc(void *ptr, size_t size, size_t nmemb, void *stream)
                     55: {
                     56:   FILE *f = stream;
                     57:   size_t n;
                     58: 
                     59:   if(ferror(f))
                     60:     return CURL_READFUNC_ABORT;
                     61: 
                     62:   n = fread(ptr, size, nmemb, f) * size;
                     63: 
                     64:   return n;
                     65: }
                     66: 
                     67: 
                     68: static int upload(CURL *curlhandle, const char *remotepath,
                     69:                   const char *localpath, long timeout, long tries)
                     70: {
                     71:   FILE *f;
                     72:   long uploaded_len = 0;
                     73:   CURLcode r = CURLE_GOT_NOTHING;
                     74:   int c;
                     75: 
                     76:   f = fopen(localpath, "rb");
                     77:   if(!f) {
                     78:     perror(NULL);
                     79:     return 0;
                     80:   }
                     81: 
                     82:   curl_easy_setopt(curlhandle, CURLOPT_UPLOAD, 1L);
                     83: 
                     84:   curl_easy_setopt(curlhandle, CURLOPT_URL, remotepath);
                     85: 
                     86:   if(timeout)
                     87:     curl_easy_setopt(curlhandle, CURLOPT_FTP_RESPONSE_TIMEOUT, timeout);
                     88: 
                     89:   curl_easy_setopt(curlhandle, CURLOPT_HEADERFUNCTION, getcontentlengthfunc);
                     90:   curl_easy_setopt(curlhandle, CURLOPT_HEADERDATA, &uploaded_len);
                     91: 
                     92:   curl_easy_setopt(curlhandle, CURLOPT_WRITEFUNCTION, discardfunc);
                     93: 
                     94:   curl_easy_setopt(curlhandle, CURLOPT_READFUNCTION, readfunc);
                     95:   curl_easy_setopt(curlhandle, CURLOPT_READDATA, f);
                     96: 
                     97:   /* disable passive mode */
                     98:   curl_easy_setopt(curlhandle, CURLOPT_FTPPORT, "-");
                     99:   curl_easy_setopt(curlhandle, CURLOPT_FTP_CREATE_MISSING_DIRS, 1L);
                    100: 
                    101:   curl_easy_setopt(curlhandle, CURLOPT_VERBOSE, 1L);
                    102: 
                    103:   for(c = 0; (r != CURLE_OK) && (c < tries); c++) {
                    104:     /* are we resuming? */
                    105:     if(c) { /* yes */
                    106:       /* determine the length of the file already written */
                    107: 
                    108:       /*
                    109:        * With NOBODY and NOHEADER, libcurl will issue a SIZE
                    110:        * command, but the only way to retrieve the result is
                    111:        * to parse the returned Content-Length header. Thus,
                    112:        * getcontentlengthfunc(). We need discardfunc() above
                    113:        * because HEADER will dump the headers to stdout
                    114:        * without it.
                    115:        */
                    116:       curl_easy_setopt(curlhandle, CURLOPT_NOBODY, 1L);
                    117:       curl_easy_setopt(curlhandle, CURLOPT_HEADER, 1L);
                    118: 
                    119:       r = curl_easy_perform(curlhandle);
                    120:       if(r != CURLE_OK)
                    121:         continue;
                    122: 
                    123:       curl_easy_setopt(curlhandle, CURLOPT_NOBODY, 0L);
                    124:       curl_easy_setopt(curlhandle, CURLOPT_HEADER, 0L);
                    125: 
                    126:       fseek(f, uploaded_len, SEEK_SET);
                    127: 
                    128:       curl_easy_setopt(curlhandle, CURLOPT_APPEND, 1L);
                    129:     }
                    130:     else { /* no */
                    131:       curl_easy_setopt(curlhandle, CURLOPT_APPEND, 0L);
                    132:     }
                    133: 
                    134:     r = curl_easy_perform(curlhandle);
                    135:   }
                    136: 
                    137:   fclose(f);
                    138: 
                    139:   if(r == CURLE_OK)
                    140:     return 1;
                    141:   else {
                    142:     fprintf(stderr, "%s\n", curl_easy_strerror(r));
                    143:     return 0;
                    144:   }
                    145: }
                    146: 
                    147: int main(void)
                    148: {
                    149:   CURL *curlhandle = NULL;
                    150: 
                    151:   curl_global_init(CURL_GLOBAL_ALL);
                    152:   curlhandle = curl_easy_init();
                    153: 
                    154:   upload(curlhandle, "ftp://user:pass@example.com/path/file", "C:\\file",
                    155:          0, 3);
                    156: 
                    157:   curl_easy_cleanup(curlhandle);
                    158:   curl_global_cleanup();
                    159: 
                    160:   return 0;
                    161: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>