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#include "test.h" 25 26#include <fcntl.h> 27 28#include "testutil.h" 29#include "warnless.h" 30#include "memdebug.h" 31 32#define TEST_HANG_TIMEOUT 60 * 1000 33 34int test(char *URL) 35{ 36 int res = 0; 37 CURL *curl = NULL; 38 FILE *hd_src = NULL; 39 int hd; 40 struct_stat file_info; 41 CURLM *m = NULL; 42 int running; 43 44 start_test_timing(); 45 46 if(!libtest_arg2) { 47#ifdef LIB529 48 /* test 529 */ 49 fprintf(stderr, "Usage: lib529 [url] [uploadfile]\n"); 50#else 51 /* test 525 */ 52 fprintf(stderr, "Usage: lib525 [url] [uploadfile]\n"); 53#endif 54 return TEST_ERR_USAGE; 55 } 56 57 hd_src = fopen(libtest_arg2, "rb"); 58 if(!hd_src) { 59 fprintf(stderr, "fopen failed with error: %d (%s)\n", 60 errno, strerror(errno)); 61 fprintf(stderr, "Error opening file: (%s)\n", libtest_arg2); 62 return TEST_ERR_FOPEN; 63 } 64 65 /* get the file size of the local file */ 66 hd = fstat(fileno(hd_src), &file_info); 67 if(hd == -1) { 68 /* can't open file, bail out */ 69 fprintf(stderr, "fstat() failed with error: %d (%s)\n", 70 errno, strerror(errno)); 71 fprintf(stderr, "ERROR: cannot open file (%s)\n", libtest_arg2); 72 fclose(hd_src); 73 return TEST_ERR_FSTAT; 74 } 75 76 res_global_init(CURL_GLOBAL_ALL); 77 if(res) { 78 fclose(hd_src); 79 return res; 80 } 81 82 easy_init(curl); 83 84 /* enable uploading */ 85 easy_setopt(curl, CURLOPT_UPLOAD, 1L); 86 87 /* specify target */ 88 easy_setopt(curl, CURLOPT_URL, URL); 89 90 /* go verbose */ 91 easy_setopt(curl, CURLOPT_VERBOSE, 1L); 92 93 /* use active FTP */ 94 easy_setopt(curl, CURLOPT_FTPPORT, "-"); 95 96 /* now specify which file to upload */ 97 easy_setopt(curl, CURLOPT_READDATA, hd_src); 98 99 /* NOTE: if you want this code to work on Windows with libcurl as a DLL, you 100 MUST also provide a read callback with CURLOPT_READFUNCTION. Failing to 101 do so will give you a crash since a DLL may not use the variable's memory 102 when passed in to it from an app like this. */ 103 104 /* Set the size of the file to upload (optional). If you give a *_LARGE 105 option you MUST make sure that the type of the passed-in argument is a 106 curl_off_t. If you use CURLOPT_INFILESIZE (without _LARGE) you must 107 make sure that to pass in a type 'long' argument. */ 108 easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size); 109 110 multi_init(m); 111 112 multi_add_handle(m, curl); 113 114 for(;;) { 115 struct timeval interval; 116 fd_set rd, wr, exc; 117 int maxfd = -99; 118 119 interval.tv_sec = 1; 120 interval.tv_usec = 0; 121 122 multi_perform(m, &running); 123 124 abort_on_test_timeout(); 125 126 if(!running) 127 break; /* done */ 128 129 FD_ZERO(&rd); 130 FD_ZERO(&wr); 131 FD_ZERO(&exc); 132 133 multi_fdset(m, &rd, &wr, &exc, &maxfd); 134 135 /* At this point, maxfd is guaranteed to be greater or equal than -1. */ 136 137 select_test(maxfd + 1, &rd, &wr, &exc, &interval); 138 139 abort_on_test_timeout(); 140 } 141 142test_cleanup: 143 144#ifdef LIB529 145 /* test 529 */ 146 /* proper cleanup sequence - type PA */ 147 curl_multi_remove_handle(m, curl); 148 curl_multi_cleanup(m); 149 curl_easy_cleanup(curl); 150 curl_global_cleanup(); 151#else 152 /* test 525 */ 153 /* proper cleanup sequence - type PB */ 154 curl_multi_remove_handle(m, curl); 155 curl_easy_cleanup(curl); 156 curl_multi_cleanup(m); 157 curl_global_cleanup(); 158#endif 159 160 /* close the local file */ 161 fclose(hd_src); 162 163 return res; 164} 165