Coverage Report

Created: 2024-05-04 12:45

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