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