Home | History | Annotate | Download | only in examples
      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel (at) 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 http://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 #include <stdio.h>
     23 #include <fcntl.h>
     24 #ifdef WIN32
     25 #  include <io.h>
     26 #else
     27 #  ifdef __VMS
     28      typedef int intptr_t;
     29 #  endif
     30 #  if !defined(_AIX) && !defined(__sgi) && !defined(__osf__)
     31 #    include <stdint.h>
     32 #  endif
     33 #  include <unistd.h>
     34 #endif
     35 #include <sys/types.h>
     36 #include <sys/stat.h>
     37 
     38 #ifdef _MSC_VER
     39 #  ifdef _WIN64
     40      typedef __int64 intptr_t;
     41 #  else
     42      typedef int intptr_t;
     43 #  endif
     44 #endif
     45 
     46 #include <curl/curl.h>
     47 
     48 #if LIBCURL_VERSION_NUM < 0x070c03
     49 #error "upgrade your libcurl to no less than 7.12.3"
     50 #endif
     51 
     52 #ifndef TRUE
     53 #define TRUE 1
     54 #endif
     55 
     56 #if defined(_AIX) || defined(__sgi) || defined(__osf__)
     57 #ifndef intptr_t
     58 #define intptr_t long
     59 #endif
     60 #endif
     61 
     62 /*
     63  * This example shows a HTTP PUT operation with authentiction using "any"
     64  * type. It PUTs a file given as a command line argument to the URL also given
     65  * on the command line.
     66  *
     67  * Since libcurl 7.12.3, using "any" auth and POST/PUT requires a set ioctl
     68  * function.
     69  *
     70  * This example also uses its own read callback.
     71  */
     72 
     73 /* ioctl callback function */
     74 static curlioerr my_ioctl(CURL *handle, curliocmd cmd, void *userp)
     75 {
     76   intptr_t fd = (intptr_t)userp;
     77 
     78   (void)handle; /* not used in here */
     79 
     80   switch(cmd) {
     81   case CURLIOCMD_RESTARTREAD:
     82     /* mr libcurl kindly asks as to rewind the read data stream to start */
     83     if(-1 == lseek(fd, 0, SEEK_SET))
     84       /* couldn't rewind */
     85       return CURLIOE_FAILRESTART;
     86 
     87     break;
     88 
     89   default: /* ignore unknown commands */
     90     return CURLIOE_UNKNOWNCMD;
     91   }
     92   return CURLIOE_OK; /* success! */
     93 }
     94 
     95 /* read callback function, fread() look alike */
     96 static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
     97 {
     98   size_t retcode;
     99   curl_off_t nread;
    100 
    101   intptr_t fd = (intptr_t)stream;
    102 
    103   retcode = read(fd, ptr, size * nmemb);
    104 
    105   nread = (curl_off_t)retcode;
    106 
    107   fprintf(stderr, "*** We read %" CURL_FORMAT_CURL_OFF_T
    108           " bytes from file\n", nread);
    109 
    110   return retcode;
    111 }
    112 
    113 int main(int argc, char **argv)
    114 {
    115   CURL *curl;
    116   CURLcode res;
    117   intptr_t hd ;
    118   struct stat file_info;
    119 
    120   char *file;
    121   char *url;
    122 
    123   if(argc < 3)
    124     return 1;
    125 
    126   file= argv[1];
    127   url = argv[2];
    128 
    129   /* get the file size of the local file */
    130   hd = open(file, O_RDONLY) ;
    131   fstat(hd, &file_info);
    132 
    133   /* In windows, this will init the winsock stuff */
    134   curl_global_init(CURL_GLOBAL_ALL);
    135 
    136   /* get a curl handle */
    137   curl = curl_easy_init();
    138   if(curl) {
    139     /* we want to use our own read function */
    140     curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
    141 
    142     /* which file to upload */
    143     curl_easy_setopt(curl, CURLOPT_READDATA, (void*)hd);
    144 
    145     /* set the ioctl function */
    146     curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, my_ioctl);
    147 
    148     /* pass the file descriptor to the ioctl callback as well */
    149     curl_easy_setopt(curl, CURLOPT_IOCTLDATA, (void*)hd);
    150 
    151     /* enable "uploading" (which means PUT when doing HTTP) */
    152     curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L) ;
    153 
    154     /* specify target URL, and note that this URL should also include a file
    155        name, not only a directory (as you can do with GTP uploads) */
    156     curl_easy_setopt(curl,CURLOPT_URL, url);
    157 
    158     /* and give the size of the upload, this supports large file sizes
    159        on systems that have general support for it */
    160     curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
    161                      (curl_off_t)file_info.st_size);
    162 
    163     /* tell libcurl we can use "any" auth, which lets the lib pick one, but it
    164        also costs one extra round-trip and possibly sending of all the PUT
    165        data twice!!! */
    166     curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_ANY);
    167 
    168     /* set user name and password for the authentication */
    169     curl_easy_setopt(curl, CURLOPT_USERPWD, "user:password");
    170 
    171     /* Now run off and do what you've been told! */
    172     res = curl_easy_perform(curl);
    173     /* Check for errors */
    174     if(res != CURLE_OK)
    175       fprintf(stderr, "curl_easy_perform() failed: %s\n",
    176               curl_easy_strerror(res));
    177 
    178     /* always cleanup */
    179     curl_easy_cleanup(curl);
    180   }
    181   close(hd); /* close the local file */
    182 
    183   curl_global_cleanup();
    184   return 0;
    185 }
    186