1/*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2011, 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 "setup.h" 23 24#include <curl/curl.h> 25 26#include "rawstr.h" 27 28#define ENABLE_CURLX_PRINTF 29/* use our own printf() functions */ 30#include "curlx.h" 31 32#include "tool_cfgable.h" 33#include "tool_convert.h" 34#include "tool_operhlp.h" 35#include "tool_version.h" 36 37#include "memdebug.h" /* keep this as LAST include */ 38 39/* 40 * my_useragent: returns allocated string with default user agent 41 */ 42char *my_useragent(void) 43{ 44 char useragent[256]; /* we don't want a larger default user agent */ 45 46 snprintf(useragent, sizeof(useragent), 47 CURL_NAME "/" CURL_VERSION " (" OS ") " "%s", curl_version()); 48 49 return strdup(useragent); 50} 51 52/* 53 * Print list of OpenSSL supported engines 54 */ 55void list_engines(const struct curl_slist *engines) 56{ 57 puts("Build-time engines:"); 58 if(!engines) { 59 puts(" <none>"); 60 return; 61 } 62 for(; engines; engines = engines->next) 63 printf(" %s\n", engines->data); 64} 65 66void clean_getout(struct Configurable *config) 67{ 68 struct getout *next; 69 struct getout *node = config->url_list; 70 71 while(node) { 72 next = node->next; 73 Curl_safefree(node->url); 74 Curl_safefree(node->outfile); 75 Curl_safefree(node->infile); 76 Curl_safefree(node); 77 node = next; 78 } 79 config->url_list = NULL; 80} 81 82bool output_expected(const char *url, const char *uploadfile) 83{ 84 if(!uploadfile) 85 return TRUE; /* download */ 86 if(checkprefix("http://", url) || checkprefix("https://", url)) 87 return TRUE; /* HTTP(S) upload */ 88 89 return FALSE; /* non-HTTP upload, probably no output should be expected */ 90} 91 92bool stdin_upload(const char *uploadfile) 93{ 94 return (curlx_strequal(uploadfile, "-") || 95 curlx_strequal(uploadfile, ".")) ? TRUE : FALSE; 96} 97 98/* 99 * Adds the file name to the URL if it doesn't already have one. 100 * url will be freed before return if the returned pointer is different 101 */ 102char *add_file_name_to_url(CURL *curl, char *url, const char *filename) 103{ 104 /* If no file name part is given in the URL, we add this file name */ 105 char *ptr = strstr(url, "://"); 106 if(ptr) 107 ptr += 3; 108 else 109 ptr = url; 110 ptr = strrchr(ptr, '/'); 111 if(!ptr || !strlen(++ptr)) { 112 /* The URL has no file name part, add the local file name. In order 113 to be able to do so, we have to create a new URL in another 114 buffer.*/ 115 116 /* We only want the part of the local path that is on the right 117 side of the rightmost slash and backslash. */ 118 const char *filep = strrchr(filename, '/'); 119 char *file2 = strrchr(filep?filep:filename, '\\'); 120 char *encfile; 121 122 if(file2) 123 filep = file2 + 1; 124 else if(filep) 125 filep++; 126 else 127 filep = filename; 128 129 /* URL encode the file name */ 130 encfile = curl_easy_escape(curl, filep, 0 /* use strlen */); 131 if(encfile) { 132 char *urlbuffer = malloc(strlen(url) + strlen(encfile) + 3); 133 if(!urlbuffer) { 134 curl_free(encfile); 135 Curl_safefree(url); 136 return NULL; 137 } 138 if(ptr) 139 /* there is a trailing slash on the URL */ 140 sprintf(urlbuffer, "%s%s", url, encfile); 141 else 142 /* there is no trailing slash on the URL */ 143 sprintf(urlbuffer, "%s/%s", url, encfile); 144 145 curl_free(encfile); 146 Curl_safefree(url); 147 148 url = urlbuffer; /* use our new URL instead! */ 149 } 150 } 151 return url; 152} 153 154/* Extracts the name portion of the URL. 155 * Returns a pointer to a heap-allocated string or NULL if 156 * no name part, at location indicated by first argument. 157 */ 158CURLcode get_url_file_name(char **filename, const char *url) 159{ 160 const char *pc; 161 162 *filename = NULL; 163 164 /* Find and get the remote file name */ 165 pc = strstr(url, "://"); 166 if(pc) 167 pc += 3; 168 else 169 pc = url; 170 pc = strrchr(pc, '/'); 171 172 if(pc) { 173 /* duplicate the string beyond the slash */ 174 pc++; 175 if(*pc) { 176 *filename = strdup(pc); 177 if(!*filename) 178 return CURLE_OUT_OF_MEMORY; 179 } 180 } 181 return CURLE_OK; 182} 183 184/* 185 * This is the main global constructor for the app. Call this before 186 * _any_ libcurl usage. If this fails, *NO* libcurl functions may be 187 * used, or havoc may be the result. 188 */ 189CURLcode main_init(void) 190{ 191#if defined(__DJGPP__) || defined(__GO32__) 192 /* stop stat() wasting time */ 193 _djstat_flags |= _STAT_INODE | _STAT_EXEC_MAGIC | _STAT_DIRSIZE; 194#endif 195 196 return curl_global_init(CURL_GLOBAL_DEFAULT); 197} 198 199/* 200 * This is the main global destructor for the app. Call this after 201 * _all_ libcurl usage is done. 202 */ 203void main_free(void) 204{ 205 curl_global_cleanup(); 206 convert_cleanup(); 207} 208 209#ifdef CURLDEBUG 210void memory_tracking_init(void) 211{ 212 char *env; 213 /* if CURL_MEMDEBUG is set, this starts memory tracking message logging */ 214 env = curlx_getenv("CURL_MEMDEBUG"); 215 if(env) { 216 /* use the value as file name */ 217 char fname[CURL_MT_LOGFNAME_BUFSIZE]; 218 if(strlen(env) >= CURL_MT_LOGFNAME_BUFSIZE) 219 env[CURL_MT_LOGFNAME_BUFSIZE-1] = '\0'; 220 strcpy(fname, env); 221 curl_free(env); 222 curl_memdebug(fname); 223 /* this weird stuff here is to make curl_free() get called 224 before curl_memdebug() as otherwise memory tracking will 225 log a free() without an alloc! */ 226 } 227 /* if CURL_MEMLIMIT is set, this enables fail-on-alloc-number-N feature */ 228 env = curlx_getenv("CURL_MEMLIMIT"); 229 if(env) { 230 char *endptr; 231 long num = strtol(env, &endptr, 10); 232 if((endptr != env) && (endptr == env + strlen(env)) && (num > 0)) 233 curl_memlimit(num); 234 curl_free(env); 235 } 236} 237#endif 238 239