Annotation of embedaddon/curl/lib/setopt.c, revision 1.1.1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>