File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / src / tool_setopt.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 10:01:15 2020 UTC (4 years, 10 months ago) by misho
Branches: curl, MAIN
CVS tags: v7_70_0p4, HEAD
curl

    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>