2011-10-04 18:03:20 -04:00
|
|
|
/***************************************************************************
|
|
|
|
* _ _ ____ _
|
|
|
|
* Project ___| | | | _ \| |
|
|
|
|
* / __| | | | |_) | |
|
|
|
|
* | (__| |_| | _ <| |___
|
|
|
|
* \___|\___/|_| \_\_____|
|
|
|
|
*
|
2018-09-16 16:04:49 -04:00
|
|
|
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
2011-10-04 18:03:20 -04:00
|
|
|
*
|
|
|
|
* This software is licensed as described in the file COPYING, which
|
|
|
|
* you should have received as part of this distribution. The terms
|
2016-02-02 18:19:02 -05:00
|
|
|
* are also available at https://curl.haxx.se/docs/copyright.html.
|
2011-10-04 18:03:20 -04:00
|
|
|
*
|
|
|
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
|
|
|
* copies of the Software, and permit persons to whom the Software is
|
|
|
|
* furnished to do so, under the terms of the COPYING file.
|
|
|
|
*
|
|
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
|
|
* KIND, either express or implied.
|
|
|
|
*
|
|
|
|
***************************************************************************/
|
2012-04-06 17:35:15 -04:00
|
|
|
#include "tool_setup.h"
|
2011-10-04 18:03:20 -04:00
|
|
|
|
2016-09-30 12:54:02 -04:00
|
|
|
#include "strcase.h"
|
2011-10-04 18:03:20 -04:00
|
|
|
|
|
|
|
#define ENABLE_CURLX_PRINTF
|
|
|
|
/* use our own printf() functions */
|
|
|
|
#include "curlx.h"
|
|
|
|
|
|
|
|
#include "tool_cfgable.h"
|
|
|
|
#include "tool_getparam.h"
|
2011-10-06 11:39:00 -04:00
|
|
|
#include "tool_getpass.h"
|
|
|
|
#include "tool_homedir.h"
|
2011-10-04 18:03:20 -04:00
|
|
|
#include "tool_msgs.h"
|
|
|
|
#include "tool_paramhlp.h"
|
2014-02-14 16:59:51 -05:00
|
|
|
#include "tool_version.h"
|
2011-10-04 18:03:20 -04:00
|
|
|
|
2013-01-03 20:50:28 -05:00
|
|
|
#include "memdebug.h" /* keep this as LAST include */
|
2011-10-04 18:03:20 -04:00
|
|
|
|
2014-02-23 07:59:59 -05:00
|
|
|
struct getout *new_getout(struct OperationConfig *config)
|
2011-10-04 18:03:20 -04:00
|
|
|
{
|
2011-10-05 09:06:26 -04:00
|
|
|
struct getout *node = calloc(1, sizeof(struct getout));
|
|
|
|
struct getout *last = config->url_last;
|
2011-10-04 18:03:20 -04:00
|
|
|
if(node) {
|
|
|
|
/* append this new node last in the list */
|
|
|
|
if(last)
|
|
|
|
last->next = node;
|
|
|
|
else
|
|
|
|
config->url_list = node; /* first node */
|
|
|
|
|
|
|
|
/* move the last pointer */
|
|
|
|
config->url_last = node;
|
|
|
|
|
|
|
|
node->flags = config->default_node_flags;
|
|
|
|
}
|
|
|
|
return node;
|
|
|
|
}
|
|
|
|
|
|
|
|
ParameterError file2string(char **bufp, FILE *file)
|
|
|
|
{
|
|
|
|
char *string = NULL;
|
|
|
|
if(file) {
|
2019-09-12 04:09:22 -04:00
|
|
|
char *ptr;
|
|
|
|
size_t alloc = 512;
|
|
|
|
size_t alloc_needed;
|
2018-06-02 16:52:56 -04:00
|
|
|
char buffer[256];
|
|
|
|
size_t stringlen = 0;
|
2019-09-12 04:09:22 -04:00
|
|
|
string = malloc(alloc);
|
|
|
|
if(!string)
|
|
|
|
return PARAM_NO_MEM;
|
|
|
|
|
2011-10-04 18:03:20 -04:00
|
|
|
while(fgets(buffer, sizeof(buffer), file)) {
|
2018-06-02 16:52:56 -04:00
|
|
|
size_t buflen;
|
2016-12-13 19:29:44 -05:00
|
|
|
ptr = strchr(buffer, '\r');
|
|
|
|
if(ptr)
|
2011-10-04 18:03:20 -04:00
|
|
|
*ptr = '\0';
|
2016-12-13 19:29:44 -05:00
|
|
|
ptr = strchr(buffer, '\n');
|
|
|
|
if(ptr)
|
2011-10-04 18:03:20 -04:00
|
|
|
*ptr = '\0';
|
|
|
|
buflen = strlen(buffer);
|
2019-09-12 04:09:22 -04:00
|
|
|
alloc_needed = stringlen + buflen + 1;
|
|
|
|
if(alloc < alloc_needed) {
|
|
|
|
#if SIZEOF_SIZE_T < 8
|
|
|
|
if(alloc >= (size_t)SIZE_T_MAX/2) {
|
|
|
|
Curl_safefree(string);
|
|
|
|
return PARAM_NO_MEM;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
/* doubling is enough since the string to add is always max 256 bytes
|
|
|
|
and the alloc size start at 512 */
|
|
|
|
alloc *= 2;
|
|
|
|
ptr = realloc(string, alloc);
|
|
|
|
if(!ptr) {
|
|
|
|
Curl_safefree(string);
|
|
|
|
return PARAM_NO_MEM;
|
|
|
|
}
|
|
|
|
string = ptr;
|
2011-10-04 18:03:20 -04:00
|
|
|
}
|
2017-09-09 17:55:08 -04:00
|
|
|
strcpy(string + stringlen, buffer);
|
2011-10-04 18:03:20 -04:00
|
|
|
stringlen += buflen;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*bufp = string;
|
|
|
|
return PARAM_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
ParameterError file2memory(char **bufp, size_t *size, FILE *file)
|
|
|
|
{
|
|
|
|
char *newbuf;
|
|
|
|
char *buffer = NULL;
|
|
|
|
size_t nused = 0;
|
|
|
|
|
|
|
|
if(file) {
|
2018-06-02 16:52:56 -04:00
|
|
|
size_t nread;
|
|
|
|
size_t alloc = 512;
|
2011-10-04 18:03:20 -04:00
|
|
|
do {
|
|
|
|
if(!buffer || (alloc == nused)) {
|
|
|
|
/* size_t overflow detection for huge files */
|
2017-09-09 17:55:08 -04:00
|
|
|
if(alloc + 1 > ((size_t)-1)/2) {
|
2011-10-04 18:03:20 -04:00
|
|
|
Curl_safefree(buffer);
|
|
|
|
return PARAM_NO_MEM;
|
|
|
|
}
|
|
|
|
alloc *= 2;
|
|
|
|
/* allocate an extra char, reserved space, for null termination */
|
2017-09-09 17:55:08 -04:00
|
|
|
newbuf = realloc(buffer, alloc + 1);
|
2016-12-13 19:29:44 -05:00
|
|
|
if(!newbuf) {
|
2011-10-04 18:03:20 -04:00
|
|
|
Curl_safefree(buffer);
|
|
|
|
return PARAM_NO_MEM;
|
|
|
|
}
|
|
|
|
buffer = newbuf;
|
|
|
|
}
|
2017-09-09 17:55:08 -04:00
|
|
|
nread = fread(buffer + nused, 1, alloc-nused, file);
|
2011-10-04 18:03:20 -04:00
|
|
|
nused += nread;
|
|
|
|
} while(nread);
|
|
|
|
/* null terminate the buffer in case it's used as a string later */
|
|
|
|
buffer[nused] = '\0';
|
|
|
|
/* free trailing slack space, if possible */
|
|
|
|
if(alloc != nused) {
|
2017-09-09 17:55:08 -04:00
|
|
|
newbuf = realloc(buffer, nused + 1);
|
2016-12-13 19:29:44 -05:00
|
|
|
if(!newbuf) {
|
2011-10-05 09:06:26 -04:00
|
|
|
Curl_safefree(buffer);
|
|
|
|
return PARAM_NO_MEM;
|
|
|
|
}
|
|
|
|
buffer = newbuf;
|
2011-10-04 18:03:20 -04:00
|
|
|
}
|
|
|
|
/* discard buffer if nothing was read */
|
|
|
|
if(!nused) {
|
|
|
|
Curl_safefree(buffer); /* no string */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*size = nused;
|
|
|
|
*bufp = buffer;
|
|
|
|
return PARAM_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void cleanarg(char *str)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_WRITABLE_ARGV
|
|
|
|
/* now that GetStr has copied the contents of nextarg, wipe the next
|
|
|
|
* argument out so that the username:password isn't displayed in the
|
|
|
|
* system process list */
|
|
|
|
if(str) {
|
|
|
|
size_t len = strlen(str);
|
|
|
|
memset(str, ' ', len);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
(void)str;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2012-11-26 10:23:02 -05:00
|
|
|
* Parse the string and write the long in the given address. Return PARAM_OK
|
|
|
|
* on success, otherwise a parameter specific error enum.
|
2011-10-04 18:03:20 -04:00
|
|
|
*
|
|
|
|
* Since this function gets called with the 'nextarg' pointer from within the
|
|
|
|
* getparameter a lot, we must check it for NULL before accessing the str
|
|
|
|
* data.
|
|
|
|
*/
|
|
|
|
|
2012-11-26 10:23:02 -05:00
|
|
|
ParameterError str2num(long *val, const char *str)
|
2011-10-04 18:03:20 -04:00
|
|
|
{
|
2012-02-12 08:49:32 -05:00
|
|
|
if(str) {
|
2011-10-04 18:03:20 -04:00
|
|
|
char *endptr;
|
2017-08-06 14:10:40 -04:00
|
|
|
long num;
|
|
|
|
errno = 0;
|
|
|
|
num = strtol(str, &endptr, 10);
|
|
|
|
if(errno == ERANGE)
|
|
|
|
return PARAM_NUMBER_TOO_LARGE;
|
2011-10-04 18:03:20 -04:00
|
|
|
if((endptr != str) && (endptr == str + strlen(str))) {
|
|
|
|
*val = num;
|
2012-07-10 17:11:30 -04:00
|
|
|
return PARAM_OK; /* Ok */
|
2011-10-04 18:03:20 -04:00
|
|
|
}
|
|
|
|
}
|
2012-07-10 17:11:30 -04:00
|
|
|
return PARAM_BAD_NUMERIC; /* badness */
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2012-11-26 10:23:02 -05:00
|
|
|
* Parse the string and write the long in the given address. Return PARAM_OK
|
|
|
|
* on success, otherwise a parameter error enum. ONLY ACCEPTS POSITIVE NUMBERS!
|
2012-07-10 17:11:30 -04:00
|
|
|
*
|
|
|
|
* Since this function gets called with the 'nextarg' pointer from within the
|
|
|
|
* getparameter a lot, we must check it for NULL before accessing the str
|
|
|
|
* data.
|
|
|
|
*/
|
|
|
|
|
2012-11-26 10:23:02 -05:00
|
|
|
ParameterError str2unum(long *val, const char *str)
|
2012-07-10 17:11:30 -04:00
|
|
|
{
|
2013-07-14 12:33:44 -04:00
|
|
|
ParameterError result = str2num(val, str);
|
|
|
|
if(result != PARAM_OK)
|
|
|
|
return result;
|
|
|
|
if(*val < 0)
|
|
|
|
return PARAM_NEGATIVE_NUMERIC;
|
|
|
|
|
|
|
|
return PARAM_OK;
|
2011-10-04 18:03:20 -04:00
|
|
|
}
|
|
|
|
|
2019-07-29 16:10:13 -04:00
|
|
|
/*
|
|
|
|
* Parse the string and write the long in the given address if it is below the
|
|
|
|
* maximum allowed value. Return PARAM_OK on success, otherwise a parameter
|
|
|
|
* error enum. ONLY ACCEPTS POSITIVE NUMBERS!
|
|
|
|
*
|
|
|
|
* Since this function gets called with the 'nextarg' pointer from within the
|
|
|
|
* getparameter a lot, we must check it for NULL before accessing the str
|
|
|
|
* data.
|
|
|
|
*/
|
|
|
|
|
|
|
|
ParameterError str2unummax(long *val, const char *str, long max)
|
|
|
|
{
|
|
|
|
ParameterError result = str2unum(val, str);
|
|
|
|
if(result != PARAM_OK)
|
|
|
|
return result;
|
|
|
|
if(*val > max)
|
|
|
|
return PARAM_NUMBER_TOO_LARGE;
|
|
|
|
|
|
|
|
return PARAM_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-04-30 10:23:39 -04:00
|
|
|
/*
|
|
|
|
* Parse the string and write the double in the given address. Return PARAM_OK
|
|
|
|
* on success, otherwise a parameter specific error enum.
|
|
|
|
*
|
2017-08-06 14:10:40 -04:00
|
|
|
* The 'max' argument is the maximum value allowed, as the numbers are often
|
|
|
|
* multiplied when later used.
|
|
|
|
*
|
2013-04-30 10:23:39 -04:00
|
|
|
* Since this function gets called with the 'nextarg' pointer from within the
|
|
|
|
* getparameter a lot, we must check it for NULL before accessing the str
|
|
|
|
* data.
|
|
|
|
*/
|
|
|
|
|
2017-08-06 14:10:40 -04:00
|
|
|
static ParameterError str2double(double *val, const char *str, long max)
|
2013-04-30 10:23:39 -04:00
|
|
|
{
|
|
|
|
if(str) {
|
|
|
|
char *endptr;
|
2017-08-06 14:10:40 -04:00
|
|
|
double num;
|
|
|
|
errno = 0;
|
|
|
|
num = strtod(str, &endptr);
|
|
|
|
if(errno == ERANGE)
|
|
|
|
return PARAM_NUMBER_TOO_LARGE;
|
2017-08-09 09:11:17 -04:00
|
|
|
if(num > max) {
|
2017-08-06 14:10:40 -04:00
|
|
|
/* too large */
|
|
|
|
return PARAM_NUMBER_TOO_LARGE;
|
|
|
|
}
|
2013-04-30 10:23:39 -04:00
|
|
|
if((endptr != str) && (endptr == str + strlen(str))) {
|
|
|
|
*val = num;
|
|
|
|
return PARAM_OK; /* Ok */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return PARAM_BAD_NUMERIC; /* badness */
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Parse the string and write the double in the given address. Return PARAM_OK
|
|
|
|
* on success, otherwise a parameter error enum. ONLY ACCEPTS POSITIVE NUMBERS!
|
|
|
|
*
|
2017-08-06 14:10:40 -04:00
|
|
|
* The 'max' argument is the maximum value allowed, as the numbers are often
|
|
|
|
* multiplied when later used.
|
|
|
|
*
|
2013-04-30 10:23:39 -04:00
|
|
|
* Since this function gets called with the 'nextarg' pointer from within the
|
|
|
|
* getparameter a lot, we must check it for NULL before accessing the str
|
|
|
|
* data.
|
|
|
|
*/
|
|
|
|
|
2017-09-15 10:38:48 -04:00
|
|
|
ParameterError str2udouble(double *valp, const char *str, long max)
|
2013-04-30 10:23:39 -04:00
|
|
|
{
|
2017-09-15 10:38:48 -04:00
|
|
|
double value;
|
|
|
|
ParameterError result = str2double(&value, str, max);
|
2013-04-30 10:23:39 -04:00
|
|
|
if(result != PARAM_OK)
|
|
|
|
return result;
|
2017-09-15 10:38:48 -04:00
|
|
|
if(value < 0)
|
2013-04-30 10:23:39 -04:00
|
|
|
return PARAM_NEGATIVE_NUMERIC;
|
|
|
|
|
2017-09-15 10:38:48 -04:00
|
|
|
*valp = value;
|
2013-04-30 10:23:39 -04:00
|
|
|
return PARAM_OK;
|
|
|
|
}
|
|
|
|
|
2011-10-04 18:03:20 -04:00
|
|
|
/*
|
|
|
|
* Parse the string and modify the long in the given address. Return
|
|
|
|
* non-zero on failure, zero on success.
|
|
|
|
*
|
|
|
|
* The string is a list of protocols
|
|
|
|
*
|
|
|
|
* Since this function gets called with the 'nextarg' pointer from within the
|
|
|
|
* getparameter a lot, we must check it for NULL before accessing the str
|
|
|
|
* data.
|
|
|
|
*/
|
|
|
|
|
2014-02-23 07:59:59 -05:00
|
|
|
long proto2num(struct OperationConfig *config, long *val, const char *str)
|
2011-10-04 18:03:20 -04:00
|
|
|
{
|
|
|
|
char *buffer;
|
|
|
|
const char *sep = ",";
|
|
|
|
char *token;
|
|
|
|
|
|
|
|
static struct sprotos {
|
|
|
|
const char *name;
|
|
|
|
long bit;
|
|
|
|
} const protos[] = {
|
|
|
|
{ "all", CURLPROTO_ALL },
|
|
|
|
{ "http", CURLPROTO_HTTP },
|
|
|
|
{ "https", CURLPROTO_HTTPS },
|
|
|
|
{ "ftp", CURLPROTO_FTP },
|
|
|
|
{ "ftps", CURLPROTO_FTPS },
|
|
|
|
{ "scp", CURLPROTO_SCP },
|
|
|
|
{ "sftp", CURLPROTO_SFTP },
|
|
|
|
{ "telnet", CURLPROTO_TELNET },
|
|
|
|
{ "ldap", CURLPROTO_LDAP },
|
|
|
|
{ "ldaps", CURLPROTO_LDAPS },
|
|
|
|
{ "dict", CURLPROTO_DICT },
|
|
|
|
{ "file", CURLPROTO_FILE },
|
|
|
|
{ "tftp", CURLPROTO_TFTP },
|
|
|
|
{ "imap", CURLPROTO_IMAP },
|
|
|
|
{ "imaps", CURLPROTO_IMAPS },
|
|
|
|
{ "pop3", CURLPROTO_POP3 },
|
|
|
|
{ "pop3s", CURLPROTO_POP3S },
|
|
|
|
{ "smtp", CURLPROTO_SMTP },
|
|
|
|
{ "smtps", CURLPROTO_SMTPS },
|
|
|
|
{ "rtsp", CURLPROTO_RTSP },
|
|
|
|
{ "gopher", CURLPROTO_GOPHER },
|
2014-11-30 11:27:03 -05:00
|
|
|
{ "smb", CURLPROTO_SMB },
|
|
|
|
{ "smbs", CURLPROTO_SMBS },
|
2011-10-04 18:03:20 -04:00
|
|
|
{ NULL, 0 }
|
|
|
|
};
|
|
|
|
|
|
|
|
if(!str)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
buffer = strdup(str); /* because strtok corrupts it */
|
2011-10-05 09:06:26 -04:00
|
|
|
if(!buffer)
|
|
|
|
return 1;
|
2011-10-04 18:03:20 -04:00
|
|
|
|
2016-09-07 04:43:40 -04:00
|
|
|
/* Allow strtok() here since this isn't used threaded */
|
|
|
|
/* !checksrc! disable BANNEDFUNC 2 */
|
2011-10-04 18:03:20 -04:00
|
|
|
for(token = strtok(buffer, sep);
|
|
|
|
token;
|
|
|
|
token = strtok(NULL, sep)) {
|
|
|
|
enum e_action { allow, deny, set } action = allow;
|
|
|
|
|
|
|
|
struct sprotos const *pp;
|
|
|
|
|
|
|
|
/* Process token modifiers */
|
|
|
|
while(!ISALNUM(*token)) { /* may be NULL if token is all modifiers */
|
|
|
|
switch (*token++) {
|
|
|
|
case '=':
|
|
|
|
action = set;
|
|
|
|
break;
|
|
|
|
case '-':
|
|
|
|
action = deny;
|
|
|
|
break;
|
|
|
|
case '+':
|
|
|
|
action = allow;
|
|
|
|
break;
|
|
|
|
default: /* Includes case of terminating NULL */
|
|
|
|
Curl_safefree(buffer);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-09 17:09:06 -04:00
|
|
|
for(pp = protos; pp->name; pp++) {
|
2016-10-31 16:49:38 -04:00
|
|
|
if(curl_strequal(token, pp->name)) {
|
2016-12-13 17:34:59 -05:00
|
|
|
switch(action) {
|
2011-10-04 18:03:20 -04:00
|
|
|
case deny:
|
|
|
|
*val &= ~(pp->bit);
|
|
|
|
break;
|
|
|
|
case allow:
|
|
|
|
*val |= pp->bit;
|
|
|
|
break;
|
|
|
|
case set:
|
|
|
|
*val = pp->bit;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!(pp->name)) { /* unknown protocol */
|
|
|
|
/* If they have specified only this protocol, we say treat it as
|
|
|
|
if no protocols are allowed */
|
|
|
|
if(action == set)
|
|
|
|
*val = 0;
|
2015-02-27 15:48:38 -05:00
|
|
|
warnf(config->global, "unrecognized protocol '%s'\n", token);
|
2011-10-04 18:03:20 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
Curl_safefree(buffer);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-08-22 21:49:26 -04:00
|
|
|
/**
|
|
|
|
* Check if the given string is a protocol supported by libcurl
|
|
|
|
*
|
|
|
|
* @param str the protocol name
|
|
|
|
* @return PARAM_OK protocol supported
|
|
|
|
* @return PARAM_LIBCURL_UNSUPPORTED_PROTOCOL protocol not supported
|
|
|
|
* @return PARAM_REQUIRES_PARAMETER missing parameter
|
|
|
|
*/
|
|
|
|
int check_protocol(const char *str)
|
|
|
|
{
|
|
|
|
const char * const *pp;
|
|
|
|
const curl_version_info_data *curlinfo = curl_version_info(CURLVERSION_NOW);
|
|
|
|
if(!str)
|
|
|
|
return PARAM_REQUIRES_PARAMETER;
|
|
|
|
for(pp = curlinfo->protocols; *pp; pp++) {
|
2016-10-31 16:49:38 -04:00
|
|
|
if(curl_strequal(*pp, str))
|
2015-08-22 21:49:26 -04:00
|
|
|
return PARAM_OK;
|
|
|
|
}
|
|
|
|
return PARAM_LIBCURL_UNSUPPORTED_PROTOCOL;
|
|
|
|
}
|
|
|
|
|
2011-10-04 18:03:20 -04:00
|
|
|
/**
|
2012-07-10 17:11:30 -04:00
|
|
|
* Parses the given string looking for an offset (which may be a
|
|
|
|
* larger-than-integer value). The offset CANNOT be negative!
|
2011-10-04 18:03:20 -04:00
|
|
|
*
|
|
|
|
* @param val the offset to populate
|
|
|
|
* @param str the buffer containing the offset
|
2012-11-26 10:23:02 -05:00
|
|
|
* @return PARAM_OK if successful, a parameter specific error enum if failure.
|
2011-10-04 18:03:20 -04:00
|
|
|
*/
|
2012-11-26 10:23:02 -05:00
|
|
|
ParameterError str2offset(curl_off_t *val, const char *str)
|
2011-10-04 18:03:20 -04:00
|
|
|
{
|
2012-07-10 17:11:30 -04:00
|
|
|
char *endptr;
|
|
|
|
if(str[0] == '-')
|
|
|
|
/* offsets aren't negative, this indicates weird input */
|
|
|
|
return PARAM_NEGATIVE_NUMERIC;
|
|
|
|
|
2017-08-12 09:54:06 -04:00
|
|
|
#if(SIZEOF_CURL_OFF_T > SIZEOF_LONG)
|
2017-08-14 17:33:23 -04:00
|
|
|
{
|
|
|
|
CURLofft offt = curlx_strtoofft(str, &endptr, 0, val);
|
|
|
|
if(CURL_OFFT_FLOW == offt)
|
|
|
|
return PARAM_NUMBER_TOO_LARGE;
|
|
|
|
else if(CURL_OFFT_INVAL == offt)
|
|
|
|
return PARAM_BAD_NUMERIC;
|
|
|
|
}
|
2011-10-04 18:03:20 -04:00
|
|
|
#else
|
2017-08-06 14:10:40 -04:00
|
|
|
errno = 0;
|
2012-07-10 17:11:30 -04:00
|
|
|
*val = strtol(str, &endptr, 0);
|
2017-06-19 00:52:38 -04:00
|
|
|
if((*val == LONG_MIN || *val == LONG_MAX) && errno == ERANGE)
|
2017-08-06 14:10:40 -04:00
|
|
|
return PARAM_NUMBER_TOO_LARGE;
|
2011-10-04 18:03:20 -04:00
|
|
|
#endif
|
2012-07-10 17:11:30 -04:00
|
|
|
if((endptr != str) && (endptr == str + strlen(str)))
|
2012-11-26 10:23:02 -05:00
|
|
|
return PARAM_OK;
|
2012-07-10 17:11:30 -04:00
|
|
|
|
|
|
|
return PARAM_BAD_NUMERIC;
|
2011-10-04 18:03:20 -04:00
|
|
|
}
|
|
|
|
|
2014-02-20 18:18:48 -05:00
|
|
|
static CURLcode checkpasswd(const char *kind, /* for what purpose */
|
|
|
|
const size_t i, /* operation index */
|
|
|
|
const bool last, /* TRUE if last operation */
|
2014-02-14 16:59:51 -05:00
|
|
|
char **userpwd) /* pointer to allocated string */
|
2011-10-04 18:03:20 -04:00
|
|
|
{
|
2013-04-20 03:51:16 -04:00
|
|
|
char *psep;
|
|
|
|
char *osep;
|
2011-10-05 09:06:26 -04:00
|
|
|
|
2011-10-04 18:03:20 -04:00
|
|
|
if(!*userpwd)
|
2014-01-19 11:14:09 -05:00
|
|
|
return CURLE_OK;
|
2011-10-04 18:03:20 -04:00
|
|
|
|
2013-04-20 03:51:16 -04:00
|
|
|
/* Attempt to find the password separator */
|
|
|
|
psep = strchr(*userpwd, ':');
|
|
|
|
|
|
|
|
/* Attempt to find the options separator */
|
|
|
|
osep = strchr(*userpwd, ';');
|
|
|
|
|
|
|
|
if(!psep && **userpwd != ';') {
|
2011-10-04 18:03:20 -04:00
|
|
|
/* no password present, prompt for one */
|
2011-10-05 09:06:26 -04:00
|
|
|
char passwd[256] = "";
|
2011-10-04 18:03:20 -04:00
|
|
|
char prompt[256];
|
|
|
|
size_t passwdlen;
|
|
|
|
size_t userlen = strlen(*userpwd);
|
|
|
|
char *passptr;
|
|
|
|
|
2013-04-20 03:51:16 -04:00
|
|
|
if(osep)
|
|
|
|
*osep = '\0';
|
|
|
|
|
2011-10-04 18:03:20 -04:00
|
|
|
/* build a nice-looking prompt */
|
2014-02-20 18:18:48 -05:00
|
|
|
if(!i && last)
|
2014-02-16 06:10:09 -05:00
|
|
|
curlx_msnprintf(prompt, sizeof(prompt),
|
|
|
|
"Enter %s password for user '%s':",
|
|
|
|
kind, *userpwd);
|
|
|
|
else
|
|
|
|
curlx_msnprintf(prompt, sizeof(prompt),
|
2018-09-16 16:04:49 -04:00
|
|
|
"Enter %s password for user '%s' on URL #%zu:",
|
|
|
|
kind, *userpwd, i + 1);
|
2011-10-04 18:03:20 -04:00
|
|
|
|
|
|
|
/* get password */
|
|
|
|
getpass_r(prompt, passwd, sizeof(passwd));
|
|
|
|
passwdlen = strlen(passwd);
|
|
|
|
|
2013-04-20 03:51:16 -04:00
|
|
|
if(osep)
|
|
|
|
*osep = ';';
|
|
|
|
|
2011-10-04 18:03:20 -04:00
|
|
|
/* extend the allocated memory area to fit the password too */
|
|
|
|
passptr = realloc(*userpwd,
|
|
|
|
passwdlen + 1 + /* an extra for the colon */
|
|
|
|
userlen + 1); /* an extra for the zero */
|
2011-10-05 09:06:26 -04:00
|
|
|
if(!passptr)
|
2014-01-19 11:14:09 -05:00
|
|
|
return CURLE_OUT_OF_MEMORY;
|
2011-10-04 18:03:20 -04:00
|
|
|
|
2011-10-05 09:06:26 -04:00
|
|
|
/* append the password separated with a colon */
|
|
|
|
passptr[userlen] = ':';
|
2017-09-09 17:55:08 -04:00
|
|
|
memcpy(&passptr[userlen + 1], passwd, passwdlen + 1);
|
2011-10-05 09:06:26 -04:00
|
|
|
*userpwd = passptr;
|
2011-10-04 18:03:20 -04:00
|
|
|
}
|
2014-01-19 11:14:09 -05:00
|
|
|
|
|
|
|
return CURLE_OK;
|
2011-10-04 18:03:20 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
ParameterError add2list(struct curl_slist **list, const char *ptr)
|
|
|
|
{
|
|
|
|
struct curl_slist *newlist = curl_slist_append(*list, ptr);
|
|
|
|
if(newlist)
|
|
|
|
*list = newlist;
|
|
|
|
else
|
|
|
|
return PARAM_NO_MEM;
|
|
|
|
|
|
|
|
return PARAM_OK;
|
|
|
|
}
|
|
|
|
|
2014-02-23 07:59:59 -05:00
|
|
|
int ftpfilemethod(struct OperationConfig *config, const char *str)
|
2011-10-04 18:03:20 -04:00
|
|
|
{
|
2016-10-31 16:49:38 -04:00
|
|
|
if(curl_strequal("singlecwd", str))
|
2011-10-04 18:03:20 -04:00
|
|
|
return CURLFTPMETHOD_SINGLECWD;
|
2016-10-31 16:49:38 -04:00
|
|
|
if(curl_strequal("nocwd", str))
|
2011-10-04 18:03:20 -04:00
|
|
|
return CURLFTPMETHOD_NOCWD;
|
2016-10-31 16:49:38 -04:00
|
|
|
if(curl_strequal("multicwd", str))
|
2011-10-04 18:03:20 -04:00
|
|
|
return CURLFTPMETHOD_MULTICWD;
|
2015-02-27 15:48:38 -05:00
|
|
|
|
|
|
|
warnf(config->global, "unrecognized ftp file method '%s', using default\n",
|
|
|
|
str);
|
|
|
|
|
2011-10-04 18:03:20 -04:00
|
|
|
return CURLFTPMETHOD_MULTICWD;
|
|
|
|
}
|
|
|
|
|
2014-02-23 07:59:59 -05:00
|
|
|
int ftpcccmethod(struct OperationConfig *config, const char *str)
|
2011-10-04 18:03:20 -04:00
|
|
|
{
|
2016-10-31 16:49:38 -04:00
|
|
|
if(curl_strequal("passive", str))
|
2011-10-04 18:03:20 -04:00
|
|
|
return CURLFTPSSL_CCC_PASSIVE;
|
2016-10-31 16:49:38 -04:00
|
|
|
if(curl_strequal("active", str))
|
2011-10-04 18:03:20 -04:00
|
|
|
return CURLFTPSSL_CCC_ACTIVE;
|
2015-02-27 15:48:38 -05:00
|
|
|
|
|
|
|
warnf(config->global, "unrecognized ftp CCC method '%s', using default\n",
|
|
|
|
str);
|
|
|
|
|
2011-10-04 18:03:20 -04:00
|
|
|
return CURLFTPSSL_CCC_PASSIVE;
|
|
|
|
}
|
|
|
|
|
2019-04-13 17:00:45 -04:00
|
|
|
long delegation(struct OperationConfig *config, const char *str)
|
2011-10-04 18:03:20 -04:00
|
|
|
{
|
2016-10-31 16:49:38 -04:00
|
|
|
if(curl_strequal("none", str))
|
2011-10-04 18:03:20 -04:00
|
|
|
return CURLGSSAPI_DELEGATION_NONE;
|
2016-10-31 16:49:38 -04:00
|
|
|
if(curl_strequal("policy", str))
|
2011-10-04 18:03:20 -04:00
|
|
|
return CURLGSSAPI_DELEGATION_POLICY_FLAG;
|
2016-10-31 16:49:38 -04:00
|
|
|
if(curl_strequal("always", str))
|
2011-10-04 18:03:20 -04:00
|
|
|
return CURLGSSAPI_DELEGATION_FLAG;
|
2015-02-27 15:48:38 -05:00
|
|
|
|
|
|
|
warnf(config->global, "unrecognized delegation method '%s', using none\n",
|
|
|
|
str);
|
|
|
|
|
2011-10-04 18:03:20 -04:00
|
|
|
return CURLGSSAPI_DELEGATION_NONE;
|
|
|
|
}
|
|
|
|
|
2014-02-14 16:59:51 -05:00
|
|
|
/*
|
|
|
|
* my_useragent: returns allocated string with default user agent
|
|
|
|
*/
|
|
|
|
static char *my_useragent(void)
|
|
|
|
{
|
|
|
|
return strdup(CURL_NAME "/" CURL_VERSION);
|
|
|
|
}
|
|
|
|
|
2014-02-23 07:59:59 -05:00
|
|
|
CURLcode get_args(struct OperationConfig *config, const size_t i)
|
2014-02-14 16:59:51 -05:00
|
|
|
{
|
|
|
|
CURLcode result = CURLE_OK;
|
2014-02-16 06:10:09 -05:00
|
|
|
bool last = (config->next ? FALSE : TRUE);
|
2014-02-14 16:59:51 -05:00
|
|
|
|
|
|
|
/* Check we have a password for the given host user */
|
2015-09-04 02:11:09 -04:00
|
|
|
if(config->userpwd && !config->oauth_bearer) {
|
2014-02-20 18:18:48 -05:00
|
|
|
result = checkpasswd("host", i, last, &config->userpwd);
|
2014-02-14 16:59:51 -05:00
|
|
|
if(result)
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check we have a password for the given proxy user */
|
|
|
|
if(config->proxyuserpwd) {
|
2014-02-20 18:18:48 -05:00
|
|
|
result = checkpasswd("proxy", i, last, &config->proxyuserpwd);
|
2014-02-14 16:59:51 -05:00
|
|
|
if(result)
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check we have a user agent */
|
|
|
|
if(!config->useragent) {
|
|
|
|
config->useragent = my_useragent();
|
|
|
|
if(!config->useragent) {
|
2019-12-09 10:15:37 -05:00
|
|
|
errorf(config->global, "out of memory\n");
|
2014-02-14 16:59:51 -05:00
|
|
|
result = CURLE_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
2016-12-13 15:10:00 -05:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Parse the string and modify ssl_version in the val argument. Return PARAM_OK
|
|
|
|
* on success, otherwise a parameter error enum. ONLY ACCEPTS POSITIVE NUMBERS!
|
|
|
|
*
|
|
|
|
* Since this function gets called with the 'nextarg' pointer from within the
|
|
|
|
* getparameter a lot, we must check it for NULL before accessing the str
|
|
|
|
* data.
|
|
|
|
*/
|
|
|
|
|
|
|
|
ParameterError str2tls_max(long *val, const char *str)
|
|
|
|
{
|
|
|
|
static struct s_tls_max {
|
|
|
|
const char *tls_max_str;
|
|
|
|
long tls_max;
|
|
|
|
} const tls_max_array[] = {
|
|
|
|
{ "default", CURL_SSLVERSION_MAX_DEFAULT },
|
|
|
|
{ "1.0", CURL_SSLVERSION_MAX_TLSv1_0 },
|
|
|
|
{ "1.1", CURL_SSLVERSION_MAX_TLSv1_1 },
|
|
|
|
{ "1.2", CURL_SSLVERSION_MAX_TLSv1_2 },
|
|
|
|
{ "1.3", CURL_SSLVERSION_MAX_TLSv1_3 }
|
|
|
|
};
|
|
|
|
size_t i = 0;
|
|
|
|
if(!str)
|
|
|
|
return PARAM_REQUIRES_PARAMETER;
|
|
|
|
for(i = 0; i < sizeof(tls_max_array)/sizeof(tls_max_array[0]); i++) {
|
|
|
|
if(!strcmp(str, tls_max_array[i].tls_max_str)) {
|
|
|
|
*val = tls_max_array[i].tls_max;
|
|
|
|
return PARAM_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return PARAM_BAD_USE;
|
|
|
|
}
|