Coverage Report

Created: 2022-10-16 06:45

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