1/*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 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.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 * SPDX-License-Identifier: curl 22 * 23 ***************************************************************************/ 24/* <DESC> 25 * FTP upload a file from memory 26 * </DESC> 27 */ 28#include <stdio.h> 29#include <string.h> 30#include <curl/curl.h> 31 32static const char data[]= 33 "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " 34 "Nam rhoncus odio id venenatis volutpat. Vestibulum dapibus " 35 "bibendum ullamcorper. Maecenas finibus elit augue, vel " 36 "condimentum odio maximus nec. In hac habitasse platea dictumst. " 37 "Vestibulum vel dolor et turpis rutrum finibus ac at nulla. " 38 "Vivamus nec neque ac elit blandit pretium vitae maximus ipsum. " 39 "Quisque sodales magna vel erat auctor, sed pellentesque nisi " 40 "rhoncus. Donec vehicula maximus pretium. Aliquam eu tincidunt " 41 "lorem."; 42 43struct WriteThis { 44 const char *readptr; 45 size_t sizeleft; 46}; 47 48static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) 49{ 50 struct WriteThis *upload = (struct WriteThis *)userp; 51 size_t max = size*nmemb; 52 53 if(max < 1) 54 return 0; 55 56 if(upload->sizeleft) { 57 size_t copylen = max; 58 if(copylen > upload->sizeleft) 59 copylen = upload->sizeleft; 60 memcpy(ptr, upload->readptr, copylen); 61 upload->readptr += copylen; 62 upload->sizeleft -= copylen; 63 return copylen; 64 } 65 66 return 0; /* no more data left to deliver */ 67} 68 69int main(void) 70{ 71 CURL *curl; 72 CURLcode res; 73 74 struct WriteThis upload; 75 76 upload.readptr = data; 77 upload.sizeleft = strlen(data); 78 79 /* In windows, this will init the winsock stuff */ 80 res = curl_global_init(CURL_GLOBAL_DEFAULT); 81 /* Check for errors */ 82 if(res != CURLE_OK) { 83 fprintf(stderr, "curl_global_init() failed: %s\n", 84 curl_easy_strerror(res)); 85 return 1; 86 } 87 88 /* get a curl handle */ 89 curl = curl_easy_init(); 90 if(curl) { 91 /* First set the URL, the target file */ 92 curl_easy_setopt(curl, CURLOPT_URL, 93 "ftp://example.com/path/to/upload/file"); 94 95 /* User and password for the FTP login */ 96 curl_easy_setopt(curl, CURLOPT_USERPWD, "login:secret"); 97 98 /* Now specify we want to UPLOAD data */ 99 curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); 100 101 /* we want to use our own read function */ 102 curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); 103 104 /* pointer to pass to our read function */ 105 curl_easy_setopt(curl, CURLOPT_READDATA, &upload); 106 107 /* get verbose debug output please */ 108 curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); 109 110 /* Set the expected upload size. */ 111 curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, 112 (curl_off_t)upload.sizeleft); 113 114 /* Perform the request, res will get the return code */ 115 res = curl_easy_perform(curl); 116 /* Check for errors */ 117 if(res != CURLE_OK) 118 fprintf(stderr, "curl_easy_perform() failed: %s\n", 119 curl_easy_strerror(res)); 120 121 /* always cleanup */ 122 curl_easy_cleanup(curl); 123 } 124 curl_global_cleanup(); 125 return 0; 126} 127