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

1.1     ! misho       1: /***************************************************************************
        !             2:  *                                  _   _ ____  _
        !             3:  *  Project                     ___| | | |  _ \| |
        !             4:  *                             / __| | | | |_) | |
        !             5:  *                            | (__| |_| |  _ <| |___
        !             6:  *                             \___|\___/|_| \_\_____|
        !             7:  *
        !             8:  * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
        !             9:  *
        !            10:  * This software is licensed as described in the file COPYING, which
        !            11:  * you should have received as part of this distribution. The terms
        !            12:  * are also available at https://curl.haxx.se/docs/copyright.html.
        !            13:  *
        !            14:  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
        !            15:  * copies of the Software, and permit persons to whom the Software is
        !            16:  * furnished to do so, under the terms of the COPYING file.
        !            17:  *
        !            18:  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
        !            19:  * KIND, either express or implied.
        !            20:  *
        !            21:  ***************************************************************************/
        !            22: 
        !            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>