1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
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.
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.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
24 #include <curl/curl.h>
28 #define ENABLE_CURLX_PRINTF
29 /* use our own printf() functions */
35 #include "tool_cfgable.h"
36 #include "tool_getparam.h"
37 #include "tool_msgs.h"
38 #include "tool_paramhlp.h"
40 #include "memdebug.h" /* keep this as LAST include */
42 struct getout *new_getout(struct Configurable *config)
44 struct getout *node =malloc(sizeof(struct getout));
45 struct getout *last= config->url_last;
47 /* clear the struct */
48 memset(node, 0, sizeof(struct getout));
50 /* append this new node last in the list */
54 config->url_list = node; /* first node */
56 /* move the last pointer */
57 config->url_last = node;
59 node->flags = config->default_node_flags;
64 ParameterError file2string(char **bufp, FILE *file)
73 while(fgets(buffer, sizeof(buffer), file)) {
74 if((ptr = strchr(buffer, '\r')) != NULL)
76 if((ptr = strchr(buffer, '\n')) != NULL)
78 buflen = strlen(buffer);
79 if((ptr = realloc(string, stringlen+buflen+1)) == NULL) {
80 Curl_safefree(string);
84 strcpy(string+stringlen, buffer);
92 ParameterError file2memory(char **bufp, size_t *size, FILE *file)
102 if(!buffer || (alloc == nused)) {
103 /* size_t overflow detection for huge files */
104 if(alloc+1 > ((size_t)-1)/2) {
105 Curl_safefree(buffer);
109 /* allocate an extra char, reserved space, for null termination */
110 if((newbuf = realloc(buffer, alloc+1)) == NULL) {
111 Curl_safefree(buffer);
116 nread = fread(buffer+nused, 1, alloc-nused, file);
119 /* null terminate the buffer in case it's used as a string later */
120 buffer[nused] = '\0';
121 /* free trailing slack space, if possible */
123 if((newbuf = realloc(buffer, nused+1)) != NULL)
126 /* discard buffer if nothing was read */
128 Curl_safefree(buffer); /* no string */
136 void cleanarg(char *str)
138 #ifdef HAVE_WRITABLE_ARGV
139 /* now that GetStr has copied the contents of nextarg, wipe the next
140 * argument out so that the username:password isn't displayed in the
141 * system process list */
143 size_t len = strlen(str);
144 memset(str, ' ', len);
152 * Parse the string and write the integer in the given address. Return
153 * non-zero on failure, zero on success.
155 * The string must start with a digit to be valid.
157 * Since this function gets called with the 'nextarg' pointer from within the
158 * getparameter a lot, we must check it for NULL before accessing the str
162 int str2num(long *val, const char *str)
164 if(str && ISDIGIT(*str)) {
166 long num = strtol(str, &endptr, 10);
167 if((endptr != str) && (endptr == str + strlen(str))) {
172 return 1; /* badness */
176 * Parse the string and modify the long in the given address. Return
177 * non-zero on failure, zero on success.
179 * The string is a list of protocols
181 * Since this function gets called with the 'nextarg' pointer from within the
182 * getparameter a lot, we must check it for NULL before accessing the str
186 long proto2num(struct Configurable *config, long *val, const char *str)
189 const char *sep = ",";
192 static struct sprotos {
196 { "all", CURLPROTO_ALL },
197 { "http", CURLPROTO_HTTP },
198 { "https", CURLPROTO_HTTPS },
199 { "ftp", CURLPROTO_FTP },
200 { "ftps", CURLPROTO_FTPS },
201 { "scp", CURLPROTO_SCP },
202 { "sftp", CURLPROTO_SFTP },
203 { "telnet", CURLPROTO_TELNET },
204 { "ldap", CURLPROTO_LDAP },
205 { "ldaps", CURLPROTO_LDAPS },
206 { "dict", CURLPROTO_DICT },
207 { "file", CURLPROTO_FILE },
208 { "tftp", CURLPROTO_TFTP },
209 { "imap", CURLPROTO_IMAP },
210 { "imaps", CURLPROTO_IMAPS },
211 { "pop3", CURLPROTO_POP3 },
212 { "pop3s", CURLPROTO_POP3S },
213 { "smtp", CURLPROTO_SMTP },
214 { "smtps", CURLPROTO_SMTPS },
215 { "rtsp", CURLPROTO_RTSP },
216 { "gopher", CURLPROTO_GOPHER },
223 buffer = strdup(str); /* because strtok corrupts it */
225 for(token = strtok(buffer, sep);
227 token = strtok(NULL, sep)) {
228 enum e_action { allow, deny, set } action = allow;
230 struct sprotos const *pp;
232 /* Process token modifiers */
233 while(!ISALNUM(*token)) { /* may be NULL if token is all modifiers */
244 default: /* Includes case of terminating NULL */
245 Curl_safefree(buffer);
250 for(pp=protos; pp->name; pp++) {
251 if(curlx_raw_equal(token, pp->name)) {
267 if(!(pp->name)) { /* unknown protocol */
268 /* If they have specified only this protocol, we say treat it as
269 if no protocols are allowed */
272 warnf(config, "unrecognized protocol '%s'\n", token);
275 Curl_safefree(buffer);
280 * Parses the given string looking for an offset (which may be
281 * a larger-than-integer value).
283 * @param val the offset to populate
284 * @param str the buffer containing the offset
285 * @return zero if successful, non-zero if failure.
287 int str2offset(curl_off_t *val, const char *str)
289 #if(CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG)
290 *val = curlx_strtoofft(str, NULL, 0);
291 if((*val == CURL_OFF_T_MAX || *val == CURL_OFF_T_MIN) && (ERRNO == ERANGE))
294 *val = strtol(str, NULL, 0);
295 if((*val == LONG_MIN || *val == LONG_MAX) && ERRNO == ERANGE)
301 void checkpasswd(const char *kind, /* for what purpose */
302 char **userpwd) /* pointer to allocated string */
308 ptr = strchr(*userpwd, ':');
310 /* no password present, prompt for one */
314 size_t userlen = strlen(*userpwd);
317 /* build a nice-looking prompt */
318 curlx_msnprintf(prompt, sizeof(prompt),
319 "Enter %s password for user '%s':",
323 getpass_r(prompt, passwd, sizeof(passwd));
324 passwdlen = strlen(passwd);
326 /* extend the allocated memory area to fit the password too */
327 passptr = realloc(*userpwd,
328 passwdlen + 1 + /* an extra for the colon */
329 userlen + 1); /* an extra for the zero */
332 /* append the password separated with a colon */
333 passptr[userlen]=':';
334 memcpy(&passptr[userlen+1], passwd, passwdlen+1);
340 ParameterError add2list(struct curl_slist **list, const char *ptr)
342 struct curl_slist *newlist = curl_slist_append(*list, ptr);
351 int ftpfilemethod(struct Configurable *config, const char *str)
353 if(curlx_raw_equal("singlecwd", str))
354 return CURLFTPMETHOD_SINGLECWD;
355 if(curlx_raw_equal("nocwd", str))
356 return CURLFTPMETHOD_NOCWD;
357 if(curlx_raw_equal("multicwd", str))
358 return CURLFTPMETHOD_MULTICWD;
359 warnf(config, "unrecognized ftp file method '%s', using default\n", str);
360 return CURLFTPMETHOD_MULTICWD;
363 int ftpcccmethod(struct Configurable *config, const char *str)
365 if(curlx_raw_equal("passive", str))
366 return CURLFTPSSL_CCC_PASSIVE;
367 if(curlx_raw_equal("active", str))
368 return CURLFTPSSL_CCC_ACTIVE;
369 warnf(config, "unrecognized ftp CCC method '%s', using default\n", str);
370 return CURLFTPSSL_CCC_PASSIVE;
373 long delegation(struct Configurable *config, char *str)
375 if(curlx_raw_equal("none", str))
376 return CURLGSSAPI_DELEGATION_NONE;
377 if(curlx_raw_equal("policy", str))
378 return CURLGSSAPI_DELEGATION_POLICY_FLAG;
379 if(curlx_raw_equal("always", str))
380 return CURLGSSAPI_DELEGATION_FLAG;
381 warnf(config, "unrecognized delegation method '%s', using none\n", str);
382 return CURLGSSAPI_DELEGATION_NONE;