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