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: #include "tool_setup.h"
23:
24: #ifndef CURL_DISABLE_LIBCURL_OPTION
25:
26: #define ENABLE_CURLX_PRINTF
27: /* use our own printf() functions */
28: #include "curlx.h"
29:
30: #include "tool_cfgable.h"
31: #include "tool_easysrc.h"
32: #include "tool_setopt.h"
33: #include "tool_convert.h"
34:
35: #include "memdebug.h" /* keep this as LAST include */
36:
37: /* Lookup tables for converting setopt values back to symbols */
38: /* For enums, values may be in any order. */
39: /* For bit masks, put combinations first, then single bits, */
40: /* and finally any "NONE" value. */
41:
42: #define NV(e) {#e, e}
43: #define NV1(e, v) {#e, (v)}
44: #define NVEND {NULL, 0} /* sentinel to mark end of list */
45:
46: const NameValue setopt_nv_CURLPROXY[] = {
47: NV(CURLPROXY_HTTP),
48: NV(CURLPROXY_HTTP_1_0),
49: NV(CURLPROXY_HTTPS),
50: NV(CURLPROXY_SOCKS4),
51: NV(CURLPROXY_SOCKS5),
52: NV(CURLPROXY_SOCKS4A),
53: NV(CURLPROXY_SOCKS5_HOSTNAME),
54: NVEND,
55: };
56:
57: const NameValue setopt_nv_CURL_SOCKS_PROXY[] = {
58: NV(CURLPROXY_SOCKS4),
59: NV(CURLPROXY_SOCKS5),
60: NV(CURLPROXY_SOCKS4A),
61: NV(CURLPROXY_SOCKS5_HOSTNAME),
62: NVEND,
63: };
64:
65: const NameValueUnsigned setopt_nv_CURLAUTH[] = {
66: NV(CURLAUTH_ANY), /* combination */
67: NV(CURLAUTH_ANYSAFE), /* combination */
68: NV(CURLAUTH_BASIC),
69: NV(CURLAUTH_DIGEST),
70: NV(CURLAUTH_GSSNEGOTIATE),
71: NV(CURLAUTH_NTLM),
72: NV(CURLAUTH_DIGEST_IE),
73: NV(CURLAUTH_NTLM_WB),
74: NV(CURLAUTH_ONLY),
75: NV(CURLAUTH_NONE),
76: NVEND,
77: };
78:
79: const NameValue setopt_nv_CURL_HTTP_VERSION[] = {
80: NV(CURL_HTTP_VERSION_NONE),
81: NV(CURL_HTTP_VERSION_1_0),
82: NV(CURL_HTTP_VERSION_1_1),
83: NV(CURL_HTTP_VERSION_2_0),
84: NV(CURL_HTTP_VERSION_2TLS),
85: NV(CURL_HTTP_VERSION_3),
86: NVEND,
87: };
88:
89: const NameValue setopt_nv_CURL_SSLVERSION[] = {
90: NV(CURL_SSLVERSION_DEFAULT),
91: NV(CURL_SSLVERSION_TLSv1),
92: NV(CURL_SSLVERSION_SSLv2),
93: NV(CURL_SSLVERSION_SSLv3),
94: NV(CURL_SSLVERSION_TLSv1_0),
95: NV(CURL_SSLVERSION_TLSv1_1),
96: NV(CURL_SSLVERSION_TLSv1_2),
97: NV(CURL_SSLVERSION_TLSv1_3),
98: NVEND,
99: };
100:
101: const NameValue setopt_nv_CURL_TIMECOND[] = {
102: NV(CURL_TIMECOND_IFMODSINCE),
103: NV(CURL_TIMECOND_IFUNMODSINCE),
104: NV(CURL_TIMECOND_LASTMOD),
105: NV(CURL_TIMECOND_NONE),
106: NVEND,
107: };
108:
109: const NameValue setopt_nv_CURLFTPSSL_CCC[] = {
110: NV(CURLFTPSSL_CCC_NONE),
111: NV(CURLFTPSSL_CCC_PASSIVE),
112: NV(CURLFTPSSL_CCC_ACTIVE),
113: NVEND,
114: };
115:
116: const NameValue setopt_nv_CURLUSESSL[] = {
117: NV(CURLUSESSL_NONE),
118: NV(CURLUSESSL_TRY),
119: NV(CURLUSESSL_CONTROL),
120: NV(CURLUSESSL_ALL),
121: NVEND,
122: };
123:
124: const NameValueUnsigned setopt_nv_CURLSSLOPT[] = {
125: NV(CURLSSLOPT_ALLOW_BEAST),
126: NV(CURLSSLOPT_NO_REVOKE),
127: NV(CURLSSLOPT_NO_PARTIALCHAIN),
128: NV(CURLSSLOPT_REVOKE_BEST_EFFORT),
129: NVEND,
130: };
131:
132: const NameValue setopt_nv_CURL_NETRC[] = {
133: NV(CURL_NETRC_IGNORED),
134: NV(CURL_NETRC_OPTIONAL),
135: NV(CURL_NETRC_REQUIRED),
136: NVEND,
137: };
138:
139: /* These mappings essentially triplicated - see
140: * tool_libinfo.c and tool_paramhlp.c */
141: const NameValue setopt_nv_CURLPROTO[] = {
142: NV(CURLPROTO_ALL), /* combination */
143: NV(CURLPROTO_DICT),
144: NV(CURLPROTO_FILE),
145: NV(CURLPROTO_FTP),
146: NV(CURLPROTO_FTPS),
147: NV(CURLPROTO_GOPHER),
148: NV(CURLPROTO_HTTP),
149: NV(CURLPROTO_HTTPS),
150: NV(CURLPROTO_IMAP),
151: NV(CURLPROTO_IMAPS),
152: NV(CURLPROTO_LDAP),
153: NV(CURLPROTO_LDAPS),
154: NV(CURLPROTO_POP3),
155: NV(CURLPROTO_POP3S),
156: NV(CURLPROTO_RTSP),
157: NV(CURLPROTO_SCP),
158: NV(CURLPROTO_SFTP),
159: NV(CURLPROTO_SMB),
160: NV(CURLPROTO_SMBS),
161: NV(CURLPROTO_SMTP),
162: NV(CURLPROTO_SMTPS),
163: NV(CURLPROTO_TELNET),
164: NV(CURLPROTO_TFTP),
165: NVEND,
166: };
167:
168: /* These options have non-zero default values. */
169: static const NameValue setopt_nv_CURLNONZERODEFAULTS[] = {
170: NV1(CURLOPT_SSL_VERIFYPEER, 1),
171: NV1(CURLOPT_SSL_VERIFYHOST, 1),
172: NV1(CURLOPT_SSL_ENABLE_NPN, 1),
173: NV1(CURLOPT_SSL_ENABLE_ALPN, 1),
174: NV1(CURLOPT_TCP_NODELAY, 1),
175: NV1(CURLOPT_PROXY_SSL_VERIFYPEER, 1),
176: NV1(CURLOPT_PROXY_SSL_VERIFYHOST, 1),
177: NV1(CURLOPT_SOCKS5_AUTH, 1),
178: NVEND
179: };
180:
181: /* Format and add code; jump to nomem on malloc error */
182: #define ADD(args) do { \
183: ret = easysrc_add args; \
184: if(ret) \
185: goto nomem; \
186: } while(0)
187: #define ADDF(args) do { \
188: ret = easysrc_addf args; \
189: if(ret) \
190: goto nomem; \
191: } while(0)
192: #define NULL_CHECK(p) do { \
193: if(!p) { \
194: ret = CURLE_OUT_OF_MEMORY; \
195: goto nomem; \
196: } \
197: } while(0)
198:
199: #define DECL0(s) ADD((&easysrc_decl, s))
200: #define DECL1(f,a) ADDF((&easysrc_decl, f,a))
201:
202: #define DATA0(s) ADD((&easysrc_data, s))
203: #define DATA1(f,a) ADDF((&easysrc_data, f,a))
204: #define DATA2(f,a,b) ADDF((&easysrc_data, f,a,b))
205: #define DATA3(f,a,b,c) ADDF((&easysrc_data, f,a,b,c))
206:
207: #define CODE0(s) ADD((&easysrc_code, s))
208: #define CODE1(f,a) ADDF((&easysrc_code, f,a))
209: #define CODE2(f,a,b) ADDF((&easysrc_code, f,a,b))
210: #define CODE3(f,a,b,c) ADDF((&easysrc_code, f,a,b,c))
211:
212: #define CLEAN0(s) ADD((&easysrc_clean, s))
213: #define CLEAN1(f,a) ADDF((&easysrc_clean, f,a))
214:
215: #define REM0(s) ADD((&easysrc_toohard, s))
216: #define REM1(f,a) ADDF((&easysrc_toohard, f,a))
217: #define REM2(f,a,b) ADDF((&easysrc_toohard, f,a,b))
218:
219: /* Escape string to C string syntax. Return NULL if out of memory.
220: * Is this correct for those wacky EBCDIC guys? */
221: static char *c_escape(const char *str, size_t len)
222: {
223: const char *s;
224: unsigned char c;
225: char *escaped, *e;
226:
227: if(len == CURL_ZERO_TERMINATED)
228: len = strlen(str);
229:
230: /* Check for possible overflow. */
231: if(len > (~(size_t) 0) / 4)
232: return NULL;
233:
234: /* Allocate space based on worst-case */
235: escaped = malloc(4 * len + 1);
236: if(!escaped)
237: return NULL;
238:
239: e = escaped;
240: for(s = str; (c = *s) != '\0'; s++) {
241: if(c == '\n') {
242: strcpy(e, "\\n");
243: e += 2;
244: }
245: else if(c == '\r') {
246: strcpy(e, "\\r");
247: e += 2;
248: }
249: else if(c == '\t') {
250: strcpy(e, "\\t");
251: e += 2;
252: }
253: else if(c == '\\') {
254: strcpy(e, "\\\\");
255: e += 2;
256: }
257: else if(c == '"') {
258: strcpy(e, "\\\"");
259: e += 2;
260: }
261: else if(! isprint(c)) {
262: msnprintf(e, 5, "\\%03o", (unsigned)c);
263: e += 4;
264: }
265: else
266: *e++ = c;
267: }
268: *e = '\0';
269: return escaped;
270: }
271:
272: /* setopt wrapper for enum types */
273: CURLcode tool_setopt_enum(CURL *curl, struct GlobalConfig *config,
274: const char *name, CURLoption tag,
275: const NameValue *nvlist, long lval)
276: {
277: CURLcode ret = CURLE_OK;
278: bool skip = FALSE;
279:
280: ret = curl_easy_setopt(curl, tag, lval);
281: if(!lval)
282: skip = TRUE;
283:
284: if(config->libcurl && !skip && !ret) {
285: /* we only use this for real if --libcurl was used */
286: const NameValue *nv = NULL;
287: for(nv = nvlist; nv->name; nv++) {
288: if(nv->value == lval)
289: break; /* found it */
290: }
291: if(! nv->name) {
292: /* If no definition was found, output an explicit value.
293: * This could happen if new values are defined and used
294: * but the NameValue list is not updated. */
295: CODE2("curl_easy_setopt(hnd, %s, %ldL);", name, lval);
296: }
297: else {
298: CODE2("curl_easy_setopt(hnd, %s, (long)%s);", name, nv->name);
299: }
300: }
301:
302: nomem:
303: return ret;
304: }
305:
306: /* setopt wrapper for flags */
307: CURLcode tool_setopt_flags(CURL *curl, struct GlobalConfig *config,
308: const char *name, CURLoption tag,
309: const NameValue *nvlist, long lval)
310: {
311: CURLcode ret = CURLE_OK;
312: bool skip = FALSE;
313:
314: ret = curl_easy_setopt(curl, tag, lval);
315: if(!lval)
316: skip = TRUE;
317:
318: if(config->libcurl && !skip && !ret) {
319: /* we only use this for real if --libcurl was used */
320: char preamble[80]; /* should accommodate any symbol name */
321: long rest = lval; /* bits not handled yet */
322: const NameValue *nv = NULL;
323: msnprintf(preamble, sizeof(preamble),
324: "curl_easy_setopt(hnd, %s, ", name);
325: for(nv = nvlist; nv->name; nv++) {
326: if((nv->value & ~ rest) == 0) {
327: /* all value flags contained in rest */
328: rest &= ~ nv->value; /* remove bits handled here */
329: CODE3("%s(long)%s%s",
330: preamble, nv->name, rest ? " |" : ");");
331: if(!rest)
332: break; /* handled them all */
333: /* replace with all spaces for continuation line */
334: msnprintf(preamble, sizeof(preamble), "%*s", strlen(preamble), "");
335: }
336: }
337: /* If any bits have no definition, output an explicit value.
338: * This could happen if new bits are defined and used
339: * but the NameValue list is not updated. */
340: if(rest)
341: CODE2("%s%ldL);", preamble, rest);
342: }
343:
344: nomem:
345: return ret;
346: }
347:
348: /* setopt wrapper for bitmasks */
349: CURLcode tool_setopt_bitmask(CURL *curl, struct GlobalConfig *config,
350: const char *name, CURLoption tag,
351: const NameValueUnsigned *nvlist,
352: long lval)
353: {
354: CURLcode ret = CURLE_OK;
355: bool skip = FALSE;
356:
357: ret = curl_easy_setopt(curl, tag, lval);
358: if(!lval)
359: skip = TRUE;
360:
361: if(config->libcurl && !skip && !ret) {
362: /* we only use this for real if --libcurl was used */
363: char preamble[80];
364: unsigned long rest = (unsigned long)lval;
365: const NameValueUnsigned *nv = NULL;
366: msnprintf(preamble, sizeof(preamble),
367: "curl_easy_setopt(hnd, %s, ", name);
368: for(nv = nvlist; nv->name; nv++) {
369: if((nv->value & ~ rest) == 0) {
370: /* all value flags contained in rest */
371: rest &= ~ nv->value; /* remove bits handled here */
372: CODE3("%s(long)%s%s",
373: preamble, nv->name, rest ? " |" : ");");
374: if(!rest)
375: break; /* handled them all */
376: /* replace with all spaces for continuation line */
377: msnprintf(preamble, sizeof(preamble), "%*s", strlen(preamble), "");
378: }
379: }
380: /* If any bits have no definition, output an explicit value.
381: * This could happen if new bits are defined and used
382: * but the NameValue list is not updated. */
383: if(rest)
384: CODE2("%s%luUL);", preamble, rest);
385: }
386:
387: nomem:
388: return ret;
389: }
390:
391: /* Generate code for a struct curl_slist. */
392: static CURLcode libcurl_generate_slist(struct curl_slist *slist, int *slistno)
393: {
394: CURLcode ret = CURLE_OK;
395: char *escaped = NULL;
396:
397: /* May need several slist variables, so invent name */
398: *slistno = ++easysrc_slist_count;
399:
400: DECL1("struct curl_slist *slist%d;", *slistno);
401: DATA1("slist%d = NULL;", *slistno);
402: CLEAN1("curl_slist_free_all(slist%d);", *slistno);
403: CLEAN1("slist%d = NULL;", *slistno);
404: for(; slist; slist = slist->next) {
405: Curl_safefree(escaped);
406: escaped = c_escape(slist->data, CURL_ZERO_TERMINATED);
407: if(!escaped)
408: return CURLE_OUT_OF_MEMORY;
409: DATA3("slist%d = curl_slist_append(slist%d, \"%s\");",
410: *slistno, *slistno, escaped);
411: }
412:
413: nomem:
414: Curl_safefree(escaped);
415: return ret;
416: }
417:
418: static CURLcode libcurl_generate_mime(CURL *curl,
419: struct GlobalConfig *config,
420: tool_mime *toolmime,
421: int *mimeno); /* Forward. */
422:
423: /* Wrapper to generate source code for a mime part. */
424: static CURLcode libcurl_generate_mime_part(CURL *curl,
425: struct GlobalConfig *config,
426: tool_mime *part,
427: int mimeno)
428: {
429: CURLcode ret = CURLE_OK;
430: int submimeno = 0;
431: char *escaped = NULL;
432: const char *data = NULL;
433: const char *filename = part->filename;
434:
435: /* Parts are linked in reverse order. */
436: if(part->prev) {
437: ret = libcurl_generate_mime_part(curl, config, part->prev, mimeno);
438: if(ret)
439: return ret;
440: }
441:
442: /* Create the part. */
443: CODE2("part%d = curl_mime_addpart(mime%d);", mimeno, mimeno);
444:
445: switch(part->kind) {
446: case TOOLMIME_PARTS:
447: ret = libcurl_generate_mime(curl, config, part, &submimeno);
448: if(!ret) {
449: CODE2("curl_mime_subparts(part%d, mime%d);", mimeno, submimeno);
450: CODE1("mime%d = NULL;", submimeno); /* Avoid freeing in CLEAN. */
451: }
452: break;
453:
454: case TOOLMIME_DATA:
455: #ifdef CURL_DOES_CONVERSIONS
456: /* Data will be set in ASCII, thus issue a comment with clear text. */
457: escaped = c_escape(part->data, CURL_ZERO_TERMINATED);
458: NULL_CHECK(escaped);
459: CODE1("/* \"%s\" */", escaped);
460:
461: /* Our data is always textual: convert it to ASCII. */
462: {
463: size_t size = strlen(part->data);
464: char *cp = malloc(size + 1);
465:
466: NULL_CHECK(cp);
467: memcpy(cp, part->data, size + 1);
468: ret = convert_to_network(cp, size);
469: data = cp;
470: }
471: #else
472: data = part->data;
473: #endif
474: if(!ret) {
475: Curl_safefree(escaped);
476: escaped = c_escape(data, CURL_ZERO_TERMINATED);
477: NULL_CHECK(escaped);
478: CODE2("curl_mime_data(part%d, \"%s\", CURL_ZERO_TERMINATED);",
479: mimeno, escaped);
480: }
481: break;
482:
483: case TOOLMIME_FILE:
484: case TOOLMIME_FILEDATA:
485: escaped = c_escape(part->data, CURL_ZERO_TERMINATED);
486: NULL_CHECK(escaped);
487: CODE2("curl_mime_filedata(part%d, \"%s\");", mimeno, escaped);
488: if(part->kind == TOOLMIME_FILEDATA && !filename) {
489: CODE1("curl_mime_filename(part%d, NULL);", mimeno);
490: }
491: break;
492:
493: case TOOLMIME_STDIN:
494: if(!filename)
495: filename = "-";
496: /* FALLTHROUGH */
497: case TOOLMIME_STDINDATA:
498: /* Can only be reading stdin in the current context. */
499: CODE1("curl_mime_data_cb(part%d, -1, (curl_read_callback) fread, \\",
500: mimeno);
501: CODE0(" (curl_seek_callback) fseek, NULL, stdin);");
502: break;
503: default:
504: /* Other cases not possible in this context. */
505: break;
506: }
507:
508: if(!ret && part->encoder) {
509: Curl_safefree(escaped);
510: escaped = c_escape(part->encoder, CURL_ZERO_TERMINATED);
511: NULL_CHECK(escaped);
512: CODE2("curl_mime_encoder(part%d, \"%s\");", mimeno, escaped);
513: }
514:
515: if(!ret && filename) {
516: Curl_safefree(escaped);
517: escaped = c_escape(filename, CURL_ZERO_TERMINATED);
518: NULL_CHECK(escaped);
519: CODE2("curl_mime_filename(part%d, \"%s\");", mimeno, escaped);
520: }
521:
522: if(!ret && part->name) {
523: Curl_safefree(escaped);
524: escaped = c_escape(part->name, CURL_ZERO_TERMINATED);
525: NULL_CHECK(escaped);
526: CODE2("curl_mime_name(part%d, \"%s\");", mimeno, escaped);
527: }
528:
529: if(!ret && part->type) {
530: Curl_safefree(escaped);
531: escaped = c_escape(part->type, CURL_ZERO_TERMINATED);
532: NULL_CHECK(escaped);
533: CODE2("curl_mime_type(part%d, \"%s\");", mimeno, escaped);
534: }
535:
536: if(!ret && part->headers) {
537: int slistno;
538:
539: ret = libcurl_generate_slist(part->headers, &slistno);
540: if(!ret) {
541: CODE2("curl_mime_headers(part%d, slist%d, 1);", mimeno, slistno);
542: CODE1("slist%d = NULL;", slistno); /* Prevent CLEANing. */
543: }
544: }
545:
546: nomem:
547: #ifdef CURL_DOES_CONVERSIONS
548: if(data)
549: free((char *) data);
550: #endif
551:
552: Curl_safefree(escaped);
553: return ret;
554: }
555:
556: /* Wrapper to generate source code for a mime structure. */
557: static CURLcode libcurl_generate_mime(CURL *curl,
558: struct GlobalConfig *config,
559: tool_mime *toolmime,
560: int *mimeno)
561: {
562: CURLcode ret = CURLE_OK;
563:
564: /* May need several mime variables, so invent name. */
565: *mimeno = ++easysrc_mime_count;
566: DECL1("curl_mime *mime%d;", *mimeno);
567: DATA1("mime%d = NULL;", *mimeno);
568: CODE1("mime%d = curl_mime_init(hnd);", *mimeno);
569: CLEAN1("curl_mime_free(mime%d);", *mimeno);
570: CLEAN1("mime%d = NULL;", *mimeno);
571:
572: if(toolmime->subparts) {
573: DECL1("curl_mimepart *part%d;", *mimeno);
574: ret = libcurl_generate_mime_part(curl, config,
575: toolmime->subparts, *mimeno);
576: }
577:
578: nomem:
579: return ret;
580: }
581:
582: /* setopt wrapper for CURLOPT_MIMEPOST */
583: CURLcode tool_setopt_mimepost(CURL *curl, struct GlobalConfig *config,
584: const char *name, CURLoption tag,
585: curl_mime *mimepost)
586: {
587: CURLcode ret = curl_easy_setopt(curl, tag, mimepost);
588: int mimeno = 0;
589:
590: if(!ret && config->libcurl) {
591: ret = libcurl_generate_mime(curl, config,
592: config->current->mimeroot, &mimeno);
593:
594: if(!ret)
595: CODE2("curl_easy_setopt(hnd, %s, mime%d);", name, mimeno);
596: }
597:
598: nomem:
599: return ret;
600: }
601:
602: /* setopt wrapper for curl_slist options */
603: CURLcode tool_setopt_slist(CURL *curl, struct GlobalConfig *config,
604: const char *name, CURLoption tag,
605: struct curl_slist *list)
606: {
607: CURLcode ret = CURLE_OK;
608:
609: ret = curl_easy_setopt(curl, tag, list);
610:
611: if(config->libcurl && list && !ret) {
612: int i;
613:
614: ret = libcurl_generate_slist(list, &i);
615: if(!ret)
616: CODE2("curl_easy_setopt(hnd, %s, slist%d);", name, i);
617: }
618:
619: nomem:
620: return ret;
621: }
622:
623: /* generic setopt wrapper for all other options.
624: * Some type information is encoded in the tag value. */
625: CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *config,
626: const char *name, CURLoption tag, ...)
627: {
628: va_list arg;
629: char buf[256];
630: const char *value = NULL;
631: bool remark = FALSE;
632: bool skip = FALSE;
633: bool escape = FALSE;
634: char *escaped = NULL;
635: CURLcode ret = CURLE_OK;
636:
637: va_start(arg, tag);
638:
639: if(tag < CURLOPTTYPE_OBJECTPOINT) {
640: /* Value is expected to be a long */
641: long lval = va_arg(arg, long);
642: long defval = 0L;
643: const NameValue *nv = NULL;
644: for(nv = setopt_nv_CURLNONZERODEFAULTS; nv->name; nv++) {
645: if(!strcmp(name, nv->name)) {
646: defval = nv->value;
647: break; /* found it */
648: }
649: }
650:
651: msnprintf(buf, sizeof(buf), "%ldL", lval);
652: value = buf;
653: ret = curl_easy_setopt(curl, tag, lval);
654: if(lval == defval)
655: skip = TRUE;
656: }
657: else if(tag < CURLOPTTYPE_OFF_T) {
658: /* Value is some sort of object pointer */
659: void *pval = va_arg(arg, void *);
660:
661: /* function pointers are never printable */
662: if(tag >= CURLOPTTYPE_FUNCTIONPOINT) {
663: if(pval) {
664: value = "functionpointer";
665: remark = TRUE;
666: }
667: else
668: skip = TRUE;
669: }
670:
671: else if(pval && str) {
672: value = (char *)pval;
673: escape = TRUE;
674: }
675: else if(pval) {
676: value = "objectpointer";
677: remark = TRUE;
678: }
679: else
680: skip = TRUE;
681:
682: ret = curl_easy_setopt(curl, tag, pval);
683:
684: }
685: else {
686: /* Value is expected to be curl_off_t */
687: curl_off_t oval = va_arg(arg, curl_off_t);
688: msnprintf(buf, sizeof(buf),
689: "(curl_off_t)%" CURL_FORMAT_CURL_OFF_T, oval);
690: value = buf;
691: ret = curl_easy_setopt(curl, tag, oval);
692:
693: if(!oval)
694: skip = TRUE;
695: }
696:
697: va_end(arg);
698:
699: if(config->libcurl && !skip && !ret) {
700: /* we only use this for real if --libcurl was used */
701:
702: if(remark)
703: REM2("%s set to a %s", name, value);
704: else {
705: if(escape) {
706: escaped = c_escape(value, CURL_ZERO_TERMINATED);
707: NULL_CHECK(escaped);
708: CODE2("curl_easy_setopt(hnd, %s, \"%s\");", name, escaped);
709: }
710: else
711: CODE2("curl_easy_setopt(hnd, %s, %s);", name, value);
712: }
713: }
714:
715: nomem:
716: Curl_safefree(escaped);
717: return ret;
718: }
719:
720: #else /* CURL_DISABLE_LIBCURL_OPTION */
721:
722: #include "tool_cfgable.h"
723: #include "tool_setopt.h"
724:
725: #endif /* CURL_DISABLE_LIBCURL_OPTION */
726:
727: /*
728: * tool_setopt_skip() allows the curl tool code to avoid setopt options that
729: * are explicitly disabled in the build.
730: */
731: bool tool_setopt_skip(CURLoption tag)
732: {
733: #ifdef CURL_DISABLE_PROXY
734: #define USED_TAG
735: switch(tag) {
736: case CURLOPT_HAPROXYPROTOCOL:
737: case CURLOPT_HTTPPROXYTUNNEL:
738: case CURLOPT_NOPROXY:
739: case CURLOPT_PRE_PROXY:
740: case CURLOPT_PROXY:
741: case CURLOPT_PROXYAUTH:
742: case CURLOPT_PROXY_CAINFO:
743: case CURLOPT_PROXY_CAPATH:
744: case CURLOPT_PROXY_CRLFILE:
745: case CURLOPT_PROXYHEADER:
746: case CURLOPT_PROXY_KEYPASSWD:
747: case CURLOPT_PROXYPASSWORD:
748: case CURLOPT_PROXY_PINNEDPUBLICKEY:
749: case CURLOPT_PROXYPORT:
750: case CURLOPT_PROXY_SERVICE_NAME:
751: case CURLOPT_PROXY_SSLCERT:
752: case CURLOPT_PROXY_SSLCERTTYPE:
753: case CURLOPT_PROXY_SSL_CIPHER_LIST:
754: case CURLOPT_PROXY_SSLKEY:
755: case CURLOPT_PROXY_SSLKEYTYPE:
756: case CURLOPT_PROXY_SSL_OPTIONS:
757: case CURLOPT_PROXY_SSL_VERIFYHOST:
758: case CURLOPT_PROXY_SSL_VERIFYPEER:
759: case CURLOPT_PROXY_SSLVERSION:
760: case CURLOPT_PROXY_TLS13_CIPHERS:
761: case CURLOPT_PROXY_TLSAUTH_PASSWORD:
762: case CURLOPT_PROXY_TLSAUTH_TYPE:
763: case CURLOPT_PROXY_TLSAUTH_USERNAME:
764: case CURLOPT_PROXY_TRANSFER_MODE:
765: case CURLOPT_PROXYTYPE:
766: case CURLOPT_PROXYUSERNAME:
767: case CURLOPT_PROXYUSERPWD:
768: return TRUE;
769: default:
770: break;
771: }
772: #endif
773: #ifdef CURL_DISABLE_FTP
774: #define USED_TAG
775: switch(tag) {
776: case CURLOPT_FTPPORT:
777: case CURLOPT_FTP_ACCOUNT:
778: case CURLOPT_FTP_ALTERNATIVE_TO_USER:
779: case CURLOPT_FTP_FILEMETHOD:
780: case CURLOPT_FTP_SKIP_PASV_IP:
781: case CURLOPT_FTP_USE_EPRT:
782: case CURLOPT_FTP_USE_EPSV:
783: case CURLOPT_FTP_USE_PRET:
784: case CURLOPT_KRBLEVEL:
785: return TRUE;
786: default:
787: break;
788: }
789: #endif
790: #ifdef CURL_DISABLE_RTSP
791: #define USED_TAG
792: switch(tag) {
793: case CURLOPT_INTERLEAVEDATA:
794: return TRUE;
795: default:
796: break;
797: }
798: #endif
799: #if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_COOKIES)
800: #define USED_TAG
801: switch(tag) {
802: case CURLOPT_COOKIE:
803: case CURLOPT_COOKIEFILE:
804: case CURLOPT_COOKIEJAR:
805: case CURLOPT_COOKIESESSION:
806: return TRUE;
807: default:
808: break;
809: }
810: #endif
811: #if defined(CURL_DISABLE_TELNET)
812: #define USED_TAG
813: switch(tag) {
814: case CURLOPT_TELNETOPTIONS:
815: return TRUE;
816: default:
817: break;
818: }
819: #endif
820: #ifdef CURL_DISABLE_TFTP
821: #define USED_TAG
822: switch(tag) {
823: case CURLOPT_TFTP_BLKSIZE:
824: case CURLOPT_TFTP_NO_OPTIONS:
825: return TRUE;
826: default:
827: break;
828: }
829: #endif
830: #ifdef CURL_DISABLE_NETRC
831: #define USED_TAG
832: switch(tag) {
833: case CURLOPT_NETRC:
834: case CURLOPT_NETRC_FILE:
835: return TRUE;
836: default:
837: break;
838: }
839: #endif
840:
841: #ifndef USED_TAG
842: (void)tag;
843: #endif
844: return FALSE;
845: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>