1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2014, 2016, 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 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 #include "tool_setup.h" 23 24 #include "strcase.h" 25 26 #define ENABLE_CURLX_PRINTF 27 /* use our own printf() functions */ 28 #include "curlx.h" 29 30 #include "tool_cfgable.h" 31 #include "tool_convert.h" 32 #include "tool_doswin.h" 33 #include "tool_operhlp.h" 34 #include "tool_metalink.h" 35 36 #include "memdebug.h" /* keep this as LAST include */ 37 38 void clean_getout(struct OperationConfig *config) 39 { 40 struct getout *next; 41 struct getout *node = config->url_list; 42 43 while(node) { 44 next = node->next; 45 Curl_safefree(node->url); 46 Curl_safefree(node->outfile); 47 Curl_safefree(node->infile); 48 Curl_safefree(node); 49 node = next; 50 } 51 config->url_list = NULL; 52 } 53 54 bool output_expected(const char *url, const char *uploadfile) 55 { 56 if(!uploadfile) 57 return TRUE; /* download */ 58 if(checkprefix("http://", url) || checkprefix("https://", url)) 59 return TRUE; /* HTTP(S) upload */ 60 61 return FALSE; /* non-HTTP upload, probably no output should be expected */ 62 } 63 64 bool stdin_upload(const char *uploadfile) 65 { 66 return (!strcmp(uploadfile, "-") || 67 !strcmp(uploadfile, ".")) ? TRUE : FALSE; 68 } 69 70 /* 71 * Adds the file name to the URL if it doesn't already have one. 72 * url will be freed before return if the returned pointer is different 73 */ 74 char *add_file_name_to_url(CURL *curl, char *url, const char *filename) 75 { 76 /* If no file name part is given in the URL, we add this file name */ 77 char *ptr = strstr(url, "://"); 78 if(ptr) 79 ptr += 3; 80 else 81 ptr = url; 82 ptr = strrchr(ptr, '/'); 83 if(!ptr || !strlen(++ptr)) { 84 /* The URL has no file name part, add the local file name. In order 85 to be able to do so, we have to create a new URL in another 86 buffer.*/ 87 88 /* We only want the part of the local path that is on the right 89 side of the rightmost slash and backslash. */ 90 const char *filep = strrchr(filename, '/'); 91 char *file2 = strrchr(filep?filep:filename, '\\'); 92 char *encfile; 93 94 if(file2) 95 filep = file2 + 1; 96 else if(filep) 97 filep++; 98 else 99 filep = filename; 100 101 /* URL encode the file name */ 102 encfile = curl_easy_escape(curl, filep, 0 /* use strlen */); 103 if(encfile) { 104 char *urlbuffer; 105 if(ptr) 106 /* there is a trailing slash on the URL */ 107 urlbuffer = aprintf("%s%s", url, encfile); 108 else 109 /* there is no trailing slash on the URL */ 110 urlbuffer = aprintf("%s/%s", url, encfile); 111 112 curl_free(encfile); 113 Curl_safefree(url); 114 115 if(!urlbuffer) 116 return NULL; 117 118 url = urlbuffer; /* use our new URL instead! */ 119 } 120 else 121 Curl_safefree(url); 122 } 123 return url; 124 } 125 126 /* Extracts the name portion of the URL. 127 * Returns a pointer to a heap-allocated string or NULL if 128 * no name part, at location indicated by first argument. 129 */ 130 CURLcode get_url_file_name(char **filename, const char *url) 131 { 132 const char *pc, *pc2; 133 134 *filename = NULL; 135 136 /* Find and get the remote file name */ 137 pc = strstr(url, "://"); 138 if(pc) 139 pc += 3; 140 else 141 pc = url; 142 143 pc2 = strrchr(pc, '\\'); 144 pc = strrchr(pc, '/'); 145 if(pc2 && (!pc || pc < pc2)) 146 pc = pc2; 147 148 if(pc) 149 /* duplicate the string beyond the slash */ 150 pc++; 151 else 152 /* no slash => empty string */ 153 pc = ""; 154 155 *filename = strdup(pc); 156 if(!*filename) 157 return CURLE_OUT_OF_MEMORY; 158 159 #if defined(MSDOS) || defined(WIN32) 160 { 161 char *sanitized; 162 SANITIZEcode sc = sanitize_file_name(&sanitized, *filename, 0); 163 Curl_safefree(*filename); 164 if(sc) 165 return CURLE_URL_MALFORMAT; 166 *filename = sanitized; 167 } 168 #endif /* MSDOS || WIN32 */ 169 170 /* in case we built debug enabled, we allow an environment variable 171 * named CURL_TESTDIR to prefix the given file name to put it into a 172 * specific directory 173 */ 174 #ifdef DEBUGBUILD 175 { 176 char *tdir = curlx_getenv("CURL_TESTDIR"); 177 if(tdir) { 178 char buffer[512]; /* suitably large */ 179 snprintf(buffer, sizeof(buffer), "%s/%s", tdir, *filename); 180 Curl_safefree(*filename); 181 *filename = strdup(buffer); /* clone the buffer */ 182 curl_free(tdir); 183 if(!*filename) 184 return CURLE_OUT_OF_MEMORY; 185 } 186 } 187 #endif 188 189 return CURLE_OK; 190 } 191