1/*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2012, 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 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 */ 74static 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 */ 96static 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 113int 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