xref: /aosp_15_r20/external/curl/src/tool_paramhlp.c (revision 6236dae45794135f37c4eb022389c904c8b0090d)
1*6236dae4SAndroid Build Coastguard Worker /***************************************************************************
2*6236dae4SAndroid Build Coastguard Worker  *                                  _   _ ____  _
3*6236dae4SAndroid Build Coastguard Worker  *  Project                     ___| | | |  _ \| |
4*6236dae4SAndroid Build Coastguard Worker  *                             / __| | | | |_) | |
5*6236dae4SAndroid Build Coastguard Worker  *                            | (__| |_| |  _ <| |___
6*6236dae4SAndroid Build Coastguard Worker  *                             \___|\___/|_| \_\_____|
7*6236dae4SAndroid Build Coastguard Worker  *
8*6236dae4SAndroid Build Coastguard Worker  * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
9*6236dae4SAndroid Build Coastguard Worker  *
10*6236dae4SAndroid Build Coastguard Worker  * This software is licensed as described in the file COPYING, which
11*6236dae4SAndroid Build Coastguard Worker  * you should have received as part of this distribution. The terms
12*6236dae4SAndroid Build Coastguard Worker  * are also available at https://curl.se/docs/copyright.html.
13*6236dae4SAndroid Build Coastguard Worker  *
14*6236dae4SAndroid Build Coastguard Worker  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15*6236dae4SAndroid Build Coastguard Worker  * copies of the Software, and permit persons to whom the Software is
16*6236dae4SAndroid Build Coastguard Worker  * furnished to do so, under the terms of the COPYING file.
17*6236dae4SAndroid Build Coastguard Worker  *
18*6236dae4SAndroid Build Coastguard Worker  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19*6236dae4SAndroid Build Coastguard Worker  * KIND, either express or implied.
20*6236dae4SAndroid Build Coastguard Worker  *
21*6236dae4SAndroid Build Coastguard Worker  * SPDX-License-Identifier: curl
22*6236dae4SAndroid Build Coastguard Worker  *
23*6236dae4SAndroid Build Coastguard Worker  ***************************************************************************/
24*6236dae4SAndroid Build Coastguard Worker #include "tool_setup.h"
25*6236dae4SAndroid Build Coastguard Worker 
26*6236dae4SAndroid Build Coastguard Worker #include "strcase.h"
27*6236dae4SAndroid Build Coastguard Worker 
28*6236dae4SAndroid Build Coastguard Worker #include "curlx.h"
29*6236dae4SAndroid Build Coastguard Worker 
30*6236dae4SAndroid Build Coastguard Worker #include "tool_cfgable.h"
31*6236dae4SAndroid Build Coastguard Worker #include "tool_getparam.h"
32*6236dae4SAndroid Build Coastguard Worker #include "tool_getpass.h"
33*6236dae4SAndroid Build Coastguard Worker #include "tool_msgs.h"
34*6236dae4SAndroid Build Coastguard Worker #include "tool_paramhlp.h"
35*6236dae4SAndroid Build Coastguard Worker #include "tool_libinfo.h"
36*6236dae4SAndroid Build Coastguard Worker #include "tool_util.h"
37*6236dae4SAndroid Build Coastguard Worker #include "tool_version.h"
38*6236dae4SAndroid Build Coastguard Worker #include "dynbuf.h"
39*6236dae4SAndroid Build Coastguard Worker 
40*6236dae4SAndroid Build Coastguard Worker #include "memdebug.h" /* keep this as LAST include */
41*6236dae4SAndroid Build Coastguard Worker 
new_getout(struct OperationConfig * config)42*6236dae4SAndroid Build Coastguard Worker struct getout *new_getout(struct OperationConfig *config)
43*6236dae4SAndroid Build Coastguard Worker {
44*6236dae4SAndroid Build Coastguard Worker   struct getout *node = calloc(1, sizeof(struct getout));
45*6236dae4SAndroid Build Coastguard Worker   struct getout *last = config->url_last;
46*6236dae4SAndroid Build Coastguard Worker   if(node) {
47*6236dae4SAndroid Build Coastguard Worker     static int outnum = 0;
48*6236dae4SAndroid Build Coastguard Worker 
49*6236dae4SAndroid Build Coastguard Worker     /* append this new node last in the list */
50*6236dae4SAndroid Build Coastguard Worker     if(last)
51*6236dae4SAndroid Build Coastguard Worker       last->next = node;
52*6236dae4SAndroid Build Coastguard Worker     else
53*6236dae4SAndroid Build Coastguard Worker       config->url_list = node; /* first node */
54*6236dae4SAndroid Build Coastguard Worker 
55*6236dae4SAndroid Build Coastguard Worker     /* move the last pointer */
56*6236dae4SAndroid Build Coastguard Worker     config->url_last = node;
57*6236dae4SAndroid Build Coastguard Worker 
58*6236dae4SAndroid Build Coastguard Worker     node->flags = config->default_node_flags;
59*6236dae4SAndroid Build Coastguard Worker     node->num = outnum++;
60*6236dae4SAndroid Build Coastguard Worker   }
61*6236dae4SAndroid Build Coastguard Worker   return node;
62*6236dae4SAndroid Build Coastguard Worker }
63*6236dae4SAndroid Build Coastguard Worker 
64*6236dae4SAndroid Build Coastguard Worker #define ISCRLF(x) (((x) == '\r') || ((x) == '\n') || ((x) == '\0'))
65*6236dae4SAndroid Build Coastguard Worker 
66*6236dae4SAndroid Build Coastguard Worker /* memcrlf() has two modes. Both operate on a given memory area with
67*6236dae4SAndroid Build Coastguard Worker    a specified size.
68*6236dae4SAndroid Build Coastguard Worker 
69*6236dae4SAndroid Build Coastguard Worker    countcrlf FALSE - return number of bytes from the start that DO NOT include
70*6236dae4SAndroid Build Coastguard Worker    any CR or LF or NULL
71*6236dae4SAndroid Build Coastguard Worker 
72*6236dae4SAndroid Build Coastguard Worker    countcrlf TRUE - return number of bytes from the start that are ONLY CR or
73*6236dae4SAndroid Build Coastguard Worker    LF or NULL.
74*6236dae4SAndroid Build Coastguard Worker 
75*6236dae4SAndroid Build Coastguard Worker */
memcrlf(char * orig,bool countcrlf,size_t max)76*6236dae4SAndroid Build Coastguard Worker static size_t memcrlf(char *orig,
77*6236dae4SAndroid Build Coastguard Worker                       bool countcrlf, /* TRUE if we count CRLF, FALSE
78*6236dae4SAndroid Build Coastguard Worker                                          if we count non-CRLF */
79*6236dae4SAndroid Build Coastguard Worker                       size_t max)
80*6236dae4SAndroid Build Coastguard Worker {
81*6236dae4SAndroid Build Coastguard Worker   char *ptr;
82*6236dae4SAndroid Build Coastguard Worker   size_t total = max;
83*6236dae4SAndroid Build Coastguard Worker   for(ptr = orig; max; max--, ptr++) {
84*6236dae4SAndroid Build Coastguard Worker     bool crlf = ISCRLF(*ptr);
85*6236dae4SAndroid Build Coastguard Worker     if(countcrlf ^ crlf)
86*6236dae4SAndroid Build Coastguard Worker       return ptr - orig;
87*6236dae4SAndroid Build Coastguard Worker   }
88*6236dae4SAndroid Build Coastguard Worker   return total; /* no delimiter found */
89*6236dae4SAndroid Build Coastguard Worker }
90*6236dae4SAndroid Build Coastguard Worker 
91*6236dae4SAndroid Build Coastguard Worker #define MAX_FILE2STRING MAX_FILE2MEMORY
92*6236dae4SAndroid Build Coastguard Worker 
file2string(char ** bufp,FILE * file)93*6236dae4SAndroid Build Coastguard Worker ParameterError file2string(char **bufp, FILE *file)
94*6236dae4SAndroid Build Coastguard Worker {
95*6236dae4SAndroid Build Coastguard Worker   struct curlx_dynbuf dyn;
96*6236dae4SAndroid Build Coastguard Worker   curlx_dyn_init(&dyn, MAX_FILE2STRING);
97*6236dae4SAndroid Build Coastguard Worker   if(file) {
98*6236dae4SAndroid Build Coastguard Worker     do {
99*6236dae4SAndroid Build Coastguard Worker       char buffer[4096];
100*6236dae4SAndroid Build Coastguard Worker       char *ptr;
101*6236dae4SAndroid Build Coastguard Worker       size_t nread = fread(buffer, 1, sizeof(buffer), file);
102*6236dae4SAndroid Build Coastguard Worker       if(ferror(file)) {
103*6236dae4SAndroid Build Coastguard Worker         curlx_dyn_free(&dyn);
104*6236dae4SAndroid Build Coastguard Worker         *bufp = NULL;
105*6236dae4SAndroid Build Coastguard Worker         return PARAM_READ_ERROR;
106*6236dae4SAndroid Build Coastguard Worker       }
107*6236dae4SAndroid Build Coastguard Worker       ptr = buffer;
108*6236dae4SAndroid Build Coastguard Worker       while(nread) {
109*6236dae4SAndroid Build Coastguard Worker         size_t nlen = memcrlf(ptr, FALSE, nread);
110*6236dae4SAndroid Build Coastguard Worker         if(curlx_dyn_addn(&dyn, ptr, nlen))
111*6236dae4SAndroid Build Coastguard Worker           return PARAM_NO_MEM;
112*6236dae4SAndroid Build Coastguard Worker         nread -= nlen;
113*6236dae4SAndroid Build Coastguard Worker 
114*6236dae4SAndroid Build Coastguard Worker         if(nread) {
115*6236dae4SAndroid Build Coastguard Worker           ptr += nlen;
116*6236dae4SAndroid Build Coastguard Worker           nlen = memcrlf(ptr, TRUE, nread);
117*6236dae4SAndroid Build Coastguard Worker           ptr += nlen;
118*6236dae4SAndroid Build Coastguard Worker           nread -= nlen;
119*6236dae4SAndroid Build Coastguard Worker         }
120*6236dae4SAndroid Build Coastguard Worker       }
121*6236dae4SAndroid Build Coastguard Worker     } while(!feof(file));
122*6236dae4SAndroid Build Coastguard Worker   }
123*6236dae4SAndroid Build Coastguard Worker   *bufp = curlx_dyn_ptr(&dyn);
124*6236dae4SAndroid Build Coastguard Worker   return PARAM_OK;
125*6236dae4SAndroid Build Coastguard Worker }
126*6236dae4SAndroid Build Coastguard Worker 
file2memory(char ** bufp,size_t * size,FILE * file)127*6236dae4SAndroid Build Coastguard Worker ParameterError file2memory(char **bufp, size_t *size, FILE *file)
128*6236dae4SAndroid Build Coastguard Worker {
129*6236dae4SAndroid Build Coastguard Worker   if(file) {
130*6236dae4SAndroid Build Coastguard Worker     size_t nread;
131*6236dae4SAndroid Build Coastguard Worker     struct curlx_dynbuf dyn;
132*6236dae4SAndroid Build Coastguard Worker     /* The size needs to fit in an int later */
133*6236dae4SAndroid Build Coastguard Worker     curlx_dyn_init(&dyn, MAX_FILE2MEMORY);
134*6236dae4SAndroid Build Coastguard Worker     do {
135*6236dae4SAndroid Build Coastguard Worker       char buffer[4096];
136*6236dae4SAndroid Build Coastguard Worker       nread = fread(buffer, 1, sizeof(buffer), file);
137*6236dae4SAndroid Build Coastguard Worker       if(ferror(file)) {
138*6236dae4SAndroid Build Coastguard Worker         curlx_dyn_free(&dyn);
139*6236dae4SAndroid Build Coastguard Worker         *size = 0;
140*6236dae4SAndroid Build Coastguard Worker         *bufp = NULL;
141*6236dae4SAndroid Build Coastguard Worker         return PARAM_READ_ERROR;
142*6236dae4SAndroid Build Coastguard Worker       }
143*6236dae4SAndroid Build Coastguard Worker       if(nread)
144*6236dae4SAndroid Build Coastguard Worker         if(curlx_dyn_addn(&dyn, buffer, nread))
145*6236dae4SAndroid Build Coastguard Worker           return PARAM_NO_MEM;
146*6236dae4SAndroid Build Coastguard Worker     } while(!feof(file));
147*6236dae4SAndroid Build Coastguard Worker     *size = curlx_dyn_len(&dyn);
148*6236dae4SAndroid Build Coastguard Worker     *bufp = curlx_dyn_ptr(&dyn);
149*6236dae4SAndroid Build Coastguard Worker   }
150*6236dae4SAndroid Build Coastguard Worker   else {
151*6236dae4SAndroid Build Coastguard Worker     *size = 0;
152*6236dae4SAndroid Build Coastguard Worker     *bufp = NULL;
153*6236dae4SAndroid Build Coastguard Worker   }
154*6236dae4SAndroid Build Coastguard Worker   return PARAM_OK;
155*6236dae4SAndroid Build Coastguard Worker }
156*6236dae4SAndroid Build Coastguard Worker 
157*6236dae4SAndroid Build Coastguard Worker /*
158*6236dae4SAndroid Build Coastguard Worker  * Parse the string and write the long in the given address. Return PARAM_OK
159*6236dae4SAndroid Build Coastguard Worker  * on success, otherwise a parameter specific error enum.
160*6236dae4SAndroid Build Coastguard Worker  *
161*6236dae4SAndroid Build Coastguard Worker  * Since this function gets called with the 'nextarg' pointer from within the
162*6236dae4SAndroid Build Coastguard Worker  * getparameter a lot, we must check it for NULL before accessing the str
163*6236dae4SAndroid Build Coastguard Worker  * data.
164*6236dae4SAndroid Build Coastguard Worker  */
getnum(long * val,const char * str,int base)165*6236dae4SAndroid Build Coastguard Worker static ParameterError getnum(long *val, const char *str, int base)
166*6236dae4SAndroid Build Coastguard Worker {
167*6236dae4SAndroid Build Coastguard Worker   if(str) {
168*6236dae4SAndroid Build Coastguard Worker     char *endptr = NULL;
169*6236dae4SAndroid Build Coastguard Worker     long num;
170*6236dae4SAndroid Build Coastguard Worker     if(!str[0])
171*6236dae4SAndroid Build Coastguard Worker       return PARAM_BLANK_STRING;
172*6236dae4SAndroid Build Coastguard Worker     errno = 0;
173*6236dae4SAndroid Build Coastguard Worker     num = strtol(str, &endptr, base);
174*6236dae4SAndroid Build Coastguard Worker     if(errno == ERANGE)
175*6236dae4SAndroid Build Coastguard Worker       return PARAM_NUMBER_TOO_LARGE;
176*6236dae4SAndroid Build Coastguard Worker     if((endptr != str) && (*endptr == '\0')) {
177*6236dae4SAndroid Build Coastguard Worker       *val = num;
178*6236dae4SAndroid Build Coastguard Worker       return PARAM_OK;  /* Ok */
179*6236dae4SAndroid Build Coastguard Worker     }
180*6236dae4SAndroid Build Coastguard Worker   }
181*6236dae4SAndroid Build Coastguard Worker   return PARAM_BAD_NUMERIC; /* badness */
182*6236dae4SAndroid Build Coastguard Worker }
183*6236dae4SAndroid Build Coastguard Worker 
str2num(long * val,const char * str)184*6236dae4SAndroid Build Coastguard Worker ParameterError str2num(long *val, const char *str)
185*6236dae4SAndroid Build Coastguard Worker {
186*6236dae4SAndroid Build Coastguard Worker   return getnum(val, str, 10);
187*6236dae4SAndroid Build Coastguard Worker }
188*6236dae4SAndroid Build Coastguard Worker 
oct2nummax(long * val,const char * str,long max)189*6236dae4SAndroid Build Coastguard Worker ParameterError oct2nummax(long *val, const char *str, long max)
190*6236dae4SAndroid Build Coastguard Worker {
191*6236dae4SAndroid Build Coastguard Worker   ParameterError result = getnum(val, str, 8);
192*6236dae4SAndroid Build Coastguard Worker   if(result != PARAM_OK)
193*6236dae4SAndroid Build Coastguard Worker     return result;
194*6236dae4SAndroid Build Coastguard Worker   else if(*val > max)
195*6236dae4SAndroid Build Coastguard Worker     return PARAM_NUMBER_TOO_LARGE;
196*6236dae4SAndroid Build Coastguard Worker   else if(*val < 0)
197*6236dae4SAndroid Build Coastguard Worker     return PARAM_NEGATIVE_NUMERIC;
198*6236dae4SAndroid Build Coastguard Worker 
199*6236dae4SAndroid Build Coastguard Worker   return PARAM_OK;
200*6236dae4SAndroid Build Coastguard Worker }
201*6236dae4SAndroid Build Coastguard Worker 
202*6236dae4SAndroid Build Coastguard Worker /*
203*6236dae4SAndroid Build Coastguard Worker  * Parse the string and write the long in the given address. Return PARAM_OK
204*6236dae4SAndroid Build Coastguard Worker  * on success, otherwise a parameter error enum. ONLY ACCEPTS POSITIVE NUMBERS!
205*6236dae4SAndroid Build Coastguard Worker  *
206*6236dae4SAndroid Build Coastguard Worker  * Since this function gets called with the 'nextarg' pointer from within the
207*6236dae4SAndroid Build Coastguard Worker  * getparameter a lot, we must check it for NULL before accessing the str
208*6236dae4SAndroid Build Coastguard Worker  * data.
209*6236dae4SAndroid Build Coastguard Worker  */
210*6236dae4SAndroid Build Coastguard Worker 
str2unum(long * val,const char * str)211*6236dae4SAndroid Build Coastguard Worker ParameterError str2unum(long *val, const char *str)
212*6236dae4SAndroid Build Coastguard Worker {
213*6236dae4SAndroid Build Coastguard Worker   ParameterError result = getnum(val, str, 10);
214*6236dae4SAndroid Build Coastguard Worker   if(result != PARAM_OK)
215*6236dae4SAndroid Build Coastguard Worker     return result;
216*6236dae4SAndroid Build Coastguard Worker   if(*val < 0)
217*6236dae4SAndroid Build Coastguard Worker     return PARAM_NEGATIVE_NUMERIC;
218*6236dae4SAndroid Build Coastguard Worker 
219*6236dae4SAndroid Build Coastguard Worker   return PARAM_OK;
220*6236dae4SAndroid Build Coastguard Worker }
221*6236dae4SAndroid Build Coastguard Worker 
222*6236dae4SAndroid Build Coastguard Worker /*
223*6236dae4SAndroid Build Coastguard Worker  * Parse the string and write the long in the given address if it is below the
224*6236dae4SAndroid Build Coastguard Worker  * maximum allowed value. Return PARAM_OK on success, otherwise a parameter
225*6236dae4SAndroid Build Coastguard Worker  * error enum. ONLY ACCEPTS POSITIVE NUMBERS!
226*6236dae4SAndroid Build Coastguard Worker  *
227*6236dae4SAndroid Build Coastguard Worker  * Since this function gets called with the 'nextarg' pointer from within the
228*6236dae4SAndroid Build Coastguard Worker  * getparameter a lot, we must check it for NULL before accessing the str
229*6236dae4SAndroid Build Coastguard Worker  * data.
230*6236dae4SAndroid Build Coastguard Worker  */
231*6236dae4SAndroid Build Coastguard Worker 
str2unummax(long * val,const char * str,long max)232*6236dae4SAndroid Build Coastguard Worker ParameterError str2unummax(long *val, const char *str, long max)
233*6236dae4SAndroid Build Coastguard Worker {
234*6236dae4SAndroid Build Coastguard Worker   ParameterError result = str2unum(val, str);
235*6236dae4SAndroid Build Coastguard Worker   if(result != PARAM_OK)
236*6236dae4SAndroid Build Coastguard Worker     return result;
237*6236dae4SAndroid Build Coastguard Worker   if(*val > max)
238*6236dae4SAndroid Build Coastguard Worker     return PARAM_NUMBER_TOO_LARGE;
239*6236dae4SAndroid Build Coastguard Worker 
240*6236dae4SAndroid Build Coastguard Worker   return PARAM_OK;
241*6236dae4SAndroid Build Coastguard Worker }
242*6236dae4SAndroid Build Coastguard Worker 
243*6236dae4SAndroid Build Coastguard Worker 
244*6236dae4SAndroid Build Coastguard Worker /*
245*6236dae4SAndroid Build Coastguard Worker  * Parse the string and write the double in the given address. Return PARAM_OK
246*6236dae4SAndroid Build Coastguard Worker  * on success, otherwise a parameter specific error enum.
247*6236dae4SAndroid Build Coastguard Worker  *
248*6236dae4SAndroid Build Coastguard Worker  * The 'max' argument is the maximum value allowed, as the numbers are often
249*6236dae4SAndroid Build Coastguard Worker  * multiplied when later used.
250*6236dae4SAndroid Build Coastguard Worker  *
251*6236dae4SAndroid Build Coastguard Worker  * Since this function gets called with the 'nextarg' pointer from within the
252*6236dae4SAndroid Build Coastguard Worker  * getparameter a lot, we must check it for NULL before accessing the str
253*6236dae4SAndroid Build Coastguard Worker  * data.
254*6236dae4SAndroid Build Coastguard Worker  */
255*6236dae4SAndroid Build Coastguard Worker 
str2double(double * val,const char * str,double max)256*6236dae4SAndroid Build Coastguard Worker static ParameterError str2double(double *val, const char *str, double max)
257*6236dae4SAndroid Build Coastguard Worker {
258*6236dae4SAndroid Build Coastguard Worker   if(str) {
259*6236dae4SAndroid Build Coastguard Worker     char *endptr;
260*6236dae4SAndroid Build Coastguard Worker     double num;
261*6236dae4SAndroid Build Coastguard Worker     errno = 0;
262*6236dae4SAndroid Build Coastguard Worker     num = strtod(str, &endptr);
263*6236dae4SAndroid Build Coastguard Worker     if(errno == ERANGE)
264*6236dae4SAndroid Build Coastguard Worker       return PARAM_NUMBER_TOO_LARGE;
265*6236dae4SAndroid Build Coastguard Worker     if(num > max) {
266*6236dae4SAndroid Build Coastguard Worker       /* too large */
267*6236dae4SAndroid Build Coastguard Worker       return PARAM_NUMBER_TOO_LARGE;
268*6236dae4SAndroid Build Coastguard Worker     }
269*6236dae4SAndroid Build Coastguard Worker     if((endptr != str) && (endptr == str + strlen(str))) {
270*6236dae4SAndroid Build Coastguard Worker       *val = num;
271*6236dae4SAndroid Build Coastguard Worker       return PARAM_OK;  /* Ok */
272*6236dae4SAndroid Build Coastguard Worker     }
273*6236dae4SAndroid Build Coastguard Worker   }
274*6236dae4SAndroid Build Coastguard Worker   return PARAM_BAD_NUMERIC; /* badness */
275*6236dae4SAndroid Build Coastguard Worker }
276*6236dae4SAndroid Build Coastguard Worker 
277*6236dae4SAndroid Build Coastguard Worker /*
278*6236dae4SAndroid Build Coastguard Worker  * Parse the string as seconds with decimals, and write the number of
279*6236dae4SAndroid Build Coastguard Worker  * milliseconds that corresponds in the given address. Return PARAM_OK on
280*6236dae4SAndroid Build Coastguard Worker  * success, otherwise a parameter error enum. ONLY ACCEPTS POSITIVE NUMBERS!
281*6236dae4SAndroid Build Coastguard Worker  *
282*6236dae4SAndroid Build Coastguard Worker  * The 'max' argument is the maximum value allowed, as the numbers are often
283*6236dae4SAndroid Build Coastguard Worker  * multiplied when later used.
284*6236dae4SAndroid Build Coastguard Worker  *
285*6236dae4SAndroid Build Coastguard Worker  * Since this function gets called with the 'nextarg' pointer from within the
286*6236dae4SAndroid Build Coastguard Worker  * getparameter a lot, we must check it for NULL before accessing the str
287*6236dae4SAndroid Build Coastguard Worker  * data.
288*6236dae4SAndroid Build Coastguard Worker  */
289*6236dae4SAndroid Build Coastguard Worker 
secs2ms(long * valp,const char * str)290*6236dae4SAndroid Build Coastguard Worker ParameterError secs2ms(long *valp, const char *str)
291*6236dae4SAndroid Build Coastguard Worker {
292*6236dae4SAndroid Build Coastguard Worker   double value;
293*6236dae4SAndroid Build Coastguard Worker   ParameterError result = str2double(&value, str, (double)LONG_MAX/1000);
294*6236dae4SAndroid Build Coastguard Worker   if(result != PARAM_OK)
295*6236dae4SAndroid Build Coastguard Worker     return result;
296*6236dae4SAndroid Build Coastguard Worker   if(value < 0)
297*6236dae4SAndroid Build Coastguard Worker     return PARAM_NEGATIVE_NUMERIC;
298*6236dae4SAndroid Build Coastguard Worker 
299*6236dae4SAndroid Build Coastguard Worker   *valp = (long)(value*1000);
300*6236dae4SAndroid Build Coastguard Worker   return PARAM_OK;
301*6236dae4SAndroid Build Coastguard Worker }
302*6236dae4SAndroid Build Coastguard Worker 
303*6236dae4SAndroid Build Coastguard Worker /*
304*6236dae4SAndroid Build Coastguard Worker  * Implement protocol sets in null-terminated array of protocol name pointers.
305*6236dae4SAndroid Build Coastguard Worker  */
306*6236dae4SAndroid Build Coastguard Worker 
307*6236dae4SAndroid Build Coastguard Worker /* Return index of prototype token in set, card(set) if not found.
308*6236dae4SAndroid Build Coastguard Worker    Can be called with proto == NULL to get card(set). */
protoset_index(const char * const * protoset,const char * proto)309*6236dae4SAndroid Build Coastguard Worker static size_t protoset_index(const char * const *protoset, const char *proto)
310*6236dae4SAndroid Build Coastguard Worker {
311*6236dae4SAndroid Build Coastguard Worker   const char * const *p = protoset;
312*6236dae4SAndroid Build Coastguard Worker 
313*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(proto == proto_token(proto));     /* Ensure it is tokenized. */
314*6236dae4SAndroid Build Coastguard Worker 
315*6236dae4SAndroid Build Coastguard Worker   for(; *p; p++)
316*6236dae4SAndroid Build Coastguard Worker     if(proto == *p)
317*6236dae4SAndroid Build Coastguard Worker       break;
318*6236dae4SAndroid Build Coastguard Worker   return p - protoset;
319*6236dae4SAndroid Build Coastguard Worker }
320*6236dae4SAndroid Build Coastguard Worker 
321*6236dae4SAndroid Build Coastguard Worker /* Include protocol token in set. */
protoset_set(const char ** protoset,const char * proto)322*6236dae4SAndroid Build Coastguard Worker static void protoset_set(const char **protoset, const char *proto)
323*6236dae4SAndroid Build Coastguard Worker {
324*6236dae4SAndroid Build Coastguard Worker   if(proto) {
325*6236dae4SAndroid Build Coastguard Worker     size_t n = protoset_index(protoset, proto);
326*6236dae4SAndroid Build Coastguard Worker 
327*6236dae4SAndroid Build Coastguard Worker     if(!protoset[n]) {
328*6236dae4SAndroid Build Coastguard Worker       DEBUGASSERT(n < proto_count);
329*6236dae4SAndroid Build Coastguard Worker       protoset[n] = proto;
330*6236dae4SAndroid Build Coastguard Worker       protoset[n + 1] = NULL;
331*6236dae4SAndroid Build Coastguard Worker     }
332*6236dae4SAndroid Build Coastguard Worker   }
333*6236dae4SAndroid Build Coastguard Worker }
334*6236dae4SAndroid Build Coastguard Worker 
335*6236dae4SAndroid Build Coastguard Worker /* Exclude protocol token from set. */
protoset_clear(const char ** protoset,const char * proto)336*6236dae4SAndroid Build Coastguard Worker static void protoset_clear(const char **protoset, const char *proto)
337*6236dae4SAndroid Build Coastguard Worker {
338*6236dae4SAndroid Build Coastguard Worker   if(proto) {
339*6236dae4SAndroid Build Coastguard Worker     size_t n = protoset_index(protoset, proto);
340*6236dae4SAndroid Build Coastguard Worker 
341*6236dae4SAndroid Build Coastguard Worker     if(protoset[n]) {
342*6236dae4SAndroid Build Coastguard Worker       size_t m = protoset_index(protoset, NULL) - 1;
343*6236dae4SAndroid Build Coastguard Worker 
344*6236dae4SAndroid Build Coastguard Worker       protoset[n] = protoset[m];
345*6236dae4SAndroid Build Coastguard Worker       protoset[m] = NULL;
346*6236dae4SAndroid Build Coastguard Worker     }
347*6236dae4SAndroid Build Coastguard Worker   }
348*6236dae4SAndroid Build Coastguard Worker }
349*6236dae4SAndroid Build Coastguard Worker 
350*6236dae4SAndroid Build Coastguard Worker /*
351*6236dae4SAndroid Build Coastguard Worker  * Parse the string and provide an allocated libcurl compatible protocol
352*6236dae4SAndroid Build Coastguard Worker  * string output. Return non-zero on failure, zero on success.
353*6236dae4SAndroid Build Coastguard Worker  *
354*6236dae4SAndroid Build Coastguard Worker  * The string is a list of protocols
355*6236dae4SAndroid Build Coastguard Worker  *
356*6236dae4SAndroid Build Coastguard Worker  * Since this function gets called with the 'nextarg' pointer from within the
357*6236dae4SAndroid Build Coastguard Worker  * getparameter a lot, we must check it for NULL before accessing the str
358*6236dae4SAndroid Build Coastguard Worker  * data.
359*6236dae4SAndroid Build Coastguard Worker  */
360*6236dae4SAndroid Build Coastguard Worker 
361*6236dae4SAndroid Build Coastguard Worker #define MAX_PROTOSTRING (64*11) /* Enough room for 64 10-chars proto names. */
362*6236dae4SAndroid Build Coastguard Worker 
proto2num(struct OperationConfig * config,const char * const * val,char ** ostr,const char * str)363*6236dae4SAndroid Build Coastguard Worker ParameterError proto2num(struct OperationConfig *config,
364*6236dae4SAndroid Build Coastguard Worker                          const char * const *val, char **ostr, const char *str)
365*6236dae4SAndroid Build Coastguard Worker {
366*6236dae4SAndroid Build Coastguard Worker   char *buffer;
367*6236dae4SAndroid Build Coastguard Worker   const char *sep = ",";
368*6236dae4SAndroid Build Coastguard Worker   char *token;
369*6236dae4SAndroid Build Coastguard Worker   const char **protoset;
370*6236dae4SAndroid Build Coastguard Worker   struct curlx_dynbuf obuf;
371*6236dae4SAndroid Build Coastguard Worker   size_t proto;
372*6236dae4SAndroid Build Coastguard Worker   CURLcode result;
373*6236dae4SAndroid Build Coastguard Worker 
374*6236dae4SAndroid Build Coastguard Worker   curlx_dyn_init(&obuf, MAX_PROTOSTRING);
375*6236dae4SAndroid Build Coastguard Worker 
376*6236dae4SAndroid Build Coastguard Worker   if(!str)
377*6236dae4SAndroid Build Coastguard Worker     return PARAM_OPTION_AMBIGUOUS;
378*6236dae4SAndroid Build Coastguard Worker 
379*6236dae4SAndroid Build Coastguard Worker   buffer = strdup(str); /* because strtok corrupts it */
380*6236dae4SAndroid Build Coastguard Worker   if(!buffer)
381*6236dae4SAndroid Build Coastguard Worker     return PARAM_NO_MEM;
382*6236dae4SAndroid Build Coastguard Worker 
383*6236dae4SAndroid Build Coastguard Worker   protoset = malloc((proto_count + 1) * sizeof(*protoset));
384*6236dae4SAndroid Build Coastguard Worker   if(!protoset) {
385*6236dae4SAndroid Build Coastguard Worker     free(buffer);
386*6236dae4SAndroid Build Coastguard Worker     return PARAM_NO_MEM;
387*6236dae4SAndroid Build Coastguard Worker   }
388*6236dae4SAndroid Build Coastguard Worker 
389*6236dae4SAndroid Build Coastguard Worker   /* Preset protocol set with default values. */
390*6236dae4SAndroid Build Coastguard Worker   protoset[0] = NULL;
391*6236dae4SAndroid Build Coastguard Worker   for(; *val; val++) {
392*6236dae4SAndroid Build Coastguard Worker     const char *p = proto_token(*val);
393*6236dae4SAndroid Build Coastguard Worker 
394*6236dae4SAndroid Build Coastguard Worker     if(p)
395*6236dae4SAndroid Build Coastguard Worker       protoset_set(protoset, p);
396*6236dae4SAndroid Build Coastguard Worker   }
397*6236dae4SAndroid Build Coastguard Worker 
398*6236dae4SAndroid Build Coastguard Worker   /* Allow strtok() here since this is not used threaded */
399*6236dae4SAndroid Build Coastguard Worker   /* !checksrc! disable BANNEDFUNC 2 */
400*6236dae4SAndroid Build Coastguard Worker   for(token = strtok(buffer, sep);
401*6236dae4SAndroid Build Coastguard Worker       token;
402*6236dae4SAndroid Build Coastguard Worker       token = strtok(NULL, sep)) {
403*6236dae4SAndroid Build Coastguard Worker     enum e_action { allow, deny, set } action = allow;
404*6236dae4SAndroid Build Coastguard Worker 
405*6236dae4SAndroid Build Coastguard Worker     /* Process token modifiers */
406*6236dae4SAndroid Build Coastguard Worker     while(!ISALNUM(*token)) { /* may be NULL if token is all modifiers */
407*6236dae4SAndroid Build Coastguard Worker       switch(*token++) {
408*6236dae4SAndroid Build Coastguard Worker       case '=':
409*6236dae4SAndroid Build Coastguard Worker         action = set;
410*6236dae4SAndroid Build Coastguard Worker         break;
411*6236dae4SAndroid Build Coastguard Worker       case '-':
412*6236dae4SAndroid Build Coastguard Worker         action = deny;
413*6236dae4SAndroid Build Coastguard Worker         break;
414*6236dae4SAndroid Build Coastguard Worker       case '+':
415*6236dae4SAndroid Build Coastguard Worker         action = allow;
416*6236dae4SAndroid Build Coastguard Worker         break;
417*6236dae4SAndroid Build Coastguard Worker       default: /* Includes case of terminating NULL */
418*6236dae4SAndroid Build Coastguard Worker         free(buffer);
419*6236dae4SAndroid Build Coastguard Worker         free((char *) protoset);
420*6236dae4SAndroid Build Coastguard Worker         return PARAM_BAD_USE;
421*6236dae4SAndroid Build Coastguard Worker       }
422*6236dae4SAndroid Build Coastguard Worker     }
423*6236dae4SAndroid Build Coastguard Worker 
424*6236dae4SAndroid Build Coastguard Worker     if(curl_strequal(token, "all")) {
425*6236dae4SAndroid Build Coastguard Worker       switch(action) {
426*6236dae4SAndroid Build Coastguard Worker       case deny:
427*6236dae4SAndroid Build Coastguard Worker         protoset[0] = NULL;
428*6236dae4SAndroid Build Coastguard Worker         break;
429*6236dae4SAndroid Build Coastguard Worker       case allow:
430*6236dae4SAndroid Build Coastguard Worker       case set:
431*6236dae4SAndroid Build Coastguard Worker         memcpy((char *) protoset,
432*6236dae4SAndroid Build Coastguard Worker                built_in_protos, (proto_count + 1) * sizeof(*protoset));
433*6236dae4SAndroid Build Coastguard Worker         break;
434*6236dae4SAndroid Build Coastguard Worker       }
435*6236dae4SAndroid Build Coastguard Worker     }
436*6236dae4SAndroid Build Coastguard Worker     else {
437*6236dae4SAndroid Build Coastguard Worker       const char *p = proto_token(token);
438*6236dae4SAndroid Build Coastguard Worker 
439*6236dae4SAndroid Build Coastguard Worker       if(p)
440*6236dae4SAndroid Build Coastguard Worker         switch(action) {
441*6236dae4SAndroid Build Coastguard Worker         case deny:
442*6236dae4SAndroid Build Coastguard Worker           protoset_clear(protoset, p);
443*6236dae4SAndroid Build Coastguard Worker           break;
444*6236dae4SAndroid Build Coastguard Worker         case set:
445*6236dae4SAndroid Build Coastguard Worker           protoset[0] = NULL;
446*6236dae4SAndroid Build Coastguard Worker           FALLTHROUGH();
447*6236dae4SAndroid Build Coastguard Worker         case allow:
448*6236dae4SAndroid Build Coastguard Worker           protoset_set(protoset, p);
449*6236dae4SAndroid Build Coastguard Worker           break;
450*6236dae4SAndroid Build Coastguard Worker         }
451*6236dae4SAndroid Build Coastguard Worker       else { /* unknown protocol */
452*6236dae4SAndroid Build Coastguard Worker         /* If they have specified only this protocol, we say treat it as
453*6236dae4SAndroid Build Coastguard Worker            if no protocols are allowed */
454*6236dae4SAndroid Build Coastguard Worker         if(action == set)
455*6236dae4SAndroid Build Coastguard Worker           protoset[0] = NULL;
456*6236dae4SAndroid Build Coastguard Worker         warnf(config->global, "unrecognized protocol '%s'", token);
457*6236dae4SAndroid Build Coastguard Worker       }
458*6236dae4SAndroid Build Coastguard Worker     }
459*6236dae4SAndroid Build Coastguard Worker   }
460*6236dae4SAndroid Build Coastguard Worker   free(buffer);
461*6236dae4SAndroid Build Coastguard Worker 
462*6236dae4SAndroid Build Coastguard Worker   /* We need the protocols in alphabetic order for CI tests requirements. */
463*6236dae4SAndroid Build Coastguard Worker   qsort((char *) protoset, protoset_index(protoset, NULL), sizeof(*protoset),
464*6236dae4SAndroid Build Coastguard Worker         struplocompare4sort);
465*6236dae4SAndroid Build Coastguard Worker 
466*6236dae4SAndroid Build Coastguard Worker   result = curlx_dyn_addn(&obuf, "", 0);
467*6236dae4SAndroid Build Coastguard Worker   for(proto = 0; protoset[proto] && !result; proto++)
468*6236dae4SAndroid Build Coastguard Worker     result = curlx_dyn_addf(&obuf, "%s,", protoset[proto]);
469*6236dae4SAndroid Build Coastguard Worker   free((char *) protoset);
470*6236dae4SAndroid Build Coastguard Worker   curlx_dyn_setlen(&obuf, curlx_dyn_len(&obuf) - 1);
471*6236dae4SAndroid Build Coastguard Worker   free(*ostr);
472*6236dae4SAndroid Build Coastguard Worker   *ostr = curlx_dyn_ptr(&obuf);
473*6236dae4SAndroid Build Coastguard Worker 
474*6236dae4SAndroid Build Coastguard Worker   return *ostr ? PARAM_OK : PARAM_NO_MEM;
475*6236dae4SAndroid Build Coastguard Worker }
476*6236dae4SAndroid Build Coastguard Worker 
477*6236dae4SAndroid Build Coastguard Worker /**
478*6236dae4SAndroid Build Coastguard Worker  * Check if the given string is a protocol supported by libcurl
479*6236dae4SAndroid Build Coastguard Worker  *
480*6236dae4SAndroid Build Coastguard Worker  * @param str  the protocol name
481*6236dae4SAndroid Build Coastguard Worker  * @return PARAM_OK  protocol supported
482*6236dae4SAndroid Build Coastguard Worker  * @return PARAM_LIBCURL_UNSUPPORTED_PROTOCOL  protocol not supported
483*6236dae4SAndroid Build Coastguard Worker  * @return PARAM_REQUIRES_PARAMETER   missing parameter
484*6236dae4SAndroid Build Coastguard Worker  */
check_protocol(const char * str)485*6236dae4SAndroid Build Coastguard Worker ParameterError check_protocol(const char *str)
486*6236dae4SAndroid Build Coastguard Worker {
487*6236dae4SAndroid Build Coastguard Worker   if(!str)
488*6236dae4SAndroid Build Coastguard Worker     return PARAM_REQUIRES_PARAMETER;
489*6236dae4SAndroid Build Coastguard Worker 
490*6236dae4SAndroid Build Coastguard Worker   if(proto_token(str))
491*6236dae4SAndroid Build Coastguard Worker     return PARAM_OK;
492*6236dae4SAndroid Build Coastguard Worker   return PARAM_LIBCURL_UNSUPPORTED_PROTOCOL;
493*6236dae4SAndroid Build Coastguard Worker }
494*6236dae4SAndroid Build Coastguard Worker 
495*6236dae4SAndroid Build Coastguard Worker /**
496*6236dae4SAndroid Build Coastguard Worker  * Parses the given string looking for an offset (which may be a
497*6236dae4SAndroid Build Coastguard Worker  * larger-than-integer value). The offset CANNOT be negative!
498*6236dae4SAndroid Build Coastguard Worker  *
499*6236dae4SAndroid Build Coastguard Worker  * @param val  the offset to populate
500*6236dae4SAndroid Build Coastguard Worker  * @param str  the buffer containing the offset
501*6236dae4SAndroid Build Coastguard Worker  * @return PARAM_OK if successful, a parameter specific error enum if failure.
502*6236dae4SAndroid Build Coastguard Worker  */
str2offset(curl_off_t * val,const char * str)503*6236dae4SAndroid Build Coastguard Worker ParameterError str2offset(curl_off_t *val, const char *str)
504*6236dae4SAndroid Build Coastguard Worker {
505*6236dae4SAndroid Build Coastguard Worker   char *endptr;
506*6236dae4SAndroid Build Coastguard Worker   if(str[0] == '-')
507*6236dae4SAndroid Build Coastguard Worker     /* offsets are not negative, this indicates weird input */
508*6236dae4SAndroid Build Coastguard Worker     return PARAM_NEGATIVE_NUMERIC;
509*6236dae4SAndroid Build Coastguard Worker 
510*6236dae4SAndroid Build Coastguard Worker #if(SIZEOF_CURL_OFF_T > SIZEOF_LONG)
511*6236dae4SAndroid Build Coastguard Worker   {
512*6236dae4SAndroid Build Coastguard Worker     CURLofft offt = curlx_strtoofft(str, &endptr, 10, val);
513*6236dae4SAndroid Build Coastguard Worker     if(CURL_OFFT_FLOW == offt)
514*6236dae4SAndroid Build Coastguard Worker       return PARAM_NUMBER_TOO_LARGE;
515*6236dae4SAndroid Build Coastguard Worker     else if(CURL_OFFT_INVAL == offt)
516*6236dae4SAndroid Build Coastguard Worker       return PARAM_BAD_NUMERIC;
517*6236dae4SAndroid Build Coastguard Worker   }
518*6236dae4SAndroid Build Coastguard Worker #else
519*6236dae4SAndroid Build Coastguard Worker   errno = 0;
520*6236dae4SAndroid Build Coastguard Worker   *val = strtol(str, &endptr, 0);
521*6236dae4SAndroid Build Coastguard Worker   if((*val == LONG_MIN || *val == LONG_MAX) && errno == ERANGE)
522*6236dae4SAndroid Build Coastguard Worker     return PARAM_NUMBER_TOO_LARGE;
523*6236dae4SAndroid Build Coastguard Worker #endif
524*6236dae4SAndroid Build Coastguard Worker   if((endptr != str) && (endptr == str + strlen(str)))
525*6236dae4SAndroid Build Coastguard Worker     return PARAM_OK;
526*6236dae4SAndroid Build Coastguard Worker 
527*6236dae4SAndroid Build Coastguard Worker   return PARAM_BAD_NUMERIC;
528*6236dae4SAndroid Build Coastguard Worker }
529*6236dae4SAndroid Build Coastguard Worker 
530*6236dae4SAndroid Build Coastguard Worker #define MAX_USERPWDLENGTH (100*1024)
checkpasswd(const char * kind,const size_t i,const bool last,char ** userpwd)531*6236dae4SAndroid Build Coastguard Worker static CURLcode checkpasswd(const char *kind, /* for what purpose */
532*6236dae4SAndroid Build Coastguard Worker                             const size_t i,   /* operation index */
533*6236dae4SAndroid Build Coastguard Worker                             const bool last,  /* TRUE if last operation */
534*6236dae4SAndroid Build Coastguard Worker                             char **userpwd)   /* pointer to allocated string */
535*6236dae4SAndroid Build Coastguard Worker {
536*6236dae4SAndroid Build Coastguard Worker   char *psep;
537*6236dae4SAndroid Build Coastguard Worker   char *osep;
538*6236dae4SAndroid Build Coastguard Worker 
539*6236dae4SAndroid Build Coastguard Worker   if(!*userpwd)
540*6236dae4SAndroid Build Coastguard Worker     return CURLE_OK;
541*6236dae4SAndroid Build Coastguard Worker 
542*6236dae4SAndroid Build Coastguard Worker   /* Attempt to find the password separator */
543*6236dae4SAndroid Build Coastguard Worker   psep = strchr(*userpwd, ':');
544*6236dae4SAndroid Build Coastguard Worker 
545*6236dae4SAndroid Build Coastguard Worker   /* Attempt to find the options separator */
546*6236dae4SAndroid Build Coastguard Worker   osep = strchr(*userpwd, ';');
547*6236dae4SAndroid Build Coastguard Worker 
548*6236dae4SAndroid Build Coastguard Worker   if(!psep && **userpwd != ';') {
549*6236dae4SAndroid Build Coastguard Worker     /* no password present, prompt for one */
550*6236dae4SAndroid Build Coastguard Worker     char passwd[2048] = "";
551*6236dae4SAndroid Build Coastguard Worker     char prompt[256];
552*6236dae4SAndroid Build Coastguard Worker     struct curlx_dynbuf dyn;
553*6236dae4SAndroid Build Coastguard Worker 
554*6236dae4SAndroid Build Coastguard Worker     curlx_dyn_init(&dyn, MAX_USERPWDLENGTH);
555*6236dae4SAndroid Build Coastguard Worker     if(osep)
556*6236dae4SAndroid Build Coastguard Worker       *osep = '\0';
557*6236dae4SAndroid Build Coastguard Worker 
558*6236dae4SAndroid Build Coastguard Worker     /* build a nice-looking prompt */
559*6236dae4SAndroid Build Coastguard Worker     if(!i && last)
560*6236dae4SAndroid Build Coastguard Worker       msnprintf(prompt, sizeof(prompt),
561*6236dae4SAndroid Build Coastguard Worker                 "Enter %s password for user '%s':",
562*6236dae4SAndroid Build Coastguard Worker                 kind, *userpwd);
563*6236dae4SAndroid Build Coastguard Worker     else
564*6236dae4SAndroid Build Coastguard Worker       msnprintf(prompt, sizeof(prompt),
565*6236dae4SAndroid Build Coastguard Worker                 "Enter %s password for user '%s' on URL #%zu:",
566*6236dae4SAndroid Build Coastguard Worker                 kind, *userpwd, i + 1);
567*6236dae4SAndroid Build Coastguard Worker 
568*6236dae4SAndroid Build Coastguard Worker     /* get password */
569*6236dae4SAndroid Build Coastguard Worker     getpass_r(prompt, passwd, sizeof(passwd));
570*6236dae4SAndroid Build Coastguard Worker     if(osep)
571*6236dae4SAndroid Build Coastguard Worker       *osep = ';';
572*6236dae4SAndroid Build Coastguard Worker 
573*6236dae4SAndroid Build Coastguard Worker     if(curlx_dyn_addf(&dyn, "%s:%s", *userpwd, passwd))
574*6236dae4SAndroid Build Coastguard Worker       return CURLE_OUT_OF_MEMORY;
575*6236dae4SAndroid Build Coastguard Worker 
576*6236dae4SAndroid Build Coastguard Worker     /* return the new string */
577*6236dae4SAndroid Build Coastguard Worker     free(*userpwd);
578*6236dae4SAndroid Build Coastguard Worker     *userpwd = curlx_dyn_ptr(&dyn);
579*6236dae4SAndroid Build Coastguard Worker   }
580*6236dae4SAndroid Build Coastguard Worker 
581*6236dae4SAndroid Build Coastguard Worker   return CURLE_OK;
582*6236dae4SAndroid Build Coastguard Worker }
583*6236dae4SAndroid Build Coastguard Worker 
add2list(struct curl_slist ** list,const char * ptr)584*6236dae4SAndroid Build Coastguard Worker ParameterError add2list(struct curl_slist **list, const char *ptr)
585*6236dae4SAndroid Build Coastguard Worker {
586*6236dae4SAndroid Build Coastguard Worker   struct curl_slist *newlist = curl_slist_append(*list, ptr);
587*6236dae4SAndroid Build Coastguard Worker   if(newlist)
588*6236dae4SAndroid Build Coastguard Worker     *list = newlist;
589*6236dae4SAndroid Build Coastguard Worker   else
590*6236dae4SAndroid Build Coastguard Worker     return PARAM_NO_MEM;
591*6236dae4SAndroid Build Coastguard Worker 
592*6236dae4SAndroid Build Coastguard Worker   return PARAM_OK;
593*6236dae4SAndroid Build Coastguard Worker }
594*6236dae4SAndroid Build Coastguard Worker 
ftpfilemethod(struct OperationConfig * config,const char * str)595*6236dae4SAndroid Build Coastguard Worker int ftpfilemethod(struct OperationConfig *config, const char *str)
596*6236dae4SAndroid Build Coastguard Worker {
597*6236dae4SAndroid Build Coastguard Worker   if(curl_strequal("singlecwd", str))
598*6236dae4SAndroid Build Coastguard Worker     return CURLFTPMETHOD_SINGLECWD;
599*6236dae4SAndroid Build Coastguard Worker   if(curl_strequal("nocwd", str))
600*6236dae4SAndroid Build Coastguard Worker     return CURLFTPMETHOD_NOCWD;
601*6236dae4SAndroid Build Coastguard Worker   if(curl_strequal("multicwd", str))
602*6236dae4SAndroid Build Coastguard Worker     return CURLFTPMETHOD_MULTICWD;
603*6236dae4SAndroid Build Coastguard Worker 
604*6236dae4SAndroid Build Coastguard Worker   warnf(config->global, "unrecognized ftp file method '%s', using default",
605*6236dae4SAndroid Build Coastguard Worker         str);
606*6236dae4SAndroid Build Coastguard Worker 
607*6236dae4SAndroid Build Coastguard Worker   return CURLFTPMETHOD_MULTICWD;
608*6236dae4SAndroid Build Coastguard Worker }
609*6236dae4SAndroid Build Coastguard Worker 
ftpcccmethod(struct OperationConfig * config,const char * str)610*6236dae4SAndroid Build Coastguard Worker int ftpcccmethod(struct OperationConfig *config, const char *str)
611*6236dae4SAndroid Build Coastguard Worker {
612*6236dae4SAndroid Build Coastguard Worker   if(curl_strequal("passive", str))
613*6236dae4SAndroid Build Coastguard Worker     return CURLFTPSSL_CCC_PASSIVE;
614*6236dae4SAndroid Build Coastguard Worker   if(curl_strequal("active", str))
615*6236dae4SAndroid Build Coastguard Worker     return CURLFTPSSL_CCC_ACTIVE;
616*6236dae4SAndroid Build Coastguard Worker 
617*6236dae4SAndroid Build Coastguard Worker   warnf(config->global, "unrecognized ftp CCC method '%s', using default",
618*6236dae4SAndroid Build Coastguard Worker         str);
619*6236dae4SAndroid Build Coastguard Worker 
620*6236dae4SAndroid Build Coastguard Worker   return CURLFTPSSL_CCC_PASSIVE;
621*6236dae4SAndroid Build Coastguard Worker }
622*6236dae4SAndroid Build Coastguard Worker 
delegation(struct OperationConfig * config,const char * str)623*6236dae4SAndroid Build Coastguard Worker long delegation(struct OperationConfig *config, const char *str)
624*6236dae4SAndroid Build Coastguard Worker {
625*6236dae4SAndroid Build Coastguard Worker   if(curl_strequal("none", str))
626*6236dae4SAndroid Build Coastguard Worker     return CURLGSSAPI_DELEGATION_NONE;
627*6236dae4SAndroid Build Coastguard Worker   if(curl_strequal("policy", str))
628*6236dae4SAndroid Build Coastguard Worker     return CURLGSSAPI_DELEGATION_POLICY_FLAG;
629*6236dae4SAndroid Build Coastguard Worker   if(curl_strequal("always", str))
630*6236dae4SAndroid Build Coastguard Worker     return CURLGSSAPI_DELEGATION_FLAG;
631*6236dae4SAndroid Build Coastguard Worker 
632*6236dae4SAndroid Build Coastguard Worker   warnf(config->global, "unrecognized delegation method '%s', using none",
633*6236dae4SAndroid Build Coastguard Worker         str);
634*6236dae4SAndroid Build Coastguard Worker 
635*6236dae4SAndroid Build Coastguard Worker   return CURLGSSAPI_DELEGATION_NONE;
636*6236dae4SAndroid Build Coastguard Worker }
637*6236dae4SAndroid Build Coastguard Worker 
638*6236dae4SAndroid Build Coastguard Worker /*
639*6236dae4SAndroid Build Coastguard Worker  * my_useragent: returns allocated string with default user agent
640*6236dae4SAndroid Build Coastguard Worker  */
my_useragent(void)641*6236dae4SAndroid Build Coastguard Worker static char *my_useragent(void)
642*6236dae4SAndroid Build Coastguard Worker {
643*6236dae4SAndroid Build Coastguard Worker   return strdup(CURL_NAME "/" CURL_VERSION);
644*6236dae4SAndroid Build Coastguard Worker }
645*6236dae4SAndroid Build Coastguard Worker 
646*6236dae4SAndroid Build Coastguard Worker #define isheadersep(x) ((((x)==':') || ((x)==';')))
647*6236dae4SAndroid Build Coastguard Worker 
648*6236dae4SAndroid Build Coastguard Worker /*
649*6236dae4SAndroid Build Coastguard Worker  * inlist() returns true if the given 'checkfor' header is present in the
650*6236dae4SAndroid Build Coastguard Worker  * header list.
651*6236dae4SAndroid Build Coastguard Worker  */
inlist(const struct curl_slist * head,const char * checkfor)652*6236dae4SAndroid Build Coastguard Worker static bool inlist(const struct curl_slist *head,
653*6236dae4SAndroid Build Coastguard Worker                    const char *checkfor)
654*6236dae4SAndroid Build Coastguard Worker {
655*6236dae4SAndroid Build Coastguard Worker   size_t thislen = strlen(checkfor);
656*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(thislen);
657*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(checkfor[thislen-1] != ':');
658*6236dae4SAndroid Build Coastguard Worker 
659*6236dae4SAndroid Build Coastguard Worker   for(; head; head = head->next) {
660*6236dae4SAndroid Build Coastguard Worker     if(curl_strnequal(head->data, checkfor, thislen) &&
661*6236dae4SAndroid Build Coastguard Worker        isheadersep(head->data[thislen]) )
662*6236dae4SAndroid Build Coastguard Worker       return TRUE;
663*6236dae4SAndroid Build Coastguard Worker   }
664*6236dae4SAndroid Build Coastguard Worker 
665*6236dae4SAndroid Build Coastguard Worker   return FALSE;
666*6236dae4SAndroid Build Coastguard Worker }
667*6236dae4SAndroid Build Coastguard Worker 
get_args(struct OperationConfig * config,const size_t i)668*6236dae4SAndroid Build Coastguard Worker CURLcode get_args(struct OperationConfig *config, const size_t i)
669*6236dae4SAndroid Build Coastguard Worker {
670*6236dae4SAndroid Build Coastguard Worker   CURLcode result = CURLE_OK;
671*6236dae4SAndroid Build Coastguard Worker   bool last = (config->next ? FALSE : TRUE);
672*6236dae4SAndroid Build Coastguard Worker 
673*6236dae4SAndroid Build Coastguard Worker   if(config->jsoned) {
674*6236dae4SAndroid Build Coastguard Worker     ParameterError err = PARAM_OK;
675*6236dae4SAndroid Build Coastguard Worker     /* --json also implies json Content-Type: and Accept: headers - if
676*6236dae4SAndroid Build Coastguard Worker        they are not set with -H */
677*6236dae4SAndroid Build Coastguard Worker     if(!inlist(config->headers, "Content-Type"))
678*6236dae4SAndroid Build Coastguard Worker       err = add2list(&config->headers, "Content-Type: application/json");
679*6236dae4SAndroid Build Coastguard Worker     if(!err && !inlist(config->headers, "Accept"))
680*6236dae4SAndroid Build Coastguard Worker       err = add2list(&config->headers, "Accept: application/json");
681*6236dae4SAndroid Build Coastguard Worker     if(err)
682*6236dae4SAndroid Build Coastguard Worker       return CURLE_OUT_OF_MEMORY;
683*6236dae4SAndroid Build Coastguard Worker   }
684*6236dae4SAndroid Build Coastguard Worker 
685*6236dae4SAndroid Build Coastguard Worker   /* Check we have a password for the given host user */
686*6236dae4SAndroid Build Coastguard Worker   if(config->userpwd && !config->oauth_bearer) {
687*6236dae4SAndroid Build Coastguard Worker     result = checkpasswd("host", i, last, &config->userpwd);
688*6236dae4SAndroid Build Coastguard Worker     if(result)
689*6236dae4SAndroid Build Coastguard Worker       return result;
690*6236dae4SAndroid Build Coastguard Worker   }
691*6236dae4SAndroid Build Coastguard Worker 
692*6236dae4SAndroid Build Coastguard Worker   /* Check we have a password for the given proxy user */
693*6236dae4SAndroid Build Coastguard Worker   if(config->proxyuserpwd) {
694*6236dae4SAndroid Build Coastguard Worker     result = checkpasswd("proxy", i, last, &config->proxyuserpwd);
695*6236dae4SAndroid Build Coastguard Worker     if(result)
696*6236dae4SAndroid Build Coastguard Worker       return result;
697*6236dae4SAndroid Build Coastguard Worker   }
698*6236dae4SAndroid Build Coastguard Worker 
699*6236dae4SAndroid Build Coastguard Worker   /* Check we have a user agent */
700*6236dae4SAndroid Build Coastguard Worker   if(!config->useragent) {
701*6236dae4SAndroid Build Coastguard Worker     config->useragent = my_useragent();
702*6236dae4SAndroid Build Coastguard Worker     if(!config->useragent) {
703*6236dae4SAndroid Build Coastguard Worker       errorf(config->global, "out of memory");
704*6236dae4SAndroid Build Coastguard Worker       result = CURLE_OUT_OF_MEMORY;
705*6236dae4SAndroid Build Coastguard Worker     }
706*6236dae4SAndroid Build Coastguard Worker   }
707*6236dae4SAndroid Build Coastguard Worker 
708*6236dae4SAndroid Build Coastguard Worker   return result;
709*6236dae4SAndroid Build Coastguard Worker }
710*6236dae4SAndroid Build Coastguard Worker 
711*6236dae4SAndroid Build Coastguard Worker /*
712*6236dae4SAndroid Build Coastguard Worker  * Parse the string and modify ssl_version in the val argument. Return PARAM_OK
713*6236dae4SAndroid Build Coastguard Worker  * on success, otherwise a parameter error enum. ONLY ACCEPTS POSITIVE NUMBERS!
714*6236dae4SAndroid Build Coastguard Worker  *
715*6236dae4SAndroid Build Coastguard Worker  * Since this function gets called with the 'nextarg' pointer from within the
716*6236dae4SAndroid Build Coastguard Worker  * getparameter a lot, we must check it for NULL before accessing the str
717*6236dae4SAndroid Build Coastguard Worker  * data.
718*6236dae4SAndroid Build Coastguard Worker  */
719*6236dae4SAndroid Build Coastguard Worker 
str2tls_max(long * val,const char * str)720*6236dae4SAndroid Build Coastguard Worker ParameterError str2tls_max(long *val, const char *str)
721*6236dae4SAndroid Build Coastguard Worker {
722*6236dae4SAndroid Build Coastguard Worker    static struct s_tls_max {
723*6236dae4SAndroid Build Coastguard Worker     const char *tls_max_str;
724*6236dae4SAndroid Build Coastguard Worker     long tls_max;
725*6236dae4SAndroid Build Coastguard Worker   } const tls_max_array[] = {
726*6236dae4SAndroid Build Coastguard Worker     { "default", CURL_SSLVERSION_MAX_DEFAULT },
727*6236dae4SAndroid Build Coastguard Worker     { "1.0",     CURL_SSLVERSION_MAX_TLSv1_0 },
728*6236dae4SAndroid Build Coastguard Worker     { "1.1",     CURL_SSLVERSION_MAX_TLSv1_1 },
729*6236dae4SAndroid Build Coastguard Worker     { "1.2",     CURL_SSLVERSION_MAX_TLSv1_2 },
730*6236dae4SAndroid Build Coastguard Worker     { "1.3",     CURL_SSLVERSION_MAX_TLSv1_3 }
731*6236dae4SAndroid Build Coastguard Worker   };
732*6236dae4SAndroid Build Coastguard Worker   size_t i = 0;
733*6236dae4SAndroid Build Coastguard Worker   if(!str)
734*6236dae4SAndroid Build Coastguard Worker     return PARAM_REQUIRES_PARAMETER;
735*6236dae4SAndroid Build Coastguard Worker   for(i = 0; i < sizeof(tls_max_array)/sizeof(tls_max_array[0]); i++) {
736*6236dae4SAndroid Build Coastguard Worker     if(!strcmp(str, tls_max_array[i].tls_max_str)) {
737*6236dae4SAndroid Build Coastguard Worker       *val = tls_max_array[i].tls_max;
738*6236dae4SAndroid Build Coastguard Worker       return PARAM_OK;
739*6236dae4SAndroid Build Coastguard Worker     }
740*6236dae4SAndroid Build Coastguard Worker   }
741*6236dae4SAndroid Build Coastguard Worker   return PARAM_BAD_USE;
742*6236dae4SAndroid Build Coastguard Worker }
743