Annotation of embedaddon/curl/lib/setopt.c, revision 1.1.1.1
1.1 misho 1: /***************************************************************************
2: * _ _ ____ _
3: * Project ___| | | | _ \| |
4: * / __| | | | |_) | |
5: * | (__| |_| | _ <| |___
6: * \___|\___/|_| \_\_____|
7: *
8: * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
9: *
10: * This software is licensed as described in the file COPYING, which
11: * you should have received as part of this distribution. The terms
12: * are also available at https://curl.haxx.se/docs/copyright.html.
13: *
14: * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15: * copies of the Software, and permit persons to whom the Software is
16: * furnished to do so, under the terms of the COPYING file.
17: *
18: * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19: * KIND, either express or implied.
20: *
21: ***************************************************************************/
22:
23: #include "curl_setup.h"
24:
25: #include <limits.h>
26:
27: #ifdef HAVE_NETINET_IN_H
28: #include <netinet/in.h>
29: #endif
30:
31: #ifdef HAVE_LINUX_TCP_H
32: #include <linux/tcp.h>
33: #endif
34:
35: #include "urldata.h"
36: #include "url.h"
37: #include "progress.h"
38: #include "content_encoding.h"
39: #include "strcase.h"
40: #include "share.h"
41: #include "vtls/vtls.h"
42: #include "warnless.h"
43: #include "sendf.h"
44: #include "http2.h"
45: #include "setopt.h"
46: #include "multiif.h"
47: #include "altsvc.h"
48:
49: /* The last 3 #include files should be in this order */
50: #include "curl_printf.h"
51: #include "curl_memory.h"
52: #include "memdebug.h"
53:
54: CURLcode Curl_setstropt(char **charp, const char *s)
55: {
56: /* Release the previous storage at `charp' and replace by a dynamic storage
57: copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */
58:
59: Curl_safefree(*charp);
60:
61: if(s) {
62: char *str = strdup(s);
63:
64: if(str) {
65: size_t len = strlen(str);
66: if(len > CURL_MAX_INPUT_LENGTH) {
67: free(str);
68: return CURLE_BAD_FUNCTION_ARGUMENT;
69: }
70: }
71: if(!str)
72: return CURLE_OUT_OF_MEMORY;
73:
74: *charp = str;
75: }
76:
77: return CURLE_OK;
78: }
79:
80: static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp)
81: {
82: CURLcode result = CURLE_OK;
83: char *user = NULL;
84: char *passwd = NULL;
85:
86: /* Parse the login details if specified. It not then we treat NULL as a hint
87: to clear the existing data */
88: if(option) {
89: result = Curl_parse_login_details(option, strlen(option),
90: (userp ? &user : NULL),
91: (passwdp ? &passwd : NULL),
92: NULL);
93: }
94:
95: if(!result) {
96: /* Store the username part of option if required */
97: if(userp) {
98: if(!user && option && option[0] == ':') {
99: /* Allocate an empty string instead of returning NULL as user name */
100: user = strdup("");
101: if(!user)
102: result = CURLE_OUT_OF_MEMORY;
103: }
104:
105: Curl_safefree(*userp);
106: *userp = user;
107: }
108:
109: /* Store the password part of option if required */
110: if(passwdp) {
111: Curl_safefree(*passwdp);
112: *passwdp = passwd;
113: }
114: }
115:
116: return result;
117: }
118:
119: #define C_SSLVERSION_VALUE(x) (x & 0xffff)
120: #define C_SSLVERSION_MAX_VALUE(x) (x & 0xffff0000)
121:
122: /*
123: * Do not make Curl_vsetopt() static: it is called from
124: * packages/OS400/ccsidcurl.c.
125: */
126: CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
127: {
128: char *argptr;
129: CURLcode result = CURLE_OK;
130: long arg;
131: unsigned long uarg;
132: curl_off_t bigsize;
133:
134: switch(option) {
135: case CURLOPT_DNS_CACHE_TIMEOUT:
136: arg = va_arg(param, long);
137: if(arg < -1)
138: return CURLE_BAD_FUNCTION_ARGUMENT;
139: data->set.dns_cache_timeout = arg;
140: break;
141: case CURLOPT_DNS_USE_GLOBAL_CACHE:
142: /* deprecated */
143: break;
144: case CURLOPT_SSL_CIPHER_LIST:
145: /* set a list of cipher we want to use in the SSL connection */
146: result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_ORIG],
147: va_arg(param, char *));
148: break;
149: #ifndef CURL_DISABLE_PROXY
150: case CURLOPT_PROXY_SSL_CIPHER_LIST:
151: /* set a list of cipher we want to use in the SSL connection for proxy */
152: result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_PROXY],
153: va_arg(param, char *));
154: break;
155: #endif
156: case CURLOPT_TLS13_CIPHERS:
157: if(Curl_ssl_tls13_ciphersuites()) {
158: /* set preferred list of TLS 1.3 cipher suites */
159: result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER13_LIST_ORIG],
160: va_arg(param, char *));
161: }
162: else
163: return CURLE_NOT_BUILT_IN;
164: break;
165: #ifndef CURL_DISABLE_PROXY
166: case CURLOPT_PROXY_TLS13_CIPHERS:
167: if(Curl_ssl_tls13_ciphersuites()) {
168: /* set preferred list of TLS 1.3 cipher suites for proxy */
169: result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER13_LIST_PROXY],
170: va_arg(param, char *));
171: }
172: else
173: return CURLE_NOT_BUILT_IN;
174: break;
175: #endif
176: case CURLOPT_RANDOM_FILE:
177: /*
178: * This is the path name to a file that contains random data to seed
179: * the random SSL stuff with. The file is only used for reading.
180: */
181: result = Curl_setstropt(&data->set.str[STRING_SSL_RANDOM_FILE],
182: va_arg(param, char *));
183: break;
184: case CURLOPT_EGDSOCKET:
185: /*
186: * The Entropy Gathering Daemon socket pathname
187: */
188: result = Curl_setstropt(&data->set.str[STRING_SSL_EGDSOCKET],
189: va_arg(param, char *));
190: break;
191: case CURLOPT_MAXCONNECTS:
192: /*
193: * Set the absolute number of maximum simultaneous alive connection that
194: * libcurl is allowed to have.
195: */
196: arg = va_arg(param, long);
197: if(arg < 0)
198: return CURLE_BAD_FUNCTION_ARGUMENT;
199: data->set.maxconnects = arg;
200: break;
201: case CURLOPT_FORBID_REUSE:
202: /*
203: * When this transfer is done, it must not be left to be reused by a
204: * subsequent transfer but shall be closed immediately.
205: */
206: data->set.reuse_forbid = (0 != va_arg(param, long)) ? TRUE : FALSE;
207: break;
208: case CURLOPT_FRESH_CONNECT:
209: /*
210: * This transfer shall not use a previously cached connection but
211: * should be made with a fresh new connect!
212: */
213: data->set.reuse_fresh = (0 != va_arg(param, long)) ? TRUE : FALSE;
214: break;
215: case CURLOPT_VERBOSE:
216: /*
217: * Verbose means infof() calls that give a lot of information about
218: * the connection and transfer procedures as well as internal choices.
219: */
220: data->set.verbose = (0 != va_arg(param, long)) ? TRUE : FALSE;
221: break;
222: case CURLOPT_HEADER:
223: /*
224: * Set to include the header in the general data output stream.
225: */
226: data->set.include_header = (0 != va_arg(param, long)) ? TRUE : FALSE;
227: break;
228: case CURLOPT_NOPROGRESS:
229: /*
230: * Shut off the internal supported progress meter
231: */
232: data->set.hide_progress = (0 != va_arg(param, long)) ? TRUE : FALSE;
233: if(data->set.hide_progress)
234: data->progress.flags |= PGRS_HIDE;
235: else
236: data->progress.flags &= ~PGRS_HIDE;
237: break;
238: case CURLOPT_NOBODY:
239: /*
240: * Do not include the body part in the output data stream.
241: */
242: data->set.opt_no_body = (0 != va_arg(param, long)) ? TRUE : FALSE;
243: break;
244: case CURLOPT_FAILONERROR:
245: /*
246: * Don't output the >=400 error code HTML-page, but instead only
247: * return error.
248: */
249: data->set.http_fail_on_error = (0 != va_arg(param, long)) ? TRUE : FALSE;
250: break;
251: case CURLOPT_KEEP_SENDING_ON_ERROR:
252: data->set.http_keep_sending_on_error = (0 != va_arg(param, long)) ?
253: TRUE : FALSE;
254: break;
255: case CURLOPT_UPLOAD:
256: case CURLOPT_PUT:
257: /*
258: * We want to sent data to the remote host. If this is HTTP, that equals
259: * using the PUT request.
260: */
261: data->set.upload = (0 != va_arg(param, long)) ? TRUE : FALSE;
262: if(data->set.upload) {
263: /* If this is HTTP, PUT is what's needed to "upload" */
264: data->set.httpreq = HTTPREQ_PUT;
265: data->set.opt_no_body = FALSE; /* this is implied */
266: }
267: else
268: /* In HTTP, the opposite of upload is GET (unless NOBODY is true as
269: then this can be changed to HEAD later on) */
270: data->set.httpreq = HTTPREQ_GET;
271: break;
272: case CURLOPT_REQUEST_TARGET:
273: result = Curl_setstropt(&data->set.str[STRING_TARGET],
274: va_arg(param, char *));
275: break;
276: case CURLOPT_FILETIME:
277: /*
278: * Try to get the file time of the remote document. The time will
279: * later (possibly) become available using curl_easy_getinfo().
280: */
281: data->set.get_filetime = (0 != va_arg(param, long)) ? TRUE : FALSE;
282: break;
283: case CURLOPT_SERVER_RESPONSE_TIMEOUT:
284: /*
285: * Option that specifies how quickly an server response must be obtained
286: * before it is considered failure. For pingpong protocols.
287: */
288: arg = va_arg(param, long);
289: if((arg >= 0) && (arg <= (INT_MAX/1000)))
290: data->set.server_response_timeout = arg * 1000;
291: else
292: return CURLE_BAD_FUNCTION_ARGUMENT;
293: break;
294: #ifndef CURL_DISABLE_TFTP
295: case CURLOPT_TFTP_NO_OPTIONS:
296: /*
297: * Option that prevents libcurl from sending TFTP option requests to the
298: * server.
299: */
300: data->set.tftp_no_options = va_arg(param, long) != 0;
301: break;
302: case CURLOPT_TFTP_BLKSIZE:
303: /*
304: * TFTP option that specifies the block size to use for data transmission.
305: */
306: arg = va_arg(param, long);
307: if(arg < 0)
308: return CURLE_BAD_FUNCTION_ARGUMENT;
309: data->set.tftp_blksize = arg;
310: break;
311: #endif
312: #ifndef CURL_DISABLE_NETRC
313: case CURLOPT_NETRC:
314: /*
315: * Parse the $HOME/.netrc file
316: */
317: arg = va_arg(param, long);
318: if((arg < CURL_NETRC_IGNORED) || (arg >= CURL_NETRC_LAST))
319: return CURLE_BAD_FUNCTION_ARGUMENT;
320: data->set.use_netrc = (enum CURL_NETRC_OPTION)arg;
321: break;
322: case CURLOPT_NETRC_FILE:
323: /*
324: * Use this file instead of the $HOME/.netrc file
325: */
326: result = Curl_setstropt(&data->set.str[STRING_NETRC_FILE],
327: va_arg(param, char *));
328: break;
329: #endif
330: case CURLOPT_TRANSFERTEXT:
331: /*
332: * This option was previously named 'FTPASCII'. Renamed to work with
333: * more protocols than merely FTP.
334: *
335: * Transfer using ASCII (instead of BINARY).
336: */
337: data->set.prefer_ascii = (0 != va_arg(param, long)) ? TRUE : FALSE;
338: break;
339: case CURLOPT_TIMECONDITION:
340: /*
341: * Set HTTP time condition. This must be one of the defines in the
342: * curl/curl.h header file.
343: */
344: arg = va_arg(param, long);
345: if((arg < CURL_TIMECOND_NONE) || (arg >= CURL_TIMECOND_LAST))
346: return CURLE_BAD_FUNCTION_ARGUMENT;
347: data->set.timecondition = (curl_TimeCond)arg;
348: break;
349: case CURLOPT_TIMEVALUE:
350: /*
351: * This is the value to compare with the remote document with the
352: * method set with CURLOPT_TIMECONDITION
353: */
354: data->set.timevalue = (time_t)va_arg(param, long);
355: break;
356:
357: case CURLOPT_TIMEVALUE_LARGE:
358: /*
359: * This is the value to compare with the remote document with the
360: * method set with CURLOPT_TIMECONDITION
361: */
362: data->set.timevalue = (time_t)va_arg(param, curl_off_t);
363: break;
364:
365: case CURLOPT_SSLVERSION:
366: case CURLOPT_PROXY_SSLVERSION:
367: /*
368: * Set explicit SSL version to try to connect with, as some SSL
369: * implementations are lame.
370: */
371: #ifdef USE_SSL
372: {
373: long version, version_max;
374: struct ssl_primary_config *primary = (option == CURLOPT_SSLVERSION ?
375: &data->set.ssl.primary :
376: &data->set.proxy_ssl.primary);
377:
378: arg = va_arg(param, long);
379:
380: version = C_SSLVERSION_VALUE(arg);
381: version_max = C_SSLVERSION_MAX_VALUE(arg);
382:
383: if(version < CURL_SSLVERSION_DEFAULT ||
384: version >= CURL_SSLVERSION_LAST ||
385: version_max < CURL_SSLVERSION_MAX_NONE ||
386: version_max >= CURL_SSLVERSION_MAX_LAST)
387: return CURLE_BAD_FUNCTION_ARGUMENT;
388:
389: primary->version = version;
390: primary->version_max = version_max;
391: }
392: #else
393: result = CURLE_UNKNOWN_OPTION;
394: #endif
395: break;
396:
397: #ifndef CURL_DISABLE_HTTP
398: case CURLOPT_AUTOREFERER:
399: /*
400: * Switch on automatic referer that gets set if curl follows locations.
401: */
402: data->set.http_auto_referer = (0 != va_arg(param, long)) ? TRUE : FALSE;
403: break;
404:
405: case CURLOPT_ACCEPT_ENCODING:
406: /*
407: * String to use at the value of Accept-Encoding header.
408: *
409: * If the encoding is set to "" we use an Accept-Encoding header that
410: * encompasses all the encodings we support.
411: * If the encoding is set to NULL we don't send an Accept-Encoding header
412: * and ignore an received Content-Encoding header.
413: *
414: */
415: argptr = va_arg(param, char *);
416: if(argptr && !*argptr) {
417: argptr = Curl_all_content_encodings();
418: if(!argptr)
419: result = CURLE_OUT_OF_MEMORY;
420: else {
421: result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr);
422: free(argptr);
423: }
424: }
425: else
426: result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr);
427: break;
428:
429: case CURLOPT_TRANSFER_ENCODING:
430: data->set.http_transfer_encoding = (0 != va_arg(param, long)) ?
431: TRUE : FALSE;
432: break;
433:
434: case CURLOPT_FOLLOWLOCATION:
435: /*
436: * Follow Location: header hints on a HTTP-server.
437: */
438: data->set.http_follow_location = (0 != va_arg(param, long)) ? TRUE : FALSE;
439: break;
440:
441: case CURLOPT_UNRESTRICTED_AUTH:
442: /*
443: * Send authentication (user+password) when following locations, even when
444: * hostname changed.
445: */
446: data->set.allow_auth_to_other_hosts =
447: (0 != va_arg(param, long)) ? TRUE : FALSE;
448: break;
449:
450: case CURLOPT_MAXREDIRS:
451: /*
452: * The maximum amount of hops you allow curl to follow Location:
453: * headers. This should mostly be used to detect never-ending loops.
454: */
455: arg = va_arg(param, long);
456: if(arg < -1)
457: return CURLE_BAD_FUNCTION_ARGUMENT;
458: data->set.maxredirs = arg;
459: break;
460:
461: case CURLOPT_POSTREDIR:
462: /*
463: * Set the behaviour of POST when redirecting
464: * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302
465: * CURL_REDIR_POST_301 - POST is kept as POST after 301
466: * CURL_REDIR_POST_302 - POST is kept as POST after 302
467: * CURL_REDIR_POST_303 - POST is kept as POST after 303
468: * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303
469: * other - POST is kept as POST after 301 and 302
470: */
471: arg = va_arg(param, long);
472: if(arg < CURL_REDIR_GET_ALL)
473: /* no return error on too high numbers since the bitmask could be
474: extended in a future */
475: return CURLE_BAD_FUNCTION_ARGUMENT;
476: data->set.keep_post = arg & CURL_REDIR_POST_ALL;
477: break;
478:
479: case CURLOPT_POST:
480: /* Does this option serve a purpose anymore? Yes it does, when
481: CURLOPT_POSTFIELDS isn't used and the POST data is read off the
482: callback! */
483: if(va_arg(param, long)) {
484: data->set.httpreq = HTTPREQ_POST;
485: data->set.opt_no_body = FALSE; /* this is implied */
486: }
487: else
488: data->set.httpreq = HTTPREQ_GET;
489: break;
490:
491: case CURLOPT_COPYPOSTFIELDS:
492: /*
493: * A string with POST data. Makes curl HTTP POST. Even if it is NULL.
494: * If needed, CURLOPT_POSTFIELDSIZE must have been set prior to
495: * CURLOPT_COPYPOSTFIELDS and not altered later.
496: */
497: argptr = va_arg(param, char *);
498:
499: if(!argptr || data->set.postfieldsize == -1)
500: result = Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], argptr);
501: else {
502: /*
503: * Check that requested length does not overflow the size_t type.
504: */
505:
506: if((data->set.postfieldsize < 0) ||
507: ((sizeof(curl_off_t) != sizeof(size_t)) &&
508: (data->set.postfieldsize > (curl_off_t)((size_t)-1))))
509: result = CURLE_OUT_OF_MEMORY;
510: else {
511: char *p;
512:
513: (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
514:
515: /* Allocate even when size == 0. This satisfies the need of possible
516: later address compare to detect the COPYPOSTFIELDS mode, and
517: to mark that postfields is used rather than read function or
518: form data.
519: */
520: p = malloc((size_t)(data->set.postfieldsize?
521: data->set.postfieldsize:1));
522:
523: if(!p)
524: result = CURLE_OUT_OF_MEMORY;
525: else {
526: if(data->set.postfieldsize)
527: memcpy(p, argptr, (size_t)data->set.postfieldsize);
528:
529: data->set.str[STRING_COPYPOSTFIELDS] = p;
530: }
531: }
532: }
533:
534: data->set.postfields = data->set.str[STRING_COPYPOSTFIELDS];
535: data->set.httpreq = HTTPREQ_POST;
536: break;
537:
538: case CURLOPT_POSTFIELDS:
539: /*
540: * Like above, but use static data instead of copying it.
541: */
542: data->set.postfields = va_arg(param, void *);
543: /* Release old copied data. */
544: (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
545: data->set.httpreq = HTTPREQ_POST;
546: break;
547:
548: case CURLOPT_POSTFIELDSIZE:
549: /*
550: * The size of the POSTFIELD data to prevent libcurl to do strlen() to
551: * figure it out. Enables binary posts.
552: */
553: bigsize = va_arg(param, long);
554: if(bigsize < -1)
555: return CURLE_BAD_FUNCTION_ARGUMENT;
556:
557: if(data->set.postfieldsize < bigsize &&
558: data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
559: /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
560: (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
561: data->set.postfields = NULL;
562: }
563:
564: data->set.postfieldsize = bigsize;
565: break;
566:
567: case CURLOPT_POSTFIELDSIZE_LARGE:
568: /*
569: * The size of the POSTFIELD data to prevent libcurl to do strlen() to
570: * figure it out. Enables binary posts.
571: */
572: bigsize = va_arg(param, curl_off_t);
573: if(bigsize < -1)
574: return CURLE_BAD_FUNCTION_ARGUMENT;
575:
576: if(data->set.postfieldsize < bigsize &&
577: data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
578: /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
579: (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
580: data->set.postfields = NULL;
581: }
582:
583: data->set.postfieldsize = bigsize;
584: break;
585:
586: case CURLOPT_HTTPPOST:
587: /*
588: * Set to make us do HTTP POST
589: */
590: data->set.httppost = va_arg(param, struct curl_httppost *);
591: data->set.httpreq = HTTPREQ_POST_FORM;
592: data->set.opt_no_body = FALSE; /* this is implied */
593: break;
594: #endif /* CURL_DISABLE_HTTP */
595:
596: case CURLOPT_MIMEPOST:
597: /*
598: * Set to make us do MIME/form POST
599: */
600: result = Curl_mime_set_subparts(&data->set.mimepost,
601: va_arg(param, curl_mime *), FALSE);
602: if(!result) {
603: data->set.httpreq = HTTPREQ_POST_MIME;
604: data->set.opt_no_body = FALSE; /* this is implied */
605: }
606: break;
607:
608: case CURLOPT_REFERER:
609: /*
610: * String to set in the HTTP Referer: field.
611: */
612: if(data->change.referer_alloc) {
613: Curl_safefree(data->change.referer);
614: data->change.referer_alloc = FALSE;
615: }
616: result = Curl_setstropt(&data->set.str[STRING_SET_REFERER],
617: va_arg(param, char *));
618: data->change.referer = data->set.str[STRING_SET_REFERER];
619: break;
620:
621: case CURLOPT_USERAGENT:
622: /*
623: * String to use in the HTTP User-Agent field
624: */
625: result = Curl_setstropt(&data->set.str[STRING_USERAGENT],
626: va_arg(param, char *));
627: break;
628:
629: case CURLOPT_HTTPHEADER:
630: /*
631: * Set a list with HTTP headers to use (or replace internals with)
632: */
633: data->set.headers = va_arg(param, struct curl_slist *);
634: break;
635:
636: #ifndef CURL_DISABLE_HTTP
637: #ifndef CURL_DISABLE_PROXY
638: case CURLOPT_PROXYHEADER:
639: /*
640: * Set a list with proxy headers to use (or replace internals with)
641: *
642: * Since CURLOPT_HTTPHEADER was the only way to set HTTP headers for a
643: * long time we remain doing it this way until CURLOPT_PROXYHEADER is
644: * used. As soon as this option has been used, if set to anything but
645: * NULL, custom headers for proxies are only picked from this list.
646: *
647: * Set this option to NULL to restore the previous behavior.
648: */
649: data->set.proxyheaders = va_arg(param, struct curl_slist *);
650: break;
651: #endif
652: case CURLOPT_HEADEROPT:
653: /*
654: * Set header option.
655: */
656: arg = va_arg(param, long);
657: data->set.sep_headers = (bool)((arg & CURLHEADER_SEPARATE)? TRUE: FALSE);
658: break;
659:
660: case CURLOPT_HTTP200ALIASES:
661: /*
662: * Set a list of aliases for HTTP 200 in response header
663: */
664: data->set.http200aliases = va_arg(param, struct curl_slist *);
665: break;
666:
667: #if !defined(CURL_DISABLE_COOKIES)
668: case CURLOPT_COOKIE:
669: /*
670: * Cookie string to send to the remote server in the request.
671: */
672: result = Curl_setstropt(&data->set.str[STRING_COOKIE],
673: va_arg(param, char *));
674: break;
675:
676: case CURLOPT_COOKIEFILE:
677: /*
678: * Set cookie file to read and parse. Can be used multiple times.
679: */
680: argptr = (char *)va_arg(param, void *);
681: if(argptr) {
682: struct curl_slist *cl;
683: /* append the cookie file name to the list of file names, and deal with
684: them later */
685: cl = curl_slist_append(data->change.cookielist, argptr);
686: if(!cl) {
687: curl_slist_free_all(data->change.cookielist);
688: data->change.cookielist = NULL;
689: return CURLE_OUT_OF_MEMORY;
690: }
691: data->change.cookielist = cl; /* store the list for later use */
692: }
693: break;
694:
695: case CURLOPT_COOKIEJAR:
696: /*
697: * Set cookie file name to dump all cookies to when we're done.
698: */
699: {
700: struct CookieInfo *newcookies;
701: result = Curl_setstropt(&data->set.str[STRING_COOKIEJAR],
702: va_arg(param, char *));
703:
704: /*
705: * Activate the cookie parser. This may or may not already
706: * have been made.
707: */
708: newcookies = Curl_cookie_init(data, NULL, data->cookies,
709: data->set.cookiesession);
710: if(!newcookies)
711: result = CURLE_OUT_OF_MEMORY;
712: data->cookies = newcookies;
713: }
714: break;
715:
716: case CURLOPT_COOKIESESSION:
717: /*
718: * Set this option to TRUE to start a new "cookie session". It will
719: * prevent the forthcoming read-cookies-from-file actions to accept
720: * cookies that are marked as being session cookies, as they belong to a
721: * previous session.
722: *
723: * In the original Netscape cookie spec, "session cookies" are cookies
724: * with no expire date set. RFC2109 describes the same action if no
725: * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
726: * a 'Discard' action that can enforce the discard even for cookies that
727: * have a Max-Age.
728: *
729: * We run mostly with the original cookie spec, as hardly anyone implements
730: * anything else.
731: */
732: data->set.cookiesession = (0 != va_arg(param, long)) ? TRUE : FALSE;
733: break;
734:
735: case CURLOPT_COOKIELIST:
736: argptr = va_arg(param, char *);
737:
738: if(argptr == NULL)
739: break;
740:
741: if(strcasecompare(argptr, "ALL")) {
742: /* clear all cookies */
743: Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
744: Curl_cookie_clearall(data->cookies);
745: Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
746: }
747: else if(strcasecompare(argptr, "SESS")) {
748: /* clear session cookies */
749: Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
750: Curl_cookie_clearsess(data->cookies);
751: Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
752: }
753: else if(strcasecompare(argptr, "FLUSH")) {
754: /* flush cookies to file, takes care of the locking */
755: Curl_flush_cookies(data, FALSE);
756: }
757: else if(strcasecompare(argptr, "RELOAD")) {
758: /* reload cookies from file */
759: Curl_cookie_loadfiles(data);
760: break;
761: }
762: else {
763: if(!data->cookies)
764: /* if cookie engine was not running, activate it */
765: data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE);
766:
767: argptr = strdup(argptr);
768: if(!argptr || !data->cookies) {
769: result = CURLE_OUT_OF_MEMORY;
770: free(argptr);
771: }
772: else {
773: Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
774:
775: if(checkprefix("Set-Cookie:", argptr))
776: /* HTTP Header format line */
777: Curl_cookie_add(data, data->cookies, TRUE, FALSE, argptr + 11, NULL,
778: NULL, TRUE);
779:
780: else
781: /* Netscape format line */
782: Curl_cookie_add(data, data->cookies, FALSE, FALSE, argptr, NULL,
783: NULL, TRUE);
784:
785: Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
786: free(argptr);
787: }
788: }
789:
790: break;
791: #endif /* !CURL_DISABLE_COOKIES */
792:
793: case CURLOPT_HTTPGET:
794: /*
795: * Set to force us do HTTP GET
796: */
797: if(va_arg(param, long)) {
798: data->set.httpreq = HTTPREQ_GET;
799: data->set.upload = FALSE; /* switch off upload */
800: data->set.opt_no_body = FALSE; /* this is implied */
801: }
802: break;
803:
804: case CURLOPT_HTTP_VERSION:
805: /*
806: * This sets a requested HTTP version to be used. The value is one of
807: * the listed enums in curl/curl.h.
808: */
809: arg = va_arg(param, long);
810: if(arg < CURL_HTTP_VERSION_NONE)
811: return CURLE_BAD_FUNCTION_ARGUMENT;
812: #ifdef ENABLE_QUIC
813: if(arg == CURL_HTTP_VERSION_3)
814: ;
815: else
816: #endif
817: #ifndef USE_NGHTTP2
818: if(arg >= CURL_HTTP_VERSION_2)
819: return CURLE_UNSUPPORTED_PROTOCOL;
820: #else
821: if(arg >= CURL_HTTP_VERSION_LAST)
822: return CURLE_UNSUPPORTED_PROTOCOL;
823: if(arg == CURL_HTTP_VERSION_NONE)
824: arg = CURL_HTTP_VERSION_2TLS;
825: #endif
826: data->set.httpversion = arg;
827: break;
828:
829: case CURLOPT_EXPECT_100_TIMEOUT_MS:
830: /*
831: * Time to wait for a response to a HTTP request containing an
832: * Expect: 100-continue header before sending the data anyway.
833: */
834: arg = va_arg(param, long);
835: if(arg < 0)
836: return CURLE_BAD_FUNCTION_ARGUMENT;
837: data->set.expect_100_timeout = arg;
838: break;
839:
840: case CURLOPT_HTTP09_ALLOWED:
841: arg = va_arg(param, unsigned long);
842: if(arg > 1L)
843: return CURLE_BAD_FUNCTION_ARGUMENT;
844: data->set.http09_allowed = arg ? TRUE : FALSE;
845: break;
846: #endif /* CURL_DISABLE_HTTP */
847:
848: case CURLOPT_HTTPAUTH:
849: /*
850: * Set HTTP Authentication type BITMASK.
851: */
852: {
853: int bitcheck;
854: bool authbits;
855: unsigned long auth = va_arg(param, unsigned long);
856:
857: if(auth == CURLAUTH_NONE) {
858: data->set.httpauth = auth;
859: break;
860: }
861:
862: /* the DIGEST_IE bit is only used to set a special marker, for all the
863: rest we need to handle it as normal DIGEST */
864: data->state.authhost.iestyle =
865: (bool)((auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE);
866:
867: if(auth & CURLAUTH_DIGEST_IE) {
868: auth |= CURLAUTH_DIGEST; /* set standard digest bit */
869: auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
870: }
871:
872: /* switch off bits we can't support */
873: #ifndef USE_NTLM
874: auth &= ~CURLAUTH_NTLM; /* no NTLM support */
875: auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
876: #elif !defined(NTLM_WB_ENABLED)
877: auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
878: #endif
879: #ifndef USE_SPNEGO
880: auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without
881: GSS-API or SSPI */
882: #endif
883:
884: /* check if any auth bit lower than CURLAUTH_ONLY is still set */
885: bitcheck = 0;
886: authbits = FALSE;
887: while(bitcheck < 31) {
888: if(auth & (1UL << bitcheck++)) {
889: authbits = TRUE;
890: break;
891: }
892: }
893: if(!authbits)
894: return CURLE_NOT_BUILT_IN; /* no supported types left! */
895:
896: data->set.httpauth = auth;
897: }
898: break;
899:
900: case CURLOPT_CUSTOMREQUEST:
901: /*
902: * Set a custom string to use as request
903: */
904: result = Curl_setstropt(&data->set.str[STRING_CUSTOMREQUEST],
905: va_arg(param, char *));
906:
907: /* we don't set
908: data->set.httpreq = HTTPREQ_CUSTOM;
909: here, we continue as if we were using the already set type
910: and this just changes the actual request keyword */
911: break;
912:
913: #ifndef CURL_DISABLE_PROXY
914: case CURLOPT_HTTPPROXYTUNNEL:
915: /*
916: * Tunnel operations through the proxy instead of normal proxy use
917: */
918: data->set.tunnel_thru_httpproxy = (0 != va_arg(param, long)) ?
919: TRUE : FALSE;
920: break;
921:
922: case CURLOPT_PROXYPORT:
923: /*
924: * Explicitly set HTTP proxy port number.
925: */
926: arg = va_arg(param, long);
927: if((arg < 0) || (arg > 65535))
928: return CURLE_BAD_FUNCTION_ARGUMENT;
929: data->set.proxyport = arg;
930: break;
931:
932: case CURLOPT_PROXYAUTH:
933: /*
934: * Set HTTP Authentication type BITMASK.
935: */
936: {
937: int bitcheck;
938: bool authbits;
939: unsigned long auth = va_arg(param, unsigned long);
940:
941: if(auth == CURLAUTH_NONE) {
942: data->set.proxyauth = auth;
943: break;
944: }
945:
946: /* the DIGEST_IE bit is only used to set a special marker, for all the
947: rest we need to handle it as normal DIGEST */
948: data->state.authproxy.iestyle =
949: (bool)((auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE);
950:
951: if(auth & CURLAUTH_DIGEST_IE) {
952: auth |= CURLAUTH_DIGEST; /* set standard digest bit */
953: auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
954: }
955: /* switch off bits we can't support */
956: #ifndef USE_NTLM
957: auth &= ~CURLAUTH_NTLM; /* no NTLM support */
958: auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
959: #elif !defined(NTLM_WB_ENABLED)
960: auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
961: #endif
962: #ifndef USE_SPNEGO
963: auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without
964: GSS-API or SSPI */
965: #endif
966:
967: /* check if any auth bit lower than CURLAUTH_ONLY is still set */
968: bitcheck = 0;
969: authbits = FALSE;
970: while(bitcheck < 31) {
971: if(auth & (1UL << bitcheck++)) {
972: authbits = TRUE;
973: break;
974: }
975: }
976: if(!authbits)
977: return CURLE_NOT_BUILT_IN; /* no supported types left! */
978:
979: data->set.proxyauth = auth;
980: }
981: break;
982:
983: case CURLOPT_PROXY:
984: /*
985: * Set proxy server:port to use as proxy.
986: *
987: * If the proxy is set to "" (and CURLOPT_SOCKS_PROXY is set to "" or NULL)
988: * we explicitly say that we don't want to use a proxy
989: * (even though there might be environment variables saying so).
990: *
991: * Setting it to NULL, means no proxy but allows the environment variables
992: * to decide for us (if CURLOPT_SOCKS_PROXY setting it to NULL).
993: */
994: result = Curl_setstropt(&data->set.str[STRING_PROXY],
995: va_arg(param, char *));
996: break;
997:
998: case CURLOPT_PRE_PROXY:
999: /*
1000: * Set proxy server:port to use as SOCKS proxy.
1001: *
1002: * If the proxy is set to "" or NULL we explicitly say that we don't want
1003: * to use the socks proxy.
1004: */
1005: result = Curl_setstropt(&data->set.str[STRING_PRE_PROXY],
1006: va_arg(param, char *));
1007: break;
1008:
1009: case CURLOPT_PROXYTYPE:
1010: /*
1011: * Set proxy type. HTTP/HTTP_1_0/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME
1012: */
1013: arg = va_arg(param, long);
1014: if((arg < CURLPROXY_HTTP) || (arg > CURLPROXY_SOCKS5_HOSTNAME))
1015: return CURLE_BAD_FUNCTION_ARGUMENT;
1016: data->set.proxytype = (curl_proxytype)arg;
1017: break;
1018:
1019: case CURLOPT_PROXY_TRANSFER_MODE:
1020: /*
1021: * set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy
1022: */
1023: switch(va_arg(param, long)) {
1024: case 0:
1025: data->set.proxy_transfer_mode = FALSE;
1026: break;
1027: case 1:
1028: data->set.proxy_transfer_mode = TRUE;
1029: break;
1030: default:
1031: /* reserve other values for future use */
1032: result = CURLE_UNKNOWN_OPTION;
1033: break;
1034: }
1035: break;
1036: #endif /* CURL_DISABLE_PROXY */
1037:
1038: case CURLOPT_SOCKS5_AUTH:
1039: data->set.socks5auth = va_arg(param, unsigned long);
1040: if(data->set.socks5auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI))
1041: result = CURLE_NOT_BUILT_IN;
1042: break;
1043: #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
1044: case CURLOPT_SOCKS5_GSSAPI_NEC:
1045: /*
1046: * Set flag for NEC SOCK5 support
1047: */
1048: data->set.socks5_gssapi_nec = (0 != va_arg(param, long)) ? TRUE : FALSE;
1049: break;
1050: #endif
1051: #ifndef CURL_DISABLE_PROXY
1052: case CURLOPT_SOCKS5_GSSAPI_SERVICE:
1053: case CURLOPT_PROXY_SERVICE_NAME:
1054: /*
1055: * Set proxy authentication service name for Kerberos 5 and SPNEGO
1056: */
1057: result = Curl_setstropt(&data->set.str[STRING_PROXY_SERVICE_NAME],
1058: va_arg(param, char *));
1059: break;
1060: #endif
1061: case CURLOPT_SERVICE_NAME:
1062: /*
1063: * Set authentication service name for DIGEST-MD5, Kerberos 5 and SPNEGO
1064: */
1065: result = Curl_setstropt(&data->set.str[STRING_SERVICE_NAME],
1066: va_arg(param, char *));
1067: break;
1068:
1069: case CURLOPT_HEADERDATA:
1070: /*
1071: * Custom pointer to pass the header write callback function
1072: */
1073: data->set.writeheader = (void *)va_arg(param, void *);
1074: break;
1075: case CURLOPT_ERRORBUFFER:
1076: /*
1077: * Error buffer provided by the caller to get the human readable
1078: * error string in.
1079: */
1080: data->set.errorbuffer = va_arg(param, char *);
1081: break;
1082: case CURLOPT_WRITEDATA:
1083: /*
1084: * FILE pointer to write to. Or possibly
1085: * used as argument to the write callback.
1086: */
1087: data->set.out = va_arg(param, void *);
1088: break;
1089:
1090: case CURLOPT_DIRLISTONLY:
1091: /*
1092: * An option that changes the command to one that asks for a list only, no
1093: * file info details. Used for FTP, POP3 and SFTP.
1094: */
1095: data->set.ftp_list_only = (0 != va_arg(param, long)) ? TRUE : FALSE;
1096: break;
1097:
1098: case CURLOPT_APPEND:
1099: /*
1100: * We want to upload and append to an existing file. Used for FTP and
1101: * SFTP.
1102: */
1103: data->set.ftp_append = (0 != va_arg(param, long)) ? TRUE : FALSE;
1104: break;
1105:
1106: #ifndef CURL_DISABLE_FTP
1107: case CURLOPT_FTP_FILEMETHOD:
1108: /*
1109: * How do access files over FTP.
1110: */
1111: arg = va_arg(param, long);
1112: if((arg < CURLFTPMETHOD_DEFAULT) || (arg >= CURLFTPMETHOD_LAST))
1113: return CURLE_BAD_FUNCTION_ARGUMENT;
1114: data->set.ftp_filemethod = (curl_ftpfile)arg;
1115: break;
1116: case CURLOPT_FTPPORT:
1117: /*
1118: * Use FTP PORT, this also specifies which IP address to use
1119: */
1120: result = Curl_setstropt(&data->set.str[STRING_FTPPORT],
1121: va_arg(param, char *));
1122: data->set.ftp_use_port = (data->set.str[STRING_FTPPORT]) ? TRUE : FALSE;
1123: break;
1124:
1125: case CURLOPT_FTP_USE_EPRT:
1126: data->set.ftp_use_eprt = (0 != va_arg(param, long)) ? TRUE : FALSE;
1127: break;
1128:
1129: case CURLOPT_FTP_USE_EPSV:
1130: data->set.ftp_use_epsv = (0 != va_arg(param, long)) ? TRUE : FALSE;
1131: break;
1132:
1133: case CURLOPT_FTP_USE_PRET:
1134: data->set.ftp_use_pret = (0 != va_arg(param, long)) ? TRUE : FALSE;
1135: break;
1136:
1137: case CURLOPT_FTP_SSL_CCC:
1138: arg = va_arg(param, long);
1139: if((arg < CURLFTPSSL_CCC_NONE) || (arg >= CURLFTPSSL_CCC_LAST))
1140: return CURLE_BAD_FUNCTION_ARGUMENT;
1141: data->set.ftp_ccc = (curl_ftpccc)arg;
1142: break;
1143:
1144: case CURLOPT_FTP_SKIP_PASV_IP:
1145: /*
1146: * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the
1147: * bypass of the IP address in PASV responses.
1148: */
1149: data->set.ftp_skip_ip = (0 != va_arg(param, long)) ? TRUE : FALSE;
1150: break;
1151:
1152: case CURLOPT_FTP_ACCOUNT:
1153: result = Curl_setstropt(&data->set.str[STRING_FTP_ACCOUNT],
1154: va_arg(param, char *));
1155: break;
1156:
1157: case CURLOPT_FTP_ALTERNATIVE_TO_USER:
1158: result = Curl_setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER],
1159: va_arg(param, char *));
1160: break;
1161:
1162: case CURLOPT_FTPSSLAUTH:
1163: /*
1164: * Set a specific auth for FTP-SSL transfers.
1165: */
1166: arg = va_arg(param, long);
1167: if((arg < CURLFTPAUTH_DEFAULT) || (arg >= CURLFTPAUTH_LAST))
1168: return CURLE_BAD_FUNCTION_ARGUMENT;
1169: data->set.ftpsslauth = (curl_ftpauth)arg;
1170: break;
1171: case CURLOPT_KRBLEVEL:
1172: /*
1173: * A string that defines the kerberos security level.
1174: */
1175: result = Curl_setstropt(&data->set.str[STRING_KRB_LEVEL],
1176: va_arg(param, char *));
1177: data->set.krb = (data->set.str[STRING_KRB_LEVEL]) ? TRUE : FALSE;
1178: break;
1179: #endif
1180: case CURLOPT_FTP_CREATE_MISSING_DIRS:
1181: /*
1182: * An FTP/SFTP option that modifies an upload to create missing
1183: * directories on the server.
1184: */
1185: switch(va_arg(param, long)) {
1186: case 0:
1187: data->set.ftp_create_missing_dirs = 0;
1188: break;
1189: case 1:
1190: data->set.ftp_create_missing_dirs = 1;
1191: break;
1192: case 2:
1193: data->set.ftp_create_missing_dirs = 2;
1194: break;
1195: default:
1196: /* reserve other values for future use */
1197: result = CURLE_UNKNOWN_OPTION;
1198: break;
1199: }
1200: break;
1201: case CURLOPT_READDATA:
1202: /*
1203: * FILE pointer to read the file to be uploaded from. Or possibly
1204: * used as argument to the read callback.
1205: */
1206: data->set.in_set = va_arg(param, void *);
1207: break;
1208: case CURLOPT_INFILESIZE:
1209: /*
1210: * If known, this should inform curl about the file size of the
1211: * to-be-uploaded file.
1212: */
1213: arg = va_arg(param, long);
1214: if(arg < -1)
1215: return CURLE_BAD_FUNCTION_ARGUMENT;
1216: data->set.filesize = arg;
1217: break;
1218: case CURLOPT_INFILESIZE_LARGE:
1219: /*
1220: * If known, this should inform curl about the file size of the
1221: * to-be-uploaded file.
1222: */
1223: bigsize = va_arg(param, curl_off_t);
1224: if(bigsize < -1)
1225: return CURLE_BAD_FUNCTION_ARGUMENT;
1226: data->set.filesize = bigsize;
1227: break;
1228: case CURLOPT_LOW_SPEED_LIMIT:
1229: /*
1230: * The low speed limit that if transfers are below this for
1231: * CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
1232: */
1233: arg = va_arg(param, long);
1234: if(arg < 0)
1235: return CURLE_BAD_FUNCTION_ARGUMENT;
1236: data->set.low_speed_limit = arg;
1237: break;
1238: case CURLOPT_MAX_SEND_SPEED_LARGE:
1239: /*
1240: * When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE
1241: * bytes per second the transfer is throttled..
1242: */
1243: bigsize = va_arg(param, curl_off_t);
1244: if(bigsize < 0)
1245: return CURLE_BAD_FUNCTION_ARGUMENT;
1246: data->set.max_send_speed = bigsize;
1247: break;
1248: case CURLOPT_MAX_RECV_SPEED_LARGE:
1249: /*
1250: * When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per
1251: * second the transfer is throttled..
1252: */
1253: bigsize = va_arg(param, curl_off_t);
1254: if(bigsize < 0)
1255: return CURLE_BAD_FUNCTION_ARGUMENT;
1256: data->set.max_recv_speed = bigsize;
1257: break;
1258: case CURLOPT_LOW_SPEED_TIME:
1259: /*
1260: * The low speed time that if transfers are below the set
1261: * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
1262: */
1263: arg = va_arg(param, long);
1264: if(arg < 0)
1265: return CURLE_BAD_FUNCTION_ARGUMENT;
1266: data->set.low_speed_time = arg;
1267: break;
1268: case CURLOPT_CURLU:
1269: /*
1270: * pass CURLU to set URL
1271: */
1272: data->set.uh = va_arg(param, CURLU *);
1273: break;
1274: case CURLOPT_URL:
1275: /*
1276: * The URL to fetch.
1277: */
1278: if(data->change.url_alloc) {
1279: /* the already set URL is allocated, free it first! */
1280: Curl_safefree(data->change.url);
1281: data->change.url_alloc = FALSE;
1282: }
1283: result = Curl_setstropt(&data->set.str[STRING_SET_URL],
1284: va_arg(param, char *));
1285: data->change.url = data->set.str[STRING_SET_URL];
1286: break;
1287: case CURLOPT_PORT:
1288: /*
1289: * The port number to use when getting the URL
1290: */
1291: arg = va_arg(param, long);
1292: if((arg < 0) || (arg > 65535))
1293: return CURLE_BAD_FUNCTION_ARGUMENT;
1294: data->set.use_port = arg;
1295: break;
1296: case CURLOPT_TIMEOUT:
1297: /*
1298: * The maximum time you allow curl to use for a single transfer
1299: * operation.
1300: */
1301: arg = va_arg(param, long);
1302: if((arg >= 0) && (arg <= (INT_MAX/1000)))
1303: data->set.timeout = arg * 1000;
1304: else
1305: return CURLE_BAD_FUNCTION_ARGUMENT;
1306: break;
1307:
1308: case CURLOPT_TIMEOUT_MS:
1309: arg = va_arg(param, long);
1310: if(arg < 0)
1311: return CURLE_BAD_FUNCTION_ARGUMENT;
1312: data->set.timeout = arg;
1313: break;
1314:
1315: case CURLOPT_CONNECTTIMEOUT:
1316: /*
1317: * The maximum time you allow curl to use to connect.
1318: */
1319: arg = va_arg(param, long);
1320: if((arg >= 0) && (arg <= (INT_MAX/1000)))
1321: data->set.connecttimeout = arg * 1000;
1322: else
1323: return CURLE_BAD_FUNCTION_ARGUMENT;
1324: break;
1325:
1326: case CURLOPT_CONNECTTIMEOUT_MS:
1327: arg = va_arg(param, long);
1328: if(arg < 0)
1329: return CURLE_BAD_FUNCTION_ARGUMENT;
1330: data->set.connecttimeout = arg;
1331: break;
1332:
1333: case CURLOPT_ACCEPTTIMEOUT_MS:
1334: /*
1335: * The maximum time you allow curl to wait for server connect
1336: */
1337: arg = va_arg(param, long);
1338: if(arg < 0)
1339: return CURLE_BAD_FUNCTION_ARGUMENT;
1340: data->set.accepttimeout = arg;
1341: break;
1342:
1343: case CURLOPT_USERPWD:
1344: /*
1345: * user:password to use in the operation
1346: */
1347: result = setstropt_userpwd(va_arg(param, char *),
1348: &data->set.str[STRING_USERNAME],
1349: &data->set.str[STRING_PASSWORD]);
1350: break;
1351:
1352: case CURLOPT_USERNAME:
1353: /*
1354: * authentication user name to use in the operation
1355: */
1356: result = Curl_setstropt(&data->set.str[STRING_USERNAME],
1357: va_arg(param, char *));
1358: break;
1359:
1360: case CURLOPT_PASSWORD:
1361: /*
1362: * authentication password to use in the operation
1363: */
1364: result = Curl_setstropt(&data->set.str[STRING_PASSWORD],
1365: va_arg(param, char *));
1366: break;
1367:
1368: case CURLOPT_LOGIN_OPTIONS:
1369: /*
1370: * authentication options to use in the operation
1371: */
1372: result = Curl_setstropt(&data->set.str[STRING_OPTIONS],
1373: va_arg(param, char *));
1374: break;
1375:
1376: case CURLOPT_XOAUTH2_BEARER:
1377: /*
1378: * OAuth 2.0 bearer token to use in the operation
1379: */
1380: result = Curl_setstropt(&data->set.str[STRING_BEARER],
1381: va_arg(param, char *));
1382: break;
1383:
1384: case CURLOPT_POSTQUOTE:
1385: /*
1386: * List of RAW FTP commands to use after a transfer
1387: */
1388: data->set.postquote = va_arg(param, struct curl_slist *);
1389: break;
1390: case CURLOPT_PREQUOTE:
1391: /*
1392: * List of RAW FTP commands to use prior to RETR (Wesley Laxton)
1393: */
1394: data->set.prequote = va_arg(param, struct curl_slist *);
1395: break;
1396: case CURLOPT_QUOTE:
1397: /*
1398: * List of RAW FTP commands to use before a transfer
1399: */
1400: data->set.quote = va_arg(param, struct curl_slist *);
1401: break;
1402: case CURLOPT_RESOLVE:
1403: /*
1404: * List of NAME:[address] names to populate the DNS cache with
1405: * Prefix the NAME with dash (-) to _remove_ the name from the cache.
1406: *
1407: * Names added with this API will remain in the cache until explicitly
1408: * removed or the handle is cleaned up.
1409: *
1410: * This API can remove any name from the DNS cache, but only entries
1411: * that aren't actually in use right now will be pruned immediately.
1412: */
1413: data->set.resolve = va_arg(param, struct curl_slist *);
1414: data->change.resolve = data->set.resolve;
1415: break;
1416: case CURLOPT_PROGRESSFUNCTION:
1417: /*
1418: * Progress callback function
1419: */
1420: data->set.fprogress = va_arg(param, curl_progress_callback);
1421: if(data->set.fprogress)
1422: data->progress.callback = TRUE; /* no longer internal */
1423: else
1424: data->progress.callback = FALSE; /* NULL enforces internal */
1425: break;
1426:
1427: case CURLOPT_XFERINFOFUNCTION:
1428: /*
1429: * Transfer info callback function
1430: */
1431: data->set.fxferinfo = va_arg(param, curl_xferinfo_callback);
1432: if(data->set.fxferinfo)
1433: data->progress.callback = TRUE; /* no longer internal */
1434: else
1435: data->progress.callback = FALSE; /* NULL enforces internal */
1436:
1437: break;
1438:
1439: case CURLOPT_PROGRESSDATA:
1440: /*
1441: * Custom client data to pass to the progress callback
1442: */
1443: data->set.progress_client = va_arg(param, void *);
1444: break;
1445:
1446: #ifndef CURL_DISABLE_PROXY
1447: case CURLOPT_PROXYUSERPWD:
1448: /*
1449: * user:password needed to use the proxy
1450: */
1451: result = setstropt_userpwd(va_arg(param, char *),
1452: &data->set.str[STRING_PROXYUSERNAME],
1453: &data->set.str[STRING_PROXYPASSWORD]);
1454: break;
1455: case CURLOPT_PROXYUSERNAME:
1456: /*
1457: * authentication user name to use in the operation
1458: */
1459: result = Curl_setstropt(&data->set.str[STRING_PROXYUSERNAME],
1460: va_arg(param, char *));
1461: break;
1462: case CURLOPT_PROXYPASSWORD:
1463: /*
1464: * authentication password to use in the operation
1465: */
1466: result = Curl_setstropt(&data->set.str[STRING_PROXYPASSWORD],
1467: va_arg(param, char *));
1468: break;
1469: case CURLOPT_NOPROXY:
1470: /*
1471: * proxy exception list
1472: */
1473: result = Curl_setstropt(&data->set.str[STRING_NOPROXY],
1474: va_arg(param, char *));
1475: break;
1476: #endif
1477:
1478: case CURLOPT_RANGE:
1479: /*
1480: * What range of the file you want to transfer
1481: */
1482: result = Curl_setstropt(&data->set.str[STRING_SET_RANGE],
1483: va_arg(param, char *));
1484: break;
1485: case CURLOPT_RESUME_FROM:
1486: /*
1487: * Resume transfer at the given file position
1488: */
1489: arg = va_arg(param, long);
1490: if(arg < -1)
1491: return CURLE_BAD_FUNCTION_ARGUMENT;
1492: data->set.set_resume_from = arg;
1493: break;
1494: case CURLOPT_RESUME_FROM_LARGE:
1495: /*
1496: * Resume transfer at the given file position
1497: */
1498: bigsize = va_arg(param, curl_off_t);
1499: if(bigsize < -1)
1500: return CURLE_BAD_FUNCTION_ARGUMENT;
1501: data->set.set_resume_from = bigsize;
1502: break;
1503: case CURLOPT_DEBUGFUNCTION:
1504: /*
1505: * stderr write callback.
1506: */
1507: data->set.fdebug = va_arg(param, curl_debug_callback);
1508: /*
1509: * if the callback provided is NULL, it'll use the default callback
1510: */
1511: break;
1512: case CURLOPT_DEBUGDATA:
1513: /*
1514: * Set to a void * that should receive all error writes. This
1515: * defaults to CURLOPT_STDERR for normal operations.
1516: */
1517: data->set.debugdata = va_arg(param, void *);
1518: break;
1519: case CURLOPT_STDERR:
1520: /*
1521: * Set to a FILE * that should receive all error writes. This
1522: * defaults to stderr for normal operations.
1523: */
1524: data->set.err = va_arg(param, FILE *);
1525: if(!data->set.err)
1526: data->set.err = stderr;
1527: break;
1528: case CURLOPT_HEADERFUNCTION:
1529: /*
1530: * Set header write callback
1531: */
1532: data->set.fwrite_header = va_arg(param, curl_write_callback);
1533: break;
1534: case CURLOPT_WRITEFUNCTION:
1535: /*
1536: * Set data write callback
1537: */
1538: data->set.fwrite_func = va_arg(param, curl_write_callback);
1539: if(!data->set.fwrite_func) {
1540: data->set.is_fwrite_set = 0;
1541: /* When set to NULL, reset to our internal default function */
1542: data->set.fwrite_func = (curl_write_callback)fwrite;
1543: }
1544: else
1545: data->set.is_fwrite_set = 1;
1546: break;
1547: case CURLOPT_READFUNCTION:
1548: /*
1549: * Read data callback
1550: */
1551: data->set.fread_func_set = va_arg(param, curl_read_callback);
1552: if(!data->set.fread_func_set) {
1553: data->set.is_fread_set = 0;
1554: /* When set to NULL, reset to our internal default function */
1555: data->set.fread_func_set = (curl_read_callback)fread;
1556: }
1557: else
1558: data->set.is_fread_set = 1;
1559: break;
1560: case CURLOPT_SEEKFUNCTION:
1561: /*
1562: * Seek callback. Might be NULL.
1563: */
1564: data->set.seek_func = va_arg(param, curl_seek_callback);
1565: break;
1566: case CURLOPT_SEEKDATA:
1567: /*
1568: * Seek control callback. Might be NULL.
1569: */
1570: data->set.seek_client = va_arg(param, void *);
1571: break;
1572: case CURLOPT_CONV_FROM_NETWORK_FUNCTION:
1573: /*
1574: * "Convert from network encoding" callback
1575: */
1576: data->set.convfromnetwork = va_arg(param, curl_conv_callback);
1577: break;
1578: case CURLOPT_CONV_TO_NETWORK_FUNCTION:
1579: /*
1580: * "Convert to network encoding" callback
1581: */
1582: data->set.convtonetwork = va_arg(param, curl_conv_callback);
1583: break;
1584: case CURLOPT_CONV_FROM_UTF8_FUNCTION:
1585: /*
1586: * "Convert from UTF-8 encoding" callback
1587: */
1588: data->set.convfromutf8 = va_arg(param, curl_conv_callback);
1589: break;
1590: case CURLOPT_IOCTLFUNCTION:
1591: /*
1592: * I/O control callback. Might be NULL.
1593: */
1594: data->set.ioctl_func = va_arg(param, curl_ioctl_callback);
1595: break;
1596: case CURLOPT_IOCTLDATA:
1597: /*
1598: * I/O control data pointer. Might be NULL.
1599: */
1600: data->set.ioctl_client = va_arg(param, void *);
1601: break;
1602: case CURLOPT_SSLCERT:
1603: /*
1604: * String that holds file name of the SSL certificate to use
1605: */
1606: result = Curl_setstropt(&data->set.str[STRING_CERT_ORIG],
1607: va_arg(param, char *));
1608: break;
1609: #ifndef CURL_DISABLE_PROXY
1610: case CURLOPT_PROXY_SSLCERT:
1611: /*
1612: * String that holds file name of the SSL certificate to use for proxy
1613: */
1614: result = Curl_setstropt(&data->set.str[STRING_CERT_PROXY],
1615: va_arg(param, char *));
1616: break;
1617: #endif
1618: case CURLOPT_SSLCERTTYPE:
1619: /*
1620: * String that holds file type of the SSL certificate to use
1621: */
1622: result = Curl_setstropt(&data->set.str[STRING_CERT_TYPE_ORIG],
1623: va_arg(param, char *));
1624: break;
1625: #ifndef CURL_DISABLE_PROXY
1626: case CURLOPT_PROXY_SSLCERTTYPE:
1627: /*
1628: * String that holds file type of the SSL certificate to use for proxy
1629: */
1630: result = Curl_setstropt(&data->set.str[STRING_CERT_TYPE_PROXY],
1631: va_arg(param, char *));
1632: break;
1633: #endif
1634: case CURLOPT_SSLKEY:
1635: /*
1636: * String that holds file name of the SSL key to use
1637: */
1638: result = Curl_setstropt(&data->set.str[STRING_KEY_ORIG],
1639: va_arg(param, char *));
1640: break;
1641: #ifndef CURL_DISABLE_PROXY
1642: case CURLOPT_PROXY_SSLKEY:
1643: /*
1644: * String that holds file name of the SSL key to use for proxy
1645: */
1646: result = Curl_setstropt(&data->set.str[STRING_KEY_PROXY],
1647: va_arg(param, char *));
1648: break;
1649: #endif
1650: case CURLOPT_SSLKEYTYPE:
1651: /*
1652: * String that holds file type of the SSL key to use
1653: */
1654: result = Curl_setstropt(&data->set.str[STRING_KEY_TYPE_ORIG],
1655: va_arg(param, char *));
1656: break;
1657: #ifndef CURL_DISABLE_PROXY
1658: case CURLOPT_PROXY_SSLKEYTYPE:
1659: /*
1660: * String that holds file type of the SSL key to use for proxy
1661: */
1662: result = Curl_setstropt(&data->set.str[STRING_KEY_TYPE_PROXY],
1663: va_arg(param, char *));
1664: break;
1665: #endif
1666: case CURLOPT_KEYPASSWD:
1667: /*
1668: * String that holds the SSL or SSH private key password.
1669: */
1670: result = Curl_setstropt(&data->set.str[STRING_KEY_PASSWD_ORIG],
1671: va_arg(param, char *));
1672: break;
1673: #ifndef CURL_DISABLE_PROXY
1674: case CURLOPT_PROXY_KEYPASSWD:
1675: /*
1676: * String that holds the SSL private key password for proxy.
1677: */
1678: result = Curl_setstropt(&data->set.str[STRING_KEY_PASSWD_PROXY],
1679: va_arg(param, char *));
1680: break;
1681: #endif
1682: case CURLOPT_SSLENGINE:
1683: /*
1684: * String that holds the SSL crypto engine.
1685: */
1686: argptr = va_arg(param, char *);
1687: if(argptr && argptr[0]) {
1688: result = Curl_setstropt(&data->set.str[STRING_SSL_ENGINE], argptr);
1689: if(!result) {
1690: result = Curl_ssl_set_engine(data, argptr);
1691: }
1692: }
1693: break;
1694:
1695: case CURLOPT_SSLENGINE_DEFAULT:
1696: /*
1697: * flag to set engine as default.
1698: */
1699: Curl_setstropt(&data->set.str[STRING_SSL_ENGINE], NULL);
1700: result = Curl_ssl_set_engine_default(data);
1701: break;
1702: case CURLOPT_CRLF:
1703: /*
1704: * Kludgy option to enable CRLF conversions. Subject for removal.
1705: */
1706: data->set.crlf = (0 != va_arg(param, long)) ? TRUE : FALSE;
1707: break;
1708: #ifndef CURL_DISABLE_PROXY
1709: case CURLOPT_HAPROXYPROTOCOL:
1710: /*
1711: * Set to send the HAProxy Proxy Protocol header
1712: */
1713: data->set.haproxyprotocol = (0 != va_arg(param, long)) ? TRUE : FALSE;
1714: break;
1715: #endif
1716: case CURLOPT_INTERFACE:
1717: /*
1718: * Set what interface or address/hostname to bind the socket to when
1719: * performing an operation and thus what from-IP your connection will use.
1720: */
1721: result = Curl_setstropt(&data->set.str[STRING_DEVICE],
1722: va_arg(param, char *));
1723: break;
1724: case CURLOPT_LOCALPORT:
1725: /*
1726: * Set what local port to bind the socket to when performing an operation.
1727: */
1728: arg = va_arg(param, long);
1729: if((arg < 0) || (arg > 65535))
1730: return CURLE_BAD_FUNCTION_ARGUMENT;
1731: data->set.localport = curlx_sltous(arg);
1732: break;
1733: case CURLOPT_LOCALPORTRANGE:
1734: /*
1735: * Set number of local ports to try, starting with CURLOPT_LOCALPORT.
1736: */
1737: arg = va_arg(param, long);
1738: if((arg < 0) || (arg > 65535))
1739: return CURLE_BAD_FUNCTION_ARGUMENT;
1740: data->set.localportrange = curlx_sltosi(arg);
1741: break;
1742: case CURLOPT_GSSAPI_DELEGATION:
1743: /*
1744: * GSS-API credential delegation bitmask
1745: */
1746: arg = va_arg(param, long);
1747: if(arg < CURLGSSAPI_DELEGATION_NONE)
1748: return CURLE_BAD_FUNCTION_ARGUMENT;
1749: data->set.gssapi_delegation = arg;
1750: break;
1751: case CURLOPT_SSL_VERIFYPEER:
1752: /*
1753: * Enable peer SSL verifying.
1754: */
1755: data->set.ssl.primary.verifypeer = (0 != va_arg(param, long)) ?
1756: TRUE : FALSE;
1757:
1758: /* Update the current connection ssl_config. */
1759: if(data->conn) {
1760: data->conn->ssl_config.verifypeer =
1761: data->set.ssl.primary.verifypeer;
1762: }
1763: break;
1764: #ifndef CURL_DISABLE_PROXY
1765: case CURLOPT_PROXY_SSL_VERIFYPEER:
1766: /*
1767: * Enable peer SSL verifying for proxy.
1768: */
1769: data->set.proxy_ssl.primary.verifypeer =
1770: (0 != va_arg(param, long))?TRUE:FALSE;
1771:
1772: /* Update the current connection proxy_ssl_config. */
1773: if(data->conn) {
1774: data->conn->proxy_ssl_config.verifypeer =
1775: data->set.proxy_ssl.primary.verifypeer;
1776: }
1777: break;
1778: #endif
1779: case CURLOPT_SSL_VERIFYHOST:
1780: /*
1781: * Enable verification of the host name in the peer certificate
1782: */
1783: arg = va_arg(param, long);
1784:
1785: /* Obviously people are not reading documentation and too many thought
1786: this argument took a boolean when it wasn't and misused it.
1787: Treat 1 and 2 the same */
1788: data->set.ssl.primary.verifyhost = (bool)((arg & 3) ? TRUE : FALSE);
1789:
1790: /* Update the current connection ssl_config. */
1791: if(data->conn) {
1792: data->conn->ssl_config.verifyhost =
1793: data->set.ssl.primary.verifyhost;
1794: }
1795: break;
1796: #ifndef CURL_DISABLE_PROXY
1797: case CURLOPT_PROXY_SSL_VERIFYHOST:
1798: /*
1799: * Enable verification of the host name in the peer certificate for proxy
1800: */
1801: arg = va_arg(param, long);
1802:
1803: /* Treat both 1 and 2 as TRUE */
1804: data->set.proxy_ssl.primary.verifyhost = (bool)((arg & 3)?TRUE:FALSE);
1805:
1806: /* Update the current connection proxy_ssl_config. */
1807: if(data->conn) {
1808: data->conn->proxy_ssl_config.verifyhost =
1809: data->set.proxy_ssl.primary.verifyhost;
1810: }
1811: break;
1812: #endif
1813: case CURLOPT_SSL_VERIFYSTATUS:
1814: /*
1815: * Enable certificate status verifying.
1816: */
1817: if(!Curl_ssl_cert_status_request()) {
1818: result = CURLE_NOT_BUILT_IN;
1819: break;
1820: }
1821:
1822: data->set.ssl.primary.verifystatus = (0 != va_arg(param, long)) ?
1823: TRUE : FALSE;
1824:
1825: /* Update the current connection ssl_config. */
1826: if(data->conn) {
1827: data->conn->ssl_config.verifystatus =
1828: data->set.ssl.primary.verifystatus;
1829: }
1830: break;
1831: case CURLOPT_SSL_CTX_FUNCTION:
1832: /*
1833: * Set a SSL_CTX callback
1834: */
1835: #ifdef USE_SSL
1836: if(Curl_ssl->supports & SSLSUPP_SSL_CTX)
1837: data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
1838: else
1839: #endif
1840: result = CURLE_NOT_BUILT_IN;
1841: break;
1842: case CURLOPT_SSL_CTX_DATA:
1843: /*
1844: * Set a SSL_CTX callback parameter pointer
1845: */
1846: #ifdef USE_SSL
1847: if(Curl_ssl->supports & SSLSUPP_SSL_CTX)
1848: data->set.ssl.fsslctxp = va_arg(param, void *);
1849: else
1850: #endif
1851: result = CURLE_NOT_BUILT_IN;
1852: break;
1853: case CURLOPT_SSL_FALSESTART:
1854: /*
1855: * Enable TLS false start.
1856: */
1857: if(!Curl_ssl_false_start()) {
1858: result = CURLE_NOT_BUILT_IN;
1859: break;
1860: }
1861:
1862: data->set.ssl.falsestart = (0 != va_arg(param, long)) ? TRUE : FALSE;
1863: break;
1864: case CURLOPT_CERTINFO:
1865: #ifdef USE_SSL
1866: if(Curl_ssl->supports & SSLSUPP_CERTINFO)
1867: data->set.ssl.certinfo = (0 != va_arg(param, long)) ? TRUE : FALSE;
1868: else
1869: #endif
1870: result = CURLE_NOT_BUILT_IN;
1871: break;
1872: case CURLOPT_PINNEDPUBLICKEY:
1873: /*
1874: * Set pinned public key for SSL connection.
1875: * Specify file name of the public key in DER format.
1876: */
1877: #ifdef USE_SSL
1878: if(Curl_ssl->supports & SSLSUPP_PINNEDPUBKEY)
1879: result = Curl_setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG],
1880: va_arg(param, char *));
1881: else
1882: #endif
1883: result = CURLE_NOT_BUILT_IN;
1884: break;
1885: #ifndef CURL_DISABLE_PROXY
1886: case CURLOPT_PROXY_PINNEDPUBLICKEY:
1887: /*
1888: * Set pinned public key for SSL connection.
1889: * Specify file name of the public key in DER format.
1890: */
1891: #ifdef USE_SSL
1892: if(Curl_ssl->supports & SSLSUPP_PINNEDPUBKEY)
1893: result = Curl_setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY],
1894: va_arg(param, char *));
1895: else
1896: #endif
1897: result = CURLE_NOT_BUILT_IN;
1898: break;
1899: #endif
1900: case CURLOPT_CAINFO:
1901: /*
1902: * Set CA info for SSL connection. Specify file name of the CA certificate
1903: */
1904: result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE_ORIG],
1905: va_arg(param, char *));
1906: break;
1907: #ifndef CURL_DISABLE_PROXY
1908: case CURLOPT_PROXY_CAINFO:
1909: /*
1910: * Set CA info SSL connection for proxy. Specify file name of the
1911: * CA certificate
1912: */
1913: result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE_PROXY],
1914: va_arg(param, char *));
1915: break;
1916: #endif
1917: case CURLOPT_CAPATH:
1918: /*
1919: * Set CA path info for SSL connection. Specify directory name of the CA
1920: * certificates which have been prepared using openssl c_rehash utility.
1921: */
1922: #ifdef USE_SSL
1923: if(Curl_ssl->supports & SSLSUPP_CA_PATH)
1924: /* This does not work on windows. */
1925: result = Curl_setstropt(&data->set.str[STRING_SSL_CAPATH_ORIG],
1926: va_arg(param, char *));
1927: else
1928: #endif
1929: result = CURLE_NOT_BUILT_IN;
1930: break;
1931: #ifndef CURL_DISABLE_PROXY
1932: case CURLOPT_PROXY_CAPATH:
1933: /*
1934: * Set CA path info for SSL connection proxy. Specify directory name of the
1935: * CA certificates which have been prepared using openssl c_rehash utility.
1936: */
1937: #ifdef USE_SSL
1938: if(Curl_ssl->supports & SSLSUPP_CA_PATH)
1939: /* This does not work on windows. */
1940: result = Curl_setstropt(&data->set.str[STRING_SSL_CAPATH_PROXY],
1941: va_arg(param, char *));
1942: else
1943: #endif
1944: result = CURLE_NOT_BUILT_IN;
1945: break;
1946: #endif
1947: case CURLOPT_CRLFILE:
1948: /*
1949: * Set CRL file info for SSL connection. Specify file name of the CRL
1950: * to check certificates revocation
1951: */
1952: result = Curl_setstropt(&data->set.str[STRING_SSL_CRLFILE_ORIG],
1953: va_arg(param, char *));
1954: break;
1955: #ifndef CURL_DISABLE_PROXY
1956: case CURLOPT_PROXY_CRLFILE:
1957: /*
1958: * Set CRL file info for SSL connection for proxy. Specify file name of the
1959: * CRL to check certificates revocation
1960: */
1961: result = Curl_setstropt(&data->set.str[STRING_SSL_CRLFILE_PROXY],
1962: va_arg(param, char *));
1963: break;
1964: #endif
1965: case CURLOPT_ISSUERCERT:
1966: /*
1967: * Set Issuer certificate file
1968: * to check certificates issuer
1969: */
1970: result = Curl_setstropt(&data->set.str[STRING_SSL_ISSUERCERT_ORIG],
1971: va_arg(param, char *));
1972: break;
1973: #ifndef CURL_DISABLE_TELNET
1974: case CURLOPT_TELNETOPTIONS:
1975: /*
1976: * Set a linked list of telnet options
1977: */
1978: data->set.telnet_options = va_arg(param, struct curl_slist *);
1979: break;
1980: #endif
1981: case CURLOPT_BUFFERSIZE:
1982: /*
1983: * The application kindly asks for a differently sized receive buffer.
1984: * If it seems reasonable, we'll use it.
1985: */
1986: arg = va_arg(param, long);
1987:
1988: if(arg > READBUFFER_MAX)
1989: arg = READBUFFER_MAX;
1990: else if(arg < 1)
1991: arg = READBUFFER_SIZE;
1992: else if(arg < READBUFFER_MIN)
1993: arg = READBUFFER_MIN;
1994:
1995: /* Resize if new size */
1996: if(arg != data->set.buffer_size) {
1997: char *newbuff = realloc(data->state.buffer, arg + 1);
1998: if(!newbuff) {
1999: DEBUGF(fprintf(stderr, "Error: realloc of buffer failed\n"));
2000: result = CURLE_OUT_OF_MEMORY;
2001: }
2002: else
2003: data->state.buffer = newbuff;
2004: }
2005: data->set.buffer_size = arg;
2006:
2007: break;
2008:
2009: case CURLOPT_UPLOAD_BUFFERSIZE:
2010: /*
2011: * The application kindly asks for a differently sized upload buffer.
2012: * Cap it to sensible.
2013: */
2014: arg = va_arg(param, long);
2015:
2016: if(arg > UPLOADBUFFER_MAX)
2017: arg = UPLOADBUFFER_MAX;
2018: else if(arg < UPLOADBUFFER_MIN)
2019: arg = UPLOADBUFFER_MIN;
2020:
2021: data->set.upload_buffer_size = arg;
2022: Curl_safefree(data->state.ulbuf); /* force a realloc next opportunity */
2023: break;
2024:
2025: case CURLOPT_NOSIGNAL:
2026: /*
2027: * The application asks not to set any signal() or alarm() handlers,
2028: * even when using a timeout.
2029: */
2030: data->set.no_signal = (0 != va_arg(param, long)) ? TRUE : FALSE;
2031: break;
2032:
2033: case CURLOPT_SHARE:
2034: {
2035: struct Curl_share *set;
2036: set = va_arg(param, struct Curl_share *);
2037:
2038: /* disconnect from old share, if any */
2039: if(data->share) {
2040: Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
2041:
2042: if(data->dns.hostcachetype == HCACHE_SHARED) {
2043: data->dns.hostcache = NULL;
2044: data->dns.hostcachetype = HCACHE_NONE;
2045: }
2046:
2047: #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
2048: if(data->share->cookies == data->cookies)
2049: data->cookies = NULL;
2050: #endif
2051:
2052: if(data->share->sslsession == data->state.session)
2053: data->state.session = NULL;
2054:
2055: #ifdef USE_LIBPSL
2056: if(data->psl == &data->share->psl)
2057: data->psl = data->multi? &data->multi->psl: NULL;
2058: #endif
2059:
2060: data->share->dirty--;
2061:
2062: Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
2063: data->share = NULL;
2064: }
2065:
2066: /* use new share if it set */
2067: data->share = set;
2068: if(data->share) {
2069:
2070: Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
2071:
2072: data->share->dirty++;
2073:
2074: if(data->share->specifier & (1<< CURL_LOCK_DATA_DNS)) {
2075: /* use shared host cache */
2076: data->dns.hostcache = &data->share->hostcache;
2077: data->dns.hostcachetype = HCACHE_SHARED;
2078: }
2079: #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
2080: if(data->share->cookies) {
2081: /* use shared cookie list, first free own one if any */
2082: Curl_cookie_cleanup(data->cookies);
2083: /* enable cookies since we now use a share that uses cookies! */
2084: data->cookies = data->share->cookies;
2085: }
2086: #endif /* CURL_DISABLE_HTTP */
2087: if(data->share->sslsession) {
2088: data->set.general_ssl.max_ssl_sessions = data->share->max_ssl_sessions;
2089: data->state.session = data->share->sslsession;
2090: }
2091: #ifdef USE_LIBPSL
2092: if(data->share->specifier & (1 << CURL_LOCK_DATA_PSL))
2093: data->psl = &data->share->psl;
2094: #endif
2095:
2096: Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
2097: }
2098: /* check for host cache not needed,
2099: * it will be done by curl_easy_perform */
2100: }
2101: break;
2102:
2103: case CURLOPT_PRIVATE:
2104: /*
2105: * Set private data pointer.
2106: */
2107: data->set.private_data = va_arg(param, void *);
2108: break;
2109:
2110: case CURLOPT_MAXFILESIZE:
2111: /*
2112: * Set the maximum size of a file to download.
2113: */
2114: arg = va_arg(param, long);
2115: if(arg < 0)
2116: return CURLE_BAD_FUNCTION_ARGUMENT;
2117: data->set.max_filesize = arg;
2118: break;
2119:
2120: #ifdef USE_SSL
2121: case CURLOPT_USE_SSL:
2122: /*
2123: * Make transfers attempt to use SSL/TLS.
2124: */
2125: arg = va_arg(param, long);
2126: if((arg < CURLUSESSL_NONE) || (arg >= CURLUSESSL_LAST))
2127: return CURLE_BAD_FUNCTION_ARGUMENT;
2128: data->set.use_ssl = (curl_usessl)arg;
2129: break;
2130:
2131: case CURLOPT_SSL_OPTIONS:
2132: arg = va_arg(param, long);
2133: data->set.ssl.enable_beast =
2134: (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE);
2135: data->set.ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
2136: data->set.ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN);
2137: data->set.ssl.revoke_best_effort = !!(arg & CURLSSLOPT_REVOKE_BEST_EFFORT);
2138: break;
2139:
2140: #ifndef CURL_DISABLE_PROXY
2141: case CURLOPT_PROXY_SSL_OPTIONS:
2142: arg = va_arg(param, long);
2143: data->set.proxy_ssl.enable_beast =
2144: (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE);
2145: data->set.proxy_ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
2146: data->set.proxy_ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN);
2147: data->set.proxy_ssl.revoke_best_effort =
2148: !!(arg & CURLSSLOPT_REVOKE_BEST_EFFORT);
2149: break;
2150: #endif
2151:
2152: #endif
2153: case CURLOPT_IPRESOLVE:
2154: arg = va_arg(param, long);
2155: if((arg < CURL_IPRESOLVE_WHATEVER) || (arg > CURL_IPRESOLVE_V6))
2156: return CURLE_BAD_FUNCTION_ARGUMENT;
2157: data->set.ipver = arg;
2158: break;
2159:
2160: case CURLOPT_MAXFILESIZE_LARGE:
2161: /*
2162: * Set the maximum size of a file to download.
2163: */
2164: bigsize = va_arg(param, curl_off_t);
2165: if(bigsize < 0)
2166: return CURLE_BAD_FUNCTION_ARGUMENT;
2167: data->set.max_filesize = bigsize;
2168: break;
2169:
2170: case CURLOPT_TCP_NODELAY:
2171: /*
2172: * Enable or disable TCP_NODELAY, which will disable/enable the Nagle
2173: * algorithm
2174: */
2175: data->set.tcp_nodelay = (0 != va_arg(param, long)) ? TRUE : FALSE;
2176: break;
2177:
2178: case CURLOPT_IGNORE_CONTENT_LENGTH:
2179: data->set.ignorecl = (0 != va_arg(param, long)) ? TRUE : FALSE;
2180: break;
2181:
2182: case CURLOPT_CONNECT_ONLY:
2183: /*
2184: * No data transfer, set up connection and let application use the socket
2185: */
2186: data->set.connect_only = (0 != va_arg(param, long)) ? TRUE : FALSE;
2187: break;
2188:
2189: case CURLOPT_SOCKOPTFUNCTION:
2190: /*
2191: * socket callback function: called after socket() but before connect()
2192: */
2193: data->set.fsockopt = va_arg(param, curl_sockopt_callback);
2194: break;
2195:
2196: case CURLOPT_SOCKOPTDATA:
2197: /*
2198: * socket callback data pointer. Might be NULL.
2199: */
2200: data->set.sockopt_client = va_arg(param, void *);
2201: break;
2202:
2203: case CURLOPT_OPENSOCKETFUNCTION:
2204: /*
2205: * open/create socket callback function: called instead of socket(),
2206: * before connect()
2207: */
2208: data->set.fopensocket = va_arg(param, curl_opensocket_callback);
2209: break;
2210:
2211: case CURLOPT_OPENSOCKETDATA:
2212: /*
2213: * socket callback data pointer. Might be NULL.
2214: */
2215: data->set.opensocket_client = va_arg(param, void *);
2216: break;
2217:
2218: case CURLOPT_CLOSESOCKETFUNCTION:
2219: /*
2220: * close socket callback function: called instead of close()
2221: * when shutting down a connection
2222: */
2223: data->set.fclosesocket = va_arg(param, curl_closesocket_callback);
2224: break;
2225:
2226: case CURLOPT_RESOLVER_START_FUNCTION:
2227: /*
2228: * resolver start callback function: called before a new resolver request
2229: * is started
2230: */
2231: data->set.resolver_start = va_arg(param, curl_resolver_start_callback);
2232: break;
2233:
2234: case CURLOPT_RESOLVER_START_DATA:
2235: /*
2236: * resolver start callback data pointer. Might be NULL.
2237: */
2238: data->set.resolver_start_client = va_arg(param, void *);
2239: break;
2240:
2241: case CURLOPT_CLOSESOCKETDATA:
2242: /*
2243: * socket callback data pointer. Might be NULL.
2244: */
2245: data->set.closesocket_client = va_arg(param, void *);
2246: break;
2247:
2248: case CURLOPT_SSL_SESSIONID_CACHE:
2249: data->set.ssl.primary.sessionid = (0 != va_arg(param, long)) ?
2250: TRUE : FALSE;
2251: data->set.proxy_ssl.primary.sessionid = data->set.ssl.primary.sessionid;
2252: break;
2253:
2254: #ifdef USE_SSH
2255: /* we only include SSH options if explicitly built to support SSH */
2256: case CURLOPT_SSH_AUTH_TYPES:
2257: data->set.ssh_auth_types = va_arg(param, long);
2258: break;
2259:
2260: case CURLOPT_SSH_PUBLIC_KEYFILE:
2261: /*
2262: * Use this file instead of the $HOME/.ssh/id_dsa.pub file
2263: */
2264: result = Curl_setstropt(&data->set.str[STRING_SSH_PUBLIC_KEY],
2265: va_arg(param, char *));
2266: break;
2267:
2268: case CURLOPT_SSH_PRIVATE_KEYFILE:
2269: /*
2270: * Use this file instead of the $HOME/.ssh/id_dsa file
2271: */
2272: result = Curl_setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY],
2273: va_arg(param, char *));
2274: break;
2275: case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
2276: /*
2277: * Option to allow for the MD5 of the host public key to be checked
2278: * for validation purposes.
2279: */
2280: result = Curl_setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5],
2281: va_arg(param, char *));
2282: break;
2283:
2284: case CURLOPT_SSH_KNOWNHOSTS:
2285: /*
2286: * Store the file name to read known hosts from.
2287: */
2288: result = Curl_setstropt(&data->set.str[STRING_SSH_KNOWNHOSTS],
2289: va_arg(param, char *));
2290: break;
2291:
2292: case CURLOPT_SSH_KEYFUNCTION:
2293: /* setting to NULL is fine since the ssh.c functions themselves will
2294: then revert to use the internal default */
2295: data->set.ssh_keyfunc = va_arg(param, curl_sshkeycallback);
2296: break;
2297:
2298: case CURLOPT_SSH_KEYDATA:
2299: /*
2300: * Custom client data to pass to the SSH keyfunc callback
2301: */
2302: data->set.ssh_keyfunc_userp = va_arg(param, void *);
2303: break;
2304:
2305: case CURLOPT_SSH_COMPRESSION:
2306: data->set.ssh_compression = (0 != va_arg(param, long))?TRUE:FALSE;
2307: break;
2308: #endif /* USE_SSH */
2309:
2310: case CURLOPT_HTTP_TRANSFER_DECODING:
2311: /*
2312: * disable libcurl transfer encoding is used
2313: */
2314: data->set.http_te_skip = (0 == va_arg(param, long)) ? TRUE : FALSE;
2315: break;
2316:
2317: case CURLOPT_HTTP_CONTENT_DECODING:
2318: /*
2319: * raw data passed to the application when content encoding is used
2320: */
2321: data->set.http_ce_skip = (0 == va_arg(param, long)) ? TRUE : FALSE;
2322: break;
2323:
2324: #if !defined(CURL_DISABLE_FTP) || defined(USE_SSH)
2325: case CURLOPT_NEW_FILE_PERMS:
2326: /*
2327: * Uses these permissions instead of 0644
2328: */
2329: arg = va_arg(param, long);
2330: if((arg < 0) || (arg > 0777))
2331: return CURLE_BAD_FUNCTION_ARGUMENT;
2332: data->set.new_file_perms = arg;
2333: break;
2334:
2335: case CURLOPT_NEW_DIRECTORY_PERMS:
2336: /*
2337: * Uses these permissions instead of 0755
2338: */
2339: arg = va_arg(param, long);
2340: if((arg < 0) || (arg > 0777))
2341: return CURLE_BAD_FUNCTION_ARGUMENT;
2342: data->set.new_directory_perms = arg;
2343: break;
2344: #endif
2345:
2346: case CURLOPT_ADDRESS_SCOPE:
2347: /*
2348: * Use this scope id when using IPv6
2349: * We always get longs when passed plain numericals so we should check
2350: * that the value fits into an unsigned 32 bit integer.
2351: */
2352: uarg = va_arg(param, unsigned long);
2353: #if SIZEOF_LONG > 4
2354: if(uarg > UINT_MAX)
2355: return CURLE_BAD_FUNCTION_ARGUMENT;
2356: #endif
2357: data->set.scope_id = (unsigned int)uarg;
2358: break;
2359:
2360: case CURLOPT_PROTOCOLS:
2361: /* set the bitmask for the protocols that are allowed to be used for the
2362: transfer, which thus helps the app which takes URLs from users or other
2363: external inputs and want to restrict what protocol(s) to deal
2364: with. Defaults to CURLPROTO_ALL. */
2365: data->set.allowed_protocols = va_arg(param, long);
2366: break;
2367:
2368: case CURLOPT_REDIR_PROTOCOLS:
2369: /* set the bitmask for the protocols that libcurl is allowed to follow to,
2370: as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
2371: to be set in both bitmasks to be allowed to get redirected to. */
2372: data->set.redir_protocols = va_arg(param, long);
2373: break;
2374:
2375: case CURLOPT_DEFAULT_PROTOCOL:
2376: /* Set the protocol to use when the URL doesn't include any protocol */
2377: result = Curl_setstropt(&data->set.str[STRING_DEFAULT_PROTOCOL],
2378: va_arg(param, char *));
2379: break;
2380: #ifndef CURL_DISABLE_SMTP
2381: case CURLOPT_MAIL_FROM:
2382: /* Set the SMTP mail originator */
2383: result = Curl_setstropt(&data->set.str[STRING_MAIL_FROM],
2384: va_arg(param, char *));
2385: break;
2386:
2387: case CURLOPT_MAIL_AUTH:
2388: /* Set the SMTP auth originator */
2389: result = Curl_setstropt(&data->set.str[STRING_MAIL_AUTH],
2390: va_arg(param, char *));
2391: break;
2392:
2393: case CURLOPT_MAIL_RCPT:
2394: /* Set the list of mail recipients */
2395: data->set.mail_rcpt = va_arg(param, struct curl_slist *);
2396: break;
2397: case CURLOPT_MAIL_RCPT_ALLLOWFAILS:
2398: /* allow RCPT TO command to fail for some recipients */
2399: data->set.mail_rcpt_allowfails = (0 != va_arg(param, long)) ? TRUE : FALSE;
2400: break;
2401: #endif
2402:
2403: case CURLOPT_SASL_AUTHZID:
2404: /* Authorisation identity (identity to act as) */
2405: result = Curl_setstropt(&data->set.str[STRING_SASL_AUTHZID],
2406: va_arg(param, char *));
2407: break;
2408:
2409: case CURLOPT_SASL_IR:
2410: /* Enable/disable SASL initial response */
2411: data->set.sasl_ir = (0 != va_arg(param, long)) ? TRUE : FALSE;
2412: break;
2413: #ifndef CURL_DISABLE_RTSP
2414: case CURLOPT_RTSP_REQUEST:
2415: {
2416: /*
2417: * Set the RTSP request method (OPTIONS, SETUP, PLAY, etc...)
2418: * Would this be better if the RTSPREQ_* were just moved into here?
2419: */
2420: long curl_rtspreq = va_arg(param, long);
2421: Curl_RtspReq rtspreq = RTSPREQ_NONE;
2422: switch(curl_rtspreq) {
2423: case CURL_RTSPREQ_OPTIONS:
2424: rtspreq = RTSPREQ_OPTIONS;
2425: break;
2426:
2427: case CURL_RTSPREQ_DESCRIBE:
2428: rtspreq = RTSPREQ_DESCRIBE;
2429: break;
2430:
2431: case CURL_RTSPREQ_ANNOUNCE:
2432: rtspreq = RTSPREQ_ANNOUNCE;
2433: break;
2434:
2435: case CURL_RTSPREQ_SETUP:
2436: rtspreq = RTSPREQ_SETUP;
2437: break;
2438:
2439: case CURL_RTSPREQ_PLAY:
2440: rtspreq = RTSPREQ_PLAY;
2441: break;
2442:
2443: case CURL_RTSPREQ_PAUSE:
2444: rtspreq = RTSPREQ_PAUSE;
2445: break;
2446:
2447: case CURL_RTSPREQ_TEARDOWN:
2448: rtspreq = RTSPREQ_TEARDOWN;
2449: break;
2450:
2451: case CURL_RTSPREQ_GET_PARAMETER:
2452: rtspreq = RTSPREQ_GET_PARAMETER;
2453: break;
2454:
2455: case CURL_RTSPREQ_SET_PARAMETER:
2456: rtspreq = RTSPREQ_SET_PARAMETER;
2457: break;
2458:
2459: case CURL_RTSPREQ_RECORD:
2460: rtspreq = RTSPREQ_RECORD;
2461: break;
2462:
2463: case CURL_RTSPREQ_RECEIVE:
2464: rtspreq = RTSPREQ_RECEIVE;
2465: break;
2466: default:
2467: rtspreq = RTSPREQ_NONE;
2468: }
2469:
2470: data->set.rtspreq = rtspreq;
2471: break;
2472: }
2473:
2474:
2475: case CURLOPT_RTSP_SESSION_ID:
2476: /*
2477: * Set the RTSP Session ID manually. Useful if the application is
2478: * resuming a previously established RTSP session
2479: */
2480: result = Curl_setstropt(&data->set.str[STRING_RTSP_SESSION_ID],
2481: va_arg(param, char *));
2482: break;
2483:
2484: case CURLOPT_RTSP_STREAM_URI:
2485: /*
2486: * Set the Stream URI for the RTSP request. Unless the request is
2487: * for generic server options, the application will need to set this.
2488: */
2489: result = Curl_setstropt(&data->set.str[STRING_RTSP_STREAM_URI],
2490: va_arg(param, char *));
2491: break;
2492:
2493: case CURLOPT_RTSP_TRANSPORT:
2494: /*
2495: * The content of the Transport: header for the RTSP request
2496: */
2497: result = Curl_setstropt(&data->set.str[STRING_RTSP_TRANSPORT],
2498: va_arg(param, char *));
2499: break;
2500:
2501: case CURLOPT_RTSP_CLIENT_CSEQ:
2502: /*
2503: * Set the CSEQ number to issue for the next RTSP request. Useful if the
2504: * application is resuming a previously broken connection. The CSEQ
2505: * will increment from this new number henceforth.
2506: */
2507: data->state.rtsp_next_client_CSeq = va_arg(param, long);
2508: break;
2509:
2510: case CURLOPT_RTSP_SERVER_CSEQ:
2511: /* Same as the above, but for server-initiated requests */
2512: data->state.rtsp_next_server_CSeq = va_arg(param, long);
2513: break;
2514:
2515: case CURLOPT_INTERLEAVEDATA:
2516: data->set.rtp_out = va_arg(param, void *);
2517: break;
2518: case CURLOPT_INTERLEAVEFUNCTION:
2519: /* Set the user defined RTP write function */
2520: data->set.fwrite_rtp = va_arg(param, curl_write_callback);
2521: break;
2522: #endif
2523: #ifndef CURL_DISABLE_FTP
2524: case CURLOPT_WILDCARDMATCH:
2525: data->set.wildcard_enabled = (0 != va_arg(param, long)) ? TRUE : FALSE;
2526: break;
2527: case CURLOPT_CHUNK_BGN_FUNCTION:
2528: data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback);
2529: break;
2530: case CURLOPT_CHUNK_END_FUNCTION:
2531: data->set.chunk_end = va_arg(param, curl_chunk_end_callback);
2532: break;
2533: case CURLOPT_FNMATCH_FUNCTION:
2534: data->set.fnmatch = va_arg(param, curl_fnmatch_callback);
2535: break;
2536: case CURLOPT_CHUNK_DATA:
2537: data->wildcard.customptr = va_arg(param, void *);
2538: break;
2539: case CURLOPT_FNMATCH_DATA:
2540: data->set.fnmatch_data = va_arg(param, void *);
2541: break;
2542: #endif
2543: #ifdef USE_TLS_SRP
2544: case CURLOPT_TLSAUTH_USERNAME:
2545: result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_ORIG],
2546: va_arg(param, char *));
2547: if(data->set.str[STRING_TLSAUTH_USERNAME_ORIG] && !data->set.ssl.authtype)
2548: data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2549: break;
2550: case CURLOPT_PROXY_TLSAUTH_USERNAME:
2551: result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_PROXY],
2552: va_arg(param, char *));
2553: if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
2554: !data->set.proxy_ssl.authtype)
2555: data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2556: break;
2557: case CURLOPT_TLSAUTH_PASSWORD:
2558: result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_ORIG],
2559: va_arg(param, char *));
2560: if(data->set.str[STRING_TLSAUTH_USERNAME_ORIG] && !data->set.ssl.authtype)
2561: data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2562: break;
2563: case CURLOPT_PROXY_TLSAUTH_PASSWORD:
2564: result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_PROXY],
2565: va_arg(param, char *));
2566: if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
2567: !data->set.proxy_ssl.authtype)
2568: data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2569: break;
2570: case CURLOPT_TLSAUTH_TYPE:
2571: argptr = va_arg(param, char *);
2572: if(!argptr ||
2573: strncasecompare(argptr, "SRP", strlen("SRP")))
2574: data->set.ssl.authtype = CURL_TLSAUTH_SRP;
2575: else
2576: data->set.ssl.authtype = CURL_TLSAUTH_NONE;
2577: break;
2578: case CURLOPT_PROXY_TLSAUTH_TYPE:
2579: argptr = va_arg(param, char *);
2580: if(!argptr ||
2581: strncasecompare(argptr, "SRP", strlen("SRP")))
2582: data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP;
2583: else
2584: data->set.proxy_ssl.authtype = CURL_TLSAUTH_NONE;
2585: break;
2586: #endif
2587: #ifdef USE_ARES
2588: case CURLOPT_DNS_SERVERS:
2589: result = Curl_setstropt(&data->set.str[STRING_DNS_SERVERS],
2590: va_arg(param, char *));
2591: if(result)
2592: return result;
2593: result = Curl_set_dns_servers(data, data->set.str[STRING_DNS_SERVERS]);
2594: break;
2595: case CURLOPT_DNS_INTERFACE:
2596: result = Curl_setstropt(&data->set.str[STRING_DNS_INTERFACE],
2597: va_arg(param, char *));
2598: if(result)
2599: return result;
2600: result = Curl_set_dns_interface(data, data->set.str[STRING_DNS_INTERFACE]);
2601: break;
2602: case CURLOPT_DNS_LOCAL_IP4:
2603: result = Curl_setstropt(&data->set.str[STRING_DNS_LOCAL_IP4],
2604: va_arg(param, char *));
2605: if(result)
2606: return result;
2607: result = Curl_set_dns_local_ip4(data, data->set.str[STRING_DNS_LOCAL_IP4]);
2608: break;
2609: case CURLOPT_DNS_LOCAL_IP6:
2610: result = Curl_setstropt(&data->set.str[STRING_DNS_LOCAL_IP6],
2611: va_arg(param, char *));
2612: if(result)
2613: return result;
2614: result = Curl_set_dns_local_ip6(data, data->set.str[STRING_DNS_LOCAL_IP6]);
2615: break;
2616: #endif
2617: case CURLOPT_TCP_KEEPALIVE:
2618: data->set.tcp_keepalive = (0 != va_arg(param, long)) ? TRUE : FALSE;
2619: break;
2620: case CURLOPT_TCP_KEEPIDLE:
2621: arg = va_arg(param, long);
2622: if(arg < 0)
2623: return CURLE_BAD_FUNCTION_ARGUMENT;
2624: data->set.tcp_keepidle = arg;
2625: break;
2626: case CURLOPT_TCP_KEEPINTVL:
2627: arg = va_arg(param, long);
2628: if(arg < 0)
2629: return CURLE_BAD_FUNCTION_ARGUMENT;
2630: data->set.tcp_keepintvl = arg;
2631: break;
2632: case CURLOPT_TCP_FASTOPEN:
2633: #if defined(CONNECT_DATA_IDEMPOTENT) || defined(MSG_FASTOPEN) || \
2634: defined(TCP_FASTOPEN_CONNECT)
2635: data->set.tcp_fastopen = (0 != va_arg(param, long))?TRUE:FALSE;
2636: #else
2637: result = CURLE_NOT_BUILT_IN;
2638: #endif
2639: break;
2640: case CURLOPT_SSL_ENABLE_NPN:
2641: data->set.ssl_enable_npn = (0 != va_arg(param, long)) ? TRUE : FALSE;
2642: break;
2643: case CURLOPT_SSL_ENABLE_ALPN:
2644: data->set.ssl_enable_alpn = (0 != va_arg(param, long)) ? TRUE : FALSE;
2645: break;
2646: #ifdef USE_UNIX_SOCKETS
2647: case CURLOPT_UNIX_SOCKET_PATH:
2648: data->set.abstract_unix_socket = FALSE;
2649: result = Curl_setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH],
2650: va_arg(param, char *));
2651: break;
2652: case CURLOPT_ABSTRACT_UNIX_SOCKET:
2653: data->set.abstract_unix_socket = TRUE;
2654: result = Curl_setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH],
2655: va_arg(param, char *));
2656: break;
2657: #endif
2658:
2659: case CURLOPT_PATH_AS_IS:
2660: data->set.path_as_is = (0 != va_arg(param, long)) ? TRUE : FALSE;
2661: break;
2662: case CURLOPT_PIPEWAIT:
2663: data->set.pipewait = (0 != va_arg(param, long)) ? TRUE : FALSE;
2664: break;
2665: case CURLOPT_STREAM_WEIGHT:
2666: #ifndef USE_NGHTTP2
2667: return CURLE_NOT_BUILT_IN;
2668: #else
2669: arg = va_arg(param, long);
2670: if((arg >= 1) && (arg <= 256))
2671: data->set.stream_weight = (int)arg;
2672: break;
2673: #endif
2674: case CURLOPT_STREAM_DEPENDS:
2675: case CURLOPT_STREAM_DEPENDS_E:
2676: {
2677: #ifndef USE_NGHTTP2
2678: return CURLE_NOT_BUILT_IN;
2679: #else
2680: struct Curl_easy *dep = va_arg(param, struct Curl_easy *);
2681: if(!dep || GOOD_EASY_HANDLE(dep)) {
2682: if(data->set.stream_depends_on) {
2683: Curl_http2_remove_child(data->set.stream_depends_on, data);
2684: }
2685: Curl_http2_add_child(dep, data, (option == CURLOPT_STREAM_DEPENDS_E));
2686: }
2687: break;
2688: #endif
2689: }
2690: case CURLOPT_CONNECT_TO:
2691: data->set.connect_to = va_arg(param, struct curl_slist *);
2692: break;
2693: case CURLOPT_SUPPRESS_CONNECT_HEADERS:
2694: data->set.suppress_connect_headers = (0 != va_arg(param, long))?TRUE:FALSE;
2695: break;
2696: case CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS:
2697: arg = va_arg(param, long);
2698: if(arg < 0)
2699: return CURLE_BAD_FUNCTION_ARGUMENT;
2700: data->set.happy_eyeballs_timeout = arg;
2701: break;
2702: #ifndef CURL_DISABLE_SHUFFLE_DNS
2703: case CURLOPT_DNS_SHUFFLE_ADDRESSES:
2704: data->set.dns_shuffle_addresses = (0 != va_arg(param, long)) ? TRUE:FALSE;
2705: break;
2706: #endif
2707: case CURLOPT_DISALLOW_USERNAME_IN_URL:
2708: data->set.disallow_username_in_url =
2709: (0 != va_arg(param, long)) ? TRUE : FALSE;
2710: break;
2711: #ifndef CURL_DISABLE_DOH
2712: case CURLOPT_DOH_URL:
2713: result = Curl_setstropt(&data->set.str[STRING_DOH],
2714: va_arg(param, char *));
2715: data->set.doh = data->set.str[STRING_DOH]?TRUE:FALSE;
2716: break;
2717: #endif
2718: case CURLOPT_UPKEEP_INTERVAL_MS:
2719: arg = va_arg(param, long);
2720: if(arg < 0)
2721: return CURLE_BAD_FUNCTION_ARGUMENT;
2722: data->set.upkeep_interval_ms = arg;
2723: break;
2724: case CURLOPT_MAXAGE_CONN:
2725: arg = va_arg(param, long);
2726: if(arg < 0)
2727: return CURLE_BAD_FUNCTION_ARGUMENT;
2728: data->set.maxage_conn = arg;
2729: break;
2730: case CURLOPT_TRAILERFUNCTION:
2731: #ifndef CURL_DISABLE_HTTP
2732: data->set.trailer_callback = va_arg(param, curl_trailer_callback);
2733: #endif
2734: break;
2735: case CURLOPT_TRAILERDATA:
2736: #ifndef CURL_DISABLE_HTTP
2737: data->set.trailer_data = va_arg(param, void *);
2738: #endif
2739: break;
2740: #ifdef USE_ALTSVC
2741: case CURLOPT_ALTSVC:
2742: if(!data->asi) {
2743: data->asi = Curl_altsvc_init();
2744: if(!data->asi)
2745: return CURLE_OUT_OF_MEMORY;
2746: }
2747: argptr = va_arg(param, char *);
2748: result = Curl_setstropt(&data->set.str[STRING_ALTSVC], argptr);
2749: if(result)
2750: return result;
2751: if(argptr)
2752: (void)Curl_altsvc_load(data->asi, argptr);
2753: break;
2754: case CURLOPT_ALTSVC_CTRL:
2755: if(!data->asi) {
2756: data->asi = Curl_altsvc_init();
2757: if(!data->asi)
2758: return CURLE_OUT_OF_MEMORY;
2759: }
2760: arg = va_arg(param, long);
2761: result = Curl_altsvc_ctrl(data->asi, arg);
2762: if(result)
2763: return result;
2764: break;
2765: #endif
2766: default:
2767: /* unknown tag and its companion, just ignore: */
2768: result = CURLE_UNKNOWN_OPTION;
2769: break;
2770: }
2771:
2772: return result;
2773: }
2774:
2775: /*
2776: * curl_easy_setopt() is the external interface for setting options on an
2777: * easy handle.
2778: *
2779: * NOTE: This is one of few API functions that are allowed to be called from
2780: * within a callback.
2781: */
2782:
2783: #undef curl_easy_setopt
2784: CURLcode curl_easy_setopt(struct Curl_easy *data, CURLoption tag, ...)
2785: {
2786: va_list arg;
2787: CURLcode result;
2788:
2789: if(!data)
2790: return CURLE_BAD_FUNCTION_ARGUMENT;
2791:
2792: va_start(arg, tag);
2793:
2794: result = Curl_vsetopt(data, tag, arg);
2795:
2796: va_end(arg);
2797: return result;
2798: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>