Annotation of embedaddon/curl/src/tool_setopt.c, revision 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: #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>