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