diff options
author | Alexander Smirnov <alex@ydb.tech> | 2024-10-16 12:11:24 +0000 |
---|---|---|
committer | Alexander Smirnov <alex@ydb.tech> | 2024-10-16 12:11:24 +0000 |
commit | 40811e93f3fdf9342a9295369994012420fac548 (patch) | |
tree | a8d85e094a9c21e10aa250f537c101fc2016a049 /contrib/libs/curl/src | |
parent | 30ebe5357bb143648c6be4d151ecd4944af81ada (diff) | |
parent | 28a0c4a9f297064538a018c512cd9bbd00a1a35d (diff) | |
download | ydb-40811e93f3fdf9342a9295369994012420fac548.tar.gz |
Merge branch 'rightlib' into mergelibs-241016-1210
Diffstat (limited to 'contrib/libs/curl/src')
62 files changed, 2841 insertions, 4196 deletions
diff --git a/contrib/libs/curl/src/terminal.c b/contrib/libs/curl/src/terminal.c deleted file mode 100644 index 7ba991d3e5..0000000000 --- a/contrib/libs/curl/src/terminal.c +++ /dev/null @@ -1,91 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "tool_setup.h" - -#ifdef HAVE_SYS_IOCTL_H -#include <sys/ioctl.h> -#endif - -#include "terminal.h" - -#include "memdebug.h" /* keep this as LAST include */ - -#ifdef HAVE_TERMIOS_H -# include <termios.h> -#elif defined(HAVE_TERMIO_H) -# include <termio.h> -#endif - -/* - * get_terminal_columns() returns the number of columns in the current - * terminal. It will return 79 on failure. Also, the number can be very big. - */ - -unsigned int get_terminal_columns(void) -{ - unsigned int width = 0; - char *colp = curl_getenv("COLUMNS"); - if(colp) { - char *endptr; - long num = strtol(colp, &endptr, 10); - if((endptr != colp) && (endptr == colp + strlen(colp)) && (num > 20) && - (num < 10000)) - width = (unsigned int)num; - curl_free(colp); - } - - if(!width) { - int cols = 0; - -#ifdef TIOCGSIZE - struct ttysize ts; - if(!ioctl(STDIN_FILENO, TIOCGSIZE, &ts)) - cols = ts.ts_cols; -#elif defined(TIOCGWINSZ) - struct winsize ts; - if(!ioctl(STDIN_FILENO, TIOCGWINSZ, &ts)) - cols = (int)ts.ws_col; -#elif defined(_WIN32) && !defined(CURL_WINDOWS_APP) - { - HANDLE stderr_hnd = GetStdHandle(STD_ERROR_HANDLE); - CONSOLE_SCREEN_BUFFER_INFO console_info; - - if((stderr_hnd != INVALID_HANDLE_VALUE) && - GetConsoleScreenBufferInfo(stderr_hnd, &console_info)) { - /* - * Do not use +1 to get the true screen-width since writing a - * character at the right edge will cause a line wrap. - */ - cols = (int) - (console_info.srWindow.Right - console_info.srWindow.Left); - } - } -#endif /* TIOCGSIZE */ - if(cols >= 0 && cols < 10000) - width = (unsigned int)cols; - } - if(!width) - width = 79; - return width; /* 79 for unknown, might also be very small or very big */ -} diff --git a/contrib/libs/curl/src/terminal.h b/contrib/libs/curl/src/terminal.h deleted file mode 100644 index dbd4abe281..0000000000 --- a/contrib/libs/curl/src/terminal.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef HEADER_CURL_TERMINAL_H -#define HEADER_CURL_TERMINAL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "tool_setup.h" - -unsigned int get_terminal_columns(void); - -#endif /* HEADER_CURL_TERMINAL_H */ diff --git a/contrib/libs/curl/src/tool_ca_embed.c b/contrib/libs/curl/src/tool_ca_embed.c deleted file mode 100644 index 9b7b593f80..0000000000 --- a/contrib/libs/curl/src/tool_ca_embed.c +++ /dev/null @@ -1 +0,0 @@ -extern const void *curl_ca_embed; const void *curl_ca_embed; diff --git a/contrib/libs/curl/src/tool_cb_dbg.c b/contrib/libs/curl/src/tool_cb_dbg.c index 6d2a617835..ce5e25e92c 100644 --- a/contrib/libs/curl/src/tool_cb_dbg.c +++ b/contrib/libs/curl/src/tool_cb_dbg.c @@ -23,6 +23,8 @@ ***************************************************************************/ #include "tool_setup.h" +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" @@ -57,7 +59,7 @@ static const char *hms_for_sec(time_t tv_sec) } secs = epoch_offset + tv_sec; /* !checksrc! disable BANNEDFUNC 1 */ - now = localtime(&secs); /* not thread safe but we do not care */ + now = localtime(&secs); /* not thread safe but we don't care */ msnprintf(hms_buf, sizeof(hms_buf), "%02d:%02d:%02d", now->tm_hour, now->tm_min, now->tm_sec); cached_tv_sec = tv_sec; @@ -97,7 +99,7 @@ int tool_debug_cb(CURL *handle, curl_infotype type, const char *text; struct timeval tv; char timebuf[20]; - /* largest signed 64-bit is: 9,223,372,036,854,775,807 + /* largest signed 64bit is: 9,223,372,036,854,775,807 * max length in decimal: 1 + (6*3) = 19 * formatted via TRC_IDS_FORMAT_IDS_2 this becomes 2 + 19 + 1 + 19 + 2 = 43 * negative xfer-id are not printed, negative conn-ids use TRC_IDS_FORMAT_1 @@ -189,8 +191,8 @@ int tool_debug_cb(CURL *handle, curl_infotype type, case CURLINFO_SSL_DATA_IN: case CURLINFO_SSL_DATA_OUT: if(!traced_data) { - /* if the data is output to a tty and we are sending this debug trace - to stderr or stdout, we do not display the alert about the data not + /* if the data is output to a tty and we're sending this debug trace + to stderr or stdout, we don't display the alert about the data not being shown as the data _is_ shown then just not via this function */ if(!config->isatty || @@ -215,7 +217,7 @@ int tool_debug_cb(CURL *handle, curl_infotype type, switch(type) { case CURLINFO_TEXT: fprintf(output, "%s%s== Info: %.*s", timebuf, idsbuf, (int)size, data); - FALLTHROUGH(); + /* FALLTHROUGH */ default: /* in case a new one is introduced to shock us */ return 0; @@ -284,7 +286,7 @@ static void dump(const char *timebuf, const char *idsbuf, const char *text, (void)infotype; fprintf(stream, "%c", ((ptr[i + c] >= 0x20) && (ptr[i + c] < 0x7F)) ? ptr[i + c] : UNPRINTABLE_CHAR); - /* check again for 0D0A, to avoid an extra \n if it is at width */ + /* check again for 0D0A, to avoid an extra \n if it's at width */ if((tracetype == TRACE_ASCII) && (i + c + 2 < size) && (ptr[i + c + 1] == 0x0D) && (ptr[i + c + 2] == 0x0A)) { diff --git a/contrib/libs/curl/src/tool_cb_hdr.c b/contrib/libs/curl/src/tool_cb_hdr.c index 969acac1e4..198a8d050c 100644 --- a/contrib/libs/curl/src/tool_cb_hdr.c +++ b/contrib/libs/curl/src/tool_cb_hdr.c @@ -24,10 +24,9 @@ #include "tool_setup.h" #include "strcase.h" -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" @@ -48,7 +47,7 @@ static char *parse_filename(const char *ptr, size_t len); #else #define BOLD "\x1b[1m" /* Switch off bold by setting "all attributes off" since the explicit - bold-off code (21) is not supported everywhere - like in the mac + bold-off code (21) isn't supported everywhere - like in the mac Terminal. */ #define BOLDOFF "\x1b[0m" /* OSC 8 hyperlink escape sequence */ @@ -103,29 +102,15 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) if(rc != cb) return rc; /* flush the stream to send off what we got earlier */ - if(fflush(heads->stream)) { - errorf(per->config->global, "Failed writing headers to %s", - per->config->headerfile); - return CURL_WRITEFUNC_ERROR; - } + (void)fflush(heads->stream); } - curl_easy_getinfo(per->curl, CURLINFO_SCHEME, &scheme); - scheme = proto_token(scheme); - if((scheme == proto_http || scheme == proto_https)) { - long response = 0; - curl_easy_getinfo(per->curl, CURLINFO_RESPONSE_CODE, &response); - - if((response/100 != 2) && (response/100 != 3)) - /* only care about etag and content-disposition headers in 2xx and 3xx - responses */ - ; - /* - * Write etag to file when --etag-save option is given. - */ - else if(per->config->etag_save_file && etag_save->stream && - /* match only header that start with etag (case insensitive) */ - checkprefix("etag:", str)) { + /* + * Write etag to file when --etag-save option is given. + */ + if(per->config->etag_save_file && etag_save->stream) { + /* match only header that start with etag (case insensitive) */ + if(curl_strnequal(str, "etag:", 5)) { const char *etag_h = &str[5]; const char *eot = end - 1; if(*eot == '\n') { @@ -136,19 +121,6 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) if(eot >= etag_h) { size_t etag_length = eot - etag_h + 1; - /* - * Truncate the etag save stream, it can have an existing etag value. - */ -#ifdef HAVE_FTRUNCATE - if(ftruncate(fileno(etag_save->stream), 0)) { - return CURL_WRITEFUNC_ERROR; - } -#else - if(fseek(etag_save->stream, 0, SEEK_SET)) { - return CURL_WRITEFUNC_ERROR; - } -#endif - fwrite(etag_h, size, etag_length, etag_save->stream); /* terminate with newline */ fputc('\n', etag_save->stream); @@ -156,72 +128,69 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) } } } + } - /* - * This callback sets the filename where output shall be written when - * curl options --remote-name (-O) and --remote-header-name (-J) have - * been simultaneously given and additionally server returns an HTTP - * Content-Disposition header specifying a filename property. - */ - - else if(hdrcbdata->honor_cd_filename && - (cb > 20) && checkprefix("Content-disposition:", str)) { - const char *p = str + 20; + /* + * This callback sets the filename where output shall be written when + * curl options --remote-name (-O) and --remote-header-name (-J) have + * been simultaneously given and additionally server returns an HTTP + * Content-Disposition header specifying a filename property. + */ - /* look for the 'filename=' parameter - (encoded filenames (*=) are not supported) */ - for(;;) { - char *filename; - size_t len; + curl_easy_getinfo(per->curl, CURLINFO_SCHEME, &scheme); + scheme = proto_token(scheme); + if(hdrcbdata->honor_cd_filename && + (cb > 20) && checkprefix("Content-disposition:", str) && + (scheme == proto_http || scheme == proto_https)) { + const char *p = str + 20; + + /* look for the 'filename=' parameter + (encoded filenames (*=) are not supported) */ + for(;;) { + char *filename; + size_t len; + + while((p < end) && *p && !ISALPHA(*p)) + p++; + if(p > end - 9) + break; - while((p < end) && *p && !ISALPHA(*p)) + if(memcmp(p, "filename=", 9)) { + /* no match, find next parameter */ + while((p < end) && *p && (*p != ';')) p++; - if(p > end - 9) + if((p < end) && *p) + continue; + else break; - - if(memcmp(p, "filename=", 9)) { - /* no match, find next parameter */ - while((p < end) && *p && (*p != ';')) - p++; - if((p < end) && *p) - continue; - else - break; - } - p += 9; - - len = cb - (size_t)(p - str); - filename = parse_filename(p, len); - if(filename) { - if(outs->stream) { - /* indication of problem, get out! */ - free(filename); - return CURL_WRITEFUNC_ERROR; - } - - if(per->config->output_dir) { - outs->filename = aprintf("%s/%s", per->config->output_dir, - filename); - free(filename); - if(!outs->filename) - return CURL_WRITEFUNC_ERROR; - } - else - outs->filename = filename; - - outs->is_cd_filename = TRUE; - outs->s_isreg = TRUE; - outs->fopened = FALSE; - outs->alloc_filename = TRUE; - hdrcbdata->honor_cd_filename = FALSE; /* done now! */ - if(!tool_create_output_file(outs, per->config)) - return CURL_WRITEFUNC_ERROR; + } + p += 9; + + /* this expression below typecasts 'cb' only to avoid + warning: signed and unsigned type in conditional expression + */ + len = (ssize_t)cb - (p - str); + filename = parse_filename(p, len); + if(filename) { + if(outs->stream) { + /* indication of problem, get out! */ + free(filename); + return CURL_WRITEFUNC_ERROR; } - break; + + outs->is_cd_filename = TRUE; + outs->s_isreg = TRUE; + outs->fopened = FALSE; + outs->filename = filename; + outs->alloc_filename = TRUE; + hdrcbdata->honor_cd_filename = FALSE; /* done now! */ + if(!tool_create_output_file(outs, per->config)) + return CURL_WRITEFUNC_ERROR; } - if(!outs->stream && !tool_create_output_file(outs, per->config)) - return CURL_WRITEFUNC_ERROR; + break; } + if(!outs->stream && !tool_create_output_file(outs, per->config)) + return CURL_WRITEFUNC_ERROR; } if(hdrcbdata->config->writeout) { char *value = memchr(ptr, ':', cb); @@ -271,7 +240,7 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) } /* - * Copies a filename part and returns an ALLOCATED data buffer. + * Copies a file name part and returns an ALLOCATED data buffer. */ static char *parse_filename(const char *ptr, size_t len) { @@ -312,7 +281,7 @@ static char *parse_filename(const char *ptr, size_t len) } /* If the filename contains a backslash, only use filename portion. The idea - is that even systems that do not handle backslashes as path separators + is that even systems that don't handle backslashes as path separators probably want the path removed for convenience. */ q = strrchr(p, '\\'); if(q) { @@ -323,7 +292,7 @@ static char *parse_filename(const char *ptr, size_t len) } } - /* make sure the filename does not end in \r or \n */ + /* make sure the file name doesn't end in \r or \n */ q = strchr(p, '\r'); if(q) *q = '\0'; @@ -347,17 +316,17 @@ static char *parse_filename(const char *ptr, size_t len) #endif /* _WIN32 || MSDOS */ /* in case we built debug enabled, we allow an environment variable - * named CURL_TESTDIR to prefix the given filename to put it into a + * named CURL_TESTDIR to prefix the given file name to put it into a * specific directory */ #ifdef DEBUGBUILD { - char *tdir = curl_getenv("CURL_TESTDIR"); + char *tdir = curlx_getenv("CURL_TESTDIR"); if(tdir) { char buffer[512]; /* suitably large */ msnprintf(buffer, sizeof(buffer), "%s/%s", tdir, copy); Curl_safefree(copy); - copy = strdup(buffer); /* clone the buffer, we do not use the libcurl + copy = strdup(buffer); /* clone the buffer, we don't use the libcurl aprintf() or similar since we want to use the same memory code as the "real" parse_filename function */ @@ -374,9 +343,9 @@ static char *parse_filename(const char *ptr, size_t len) * Treat the Location: header specially, by writing a special escape * sequence that adds a hyperlink to the displayed text. This makes * the absolute URL of the redirect clickable in supported terminals, - * which could not happen otherwise for relative URLs. The Location: + * which couldn't happen otherwise for relative URLs. The Location: * header is supposed to always be absolute so this theoretically - * should not be needed but the real world returns plenty of relative + * shouldn't be needed but the real world returns plenty of relative * URLs here. */ static @@ -448,7 +417,7 @@ void write_linked_location(CURL *curl, const char *location, size_t loclen, goto locdone; } - /* Not a "safe" URL: do not linkify it */ + /* Not a "safe" URL: don't linkify it */ locout: /* Write the normal output in case of error or unsafe */ diff --git a/contrib/libs/curl/src/tool_cb_prg.c b/contrib/libs/curl/src/tool_cb_prg.c index 5acd3fcc78..ef47b42da0 100644 --- a/contrib/libs/curl/src/tool_cb_prg.c +++ b/contrib/libs/curl/src/tool_cb_prg.c @@ -23,18 +23,28 @@ ***************************************************************************/ #include "tool_setup.h" +#ifdef HAVE_SYS_IOCTL_H +#include <sys/ioctl.h> +#endif + +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" #include "tool_cb_prg.h" #include "tool_util.h" #include "tool_operate.h" -#include "terminal.h" #include "memdebug.h" /* keep this as LAST include */ -#define MAX_BARLENGTH 400 -#define MIN_BARLENGTH 20 +#define MAX_BARLENGTH 256 + +#ifdef HAVE_TERMIOS_H +# include <termios.h> +#elif defined(HAVE_TERMIO_H) +# include <termio.h> +#endif /* 200 values generated by this perl code: @@ -43,7 +53,7 @@ printf "%d, ", sin($i/200 * 2 * $pi) * 500000 + 500000; } */ -static const int sinus[] = { +static const unsigned int sinus[] = { 515704, 531394, 547052, 562664, 578214, 593687, 609068, 624341, 639491, 654504, 669364, 684057, 698568, 712883, 726989, 740870, 754513, 767906, 781034, 793885, 806445, 818704, 830647, 842265, 853545, 864476, 875047, @@ -76,19 +86,19 @@ static void fly(struct ProgressData *bar, bool moved) /* bar->width is range checked when assigned */ DEBUGASSERT(bar->width <= MAX_BARLENGTH); - buf[0] = '\r'; - memset(&buf[1], ' ', bar->width); + memset(buf, ' ', bar->width); + buf[bar->width] = '\r'; buf[bar->width + 1] = '\0'; - memcpy(&buf[bar->bar + 1], "-=O=-", 5); + memcpy(&buf[bar->bar], "-=O=-", 5); - pos = sinus[bar->tick%200] / (1000000 / check) + 1; + pos = sinus[bar->tick%200] / (1000000 / check); buf[pos] = '#'; - pos = sinus[(bar->tick + 5)%200] / (1000000 / check) + 1; + pos = sinus[(bar->tick + 5)%200] / (1000000 / check); buf[pos] = '#'; - pos = sinus[(bar->tick + 10)%200] / (1000000 / check) + 1; + pos = sinus[(bar->tick + 10)%200] / (1000000 / check); buf[pos] = '#'; - pos = sinus[(bar->tick + 15)%200] / (1000000 / check) + 1; + pos = sinus[(bar->tick + 15)%200] / (1000000 / check); buf[pos] = '#'; fputs(buf, bar->out); @@ -118,17 +128,6 @@ static void fly(struct ProgressData *bar, bool moved) # define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFFFFFFFFFF) #endif -static void update_width(struct ProgressData *bar) -{ - int cols = get_terminal_columns(); - if(cols > MAX_BARLENGTH) - bar->width = MAX_BARLENGTH; - else if(cols > MIN_BARLENGTH) - bar->width = (int)cols; - else - bar->width = MIN_BARLENGTH; -} - int tool_progress_cb(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow) @@ -171,10 +170,10 @@ int tool_progress_cb(void *clientp, if(total) { /* we know the total data to get... */ if(bar->prev == point) - /* progress did not change since last invoke */ + /* progress didn't change since last invoke */ return 0; else if((tvdiff(now, bar->prevtime) < 100L) && point < total) - /* limit progress-bar updating to 10 Hz except when we are at 100% */ + /* limit progress-bar updating to 10 Hz except when we're at 100% */ return 0; } else { @@ -182,7 +181,6 @@ int tool_progress_cb(void *clientp, if(tvdiff(now, bar->prevtime) < 100L) /* limit progress-bar updating to 10 Hz */ return 0; - update_width(bar); fly(bar, point != bar->prev); } } @@ -190,14 +188,13 @@ int tool_progress_cb(void *clientp, /* simply count invokes */ bar->calls++; - update_width(bar); if((total > 0) && (point != bar->prev)) { char line[MAX_BARLENGTH + 1]; char format[40]; double frac; double percent; int barwidth; - size_t num; + int num; if(point > total) /* we have got more than the expected total! */ total = point; @@ -205,20 +202,13 @@ int tool_progress_cb(void *clientp, frac = (double)point / (double)total; percent = frac * 100.0; barwidth = bar->width - 7; - num = (size_t) (((double)barwidth) * frac); + num = (int) (((double)barwidth) * frac); if(num > MAX_BARLENGTH) num = MAX_BARLENGTH; memset(line, '#', num); line[num] = '\0'; msnprintf(format, sizeof(format), "\r%%-%ds %%5.1f%%%%", barwidth); -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wformat-nonliteral" -#endif fprintf(bar->out, format, line, percent); -#ifdef __clang__ -#pragma clang diagnostic pop -#endif } fflush(bar->out); bar->prev = point; @@ -235,14 +225,59 @@ int tool_progress_cb(void *clientp, void progressbarinit(struct ProgressData *bar, struct OperationConfig *config) { + char *colp; memset(bar, 0, sizeof(struct ProgressData)); /* pass the resume from value through to the progress function so it can - * display progress towards total file not just the part that is left. */ + * display progress towards total file not just the part that's left. */ if(config->use_resume) bar->initial_size = config->resume_from; - update_width(bar); + colp = curlx_getenv("COLUMNS"); + if(colp) { + char *endptr; + long num = strtol(colp, &endptr, 10); + if((endptr != colp) && (endptr == colp + strlen(colp)) && (num > 20) && + (num < 10000)) + bar->width = (int)num; + curl_free(colp); + } + + if(!bar->width) { + int cols = 0; + +#ifdef TIOCGSIZE + struct ttysize ts; + if(!ioctl(STDIN_FILENO, TIOCGSIZE, &ts)) + cols = ts.ts_cols; +#elif defined(TIOCGWINSZ) + struct winsize ts; + if(!ioctl(STDIN_FILENO, TIOCGWINSZ, &ts)) + cols = ts.ws_col; +#elif defined(_WIN32) + { + HANDLE stderr_hnd = GetStdHandle(STD_ERROR_HANDLE); + CONSOLE_SCREEN_BUFFER_INFO console_info; + + if((stderr_hnd != INVALID_HANDLE_VALUE) && + GetConsoleScreenBufferInfo(stderr_hnd, &console_info)) { + /* + * Do not use +1 to get the true screen-width since writing a + * character at the right edge will cause a line wrap. + */ + cols = (int) + (console_info.srWindow.Right - console_info.srWindow.Left); + } + } +#endif /* TIOCGSIZE */ + if(cols > 20) + bar->width = cols; + } + + if(!bar->width) + bar->width = 79; + else if(bar->width > MAX_BARLENGTH) + bar->width = MAX_BARLENGTH; bar->out = tool_stderr; bar->tick = 150; diff --git a/contrib/libs/curl/src/tool_cb_prg.h b/contrib/libs/curl/src/tool_cb_prg.h index dc10f2a5cc..565ad565a9 100644 --- a/contrib/libs/curl/src/tool_cb_prg.h +++ b/contrib/libs/curl/src/tool_cb_prg.h @@ -40,8 +40,6 @@ struct ProgressData { int barmove; }; -struct OperationConfig; - void progressbarinit(struct ProgressData *bar, struct OperationConfig *config); diff --git a/contrib/libs/curl/src/tool_cb_rea.c b/contrib/libs/curl/src/tool_cb_rea.c index 0fe4014300..8cb5bbe8ac 100644 --- a/contrib/libs/curl/src/tool_cb_rea.c +++ b/contrib/libs/curl/src/tool_cb_rea.c @@ -27,6 +27,8 @@ #include <sys/select.h> #endif +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" @@ -34,7 +36,6 @@ #include "tool_operate.h" #include "tool_util.h" #include "tool_msgs.h" -#include "tool_sleep.h" #include "memdebug.h" /* keep this as LAST include */ @@ -88,7 +89,7 @@ size_t tool_read_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) config->readbusy = TRUE; return CURL_READFUNC_PAUSE; } - /* since size_t is unsigned we cannot return negative values fine */ + /* since size_t is unsigned we can't return negative values fine */ rc = 0; } if((per->uploadfilesize != -1) && @@ -123,33 +124,8 @@ int tool_readbusy_cb(void *clientp, (void)ulnow; /* unused */ if(config->readbusy) { - /* lame code to keep the rate down because the input might not deliver - anything, get paused again and come back here immediately */ - static long rate = 500; - static struct timeval prev; - static curl_off_t ulprev; - - if(ulprev == ulnow) { - /* it did not upload anything since last call */ - struct timeval now = tvnow(); - if(prev.tv_sec) - /* get a rolling average rate */ - /* rate = rate - rate/4 + tvdiff(now, prev)/4; */ - rate -= rate/4 - tvdiff(now, prev)/4; - prev = now; - } - else { - rate = 50; - ulprev = ulnow; - } - if(rate >= 50) { - /* keeps the looping down to 20 times per second in the crazy case */ - config->readbusy = FALSE; - curl_easy_pause(per->curl, CURLPAUSE_CONT); - } - else - /* sleep half a period */ - tool_go_sleep(25); + config->readbusy = FALSE; + curl_easy_pause(per->curl, CURLPAUSE_CONT); } return per->noprogress? 0 : CURL_PROGRESSFUNC_CONTINUE; diff --git a/contrib/libs/curl/src/tool_cb_see.c b/contrib/libs/curl/src/tool_cb_see.c index a425ebe9de..bce57bb281 100644 --- a/contrib/libs/curl/src/tool_cb_see.c +++ b/contrib/libs/curl/src/tool_cb_see.c @@ -23,6 +23,8 @@ ***************************************************************************/ #include "tool_setup.h" +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" @@ -52,27 +54,27 @@ int tool_seek_cb(void *userdata, curl_off_t offset, int whence) #if(SIZEOF_CURL_OFF_T > SIZEOF_OFF_T) && !defined(USE_WIN32_LARGE_FILES) /* The offset check following here is only interesting if curl_off_t is - larger than off_t and we are not using the Win32 large file support - macros that provide the support to do 64-bit seeks correctly */ + larger than off_t and we are not using the WIN32 large file support + macros that provide the support to do 64bit seeks correctly */ if(offset > OUR_MAX_SEEK_O) { /* Some precaution code to work around problems with different data sizes - to allow seeking >32-bit even if off_t is 32-bit. Should be very rare - and is really valid on weirdo-systems. */ + to allow seeking >32bit even if off_t is 32bit. Should be very rare and + is really valid on weirdo-systems. */ curl_off_t left = offset; if(whence != SEEK_SET) - /* this code path does not support other types */ + /* this code path doesn't support other types */ return CURL_SEEKFUNC_FAIL; if(LSEEK_ERROR == lseek(per->infd, 0, SEEK_SET)) - /* could not rewind to beginning */ + /* couldn't rewind to beginning */ return CURL_SEEKFUNC_FAIL; while(left) { long step = (left > OUR_MAX_SEEK_O) ? OUR_MAX_SEEK_L : (long)left; if(LSEEK_ERROR == lseek(per->infd, step, SEEK_CUR)) - /* could not seek forwards the desired amount */ + /* couldn't seek forwards the desired amount */ return CURL_SEEKFUNC_FAIL; left -= step; } @@ -81,10 +83,39 @@ int tool_seek_cb(void *userdata, curl_off_t offset, int whence) #endif if(LSEEK_ERROR == lseek(per->infd, offset, whence)) - /* could not rewind, the reason is in errno but errno is just not portable - enough and we do not actually care that much why we failed. We will let + /* couldn't rewind, the reason is in errno but errno is just not portable + enough and we don't actually care that much why we failed. We'll let libcurl know that it may try other means if it wants to. */ return CURL_SEEKFUNC_CANTSEEK; return CURL_SEEKFUNC_OK; } + +#ifdef USE_TOOL_FTRUNCATE + +#ifdef _WIN32_WCE +/* 64-bit lseek-like function unavailable */ +# undef _lseeki64 +# define _lseeki64(hnd,ofs,whence) lseek(hnd,ofs,whence) +# undef _get_osfhandle +# define _get_osfhandle(fd) (fd) +#endif + +/* + * Truncate a file handle at a 64-bit position 'where'. + */ + +int tool_ftruncate64(int fd, curl_off_t where) +{ + intptr_t handle = _get_osfhandle(fd); + + if(_lseeki64(fd, where, SEEK_SET) < 0) + return -1; + + if(!SetEndOfFile((HANDLE)handle)) + return -1; + + return 0; +} + +#endif /* USE_TOOL_FTRUNCATE */ diff --git a/contrib/libs/curl/src/tool_cb_see.h b/contrib/libs/curl/src/tool_cb_see.h index e7b30a765d..b5d7bf985e 100644 --- a/contrib/libs/curl/src/tool_cb_see.h +++ b/contrib/libs/curl/src/tool_cb_see.h @@ -25,6 +25,18 @@ ***************************************************************************/ #include "tool_setup.h" +#if defined(_WIN32) && !defined(HAVE_FTRUNCATE) + +int tool_ftruncate64(int fd, curl_off_t where); + +#undef ftruncate +#define ftruncate(fd,where) tool_ftruncate64(fd,where) + +#define HAVE_FTRUNCATE 1 +#define USE_TOOL_FTRUNCATE 1 + +#endif /* _WIN32 && ! HAVE_FTRUNCATE */ + /* ** callback for CURLOPT_SEEKFUNCTION */ diff --git a/contrib/libs/curl/src/tool_cb_soc.c b/contrib/libs/curl/src/tool_cb_soc.c deleted file mode 100644 index 22048ee6bb..0000000000 --- a/contrib/libs/curl/src/tool_cb_soc.c +++ /dev/null @@ -1,58 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "tool_setup.h" - -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> /* IPPROTO_TCP */ -#endif - -#include "tool_cb_soc.h" - -/* -** callback for CURLOPT_OPENSOCKETFUNCTION -** -** Notice that only Linux is supported for the moment. -*/ - -curl_socket_t tool_socket_open_mptcp_cb(void *clientp, - curlsocktype purpose, - struct curl_sockaddr *addr) -{ - int protocol = addr->protocol; - - (void)clientp; - (void)purpose; - - if(protocol == IPPROTO_TCP) -#if defined(__linux__) -# ifndef IPPROTO_MPTCP -# define IPPROTO_MPTCP 262 -# endif - protocol = IPPROTO_MPTCP; -#else - return CURL_SOCKET_BAD; -#endif - - return socket(addr->family, addr->socktype, protocol); -} diff --git a/contrib/libs/curl/src/tool_cb_soc.h b/contrib/libs/curl/src/tool_cb_soc.h deleted file mode 100644 index f02150aa82..0000000000 --- a/contrib/libs/curl/src/tool_cb_soc.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef HEADER_CURL_TOOL_CB_SOC_H -#define HEADER_CURL_TOOL_CB_SOC_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "tool_setup.h" - -/* -** callback for CURLOPT_OPENSOCKETFUNCTION -*/ - -curl_socket_t tool_socket_open_mptcp_cb(void *clientp, - curlsocktype purpose, - struct curl_sockaddr *addr); - -#endif /* HEADER_CURL_TOOL_CB_SOC_H */ diff --git a/contrib/libs/curl/src/tool_cb_wrt.c b/contrib/libs/curl/src/tool_cb_wrt.c index e35489a39f..98063c39c2 100644 --- a/contrib/libs/curl/src/tool_cb_wrt.c +++ b/contrib/libs/curl/src/tool_cb_wrt.c @@ -30,6 +30,8 @@ #include <sys/stat.h> +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" @@ -54,11 +56,24 @@ bool tool_create_output_file(struct OutStruct *outs, { struct GlobalConfig *global; FILE *file = NULL; - const char *fname = outs->filename; + char *fname = outs->filename; + char *aname = NULL; DEBUGASSERT(outs); DEBUGASSERT(config); global = config->global; - DEBUGASSERT(fname && *fname); + if(!fname || !*fname) { + warnf(global, "Remote filename has no length"); + return FALSE; + } + + if(config->output_dir && outs->is_cd_filename) { + aname = aprintf("%s/%s", config->output_dir, fname); + if(!aname) { + errorf(global, "out of memory"); + return FALSE; + } + fname = aname; + } if(config->file_clobber_mode == CLOBBER_ALWAYS || (config->file_clobber_mode == CLOBBER_DEFAULT && @@ -70,7 +85,7 @@ bool tool_create_output_file(struct OutStruct *outs, int fd; do { fd = open(fname, O_CREAT | O_WRONLY | O_EXCL | O_BINARY, OPENMODE); - /* Keep retrying in the hope that it is not interrupted sometime */ + /* Keep retrying in the hope that it isn't interrupted sometime */ } while(fd == -1 && errno == EINTR); if(config->file_clobber_mode == CLOBBER_NEVER && fd == -1) { int next_num = 1; @@ -79,25 +94,27 @@ bool tool_create_output_file(struct OutStruct *outs, char *newname; /* Guard against wraparound in new filename */ if(newlen < len) { + free(aname); errorf(global, "overflow in filename generation"); return FALSE; } newname = malloc(newlen); if(!newname) { errorf(global, "out of memory"); + free(aname); return FALSE; } memcpy(newname, fname, len); newname[len] = '.'; - while(fd == -1 && /* have not successfully opened a file */ + while(fd == -1 && /* haven't successfully opened a file */ (errno == EEXIST || errno == EISDIR) && /* because we keep having files that already exist */ - next_num < 100 /* and we have not reached the retry limit */ ) { - msnprintf(newname + len + 1, 12, "%d", next_num); + next_num < 100 /* and we haven't reached the retry limit */ ) { + curlx_msnprintf(newname + len + 1, 12, "%d", next_num); next_num++; do { fd = open(newname, O_CREAT | O_WRONLY | O_EXCL | O_BINARY, OPENMODE); - /* Keep retrying in the hope that it is not interrupted sometime */ + /* Keep retrying in the hope that it isn't interrupted sometime */ } while(fd == -1 && errno == EINTR); } outs->filename = newname; /* remember the new one */ @@ -118,8 +135,10 @@ bool tool_create_output_file(struct OutStruct *outs, if(!file) { warnf(global, "Failed to open the file %s: %s", fname, strerror(errno)); + free(aname); return FALSE; } + free(aname); outs->s_isreg = TRUE; outs->fopened = TRUE; outs->stream = file; @@ -147,7 +166,7 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) #ifdef DEBUGBUILD { - char *tty = curl_getenv("CURL_ISATTY"); + char *tty = curlx_getenv("CURL_ISATTY"); if(tty) { is_tty = TRUE; curl_free(tty); @@ -214,7 +233,7 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) #ifdef _WIN32 fhnd = _get_osfhandle(fileno(outs->stream)); - /* if Windows console then UTF-8 must be converted to UTF-16 */ + /* if windows console then UTF-8 must be converted to UTF-16 */ if(isatty(fileno(outs->stream)) && GetConsoleScreenBufferInfo((HANDLE)fhnd, &console_info)) { wchar_t *wc_buf; @@ -313,8 +332,7 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) if(rlen) { /* calculate buffer size for wide characters */ - wc_len = (DWORD)MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)rbuf, (int)rlen, - NULL, 0); + wc_len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)rbuf, rlen, NULL, 0); if(!wc_len) return CURL_WRITEFUNC_ERROR; @@ -322,8 +340,8 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) if(!wc_buf) return CURL_WRITEFUNC_ERROR; - wc_len = (DWORD)MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)rbuf, (int)rlen, - wc_buf, (int)wc_len); + wc_len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)rbuf, rlen, wc_buf, + wc_len); if(!wc_len) { free(wc_buf); return CURL_WRITEFUNC_ERROR; diff --git a/contrib/libs/curl/src/tool_cfgable.c b/contrib/libs/curl/src/tool_cfgable.c index 5564e250d3..906e23e141 100644 --- a/contrib/libs/curl/src/tool_cfgable.c +++ b/contrib/libs/curl/src/tool_cfgable.c @@ -25,7 +25,6 @@ #include "tool_cfgable.h" #include "tool_formparse.h" -#include "tool_paramhlp.h" #include "tool_main.h" #include "memdebug.h" /* keep this as LAST include */ @@ -34,6 +33,7 @@ void config_init(struct OperationConfig *config) { memset(config, 0, sizeof(struct OperationConfig)); + config->postfieldsize = -1; config->use_httpget = FALSE; config->create_dirs = FALSE; config->maxredirs = DEFAULT_MAXREDIRS; @@ -45,7 +45,6 @@ void config_init(struct OperationConfig *config) config->http09_allowed = FALSE; config->ftp_skip_ip = TRUE; config->file_clobber_mode = CLOBBER_DEFAULT; - curlx_dyn_init(&config->postdata, MAX_FILE2MEMORY); } static void free_config_fields(struct OperationConfig *config) @@ -60,7 +59,7 @@ static void free_config_fields(struct OperationConfig *config) Curl_safefree(config->cookiejar); curl_slist_free_all(config->cookiefiles); - Curl_dyn_free(&config->postdata); + Curl_safefree(config->postfields); Curl_safefree(config->query); Curl_safefree(config->referer); @@ -114,8 +113,6 @@ static void free_config_fields(struct OperationConfig *config) Curl_safefree(config->doh_url); Curl_safefree(config->cipher_list); Curl_safefree(config->proxy_cipher_list); - Curl_safefree(config->cipher13_list); - Curl_safefree(config->proxy_cipher13_list); Curl_safefree(config->cert); Curl_safefree(config->proxy_cert); Curl_safefree(config->cert_type); @@ -178,14 +175,6 @@ static void free_config_fields(struct OperationConfig *config) Curl_safefree(config->aws_sigv4); Curl_safefree(config->proto_str); Curl_safefree(config->proto_redir_str); -#ifdef USE_ECH - Curl_safefree(config->ech); - config->ech = NULL; - Curl_safefree(config->ech_config); - config->ech_config = NULL; - Curl_safefree(config->ech_public); - config->ech_public = NULL; -#endif } void config_free(struct OperationConfig *config) diff --git a/contrib/libs/curl/src/tool_cfgable.h b/contrib/libs/curl/src/tool_cfgable.h index 729cd5241a..57e8fce527 100644 --- a/contrib/libs/curl/src/tool_cfgable.h +++ b/contrib/libs/curl/src/tool_cfgable.h @@ -50,8 +50,8 @@ struct OperationConfig { struct curl_slist *cookies; /* cookies to serialize into a single line */ char *cookiejar; /* write to this file */ struct curl_slist *cookiefiles; /* file(s) to load cookies from */ - char *altsvc; /* alt-svc cache filename */ - char *hsts; /* HSTS cache filename */ + char *altsvc; /* alt-svc cache file name */ + char *hsts; /* HSTS cache file name */ bool cookiesession; /* new session? */ bool encoding; /* Accept-Encoding please */ bool tr_encoding; /* Transfer-Encoding please */ @@ -68,7 +68,7 @@ struct OperationConfig { char *proto_default; curl_off_t resume_from; char *postfields; - struct curlx_dynbuf postdata; + curl_off_t postfieldsize; char *referer; char *query; long timeout_ms; @@ -85,8 +85,6 @@ struct OperationConfig { char *range; long low_speed_limit; long low_speed_time; - long ip_tos; /* IP Type of Service */ - long vlan_priority; /* VLAN priority */ char *dns_servers; /* dot notation: 1.1.1.1;2.2.2.2 */ char *dns_interface; /* interface name */ char *dns_ipv4_addr; /* dot notation */ @@ -111,12 +109,12 @@ struct OperationConfig { bool sasl_ir; /* Enable/disable SASL initial response */ bool proxytunnel; bool ftp_append; /* APPE on ftp */ - bool use_ascii; /* select ASCII or text transfer */ + bool use_ascii; /* select ascii or text transfer */ bool autoreferer; /* automatically set referer */ bool failonerror; /* fail on (HTTP) errors */ bool failwithbody; /* fail on (HTTP) errors but still store body */ bool show_headers; /* show headers to data output */ - bool no_body; /* do not get the body */ + bool no_body; /* don't get the body */ bool dirlistonly; /* only get the FTP dir list */ bool followlocation; /* follow http redirects */ bool unrestricted_auth; /* Continue to send authentication (user+password) @@ -249,8 +247,7 @@ struct OperationConfig { bool post302; bool post303; bool nokeepalive; /* for keepalive needs */ - long alivetime; /* keepalive-time */ - long alivecnt; /* keepalive-cnt */ + long alivetime; bool content_disposition; /* use Content-disposition filename */ int default_node_flags; /* default flags to search for each 'node', which @@ -295,28 +292,19 @@ struct OperationConfig { CLOBBER_NEVER, /* If the file exists, always fail */ CLOBBER_ALWAYS /* If the file exists, always overwrite it */ } file_clobber_mode; - bool mptcp; /* enable MPTCP support */ struct GlobalConfig *global; struct OperationConfig *prev; struct OperationConfig *next; /* Always last in the struct */ struct State state; /* for create_transfer() */ bool rm_partial; /* on error, remove partially written output files */ - bool skip_existing; -#ifdef USE_ECH - char *ech; /* Config set by --ech keywords */ - char *ech_config; /* Config set by "--ech esl:" option */ - char *ech_public; /* Config set by "--ech pn:" option */ -#endif - }; struct GlobalConfig { bool showerror; /* show errors when silent */ - bool silent; /* do not show messages, --silent given */ - bool noprogress; /* do not show progress bar */ + bool silent; /* don't show messages, --silent given */ + bool noprogress; /* don't show progress bar */ bool isatty; /* Updated internally if output is a tty */ - unsigned char verbosity; /* How verbose we should be */ char *trace_dump; /* file to dump the network trace to */ FILE *trace_stream; bool trace_fopened; @@ -324,12 +312,12 @@ struct GlobalConfig { bool tracetime; /* include timestamp? */ bool traceids; /* include xfer-/conn-id? */ int progressmode; /* CURL_PROGRESS_BAR / CURL_PROGRESS_STATS */ - char *libcurl; /* Output libcurl code to this filename */ + char *libcurl; /* Output libcurl code to this file name */ bool fail_early; /* exit on first transfer error */ bool styled_output; /* enable fancy output style detection */ long ms_per_transfer; /* start next transfer after (at least) this many milliseconds */ -#ifdef DEBUGBUILD +#ifdef CURLDEBUG bool test_event_based; #endif bool parallel; diff --git a/contrib/libs/curl/src/tool_dirhie.c b/contrib/libs/curl/src/tool_dirhie.c index 772664c5fb..1cadbd0beb 100644 --- a/contrib/libs/curl/src/tool_dirhie.c +++ b/contrib/libs/curl/src/tool_dirhie.c @@ -29,6 +29,8 @@ # include <direct.h> #endif +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" #include "tool_dirhie.h" @@ -48,7 +50,7 @@ static void show_dir_errno(struct GlobalConfig *global, const char *name) switch(errno) { #ifdef EACCES case EACCES: - errorf(global, "You do not have permission to create %s", name); + errorf(global, "You don't have permission to create %s", name); break; #endif #ifdef ENAMETOOLONG @@ -115,7 +117,7 @@ CURLcode create_dir_hierarchy(const char *outfile, struct GlobalConfig *global) } dirbuildup[0] = '\0'; - /* Allow strtok() here since this is not used threaded */ + /* Allow strtok() here since this isn't used threaded */ /* !checksrc! disable BANNEDFUNC 2 */ tempdir = strtok(outdup, PATH_DELIMITERS); @@ -135,13 +137,13 @@ CURLcode create_dir_hierarchy(const char *outfile, struct GlobalConfig *global) It may seem as though that would harmlessly fail but it could be a corner case if X: did not exist, since we would be creating it erroneously. - eg if outfile is X:\foo\bar\filename then do not mkdir X: + eg if outfile is X:\foo\bar\filename then don't mkdir X: This logic takes into account unsupported drives !:, 1:, etc. */ char *p = strchr(tempdir, ':'); if(p && !p[1]) skip = true; #endif - /* the output string does not start with a separator */ + /* the output string doesn't start with a separator */ strcpy(dirbuildup, tempdir); } else diff --git a/contrib/libs/curl/src/tool_doswin.c b/contrib/libs/curl/src/tool_doswin.c index 321e44f9c0..db2b8b78ac 100644 --- a/contrib/libs/curl/src/tool_doswin.c +++ b/contrib/libs/curl/src/tool_doswin.c @@ -56,9 +56,9 @@ #endif #ifdef _WIN32 -# define _use_lfn(f) (1) /* long filenames always available */ +# define _use_lfn(f) (1) /* long file names always available */ #elif !defined(__DJGPP__) || (__DJGPP__ < 2) /* DJGPP 2.0 has _use_lfn() */ -# define _use_lfn(f) (0) /* long filenames never available */ +# define _use_lfn(f) (0) /* long file names never available */ #elif defined(__DJGPP__) # include <fcntl.h> /* _use_lfn(f) prototype */ #endif @@ -98,8 +98,8 @@ SANITIZE_ALLOW_PATH: Allow path separators and colons. Without this flag path separators and colons are sanitized. SANITIZE_ALLOW_RESERVED: Allow reserved device names. -Without this flag a reserved device name is renamed (COM1 => _COM1) unless it -is in a UNC prefixed path. +Without this flag a reserved device name is renamed (COM1 => _COM1) unless it's +in a UNC prefixed path. SANITIZE_ALLOW_TRUNCATE: Allow truncating a long filename. Without this flag if the sanitized filename or path will be too long an error @@ -136,9 +136,9 @@ SANITIZEcode sanitize_file_name(char **const sanitized, const char *file_name, max_sanitized_len = PATH_MAX-1; } else - /* The maximum length of a filename. FILENAME_MAX is often the same as - PATH_MAX, in other words it is 260 and does not discount the path - information therefore we should not use it. */ + /* The maximum length of a filename. + FILENAME_MAX is often the same as PATH_MAX, in other words it is 260 and + does not discount the path information therefore we shouldn't use it. */ max_sanitized_len = (PATH_MAX-1 > 255) ? 255 : PATH_MAX-1; len = strlen(file_name); @@ -237,7 +237,7 @@ SANITIZEcode sanitize_file_name(char **const sanitized, const char *file_name, /* Test if truncating a path to a file will leave at least a single character in -the filename. Filenames suffixed by an alternate data stream cannot be +the filename. Filenames suffixed by an alternate data stream can't be truncated. This performs a dry run, nothing is modified. Good truncate_pos 9: C:\foo\bar => C:\foo\ba @@ -253,7 +253,7 @@ Error truncate_pos 7: C:\foo => (pos out of range) Bad truncate_pos 1: C:\foo\ => C * C:foo is ambiguous, C could end up being a drive or file therefore something - like C:superlongfilename cannot be truncated. + like C:superlongfilename can't be truncated. Returns SANITIZE_ERR_OK: Good -- 'path' can be truncated @@ -278,7 +278,7 @@ SANITIZEcode truncate_dryrun(const char *path, const size_t truncate_pos) if(strpbrk(&path[truncate_pos - 1], "\\/:")) return SANITIZE_ERR_INVALID_PATH; - /* C:\foo can be truncated but C:\foo:ads cannot */ + /* C:\foo can be truncated but C:\foo:ads can't */ if(truncate_pos > 1) { const char *p = &path[truncate_pos - 1]; do { @@ -297,11 +297,11 @@ SANITIZEcode truncate_dryrun(const char *path, const size_t truncate_pos) */ /* -Extra sanitization MS-DOS for file_name. +Extra sanitization MSDOS for file_name. This is a supporting function for sanitize_file_name. -Warning: This is an MS-DOS legacy function and was purposely written in a way +Warning: This is an MSDOS legacy function and was purposely written in a way that some path information may pass through. For example drive letter names (C:, D:, etc) are allowed to pass through. For sanitizing a filename use sanitize_file_name. @@ -357,8 +357,8 @@ SANITIZEcode msdosify(char **const sanitized, const char *file_name, *d = ':'; else if((flags & SANITIZE_ALLOW_PATH) && (*s == '/' || *s == '\\')) *d = *s; - /* Dots are special: DOS does not allow them as the leading character, - and a filename cannot have more than a single dot. We leave the + /* Dots are special: DOS doesn't allow them as the leading character, + and a file name cannot have more than a single dot. We leave the first non-leading dot alone, unless it comes too close to the beginning of the name: we want sh.lex.c to become sh_lex.c, not sh.lex-c. */ @@ -445,11 +445,11 @@ SANITIZEcode msdosify(char **const sanitized, const char *file_name, #endif /* MSDOS || UNITTESTS */ /* -Rename file_name if it is a reserved dos device name. +Rename file_name if it's a reserved dos device name. This is a supporting function for sanitize_file_name. -Warning: This is an MS-DOS legacy function and was purposely written in a way +Warning: This is an MSDOS legacy function and was purposely written in a way that some path information may pass through. For example drive letter names (C:, D:, etc) are allowed to pass through. For sanitizing a filename use sanitize_file_name. @@ -461,8 +461,8 @@ SANITIZEcode rename_if_reserved_dos_device_name(char **const sanitized, const char *file_name, int flags) { - /* We could have a file whose name is a device on MS-DOS. Trying to - * retrieve such a file would fail at best and wedge us at worst. We need + /* We could have a file whose name is a device on MS-DOS. Trying to + * retrieve such a file would fail at best and wedge us at worst. We need * to rename such files. */ char *p, *base; char fname[PATH_MAX]; @@ -558,12 +558,11 @@ SANITIZEcode rename_if_reserved_dos_device_name(char **const sanitized, } /* This is the legacy portion from rename_if_dos_device_name that checks for - reserved device names. It only works on MS-DOS. On Windows XP the stat + reserved device names. It only works on MSDOS. On Windows XP the stat check errors with EINVAL if the device name is reserved. On Windows - Vista/7/8 it sets mode S_IFREG (regular file or device). According to - MSDN stat doc the latter behavior is correct, but that does not help us - identify whether it is a reserved device name and not a regular - filename. */ + Vista/7/8 it sets mode S_IFREG (regular file or device). According to MSDN + stat doc the latter behavior is correct, but that doesn't help us identify + whether it's a reserved device name and not a regular file name. */ #ifdef MSDOS if(base && ((stat(base, &st_buf)) == 0) && (S_ISCHR(st_buf.st_mode))) { /* Prepend a '_' */ @@ -603,12 +602,12 @@ char **__crt0_glob_function(char *arg) /* * Function to find CACert bundle on a Win32 platform using SearchPath. * (SearchPath is already declared via inclusions done in setup header file) - * (Use the ASCII version instead of the Unicode one!) + * (Use the ASCII version instead of the unicode one!) * The order of the directories it searches is: * 1. application's directory * 2. current working directory - * 3. Windows System directory (e.g. C:\Windows\System32) - * 4. Windows Directory (e.g. C:\Windows) + * 3. Windows System directory (e.g. C:\windows\system32) + * 4. Windows Directory (e.g. C:\windows) * 5. all directories along %PATH% * * For WinXP and later search order actually depends on registry value: @@ -621,11 +620,6 @@ CURLcode FindWin32CACert(struct OperationConfig *config, { CURLcode result = CURLE_OK; -#ifdef CURL_WINDOWS_APP - (void)config; - (void)backend; - (void)bundle_file; -#else /* Search and set cert file only if libcurl supports SSL. * * If Schannel is the selected SSL backend then these locations are @@ -651,7 +645,6 @@ CURLcode FindWin32CACert(struct OperationConfig *config, result = CURLE_OUT_OF_MEMORY; } } -#endif return result; } @@ -684,7 +677,7 @@ struct curl_slist *GetLoadedModulePaths(void) #ifdef UNICODE /* sizeof(mod.szExePath) is the max total bytes of wchars. the max total - bytes of multibyte chars will not be more than twice that. */ + bytes of multibyte chars won't be more than twice that. */ char buffer[sizeof(mod.szExePath) * 2]; if(!WideCharToMultiByte(CP_ACP, 0, mod.szExePath, -1, buffer, sizeof(buffer), NULL, NULL)) @@ -710,9 +703,6 @@ cleanup: return slist; } -bool tool_term_has_bold; - -#ifndef CURL_WINDOWS_APP /* The terminal settings to restore on exit */ static struct TerminalSettings { HANDLE hStdOut; @@ -724,6 +714,8 @@ static struct TerminalSettings { #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 #endif +bool tool_term_has_bold; + static void restore_terminal(void) { if(InterlockedExchange(&TerminalSettings.valid, (LONG)FALSE)) @@ -778,7 +770,6 @@ static void init_terminal(void) } } } -#endif LARGE_INTEGER tool_freq; bool tool_isVistaOrGreater; @@ -795,9 +786,7 @@ CURLcode win32_init(void) QueryPerformanceFrequency(&tool_freq); -#ifndef CURL_WINDOWS_APP init_terminal(); -#endif return CURLE_OK; } diff --git a/contrib/libs/curl/src/tool_easysrc.c b/contrib/libs/curl/src/tool_easysrc.c index a623f19613..6ef2be721c 100644 --- a/contrib/libs/curl/src/tool_easysrc.c +++ b/contrib/libs/curl/src/tool_easysrc.c @@ -27,6 +27,8 @@ #ifndef CURL_DISABLE_LIBCURL_OPTION +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" @@ -111,7 +113,7 @@ CURLcode easysrc_addf(struct slist_wc **plist, const char *fmt, ...) char *bufp; va_list ap; va_start(ap, fmt); - bufp = vaprintf(fmt, ap); + bufp = curlx_mvaprintf(fmt, ap); va_end(ap); if(!bufp) { ret = CURLE_OUT_OF_MEMORY; diff --git a/contrib/libs/curl/src/tool_easysrc.h b/contrib/libs/curl/src/tool_easysrc.h index f698c8f5cc..8c8d131501 100644 --- a/contrib/libs/curl/src/tool_easysrc.h +++ b/contrib/libs/curl/src/tool_easysrc.h @@ -40,7 +40,7 @@ extern int easysrc_slist_count; /* Number of curl_slist variables */ extern CURLcode easysrc_init(void); extern CURLcode easysrc_add(struct slist_wc **plist, const char *bupf); extern CURLcode easysrc_addf(struct slist_wc **plist, - const char *fmt, ...) CURL_PRINTF(2, 3); + const char *fmt, ...); extern CURLcode easysrc_perform(void); extern CURLcode easysrc_cleanup(void); diff --git a/contrib/libs/curl/src/tool_filetime.c b/contrib/libs/curl/src/tool_filetime.c index a80019f152..13113886e6 100644 --- a/contrib/libs/curl/src/tool_filetime.c +++ b/contrib/libs/curl/src/tool_filetime.c @@ -38,10 +38,10 @@ int getfiletime(const char *filename, struct GlobalConfig *global, { int rc = 1; -/* Windows stat() may attempt to adjust the Unix GMT file time by a daylight - saving time offset and since it is GMT that is bad behavior. When we have +/* Windows stat() may attempt to adjust the unix GMT file time by a daylight + saving time offset and since it's GMT that is bad behavior. When we have access to a 64-bit type we can bypass stat and get the times directly. */ -#if defined(_WIN32) && !defined(CURL_WINDOWS_APP) +#if defined(_WIN32) HANDLE hfile; TCHAR *tchar_filename = curlx_convert_UTF8_to_tchar((char *)filename); @@ -92,14 +92,14 @@ void setfiletime(curl_off_t filetime, const char *filename, struct GlobalConfig *global) { if(filetime >= 0) { -/* Windows utime() may attempt to adjust the Unix GMT file time by a daylight - saving time offset and since it is GMT that is bad behavior. When we have +/* Windows utime() may attempt to adjust the unix GMT file time by a daylight + saving time offset and since it's GMT that is bad behavior. When we have access to a 64-bit type we can bypass utime and set the times directly. */ -#if defined(_WIN32) && !defined(CURL_WINDOWS_APP) +#if defined(_WIN32) HANDLE hfile; TCHAR *tchar_filename = curlx_convert_UTF8_to_tchar((char *)filename); - /* 910670515199 is the maximum Unix filetime that can be used as a + /* 910670515199 is the maximum unix filetime that can be used as a Windows FILETIME without overflow: 30827-12-31T23:59:59. */ if(filetime > CURL_OFF_T_C(910670515199)) { warnf(global, "Failed to set filetime %" CURL_FORMAT_CURL_OFF_T diff --git a/contrib/libs/curl/src/tool_findfile.c b/contrib/libs/curl/src/tool_findfile.c index 672fc7b992..a1544a5633 100644 --- a/contrib/libs/curl/src/tool_findfile.c +++ b/contrib/libs/curl/src/tool_findfile.c @@ -35,7 +35,7 @@ #include <fcntl.h> #endif -#include <curlx.h> +#include <curl/mprintf.h> #include "tool_findfile.h" @@ -51,7 +51,7 @@ struct finder { in the findfile() function */ static const struct finder conf_list[] = { { "CURL_HOME", NULL, FALSE }, - { "XDG_CONFIG_HOME", NULL, TRUE }, + { "XDG_CONFIG_HOME", NULL, FALSE }, /* index == 1, used in the code */ { "HOME", NULL, FALSE }, #ifdef _WIN32 { "USERPROFILE", NULL, FALSE }, @@ -72,9 +72,9 @@ static char *checkhome(const char *home, const char *fname, bool dotscore) for(i = 0; i < (dotscore ? 2 : 1); i++) { char *c; if(dotscore) - c = aprintf("%s" DIR_CHAR "%c%s", home, pref[i], &fname[1]); + c = curl_maprintf("%s" DIR_CHAR "%c%s", home, pref[i], &fname[1]); else - c = aprintf("%s" DIR_CHAR "%s", home, fname); + c = curl_maprintf("%s" DIR_CHAR "%s", home, fname); if(c) { int fd = open(c, O_RDONLY); if(fd >= 0) { @@ -97,11 +97,12 @@ static char *checkhome(const char *home, const char *fname, bool dotscore) * * 1. Iterate over the environment variables in order, and if set, check for * the given file to be accessed there, then it is a match. - * 2. Non-Windows: try getpwuid + * 2. Non-windows: try getpwuid */ char *findfile(const char *fname, int dotscore) { int i; + bool xdg = FALSE; DEBUGASSERT(fname && fname[0]); DEBUGASSERT((dotscore != 1) || (fname[0] == '.')); @@ -113,19 +114,21 @@ char *findfile(const char *fname, int dotscore) if(home) { char *path; const char *filename = fname; + if(i == 1 /* XDG_CONFIG_HOME */) + xdg = TRUE; if(!home[0]) { curl_free(home); continue; } if(conf_list[i].append) { - char *c = aprintf("%s%s", home, conf_list[i].append); + char *c = curl_maprintf("%s%s", home, conf_list[i].append); curl_free(home); if(!c) return NULL; home = c; } if(conf_list[i].withoutdot) { - if(!dotscore) { + if(!dotscore || xdg) { /* this is not looking for .curlrc, or the XDG_CONFIG_HOME was defined so we skip the extended check */ curl_free(home); diff --git a/contrib/libs/curl/src/tool_formparse.c b/contrib/libs/curl/src/tool_formparse.c index 15918d3ee5..fa38698d5e 100644 --- a/contrib/libs/curl/src/tool_formparse.c +++ b/contrib/libs/curl/src/tool_formparse.c @@ -25,6 +25,8 @@ #include "strcase.h" +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" @@ -276,7 +278,7 @@ static CURLcode tool2curlparts(CURL *curl, struct tool_mime *m, case TOOLMIME_STDIN: if(!filename) filename = "-"; - FALLTHROUGH(); + /* FALLTHROUGH */ case TOOLMIME_STDINDATA: ret = curl_mime_data_cb(part, m->size, (curl_read_callback) tool_mime_stdin_read, @@ -635,7 +637,7 @@ static int get_param_part(struct OperationConfig *config, char endchar, *pfilename = filename; else if(filename) warnf(config->global, - "Field filename not allowed here: %s", filename); + "Field file name not allowed here: %s", filename); if(pencoder) *pencoder = encoder; @@ -691,7 +693,7 @@ static int get_param_part(struct OperationConfig *config, char endchar, * 'name=foo;headers=@headerfile' or why not * 'name=@filemame;headers=@headerfile' * - * To upload a file, but to fake the filename that will be included in the + * To upload a file, but to fake the file name that will be included in the * formpost, do like this: * * 'name=@filename;filename=/dev/null' or quote the faked filename like: @@ -718,7 +720,7 @@ int formparse(struct OperationConfig *config, struct tool_mime **mimecurrent, bool literal_value) { - /* input MUST be a string in the format 'name=contents' and we will + /* input MUST be a string in the format 'name=contents' and we'll build a linked list with the info */ char *name = NULL; char *contents = NULL; @@ -777,7 +779,7 @@ int formparse(struct OperationConfig *config, } else if('@' == contp[0] && !literal_value) { - /* we use the @-letter to indicate filename(s) */ + /* we use the @-letter to indicate file name(s) */ struct tool_mime *subparts = NULL; @@ -829,7 +831,7 @@ int formparse(struct OperationConfig *config, SET_TOOL_MIME_PTR(part, encoder); /* *contp could be '\0', so we just check with the delimiter */ - } while(sep); /* loop if there is another filename */ + } while(sep); /* loop if there's another file name */ part = (*mimecurrent)->subparts; /* Set name on group. */ } else { diff --git a/contrib/libs/curl/src/tool_getparam.c b/contrib/libs/curl/src/tool_getparam.c index be41aa35d5..5fa1ace10d 100644 --- a/contrib/libs/curl/src/tool_getparam.c +++ b/contrib/libs/curl/src/tool_getparam.c @@ -25,6 +25,8 @@ #include "strcase.h" +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" #include "tool_binmode.h" @@ -49,308 +51,320 @@ # define USE_WATT32 #endif -#define ALLOW_BLANK TRUE -#define DENY_BLANK FALSE - -static ParameterError getstr(char **str, const char *val, bool allowblank) -{ - if(*str) { - free(*str); - *str = NULL; - } - if(val) { - if(!allowblank && !val[0]) - return PARAM_BLANK_STRING; - - *str = strdup(val); - if(!*str) - return PARAM_NO_MEM; - } - return PARAM_OK; -} +#define GetStr(str,val) do { \ + if(*(str)) { \ + free(*(str)); \ + *(str) = NULL; \ + } \ + if((val)) { \ + *(str) = strdup((val)); \ + if(!(*(str))) { \ + err = PARAM_NO_MEM; \ + goto error; \ + } \ + } \ + } while(0) + +struct LongShort { + const char *letter; /* short name option */ + const char *lname; /* long name option */ + enum { + ARG_NONE, /* stand-alone but not a boolean */ + ARG_BOOL, /* accepts a --no-[name] prefix */ + ARG_STRING, /* requires an argument */ + ARG_FILENAME /* requires an argument, usually a file name */ + } desc; +}; -/* this array MUST be alphasorted based on the 'lname' */ static const struct LongShort aliases[]= { - {"abstract-unix-socket", ARG_FILE, ' ', C_ABSTRACT_UNIX_SOCKET}, - {"alpn", ARG_BOOL|ARG_NO, ' ', C_ALPN}, - {"alt-svc", ARG_STRG, ' ', C_ALT_SVC}, - {"anyauth", ARG_BOOL, ' ', C_ANYAUTH}, - {"append", ARG_BOOL, 'a', C_APPEND}, - {"aws-sigv4", ARG_STRG, ' ', C_AWS_SIGV4}, - {"basic", ARG_BOOL, ' ', C_BASIC}, - {"buffer", ARG_BOOL|ARG_NO, 'N', C_BUFFER}, - {"ca-native", ARG_BOOL, ' ', C_CA_NATIVE}, - {"cacert", ARG_FILE, ' ', C_CACERT}, - {"capath", ARG_FILE, ' ', C_CAPATH}, - {"cert", ARG_FILE, 'E', C_CERT}, - {"cert-status", ARG_BOOL, ' ', C_CERT_STATUS}, - {"cert-type", ARG_STRG, ' ', C_CERT_TYPE}, - {"ciphers", ARG_STRG, ' ', C_CIPHERS}, - {"clobber", ARG_BOOL|ARG_NO, ' ', C_CLOBBER}, - {"compressed", ARG_BOOL, ' ', C_COMPRESSED}, - {"compressed-ssh", ARG_BOOL, ' ', C_COMPRESSED_SSH}, - {"config", ARG_FILE, 'K', C_CONFIG}, - {"connect-timeout", ARG_STRG, ' ', C_CONNECT_TIMEOUT}, - {"connect-to", ARG_STRG, ' ', C_CONNECT_TO}, - {"continue-at", ARG_STRG, 'C', C_CONTINUE_AT}, - {"cookie", ARG_STRG, 'b', C_COOKIE}, - {"cookie-jar", ARG_STRG, 'c', C_COOKIE_JAR}, - {"create-dirs", ARG_BOOL, ' ', C_CREATE_DIRS}, - {"create-file-mode", ARG_STRG, ' ', C_CREATE_FILE_MODE}, - {"crlf", ARG_BOOL, ' ', C_CRLF}, - {"crlfile", ARG_FILE, ' ', C_CRLFILE}, - {"curves", ARG_STRG, ' ', C_CURVES}, - {"data", ARG_STRG, 'd', C_DATA}, - {"data-ascii", ARG_STRG, ' ', C_DATA_ASCII}, - {"data-binary", ARG_STRG, ' ', C_DATA_BINARY}, - {"data-raw", ARG_STRG, ' ', C_DATA_RAW}, - {"data-urlencode", ARG_STRG, ' ', C_DATA_URLENCODE}, - {"delegation", ARG_STRG, ' ', C_DELEGATION}, - {"digest", ARG_BOOL, ' ', C_DIGEST}, - {"disable", ARG_BOOL, 'q', C_DISABLE}, - {"disable-eprt", ARG_BOOL, ' ', C_DISABLE_EPRT}, - {"disable-epsv", ARG_BOOL, ' ', C_DISABLE_EPSV}, - {"disallow-username-in-url", ARG_BOOL, ' ', C_DISALLOW_USERNAME_IN_URL}, - {"dns-interface", ARG_STRG, ' ', C_DNS_INTERFACE}, - {"dns-ipv4-addr", ARG_STRG, ' ', C_DNS_IPV4_ADDR}, - {"dns-ipv6-addr", ARG_STRG, ' ', C_DNS_IPV6_ADDR}, - {"dns-servers", ARG_STRG, ' ', C_DNS_SERVERS}, - {"doh-cert-status", ARG_BOOL, ' ', C_DOH_CERT_STATUS}, - {"doh-insecure", ARG_BOOL, ' ', C_DOH_INSECURE}, - {"doh-url" , ARG_STRG, ' ', C_DOH_URL}, - {"dump-ca-embed", ARG_NONE, ' ', C_DUMP_CA_EMBED}, - {"dump-header", ARG_FILE, 'D', C_DUMP_HEADER}, - {"ech", ARG_STRG, ' ', C_ECH}, - {"egd-file", ARG_STRG, ' ', C_EGD_FILE}, - {"engine", ARG_STRG, ' ', C_ENGINE}, - {"eprt", ARG_BOOL, ' ', C_EPRT}, - {"epsv", ARG_BOOL, ' ', C_EPSV}, - {"etag-compare", ARG_FILE, ' ', C_ETAG_COMPARE}, - {"etag-save", ARG_FILE, ' ', C_ETAG_SAVE}, - {"expect100-timeout", ARG_STRG, ' ', C_EXPECT100_TIMEOUT}, - {"fail", ARG_BOOL, 'f', C_FAIL}, - {"fail-early", ARG_BOOL, ' ', C_FAIL_EARLY}, - {"fail-with-body", ARG_BOOL, ' ', C_FAIL_WITH_BODY}, - {"false-start", ARG_BOOL, ' ', C_FALSE_START}, - {"form", ARG_STRG, 'F', C_FORM}, - {"form-escape", ARG_BOOL, ' ', C_FORM_ESCAPE}, - {"form-string", ARG_STRG, ' ', C_FORM_STRING}, - {"ftp-account", ARG_STRG, ' ', C_FTP_ACCOUNT}, - {"ftp-alternative-to-user", ARG_STRG, ' ', C_FTP_ALTERNATIVE_TO_USER}, - {"ftp-create-dirs", ARG_BOOL, ' ', C_FTP_CREATE_DIRS}, - {"ftp-method", ARG_STRG, ' ', C_FTP_METHOD}, - {"ftp-pasv", ARG_BOOL, ' ', C_FTP_PASV}, - {"ftp-port", ARG_STRG, 'P', C_FTP_PORT}, - {"ftp-pret", ARG_BOOL, ' ', C_FTP_PRET}, - {"ftp-skip-pasv-ip", ARG_BOOL, ' ', C_FTP_SKIP_PASV_IP}, - {"ftp-ssl", ARG_BOOL, ' ', C_FTP_SSL}, - {"ftp-ssl-ccc", ARG_BOOL, ' ', C_FTP_SSL_CCC}, - {"ftp-ssl-ccc-mode", ARG_STRG, ' ', C_FTP_SSL_CCC_MODE}, - {"ftp-ssl-control", ARG_BOOL, ' ', C_FTP_SSL_CONTROL}, - {"ftp-ssl-reqd", ARG_BOOL, ' ', C_FTP_SSL_REQD}, - {"get", ARG_BOOL, 'G', C_GET}, - {"globoff", ARG_BOOL, 'g', C_GLOBOFF}, - {"happy-eyeballs-timeout-ms", ARG_STRG, ' ', C_HAPPY_EYEBALLS_TIMEOUT_MS}, - {"haproxy-clientip", ARG_STRG, ' ', C_HAPROXY_CLIENTIP}, - {"haproxy-protocol", ARG_BOOL, ' ', C_HAPROXY_PROTOCOL}, - {"head", ARG_BOOL, 'I', C_HEAD}, - {"header", ARG_STRG, 'H', C_HEADER}, - {"help", ARG_BOOL, 'h', C_HELP}, - {"hostpubmd5", ARG_STRG, ' ', C_HOSTPUBMD5}, - {"hostpubsha256", ARG_STRG, ' ', C_HOSTPUBSHA256}, - {"hsts", ARG_STRG, ' ', C_HSTS}, - {"http0.9", ARG_BOOL, ' ', C_HTTP0_9}, - {"http1.0", ARG_NONE, '0', C_HTTP1_0}, - {"http1.1", ARG_NONE, ' ', C_HTTP1_1}, - {"http2", ARG_NONE, ' ', C_HTTP2}, - {"http2-prior-knowledge", ARG_NONE, ' ', C_HTTP2_PRIOR_KNOWLEDGE}, - {"http3", ARG_NONE, ' ', C_HTTP3}, - {"http3-only", ARG_NONE, ' ', C_HTTP3_ONLY}, - {"ignore-content-length", ARG_BOOL, ' ', C_IGNORE_CONTENT_LENGTH}, - {"include", ARG_BOOL, ' ', C_INCLUDE}, - {"insecure", ARG_BOOL, 'k', C_INSECURE}, - {"interface", ARG_STRG, ' ', C_INTERFACE}, - {"ip-tos", ARG_STRG, ' ', C_IP_TOS}, - {"ipfs-gateway", ARG_STRG, ' ', C_IPFS_GATEWAY}, - {"ipv4", ARG_NONE, '4', C_IPV4}, - {"ipv6", ARG_NONE, '6', C_IPV6}, - {"json", ARG_STRG, ' ', C_JSON}, - {"junk-session-cookies", ARG_BOOL, 'j', C_JUNK_SESSION_COOKIES}, - {"keepalive", ARG_BOOL|ARG_NO, ' ', C_KEEPALIVE}, - {"keepalive-cnt", ARG_STRG, ' ', C_KEEPALIVE_CNT}, - {"keepalive-time", ARG_STRG, ' ', C_KEEPALIVE_TIME}, - {"key", ARG_FILE, ' ', C_KEY}, - {"key-type", ARG_STRG, ' ', C_KEY_TYPE}, - {"krb", ARG_STRG, ' ', C_KRB}, - {"krb4", ARG_STRG, ' ', C_KRB4}, - {"libcurl", ARG_STRG, ' ', C_LIBCURL}, - {"limit-rate", ARG_STRG, ' ', C_LIMIT_RATE}, - {"list-only", ARG_BOOL, 'l', C_LIST_ONLY}, - {"local-port", ARG_STRG, ' ', C_LOCAL_PORT}, - {"location", ARG_BOOL, 'L', C_LOCATION}, - {"location-trusted", ARG_BOOL, ' ', C_LOCATION_TRUSTED}, - {"login-options", ARG_STRG, ' ', C_LOGIN_OPTIONS}, - {"mail-auth", ARG_STRG, ' ', C_MAIL_AUTH}, - {"mail-from", ARG_STRG, ' ', C_MAIL_FROM}, - {"mail-rcpt", ARG_STRG, ' ', C_MAIL_RCPT}, - {"mail-rcpt-allowfails", ARG_BOOL, ' ', C_MAIL_RCPT_ALLOWFAILS}, - {"manual", ARG_BOOL, 'M', C_MANUAL}, - {"max-filesize", ARG_STRG, ' ', C_MAX_FILESIZE}, - {"max-redirs", ARG_STRG, ' ', C_MAX_REDIRS}, - {"max-time", ARG_STRG, 'm', C_MAX_TIME}, - {"metalink", ARG_BOOL, ' ', C_METALINK}, - {"mptcp", ARG_BOOL, ' ', C_MPTCP}, - {"negotiate", ARG_BOOL, ' ', C_NEGOTIATE}, - {"netrc", ARG_BOOL, 'n', C_NETRC}, - {"netrc-file", ARG_FILE, ' ', C_NETRC_FILE}, - {"netrc-optional", ARG_BOOL, ' ', C_NETRC_OPTIONAL}, - {"next", ARG_NONE, ':', C_NEXT}, - {"noproxy", ARG_STRG, ' ', C_NOPROXY}, - {"npn", ARG_BOOL|ARG_NO, ' ', C_NPN}, - {"ntlm", ARG_BOOL, ' ', C_NTLM}, - {"ntlm-wb", ARG_BOOL, ' ', C_NTLM_WB}, - {"oauth2-bearer", ARG_STRG, ' ', C_OAUTH2_BEARER}, - {"output", ARG_FILE, 'o', C_OUTPUT}, - {"output-dir", ARG_STRG, ' ', C_OUTPUT_DIR}, - {"parallel", ARG_BOOL, 'Z', C_PARALLEL}, - {"parallel-immediate", ARG_BOOL, ' ', C_PARALLEL_IMMEDIATE}, - {"parallel-max", ARG_STRG, ' ', C_PARALLEL_MAX}, - {"pass", ARG_STRG, ' ', C_PASS}, - {"path-as-is", ARG_BOOL, ' ', C_PATH_AS_IS}, - {"pinnedpubkey", ARG_STRG, ' ', C_PINNEDPUBKEY}, - {"post301", ARG_BOOL, ' ', C_POST301}, - {"post302", ARG_BOOL, ' ', C_POST302}, - {"post303", ARG_BOOL, ' ', C_POST303}, - {"preproxy", ARG_STRG, ' ', C_PREPROXY}, - {"progress-bar", ARG_BOOL, '#', C_PROGRESS_BAR}, - {"progress-meter", ARG_BOOL|ARG_NO, ' ', C_PROGRESS_METER}, - {"proto", ARG_STRG, ' ', C_PROTO}, - {"proto-default", ARG_STRG, ' ', C_PROTO_DEFAULT}, - {"proto-redir", ARG_STRG, ' ', C_PROTO_REDIR}, - {"proxy", ARG_STRG, 'x', C_PROXY}, - {"proxy-anyauth", ARG_BOOL, ' ', C_PROXY_ANYAUTH}, - {"proxy-basic", ARG_BOOL, ' ', C_PROXY_BASIC}, - {"proxy-ca-native", ARG_BOOL, ' ', C_PROXY_CA_NATIVE}, - {"proxy-cacert", ARG_FILE, ' ', C_PROXY_CACERT}, - {"proxy-capath", ARG_FILE, ' ', C_PROXY_CAPATH}, - {"proxy-cert", ARG_FILE, ' ', C_PROXY_CERT}, - {"proxy-cert-type", ARG_STRG, ' ', C_PROXY_CERT_TYPE}, - {"proxy-ciphers", ARG_STRG, ' ', C_PROXY_CIPHERS}, - {"proxy-crlfile", ARG_FILE, ' ', C_PROXY_CRLFILE}, - {"proxy-digest", ARG_BOOL, ' ', C_PROXY_DIGEST}, - {"proxy-header", ARG_STRG, ' ', C_PROXY_HEADER}, - {"proxy-http2", ARG_BOOL, ' ', C_PROXY_HTTP2}, - {"proxy-insecure", ARG_BOOL, ' ', C_PROXY_INSECURE}, - {"proxy-key", ARG_FILE, ' ', C_PROXY_KEY}, - {"proxy-key-type", ARG_STRG, ' ', C_PROXY_KEY_TYPE}, - {"proxy-negotiate", ARG_BOOL, ' ', C_PROXY_NEGOTIATE}, - {"proxy-ntlm", ARG_BOOL, ' ', C_PROXY_NTLM}, - {"proxy-pass", ARG_STRG, ' ', C_PROXY_PASS}, - {"proxy-pinnedpubkey", ARG_STRG, ' ', C_PROXY_PINNEDPUBKEY}, - {"proxy-service-name", ARG_STRG, ' ', C_PROXY_SERVICE_NAME}, - {"proxy-ssl-allow-beast", ARG_BOOL, ' ', C_PROXY_SSL_ALLOW_BEAST}, - {"proxy-ssl-auto-client-cert", ARG_BOOL, ' ', C_PROXY_SSL_AUTO_CLIENT_CERT}, - {"proxy-tls13-ciphers", ARG_STRG, ' ', C_PROXY_TLS13_CIPHERS}, - {"proxy-tlsauthtype", ARG_STRG, ' ', C_PROXY_TLSAUTHTYPE}, - {"proxy-tlspassword", ARG_STRG, ' ', C_PROXY_TLSPASSWORD}, - {"proxy-tlsuser", ARG_STRG, ' ', C_PROXY_TLSUSER}, - {"proxy-tlsv1", ARG_NONE, ' ', C_PROXY_TLSV1}, - {"proxy-user", ARG_STRG, 'U', C_PROXY_USER}, - {"proxy1.0", ARG_STRG, ' ', C_PROXY1_0}, - {"proxytunnel", ARG_BOOL, 'p', C_PROXYTUNNEL}, - {"pubkey", ARG_STRG, ' ', C_PUBKEY}, - {"quote", ARG_STRG, 'Q', C_QUOTE}, - {"random-file", ARG_FILE, ' ', C_RANDOM_FILE}, - {"range", ARG_STRG, 'r', C_RANGE}, - {"rate", ARG_STRG, ' ', C_RATE}, - {"raw", ARG_BOOL, ' ', C_RAW}, - {"referer", ARG_STRG, 'e', C_REFERER}, - {"remote-header-name", ARG_BOOL, 'J', C_REMOTE_HEADER_NAME}, - {"remote-name", ARG_BOOL, 'O', C_REMOTE_NAME}, - {"remote-name-all", ARG_BOOL, ' ', C_REMOTE_NAME_ALL}, - {"remote-time", ARG_BOOL, 'R', C_REMOTE_TIME}, - {"remove-on-error", ARG_BOOL, ' ', C_REMOVE_ON_ERROR}, - {"request", ARG_STRG, 'X', C_REQUEST}, - {"request-target", ARG_STRG, ' ', C_REQUEST_TARGET}, - {"resolve", ARG_STRG, ' ', C_RESOLVE}, - {"retry", ARG_STRG, ' ', C_RETRY}, - {"retry-all-errors", ARG_BOOL, ' ', C_RETRY_ALL_ERRORS}, - {"retry-connrefused", ARG_BOOL, ' ', C_RETRY_CONNREFUSED}, - {"retry-delay", ARG_STRG, ' ', C_RETRY_DELAY}, - {"retry-max-time", ARG_STRG, ' ', C_RETRY_MAX_TIME}, - {"sasl-authzid", ARG_STRG, ' ', C_SASL_AUTHZID}, - {"sasl-ir", ARG_BOOL, ' ', C_SASL_IR}, - {"service-name", ARG_STRG, ' ', C_SERVICE_NAME}, - {"sessionid", ARG_BOOL|ARG_NO, ' ', C_SESSIONID}, - {"show-error", ARG_BOOL, 'S', C_SHOW_ERROR}, - {"show-headers", ARG_BOOL, 'i', C_SHOW_HEADERS}, - {"silent", ARG_BOOL, 's', C_SILENT}, - {"skip-existing", ARG_BOOL, ' ', C_SKIP_EXISTING}, - {"socks4", ARG_STRG, ' ', C_SOCKS4}, - {"socks4a", ARG_STRG, ' ', C_SOCKS4A}, - {"socks5", ARG_STRG, ' ', C_SOCKS5}, - {"socks5-basic", ARG_BOOL, ' ', C_SOCKS5_BASIC}, - {"socks5-gssapi", ARG_BOOL, ' ', C_SOCKS5_GSSAPI}, - {"socks5-gssapi-nec", ARG_BOOL, ' ', C_SOCKS5_GSSAPI_NEC}, - {"socks5-gssapi-service", ARG_STRG, ' ', C_SOCKS5_GSSAPI_SERVICE}, - {"socks5-hostname", ARG_STRG, ' ', C_SOCKS5_HOSTNAME}, - {"speed-limit", ARG_STRG, 'Y', C_SPEED_LIMIT}, - {"speed-time", ARG_STRG, 'y', C_SPEED_TIME}, - {"ssl", ARG_BOOL, ' ', C_SSL}, - {"ssl-allow-beast", ARG_BOOL, ' ', C_SSL_ALLOW_BEAST}, - {"ssl-auto-client-cert", ARG_BOOL, ' ', C_SSL_AUTO_CLIENT_CERT}, - {"ssl-no-revoke", ARG_BOOL, ' ', C_SSL_NO_REVOKE}, - {"ssl-reqd", ARG_BOOL, ' ', C_SSL_REQD}, - {"ssl-revoke-best-effort", ARG_BOOL, ' ', C_SSL_REVOKE_BEST_EFFORT}, - {"sslv2", ARG_NONE, '2', C_SSLV2}, - {"sslv3", ARG_NONE, '3', C_SSLV3}, - {"stderr", ARG_FILE, ' ', C_STDERR}, - {"styled-output", ARG_BOOL, ' ', C_STYLED_OUTPUT}, - {"suppress-connect-headers", ARG_BOOL, ' ', C_SUPPRESS_CONNECT_HEADERS}, - {"tcp-fastopen", ARG_BOOL, ' ', C_TCP_FASTOPEN}, - {"tcp-nodelay", ARG_BOOL, ' ', C_TCP_NODELAY}, - {"telnet-option", ARG_STRG, 't', C_TELNET_OPTION}, - {"test-event", ARG_BOOL, ' ', C_TEST_EVENT}, - {"tftp-blksize", ARG_STRG, ' ', C_TFTP_BLKSIZE}, - {"tftp-no-options", ARG_BOOL, ' ', C_TFTP_NO_OPTIONS}, - {"time-cond", ARG_STRG, 'z', C_TIME_COND}, - {"tls-max", ARG_STRG, ' ', C_TLS_MAX}, - {"tls13-ciphers", ARG_STRG, ' ', C_TLS13_CIPHERS}, - {"tlsauthtype", ARG_STRG, ' ', C_TLSAUTHTYPE}, - {"tlspassword", ARG_STRG, ' ', C_TLSPASSWORD}, - {"tlsuser", ARG_STRG, ' ', C_TLSUSER}, - {"tlsv1", ARG_NONE, '1', C_TLSV1}, - {"tlsv1.0", ARG_NONE, ' ', C_TLSV1_0}, - {"tlsv1.1", ARG_NONE, ' ', C_TLSV1_1}, - {"tlsv1.2", ARG_NONE, ' ', C_TLSV1_2}, - {"tlsv1.3", ARG_NONE, ' ', C_TLSV1_3}, - {"tr-encoding", ARG_BOOL, ' ', C_TR_ENCODING}, - {"trace", ARG_FILE, ' ', C_TRACE}, - {"trace-ascii", ARG_FILE, ' ', C_TRACE_ASCII}, - {"trace-config", ARG_STRG, ' ', C_TRACE_CONFIG}, - {"trace-ids", ARG_BOOL, ' ', C_TRACE_IDS}, - {"trace-time", ARG_BOOL, ' ', C_TRACE_TIME}, - {"unix-socket", ARG_FILE, ' ', C_UNIX_SOCKET}, - {"upload-file", ARG_FILE, 'T', C_UPLOAD_FILE}, - {"url", ARG_STRG, ' ', C_URL}, - {"url-query", ARG_STRG, ' ', C_URL_QUERY}, - {"use-ascii", ARG_BOOL, 'B', C_USE_ASCII}, - {"user", ARG_STRG, 'u', C_USER}, - {"user-agent", ARG_STRG, 'A', C_USER_AGENT}, - {"variable", ARG_STRG, ' ', C_VARIABLE}, - {"verbose", ARG_BOOL, 'v', C_VERBOSE}, - {"version", ARG_BOOL, 'V', C_VERSION}, - {"vlan-priority", ARG_STRG, ' ', C_VLAN_PRIORITY}, + /* 'letter' strings with more than one character have *no* short option to + mention. */ + {"*@", "url", ARG_STRING}, + {"*4", "dns-ipv4-addr", ARG_STRING}, + {"*6", "dns-ipv6-addr", ARG_STRING}, + {"*a", "random-file", ARG_FILENAME}, + {"*b", "egd-file", ARG_STRING}, + {"*B", "oauth2-bearer", ARG_STRING}, + {"*c", "connect-timeout", ARG_STRING}, + {"*C", "doh-url" , ARG_STRING}, + {"*d", "ciphers", ARG_STRING}, + {"*D", "dns-interface", ARG_STRING}, + {"*e", "disable-epsv", ARG_BOOL}, + {"*f", "disallow-username-in-url", ARG_BOOL}, + {"*E", "epsv", ARG_BOOL}, + /* 'epsv' made like this to make --no-epsv and --epsv to work + although --disable-epsv is the documented option */ + {"*F", "dns-servers", ARG_STRING}, + {"*g", "trace", ARG_FILENAME}, + {"*G", "npn", ARG_BOOL}, + {"*h", "trace-ascii", ARG_FILENAME}, + {"*H", "alpn", ARG_BOOL}, + {"*i", "limit-rate", ARG_STRING}, + {"*I", "rate", ARG_STRING}, + {"*j", "compressed", ARG_BOOL}, + {"*J", "tr-encoding", ARG_BOOL}, + {"*k", "digest", ARG_BOOL}, + {"*l", "negotiate", ARG_BOOL}, + {"*m", "ntlm", ARG_BOOL}, + {"*M", "ntlm-wb", ARG_BOOL}, + {"*n", "basic", ARG_BOOL}, + {"*o", "anyauth", ARG_BOOL}, #ifdef USE_WATT32 - {"wdebug", ARG_BOOL, ' ', C_WDEBUG}, + {"*p", "wdebug", ARG_BOOL}, #endif - {"write-out", ARG_STRG, 'w', C_WRITE_OUT}, - {"xattr", ARG_BOOL, ' ', C_XATTR}, + {"*q", "ftp-create-dirs", ARG_BOOL}, + {"*r", "create-dirs", ARG_BOOL}, + {"*R", "create-file-mode", ARG_STRING}, + {"*s", "max-redirs", ARG_STRING}, + {"*S", "ipfs-gateway", ARG_STRING}, + {"*t", "proxy-ntlm", ARG_BOOL}, + {"*u", "crlf", ARG_BOOL}, + {"*v", "stderr", ARG_FILENAME}, + {"*V", "aws-sigv4", ARG_STRING}, + {"*w", "interface", ARG_STRING}, + {"*x", "krb", ARG_STRING}, + {"*x", "krb4", ARG_STRING}, + /* 'krb4' is the previous name */ + {"*X", "haproxy-protocol", ARG_BOOL}, + {"*P", "haproxy-clientip", ARG_STRING}, + {"*y", "max-filesize", ARG_STRING}, + {"*z", "disable-eprt", ARG_BOOL}, + {"*Z", "eprt", ARG_BOOL}, + /* 'eprt' made like this to make --no-eprt and --eprt to work + although --disable-eprt is the documented option */ + {"*~", "xattr", ARG_BOOL}, + {"$a", "ftp-ssl", ARG_BOOL}, + /* 'ftp-ssl' deprecated name since 7.20.0 */ + {"$a", "ssl", ARG_BOOL}, + /* 'ssl' new option name in 7.20.0, previously this was ftp-ssl */ + {"$b", "ftp-pasv", ARG_BOOL}, + {"$c", "socks5", ARG_STRING}, + {"$d", "tcp-nodelay", ARG_BOOL}, + {"$e", "proxy-digest", ARG_BOOL}, + {"$f", "proxy-basic", ARG_BOOL}, + {"$g", "retry", ARG_STRING}, + {"$V", "retry-connrefused", ARG_BOOL}, + {"$h", "retry-delay", ARG_STRING}, + {"$i", "retry-max-time", ARG_STRING}, + {"$k", "proxy-negotiate", ARG_BOOL}, + {"$l", "form-escape", ARG_BOOL}, + {"$m", "ftp-account", ARG_STRING}, + {"$n", "proxy-anyauth", ARG_BOOL}, + {"$o", "trace-time", ARG_BOOL}, + {"$p", "ignore-content-length", ARG_BOOL}, + {"$q", "ftp-skip-pasv-ip", ARG_BOOL}, + {"$r", "ftp-method", ARG_STRING}, + {"$s", "local-port", ARG_STRING}, + {"$t", "socks4", ARG_STRING}, + {"$T", "socks4a", ARG_STRING}, + {"$u", "ftp-alternative-to-user", ARG_STRING}, + {"$v", "ftp-ssl-reqd", ARG_BOOL}, + /* 'ftp-ssl-reqd' deprecated name since 7.20.0 */ + {"$v", "ssl-reqd", ARG_BOOL}, + /* 'ssl-reqd' new in 7.20.0, previously this was ftp-ssl-reqd */ + {"$w", "sessionid", ARG_BOOL}, + /* 'sessionid' listed as --no-sessionid in the help */ + {"$x", "ftp-ssl-control", ARG_BOOL}, + {"$y", "ftp-ssl-ccc", ARG_BOOL}, + {"$j", "ftp-ssl-ccc-mode", ARG_STRING}, + {"$z", "libcurl", ARG_STRING}, + {"$#", "raw", ARG_BOOL}, + {"$0", "post301", ARG_BOOL}, + {"$1", "keepalive", ARG_BOOL}, + /* 'keepalive' listed as --no-keepalive in the help */ + {"$2", "socks5-hostname", ARG_STRING}, + {"$3", "keepalive-time", ARG_STRING}, + {"$4", "post302", ARG_BOOL}, + {"$5", "noproxy", ARG_STRING}, + {"$7", "socks5-gssapi-nec", ARG_BOOL}, + {"$8", "proxy1.0", ARG_STRING}, + {"$9", "tftp-blksize", ARG_STRING}, + {"$A", "mail-from", ARG_STRING}, + {"$B", "mail-rcpt", ARG_STRING}, + {"$C", "ftp-pret", ARG_BOOL}, + {"$D", "proto", ARG_STRING}, + {"$E", "proto-redir", ARG_STRING}, + {"$F", "resolve", ARG_STRING}, + {"$G", "delegation", ARG_STRING}, + {"$H", "mail-auth", ARG_STRING}, + {"$I", "post303", ARG_BOOL}, + {"$J", "metalink", ARG_BOOL}, + {"$6", "sasl-authzid", ARG_STRING}, + {"$K", "sasl-ir", ARG_BOOL }, + {"$L", "test-event", ARG_BOOL}, + {"$M", "unix-socket", ARG_FILENAME}, + {"$N", "path-as-is", ARG_BOOL}, + {"$O", "socks5-gssapi-service", ARG_STRING}, + /* 'socks5-gssapi-service' merged with'proxy-service-name' and + deprecated since 7.49.0 */ + {"$O", "proxy-service-name", ARG_STRING}, + {"$P", "service-name", ARG_STRING}, + {"$Q", "proto-default", ARG_STRING}, + {"$R", "expect100-timeout", ARG_STRING}, + {"$S", "tftp-no-options", ARG_BOOL}, + {"$U", "connect-to", ARG_STRING}, + {"$W", "abstract-unix-socket", ARG_FILENAME}, + {"$X", "tls-max", ARG_STRING}, + {"$Y", "suppress-connect-headers", ARG_BOOL}, + {"$Z", "compressed-ssh", ARG_BOOL}, + {"$~", "happy-eyeballs-timeout-ms", ARG_STRING}, + {"$!", "retry-all-errors", ARG_BOOL}, + {"$%", "trace-ids", ARG_BOOL}, + {"$&", "trace-config", ARG_STRING}, + {"0", "http1.0", ARG_NONE}, + {"01", "http1.1", ARG_NONE}, + {"02", "http2", ARG_NONE}, + {"03", "http2-prior-knowledge", ARG_NONE}, + {"04", "http3", ARG_NONE}, + {"05", "http3-only", ARG_NONE}, + {"09", "http0.9", ARG_BOOL}, + {"0a", "proxy-http2", ARG_BOOL}, + {"1", "tlsv1", ARG_NONE}, + {"10", "tlsv1.0", ARG_NONE}, + {"11", "tlsv1.1", ARG_NONE}, + {"12", "tlsv1.2", ARG_NONE}, + {"13", "tlsv1.3", ARG_NONE}, + {"1A", "tls13-ciphers", ARG_STRING}, + {"1B", "proxy-tls13-ciphers", ARG_STRING}, + {"2", "sslv2", ARG_NONE}, + {"3", "sslv3", ARG_NONE}, + {"4", "ipv4", ARG_NONE}, + {"6", "ipv6", ARG_NONE}, + {"a", "append", ARG_BOOL}, + {"A", "user-agent", ARG_STRING}, + {"b", "cookie", ARG_STRING}, + {"ba", "alt-svc", ARG_STRING}, + {"bb", "hsts", ARG_STRING}, + {"B", "use-ascii", ARG_BOOL}, + {"c", "cookie-jar", ARG_STRING}, + {"C", "continue-at", ARG_STRING}, + {"d", "data", ARG_STRING}, + {"dr", "data-raw", ARG_STRING}, + {"da", "data-ascii", ARG_STRING}, + {"db", "data-binary", ARG_STRING}, + {"de", "data-urlencode", ARG_STRING}, + {"df", "json", ARG_STRING}, + {"dg", "url-query", ARG_STRING}, + {"D", "dump-header", ARG_FILENAME}, + {"e", "referer", ARG_STRING}, + {"E", "cert", ARG_FILENAME}, + {"Ea", "cacert", ARG_FILENAME}, + {"Eb", "cert-type", ARG_STRING}, + {"Ec", "key", ARG_FILENAME}, + {"Ed", "key-type", ARG_STRING}, + {"Ee", "pass", ARG_STRING}, + {"Ef", "engine", ARG_STRING}, + {"EG", "ca-native", ARG_BOOL}, + {"EH", "proxy-ca-native", ARG_BOOL}, + {"Eg", "capath", ARG_FILENAME}, + {"Eh", "pubkey", ARG_STRING}, + {"Ei", "hostpubmd5", ARG_STRING}, + {"EF", "hostpubsha256", ARG_STRING}, + {"Ej", "crlfile", ARG_FILENAME}, + {"Ek", "tlsuser", ARG_STRING}, + {"El", "tlspassword", ARG_STRING}, + {"Em", "tlsauthtype", ARG_STRING}, + {"En", "ssl-allow-beast", ARG_BOOL}, + {"Eo", "ssl-auto-client-cert", ARG_BOOL}, + {"EO", "proxy-ssl-auto-client-cert", ARG_BOOL}, + {"Ep", "pinnedpubkey", ARG_STRING}, + {"EP", "proxy-pinnedpubkey", ARG_STRING}, + {"Eq", "cert-status", ARG_BOOL}, + {"EQ", "doh-cert-status", ARG_BOOL}, + {"Er", "false-start", ARG_BOOL}, + {"Es", "ssl-no-revoke", ARG_BOOL}, + {"ES", "ssl-revoke-best-effort", ARG_BOOL}, + {"Et", "tcp-fastopen", ARG_BOOL}, + {"Eu", "proxy-tlsuser", ARG_STRING}, + {"Ev", "proxy-tlspassword", ARG_STRING}, + {"Ew", "proxy-tlsauthtype", ARG_STRING}, + {"Ex", "proxy-cert", ARG_FILENAME}, + {"Ey", "proxy-cert-type", ARG_STRING}, + {"Ez", "proxy-key", ARG_FILENAME}, + {"E0", "proxy-key-type", ARG_STRING}, + {"E1", "proxy-pass", ARG_STRING}, + {"E2", "proxy-ciphers", ARG_STRING}, + {"E3", "proxy-crlfile", ARG_FILENAME}, + {"E4", "proxy-ssl-allow-beast", ARG_BOOL}, + {"E5", "login-options", ARG_STRING}, + {"E6", "proxy-cacert", ARG_FILENAME}, + {"E7", "proxy-capath", ARG_FILENAME}, + {"E8", "proxy-insecure", ARG_BOOL}, + {"E9", "proxy-tlsv1", ARG_NONE}, + {"EA", "socks5-basic", ARG_BOOL}, + {"EB", "socks5-gssapi", ARG_BOOL}, + {"EC", "etag-save", ARG_FILENAME}, + {"ED", "etag-compare", ARG_FILENAME}, + {"EE", "curves", ARG_STRING}, + {"f", "fail", ARG_BOOL}, + {"fa", "fail-early", ARG_BOOL}, + {"fb", "styled-output", ARG_BOOL}, + {"fc", "mail-rcpt-allowfails", ARG_BOOL}, + {"fd", "fail-with-body", ARG_BOOL}, + {"fe", "remove-on-error", ARG_BOOL}, + {"F", "form", ARG_STRING}, + {"Fs", "form-string", ARG_STRING}, + {"g", "globoff", ARG_BOOL}, + {"G", "get", ARG_BOOL}, + {"Ga", "request-target", ARG_STRING}, + {"h", "help", ARG_BOOL}, + {"H", "header", ARG_STRING}, + {"Hp", "proxy-header", ARG_STRING}, + {"i", "include", ARG_BOOL}, + {"I", "head", ARG_BOOL}, + {"j", "junk-session-cookies", ARG_BOOL}, + {"J", "remote-header-name", ARG_BOOL}, + {"k", "insecure", ARG_BOOL}, + {"kd", "doh-insecure", ARG_BOOL}, + {"K", "config", ARG_FILENAME}, + {"l", "list-only", ARG_BOOL}, + {"L", "location", ARG_BOOL}, + {"Lt", "location-trusted", ARG_BOOL}, + {"m", "max-time", ARG_STRING}, + {"M", "manual", ARG_BOOL}, + {"n", "netrc", ARG_BOOL}, + {"no", "netrc-optional", ARG_BOOL}, + {"ne", "netrc-file", ARG_FILENAME}, + {"N", "buffer", ARG_BOOL}, + /* 'buffer' listed as --no-buffer in the help */ + {"o", "output", ARG_FILENAME}, + {"O", "remote-name", ARG_BOOL}, + {"Oa", "remote-name-all", ARG_BOOL}, + {"Ob", "output-dir", ARG_STRING}, + {"Oc", "clobber", ARG_BOOL}, + {"p", "proxytunnel", ARG_BOOL}, + {"P", "ftp-port", ARG_STRING}, + {"q", "disable", ARG_BOOL}, + {"Q", "quote", ARG_STRING}, + {"r", "range", ARG_STRING}, + {"R", "remote-time", ARG_BOOL}, + {"s", "silent", ARG_BOOL}, + {"S", "show-error", ARG_BOOL}, + {"t", "telnet-option", ARG_STRING}, + {"T", "upload-file", ARG_FILENAME}, + {"u", "user", ARG_STRING}, + {"U", "proxy-user", ARG_STRING}, + {"v", "verbose", ARG_BOOL}, + {"V", "version", ARG_BOOL}, + {"w", "write-out", ARG_STRING}, + {"x", "proxy", ARG_STRING}, + {"xa", "preproxy", ARG_STRING}, + {"X", "request", ARG_STRING}, + {"Y", "speed-limit", ARG_STRING}, + {"y", "speed-time", ARG_STRING}, + {"z", "time-cond", ARG_STRING}, + {"Z", "parallel", ARG_BOOL}, + {"Zb", "parallel-max", ARG_STRING}, + {"Zc", "parallel-immediate", ARG_BOOL}, + {"#", "progress-bar", ARG_BOOL}, + {"#m", "progress-meter", ARG_BOOL}, + {":", "next", ARG_NONE}, + {":a", "variable", ARG_STRING}, }; /* Split the argument of -E to 'certname' and 'passphrase' separated by colon. * We allow ':' and '\' to be escaped by '\' so that we can use certificate - * nicknames containing ':'. See <https://sourceforge.net/p/curl/bugs/1196/> + * nicknames containing ':'. See <https://sourceforge.net/p/curl/bugs/1196/> * for details. */ #ifndef UNITTESTS static @@ -391,7 +405,7 @@ void parse_cert_parameter(const char *cert_parameter, strncpy(certname_place, param_place, span); param_place += span; certname_place += span; - /* we just ate all the non-special chars. now we are on either a special + /* we just ate all the non-special chars. now we're on either a special * char or the end of the string. */ switch(*param_place) { case '\0': @@ -418,11 +432,11 @@ void parse_cert_parameter(const char *cert_parameter, } break; case ':': - /* Since we live in a world of weirdness and confusion, the Windows + /* Since we live in a world of weirdness and confusion, the win32 dudes can use : when using drive letters and thus c:\file:password needs to work. In order not to break compatibility, we still use : as - separator, but we try to detect when it is used for a filename! On - Windows. */ + separator, but we try to detect when it is used for a file name! On + windows. */ #ifdef _WIN32 if((param_place == &cert_parameter[1]) && (cert_parameter[2] == '\\' || cert_parameter[2] == '/') && @@ -437,7 +451,7 @@ void parse_cert_parameter(const char *cert_parameter, } #endif /* escaped colons and Windows drive letter colons were handled - * above; if we are still here, this is a separating colon */ + * above; if we're still here, this is a separating colon */ param_place++; if(*param_place) { *passphrase = strdup(param_place); @@ -481,14 +495,12 @@ static void GetFileAndPassword(char *nextarg, char **file, char **password) { char *certname, *passphrase; - if(nextarg) { - parse_cert_parameter(nextarg, &certname, &passphrase); - Curl_safefree(*file); - *file = certname; - if(passphrase) { - Curl_safefree(*password); - *password = passphrase; - } + parse_cert_parameter(nextarg, &certname, &passphrase); + Curl_safefree(*file); + *file = certname; + if(passphrase) { + Curl_safefree(*password); + *password = passphrase; } } @@ -547,8 +559,8 @@ static ParameterError GetSizeParameter(struct GlobalConfig *global, #ifdef HAVE_WRITABLE_ARGV static void cleanarg(argv_item_t str) { - /* now that getstr has copied the contents of nextarg, wipe the next - * argument out so that the username:password is not displayed in the + /* now that GetStr has copied the contents of nextarg, wipe the next + * argument out so that the username:password isn't displayed in the * system process list */ if(str) { size_t len = strlen(str); @@ -559,9 +571,6 @@ static void cleanarg(argv_item_t str) #define cleanarg(x) #endif -/* the maximum size we allow the dynbuf generated string */ -#define MAX_DATAURLENCODE (500*1024*1024) - /* --data-urlencode */ static ParameterError data_urlencode(struct GlobalConfig *global, char *nextarg, @@ -569,7 +578,7 @@ static ParameterError data_urlencode(struct GlobalConfig *global, size_t *lenp) { /* [name]=[content], we encode the content part only - * [name]@[filename] + * [name]@[file name] * * Case 2: we first load the file using that name and then encode * the content. @@ -588,14 +597,13 @@ static ParameterError data_urlencode(struct GlobalConfig *global, is_file = *p++; /* pass the separator */ } else { - /* neither @ nor =, so no name and it is not a file */ - nlen = 0; - is_file = 0; + /* neither @ nor =, so no name and it isn't a file */ + nlen = is_file = 0; p = nextarg; } if('@' == is_file) { FILE *file; - /* a '@' letter, it means that a filename or - (stdin) follows */ + /* a '@' letter, it means that a file name or - (stdin) follows */ if(!strcmp("-", p)) { file = stdin; set_binmode(stdin); @@ -616,10 +624,9 @@ static ParameterError data_urlencode(struct GlobalConfig *global, return err; } else { - err = getstr(&postdata, p, ALLOW_BLANK); - if(err) - goto error; - size = strlen(postdata); + GetStr(&postdata, p); + if(postdata) + size = strlen(postdata); } if(!postdata) { @@ -634,25 +641,25 @@ static ParameterError data_urlencode(struct GlobalConfig *global, char *enc = curl_easy_escape(NULL, postdata, (int)size); Curl_safefree(postdata); /* no matter if it worked or not */ if(enc) { - char *n; - replace_url_encoded_space_by_plus(enc); - if(nlen > 0) { /* only append '=' if we have a name */ - struct curlx_dynbuf dyn; - curlx_dyn_init(&dyn, MAX_DATAURLENCODE); - if(curlx_dyn_addn(&dyn, nextarg, nlen) || - curlx_dyn_addn(&dyn, "=", 1) || - curlx_dyn_add(&dyn, enc)) { - curl_free(enc); - return PARAM_NO_MEM; - } + /* replace (in-place) '%20' by '+' according to RFC1866 */ + size_t enclen = replace_url_encoded_space_by_plus(enc); + /* now make a string with the name from above and append the + encoded string */ + size_t outlen = nlen + enclen + 2; + char *n = malloc(outlen); + if(!n) { curl_free(enc); - n = curlx_dyn_ptr(&dyn); - size = curlx_dyn_len(&dyn); + return PARAM_NO_MEM; + } + if(nlen > 0) { /* only append '=' if we have a name */ + msnprintf(n, outlen, "%.*s=%s", (int)nlen, nextarg, enc); + size = outlen-1; } else { - n = enc; - size = strlen(n); + strcpy(n, enc); + size = outlen-2; /* since no '=' was inserted */ } + curl_free(enc); postdata = n; } else @@ -687,7 +694,7 @@ static CURLcode set_trace_config(struct GlobalConfig *global, if(!tmp) return CURLE_OUT_OF_MEMORY; - /* Allow strtok() here since this is not used threaded */ + /* Allow strtok() here since this isn't used threaded */ /* !checksrc! disable BANNEDFUNC 2 */ token = strtok(tmp, ", "); while(token) { @@ -731,289 +738,6 @@ out: return result; } -static int findarg(const void *a, const void *b) -{ - const struct LongShort *aa = a; - const struct LongShort *bb = b; - return strcmp(aa->lname, bb->lname); -} - -const struct LongShort *findshortopt(char letter) -{ - static const struct LongShort *singles[128 - ' ']; /* ASCII => pointer */ - static bool singles_done = FALSE; - if((letter >= 127) || (letter <= ' ')) - return NULL; - - if(!singles_done) { - unsigned int j; - for(j = 0; j < sizeof(aliases)/sizeof(aliases[0]); j++) { - if(aliases[j].letter != ' ') { - unsigned char l = (unsigned char)aliases[j].letter; - singles[l - ' '] = &aliases[j]; - } - } - singles_done = TRUE; - } - return singles[letter - ' ']; -} - -struct TOSEntry { - const char *name; - unsigned char value; -}; - -static const struct TOSEntry tos_entries[] = { - {"AF11", 0x28}, - {"AF12", 0x30}, - {"AF13", 0x38}, - {"AF21", 0x48}, - {"AF22", 0x50}, - {"AF23", 0x58}, - {"AF31", 0x68}, - {"AF32", 0x70}, - {"AF33", 0x78}, - {"AF41", 0x88}, - {"AF42", 0x90}, - {"AF43", 0x98}, - {"CE", 0x03}, - {"CS0", 0x00}, - {"CS1", 0x20}, - {"CS2", 0x40}, - {"CS3", 0x60}, - {"CS4", 0x80}, - {"CS5", 0xa0}, - {"CS6", 0xc0}, - {"CS7", 0xe0}, - {"ECT0", 0x02}, - {"ECT1", 0x01}, - {"EF", 0xb8}, - {"LE", 0x04}, - {"LOWCOST", 0x02}, - {"LOWDELAY", 0x10}, - {"MINCOST", 0x02}, - {"RELIABILITY", 0x04}, - {"THROUGHPUT", 0x08}, - {"VOICE-ADMIT", 0xb0} -}; - -static int find_tos(const void *a, const void *b) -{ - const struct TOSEntry *aa = a; - const struct TOSEntry *bb = b; - return strcmp(aa->name, bb->name); -} - -#define MAX_QUERY_LEN 100000 /* larger is not likely to ever work */ -static ParameterError url_query(char *nextarg, - struct GlobalConfig *global, - struct OperationConfig *config) -{ - size_t size = 0; - ParameterError err = PARAM_OK; - char *query; - struct curlx_dynbuf dyn; - curlx_dyn_init(&dyn, MAX_QUERY_LEN); - - if(*nextarg == '+') { - /* use without encoding */ - query = strdup(&nextarg[1]); - if(!query) - err = PARAM_NO_MEM; - } - else - err = data_urlencode(global, nextarg, &query, &size); - - if(!err) { - if(config->query) { - CURLcode result = curlx_dyn_addf(&dyn, "%s&%s", config->query, query); - free(query); - if(result) - err = PARAM_NO_MEM; - else { - free(config->query); - config->query = curlx_dyn_ptr(&dyn); - } - } - else - config->query = query; - } - return err; -} - -static ParameterError set_data(cmdline_t cmd, - char *nextarg, - struct GlobalConfig *global, - struct OperationConfig *config) -{ - char *postdata = NULL; - FILE *file; - size_t size = 0; - ParameterError err = PARAM_OK; - - if(cmd == C_DATA_URLENCODE) { /* --data-urlencode */ - err = data_urlencode(global, nextarg, &postdata, &size); - if(err) - return err; - } - else if('@' == *nextarg && (cmd != C_DATA_RAW)) { - /* the data begins with a '@' letter, it means that a filename - or - (stdin) follows */ - nextarg++; /* pass the @ */ - - if(!strcmp("-", nextarg)) { - file = stdin; - if(cmd == C_DATA_BINARY) /* forced data-binary */ - set_binmode(stdin); - } - else { - file = fopen(nextarg, "rb"); - if(!file) { - errorf(global, "Failed to open %s", nextarg); - return PARAM_READ_ERROR; - } - } - - if((cmd == C_DATA_BINARY) || /* --data-binary */ - (cmd == C_JSON) /* --json */) - /* forced binary */ - err = file2memory(&postdata, &size, file); - else { - err = file2string(&postdata, file); - if(postdata) - size = strlen(postdata); - } - - if(file && (file != stdin)) - fclose(file); - if(err) - return err; - - if(!postdata) { - /* no data from the file, point to a zero byte string to make this - get sent as a POST anyway */ - postdata = strdup(""); - if(!postdata) - return PARAM_NO_MEM; - } - } - else { - err = getstr(&postdata, nextarg, ALLOW_BLANK); - if(err) - return err; - size = strlen(postdata); - } - if(cmd == C_JSON) - config->jsoned = TRUE; - - if(curlx_dyn_len(&config->postdata)) { - /* skip separator append for --json */ - if(!err && (cmd != C_JSON) && - curlx_dyn_addn(&config->postdata, "&", 1)) - err = PARAM_NO_MEM; - } - - if(!err && curlx_dyn_addn(&config->postdata, postdata, size)) - err = PARAM_NO_MEM; - - Curl_safefree(postdata); - - config->postfields = curlx_dyn_ptr(&config->postdata); - return err; -} - -static ParameterError set_rate(struct GlobalConfig *global, - char *nextarg) -{ - /* --rate */ - /* support a few different suffixes, extract the suffix first, then - get the number and convert to per hour. - /s == per second - /m == per minute - /h == per hour (default) - /d == per day (24 hours) - */ - ParameterError err = PARAM_OK; - char *div = strchr(nextarg, '/'); - char number[26]; - long denominator; - long numerator = 60*60*1000; /* default per hour */ - size_t numlen = div ? (size_t)(div - nextarg) : strlen(nextarg); - if(numlen > sizeof(number) -1) - return PARAM_NUMBER_TOO_LARGE; - - strncpy(number, nextarg, numlen); - number[numlen] = 0; - err = str2unum(&denominator, number); - if(err) - return err; - - if(denominator < 1) - return PARAM_BAD_USE; - - if(div) { - char unit = div[1]; - curl_off_t numunits; - char *endp; - - if(curlx_strtoofft(&div[1], &endp, 10, &numunits)) { - /* if it fails, there is no legit number specified */ - if(endp == &div[1]) - /* if endp did not move, accept it as a 1 */ - numunits = 1; - else - return PARAM_BAD_USE; - } - else - unit = *endp; - - switch(unit) { - case 's': /* per second */ - numerator = 1000; - break; - case 'm': /* per minute */ - numerator = 60*1000; - break; - case 'h': /* per hour */ - break; - case 'd': /* per day */ - numerator = 24*60*60*1000; - break; - default: - errorf(global, "unsupported --rate unit"); - err = PARAM_BAD_USE; - break; - } - - if((LONG_MAX / numerator) < numunits) { - /* overflow, too large number */ - errorf(global, "too large --rate unit"); - err = PARAM_NUMBER_TOO_LARGE; - } - /* this typecast is okay based on the check above */ - numerator *= (long)numunits; - } - - if(err) - ; - else if(denominator > numerator) - err = PARAM_NUMBER_TOO_LARGE; - else - global->ms_per_transfer = numerator/denominator; - - return err; -} - -const struct LongShort *findlongopt(const char *opt) -{ - struct LongShort key; - key.lname = opt; - - return bsearch(&key, aliases, sizeof(aliases)/sizeof(aliases[0]), - sizeof(aliases[0]), findarg); -} - - ParameterError getparameter(const char *flag, /* f or -long-flag */ char *nextarg, /* NULL if unset */ argv_item_t cleararg, @@ -1022,17 +746,19 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ struct GlobalConfig *global, struct OperationConfig *config) { + char letter; + char subletter = '\0'; /* subletters can only occur on long options */ int rc; const char *parse = NULL; + unsigned int j; time_t now; + int hit = -1; bool longopt = FALSE; bool singleopt = FALSE; /* when true means '-o foo' used '-ofoo' */ - size_t nopts = 0; /* options processed in `flag`*/ ParameterError err = PARAM_OK; bool toggle = TRUE; /* how to switch boolean options, on or off. Controlled by using --OPTION or --no-OPTION */ bool nextalloc = FALSE; /* if nextarg is allocated */ - struct getout *url; static const char *redir_protos[] = { "http", "https", @@ -1040,19 +766,19 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ "ftps", NULL }; - const struct LongShort *a = NULL; - curl_off_t value; #ifdef HAVE_WRITABLE_ARGV argv_item_t clearthis = NULL; #else (void)cleararg; #endif - *usedarg = FALSE; /* default is that we do not use the arg */ + *usedarg = FALSE; /* default is that we don't use the arg */ if(('-' != flag[0]) || ('-' == flag[1])) { /* this should be a long name */ const char *word = ('-' == flag[0]) ? flag + 2 : flag; + size_t fnam = strlen(word); + int numhits = 0; bool noflagged = FALSE; bool expand = FALSE; @@ -1068,26 +794,41 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ expand = TRUE; } - a = findlongopt(word); - if(a) { - longopt = TRUE; + for(j = 0; j < sizeof(aliases)/sizeof(aliases[0]); j++) { + if(curl_strnequal(aliases[j].lname, word, fnam)) { + longopt = TRUE; + numhits++; + if(curl_strequal(aliases[j].lname, word)) { + parse = aliases[j].letter; + hit = j; + numhits = 1; /* a single unique hit */ + break; + } + parse = aliases[j].letter; + hit = j; + } } - else { + if(numhits > 1) { + /* this is at least the second match! */ + err = PARAM_OPTION_AMBIGUOUS; + goto error; + } + else if(hit < 0) { err = PARAM_OPTION_UNKNOWN; goto error; } - if(noflagged && (ARGTYPE(a->desc) != ARG_BOOL)) { - /* --no- prefixed an option that is not boolean! */ + else if(noflagged && (aliases[hit].desc != ARG_BOOL)) { + /* --no- prefixed an option that isn't boolean! */ err = PARAM_NO_NOT_BOOLEAN; goto error; } - else if(expand && nextarg) { + else if(expand) { struct curlx_dynbuf nbuf; bool replaced; - if((ARGTYPE(a->desc) != ARG_STRG) && - (ARGTYPE(a->desc) != ARG_FILE)) { - /* --expand on an option that is not a string or a filename */ + if((aliases[hit].desc != ARG_STRING) && + (aliases[hit].desc != ARG_FILENAME)) { + /* --expand on an option that isn't a string or a filename */ err = PARAM_EXPAND_ERROR; goto error; } @@ -1104,28 +845,40 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ } else { flag++; /* prefixed with one dash, pass it */ + hit = -1; parse = flag; } do { /* we can loop here if we have multiple single-letters */ - char letter; - cmdline_t cmd; - if(!longopt && !a) { - a = findshortopt(*parse); - if(!a) { + if(!longopt) { + letter = (char)*parse; + subletter = '\0'; + } + else { + letter = parse[0]; + subletter = parse[1]; + } + + if(hit < 0) { + for(j = 0; j < sizeof(aliases)/sizeof(aliases[0]); j++) { + if(letter == aliases[j].letter[0]) { + hit = j; + break; + } + } + if(hit < 0) { err = PARAM_OPTION_UNKNOWN; break; } } - letter = a->letter; - cmd = (cmdline_t)a->cmd; - if(ARGTYPE(a->desc) >= ARG_STRG) { + + if(aliases[hit].desc >= ARG_STRING) { /* this option requires an extra parameter */ if(!longopt && parse[1]) { nextarg = (char *)&parse[1]; /* this is the actual extra parameter */ - singleopt = TRUE; /* do not loop anymore after this */ + singleopt = TRUE; /* don't loop anymore after this */ } else if(!nextarg) { err = PARAM_REQUIRES_PARAMETER; @@ -1138,704 +891,819 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ *usedarg = TRUE; /* mark it as used */ } - if((ARGTYPE(a->desc) == ARG_FILE) && + if((aliases[hit].desc == ARG_FILENAME) && (nextarg[0] == '-') && nextarg[1]) { - /* if the filename looks like a command line option */ - warnf(global, "The filename argument '%s' looks like a flag.", - nextarg); - } - else if(!strncmp("\xe2\x80\x9c", nextarg, 3)) { - warnf(global, "The argument '%s' starts with a Unicode quote where " - "maybe an ASCII \" was intended?", + /* if the file name looks like a command line option */ + warnf(global, "The file name argument '%s' looks like a flag.", nextarg); } } - else if((ARGTYPE(a->desc) == ARG_NONE) && !toggle) { + else if((aliases[hit].desc == ARG_NONE) && !toggle) { err = PARAM_NO_PREFIX; break; } - if(!nextarg) - /* this is a precaution mostly to please scan-build, as all arguments - that use nextarg should be marked as such and they will check that - nextarg is set before continuing, but code analyzers are not always - that aware of that state */ - nextarg = (char *)""; - - switch(cmd) { - case C_RANDOM_FILE: /* --random-file */ - case C_EGD_FILE: /* --egd-file */ - case C_NTLM_WB: /* --ntlm-wb */ - warnf(global, "--%s is deprecated and has no function anymore", - a->lname); - break; - case C_DNS_IPV4_ADDR: /* --dns-ipv4-addr */ - if(!curlinfo->ares_num) /* c-ares is needed for this */ - err = PARAM_LIBCURL_DOESNT_SUPPORT; - else + switch(letter) { + case '*': /* options without a short option */ + switch(subletter) { + case '4': /* --dns-ipv4-addr */ + if(!curlinfo->ares_num) { /* c-ares is needed for this */ + err = PARAM_LIBCURL_DOESNT_SUPPORT; + break; + } /* addr in dot notation */ - err = getstr(&config->dns_ipv4_addr, nextarg, DENY_BLANK); - break; - case C_DNS_IPV6_ADDR: /* --dns-ipv6-addr */ - if(!curlinfo->ares_num) /* c-ares is needed for this */ - err = PARAM_LIBCURL_DOESNT_SUPPORT; - else + GetStr(&config->dns_ipv4_addr, nextarg); + break; + case '6': /* --dns-ipv6-addr */ + if(!curlinfo->ares_num) { /* c-ares is needed for this */ + err = PARAM_LIBCURL_DOESNT_SUPPORT; + break; + } /* addr in dot notation */ - err = getstr(&config->dns_ipv6_addr, nextarg, DENY_BLANK); - break; - case C_OAUTH2_BEARER: /* --oauth2-bearer */ - err = getstr(&config->oauth_bearer, nextarg, DENY_BLANK); - if(!err) { + GetStr(&config->dns_ipv6_addr, nextarg); + break; + case 'a': /* random-file */ + break; + case 'b': /* egd-file */ + break; + case 'B': /* OAuth 2.0 bearer token */ + GetStr(&config->oauth_bearer, nextarg); cleanarg(clearthis); config->authtype |= CURLAUTH_BEARER; - } - break; - case C_CONNECT_TIMEOUT: /* --connect-timeout */ - err = secs2ms(&config->connecttimeout_ms, nextarg); - break; - case C_DOH_URL: /* --doh-url */ - err = getstr(&config->doh_url, nextarg, ALLOW_BLANK); - if(!err && config->doh_url && !config->doh_url[0]) - /* if given a blank string, make it NULL again */ - Curl_safefree(config->doh_url); - break; - case C_CIPHERS: /* -- ciphers */ - err = getstr(&config->cipher_list, nextarg, DENY_BLANK); - break; - case C_DNS_INTERFACE: /* --dns-interface */ - if(!curlinfo->ares_num) /* c-ares is needed for this */ - err = PARAM_LIBCURL_DOESNT_SUPPORT; - else - /* interface name */ - err = getstr(&config->dns_interface, nextarg, DENY_BLANK); - break; - case C_DISABLE_EPSV: /* --disable-epsv */ - config->disable_epsv = toggle; - break; - case C_DISALLOW_USERNAME_IN_URL: /* --disallow-username-in-url */ - config->disallow_username_in_url = toggle; - break; - case C_EPSV: /* --epsv */ - config->disable_epsv = (!toggle)?TRUE:FALSE; - break; - case C_DNS_SERVERS: /* --dns-servers */ - if(!curlinfo->ares_num) /* c-ares is needed for this */ - err = PARAM_LIBCURL_DOESNT_SUPPORT; - else - /* IP addrs of DNS servers */ - err = getstr(&config->dns_servers, nextarg, DENY_BLANK); - break; - case C_TRACE: /* --trace */ - err = getstr(&global->trace_dump, nextarg, DENY_BLANK); - if(!err) { + break; + case 'c': /* connect-timeout */ + err = secs2ms(&config->connecttimeout_ms, nextarg); + break; + case 'C': /* doh-url */ + GetStr(&config->doh_url, nextarg); + if(config->doh_url && !config->doh_url[0]) + /* if given a blank string, we make it NULL again */ + Curl_safefree(config->doh_url); + break; + case 'd': /* ciphers */ + GetStr(&config->cipher_list, nextarg); + break; + case 'D': /* --dns-interface */ + if(!curlinfo->ares_num) /* c-ares is needed for this */ + err = PARAM_LIBCURL_DOESNT_SUPPORT; + else + /* interface name */ + GetStr(&config->dns_interface, nextarg); + break; + case 'e': /* --disable-epsv */ + config->disable_epsv = toggle; + break; + case 'f': /* --disallow-username-in-url */ + config->disallow_username_in_url = toggle; + break; + case 'E': /* --epsv */ + config->disable_epsv = (!toggle)?TRUE:FALSE; + break; + case 'F': /* --dns-servers */ + if(!curlinfo->ares_num) /* c-ares is needed for this */ + err = PARAM_LIBCURL_DOESNT_SUPPORT; + else + /* IP addrs of DNS servers */ + GetStr(&config->dns_servers, nextarg); + break; + case 'g': /* --trace */ + GetStr(&global->trace_dump, nextarg); if(global->tracetype && (global->tracetype != TRACE_BIN)) warnf(global, "--trace overrides an earlier trace/verbose option"); global->tracetype = TRACE_BIN; - } - break; - case C_NPN: /* --npn */ - warnf(global, "--npn is no longer supported"); - break; - case C_TRACE_ASCII: /* --trace-ascii */ - err = getstr(&global->trace_dump, nextarg, DENY_BLANK); - if(!err) { + break; + case 'G': /* --npn */ + warnf(global, "--npn is no longer supported"); + break; + case 'h': /* --trace-ascii */ + GetStr(&global->trace_dump, nextarg); if(global->tracetype && (global->tracetype != TRACE_ASCII)) warnf(global, "--trace-ascii overrides an earlier trace/verbose option"); global->tracetype = TRACE_ASCII; - } - break; - case C_ALPN: /* --alpn */ - config->noalpn = (!toggle)?TRUE:FALSE; - break; - case C_LIMIT_RATE: /* --limit-rate */ - err = GetSizeParameter(global, nextarg, "rate", &value); - if(!err) { + break; + case 'H': /* --alpn */ + config->noalpn = (!toggle)?TRUE:FALSE; + break; + case 'i': /* --limit-rate */ + { + curl_off_t value; + err = GetSizeParameter(global, nextarg, "rate", &value); + if(err) + break; config->recvpersecond = value; config->sendpersecond = value; } break; - case C_RATE: - err = set_rate(global, nextarg); + case 'I': /* --rate (request rate) */ + { + /* support a few different suffixes, extract the suffix first, then + get the number and convert to per hour. + /s == per second + /m == per minute + /h == per hour (default) + /d == per day (24 hours) + */ + char *div = strchr(nextarg, '/'); + char number[26]; + long denominator; + long numerator = 60*60*1000; /* default per hour */ + size_t numlen = div ? (size_t)(div - nextarg) : strlen(nextarg); + if(numlen > sizeof(number)-1) { + err = PARAM_NUMBER_TOO_LARGE; + break; + } + strncpy(number, nextarg, numlen); + number[numlen] = 0; + err = str2unum(&denominator, number); + if(err) + break; + + if(denominator < 1) { + err = PARAM_BAD_USE; + break; + } + if(div) { + char unit = div[1]; + switch(unit) { + case 's': /* per second */ + numerator = 1000; + break; + case 'm': /* per minute */ + numerator = 60*1000; + break; + case 'h': /* per hour */ + break; + case 'd': /* per day */ + numerator = 24*60*60*1000; + break; + default: + errorf(global, "unsupported --rate unit"); + err = PARAM_BAD_USE; + break; + } + } + + if(denominator > numerator) { + err = PARAM_NUMBER_TOO_LARGE; + break; + } + + global->ms_per_transfer = numerator/denominator; + } break; - case C_COMPRESSED: /* --compressed */ - if(toggle && !(feature_libz || feature_brotli || feature_zstd)) - err = PARAM_LIBCURL_DOESNT_SUPPORT; - else + + case 'j': /* --compressed */ + if(toggle && !(feature_libz || feature_brotli || feature_zstd)) { + err = PARAM_LIBCURL_DOESNT_SUPPORT; + break; + } config->encoding = toggle; - break; - case C_TR_ENCODING: /* --tr-encoding */ - config->tr_encoding = toggle; - break; - case C_DIGEST: /* --digest */ - if(toggle) - config->authtype |= CURLAUTH_DIGEST; - else - config->authtype &= ~CURLAUTH_DIGEST; - break; - case C_NEGOTIATE: /* --negotiate */ - if(!toggle) - config->authtype &= ~CURLAUTH_NEGOTIATE; - else if(feature_spnego) - config->authtype |= CURLAUTH_NEGOTIATE; - else - err = PARAM_LIBCURL_DOESNT_SUPPORT; - break; - case C_NTLM: /* --ntlm */ - if(!toggle) - config->authtype &= ~CURLAUTH_NTLM; - else if(feature_ntlm) - config->authtype |= CURLAUTH_NTLM; - else - err = PARAM_LIBCURL_DOESNT_SUPPORT; - break; - case C_BASIC: /* --basic */ - if(toggle) - config->authtype |= CURLAUTH_BASIC; - else - config->authtype &= ~CURLAUTH_BASIC; - break; - case C_ANYAUTH: /* --anyauth */ - if(toggle) - config->authtype = CURLAUTH_ANY; - /* --no-anyauth simply does not touch it */ - break; + break; + + case 'J': /* --tr-encoding */ + config->tr_encoding = toggle; + break; + + case 'k': /* --digest */ + if(toggle) + config->authtype |= CURLAUTH_DIGEST; + else + config->authtype &= ~CURLAUTH_DIGEST; + break; + + case 'l': /* --negotiate */ + if(!toggle) + config->authtype &= ~CURLAUTH_NEGOTIATE; + else if(feature_spnego) + config->authtype |= CURLAUTH_NEGOTIATE; + else { + err = PARAM_LIBCURL_DOESNT_SUPPORT; + break; + } + break; + + case 'm': /* --ntlm */ + if(!toggle) + config->authtype &= ~CURLAUTH_NTLM; + else if(feature_ntlm) + config->authtype |= CURLAUTH_NTLM; + else { + err = PARAM_LIBCURL_DOESNT_SUPPORT; + break; + } + break; + + case 'M': /* --ntlm-wb */ + if(!toggle) + config->authtype &= ~CURLAUTH_NTLM_WB; + else if(feature_ntlm_wb) + config->authtype |= CURLAUTH_NTLM_WB; + else { + err = PARAM_LIBCURL_DOESNT_SUPPORT; + break; + } + break; + + case 'n': /* --basic for completeness */ + if(toggle) + config->authtype |= CURLAUTH_BASIC; + else + config->authtype &= ~CURLAUTH_BASIC; + break; + + case 'o': /* --anyauth, let libcurl pick it */ + if(toggle) + config->authtype = CURLAUTH_ANY; + /* --no-anyauth simply doesn't touch it */ + break; + #ifdef USE_WATT32 - case C_WDEBUG: /* --wdebug */ - dbug_init(); - break; + case 'p': /* --wdebug */ + dbug_init(); + break; #endif - case C_FTP_CREATE_DIRS: /* --ftp-create-dirs */ - config->ftp_create_dirs = toggle; - break; - case C_CREATE_DIRS: /* --create-dirs */ - config->create_dirs = toggle; - break; - case C_CREATE_FILE_MODE: /* --create-file-mode */ - err = oct2nummax(&config->create_file_mode, nextarg, 0777); - break; - case C_MAX_REDIRS: /* --max-redirs */ - /* specified max no of redirects (http(s)), this accepts -1 as a - special condition */ - err = str2num(&config->maxredirs, nextarg); - if(!err && (config->maxredirs < -1)) - err = PARAM_BAD_NUMERIC; - break; - case C_IPFS_GATEWAY: /* --ipfs-gateway */ - err = getstr(&config->ipfs_gateway, nextarg, DENY_BLANK); - break; - case C_PROXY_NTLM: /* --proxy-ntlm */ - if(!feature_ntlm) - err = PARAM_LIBCURL_DOESNT_SUPPORT; - else + case 'q': /* --ftp-create-dirs */ + config->ftp_create_dirs = toggle; + break; + + case 'r': /* --create-dirs */ + config->create_dirs = toggle; + break; + + case 'R': /* --create-file-mode */ + err = oct2nummax(&config->create_file_mode, nextarg, 0777); + break; + + case 's': /* --max-redirs */ + /* specified max no of redirects (http(s)), this accepts -1 as a + special condition */ + err = str2num(&config->maxredirs, nextarg); + if(err) + break; + if(config->maxredirs < -1) + err = PARAM_BAD_NUMERIC; + break; + + case 'S': /* ipfs gateway url */ + GetStr(&config->ipfs_gateway, nextarg); + break; + + case 't': /* --proxy-ntlm */ + if(!feature_ntlm) { + err = PARAM_LIBCURL_DOESNT_SUPPORT; + break; + } config->proxyntlm = toggle; - break; - case C_CRLF: /* --crlf */ - /* LF -> CRLF conversion? */ - config->crlf = toggle; - break; - case C_AWS_SIGV4: /* --aws-sigv4 */ - config->authtype |= CURLAUTH_AWS_SIGV4; - err = getstr(&config->aws_sigv4, nextarg, DENY_BLANK); - break; - case C_STDERR: /* --stderr */ - tool_set_stderr_file(global, nextarg); - break; - case C_INTERFACE: /* --interface */ - /* interface */ - err = getstr(&config->iface, nextarg, DENY_BLANK); - break; - case C_KRB: /* --krb */ - /* kerberos level string */ - if(!feature_spnego) - err = PARAM_LIBCURL_DOESNT_SUPPORT; - else - err = getstr(&config->krblevel, nextarg, DENY_BLANK); - break; - case C_HAPROXY_PROTOCOL: /* --haproxy-protocol */ - config->haproxy_protocol = toggle; - break; - case C_HAPROXY_CLIENTIP: /* --haproxy-clientip */ - err = getstr(&config->haproxy_clientip, nextarg, DENY_BLANK); - break; - case C_MAX_FILESIZE: /* --max-filesize */ - err = GetSizeParameter(global, nextarg, "max-filesize", &value); - if(!err) - config->max_filesize = value; - break; - case C_DISABLE_EPRT: /* --disable-eprt */ - config->disable_eprt = toggle; - break; - case C_EPRT: /* --eprt */ - config->disable_eprt = (!toggle)?TRUE:FALSE; - break; - case C_XATTR: /* --xattr */ - config->xattr = toggle; - break; - case C_URL: /* --url */ - if(!config->url_get) - config->url_get = config->url_list; + break; - if(config->url_get) { - /* there is a node here, if it already is filled-in continue to find - an "empty" node */ - while(config->url_get && (config->url_get->flags & GETOUT_URL)) - config->url_get = config->url_get->next; - } + case 'u': /* --crlf */ + /* LF -> CRLF conversion? */ + config->crlf = toggle; + break; - /* now there might or might not be an available node to fill in! */ + case 'V': /* --aws-sigv4 */ + config->authtype |= CURLAUTH_AWS_SIGV4; + GetStr(&config->aws_sigv4, nextarg); + break; - if(config->url_get) - /* existing node */ - url = config->url_get; - else - /* there was no free node, create one! */ - config->url_get = url = new_getout(config); + case 'v': /* --stderr */ + tool_set_stderr_file(global, nextarg); + break; + case 'w': /* --interface */ + /* interface */ + GetStr(&config->iface, nextarg); + break; + case 'x': /* --krb */ + /* kerberos level string */ + if(!feature_spnego) { + err = PARAM_LIBCURL_DOESNT_SUPPORT; + break; + } + GetStr(&config->krblevel, nextarg); + break; + case 'X': /* --haproxy-protocol */ + config->haproxy_protocol = toggle; + break; + case 'P': /* --haproxy-clientip */ + GetStr(&config->haproxy_clientip, nextarg); + break; + case 'y': /* --max-filesize */ + { + curl_off_t value; + err = + GetSizeParameter(global, nextarg, "max-filesize", &value); + if(err) + break; + config->max_filesize = value; + } + break; + case 'z': /* --disable-eprt */ + config->disable_eprt = toggle; + break; + case 'Z': /* --eprt */ + config->disable_eprt = (!toggle)?TRUE:FALSE; + break; + case '~': /* --xattr */ + config->xattr = toggle; + break; + case '@': /* the URL! */ + { + struct getout *url; + + if(!config->url_get) + config->url_get = config->url_list; + + if(config->url_get) { + /* there's a node here, if it already is filled-in continue to find + an "empty" node */ + while(config->url_get && (config->url_get->flags & GETOUT_URL)) + config->url_get = config->url_get->next; + } + + /* now there might or might not be an available node to fill in! */ + + if(config->url_get) + /* existing node */ + url = config->url_get; + else + /* there was no free node, create one! */ + config->url_get = url = new_getout(config); + + if(!url) { + err = PARAM_NO_MEM; + break; + } - if(!url) - err = PARAM_NO_MEM; - else { /* fill in the URL */ - err = getstr(&url->url, nextarg, DENY_BLANK); + GetStr(&url->url, nextarg); url->flags |= GETOUT_URL; } + } break; - case C_FTP_SSL: /* --ftp-ssl */ - case C_SSL: /* --ssl */ - if(toggle && !feature_ssl) - err = PARAM_LIBCURL_DOESNT_SUPPORT; - else { + case '$': /* more options without a short option */ + switch(subletter) { + case 'a': /* --ssl */ + if(toggle && !feature_ssl) { + err = PARAM_LIBCURL_DOESNT_SUPPORT; + break; + } config->ftp_ssl = toggle; if(config->ftp_ssl) warnf(global, - "--%s is an insecure option, consider --ssl-reqd instead", - a->lname); - } - break; - case C_FTP_PASV: /* --ftp-pasv */ - Curl_safefree(config->ftpport); - break; - case C_SOCKS5: /* --socks5 */ - /* socks5 proxy to use, and resolves the name locally and passes on the - resolved address */ - err = getstr(&config->proxy, nextarg, DENY_BLANK); - config->proxyver = CURLPROXY_SOCKS5; - break; - case C_SOCKS4: /* --socks4 */ - err = getstr(&config->proxy, nextarg, DENY_BLANK); - config->proxyver = CURLPROXY_SOCKS4; - break; - case C_SOCKS4A: /* --socks4a */ - err = getstr(&config->proxy, nextarg, DENY_BLANK); - config->proxyver = CURLPROXY_SOCKS4A; - break; - case C_SOCKS5_HOSTNAME: /* --socks5-hostname */ - err = getstr(&config->proxy, nextarg, DENY_BLANK); - config->proxyver = CURLPROXY_SOCKS5_HOSTNAME; - break; - case C_TCP_NODELAY: /* --tcp-nodelay */ - config->tcp_nodelay = toggle; - break; - case C_IP_TOS: { /* --ip-tos */ - struct TOSEntry find; - const struct TOSEntry *entry; - find.name = nextarg; - entry = bsearch(&find, tos_entries, - sizeof(tos_entries)/sizeof(*tos_entries), - sizeof(*tos_entries), find_tos); - if(entry) - config->ip_tos = entry->value; - else /* numeric tos value */ - err = str2unummax(&config->ip_tos, nextarg, 0xFF); - break; - } - case C_VLAN_PRIORITY: /* --vlan-priority */ - err = str2unummax(&config->vlan_priority, nextarg, 7); - break; - case C_PROXY_DIGEST: /* --proxy-digest */ - config->proxydigest = toggle; - break; - case C_PROXY_BASIC: /* --proxy-basic */ - config->proxybasic = toggle; - break; - case C_RETRY: /* --retry */ - err = str2unum(&config->req_retry, nextarg); - break; - case C_RETRY_CONNREFUSED: /* --retry-connrefused */ - config->retry_connrefused = toggle; - break; - case C_RETRY_DELAY: /* --retry-delay */ - err = str2unummax(&config->retry_delay, nextarg, LONG_MAX/1000); - break; - case C_RETRY_MAX_TIME: /* --retry-max-time */ - err = str2unummax(&config->retry_maxtime, nextarg, LONG_MAX/1000); - break; - case C_RETRY_ALL_ERRORS: /* --retry-all-errors */ - config->retry_all_errors = toggle; - break; - case C_PROXY_NEGOTIATE: /* --proxy-negotiate */ - if(!feature_spnego) - err = PARAM_LIBCURL_DOESNT_SUPPORT; - else + "--ssl is an insecure option, consider --ssl-reqd instead"); + break; + case 'b': /* --ftp-pasv */ + Curl_safefree(config->ftpport); + break; + case 'c': /* --socks5 specifies a socks5 proxy to use, and resolves + the name locally and passes on the resolved address */ + GetStr(&config->proxy, nextarg); + config->proxyver = CURLPROXY_SOCKS5; + break; + case 't': /* --socks4 specifies a socks4 proxy to use */ + GetStr(&config->proxy, nextarg); + config->proxyver = CURLPROXY_SOCKS4; + break; + case 'T': /* --socks4a specifies a socks4a proxy to use */ + GetStr(&config->proxy, nextarg); + config->proxyver = CURLPROXY_SOCKS4A; + break; + case '2': /* --socks5-hostname specifies a socks5 proxy and enables name + resolving with the proxy */ + GetStr(&config->proxy, nextarg); + config->proxyver = CURLPROXY_SOCKS5_HOSTNAME; + break; + case 'd': /* --tcp-nodelay option */ + config->tcp_nodelay = toggle; + break; + case 'e': /* --proxy-digest */ + config->proxydigest = toggle; + break; + case 'f': /* --proxy-basic */ + config->proxybasic = toggle; + break; + case 'g': /* --retry */ + err = str2unum(&config->req_retry, nextarg); + break; + case 'V': /* --retry-connrefused */ + config->retry_connrefused = toggle; + break; + case 'h': /* --retry-delay */ + err = str2unummax(&config->retry_delay, nextarg, LONG_MAX/1000); + break; + case 'i': /* --retry-max-time */ + err = str2unummax(&config->retry_maxtime, nextarg, LONG_MAX/1000); + break; + case '!': /* --retry-all-errors */ + config->retry_all_errors = toggle; + break; + + case 'k': /* --proxy-negotiate */ + if(!feature_spnego) { + err = PARAM_LIBCURL_DOESNT_SUPPORT; + break; + } config->proxynegotiate = toggle; - break; - case C_FORM_ESCAPE: /* --form-escape */ - config->mime_options &= ~CURLMIMEOPT_FORMESCAPE; - if(toggle) - config->mime_options |= CURLMIMEOPT_FORMESCAPE; - break; - case C_FTP_ACCOUNT: /* --ftp-account */ - err = getstr(&config->ftp_account, nextarg, DENY_BLANK); - break; - case C_PROXY_ANYAUTH: /* --proxy-anyauth */ - config->proxyanyauth = toggle; - break; - case C_TRACE_TIME: /* --trace-time */ - global->tracetime = toggle; - break; - case C_IGNORE_CONTENT_LENGTH: /* --ignore-content-length */ - config->ignorecl = toggle; - break; - case C_FTP_SKIP_PASV_IP: /* --ftp-skip-pasv-ip */ - config->ftp_skip_ip = toggle; - break; - case C_FTP_METHOD: /* --ftp-method */ - config->ftp_filemethod = ftpfilemethod(config, nextarg); - break; - case C_LOCAL_PORT: { /* --local-port */ - /* 16bit base 10 is 5 digits, but we allow 6 so that this catches - overflows, not just truncates */ - char lrange[7]=""; - char *p = nextarg; - while(ISDIGIT(*p)) - p++; - if(*p) { - /* if there is anything more than a plain decimal number */ - rc = sscanf(p, " - %6s", lrange); - *p = 0; /* null-terminate to make str2unum() work below */ - } - else - rc = 0; + break; - err = str2unum(&config->localport, nextarg); - if(err || (config->localport > 65535)) { - err = PARAM_BAD_USE; + case 'l': /* --form-escape */ + config->mime_options &= ~CURLMIMEOPT_FORMESCAPE; + if(toggle) + config->mime_options |= CURLMIMEOPT_FORMESCAPE; break; - } - if(!rc) - config->localportrange = 1; /* default number of ports to try */ - else { - err = str2unum(&config->localportrange, lrange); - if(err || (config->localportrange > 65535)) + + case 'm': /* --ftp-account */ + GetStr(&config->ftp_account, nextarg); + break; + case 'n': /* --proxy-anyauth */ + config->proxyanyauth = toggle; + break; + case 'o': /* --trace-time */ + global->tracetime = toggle; + break; + case 'p': /* --ignore-content-length */ + config->ignorecl = toggle; + break; + case 'q': /* --ftp-skip-pasv-ip */ + config->ftp_skip_ip = toggle; + break; + case 'r': /* --ftp-method (undocumented at this point) */ + config->ftp_filemethod = ftpfilemethod(config, nextarg); + break; + case 's': { /* --local-port */ + /* 16bit base 10 is 5 digits, but we allow 6 so that this catches + overflows, not just truncates */ + char lrange[7]=""; + char *p = nextarg; + while(ISDIGIT(*p)) + p++; + if(*p) { + /* if there's anything more than a plain decimal number */ + rc = sscanf(p, " - %6s", lrange); + *p = 0; /* null-terminate to make str2unum() work below */ + } + else + rc = 0; + + err = str2unum(&config->localport, nextarg); + if(err || (config->localport > 65535)) { err = PARAM_BAD_USE; + break; + } + if(!rc) + config->localportrange = 1; /* default number of ports to try */ else { - config->localportrange -= (config->localport-1); - if(config->localportrange < 1) + err = str2unum(&config->localportrange, lrange); + if(err || (config->localportrange > 65535)) err = PARAM_BAD_USE; + else { + config->localportrange -= (config->localport-1); + if(config->localportrange < 1) + err = PARAM_BAD_USE; + } } - } - break; - } - case C_FTP_ALTERNATIVE_TO_USER: /* --ftp-alternative-to-user */ - err = getstr(&config->ftp_alternative_to_user, nextarg, DENY_BLANK); - break; - case C_FTP_SSL_REQD: /* --ftp-ssl-reqd */ - case C_SSL_REQD: /* --ssl-reqd */ - if(toggle && !feature_ssl) { - err = PARAM_LIBCURL_DOESNT_SUPPORT; break; } - config->ftp_ssl_reqd = toggle; - break; - case C_SESSIONID: /* --sessionid */ - config->disable_sessionid = (!toggle)?TRUE:FALSE; - break; - case C_FTP_SSL_CONTROL: /* --ftp-ssl-control */ - if(toggle && !feature_ssl) - err = PARAM_LIBCURL_DOESNT_SUPPORT; - else + case 'u': /* --ftp-alternative-to-user */ + GetStr(&config->ftp_alternative_to_user, nextarg); + break; + case 'v': /* --ssl-reqd */ + if(toggle && !feature_ssl) { + err = PARAM_LIBCURL_DOESNT_SUPPORT; + break; + } + config->ftp_ssl_reqd = toggle; + break; + case 'w': /* --no-sessionid */ + config->disable_sessionid = (!toggle)?TRUE:FALSE; + break; + case 'x': /* --ftp-ssl-control */ + if(toggle && !feature_ssl) { + err = PARAM_LIBCURL_DOESNT_SUPPORT; + break; + } config->ftp_ssl_control = toggle; - break; - case C_FTP_SSL_CCC: /* --ftp-ssl-ccc */ - config->ftp_ssl_ccc = toggle; - if(!config->ftp_ssl_ccc_mode) - config->ftp_ssl_ccc_mode = CURLFTPSSL_CCC_PASSIVE; - break; - case C_FTP_SSL_CCC_MODE: /* --ftp-ssl-ccc-mode */ - config->ftp_ssl_ccc = TRUE; - config->ftp_ssl_ccc_mode = ftpcccmethod(config, nextarg); - break; - case C_LIBCURL: /* --libcurl */ + break; + case 'y': /* --ftp-ssl-ccc */ + config->ftp_ssl_ccc = toggle; + if(!config->ftp_ssl_ccc_mode) + config->ftp_ssl_ccc_mode = CURLFTPSSL_CCC_PASSIVE; + break; + case 'j': /* --ftp-ssl-ccc-mode */ + config->ftp_ssl_ccc = TRUE; + config->ftp_ssl_ccc_mode = ftpcccmethod(config, nextarg); + break; + case 'z': /* --libcurl */ #ifdef CURL_DISABLE_LIBCURL_OPTION - warnf(global, - "--libcurl option was disabled at build-time"); - err = PARAM_OPTION_UNKNOWN; + warnf(global, + "--libcurl option was disabled at build-time"); + err = PARAM_OPTION_UNKNOWN; + break; #else - err = getstr(&global->libcurl, nextarg, DENY_BLANK); + GetStr(&global->libcurl, nextarg); + break; #endif - break; - case C_RAW: /* --raw */ - config->raw = toggle; - break; - case C_KEEPALIVE: /* --keepalive */ - config->nokeepalive = (!toggle)?TRUE:FALSE; - break; - case C_KEEPALIVE_TIME: /* --keepalive-time */ - err = str2unum(&config->alivetime, nextarg); - break; - case C_KEEPALIVE_CNT: /* --keepalive-cnt */ - err = str2unum(&config->alivecnt, nextarg); - break; - case C_POST301: /* --post301 */ - config->post301 = toggle; - break; - case C_POST302: /* --post302 */ - config->post302 = toggle; - break; - case C_POST303: /* --post303 */ - config->post303 = toggle; - break; - case C_NOPROXY: /* --noproxy */ - /* This specifies the noproxy list */ - err = getstr(&config->noproxy, nextarg, ALLOW_BLANK); - break; - case C_SOCKS5_GSSAPI_NEC: /* --socks5-gssapi-nec */ - config->socks5_gssapi_nec = toggle; - break; - case C_PROXY1_0: /* --proxy1.0 */ - /* http 1.0 proxy */ - err = getstr(&config->proxy, nextarg, DENY_BLANK); - config->proxyver = CURLPROXY_HTTP_1_0; - break; - case C_TFTP_BLKSIZE: /* --tftp-blksize */ - err = str2unum(&config->tftp_blksize, nextarg); - break; - case C_MAIL_FROM: /* --mail-from */ - err = getstr(&config->mail_from, nextarg, DENY_BLANK); - break; - case C_MAIL_RCPT: /* --mail-rcpt */ - /* append receiver to a list */ - err = add2list(&config->mail_rcpt, nextarg); - break; - case C_FTP_PRET: /* --ftp-pret */ - config->ftp_pret = toggle; - break; - case C_PROTO: /* --proto */ - config->proto_present = TRUE; - err = proto2num(config, built_in_protos, &config->proto_str, nextarg); - break; - case C_PROTO_REDIR: /* --proto-redir */ - config->proto_redir_present = TRUE; - if(proto2num(config, redir_protos, &config->proto_redir_str, - nextarg)) + case '#': /* --raw */ + config->raw = toggle; + break; + case '0': /* --post301 */ + config->post301 = toggle; + break; + case '1': /* --no-keepalive */ + config->nokeepalive = (!toggle)?TRUE:FALSE; + break; + case '3': /* --keepalive-time */ + err = str2unum(&config->alivetime, nextarg); + break; + case '4': /* --post302 */ + config->post302 = toggle; + break; + case 'I': /* --post303 */ + config->post303 = toggle; + break; + case '5': /* --noproxy */ + /* This specifies the noproxy list */ + GetStr(&config->noproxy, nextarg); + break; + case '7': /* --socks5-gssapi-nec */ + config->socks5_gssapi_nec = toggle; + break; + case '8': /* --proxy1.0 */ + /* http 1.0 proxy */ + GetStr(&config->proxy, nextarg); + config->proxyver = CURLPROXY_HTTP_1_0; + break; + case '9': /* --tftp-blksize */ + err = str2unum(&config->tftp_blksize, nextarg); + break; + case 'A': /* --mail-from */ + GetStr(&config->mail_from, nextarg); + break; + case 'B': /* --mail-rcpt */ + /* append receiver to a list */ + err = add2list(&config->mail_rcpt, nextarg); + break; + case 'C': /* --ftp-pret */ + config->ftp_pret = toggle; + break; + case 'D': /* --proto */ + config->proto_present = TRUE; + err = proto2num(config, built_in_protos, &config->proto_str, nextarg); + break; + case 'E': /* --proto-redir */ + config->proto_redir_present = TRUE; + if(proto2num(config, redir_protos, &config->proto_redir_str, + nextarg)) { + err = PARAM_BAD_USE; + break; + } + break; + case 'F': /* --resolve */ + err = add2list(&config->resolve, nextarg); + break; + case 'G': /* --delegation LEVEL */ + config->gssapi_delegation = delegation(config, nextarg); + break; + case 'H': /* --mail-auth */ + GetStr(&config->mail_auth, nextarg); + break; + case 'J': /* --metalink */ + errorf(global, "--metalink is disabled"); err = PARAM_BAD_USE; - break; - case C_RESOLVE: /* --resolve */ - err = add2list(&config->resolve, nextarg); - break; - case C_DELEGATION: /* --delegation */ - config->gssapi_delegation = delegation(config, nextarg); - break; - case C_MAIL_AUTH: /* --mail-auth */ - err = getstr(&config->mail_auth, nextarg, DENY_BLANK); - break; - case C_METALINK: /* --metalink */ - errorf(global, "--metalink is disabled"); - err = PARAM_BAD_USE; - break; - case C_SASL_AUTHZID: /* --sasl-authzid */ - err = getstr(&config->sasl_authzid, nextarg, DENY_BLANK); - break; - case C_SASL_IR: /* --sasl-ir */ - config->sasl_ir = toggle; - break; - case C_TEST_EVENT: /* --test-event */ -#ifdef DEBUGBUILD - global->test_event_based = toggle; + break; + case '6': /* --sasl-authzid */ + GetStr(&config->sasl_authzid, nextarg); + break; + case 'K': /* --sasl-ir */ + config->sasl_ir = toggle; + break; + case 'L': /* --test-event */ +#ifdef CURLDEBUG + global->test_event_based = toggle; #else - warnf(global, "--test-event is ignored unless a debug build"); + warnf(global, "--test-event is ignored unless a debug build"); #endif - break; - case C_UNIX_SOCKET: /* --unix-socket */ - config->abstract_unix_socket = FALSE; - err = getstr(&config->unix_socket_path, nextarg, DENY_BLANK); - break; - case C_PATH_AS_IS: /* --path-as-is */ - config->path_as_is = toggle; - break; - case C_PROXY_SERVICE_NAME: /* --proxy-service-name */ - err = getstr(&config->proxy_service_name, nextarg, DENY_BLANK); - break; - case C_SERVICE_NAME: /* --service-name */ - err = getstr(&config->service_name, nextarg, DENY_BLANK); - break; - case C_PROTO_DEFAULT: /* --proto-default */ - err = getstr(&config->proto_default, nextarg, DENY_BLANK); - if(!err) + break; + case 'M': /* --unix-socket */ + config->abstract_unix_socket = FALSE; + GetStr(&config->unix_socket_path, nextarg); + break; + case 'N': /* --path-as-is */ + config->path_as_is = toggle; + break; + case 'O': /* --proxy-service-name */ + GetStr(&config->proxy_service_name, nextarg); + break; + case 'P': /* --service-name */ + GetStr(&config->service_name, nextarg); + break; + case 'Q': /* --proto-default */ + GetStr(&config->proto_default, nextarg); err = check_protocol(config->proto_default); + break; + case 'R': /* --expect100-timeout */ + err = secs2ms(&config->expect100timeout_ms, nextarg); + break; + case 'S': /* --tftp-no-options */ + config->tftp_no_options = toggle; + break; + case 'U': /* --connect-to */ + err = add2list(&config->connect_to, nextarg); + break; + case 'W': /* --abstract-unix-socket */ + config->abstract_unix_socket = TRUE; + GetStr(&config->unix_socket_path, nextarg); + break; + case 'X': /* --tls-max */ + err = str2tls_max(&config->ssl_version_max, nextarg); + break; + case 'Y': /* --suppress-connect-headers */ + config->suppress_connect_headers = toggle; + break; + case 'Z': /* --compressed-ssh */ + config->ssh_compression = toggle; + break; + case '~': /* --happy-eyeballs-timeout-ms */ + err = str2unum(&config->happy_eyeballs_timeout_ms, nextarg); + /* 0 is a valid value for this timeout */ + break; + case '%': /* --trace-ids */ + global->traceids = toggle; + break; + case '&': /* --trace-config */ + if(set_trace_config(global, nextarg)) { + err = PARAM_NO_MEM; + } + break; + } break; - case C_EXPECT100_TIMEOUT: /* --expect100-timeout */ - err = secs2ms(&config->expect100timeout_ms, nextarg); - break; - case C_TFTP_NO_OPTIONS: /* --tftp-no-options */ - config->tftp_no_options = toggle; - break; - case C_CONNECT_TO: /* --connect-to */ - err = add2list(&config->connect_to, nextarg); - break; - case C_ABSTRACT_UNIX_SOCKET: /* --abstract-unix-socket */ - config->abstract_unix_socket = TRUE; - err = getstr(&config->unix_socket_path, nextarg, DENY_BLANK); - break; - case C_TLS_MAX: /* --tls-max */ - err = str2tls_max(&config->ssl_version_max, nextarg); - break; - case C_SUPPRESS_CONNECT_HEADERS: /* --suppress-connect-headers */ - config->suppress_connect_headers = toggle; - break; - case C_COMPRESSED_SSH: /* --compressed-ssh */ - config->ssh_compression = toggle; - break; - case C_HAPPY_EYEBALLS_TIMEOUT_MS: /* --happy-eyeballs-timeout-ms */ - err = str2unum(&config->happy_eyeballs_timeout_ms, nextarg); - /* 0 is a valid value for this timeout */ - break; - case C_TRACE_IDS: /* --trace-ids */ - global->traceids = toggle; - break; - case C_TRACE_CONFIG: /* --trace-config */ - if(set_trace_config(global, nextarg)) - err = PARAM_NO_MEM; - break; - case C_PROGRESS_METER: /* --progress-meter */ - global->noprogress = !toggle; - break; - case C_PROGRESS_BAR: /* --progress-bar */ - global->progressmode = toggle ? CURL_PROGRESS_BAR : CURL_PROGRESS_STATS; - break; - case C_VARIABLE: /* --variable */ - err = setvariable(global, nextarg); - break; - case C_NEXT: /* --next */ - err = PARAM_NEXT_OPERATION; - break; - case C_HTTP1_0: /* --http1.0 */ - /* HTTP version 1.0 */ - sethttpver(global, config, CURL_HTTP_VERSION_1_0); - break; - case C_HTTP1_1: /* --http1.1 */ - /* HTTP version 1.1 */ - sethttpver(global, config, CURL_HTTP_VERSION_1_1); - break; - case C_HTTP2: /* --http2 */ - /* HTTP version 2.0 */ - if(!feature_http2) - return PARAM_LIBCURL_DOESNT_SUPPORT; - sethttpver(global, config, CURL_HTTP_VERSION_2_0); + case '#': + switch(subletter) { + case 'm': /* --progress-meter */ + global->noprogress = !toggle; + break; + default: /* --progress-bar */ + global->progressmode = + toggle ? CURL_PROGRESS_BAR : CURL_PROGRESS_STATS; + break; + } break; - case C_HTTP2_PRIOR_KNOWLEDGE: /* --http2-prior-knowledge */ - /* HTTP version 2.0 over clean TCP */ - if(!feature_http2) - return PARAM_LIBCURL_DOESNT_SUPPORT; - sethttpver(global, config, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE); + case ':': + switch(subletter) { + case 'a': /* --variable */ + err = setvariable(global, nextarg); + break; + default: /* --next */ + err = PARAM_NEXT_OPERATION; + break; + } break; - case C_HTTP3: /* --http3: */ - /* Try HTTP/3, allow fallback */ - if(!feature_http3) - err = PARAM_LIBCURL_DOESNT_SUPPORT; - else + case '0': /* --http* options */ + switch(subletter) { + case '\0': + /* HTTP version 1.0 */ + sethttpver(global, config, CURL_HTTP_VERSION_1_0); + break; + case '1': + /* HTTP version 1.1 */ + sethttpver(global, config, CURL_HTTP_VERSION_1_1); + break; + case '2': + /* HTTP version 2.0 */ + if(!feature_http2) + return PARAM_LIBCURL_DOESNT_SUPPORT; + sethttpver(global, config, CURL_HTTP_VERSION_2_0); + break; + case '3': /* --http2-prior-knowledge */ + /* HTTP version 2.0 over clean TCP */ + if(!feature_http2) + return PARAM_LIBCURL_DOESNT_SUPPORT; + sethttpver(global, config, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE); + break; + case '4': /* --http3 */ + /* Try HTTP/3, allow fallback */ + if(!feature_http3) { + err = PARAM_LIBCURL_DOESNT_SUPPORT; + break; + } sethttpver(global, config, CURL_HTTP_VERSION_3); - break; - case C_HTTP3_ONLY: /* --http3-only */ - /* Try HTTP/3 without fallback */ - if(!feature_http3) - err = PARAM_LIBCURL_DOESNT_SUPPORT; - else + break; + case '5': /* --http3-only */ + /* Try HTTP/3 without fallback */ + if(!feature_http3) { + err = PARAM_LIBCURL_DOESNT_SUPPORT; + break; + } sethttpver(global, config, CURL_HTTP_VERSION_3ONLY); - break; - case C_HTTP0_9: /* --http0.9 */ - /* Allow HTTP/0.9 responses! */ - config->http09_allowed = toggle; - break; - case C_PROXY_HTTP2: /* --proxy-http2 */ - if(!feature_httpsproxy || !feature_http2) - err = PARAM_LIBCURL_DOESNT_SUPPORT; - else + break; + case '9': + /* Allow HTTP/0.9 responses! */ + config->http09_allowed = toggle; + break; + case 'a': + /* --proxy-http2 */ + if(!feature_httpsproxy || !feature_http2) + return PARAM_LIBCURL_DOESNT_SUPPORT; config->proxyver = CURLPROXY_HTTPS2; + break; + } break; - case C_TLSV1: /* --tlsv1 */ - config->ssl_version = CURL_SSLVERSION_TLSv1; - break; - case C_TLSV1_0: /* --tlsv1.0 */ - config->ssl_version = CURL_SSLVERSION_TLSv1_0; - break; - case C_TLSV1_1: /* --tlsv1.1 */ - config->ssl_version = CURL_SSLVERSION_TLSv1_1; - break; - case C_TLSV1_2: /* --tlsv1.2 */ - config->ssl_version = CURL_SSLVERSION_TLSv1_2; - break; - case C_TLSV1_3: /* --tlsv1.3 */ - config->ssl_version = CURL_SSLVERSION_TLSv1_3; - break; - case C_TLS13_CIPHERS: /* --tls13-ciphers */ - err = getstr(&config->cipher13_list, nextarg, DENY_BLANK); - break; - case C_PROXY_TLS13_CIPHERS: /* --proxy-tls13-ciphers */ - err = getstr(&config->proxy_cipher13_list, nextarg, DENY_BLANK); + case '1': /* --tlsv1* options */ + switch(subletter) { + case '\0': + /* TLS version 1.x */ + config->ssl_version = CURL_SSLVERSION_TLSv1; + break; + case '0': + /* TLS version 1.0 */ + config->ssl_version = CURL_SSLVERSION_TLSv1_0; + break; + case '1': + /* TLS version 1.1 */ + config->ssl_version = CURL_SSLVERSION_TLSv1_1; + break; + case '2': + /* TLS version 1.2 */ + config->ssl_version = CURL_SSLVERSION_TLSv1_2; + break; + case '3': + /* TLS version 1.3 */ + config->ssl_version = CURL_SSLVERSION_TLSv1_3; + break; + case 'A': /* --tls13-ciphers */ + GetStr(&config->cipher13_list, nextarg); + break; + case 'B': /* --proxy-tls13-ciphers */ + GetStr(&config->proxy_cipher13_list, nextarg); + break; + } break; - case C_SSLV2: /* --sslv2 */ + case '2': + /* SSL version 2 */ warnf(global, "Ignores instruction to use SSLv2"); break; - case C_SSLV3: /* --sslv3 */ + case '3': + /* SSL version 3 */ warnf(global, "Ignores instruction to use SSLv3"); break; - case C_IPV4: /* --ipv4 */ + case '4': + /* IPv4 */ config->ip_version = CURL_IPRESOLVE_V4; break; - case C_IPV6: /* --ipv6 */ + case '6': + /* IPv6 */ config->ip_version = CURL_IPRESOLVE_V6; break; - case C_APPEND: /* --append */ + case 'a': /* This makes the FTP sessions use APPE instead of STOR */ config->ftp_append = toggle; break; - case C_USER_AGENT: /* --user-agent */ - err = getstr(&config->useragent, nextarg, ALLOW_BLANK); - break; - case C_ALT_SVC: /* --alt-svc */ - if(!feature_altsvc) - err = PARAM_LIBCURL_DOESNT_SUPPORT; - else - err = getstr(&config->altsvc, nextarg, ALLOW_BLANK); - break; - case C_HSTS: /* --hsts */ - if(!feature_hsts) - err = PARAM_LIBCURL_DOESNT_SUPPORT; - else - err = getstr(&config->hsts, nextarg, ALLOW_BLANK); + case 'A': + /* This specifies the User-Agent name */ + GetStr(&config->useragent, nextarg); break; - case C_COOKIE: /* --cookie */ - if(strchr(nextarg, '=')) { - /* A cookie string must have a =-letter */ - err = add2list(&config->cookies, nextarg); + case 'b': + switch(subletter) { + case 'a': /* --alt-svc */ + if(!feature_altsvc) + err = PARAM_LIBCURL_DOESNT_SUPPORT; + else + GetStr(&config->altsvc, nextarg); break; - } - else { + case 'b': /* --hsts */ + if(!feature_hsts) + err = PARAM_LIBCURL_DOESNT_SUPPORT; + else + GetStr(&config->hsts, nextarg); + break; + default: /* --cookie string coming up: */ + if(nextarg[0] == '@') { + nextarg++; + } + else if(strchr(nextarg, '=')) { + /* A cookie string must have a =-letter */ + err = add2list(&config->cookies, nextarg); + break; + } /* We have a cookie file to read from! */ err = add2list(&config->cookiefiles, nextarg); } break; - case C_USE_ASCII: /* --use-ascii */ + case 'B': + /* use ASCII/text when transferring */ config->use_ascii = toggle; break; - case C_COOKIE_JAR: /* --cookie-jar */ - err = getstr(&config->cookiejar, nextarg, DENY_BLANK); + case 'c': + /* get the file name to dump all cookies in */ + GetStr(&config->cookiejar, nextarg); break; - case C_CONTINUE_AT: /* --continue-at */ + case 'C': /* This makes us continue an ftp transfer at given position */ if(strcmp(nextarg, "-")) { err = str2offset(&config->resume_from, nextarg); + if(err) + break; config->resume_from_current = FALSE; } else { @@ -1844,24 +1712,158 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ } config->use_resume = TRUE; break; - case C_DATA: /* --data */ - case C_DATA_ASCII: /* --data-ascii */ - case C_DATA_BINARY: /* --data-binary */ - case C_DATA_URLENCODE: /* --data-urlencode */ - case C_JSON: /* --json */ - case C_DATA_RAW: /* --data-raw */ - err = set_data(cmd, nextarg, global, config); - break; - case C_URL_QUERY: /* --url-query */ - err = url_query(nextarg, global, config); - break; - case C_DUMP_CA_EMBED: /* --dump-ca-embed */ - err = PARAM_CA_EMBED_REQUESTED; - break; - case C_DUMP_HEADER: /* --dump-header */ - err = getstr(&config->headerfile, nextarg, DENY_BLANK); + case 'd': + /* postfield data */ + { + char *postdata = NULL; + FILE *file; + size_t size = 0; + bool raw_mode = (subletter == 'r'); + + if(subletter == 'g') { /* --url-query */ +#define MAX_QUERY_LEN 100000 /* larger is not likely to ever work */ + char *query; + struct curlx_dynbuf dyn; + curlx_dyn_init(&dyn, MAX_QUERY_LEN); + + if(*nextarg == '+') { + /* use without encoding */ + query = strdup(&nextarg[1]); + if(!query) { + err = PARAM_NO_MEM; + break; + } + } + else { + err = data_urlencode(global, nextarg, &query, &size); + if(err) + break; + } + + if(config->query) { + CURLcode result = + curlx_dyn_addf(&dyn, "%s&%s", config->query, query); + free(query); + if(result) { + err = PARAM_NO_MEM; + break; + } + free(config->query); + config->query = curlx_dyn_ptr(&dyn); + } + else + config->query = query; + + break; /* this is not a POST argument at all */ + } + else if(subletter == 'e') { /* --data-urlencode */ + err = data_urlencode(global, nextarg, &postdata, &size); + if(err) + break; + } + else if('@' == *nextarg && !raw_mode) { + /* the data begins with a '@' letter, it means that a file name + or - (stdin) follows */ + nextarg++; /* pass the @ */ + + if(!strcmp("-", nextarg)) { + file = stdin; + if(subletter == 'b') /* forced data-binary */ + set_binmode(stdin); + } + else { + file = fopen(nextarg, "rb"); + if(!file) { + errorf(global, "Failed to open %s", nextarg); + err = PARAM_READ_ERROR; + break; + } + } + + if((subletter == 'b') || /* --data-binary */ + (subletter == 'f') /* --json */) + /* forced binary */ + err = file2memory(&postdata, &size, file); + else { + err = file2string(&postdata, file); + if(postdata) + size = strlen(postdata); + } + + if(file && (file != stdin)) + fclose(file); + if(err) + break; + + if(!postdata) { + /* no data from the file, point to a zero byte string to make this + get sent as a POST anyway */ + postdata = strdup(""); + if(!postdata) { + err = PARAM_NO_MEM; + break; + } + } + } + else { + GetStr(&postdata, nextarg); + if(postdata) + size = strlen(postdata); + } + if(subletter == 'f') + config->jsoned = TRUE; + + if(config->postfields) { + /* we already have a string, we append this one with a separating + &-letter */ + char *oldpost = config->postfields; + curl_off_t oldlen = config->postfieldsize; + curl_off_t newlen = oldlen + curlx_uztoso(size) + 2; + config->postfields = malloc((size_t)newlen); + if(!config->postfields) { + Curl_safefree(oldpost); + Curl_safefree(postdata); + err = PARAM_NO_MEM; + break; + } + memcpy(config->postfields, oldpost, (size_t)oldlen); + if(subletter != 'f') { + /* skip this treatment for --json */ + /* use byte value 0x26 for '&' to accommodate non-ASCII platforms */ + config->postfields[oldlen] = '\x26'; + memcpy(&config->postfields[oldlen + 1], postdata, size); + config->postfields[oldlen + 1 + size] = '\0'; + config->postfieldsize += size + 1; + } + else { + memcpy(&config->postfields[oldlen], postdata, size); + config->postfields[oldlen + size] = '\0'; + config->postfieldsize += size; + } + Curl_safefree(oldpost); + Curl_safefree(postdata); + } + else { + config->postfields = postdata; + config->postfieldsize = curlx_uztoso(size); + } + } + /* + We can't set the request type here, as this data might be used in + a simple GET if -G is used. Already or soon. + + if(SetHTTPrequest(HTTPREQ_SIMPLEPOST, &config->httpreq)) { + Curl_safefree(postdata); + return PARAM_BAD_USE; + } + */ + break; + case 'D': + /* dump-header to given file name */ + GetStr(&config->headerfile, nextarg); break; - case C_REFERER: { /* --referer */ + case 'e': + { char *ptr = strstr(nextarg, ";auto"); if(ptr) { /* Automatic referer requested, this may be combined with a @@ -1872,314 +1874,322 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ else config->autoreferer = FALSE; ptr = *nextarg ? nextarg : NULL; - err = getstr(&config->referer, ptr, ALLOW_BLANK); - } - break; - case C_CERT: /* --cert */ - cleanarg(clearthis); - GetFileAndPassword(nextarg, &config->cert, &config->key_passwd); - break; - case C_CACERT: /* --cacert */ - err = getstr(&config->cacert, nextarg, DENY_BLANK); - break; - case C_CA_NATIVE: /* --ca-native */ - config->native_ca_store = toggle; - break; - case C_PROXY_CA_NATIVE: /* --proxy-ca-native */ - config->proxy_native_ca_store = toggle; - break; - case C_CERT_TYPE: /* --cert-type */ - err = getstr(&config->cert_type, nextarg, DENY_BLANK); - break; - case C_KEY: /* --key */ - err = getstr(&config->key, nextarg, DENY_BLANK); - break; - case C_KEY_TYPE: /* --key-type */ - err = getstr(&config->key_type, nextarg, DENY_BLANK); - break; - case C_PASS: /* --pass */ - err = getstr(&config->key_passwd, nextarg, DENY_BLANK); - cleanarg(clearthis); - break; - case C_ENGINE: /* --engine */ - err = getstr(&config->engine, nextarg, DENY_BLANK); - if(!err && - config->engine && !strcmp(config->engine, "list")) { - err = PARAM_ENGINES_REQUESTED; - } - break; -#ifndef USE_ECH - case C_ECH: /* --ech, not implemented by default */ - err = PARAM_LIBCURL_DOESNT_SUPPORT; - break; -#else - case C_ECH: /* --ech */ - if(strlen(nextarg) > 4 && strncasecompare("pn:", nextarg, 3)) { - /* a public_name */ - err = getstr(&config->ech_public, nextarg, DENY_BLANK); - } - else if(strlen(nextarg) > 5 && strncasecompare("ecl:", nextarg, 4)) { - /* an ECHConfigList */ - if('@' != *(nextarg + 4)) { - err = getstr(&config->ech_config, nextarg, DENY_BLANK); - } - else { - /* Indirect case: @filename or @- for stdin */ - char *tmpcfg = NULL; - FILE *file; - - nextarg++; /* skip over '@' */ - if(!strcmp("-", nextarg)) { - file = stdin; - } - else { - file = fopen(nextarg, FOPEN_READTEXT); - } - if(!file) { - warnf(global, - "Couldn't read file \"%s\" " - "specified for \"--ech ecl:\" option", - nextarg); - return PARAM_BAD_USE; /* */ - } - err = file2string(&tmpcfg, file); - if(file != stdin) - fclose(file); - if(err) - return err; - config->ech_config = aprintf("ecl:%s",tmpcfg); - if(!config->ech_config) - return PARAM_NO_MEM; - free(tmpcfg); - } /* file done */ - } - else { - /* Simple case: just a string, with a keyword */ - err = getstr(&config->ech, nextarg, DENY_BLANK); + GetStr(&config->referer, ptr); } break; -#endif - case C_CAPATH: /* --capath */ - err = getstr(&config->capath, nextarg, DENY_BLANK); - break; - case C_PUBKEY: /* --pubkey */ - err = getstr(&config->pubkey, nextarg, DENY_BLANK); - break; - case C_HOSTPUBMD5: /* --hostpubmd5 */ - err = getstr(&config->hostpubmd5, nextarg, DENY_BLANK); - if(!err) { - if(!config->hostpubmd5 || strlen(config->hostpubmd5) != 32) + case 'E': + switch(subletter) { + case '\0': /* certificate file */ + cleanarg(clearthis); + GetFileAndPassword(nextarg, &config->cert, &config->key_passwd); + break; + case 'a': /* --cacert CA info PEM file */ + GetStr(&config->cacert, nextarg); + break; + case 'G': /* --ca-native */ + config->native_ca_store = toggle; + break; + case 'H': /* --proxy-ca-native */ + config->proxy_native_ca_store = toggle; + break; + case 'b': /* cert file type */ + GetStr(&config->cert_type, nextarg); + break; + case 'c': /* private key file */ + GetStr(&config->key, nextarg); + break; + case 'd': /* private key file type */ + GetStr(&config->key_type, nextarg); + break; + case 'e': /* private key passphrase */ + GetStr(&config->key_passwd, nextarg); + cleanarg(clearthis); + break; + case 'f': /* crypto engine */ + GetStr(&config->engine, nextarg); + if(config->engine && curl_strequal(config->engine, "list")) { + err = PARAM_ENGINES_REQUESTED; + break; + } + break; + case 'g': /* CA cert directory */ + GetStr(&config->capath, nextarg); + break; + case 'h': /* --pubkey public key file */ + GetStr(&config->pubkey, nextarg); + break; + case 'i': /* --hostpubmd5 md5 of the host public key */ + GetStr(&config->hostpubmd5, nextarg); + if(!config->hostpubmd5 || strlen(config->hostpubmd5) != 32) { err = PARAM_BAD_USE; - } - break; - case C_HOSTPUBSHA256: /* --hostpubsha256 */ - err = getstr(&config->hostpubsha256, nextarg, DENY_BLANK); - break; - case C_CRLFILE: /* --crlfile */ - err = getstr(&config->crlfile, nextarg, DENY_BLANK); - break; - case C_TLSUSER: /* --tlsuser */ - if(!feature_tls_srp) - err = PARAM_LIBCURL_DOESNT_SUPPORT; - else - err = getstr(&config->tls_username, nextarg, DENY_BLANK); - cleanarg(clearthis); - break; - case C_TLSPASSWORD: /* --tlspassword */ - if(!feature_tls_srp) - err = PARAM_LIBCURL_DOESNT_SUPPORT; - else - err = getstr(&config->tls_password, nextarg, ALLOW_BLANK); - cleanarg(clearthis); - break; - case C_TLSAUTHTYPE: /* --tlsauthtype */ - if(!feature_tls_srp) - err = PARAM_LIBCURL_DOESNT_SUPPORT; - else { - err = getstr(&config->tls_authtype, nextarg, DENY_BLANK); - if(!err && strcmp(config->tls_authtype, "SRP")) + break; + } + break; + case 'F': /* --hostpubsha256 sha256 of the host public key */ + GetStr(&config->hostpubsha256, nextarg); + break; + case 'j': /* CRL file */ + GetStr(&config->crlfile, nextarg); + break; + case 'k': /* TLS username */ + if(!feature_tls_srp) { + cleanarg(clearthis); + err = PARAM_LIBCURL_DOESNT_SUPPORT; + break; + } + GetStr(&config->tls_username, nextarg); + cleanarg(clearthis); + break; + case 'l': /* TLS password */ + if(!feature_tls_srp) { + cleanarg(clearthis); + err = PARAM_LIBCURL_DOESNT_SUPPORT; + break; + } + GetStr(&config->tls_password, nextarg); + cleanarg(clearthis); + break; + case 'm': /* TLS authentication type */ + if(!feature_tls_srp) { + err = PARAM_LIBCURL_DOESNT_SUPPORT; + break; + } + GetStr(&config->tls_authtype, nextarg); + if(!curl_strequal(config->tls_authtype, "SRP")) { err = PARAM_LIBCURL_DOESNT_SUPPORT; /* only support TLS-SRP */ - } - break; - case C_SSL_ALLOW_BEAST: /* --ssl-allow-beast */ - if(feature_ssl) - config->ssl_allow_beast = toggle; - break; - case C_SSL_AUTO_CLIENT_CERT: /* --ssl-auto-client-cert */ - if(feature_ssl) - config->ssl_auto_client_cert = toggle; - break; - case C_PROXY_SSL_AUTO_CLIENT_CERT: /* --proxy-ssl-auto-client-cert */ - if(feature_ssl) - config->proxy_ssl_auto_client_cert = toggle; - break; - case C_PINNEDPUBKEY: /* --pinnedpubkey */ - err = getstr(&config->pinnedpubkey, nextarg, DENY_BLANK); - break; - case C_PROXY_PINNEDPUBKEY: /* --proxy-pinnedpubkey */ - err = getstr(&config->proxy_pinnedpubkey, nextarg, DENY_BLANK); - break; - case C_CERT_STATUS: /* --cert-status */ - config->verifystatus = TRUE; - break; - case C_DOH_CERT_STATUS: /* --doh-cert-status */ - config->doh_verifystatus = TRUE; - break; - case C_FALSE_START: /* --false-start */ - config->falsestart = TRUE; - break; - case C_SSL_NO_REVOKE: /* --ssl-no-revoke */ - if(feature_ssl) - config->ssl_no_revoke = TRUE; - break; - case C_SSL_REVOKE_BEST_EFFORT: /* --ssl-revoke-best-effort */ - if(feature_ssl) - config->ssl_revoke_best_effort = TRUE; - break; - case C_TCP_FASTOPEN: /* --tcp-fastopen */ - config->tcp_fastopen = TRUE; - break; - case C_PROXY_TLSUSER: /* --proxy-tlsuser */ - cleanarg(clearthis); - if(!feature_tls_srp) - err = PARAM_LIBCURL_DOESNT_SUPPORT; - else - err = getstr(&config->proxy_tls_username, nextarg, ALLOW_BLANK); - break; - case C_PROXY_TLSPASSWORD: /* --proxy-tlspassword */ - cleanarg(clearthis); - if(!feature_tls_srp) - err = PARAM_LIBCURL_DOESNT_SUPPORT; - else - err = getstr(&config->proxy_tls_password, nextarg, DENY_BLANK); - break; - case C_PROXY_TLSAUTHTYPE: /* --proxy-tlsauthtype */ - if(!feature_tls_srp) - err = PARAM_LIBCURL_DOESNT_SUPPORT; - else { - err = getstr(&config->proxy_tls_authtype, nextarg, DENY_BLANK); - if(!err && strcmp(config->proxy_tls_authtype, "SRP")) + break; + } + break; + case 'n': /* no empty SSL fragments, --ssl-allow-beast */ + if(feature_ssl) + config->ssl_allow_beast = toggle; + break; + + case 'o': /* --ssl-auto-client-cert */ + if(feature_ssl) + config->ssl_auto_client_cert = toggle; + break; + + case 'O': /* --proxy-ssl-auto-client-cert */ + if(feature_ssl) + config->proxy_ssl_auto_client_cert = toggle; + break; + + case 'p': /* Pinned public key DER file */ + GetStr(&config->pinnedpubkey, nextarg); + break; + + case 'P': /* proxy pinned public key */ + GetStr(&config->proxy_pinnedpubkey, nextarg); + break; + + case 'q': /* --cert-status */ + config->verifystatus = TRUE; + break; + + case 'Q': /* --doh-cert-status */ + config->doh_verifystatus = TRUE; + break; + + case 'r': /* --false-start */ + config->falsestart = TRUE; + break; + + case 's': /* --ssl-no-revoke */ + if(feature_ssl) + config->ssl_no_revoke = TRUE; + break; + + case 'S': /* --ssl-revoke-best-effort */ + if(feature_ssl) + config->ssl_revoke_best_effort = TRUE; + break; + + case 't': /* --tcp-fastopen */ + config->tcp_fastopen = TRUE; + break; + + case 'u': /* TLS username for proxy */ + cleanarg(clearthis); + if(!feature_tls_srp) { + err = PARAM_LIBCURL_DOESNT_SUPPORT; + break; + } + GetStr(&config->proxy_tls_username, nextarg); + break; + + case 'v': /* TLS password for proxy */ + cleanarg(clearthis); + if(!feature_tls_srp) { + err = PARAM_LIBCURL_DOESNT_SUPPORT; + break; + } + GetStr(&config->proxy_tls_password, nextarg); + break; + + case 'w': /* TLS authentication type for proxy */ + if(!feature_tls_srp) { + err = PARAM_LIBCURL_DOESNT_SUPPORT; + break; + } + GetStr(&config->proxy_tls_authtype, nextarg); + if(!curl_strequal(config->proxy_tls_authtype, "SRP")) { err = PARAM_LIBCURL_DOESNT_SUPPORT; /* only support TLS-SRP */ + break; + } + break; + + case 'x': /* certificate file for proxy */ + cleanarg(clearthis); + GetFileAndPassword(nextarg, &config->proxy_cert, + &config->proxy_key_passwd); + break; + + case 'y': /* cert file type for proxy */ + GetStr(&config->proxy_cert_type, nextarg); + break; + + case 'z': /* private key file for proxy */ + GetStr(&config->proxy_key, nextarg); + break; + + case '0': /* private key file type for proxy */ + GetStr(&config->proxy_key_type, nextarg); + break; + + case '1': /* private key passphrase for proxy */ + GetStr(&config->proxy_key_passwd, nextarg); + cleanarg(clearthis); + break; + + case '2': /* ciphers for proxy */ + GetStr(&config->proxy_cipher_list, nextarg); + break; + + case '3': /* CRL file for proxy */ + GetStr(&config->proxy_crlfile, nextarg); + break; + + case '4': /* no empty SSL fragments for proxy */ + if(feature_ssl) + config->proxy_ssl_allow_beast = toggle; + break; + + case '5': /* --login-options */ + GetStr(&config->login_options, nextarg); + break; + + case '6': /* CA info PEM file for proxy */ + GetStr(&config->proxy_cacert, nextarg); + break; + + case '7': /* CA cert directory for proxy */ + GetStr(&config->proxy_capath, nextarg); + break; + + case '8': /* allow insecure SSL connects for proxy */ + config->proxy_insecure_ok = toggle; + break; + + case '9': /* --proxy-tlsv1 */ + /* TLS version 1 for proxy */ + config->proxy_ssl_version = CURL_SSLVERSION_TLSv1; + break; + + case 'A': + /* --socks5-basic */ + if(toggle) + config->socks5_auth |= CURLAUTH_BASIC; + else + config->socks5_auth &= ~CURLAUTH_BASIC; + break; + + case 'B': + /* --socks5-gssapi */ + if(toggle) + config->socks5_auth |= CURLAUTH_GSSAPI; + else + config->socks5_auth &= ~CURLAUTH_GSSAPI; + break; + + case 'C': + GetStr(&config->etag_save_file, nextarg); + break; + + case 'D': + GetStr(&config->etag_compare_file, nextarg); + break; + + case 'E': + GetStr(&config->ssl_ec_curves, nextarg); + break; + + default: /* unknown flag */ + err = PARAM_OPTION_UNKNOWN; + break; } break; - case C_PROXY_CERT: /* --proxy-cert */ - cleanarg(clearthis); - GetFileAndPassword(nextarg, &config->proxy_cert, - &config->proxy_key_passwd); - break; - case C_PROXY_CERT_TYPE: /* --proxy-cert-type */ - err = getstr(&config->proxy_cert_type, nextarg, DENY_BLANK); - break; - case C_PROXY_KEY: /* --proxy-key */ - err = getstr(&config->proxy_key, nextarg, ALLOW_BLANK); - break; - case C_PROXY_KEY_TYPE: /* --proxy-key-type */ - err = getstr(&config->proxy_key_type, nextarg, DENY_BLANK); - break; - case C_PROXY_PASS: /* --proxy-pass */ - err = getstr(&config->proxy_key_passwd, nextarg, ALLOW_BLANK); - cleanarg(clearthis); - break; - case C_PROXY_CIPHERS: /* --proxy-ciphers */ - err = getstr(&config->proxy_cipher_list, nextarg, DENY_BLANK); - break; - case C_PROXY_CRLFILE: /* --proxy-crlfile */ - err = getstr(&config->proxy_crlfile, nextarg, DENY_BLANK); - break; - case C_PROXY_SSL_ALLOW_BEAST: /* --proxy-ssl-allow-beast */ - if(feature_ssl) - config->proxy_ssl_allow_beast = toggle; - break; - case C_LOGIN_OPTIONS: /* --login-options */ - err = getstr(&config->login_options, nextarg, ALLOW_BLANK); - break; - case C_PROXY_CACERT: /* --proxy-cacert */ - err = getstr(&config->proxy_cacert, nextarg, DENY_BLANK); - break; - case C_PROXY_CAPATH: /* --proxy-capath */ - err = getstr(&config->proxy_capath, nextarg, DENY_BLANK); - break; - case C_PROXY_INSECURE: /* --proxy-insecure */ - config->proxy_insecure_ok = toggle; - break; - case C_PROXY_TLSV1: /* --proxy-tlsv1 */ - /* TLS version 1 for proxy */ - config->proxy_ssl_version = CURL_SSLVERSION_TLSv1; - break; - case C_SOCKS5_BASIC: /* --socks5-basic */ - if(toggle) - config->socks5_auth |= CURLAUTH_BASIC; - else - config->socks5_auth &= ~CURLAUTH_BASIC; - break; - case C_SOCKS5_GSSAPI: /* --socks5-gssapi */ - if(toggle) - config->socks5_auth |= CURLAUTH_GSSAPI; - else - config->socks5_auth &= ~CURLAUTH_GSSAPI; - break; - case C_ETAG_SAVE: /* --etag-save */ - err = getstr(&config->etag_save_file, nextarg, DENY_BLANK); - break; - case C_ETAG_COMPARE: /* --etag-compare */ - err = getstr(&config->etag_compare_file, nextarg, DENY_BLANK); - break; - case C_CURVES: /* --curves */ - err = getstr(&config->ssl_ec_curves, nextarg, DENY_BLANK); - break; - case C_FAIL_EARLY: /* --fail-early */ - global->fail_early = toggle; - break; - case C_STYLED_OUTPUT: /* --styled-output */ - global->styled_output = toggle; - break; - case C_MAIL_RCPT_ALLOWFAILS: /* --mail-rcpt-allowfails */ - config->mail_rcpt_allowfails = toggle; - break; - case C_FAIL_WITH_BODY: /* --fail-with-body */ - config->failwithbody = toggle; - if(config->failonerror && config->failwithbody) { - errorf(config->global, "You must select either --fail or " - "--fail-with-body, not both."); - err = PARAM_BAD_USE; + case 'f': + switch(subletter) { + case 'a': /* --fail-early */ + global->fail_early = toggle; + break; + case 'b': /* --styled-output */ + global->styled_output = toggle; + break; + case 'c': /* --mail-rcpt-allowfails */ + config->mail_rcpt_allowfails = toggle; + break; + case 'd': /* --fail-with-body */ + config->failwithbody = toggle; + break; + case 'e': /* --remove-on-error */ + config->rm_partial = toggle; + break; + default: /* --fail (hard on errors) */ + config->failonerror = toggle; + break; } - break; - case C_REMOVE_ON_ERROR: /* --remove-on-error */ - config->rm_partial = toggle; - break; - case C_FAIL: /* --fail */ - config->failonerror = toggle; if(config->failonerror && config->failwithbody) { errorf(config->global, "You must select either --fail or " "--fail-with-body, not both."); err = PARAM_BAD_USE; + break; } break; - case C_FORM: /* --form */ - case C_FORM_STRING: /* --form-string */ + case 'F': /* "form data" simulation, this is a little advanced so lets do our best to sort this out slowly and carefully */ if(formparse(config, nextarg, &config->mimeroot, &config->mimecurrent, - (cmd == C_FORM_STRING)?TRUE:FALSE)) /* literal string */ + (subletter == 's')?TRUE:FALSE)) { /* 's' is literal + string */ err = PARAM_BAD_USE; - else if(SetHTTPrequest(config, TOOL_HTTPREQ_MIMEPOST, &config->httpreq)) + break; + } + if(SetHTTPrequest(config, HTTPREQ_MIMEPOST, &config->httpreq)) { err = PARAM_BAD_USE; + break; + } break; - case C_GLOBOFF: /* --globoff */ + + case 'g': /* g disables URLglobbing */ config->globoff = toggle; break; - case C_GET: /* --get */ - config->use_httpget = toggle; - break; - case C_REQUEST_TARGET: /* --request-target */ - err = getstr(&config->request_target, nextarg, DENY_BLANK); + + case 'G': /* HTTP GET */ + if(subletter == 'a') { /* --request-target */ + GetStr(&config->request_target, nextarg); + } + else + config->use_httpget = toggle; break; - case C_HELP: /* --help */ + + case 'h': /* h for help */ if(toggle) { - if(*nextarg) { + if(nextarg) { global->help_category = strdup(nextarg); if(!global->help_category) { err = PARAM_NO_MEM; @@ -2187,11 +2197,11 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ } } err = PARAM_HELP_REQUESTED; + break; } /* we now actually support --no-help too! */ break; - case C_HEADER: /* --header */ - case C_PROXY_HEADER: /* --proxy-header */ + case 'H': /* A custom header to append to a list */ if(nextarg[0] == '@') { /* read many headers from a file or stdin */ @@ -2202,15 +2212,16 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ if(!file) { errorf(global, "Failed to open %s", &nextarg[1]); err = PARAM_READ_ERROR; + break; } else { err = file2memory(&string, &len, file); if(!err && string) { - /* Allow strtok() here since this is not used threaded */ + /* Allow strtok() here since this isn't used threaded */ /* !checksrc! disable BANNEDFUNC 2 */ char *h = strtok(string, "\r\n"); while(h) { - if(cmd == C_PROXY_HEADER) /* --proxy-header */ + if(subletter == 'p') /* --proxy-header */ err = add2list(&config->proxyheaders, h); else err = add2list(&config->headers, h); @@ -2222,102 +2233,119 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ } if(!use_stdin) fclose(file); + if(err) + break; } } else { - if(cmd == C_PROXY_HEADER) /* --proxy-header */ + if(subletter == 'p') /* --proxy-header */ err = add2list(&config->proxyheaders, nextarg); else err = add2list(&config->headers, nextarg); } break; - case C_INCLUDE: /* --include */ - case C_SHOW_HEADERS: /* --show-headers */ + case 'i': config->show_headers = toggle; /* show the headers as well in the general output stream */ break; - case C_JUNK_SESSION_COOKIES: /* --junk-session-cookies */ + case 'j': config->cookiesession = toggle; break; - case C_HEAD: /* --head */ + case 'I': /* --head */ config->no_body = toggle; config->show_headers = toggle; if(SetHTTPrequest(config, - (config->no_body)?TOOL_HTTPREQ_HEAD:TOOL_HTTPREQ_GET, - &config->httpreq)) + (config->no_body)?HTTPREQ_HEAD:HTTPREQ_GET, + &config->httpreq)) { err = PARAM_BAD_USE; + break; + } break; - case C_REMOTE_HEADER_NAME: /* --remote-header-name */ + case 'J': /* --remote-header-name */ config->content_disposition = toggle; break; - case C_INSECURE: /* --insecure */ - config->insecure_ok = toggle; - break; - case C_DOH_INSECURE: /* --doh-insecure */ - config->doh_insecure_ok = toggle; + case 'k': /* allow insecure SSL connects */ + if(subletter == 'd') /* --doh-insecure */ + config->doh_insecure_ok = toggle; + else + config->insecure_ok = toggle; break; - case C_CONFIG: /* --config */ + case 'K': /* parse config file */ if(parseconfig(nextarg, global)) { errorf(global, "cannot read config from '%s'", nextarg); err = PARAM_READ_ERROR; + break; } break; - case C_LIST_ONLY: /* --list-only */ + case 'l': config->dirlistonly = toggle; /* only list the names of the FTP dir */ break; - case C_LOCATION_TRUSTED: /* --location-trusted */ - /* Continue to send authentication (user+password) when following - * locations, even when hostname changed */ - config->unrestricted_auth = toggle; - FALLTHROUGH(); - case C_LOCATION: /* --location */ + case 'L': config->followlocation = toggle; /* Follow Location: HTTP headers */ + switch(subletter) { + case 't': + /* Continue to send authentication (user+password) when following + * locations, even when hostname changed */ + config->unrestricted_auth = toggle; + break; + } break; - case C_MAX_TIME: /* --max-time */ + case 'm': /* specified max time */ err = secs2ms(&config->timeout_ms, nextarg); break; - case C_MANUAL: /* --manual */ + case 'M': /* M for manual, huge help */ if(toggle) { /* --no-manual shows no manual... */ #ifndef USE_MANUAL warnf(global, "built-in manual was disabled at build-time"); #endif err = PARAM_MANUAL_REQUESTED; + break; } break; - case C_NETRC_OPTIONAL: /* --netrc-optional */ - config->netrc_opt = toggle; - break; - case C_NETRC_FILE: /* --netrc-file */ - err = getstr(&config->netrc_file, nextarg, DENY_BLANK); - break; - case C_NETRC: /* --netrc */ - /* pick info from .netrc, if this is used for http, curl will - automatically enforce user+password with the request */ - config->netrc = toggle; + case 'n': + switch(subletter) { + case 'o': /* use .netrc or URL */ + config->netrc_opt = toggle; + break; + case 'e': /* netrc-file */ + GetStr(&config->netrc_file, nextarg); + break; + default: + /* pick info from .netrc, if this is used for http, curl will + automatically enforce user+password with the request */ + config->netrc = toggle; + break; + } break; - case C_BUFFER: /* --buffer */ + case 'N': /* disable the output I/O buffering. note that the option is called --buffer but is mostly used in the negative form: --no-buffer */ config->nobuffer = longopt ? !toggle : TRUE; break; - case C_REMOTE_NAME_ALL: /* --remote-name-all */ - config->default_node_flags = toggle?GETOUT_USEREMOTE:0; - break; - case C_OUTPUT_DIR: /* --output-dir */ - err = getstr(&config->output_dir, nextarg, DENY_BLANK); - break; - case C_CLOBBER: /* --clobber */ - config->file_clobber_mode = toggle ? CLOBBER_ALWAYS : CLOBBER_NEVER; - break; - case C_OUTPUT: /* --output */ - case C_REMOTE_NAME: /* --remote-name */ + case 'O': /* --remote-name */ + if(subletter == 'a') { /* --remote-name-all */ + config->default_node_flags = toggle?GETOUT_USEREMOTE:0; + break; + } + else if(subletter == 'b') { /* --output-dir */ + GetStr(&config->output_dir, nextarg); + break; + } + else if(subletter == 'c') { /* --clobber / --no-clobber */ + config->file_clobber_mode = toggle ? CLOBBER_ALWAYS : CLOBBER_NEVER; + break; + } + /* FALLTHROUGH */ + case 'o': /* --output */ /* output file */ + { + struct getout *url; if(!config->url_out) config->url_out = config->url_list; if(config->url_out) { - /* there is a node here, if it already is filled-in continue to find + /* there's a node here, if it already is filled-in continue to find an "empty" node */ while(config->url_out && (config->url_out->flags & GETOUT_OUTFILE)) config->url_out = config->url_out->next; @@ -2342,7 +2370,12 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ /* fill in the outfile */ if('o' == letter) { - err = getstr(&url->outfile, nextarg, DENY_BLANK); + if(!*nextarg) { + warnf(global, "output file name has no length"); + err = PARAM_BAD_USE; + break; + } + GetStr(&url->outfile, nextarg); url->flags &= ~GETOUT_USEREMOTE; /* switch off */ } else { @@ -2353,25 +2386,25 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ url->flags &= ~GETOUT_USEREMOTE; /* switch off */ } url->flags |= GETOUT_OUTFILE; - break; - case C_FTP_PORT: /* --ftp-port */ + } + break; + case 'P': /* This makes the FTP sessions use PORT instead of PASV */ /* use <eth0> or <192.168.10.10> style addresses. Anything except this will make us try to get the "default" address. NOTE: this is a changed behavior since the released 4.1! */ - err = getstr(&config->ftpport, nextarg, DENY_BLANK); + GetStr(&config->ftpport, nextarg); break; - case C_PROXYTUNNEL: /* --proxytunnel */ + case 'p': /* proxy tunnel for non-http protocols */ config->proxytunnel = toggle; break; - case C_DISABLE: /* --disable */ - /* if used first, already taken care of, we do it like this so we do not - cause an error! */ + case 'q': /* if used first, already taken care of, we do it like + this so we don't cause an error! */ break; - case C_QUOTE: /* --quote */ + case 'Q': /* QUOTE command to send to FTP server */ switch(nextarg[0]) { case '-': @@ -2389,33 +2422,34 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ break; } break; - case C_RANGE: /* --range */ + case 'r': /* Specifying a range WITHOUT A DASH will create an illegal HTTP range - (and will not actually be range by definition). The manpage - previously claimed that to be a good way, why this code is added to - work-around it. */ + (and won't actually be range by definition). The man page previously + claimed that to be a good way, why this code is added to work-around + it. */ if(ISDIGIT(*nextarg) && !strchr(nextarg, '-')) { char buffer[32]; - if(curlx_strtoofft(nextarg, NULL, 10, &value)) { + curl_off_t off; + if(curlx_strtoofft(nextarg, NULL, 10, &off)) { warnf(global, "unsupported range point"); err = PARAM_BAD_USE; + break; } - else { - warnf(global, - "A specified range MUST include at least one dash (-). " - "Appending one for you"); - msnprintf(buffer, sizeof(buffer), "%" CURL_FORMAT_CURL_OFF_T "-", - value); - Curl_safefree(config->range); - config->range = strdup(buffer); - if(!config->range) - err = PARAM_NO_MEM; + warnf(global, + "A specified range MUST include at least one dash (-). " + "Appending one for you"); + msnprintf(buffer, sizeof(buffer), "%" CURL_FORMAT_CURL_OFF_T "-", off); + Curl_safefree(config->range); + config->range = strdup(buffer); + if(!config->range) { + err = PARAM_NO_MEM; + break; } } else { /* byte range requested */ const char *tmp_range = nextarg; - while(*tmp_range) { + while(*tmp_range != '\0') { if(!ISDIGIT(*tmp_range) && *tmp_range != '-' && *tmp_range != ',') { warnf(global, "Invalid character is found in given range. " "A specified range MUST have only digits in " @@ -2425,32 +2459,31 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ } tmp_range++; } - err = getstr(&config->range, nextarg, DENY_BLANK); + GetStr(&config->range, nextarg); } break; - case C_REMOTE_TIME: /* --remote-time */ + case 'R': /* use remote file's time */ config->remote_time = toggle; break; - case C_SILENT: /* --silent */ + case 's': /* --silent */ global->silent = toggle; break; - case C_SKIP_EXISTING: /* --skip-existing */ - config->skip_existing = toggle; - break; - case C_SHOW_ERROR: /* --show-error */ + case 'S': /* --show-error */ global->showerror = toggle; break; - case C_TELNET_OPTION: /* --telnet-option */ + case 't': /* Telnet options */ err = add2list(&config->telnet_options, nextarg); break; - case C_UPLOAD_FILE: /* --upload-file */ + case 'T': /* we are uploading */ + { + struct getout *url; if(!config->url_ul) config->url_ul = config->url_list; if(config->url_ul) { - /* there is a node here, if it already is filled-in continue to find + /* there's a node here, if it already is filled-in continue to find an "empty" node */ while(config->url_ul && (config->url_ul->flags & GETOUT_UPLOAD)) config->url_ul = config->url_ul->next; @@ -2475,81 +2508,49 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ url->flags |= GETOUT_NOUPLOAD; else { /* "-" equals stdin, but keep the string around for now */ - err = getstr(&url->infile, nextarg, DENY_BLANK); + GetStr(&url->infile, nextarg); } - break; - case C_USER: /* --user */ + } + break; + case 'u': /* user:password */ - err = getstr(&config->userpwd, nextarg, ALLOW_BLANK); + GetStr(&config->userpwd, nextarg); cleanarg(clearthis); break; - case C_PROXY_USER: /* --proxy-user */ + case 'U': /* Proxy user:password */ - err = getstr(&config->proxyuserpwd, nextarg, ALLOW_BLANK); + GetStr(&config->proxyuserpwd, nextarg); cleanarg(clearthis); break; - case C_VERBOSE: /* --verbose */ - /* This option is a super-boolean with side effect when applied - * more than once in the same argument flag, like `-vvv`. */ - if(!toggle) { - global->verbosity = 0; - if(set_trace_config(global, "-all")) - err = PARAM_NO_MEM; - global->tracetype = TRACE_NONE; - break; - } - else if(!nopts) { - /* fist `-v` in an argument resets to base verbosity */ - global->verbosity = 0; - if(set_trace_config(global, "-all")) { - err = PARAM_NO_MEM; - break; - } - } - /* the '%' thing here will cause the trace get sent to stderr */ - switch(global->verbosity) { - case 0: - global->verbosity = 1; + case 'v': + if(toggle) { + /* the '%' thing here will cause the trace get sent to stderr */ Curl_safefree(global->trace_dump); global->trace_dump = strdup("%"); - if(!global->trace_dump) + if(!global->trace_dump) { err = PARAM_NO_MEM; - else { - if(global->tracetype && (global->tracetype != TRACE_PLAIN)) - warnf(global, - "-v, --verbose overrides an earlier trace option"); - global->tracetype = TRACE_PLAIN; + break; } - break; - case 1: - global->verbosity = 2; - if(set_trace_config(global, "ids,time,protocol")) - err = PARAM_NO_MEM; - break; - case 2: - global->verbosity = 3; - global->tracetype = TRACE_ASCII; - if(set_trace_config(global, "ssl,read,write")) - err = PARAM_NO_MEM; - break; - case 3: - global->verbosity = 4; - if(set_trace_config(global, "network")) - err = PARAM_NO_MEM; - break; - default: - /* no effect for now */ - break; + if(global->tracetype && (global->tracetype != TRACE_PLAIN)) + warnf(global, + "-v, --verbose overrides an earlier trace/verbose option"); + global->tracetype = TRACE_PLAIN; } + else + /* verbose is disabled here */ + global->tracetype = TRACE_NONE; break; - case C_VERSION: /* --version */ - if(toggle) /* --no-version yields no output! */ + case 'V': + if(toggle) { /* --no-version yields no output! */ err = PARAM_VERSION_INFO_REQUESTED; + break; + } break; - case C_WRITE_OUT: /* --write-out */ + + case 'w': /* get the output string */ if('@' == *nextarg) { - /* the data begins with a '@' letter, it means that a filename + /* the data begins with a '@' letter, it means that a file name or - (stdin) follows */ FILE *file; const char *fname; @@ -2577,57 +2578,69 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ warnf(global, "Failed to read %s", fname); } else - err = getstr(&config->writeout, nextarg, ALLOW_BLANK); + GetStr(&config->writeout, nextarg); break; - case C_PREPROXY: /* --preproxy */ - err = getstr(&config->preproxy, nextarg, DENY_BLANK); - break; - case C_PROXY: /* --proxy */ - /* --proxy */ - err = getstr(&config->proxy, nextarg, ALLOW_BLANK); - if(config->proxyver != CURLPROXY_HTTPS2) - config->proxyver = CURLPROXY_HTTP; + case 'x': + switch(subletter) { + case 'a': /* --preproxy */ + GetStr(&config->preproxy, nextarg); + break; + default: + /* --proxy */ + GetStr(&config->proxy, nextarg); + if(config->proxyver != CURLPROXY_HTTPS2) + config->proxyver = CURLPROXY_HTTP; + break; + } break; - case C_REQUEST: /* --request */ + case 'X': /* set custom request */ - err = getstr(&config->customrequest, nextarg, DENY_BLANK); + GetStr(&config->customrequest, nextarg); break; - case C_SPEED_TIME: /* --speed-time */ + case 'y': /* low speed time */ err = str2unum(&config->low_speed_time, nextarg); - if(!err && !config->low_speed_limit) + if(err) + break; + if(!config->low_speed_limit) config->low_speed_limit = 1; break; - case C_SPEED_LIMIT: /* --speed-limit */ + case 'Y': /* low speed limit */ err = str2unum(&config->low_speed_limit, nextarg); - if(!err && !config->low_speed_time) - config->low_speed_time = 30; - break; - case C_PARALLEL: /* --parallel */ - global->parallel = toggle; - break; - case C_PARALLEL_MAX: { /* --parallel-max */ - long val; - err = str2unum(&val, nextarg); if(err) break; - if(val > MAX_PARALLEL) - global->parallel_max = MAX_PARALLEL; - else if(val < 1) - global->parallel_max = PARALLEL_DEFAULT; - else - global->parallel_max = (unsigned short)val; + if(!config->low_speed_time) + config->low_speed_time = 30; break; - } - case C_PARALLEL_IMMEDIATE: /* --parallel-immediate */ - global->parallel_connect = toggle; + case 'Z': + switch(subletter) { + case '\0': /* --parallel */ + global->parallel = toggle; + break; + case 'b': { /* --parallel-max */ + long val; + err = str2unum(&val, nextarg); + if(err) + break; + if(val > MAX_PARALLEL) + global->parallel_max = MAX_PARALLEL; + else if(val < 1) + global->parallel_max = PARALLEL_DEFAULT; + else + global->parallel_max = (unsigned short)val; + break; + } + case 'c': /* --parallel-immediate */ + global->parallel_connect = toggle; + break; + } break; - case C_TIME_COND: /* --time-cond */ + case 'z': /* time condition coming up */ switch(*nextarg) { case '+': nextarg++; - FALLTHROUGH(); + /* FALLTHROUGH */ default: /* If-Modified-Since: (section 14.28 in RFC2068) */ config->timecond = CURL_TIMECOND_IFMODSINCE; @@ -2646,30 +2659,28 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ now = time(NULL); config->condtime = (curl_off_t)curl_getdate(nextarg, &now); if(-1 == config->condtime) { - /* now let's see if it is a filename to get the time from instead! */ - rc = getfiletime(nextarg, global, &value); + /* now let's see if it is a file name to get the time from instead! */ + curl_off_t filetime; + rc = getfiletime(nextarg, global, &filetime); if(!rc) /* pull the time out from the file */ - config->condtime = value; + config->condtime = filetime; else { /* failed, remove time condition */ config->timecond = CURL_TIMECOND_NONE; warnf(global, "Illegal date format for -z, --time-cond (and not " - "a filename). Disabling time condition. " + "a file name). Disabling time condition. " "See curl_getdate(3) for valid date syntax."); } } break; - case C_MPTCP: /* --mptcp */ - config->mptcp = TRUE; - break; default: /* unknown flag */ err = PARAM_OPTION_UNKNOWN; break; } - a = NULL; - ++nopts; /* processed one option from `flag` input, loop for more */ + hit = -1; + } while(!longopt && !singleopt && *++parse && !*usedarg && !err); error: @@ -2745,7 +2756,7 @@ ParameterError parse_args(struct GlobalConfig *global, int argc, } } else if(!result && passarg) - i++; /* we are supposed to skip this */ + i++; /* we're supposed to skip this */ } } else { @@ -2769,8 +2780,7 @@ ParameterError parse_args(struct GlobalConfig *global, int argc, if(result && result != PARAM_HELP_REQUESTED && result != PARAM_MANUAL_REQUESTED && result != PARAM_VERSION_INFO_REQUESTED && - result != PARAM_ENGINES_REQUESTED && - result != PARAM_CA_EMBED_REQUESTED) { + result != PARAM_ENGINES_REQUESTED) { const char *reason = param2text(result); if(orig_opt && strcmp(":", orig_opt)) diff --git a/contrib/libs/curl/src/tool_getparam.h b/contrib/libs/curl/src/tool_getparam.h index 9d6c72ef82..a8a9d45975 100644 --- a/contrib/libs/curl/src/tool_getparam.h +++ b/contrib/libs/curl/src/tool_getparam.h @@ -25,302 +25,6 @@ ***************************************************************************/ #include "tool_setup.h" -/* one enum for every command line option. The name is the verbatim long - option name, but in uppercase with periods and minuses replaced with - underscores using a "C_" prefix. */ -typedef enum { - C_ABSTRACT_UNIX_SOCKET, - C_ALPN, - C_ALT_SVC, - C_ANYAUTH, - C_APPEND, - C_AWS_SIGV4, - C_BASIC, - C_BUFFER, - C_CA_NATIVE, - C_CACERT, - C_CAPATH, - C_CERT, - C_CERT_STATUS, - C_CERT_TYPE, - C_CIPHERS, - C_CLOBBER, - C_COMPRESSED, - C_COMPRESSED_SSH, - C_CONFIG, - C_CONNECT_TIMEOUT, - C_CONNECT_TO, - C_CONTINUE_AT, - C_COOKIE, - C_COOKIE_JAR, - C_CREATE_DIRS, - C_CREATE_FILE_MODE, - C_CRLF, - C_CRLFILE, - C_CURVES, - C_DATA, - C_DATA_ASCII, - C_DATA_BINARY, - C_DATA_RAW, - C_DATA_URLENCODE, - C_DELEGATION, - C_DIGEST, - C_DISABLE, - C_DISABLE_EPRT, - C_DISABLE_EPSV, - C_DISALLOW_USERNAME_IN_URL, - C_DNS_INTERFACE, - C_DNS_IPV4_ADDR, - C_DNS_IPV6_ADDR, - C_DNS_SERVERS, - C_DOH_CERT_STATUS, - C_DOH_INSECURE, - C_DOH_URL, - C_DUMP_CA_EMBED, - C_DUMP_HEADER, - C_ECH, - C_EGD_FILE, - C_ENGINE, - C_EPRT, - C_EPSV, - C_ETAG_COMPARE, - C_ETAG_SAVE, - C_EXPECT100_TIMEOUT, - C_FAIL, - C_FAIL_EARLY, - C_FAIL_WITH_BODY, - C_FALSE_START, - C_FORM, - C_FORM_ESCAPE, - C_FORM_STRING, - C_FTP_ACCOUNT, - C_FTP_ALTERNATIVE_TO_USER, - C_FTP_CREATE_DIRS, - C_FTP_METHOD, - C_FTP_PASV, - C_FTP_PORT, - C_FTP_PRET, - C_FTP_SKIP_PASV_IP, - C_FTP_SSL, - C_FTP_SSL_CCC, - C_FTP_SSL_CCC_MODE, - C_FTP_SSL_CONTROL, - C_FTP_SSL_REQD, - C_GET, - C_GLOBOFF, - C_HAPPY_EYEBALLS_TIMEOUT_MS, - C_HAPROXY_CLIENTIP, - C_HAPROXY_PROTOCOL, - C_HEAD, - C_HEADER, - C_HELP, - C_HOSTPUBMD5, - C_HOSTPUBSHA256, - C_HSTS, - C_HTTP0_9, - C_HTTP1_0, - C_HTTP1_1, - C_HTTP2, - C_HTTP2_PRIOR_KNOWLEDGE, - C_HTTP3, - C_HTTP3_ONLY, - C_IGNORE_CONTENT_LENGTH, - C_INCLUDE, - C_INSECURE, - C_INTERFACE, - C_IPFS_GATEWAY, - C_IPV4, - C_IPV6, - C_JSON, - C_JUNK_SESSION_COOKIES, - C_KEEPALIVE, - C_KEEPALIVE_CNT, - C_KEEPALIVE_TIME, - C_KEY, - C_KEY_TYPE, - C_KRB, - C_KRB4, - C_LIBCURL, - C_LIMIT_RATE, - C_LIST_ONLY, - C_LOCAL_PORT, - C_LOCATION, - C_LOCATION_TRUSTED, - C_LOGIN_OPTIONS, - C_MAIL_AUTH, - C_MAIL_FROM, - C_MAIL_RCPT, - C_MAIL_RCPT_ALLOWFAILS, - C_MANUAL, - C_MAX_FILESIZE, - C_MAX_REDIRS, - C_MAX_TIME, - C_METALINK, - C_MPTCP, - C_NEGOTIATE, - C_NETRC, - C_NETRC_FILE, - C_NETRC_OPTIONAL, - C_NEXT, - C_NOPROXY, - C_NPN, - C_NTLM, - C_NTLM_WB, - C_OAUTH2_BEARER, - C_OUTPUT, - C_OUTPUT_DIR, - C_PARALLEL, - C_PARALLEL_IMMEDIATE, - C_PARALLEL_MAX, - C_PASS, - C_PATH_AS_IS, - C_PINNEDPUBKEY, - C_POST301, - C_POST302, - C_POST303, - C_PREPROXY, - C_PROGRESS_BAR, - C_PROGRESS_METER, - C_PROTO, - C_PROTO_DEFAULT, - C_PROTO_REDIR, - C_PROXY, - C_PROXY_ANYAUTH, - C_PROXY_BASIC, - C_PROXY_CA_NATIVE, - C_PROXY_CACERT, - C_PROXY_CAPATH, - C_PROXY_CERT, - C_PROXY_CERT_TYPE, - C_PROXY_CIPHERS, - C_PROXY_CRLFILE, - C_PROXY_DIGEST, - C_PROXY_HEADER, - C_PROXY_HTTP2, - C_PROXY_INSECURE, - C_PROXY_KEY, - C_PROXY_KEY_TYPE, - C_PROXY_NEGOTIATE, - C_PROXY_NTLM, - C_PROXY_PASS, - C_PROXY_PINNEDPUBKEY, - C_PROXY_SERVICE_NAME, - C_PROXY_SSL_ALLOW_BEAST, - C_PROXY_SSL_AUTO_CLIENT_CERT, - C_PROXY_TLS13_CIPHERS, - C_PROXY_TLSAUTHTYPE, - C_PROXY_TLSPASSWORD, - C_PROXY_TLSUSER, - C_PROXY_TLSV1, - C_PROXY_USER, - C_PROXY1_0, - C_PROXYTUNNEL, - C_PUBKEY, - C_QUOTE, - C_RANDOM_FILE, - C_RANGE, - C_RATE, - C_RAW, - C_REFERER, - C_REMOTE_HEADER_NAME, - C_REMOTE_NAME, - C_REMOTE_NAME_ALL, - C_REMOTE_TIME, - C_REMOVE_ON_ERROR, - C_REQUEST, - C_REQUEST_TARGET, - C_RESOLVE, - C_RETRY, - C_RETRY_ALL_ERRORS, - C_RETRY_CONNREFUSED, - C_RETRY_DELAY, - C_RETRY_MAX_TIME, - C_SASL_AUTHZID, - C_SASL_IR, - C_SERVICE_NAME, - C_SESSIONID, - C_SHOW_ERROR, - C_SHOW_HEADERS, - C_SILENT, - C_SKIP_EXISTING, - C_SOCKS4, - C_SOCKS4A, - C_SOCKS5, - C_SOCKS5_BASIC, - C_SOCKS5_GSSAPI, - C_SOCKS5_GSSAPI_NEC, - C_SOCKS5_GSSAPI_SERVICE, - C_SOCKS5_HOSTNAME, - C_SPEED_LIMIT, - C_SPEED_TIME, - C_SSL, - C_SSL_ALLOW_BEAST, - C_SSL_AUTO_CLIENT_CERT, - C_SSL_NO_REVOKE, - C_SSL_REQD, - C_SSL_REVOKE_BEST_EFFORT, - C_SSLV2, - C_SSLV3, - C_STDERR, - C_STYLED_OUTPUT, - C_SUPPRESS_CONNECT_HEADERS, - C_TCP_FASTOPEN, - C_TCP_NODELAY, - C_TELNET_OPTION, - C_TEST_EVENT, - C_TFTP_BLKSIZE, - C_TFTP_NO_OPTIONS, - C_TIME_COND, - C_TLS_MAX, - C_TLS13_CIPHERS, - C_TLSAUTHTYPE, - C_TLSPASSWORD, - C_TLSUSER, - C_TLSV1, - C_TLSV1_0, - C_TLSV1_1, - C_TLSV1_2, - C_TLSV1_3, - C_TR_ENCODING, - C_TRACE, - C_TRACE_ASCII, - C_TRACE_CONFIG, - C_TRACE_IDS, - C_TRACE_TIME, - C_IP_TOS, - C_UNIX_SOCKET, - C_UPLOAD_FILE, - C_URL, - C_URL_QUERY, - C_USE_ASCII, - C_USER, - C_USER_AGENT, - C_VARIABLE, - C_VERBOSE, - C_VERSION, - C_VLAN_PRIORITY, - C_WDEBUG, - C_WRITE_OUT, - C_XATTR -} cmdline_t; - -#define ARG_NONE 0 /* stand-alone but not a boolean */ -#define ARG_BOOL 1 /* accepts a --no-[name] prefix */ -#define ARG_STRG 2 /* requires an argument */ -#define ARG_FILE 3 /* requires an argument, usually a filename */ - -#define ARG_TYPEMASK 0x03 -#define ARGTYPE(x) ((x) & ARG_TYPEMASK) - -#define ARG_NO 0x80 /* set if the option is documented as --no-* */ - -struct LongShort { - const char *lname; /* long name option */ - unsigned char desc; /* type, see ARG_* */ - char letter; /* short name option or ' ' */ - unsigned short cmd; -}; - typedef enum { PARAM_OK = 0, PARAM_OPTION_AMBIGUOUS, @@ -331,7 +35,6 @@ typedef enum { PARAM_MANUAL_REQUESTED, PARAM_VERSION_INFO_REQUESTED, PARAM_ENGINES_REQUESTED, - PARAM_CA_EMBED_REQUESTED, PARAM_GOT_EXTRA_PARAMETER, PARAM_BAD_NUMERIC, PARAM_NEGATIVE_NUMERIC, @@ -346,16 +49,12 @@ typedef enum { PARAM_CONTDISP_RESUME_FROM, /* --continue-at and --remote-header-name */ PARAM_READ_ERROR, PARAM_EXPAND_ERROR, /* --expand problem */ - PARAM_BLANK_STRING, PARAM_LAST } ParameterError; struct GlobalConfig; struct OperationConfig; -const struct LongShort *findlongopt(const char *opt); -const struct LongShort *findshortopt(char letter); - ParameterError getparameter(const char *flag, char *nextarg, argv_item_t cleararg, bool *usedarg, diff --git a/contrib/libs/curl/src/tool_getpass.c b/contrib/libs/curl/src/tool_getpass.c index 1bc82584d2..b8f0b23c48 100644 --- a/contrib/libs/curl/src/tool_getpass.c +++ b/contrib/libs/curl/src/tool_getpass.c @@ -64,8 +64,8 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen) long sts; short chan; - /* MSK, 23-JAN-2004, iosbdef.h was not in VAX V7.2 or CC 6.4 */ - /* distribution so I created this. May revert back later to */ + /* MSK, 23-JAN-2004, iosbdef.h wasn't in VAX V7.2 or CC 6.4 */ + /* distribution so I created this. May revert back later to */ /* struct _iosb iosb; */ struct _iosb { @@ -115,7 +115,7 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen) } /* since echo is disabled, print a newline */ fputs("\n", tool_stderr); - /* if user did not hit ENTER, terminate buffer */ + /* if user didn't hit ENTER, terminate buffer */ if(i == buflen) buffer[buflen-1] = '\0'; @@ -146,15 +146,15 @@ static bool ttyecho(bool enable, int fd) #ifdef HAVE_TERMIOS_H tcgetattr(fd, &withecho); noecho = withecho; - noecho.c_lflag &= ~(tcflag_t)ECHO; + noecho.c_lflag &= ~ECHO; tcsetattr(fd, TCSANOW, &noecho); #elif defined(HAVE_TERMIO_H) ioctl(fd, TCGETA, &withecho); noecho = withecho; - noecho.c_lflag &= ~(tcflag_t)ECHO; + noecho.c_lflag &= ~ECHO; ioctl(fd, TCSETA, &noecho); #else - /* neither HAVE_TERMIO_H nor HAVE_TERMIOS_H, we cannot disable echo! */ + /* neither HAVE_TERMIO_H nor HAVE_TERMIOS_H, we can't disable echo! */ (void)fd; return FALSE; /* not disabled */ #endif @@ -180,7 +180,7 @@ char *getpass_r(const char *prompt, /* prompt to display */ bool disabled; int fd = open("/dev/tty", O_RDONLY); if(-1 == fd) - fd = STDIN_FILENO; /* use stdin if the tty could not be used */ + fd = STDIN_FILENO; /* use stdin if the tty couldn't be used */ disabled = ttyecho(FALSE, fd); /* disable terminal echo */ diff --git a/contrib/libs/curl/src/tool_getpass.h b/contrib/libs/curl/src/tool_getpass.h index 0a4d6d5a83..b93585d94d 100644 --- a/contrib/libs/curl/src/tool_getpass.h +++ b/contrib/libs/curl/src/tool_getpass.h @@ -26,7 +26,7 @@ #include "tool_setup.h" #ifndef HAVE_GETPASS_R -/* If there is a system-provided function named like this, we trust it is +/* If there's a system-provided function named like this, we trust it is also found in one of the standard headers. */ /* diff --git a/contrib/libs/curl/src/tool_help.c b/contrib/libs/curl/src/tool_help.c index 8c655c4b2b..c8aea295d5 100644 --- a/contrib/libs/curl/src/tool_help.c +++ b/contrib/libs/curl/src/tool_help.c @@ -22,17 +22,14 @@ * ***************************************************************************/ #include "tool_setup.h" - +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" #include "tool_help.h" #include "tool_libinfo.h" #include "tool_util.h" #include "tool_version.h" -#include "tool_cb_prg.h" -#include "tool_hugehelp.h" -#include "tool_getparam.h" -#include "terminal.h" #include "memdebug.h" /* keep this as LAST include */ @@ -40,46 +37,44 @@ # define USE_WATT32 #endif -#ifndef ARRAYSIZE -#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) -#endif - struct category_descriptors { const char *opt; const char *desc; - unsigned int category; + curlhelp_t category; }; static const struct category_descriptors categories[] = { - /* important is left out because it is the default help page */ - {"auth", "Authentication methods", CURLHELP_AUTH}, - {"connection", "Manage connections", CURLHELP_CONNECTION}, + {"auth", "Different types of authentication methods", CURLHELP_AUTH}, + {"connection", "Low level networking operations", + CURLHELP_CONNECTION}, {"curl", "The command line tool itself", CURLHELP_CURL}, - {"deprecated", "Legacy", CURLHELP_DEPRECATED}, - {"dns", "Names and resolving", CURLHELP_DNS}, - {"file", "FILE protocol", CURLHELP_FILE}, - {"ftp", "FTP protocol", CURLHELP_FTP}, - {"global", "Global options", CURLHELP_GLOBAL}, - {"http", "HTTP and HTTPS protocol", CURLHELP_HTTP}, - {"imap", "IMAP protocol", CURLHELP_IMAP}, - {"ldap", "LDAP protocol", CURLHELP_LDAP}, + {"dns", "General DNS options", CURLHELP_DNS}, + {"file", "FILE protocol options", CURLHELP_FILE}, + {"ftp", "FTP protocol options", CURLHELP_FTP}, + {"http", "HTTP and HTTPS protocol options", CURLHELP_HTTP}, + {"imap", "IMAP protocol options", CURLHELP_IMAP}, + /* important is left out because it is the default help page */ + {"misc", "Options that don't fit into any other category", CURLHELP_MISC}, {"output", "Filesystem output", CURLHELP_OUTPUT}, - {"pop3", "POP3 protocol", CURLHELP_POP3}, - {"post", "HTTP POST specific", CURLHELP_POST}, - {"proxy", "Options for proxies", CURLHELP_PROXY}, - {"scp", "SCP protocol", CURLHELP_SCP}, - {"sftp", "SFTP protocol", CURLHELP_SFTP}, - {"smtp", "SMTP protocol", CURLHELP_SMTP}, - {"ssh", "SSH protocol", CURLHELP_SSH}, - {"telnet", "TELNET protocol", CURLHELP_TELNET}, - {"tftp", "TFTP protocol", CURLHELP_TFTP}, - {"timeout", "Timeouts and delays", CURLHELP_TIMEOUT}, - {"tls", "TLS/SSL related", CURLHELP_TLS}, - {"upload", "Upload, sending data", CURLHELP_UPLOAD}, - {"verbose", "Tracing, logging etc", CURLHELP_VERBOSE} + {"pop3", "POP3 protocol options", CURLHELP_POP3}, + {"post", "HTTP Post specific options", CURLHELP_POST}, + {"proxy", "All options related to proxies", CURLHELP_PROXY}, + {"scp", "SCP protocol options", CURLHELP_SCP}, + {"sftp", "SFTP protocol options", CURLHELP_SFTP}, + {"smtp", "SMTP protocol options", CURLHELP_SMTP}, + {"ssh", "SSH protocol options", CURLHELP_SSH}, + {"telnet", "TELNET protocol options", CURLHELP_TELNET}, + {"tftp", "TFTP protocol options", CURLHELP_TFTP}, + {"tls", "All TLS/SSL related options", CURLHELP_TLS}, + {"upload", "All options for uploads", + CURLHELP_UPLOAD}, + {"verbose", "Options related to any kind of command line output of curl", + CURLHELP_VERBOSE}, + {NULL, NULL, CURLHELP_HIDDEN} }; -static void print_category(unsigned int category, unsigned int cols) + +static void print_category(curlhelp_t category) { unsigned int i; size_t longopt = 5; @@ -96,31 +91,23 @@ static void print_category(unsigned int category, unsigned int cols) if(len > longdesc) longdesc = len; } - if(longopt + longdesc > cols) - longopt = cols - longdesc; + if(longopt + longdesc > 80) + longopt = 80 - longdesc; for(i = 0; helptext[i].opt; ++i) if(helptext[i].categories & category) { - size_t opt = longopt; - size_t desclen = strlen(helptext[i].desc); - if(opt + desclen >= (cols - 2)) { - if(desclen < (cols - 2)) - opt = (cols - 3) - desclen; - else - opt = 0; - } - printf(" %-*s %s\n", (int)opt, helptext[i].opt, helptext[i].desc); + printf(" %-*s %s\n", (int)longopt, helptext[i].opt, helptext[i].desc); } } /* Prints category if found. If not, it returns 1 */ -static int get_category_content(const char *category, unsigned int cols) +static int get_category_content(const char *category) { unsigned int i; - for(i = 0; i < ARRAYSIZE(categories); ++i) + for(i = 0; categories[i].opt; ++i) if(curl_strequal(categories[i].opt, category)) { printf("%s: %s\n", categories[i].opt, categories[i].desc); - print_category(categories[i].category, cols); + print_category(categories[i].category); return 0; } return 1; @@ -130,178 +117,33 @@ static int get_category_content(const char *category, unsigned int cols) static void get_categories(void) { unsigned int i; - for(i = 0; i < ARRAYSIZE(categories); ++i) + for(i = 0; categories[i].opt; ++i) printf(" %-11s %s\n", categories[i].opt, categories[i].desc); } -/* Prints all categories as a comma-separated list of given width */ -static void get_categories_list(unsigned int width) -{ - unsigned int i; - size_t col = 0; - for(i = 0; i < ARRAYSIZE(categories); ++i) { - size_t len = strlen(categories[i].opt); - if(i == ARRAYSIZE(categories) - 1) { - /* final category */ - if(col + len + 1 < width) - printf("%s.\n", categories[i].opt); - else - /* start a new line first */ - printf("\n%s.\n", categories[i].opt); - } - else if(col + len + 2 < width) { - printf("%s, ", categories[i].opt); - col += len + 2; - } - else { - /* start a new line first */ - printf("\n%s, ", categories[i].opt); - col = len + 2; - } - } -} - -#ifdef USE_MANUAL - -void inithelpscan(struct scan_ctx *ctx, - const char *trigger, - const char *arg, - const char *endarg) -{ - ctx->trigger = trigger; - ctx->tlen = strlen(trigger); - ctx->arg = arg; - ctx->flen = strlen(arg); - ctx->endarg = endarg; - ctx->elen = strlen(endarg); - DEBUGASSERT((ctx->elen < sizeof(ctx->rbuf)) || - (ctx->flen < sizeof(ctx->rbuf))); - ctx->show = 0; - ctx->olen = 0; - memset(ctx->rbuf, 0, sizeof(ctx->rbuf)); -} - -bool helpscan(unsigned char *buf, size_t len, struct scan_ctx *ctx) -{ - size_t i; - for(i = 0; i < len; i++) { - if(!ctx->show) { - /* wait for the trigger */ - memmove(&ctx->rbuf[0], &ctx->rbuf[1], ctx->tlen - 1); - ctx->rbuf[ctx->tlen - 1] = buf[i]; - if(!memcmp(ctx->rbuf, ctx->trigger, ctx->tlen)) - ctx->show++; - continue; - } - /* past the trigger */ - if(ctx->show == 1) { - memmove(&ctx->rbuf[0], &ctx->rbuf[1], ctx->flen - 1); - ctx->rbuf[ctx->flen - 1] = buf[i]; - if(!memcmp(ctx->rbuf, ctx->arg, ctx->flen)) { - /* match, now output until endarg */ - fputs(&ctx->arg[1], stdout); - ctx->show++; - } - continue; - } - /* show until the end */ - memmove(&ctx->rbuf[0], &ctx->rbuf[1], ctx->elen - 1); - ctx->rbuf[ctx->elen - 1] = buf[i]; - if(!memcmp(ctx->rbuf, ctx->endarg, ctx->elen)) - return FALSE; - - if(buf[i] == '\n') { - DEBUGASSERT(ctx->olen < sizeof(ctx->obuf)); - if(ctx->olen == sizeof(ctx->obuf)) - return FALSE; /* bail out */ - ctx->obuf[ctx->olen++] = 0; - ctx->olen = 0; - puts(ctx->obuf); - } - else { - DEBUGASSERT(ctx->olen < sizeof(ctx->obuf)); - if(ctx->olen == sizeof(ctx->obuf)) - return FALSE; /* bail out */ - ctx->obuf[ctx->olen++] = buf[i]; - } - } - return TRUE; -} - -#endif void tool_help(char *category) { - unsigned int cols = get_terminal_columns(); + puts("Usage: curl [options...] <url>"); /* If no category was provided */ if(!category) { - const char *category_note = "\nThis is not the full help; this " - "menu is split into categories.\nUse \"--help category\" to get " - "an overview of all categories, which are:"; - const char *category_note2 = - "Use \"--help all\" to list all options" -#ifdef USE_MANUAL - "\nUse \"--help [option]\" to view documentation for a given option" -#endif - ; - puts("Usage: curl [options...] <url>"); - print_category(CURLHELP_IMPORTANT, cols); + const char *category_note = "\nThis is not the full help, this " + "menu is stripped into categories.\nUse \"--help category\" to get " + "an overview of all categories.\nFor all options use the manual" + " or \"--help all\"."; + print_category(CURLHELP_IMPORTANT); puts(category_note); - get_categories_list(cols); - puts(category_note2); } /* Lets print everything if "all" was provided */ else if(curl_strequal(category, "all")) - /* Print everything */ - print_category(CURLHELP_ALL, cols); + /* Print everything except hidden */ + print_category(~(CURLHELP_HIDDEN)); /* Lets handle the string "category" differently to not print an errormsg */ else if(curl_strequal(category, "category")) get_categories(); - else if(category[0] == '-') { -#ifdef USE_MANUAL - /* command line option help */ - const struct LongShort *a = NULL; - if(category[1] == '-') { - char *lookup = &category[2]; - bool noflagged = FALSE; - if(!strncmp(lookup, "no-", 3)) { - lookup += 3; - noflagged = TRUE; - } - a = findlongopt(lookup); - if(a && noflagged && (ARGTYPE(a->desc) != ARG_BOOL)) - /* a --no- prefix for a non-boolean is not specifying a proper - option */ - a = NULL; - } - else if(!category[2]) - a = findshortopt(category[1]); - if(!a) { - fprintf(tool_stderr, "Incorrect option name to show help for," - " see curl -h\n"); - } - else { - char cmdbuf[80]; - if(a->letter != ' ') - msnprintf(cmdbuf, sizeof(cmdbuf), "\n -%c, --", a->letter); - else if(a->desc & ARG_NO) - msnprintf(cmdbuf, sizeof(cmdbuf), "\n --no-%s", a->lname); - else - msnprintf(cmdbuf, sizeof(cmdbuf), "\n %s", category); - if(a->cmd == C_XATTR) - /* this is the last option, which then ends when FILES starts */ - showhelp("\nALL OPTIONS\n", cmdbuf, "\nFILES"); - else - showhelp("\nALL OPTIONS\n", cmdbuf, "\n -"); - } -#else - fprintf(tool_stderr, "Cannot comply. " - "This curl was built without built-in manual\n"); -#endif - } /* Otherwise print category and handle the case if the cat was not found */ - else if(get_category_content(category, cols)) { - puts("Unknown category provided, here is a list of all categories:\n"); + else if(get_category_content(category)) { + puts("Invalid category provided, here is a list of all categories:\n"); get_categories(); } free(category); @@ -331,56 +173,20 @@ void tool_version_info(void) printf("Release-Date: %s\n", LIBCURL_TIMESTAMP); #endif if(built_in_protos[0]) { - const char *insert = NULL; - /* we have ipfs and ipns support if libcurl has http support */ - for(builtin = built_in_protos; *builtin; ++builtin) { - if(insert) { - /* update insertion so ipfs will be printed in alphabetical order */ - if(strcmp(*builtin, "ipfs") < 0) - insert = *builtin; - else - break; - } - else if(!strcmp(*builtin, "http")) { - insert = *builtin; - } - } printf("Protocols:"); for(builtin = built_in_protos; *builtin; ++builtin) { /* Special case: do not list rtmp?* protocols. They may only appear together with "rtmp" */ if(!curl_strnequal(*builtin, "rtmp", 4) || !builtin[0][4]) printf(" %s", *builtin); - if(insert && insert == *builtin) { - printf(" ipfs ipns"); - insert = NULL; - } } puts(""); /* newline */ } if(feature_names[0]) { - const char **feat_ext; - size_t feat_ext_count = feature_count; -#ifdef CURL_CA_EMBED - ++feat_ext_count; -#endif - feat_ext = malloc(sizeof(*feature_names) * (feat_ext_count + 1)); - if(feat_ext) { - memcpy((void *)feat_ext, feature_names, - sizeof(*feature_names) * feature_count); - feat_ext_count = feature_count; -#ifdef CURL_CA_EMBED - feat_ext[feat_ext_count++] = "CAcert"; -#endif - feat_ext[feat_ext_count] = NULL; - qsort((void *)feat_ext, feat_ext_count, sizeof(*feat_ext), - struplocompare4sort); - printf("Features:"); - for(builtin = feat_ext; *builtin; ++builtin) - printf(" %s", *builtin); - puts(""); /* newline */ - free((void *)feat_ext); - } + printf("Features:"); + for(builtin = feature_names; *builtin; ++builtin) + printf(" %s", *builtin); + puts(""); /* newline */ } if(strcmp(CURL_VERSION, curlinfo->version)) { printf("WARNING: curl and libcurl versions do not match. " diff --git a/contrib/libs/curl/src/tool_help.h b/contrib/libs/curl/src/tool_help.h index 4b40715375..a7906266e3 100644 --- a/contrib/libs/curl/src/tool_help.h +++ b/contrib/libs/curl/src/tool_help.h @@ -28,65 +28,47 @@ void tool_help(char *category); void tool_list_engines(void); void tool_version_info(void); -struct scan_ctx { - const char *trigger; - size_t tlen; - const char *arg; - size_t flen; - const char *endarg; - size_t elen; - size_t olen; - char rbuf[40]; - char obuf[160]; - unsigned char show; /* start as at 0. - trigger match moves it to 1 - arg match moves it to 2 - endarg stops the search */ -}; -void inithelpscan(struct scan_ctx *ctx, const char *trigger, - const char *arg, const char *endarg); -bool helpscan(unsigned char *buf, size_t len, struct scan_ctx *ctx); + +typedef unsigned int curlhelp_t; struct helptxt { const char *opt; const char *desc; - unsigned int categories; + curlhelp_t categories; }; /* * The bitmask output is generated with the following command ------------------------------------------------------------ - make -C docs/cmdline-opts listcats + cd $srcroot/docs/cmdline-opts + ./gen.pl listcats *.d */ -#define CURLHELP_AUTH (1u << 0u) -#define CURLHELP_CONNECTION (1u << 1u) -#define CURLHELP_CURL (1u << 2u) -#define CURLHELP_DEPRECATED (1u << 3u) -#define CURLHELP_DNS (1u << 4u) -#define CURLHELP_FILE (1u << 5u) -#define CURLHELP_FTP (1u << 6u) -#define CURLHELP_GLOBAL (1u << 7u) -#define CURLHELP_HTTP (1u << 8u) -#define CURLHELP_IMAP (1u << 9u) -#define CURLHELP_IMPORTANT (1u << 10u) -#define CURLHELP_LDAP (1u << 11u) -#define CURLHELP_OUTPUT (1u << 12u) -#define CURLHELP_POP3 (1u << 13u) -#define CURLHELP_POST (1u << 14u) -#define CURLHELP_PROXY (1u << 15u) -#define CURLHELP_SCP (1u << 16u) -#define CURLHELP_SFTP (1u << 17u) -#define CURLHELP_SMTP (1u << 18u) -#define CURLHELP_SSH (1u << 19u) -#define CURLHELP_TELNET (1u << 20u) -#define CURLHELP_TFTP (1u << 21u) -#define CURLHELP_TIMEOUT (1u << 22u) -#define CURLHELP_TLS (1u << 23u) -#define CURLHELP_UPLOAD (1u << 24u) -#define CURLHELP_VERBOSE (1u << 25u) - -#define CURLHELP_ALL (0xfffffffu) +#define CURLHELP_HIDDEN 1u << 0u +#define CURLHELP_AUTH 1u << 1u +#define CURLHELP_CONNECTION 1u << 2u +#define CURLHELP_CURL 1u << 3u +#define CURLHELP_DNS 1u << 4u +#define CURLHELP_FILE 1u << 5u +#define CURLHELP_FTP 1u << 6u +#define CURLHELP_HTTP 1u << 7u +#define CURLHELP_IMAP 1u << 8u +#define CURLHELP_IMPORTANT 1u << 9u +#define CURLHELP_IPFS 1u << 10u +#define CURLHELP_MISC 1u << 11u +#define CURLHELP_OUTPUT 1u << 12u +#define CURLHELP_POP3 1u << 13u +#define CURLHELP_POST 1u << 14u +#define CURLHELP_PROXY 1u << 15u +#define CURLHELP_SCP 1u << 16u +#define CURLHELP_SFTP 1u << 17u +#define CURLHELP_SMTP 1u << 18u +#define CURLHELP_SSH 1u << 19u +#define CURLHELP_TELNET 1u << 20u +#define CURLHELP_TFTP 1u << 21u +#define CURLHELP_TLS 1u << 22u +#define CURLHELP_UPLOAD 1u << 23u +#define CURLHELP_VERBOSE 1u << 24u extern const struct helptxt helptext[]; diff --git a/contrib/libs/curl/src/tool_helpers.c b/contrib/libs/curl/src/tool_helpers.c index 2e15144b7b..854bf777a0 100644 --- a/contrib/libs/curl/src/tool_helpers.c +++ b/contrib/libs/curl/src/tool_helpers.c @@ -25,6 +25,8 @@ #include "strcase.h" +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" @@ -38,8 +40,9 @@ ** Helper functions that are used from more than one source file. */ -const char *param2text(ParameterError error) +const char *param2text(int res) { + ParameterError error = (ParameterError)res; switch(error) { case PARAM_GOT_EXTRA_PARAMETER: return "had unsupported trailing garbage"; @@ -56,17 +59,17 @@ const char *param2text(ParameterError error) case PARAM_NEGATIVE_NUMERIC: return "expected a positive numerical parameter"; case PARAM_LIBCURL_DOESNT_SUPPORT: - return "the installed libcurl version does not support this"; + return "the installed libcurl version doesn't support this"; case PARAM_LIBCURL_UNSUPPORTED_PROTOCOL: return "a specified protocol is unsupported by libcurl"; case PARAM_NO_MEM: return "out of memory"; case PARAM_NO_PREFIX: - return "the given option cannot be reversed with a --no- prefix"; + return "the given option can't be reversed with a --no- prefix"; case PARAM_NUMBER_TOO_LARGE: return "too large number"; case PARAM_NO_NOT_BOOLEAN: - return "used '--no-' for option that is not a boolean"; + return "used '--no-' for option that isn't a boolean"; case PARAM_CONTDISP_SHOW_HEADER: return "showing headers and --remote-header-name cannot be combined"; case PARAM_CONTDISP_RESUME_FROM: @@ -75,8 +78,6 @@ const char *param2text(ParameterError error) return "error encountered when reading a file"; case PARAM_EXPAND_ERROR: return "variable expansion failure"; - case PARAM_BLANK_STRING: - return "blank argument where content is expected"; default: return "unknown error"; } @@ -94,7 +95,7 @@ int SetHTTPrequest(struct OperationConfig *config, HttpReq req, HttpReq *store) "PUT (-T, --upload-file)" }; - if((*store == TOOL_HTTPREQ_UNSPEC) || + if((*store == HTTPREQ_UNSPEC) || (*store == req)) { *store = req; return 0; diff --git a/contrib/libs/curl/src/tool_helpers.h b/contrib/libs/curl/src/tool_helpers.h index dd085e2cc7..2cfbad21a3 100644 --- a/contrib/libs/curl/src/tool_helpers.h +++ b/contrib/libs/curl/src/tool_helpers.h @@ -25,7 +25,7 @@ ***************************************************************************/ #include "tool_setup.h" -const char *param2text(ParameterError error); +const char *param2text(int res); int SetHTTPrequest(struct OperationConfig *config, HttpReq req, HttpReq *store); diff --git a/contrib/libs/curl/src/tool_hugehelp.h b/contrib/libs/curl/src/tool_hugehelp.h index f00f88702b..ce9af0c545 100644 --- a/contrib/libs/curl/src/tool_hugehelp.h +++ b/contrib/libs/curl/src/tool_hugehelp.h @@ -25,8 +25,6 @@ ***************************************************************************/ #include "tool_setup.h" -void showhelp(const char *trigger, const char *arg, const char *endarg); - #ifdef USE_MANUAL void hugehelp(void); #else diff --git a/contrib/libs/curl/src/tool_ipfs.c b/contrib/libs/curl/src/tool_ipfs.c index 09bff49067..435d1697ce 100644 --- a/contrib/libs/curl/src/tool_ipfs.c +++ b/contrib/libs/curl/src/tool_ipfs.c @@ -23,6 +23,8 @@ ***************************************************************************/ #include "tool_setup.h" +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" #include "dynbuf.h" @@ -63,7 +65,7 @@ static char *ipfs_gateway(void) char *ipfs_path = NULL; char *gateway_composed_file_path = NULL; FILE *gateway_file = NULL; - char *gateway = curl_getenv("IPFS_GATEWAY"); + char *gateway = curlx_getenv("IPFS_GATEWAY"); /* Gateway is found from environment variable. */ if(gateway) { @@ -73,13 +75,15 @@ static char *ipfs_gateway(void) } /* Try to find the gateway in the IPFS data folder. */ - ipfs_path = curl_getenv("IPFS_PATH"); + ipfs_path = curlx_getenv("IPFS_PATH"); if(!ipfs_path) { - char *home = getenv("HOME"); + char *home = curlx_getenv("HOME"); if(home && *home) ipfs_path = aprintf("%s/.ipfs/", home); - /* fallback to "~/.ipfs", as that is the default location. */ + /* fallback to "~/.ipfs", as that's the default location. */ + + Curl_safefree(home); } if(!ipfs_path || ensure_trailing_slash(&ipfs_path)) @@ -130,7 +134,7 @@ fail: } /* - * Rewrite ipfs://<cid> and ipns://<cid> to an HTTP(S) + * Rewrite ipfs://<cid> and ipns://<cid> to a HTTP(S) * URL that can be handled by an IPFS gateway. */ CURLcode ipfs_url_rewrite(CURLU *uh, const char *protocol, char **url, @@ -160,7 +164,7 @@ CURLcode ipfs_url_rewrite(CURLU *uh, const char *protocol, char **url, goto clean; /* We might have a --ipfs-gateway argument. Check it first and use it. Error - * if we do have something but if it is an invalid url. + * if we do have something but if it's an invalid url. */ if(config->ipfs_gateway) { /* ensure the gateway ends in a trailing / */ @@ -271,19 +275,22 @@ clean: curl_free(pathbuffer); curl_url_cleanup(gatewayurl); { + const char *msg = NULL; switch(result) { case CURLE_URL_MALFORMAT: - helpf(tool_stderr, "malformed target URL"); + msg = "malformed target URL"; break; case CURLE_FILE_COULDNT_READ_FILE: - helpf(tool_stderr, "IPFS automatic gateway detection failed"); + msg = "IPFS automatic gateway detection failed"; break; case CURLE_BAD_FUNCTION_ARGUMENT: - helpf(tool_stderr, "--ipfs-gateway was given a malformed URL"); + msg = "--ipfs-gateway was given a malformed URL"; break; default: break; } + if(msg) + helpf(tool_stderr, msg); } return result; } diff --git a/contrib/libs/curl/src/tool_libinfo.c b/contrib/libs/curl/src/tool_libinfo.c index 4bc22217f9..0bf3a90bf2 100644 --- a/contrib/libs/curl/src/tool_libinfo.c +++ b/contrib/libs/curl/src/tool_libinfo.c @@ -25,13 +25,15 @@ #include "strcase.h" +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" #include "tool_libinfo.h" #include "memdebug.h" /* keep this as LAST include */ -/* global variable definitions, for libcurl runtime info */ +/* global variable definitions, for libcurl run-time info */ static const char *no_protos = NULL; @@ -122,11 +124,10 @@ static struct feature_name_presentp { static const char *fnames[sizeof(maybe_feature) / sizeof(maybe_feature[0])]; const char * const *feature_names = fnames; -size_t feature_count; /* - * libcurl_info_init: retrieves runtime information about libcurl, - * setting a global pointer 'curlinfo' to libcurl's runtime info + * libcurl_info_init: retrieves run-time information about libcurl, + * setting a global pointer 'curlinfo' to libcurl's run-time info * struct, count protocols and flag those we are interested in. * Global pointer feature_names is set to the feature names array. If * the latter is not returned by curl_version_info(), it is built from @@ -138,7 +139,7 @@ CURLcode get_libcurl_info(void) CURLcode result = CURLE_OK; const char *const *builtin; - /* Pointer to libcurl's runtime version information */ + /* Pointer to libcurl's run-time version information */ curlinfo = curl_version_info(CURLVERSION_NOW); if(!curlinfo) return CURLE_FAILED_INIT; @@ -181,7 +182,6 @@ CURLcode get_libcurl_info(void) *p->feature_presentp = TRUE; break; } - ++feature_count; } return CURLE_OK; diff --git a/contrib/libs/curl/src/tool_libinfo.h b/contrib/libs/curl/src/tool_libinfo.h index ad9c195dc0..46063ad1be 100644 --- a/contrib/libs/curl/src/tool_libinfo.h +++ b/contrib/libs/curl/src/tool_libinfo.h @@ -25,7 +25,7 @@ ***************************************************************************/ #include "tool_setup.h" -/* global variable declarations, for libcurl runtime info */ +/* global variable declarations, for libcurl run-time info */ extern curl_version_info_data *curlinfo; @@ -34,7 +34,6 @@ extern const char * const *built_in_protos; extern size_t proto_count; extern const char * const *feature_names; -extern size_t feature_count; extern const char *proto_file; extern const char *proto_ftp; diff --git a/contrib/libs/curl/src/tool_listhelp.c b/contrib/libs/curl/src/tool_listhelp.c index fa29a51c1f..4e7a6dd632 100644 --- a/contrib/libs/curl/src/tool_listhelp.c +++ b/contrib/libs/curl/src/tool_listhelp.c @@ -26,17 +26,17 @@ /* * DO NOT edit tool_listhelp.c manually. - * This source file is generated with the following command in an autotools - * build: - * - * "make listhelp" + * This source file is generated with the following command: + + cd $srcroot/docs/cmdline-opts + ./gen.pl listhelp *.d > $srcroot/src/tool_listhelp.c */ const struct helptxt helptext[] = { {" --abstract-unix-socket <path>", "Connect via abstract Unix domain socket", CURLHELP_CONNECTION}, - {" --alt-svc <filename>", + {" --alt-svc <file name>", "Enable alt-svc with this cache file", CURLHELP_HTTP}, {" --anyauth", @@ -45,14 +45,14 @@ const struct helptxt helptext[] = { {"-a, --append", "Append to target file when uploading", CURLHELP_FTP | CURLHELP_SFTP}, - {" --aws-sigv4 <provider1[:prvdr2[:reg[:srv]]]>", - "AWS V4 signature auth", + {" --aws-sigv4 <provider1[:provider2[:region[:service]]]>", + "Use AWS V4 signature authentication", CURLHELP_AUTH | CURLHELP_HTTP}, {" --basic", - "HTTP Basic Authentication", + "Use HTTP Basic Authentication", CURLHELP_AUTH}, {" --ca-native", - "Load CA certs from the OS", + "Use CA certificates from the native OS", CURLHELP_TLS}, {" --cacert <file>", "CA certificate to verify peer against", @@ -64,13 +64,13 @@ const struct helptxt helptext[] = { "Client certificate file and password", CURLHELP_TLS}, {" --cert-status", - "Verify server cert status OCSP-staple", + "Verify the status of the server cert via OCSP-staple", CURLHELP_TLS}, {" --cert-type <type>", "Certificate type (DER/PEM/ENG/P12)", CURLHELP_TLS}, - {" --ciphers <list>", - "TLS 1.2 (1.1, 1.0) ciphers to use", + {" --ciphers <list of ciphers>", + "SSL ciphers to use", CURLHELP_TLS}, {" --compressed", "Request compressed response", @@ -81,24 +81,24 @@ const struct helptxt helptext[] = { {"-K, --config <file>", "Read config from a file", CURLHELP_CURL}, - {" --connect-timeout <seconds>", - "Maximum time allowed to connect", - CURLHELP_CONNECTION | CURLHELP_TIMEOUT}, + {" --connect-timeout <fractional seconds>", + "Maximum time allowed for connection", + CURLHELP_CONNECTION}, {" --connect-to <HOST1:PORT1:HOST2:PORT2>", - "Connect to host2 instead of host1", - CURLHELP_CONNECTION | CURLHELP_DNS}, + "Connect to host", + CURLHELP_CONNECTION}, {"-C, --continue-at <offset>", "Resumed transfer offset", CURLHELP_CONNECTION}, {"-b, --cookie <data|filename>", - "Send cookies from string/load from file", + "Send cookies from string/file", CURLHELP_HTTP}, {"-c, --cookie-jar <filename>", - "Save cookies to <filename> after operation", + "Write cookies to <filename> after operation", CURLHELP_HTTP}, {" --create-dirs", "Create necessary local directory hierarchy", - CURLHELP_OUTPUT}, + CURLHELP_CURL}, {" --create-file-mode <mode>", "File mode for created files", CURLHELP_SFTP | CURLHELP_SCP | CURLHELP_FILE | CURLHELP_UPLOAD}, @@ -106,10 +106,10 @@ const struct helptxt helptext[] = { "Convert LF to CRLF in upload", CURLHELP_FTP | CURLHELP_SMTP}, {" --crlfile <file>", - "Certificate Revocation list", + "Use this CRL list", CURLHELP_TLS}, - {" --curves <list>", - "(EC) TLS key exchange algorithms to request", + {" --curves <algorithm list>", + "(EC) TLS key exchange algorithm(s) to request", CURLHELP_TLS}, {"-d, --data <data>", "HTTP POST data", @@ -130,7 +130,7 @@ const struct helptxt helptext[] = { "GSS-API delegation permission", CURLHELP_AUTH}, {" --digest", - "HTTP Digest Authentication", + "Use HTTP Digest Authentication", CURLHELP_PROXY | CURLHELP_AUTH | CURLHELP_HTTP}, {"-q, --disable", "Disable .curlrc", @@ -143,7 +143,7 @@ const struct helptxt helptext[] = { CURLHELP_FTP}, {" --disallow-username-in-url", "Disallow username in URL", - CURLHELP_CURL}, + CURLHELP_CURL | CURLHELP_HTTP}, {" --dns-interface <interface>", "Interface to use for DNS requests", CURLHELP_DNS}, @@ -157,44 +157,38 @@ const struct helptxt helptext[] = { "DNS server addrs to use", CURLHELP_DNS}, {" --doh-cert-status", - "Verify DoH server cert status OCSP-staple", + "Verify the status of the DoH server cert via OCSP-staple", CURLHELP_DNS | CURLHELP_TLS}, {" --doh-insecure", "Allow insecure DoH server connections", CURLHELP_DNS | CURLHELP_TLS}, {" --doh-url <URL>", - "Resolve hostnames over DoH", + "Resolve host names over DoH", CURLHELP_DNS}, - {" --dump-ca-embed", - "Write the embedded CA bundle to standard output", - CURLHELP_HTTP | CURLHELP_PROXY | CURLHELP_TLS}, {"-D, --dump-header <filename>", "Write the received headers to <filename>", CURLHELP_HTTP | CURLHELP_FTP}, - {" --ech <config>", - "Configure ECH", - CURLHELP_TLS}, {" --egd-file <file>", "EGD socket path for random data", - CURLHELP_DEPRECATED}, + CURLHELP_TLS}, {" --engine <name>", "Crypto engine to use", CURLHELP_TLS}, {" --etag-compare <file>", - "Load ETag from file", + "Pass an ETag from a file as a custom header", CURLHELP_HTTP}, {" --etag-save <file>", - "Parse incoming ETag and save to a file", + "Parse ETag from a request and save it to a file", CURLHELP_HTTP}, {" --expect100-timeout <seconds>", "How long to wait for 100-continue", - CURLHELP_HTTP | CURLHELP_TIMEOUT}, + CURLHELP_HTTP}, {"-f, --fail", "Fail fast with no output on HTTP errors", CURLHELP_IMPORTANT | CURLHELP_HTTP}, {" --fail-early", - "Fail on first transfer error", - CURLHELP_CURL | CURLHELP_GLOBAL}, + "Fail on first transfer error, do not continue", + CURLHELP_CURL}, {" --fail-with-body", "Fail on HTTP errors but save the body", CURLHELP_HTTP | CURLHELP_OUTPUT}, @@ -203,15 +197,13 @@ const struct helptxt helptext[] = { CURLHELP_TLS}, {"-F, --form <name=content>", "Specify multipart MIME data", - CURLHELP_HTTP | CURLHELP_UPLOAD | CURLHELP_POST | CURLHELP_IMAP | - CURLHELP_SMTP}, + CURLHELP_HTTP | CURLHELP_UPLOAD}, {" --form-escape", - "Escape form fields using backslash", - CURLHELP_HTTP | CURLHELP_UPLOAD | CURLHELP_POST}, + "Escape multipart form field/file names using backslash", + CURLHELP_HTTP | CURLHELP_UPLOAD}, {" --form-string <name=string>", "Specify multipart MIME data", - CURLHELP_HTTP | CURLHELP_UPLOAD | CURLHELP_POST | CURLHELP_SMTP | - CURLHELP_IMAP}, + CURLHELP_HTTP | CURLHELP_UPLOAD}, {" --ftp-account <data>", "Account data string", CURLHELP_FTP | CURLHELP_AUTH}, @@ -220,15 +212,15 @@ const struct helptxt helptext[] = { CURLHELP_FTP}, {" --ftp-create-dirs", "Create the remote dirs if not present", - CURLHELP_FTP | CURLHELP_SFTP}, + CURLHELP_FTP | CURLHELP_SFTP | CURLHELP_CURL}, {" --ftp-method <method>", "Control CWD usage", CURLHELP_FTP}, {" --ftp-pasv", - "Send PASV/EPSV instead of PORT", + "Use PASV/EPSV instead of PORT", CURLHELP_FTP}, {"-P, --ftp-port <address>", - "Send PORT instead of PASV", + "Use PORT instead of PASV", CURLHELP_FTP}, {" --ftp-pret", "Send PRET before PASV", @@ -243,19 +235,19 @@ const struct helptxt helptext[] = { "Set CCC mode", CURLHELP_FTP | CURLHELP_TLS}, {" --ftp-ssl-control", - "Require TLS for login, clear for transfer", + "Require SSL/TLS for FTP login, clear for transfer", CURLHELP_FTP | CURLHELP_TLS}, {"-G, --get", "Put the post data in the URL and use GET", - CURLHELP_HTTP}, + CURLHELP_HTTP | CURLHELP_UPLOAD}, {"-g, --globoff", - "Disable URL globbing with {} and []", + "Disable URL sequences and ranges using {} and []", CURLHELP_CURL}, - {" --happy-eyeballs-timeout-ms <ms>", - "Time for IPv6 before IPv4", - CURLHELP_CONNECTION | CURLHELP_TIMEOUT}, - {" --haproxy-clientip <ip>", - "Set address in HAProxy PROXY", + {" --happy-eyeballs-timeout-ms <milliseconds>", + "Time for IPv6 before trying IPv4", + CURLHELP_CONNECTION}, + {" --haproxy-clientip", + "Sets client IP in HAProxy PROXY protocol v1 header", CURLHELP_HTTP | CURLHELP_PROXY}, {" --haproxy-protocol", "Send HAProxy PROXY protocol v1 header", @@ -266,16 +258,16 @@ const struct helptxt helptext[] = { {"-H, --header <header/@file>", "Pass custom header(s) to server", CURLHELP_HTTP | CURLHELP_IMAP | CURLHELP_SMTP}, - {"-h, --help <subject>", + {"-h, --help <category>", "Get help for commands", CURLHELP_IMPORTANT | CURLHELP_CURL}, {" --hostpubmd5 <md5>", - "Acceptable MD5 hash of host public key", - CURLHELP_SFTP | CURLHELP_SCP | CURLHELP_SSH}, + "Acceptable MD5 hash of the host public key", + CURLHELP_SFTP | CURLHELP_SCP}, {" --hostpubsha256 <sha256>", - "Acceptable SHA256 hash of host public key", - CURLHELP_SFTP | CURLHELP_SCP | CURLHELP_SSH}, - {" --hsts <filename>", + "Acceptable SHA256 hash of the host public key", + CURLHELP_SFTP | CURLHELP_SCP}, + {" --hsts <file name>", "Enable HSTS with this cache file", CURLHELP_HTTP}, {" --http0.9", @@ -302,18 +294,18 @@ const struct helptxt helptext[] = { {" --ignore-content-length", "Ignore the size of the remote resource", CURLHELP_HTTP | CURLHELP_FTP}, + {"-i, --include", + "Include protocol response headers in the output", + CURLHELP_IMPORTANT | CURLHELP_VERBOSE}, {"-k, --insecure", "Allow insecure server connections", - CURLHELP_TLS | CURLHELP_SFTP | CURLHELP_SCP | CURLHELP_SSH}, + CURLHELP_TLS | CURLHELP_SFTP | CURLHELP_SCP}, {" --interface <name>", - "Use network interface", - CURLHELP_CONNECTION}, - {" --ip-tos <string>", - "Set IP Type of Service or Traffic Class", + "Use network INTERFACE (or address)", CURLHELP_CONNECTION}, {" --ipfs-gateway <URL>", "Gateway for IPFS", - CURLHELP_CURL}, + CURLHELP_IPFS}, {"-4, --ipv4", "Resolve names to IPv4 addresses", CURLHELP_CONNECTION | CURLHELP_DNS}, @@ -326,14 +318,11 @@ const struct helptxt helptext[] = { {"-j, --junk-session-cookies", "Ignore session cookies read from file", CURLHELP_HTTP}, - {" --keepalive-cnt <integer>", - "Maximum number of keepalive probes", - CURLHELP_CONNECTION}, {" --keepalive-time <seconds>", "Interval time for keepalive probes", - CURLHELP_CONNECTION | CURLHELP_TIMEOUT}, + CURLHELP_CONNECTION}, {" --key <key>", - "Private key filename", + "Private key file name", CURLHELP_TLS | CURLHELP_SSH}, {" --key-type <type>", "Private key file type (DER/PEM/ENG)", @@ -342,27 +331,26 @@ const struct helptxt helptext[] = { "Enable Kerberos with security <level>", CURLHELP_FTP}, {" --libcurl <file>", - "Generate libcurl code for this command line", - CURLHELP_CURL | CURLHELP_GLOBAL}, + "Dump libcurl equivalent code of this command line", + CURLHELP_CURL}, {" --limit-rate <speed>", "Limit transfer speed to RATE", CURLHELP_CONNECTION}, {"-l, --list-only", "List only mode", - CURLHELP_FTP | CURLHELP_POP3 | CURLHELP_SFTP | CURLHELP_FILE}, - {" --local-port <range>", - "Use a local port number within RANGE", + CURLHELP_FTP | CURLHELP_POP3 | CURLHELP_SFTP}, + {" --local-port <num/range>", + "Force use of RANGE for local port numbers", CURLHELP_CONNECTION}, {"-L, --location", "Follow redirects", CURLHELP_HTTP}, {" --location-trusted", - "As --location, but send secrets to other hosts", + "Like --location, and send auth to other hosts", CURLHELP_HTTP | CURLHELP_AUTH}, {" --login-options <options>", "Server login options", - CURLHELP_IMAP | CURLHELP_POP3 | CURLHELP_SMTP | CURLHELP_AUTH | - CURLHELP_LDAP}, + CURLHELP_IMAP | CURLHELP_POP3 | CURLHELP_SMTP | CURLHELP_AUTH}, {" --mail-auth <address>", "Originator address of the original email", CURLHELP_SMTP}, @@ -373,7 +361,7 @@ const struct helptxt helptext[] = { "Mail to this address", CURLHELP_SMTP}, {" --mail-rcpt-allowfails", - "Allow RCPT TO command to fail", + "Allow RCPT TO command to fail for some recipients", CURLHELP_SMTP}, {"-M, --manual", "Display the full manual", @@ -384,45 +372,42 @@ const struct helptxt helptext[] = { {" --max-redirs <num>", "Maximum number of redirects allowed", CURLHELP_HTTP}, - {"-m, --max-time <seconds>", + {"-m, --max-time <fractional seconds>", "Maximum time allowed for transfer", - CURLHELP_CONNECTION | CURLHELP_TIMEOUT}, + CURLHELP_CONNECTION}, {" --metalink", "Process given URLs as metalink XML file", - CURLHELP_DEPRECATED}, - {" --mptcp", - "Enable Multipath TCP", - CURLHELP_CONNECTION}, + CURLHELP_MISC}, {" --negotiate", "Use HTTP Negotiate (SPNEGO) authentication", CURLHELP_AUTH | CURLHELP_HTTP}, {"-n, --netrc", - "Must read .netrc for username and password", - CURLHELP_AUTH}, + "Must read .netrc for user name and password", + CURLHELP_CURL}, {" --netrc-file <filename>", "Specify FILE for netrc", - CURLHELP_AUTH}, + CURLHELP_CURL}, {" --netrc-optional", "Use either .netrc or URL", - CURLHELP_AUTH}, + CURLHELP_CURL}, {"-:, --next", - "Make next URL use separate options", + "Make next URL use its separate set of options", CURLHELP_CURL}, {" --no-alpn", "Disable the ALPN TLS extension", CURLHELP_TLS | CURLHELP_HTTP}, {"-N, --no-buffer", "Disable buffering of the output stream", - CURLHELP_OUTPUT}, + CURLHELP_CURL}, {" --no-clobber", "Do not overwrite files that already exist", - CURLHELP_OUTPUT}, + CURLHELP_CURL | CURLHELP_OUTPUT}, {" --no-keepalive", "Disable TCP keepalive on the connection", CURLHELP_CONNECTION}, {" --no-npn", "Disable the NPN TLS extension", - CURLHELP_DEPRECATED}, + CURLHELP_TLS | CURLHELP_HTTP}, {" --no-progress-meter", "Do not show the progress meter", CURLHELP_VERBOSE}, @@ -433,54 +418,53 @@ const struct helptxt helptext[] = { "List of hosts which do not use proxy", CURLHELP_PROXY}, {" --ntlm", - "HTTP NTLM authentication", + "Use HTTP NTLM authentication", CURLHELP_AUTH | CURLHELP_HTTP}, {" --ntlm-wb", - "HTTP NTLM authentication with winbind", - CURLHELP_DEPRECATED}, + "Use HTTP NTLM authentication with winbind", + CURLHELP_AUTH | CURLHELP_HTTP}, {" --oauth2-bearer <token>", "OAuth 2 Bearer Token", - CURLHELP_AUTH | CURLHELP_IMAP | CURLHELP_POP3 | CURLHELP_SMTP | - CURLHELP_LDAP}, + CURLHELP_AUTH}, {"-o, --output <file>", "Write to file instead of stdout", - CURLHELP_IMPORTANT | CURLHELP_OUTPUT}, + CURLHELP_IMPORTANT | CURLHELP_CURL}, {" --output-dir <dir>", "Directory to save files in", - CURLHELP_OUTPUT}, + CURLHELP_CURL}, {"-Z, --parallel", "Perform transfers in parallel", - CURLHELP_CONNECTION | CURLHELP_CURL | CURLHELP_GLOBAL}, + CURLHELP_CONNECTION | CURLHELP_CURL}, {" --parallel-immediate", - "Do not wait for multiplexing", - CURLHELP_CONNECTION | CURLHELP_CURL | CURLHELP_GLOBAL}, + "Do not wait for multiplexing (with --parallel)", + CURLHELP_CONNECTION | CURLHELP_CURL}, {" --parallel-max <num>", "Maximum concurrency for parallel transfers", - CURLHELP_CONNECTION | CURLHELP_CURL | CURLHELP_GLOBAL}, + CURLHELP_CONNECTION | CURLHELP_CURL}, {" --pass <phrase>", - "Passphrase for the private key", + "Pass phrase for the private key", CURLHELP_SSH | CURLHELP_TLS | CURLHELP_AUTH}, {" --path-as-is", "Do not squash .. sequences in URL path", CURLHELP_CURL}, {" --pinnedpubkey <hashes>", - "Public key to verify peer against", + "FILE/HASHES Public key to verify peer against", CURLHELP_TLS}, {" --post301", - "Do not switch to GET after a 301 redirect", + "Do not switch to GET after following a 301", CURLHELP_HTTP | CURLHELP_POST}, {" --post302", - "Do not switch to GET after a 302 redirect", + "Do not switch to GET after following a 302", CURLHELP_HTTP | CURLHELP_POST}, {" --post303", - "Do not switch to GET after a 303 redirect", + "Do not switch to GET after following a 303", CURLHELP_HTTP | CURLHELP_POST}, {" --preproxy [protocol://]host[:port]", "Use this proxy first", CURLHELP_PROXY}, {"-#, --progress-bar", "Display transfer progress as a bar", - CURLHELP_VERBOSE | CURLHELP_GLOBAL}, + CURLHELP_VERBOSE}, {" --proto <protocols>", "Enable/disable PROTOCOLS", CURLHELP_CONNECTION | CURLHELP_CURL}, @@ -500,13 +484,13 @@ const struct helptxt helptext[] = { "Use Basic authentication on the proxy", CURLHELP_PROXY | CURLHELP_AUTH}, {" --proxy-ca-native", - "Load CA certs from the OS to verify proxy", + "Use CA certificates from the native OS for proxy", CURLHELP_TLS}, {" --proxy-cacert <file>", - "CA certificates to verify proxy against", + "CA certificate to verify peer against for proxy", CURLHELP_PROXY | CURLHELP_TLS}, {" --proxy-capath <dir>", - "CA directory to verify proxy against", + "CA directory to verify peer against for proxy", CURLHELP_PROXY | CURLHELP_TLS}, {" --proxy-cert <cert[:passwd]>", "Set client certificate for proxy", @@ -515,13 +499,13 @@ const struct helptxt helptext[] = { "Client certificate type for HTTPS proxy", CURLHELP_PROXY | CURLHELP_TLS}, {" --proxy-ciphers <list>", - "TLS 1.2 (1.1, 1.0) ciphers to use for proxy", + "SSL ciphers to use for proxy", CURLHELP_PROXY | CURLHELP_TLS}, {" --proxy-crlfile <file>", "Set a CRL list for proxy", CURLHELP_PROXY | CURLHELP_TLS}, {" --proxy-digest", - "Digest auth with the proxy", + "Use Digest authentication on the proxy", CURLHELP_PROXY | CURLHELP_TLS}, {" --proxy-header <header/@file>", "Pass custom header(s) to proxy", @@ -530,7 +514,7 @@ const struct helptxt helptext[] = { "Use HTTP/2 with HTTPS proxy", CURLHELP_HTTP | CURLHELP_PROXY}, {" --proxy-insecure", - "Skip HTTPS proxy cert verification", + "Do HTTPS proxy connections without verifying the proxy", CURLHELP_PROXY | CURLHELP_TLS}, {" --proxy-key <key>", "Private key for HTTPS proxy", @@ -539,13 +523,13 @@ const struct helptxt helptext[] = { "Private key file type for proxy", CURLHELP_PROXY | CURLHELP_TLS}, {" --proxy-negotiate", - "HTTP Negotiate (SPNEGO) auth with the proxy", + "Use HTTP Negotiate (SPNEGO) authentication on the proxy", CURLHELP_PROXY | CURLHELP_AUTH}, {" --proxy-ntlm", - "NTLM authentication with the proxy", + "Use NTLM authentication on the proxy", CURLHELP_PROXY | CURLHELP_AUTH}, {" --proxy-pass <phrase>", - "Passphrase for private key for HTTPS proxy", + "Pass phrase for the private key for HTTPS proxy", CURLHELP_PROXY | CURLHELP_TLS | CURLHELP_AUTH}, {" --proxy-pinnedpubkey <hashes>", "FILE/HASHES public key to verify proxy with", @@ -554,12 +538,12 @@ const struct helptxt helptext[] = { "SPNEGO proxy service name", CURLHELP_PROXY | CURLHELP_TLS}, {" --proxy-ssl-allow-beast", - "Allow this security flaw for HTTPS proxy", + "Allow security flaw for interop for HTTPS proxy", CURLHELP_PROXY | CURLHELP_TLS}, {" --proxy-ssl-auto-client-cert", - "Auto client certificate for proxy", + "Use auto client certificate for proxy (Schannel)", CURLHELP_PROXY | CURLHELP_TLS}, - {" --proxy-tls13-ciphers <list>", + {" --proxy-tls13-ciphers <ciphersuite list>", "TLS 1.3 proxy cipher suites", CURLHELP_PROXY | CURLHELP_TLS}, {" --proxy-tlsauthtype <type>", @@ -572,7 +556,7 @@ const struct helptxt helptext[] = { "TLS username for HTTPS proxy", CURLHELP_PROXY | CURLHELP_TLS | CURLHELP_AUTH}, {" --proxy-tlsv1", - "TLSv1 for HTTPS proxy", + "Use TLSv1 for HTTPS proxy", CURLHELP_PROXY | CURLHELP_TLS | CURLHELP_AUTH}, {"-U, --proxy-user <user:password>", "Proxy user and password", @@ -581,25 +565,25 @@ const struct helptxt helptext[] = { "Use HTTP/1.0 proxy on given port", CURLHELP_PROXY}, {"-p, --proxytunnel", - "HTTP proxy tunnel (using CONNECT)", + "Operate through an HTTP proxy tunnel (using CONNECT)", CURLHELP_PROXY}, {" --pubkey <key>", - "SSH Public key filename", - CURLHELP_SFTP | CURLHELP_SCP | CURLHELP_SSH | CURLHELP_AUTH}, + "SSH Public key file name", + CURLHELP_SFTP | CURLHELP_SCP | CURLHELP_AUTH}, {"-Q, --quote <command>", "Send command(s) to server before transfer", CURLHELP_FTP | CURLHELP_SFTP}, {" --random-file <file>", "File for reading random data from", - CURLHELP_DEPRECATED}, + CURLHELP_MISC}, {"-r, --range <range>", "Retrieve only the bytes within RANGE", CURLHELP_HTTP | CURLHELP_FTP | CURLHELP_SFTP | CURLHELP_FILE}, {" --rate <max request rate>", "Request rate for serial transfers", - CURLHELP_CONNECTION | CURLHELP_GLOBAL}, + CURLHELP_CONNECTION}, {" --raw", - "Do HTTP raw; no transfer decoding", + "Do HTTP \"raw\"; no transfer decoding", CURLHELP_HTTP}, {"-e, --referer <URL>", "Referrer URL", @@ -608,63 +592,56 @@ const struct helptxt helptext[] = { "Use the header-provided filename", CURLHELP_OUTPUT}, {"-O, --remote-name", - "Write output to file named as remote file", + "Write output to a file named as the remote file", CURLHELP_IMPORTANT | CURLHELP_OUTPUT}, {" --remote-name-all", - "Use the remote filename for all URLs", + "Use the remote file name for all URLs", CURLHELP_OUTPUT}, {"-R, --remote-time", - "Set remote file's time on local output", + "Set the remote file's time on the local output", CURLHELP_OUTPUT}, {" --remove-on-error", "Remove output file on errors", - CURLHELP_OUTPUT}, + CURLHELP_CURL}, {"-X, --request <method>", "Specify request method to use", - CURLHELP_CONNECTION | CURLHELP_POP3 | CURLHELP_FTP | CURLHELP_IMAP | - CURLHELP_SMTP}, + CURLHELP_CONNECTION}, {" --request-target <path>", "Specify the target for this request", CURLHELP_HTTP}, {" --resolve <[+]host:port:addr[,addr]...>", - "Resolve host+port to address", + "Resolve the host+port to this address", CURLHELP_CONNECTION | CURLHELP_DNS}, {" --retry <num>", "Retry request if transient problems occur", CURLHELP_CURL}, {" --retry-all-errors", - "Retry all errors (with --retry)", + "Retry all errors (use with --retry)", CURLHELP_CURL}, {" --retry-connrefused", - "Retry on connection refused (with --retry)", + "Retry on connection refused (use with --retry)", CURLHELP_CURL}, {" --retry-delay <seconds>", "Wait time between retries", - CURLHELP_CURL | CURLHELP_TIMEOUT}, + CURLHELP_CURL}, {" --retry-max-time <seconds>", "Retry only within this period", - CURLHELP_CURL | CURLHELP_TIMEOUT}, + CURLHELP_CURL}, {" --sasl-authzid <identity>", "Identity for SASL PLAIN authentication", CURLHELP_AUTH}, {" --sasl-ir", - "Initial response in SASL authentication", + "Enable initial response in SASL authentication", CURLHELP_AUTH}, {" --service-name <name>", "SPNEGO service name", - CURLHELP_AUTH}, + CURLHELP_MISC}, {"-S, --show-error", "Show error even when -s is used", - CURLHELP_CURL | CURLHELP_GLOBAL}, - {"-i, --show-headers", - "Show response headers in output", - CURLHELP_IMPORTANT | CURLHELP_VERBOSE | CURLHELP_OUTPUT}, + CURLHELP_CURL}, {"-s, --silent", "Silent mode", CURLHELP_IMPORTANT | CURLHELP_VERBOSE}, - {" --skip-existing", - "Skip download if local file already exists", - CURLHELP_CURL | CURLHELP_OUTPUT}, {" --socks4 <host[:port]>", "SOCKS4 proxy on given host + port", CURLHELP_PROXY}, @@ -675,7 +652,7 @@ const struct helptxt helptext[] = { "SOCKS5 proxy on given host + port", CURLHELP_PROXY}, {" --socks5-basic", - "Username/password auth for SOCKS5 proxies", + "Enable username/password auth for SOCKS5 proxies", CURLHELP_PROXY | CURLHELP_AUTH}, {" --socks5-gssapi", "Enable GSS-API auth for SOCKS5 proxies", @@ -687,18 +664,17 @@ const struct helptxt helptext[] = { "SOCKS5 proxy service name for GSS-API", CURLHELP_PROXY | CURLHELP_AUTH}, {" --socks5-hostname <host[:port]>", - "SOCKS5 proxy, pass hostname to proxy", + "SOCKS5 proxy, pass host name to proxy", CURLHELP_PROXY}, {"-Y, --speed-limit <speed>", "Stop transfers slower than this", CURLHELP_CONNECTION}, {"-y, --speed-time <seconds>", "Trigger 'speed-limit' abort after this time", - CURLHELP_CONNECTION | CURLHELP_TIMEOUT}, + CURLHELP_CONNECTION}, {" --ssl", - "Try enabling TLS", - CURLHELP_TLS | CURLHELP_IMAP | CURLHELP_POP3 | CURLHELP_SMTP | - CURLHELP_LDAP}, + "Try SSL/TLS", + CURLHELP_TLS}, {" --ssl-allow-beast", "Allow security flaw to improve interop", CURLHELP_TLS}, @@ -710,23 +686,22 @@ const struct helptxt helptext[] = { CURLHELP_TLS}, {" --ssl-reqd", "Require SSL/TLS", - CURLHELP_TLS | CURLHELP_IMAP | CURLHELP_POP3 | CURLHELP_SMTP | - CURLHELP_LDAP}, + CURLHELP_TLS}, {" --ssl-revoke-best-effort", - "Ignore missing cert CRL dist points", + "Ignore missing/offline cert CRL dist points (Schannel)", CURLHELP_TLS}, {"-2, --sslv2", - "SSLv2", - CURLHELP_DEPRECATED}, + "Use SSLv2", + CURLHELP_TLS}, {"-3, --sslv3", - "SSLv3", - CURLHELP_DEPRECATED}, + "Use SSLv3", + CURLHELP_TLS}, {" --stderr <file>", "Where to redirect stderr", - CURLHELP_VERBOSE | CURLHELP_GLOBAL}, + CURLHELP_VERBOSE}, {" --styled-output", "Enable styled output for HTTP headers", - CURLHELP_VERBOSE | CURLHELP_GLOBAL}, + CURLHELP_VERBOSE}, {" --suppress-connect-headers", "Suppress proxy CONNECT response headers", CURLHELP_PROXY}, @@ -734,7 +709,7 @@ const struct helptxt helptext[] = { "Use TCP Fast Open", CURLHELP_CONNECTION}, {" --tcp-nodelay", - "Set TCP_NODELAY", + "Use the TCP_NODELAY option", CURLHELP_CONNECTION}, {"-t, --telnet-option <opt=val>", "Set telnet option", @@ -749,9 +724,9 @@ const struct helptxt helptext[] = { "Transfer based on a time condition", CURLHELP_HTTP | CURLHELP_FTP}, {" --tls-max <VERSION>", - "Maximum allowed TLS version", + "Set maximum allowed TLS version", CURLHELP_TLS}, - {" --tls13-ciphers <list>", + {" --tls13-ciphers <ciphersuite list>", "TLS 1.3 cipher suites to use", CURLHELP_TLS}, {" --tlsauthtype <type>", @@ -761,41 +736,41 @@ const struct helptxt helptext[] = { "TLS password", CURLHELP_TLS | CURLHELP_AUTH}, {" --tlsuser <name>", - "TLS username", + "TLS user name", CURLHELP_TLS | CURLHELP_AUTH}, {"-1, --tlsv1", - "TLSv1.0 or greater", + "Use TLSv1.0 or greater", CURLHELP_TLS}, {" --tlsv1.0", - "TLSv1.0 or greater", + "Use TLSv1.0 or greater", CURLHELP_TLS}, {" --tlsv1.1", - "TLSv1.1 or greater", + "Use TLSv1.1 or greater", CURLHELP_TLS}, {" --tlsv1.2", - "TLSv1.2 or greater", + "Use TLSv1.2 or greater", CURLHELP_TLS}, {" --tlsv1.3", - "TLSv1.3 or greater", + "Use TLSv1.3 or greater", CURLHELP_TLS}, {" --tr-encoding", "Request compressed transfer encoding", CURLHELP_HTTP}, {" --trace <file>", "Write a debug trace to FILE", - CURLHELP_VERBOSE | CURLHELP_GLOBAL}, + CURLHELP_VERBOSE}, {" --trace-ascii <file>", "Like --trace, but without hex output", - CURLHELP_VERBOSE | CURLHELP_GLOBAL}, + CURLHELP_VERBOSE}, {" --trace-config <string>", "Details to log in trace/verbose output", - CURLHELP_VERBOSE | CURLHELP_GLOBAL}, + CURLHELP_VERBOSE}, {" --trace-ids", - "Transfer + connection ids in verbose output", - CURLHELP_VERBOSE | CURLHELP_GLOBAL}, + "Add transfer and connection identifiers to trace/verbose output", + CURLHELP_VERBOSE}, {" --trace-time", "Add time stamps to trace/verbose output", - CURLHELP_VERBOSE | CURLHELP_GLOBAL}, + CURLHELP_VERBOSE}, {" --unix-socket <path>", "Connect through this Unix domain socket", CURLHELP_CONNECTION}, @@ -810,7 +785,7 @@ const struct helptxt helptext[] = { CURLHELP_HTTP | CURLHELP_POST | CURLHELP_UPLOAD}, {"-B, --use-ascii", "Use ASCII/text transfer", - CURLHELP_FTP | CURLHELP_OUTPUT | CURLHELP_LDAP}, + CURLHELP_MISC}, {"-u, --user <user:password>", "Server user and password", CURLHELP_IMPORTANT | CURLHELP_AUTH}, @@ -822,18 +797,15 @@ const struct helptxt helptext[] = { CURLHELP_CURL}, {"-v, --verbose", "Make the operation more talkative", - CURLHELP_IMPORTANT | CURLHELP_VERBOSE | CURLHELP_GLOBAL}, + CURLHELP_IMPORTANT | CURLHELP_VERBOSE}, {"-V, --version", "Show version number and quit", CURLHELP_IMPORTANT | CURLHELP_CURL}, - {" --vlan-priority <priority>", - "Set VLAN priority", - CURLHELP_CONNECTION}, {"-w, --write-out <format>", - "Output FORMAT after completion", + "Use output FORMAT after completion", CURLHELP_VERBOSE}, {" --xattr", "Store metadata in extended file attributes", - CURLHELP_OUTPUT}, - { NULL, NULL, 0 } + CURLHELP_MISC}, + { NULL, NULL, CURLHELP_HIDDEN } }; diff --git a/contrib/libs/curl/src/tool_main.c b/contrib/libs/curl/src/tool_main.c index 01993123e2..446806ecbd 100644 --- a/contrib/libs/curl/src/tool_main.c +++ b/contrib/libs/curl/src/tool_main.c @@ -35,6 +35,8 @@ #include <fcntl.h> #endif +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" @@ -79,7 +81,7 @@ int _CRT_glob = 0; #if defined(HAVE_PIPE) && defined(HAVE_FCNTL) /* * Ensure that file descriptors 0, 1 and 2 (stdin, stdout, stderr) are - * open before starting to run. Otherwise, the first three network + * open before starting to run. Otherwise, the first three network * sockets opened by curl could be used for input sources, downloaded data * or error logs as they will effectively be stdin, stdout and/or stderr. * @@ -106,9 +108,9 @@ static void memory_tracking_init(void) { char *env; /* if CURL_MEMDEBUG is set, this starts memory tracking message logging */ - env = curl_getenv("CURL_MEMDEBUG"); + env = curlx_getenv("CURL_MEMDEBUG"); if(env) { - /* use the value as filename */ + /* use the value as file name */ char fname[CURL_MT_LOGFNAME_BUFSIZE]; if(strlen(env) >= CURL_MT_LOGFNAME_BUFSIZE) env[CURL_MT_LOGFNAME_BUFSIZE-1] = '\0'; @@ -120,7 +122,7 @@ static void memory_tracking_init(void) without an alloc! */ } /* if CURL_MEMLIMIT is set, this enables fail-on-alloc-number-N feature */ - env = curl_getenv("CURL_MEMLIMIT"); + env = curlx_getenv("CURL_MEMLIMIT"); if(env) { char *endptr; long num = strtol(env, &endptr, 10); @@ -217,7 +219,7 @@ static void main_free(struct GlobalConfig *config) */ #ifdef _UNICODE #if defined(__GNUC__) -/* GCC does not know about wmain() */ +/* GCC doesn't know about wmain() */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmissing-prototypes" #pragma GCC diagnostic ignored "-Wmissing-declarations" @@ -247,7 +249,7 @@ int main(int argc, char *argv[]) result = win32_init(); if(result) { errorf(&global, "(%d) Windows-specific init failed", result); - return (int)result; + return result; } #endif diff --git a/contrib/libs/curl/src/tool_msgs.c b/contrib/libs/curl/src/tool_msgs.c index 58b935e962..c914836db7 100644 --- a/contrib/libs/curl/src/tool_msgs.c +++ b/contrib/libs/curl/src/tool_msgs.c @@ -23,12 +23,12 @@ ***************************************************************************/ #include "tool_setup.h" +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" #include "tool_msgs.h" -#include "tool_cb_prg.h" -#include "terminal.h" #include "memdebug.h" /* keep this as LAST include */ @@ -39,21 +39,16 @@ static void voutf(struct GlobalConfig *config, const char *prefix, const char *fmt, - va_list ap) CURL_PRINTF(3, 0); - -static void voutf(struct GlobalConfig *config, - const char *prefix, - const char *fmt, va_list ap) { - size_t width = (get_terminal_columns() - strlen(prefix)); + size_t width = (79 - strlen(prefix)); DEBUGASSERT(!strchr(fmt, '\n')); if(!config->silent) { size_t len; char *ptr; char *print_buffer; - print_buffer = vaprintf(fmt, ap); + print_buffer = curlx_mvaprintf(fmt, ap); if(!print_buffer) return; len = strlen(print_buffer); @@ -105,6 +100,7 @@ void notef(struct GlobalConfig *config, const char *fmt, ...) * Emit warning formatted message on configured 'errors' stream unless * mute (--silent) was selected. */ + void warnf(struct GlobalConfig *config, const char *fmt, ...) { va_list ap; @@ -112,7 +108,6 @@ void warnf(struct GlobalConfig *config, const char *fmt, ...) voutf(config, WARN_PREFIX, fmt, ap); va_end(ap); } - /* * Emit help formatted message on given stream. This is for errors with or * related to command line arguments. diff --git a/contrib/libs/curl/src/tool_msgs.h b/contrib/libs/curl/src/tool_msgs.h index e963efaa0b..9458991c01 100644 --- a/contrib/libs/curl/src/tool_msgs.h +++ b/contrib/libs/curl/src/tool_msgs.h @@ -26,13 +26,9 @@ #include "tool_setup.h" #include "tool_cfgable.h" -void warnf(struct GlobalConfig *config, const char *fmt, ...) - CURL_PRINTF(2, 3); -void notef(struct GlobalConfig *config, const char *fmt, ...) - CURL_PRINTF(2, 3); -void helpf(FILE *errors, const char *fmt, ...) - CURL_PRINTF(2, 3); -void errorf(struct GlobalConfig *config, const char *fmt, ...) - CURL_PRINTF(2, 3); +void warnf(struct GlobalConfig *config, const char *fmt, ...); +void notef(struct GlobalConfig *config, const char *fmt, ...); +void helpf(FILE *errors, const char *fmt, ...); +void errorf(struct GlobalConfig *config, const char *fmt, ...); #endif /* HEADER_CURL_TOOL_MSGS_H */ diff --git a/contrib/libs/curl/src/tool_operate.c b/contrib/libs/curl/src/tool_operate.c index 53f1bd82aa..097e7e0d08 100644 --- a/contrib/libs/curl/src/tool_operate.c +++ b/contrib/libs/curl/src/tool_operate.c @@ -45,21 +45,8 @@ # error #include <proto/dos.h> #endif -#ifdef HAVE_NETINET_IN_H -# include <netinet/in.h> -#endif - -#ifdef HAVE_UV_H -/* Hack for Unity mode */ -#ifdef HEADER_CURL_MEMDEBUG_H -#undef HEADER_CURL_MEMDEBUG_H -#undef freeaddrinfo -#undef getaddrinfo -#endif -/* this is for libuv-enabled debug builds only */ -#error #include <uv.h> -#endif - +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" #include "tool_binmode.h" @@ -69,7 +56,6 @@ #include "tool_cb_prg.h" #include "tool_cb_rea.h" #include "tool_cb_see.h" -#include "tool_cb_soc.h" #include "tool_cb_wrt.h" #include "tool_dirhie.h" #include "tool_doswin.h" @@ -97,31 +83,25 @@ #include "tool_progress.h" #include "tool_ipfs.h" #include "dynbuf.h" -#ifdef DEBUGBUILD -#include "easyif.h" /* for libcurl's debug-only curl_easy_perform_ev() */ -#endif #include "memdebug.h" /* keep this as LAST include */ -#ifdef CURL_CA_EMBED -extern const unsigned char curl_ca_embed[]; +#ifdef CURLDEBUG +/* libcurl's debug builds provide an extra function */ +CURLcode curl_easy_perform_ev(CURL *easy); #endif #ifndef O_BINARY /* since O_BINARY as used in bitmasks, setting it to zero makes it usable in - source code but yet it does not ruin anything */ + source code but yet it doesn't ruin anything */ # define O_BINARY 0 #endif -#ifndef SOL_IP -# define SOL_IP IPPROTO_IP -#endif - -#define CURL_CA_CERT_ERRORMSG \ - "More details here: https://curl.se/docs/sslcerts.html\n\n" \ - "curl failed to verify the legitimacy of the server and therefore " \ - "could not\nestablish a secure connection to it. To learn more about " \ - "this situation and\nhow to fix it, please visit the webpage mentioned " \ +#define CURL_CA_CERT_ERRORMSG \ + "More details here: https://curl.se/docs/sslcerts.html\n\n" \ + "curl failed to verify the legitimacy of the server and therefore " \ + "could not\nestablish a secure connection to it. To learn more about " \ + "this situation and\nhow to fix it, please visit the web page mentioned " \ "above.\n" static CURLcode single_transfer(struct GlobalConfig *global, @@ -164,67 +144,6 @@ static bool is_pkcs11_uri(const char *string) } } -#ifdef IP_TOS -static int get_address_family(curl_socket_t sockfd) -{ - struct sockaddr addr; - curl_socklen_t addrlen = sizeof(addr); - if(getsockname(sockfd, (struct sockaddr *)&addr, &addrlen) == 0) - return addr.sa_family; - return AF_UNSPEC; -} -#endif - -#if defined(IP_TOS) || defined(IPV6_TCLASS) || defined(SO_PRIORITY) -static int sockopt_callback(void *clientp, curl_socket_t curlfd, - curlsocktype purpose) -{ - struct OperationConfig *config = (struct OperationConfig *)clientp; - if(purpose != CURLSOCKTYPE_IPCXN) - return CURL_SOCKOPT_OK; - (void)config; - (void)curlfd; -#if defined(IP_TOS) || defined(IPV6_TCLASS) - if(config->ip_tos > 0) { - int tos = (int)config->ip_tos; - int result = 0; - switch(get_address_family(curlfd)) { - case AF_INET: -#ifdef IP_TOS - result = setsockopt(curlfd, SOL_IP, IP_TOS, (void *)&tos, sizeof(tos)); -#endif - break; -#if defined(IPV6_TCLASS) && defined(AF_INET6) - case AF_INET6: - result = setsockopt(curlfd, IPPROTO_IPV6, IPV6_TCLASS, - (void *)&tos, sizeof(tos)); - break; -#endif - } - if(result < 0) { - int error = errno; - warnf(config->global, - "Setting type of service to %d failed with errno %d: %s;\n", - tos, error, strerror(error)); - } - } -#endif -#ifdef SO_PRIORITY - if(config->vlan_priority > 0) { - int priority = (int)config->vlan_priority; - if(setsockopt(curlfd, SOL_SOCKET, SO_PRIORITY, - (void *)&priority, sizeof(priority)) != 0) { - int error = errno; - warnf(config->global, "VLAN priority %d failed with errno %d: %s;\n", - priority, error, strerror(error)); - } - } -#endif - return CURL_SOCKOPT_OK; -} -#endif - - #ifdef __VMS /* * get_vms_file_size does what it takes to get the real size of the file @@ -352,7 +271,7 @@ static CURLcode pre_transfer(struct GlobalConfig *global, if(per->uploadfile && !stdin_upload(per->uploadfile)) { /* VMS Note: * - * Reading binary from files can be a problem... Only FIXED, VAR + * Reading binary from files can be a problem... Only FIXED, VAR * etc WITHOUT implied CC will work. Others need a \n appended to * a line * @@ -386,7 +305,7 @@ static CURLcode pre_transfer(struct GlobalConfig *global, if((per->infd == -1) || fstat(per->infd, &fileinfo)) #endif { - helpf(tool_stderr, "cannot open '%s'", per->uploadfile); + helpf(tool_stderr, "Can't open '%s'", per->uploadfile); if(per->infd != -1) { close(per->infd); per->infd = STDIN_FILENO; @@ -424,6 +343,22 @@ static CURLcode pre_transfer(struct GlobalConfig *global, return result; } +#ifdef __AMIGA__ +static void AmigaSetComment(struct per_transfer *per, + CURLcode result) +{ + struct OutStruct *outs = &per->outs; + if(!result && outs->s_isreg && outs->filename) { + /* Set the url (up to 80 chars) as comment for the file */ + if(strlen(per->this_url) > 78) + per->this_url[79] = '\0'; + SetComment(outs->filename, per->this_url); + } +} +#else +#define AmigaSetComment(x,y) Curl_nop_stmt +#endif + /* When doing serial transfers, we use a single fixed error area */ static char global_errorbuffer[CURL_ERROR_SIZE]; @@ -437,6 +372,7 @@ void single_transfer_cleanup(struct OperationConfig *config) state->urls = NULL; } Curl_safefree(state->outfiles); + Curl_safefree(state->httpgetfields); Curl_safefree(state->uploadfile); if(state->inglob) { /* Free list of globbed upload files */ @@ -460,18 +396,15 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, struct OperationConfig *config = per->config; int rc; - *retryp = FALSE; - *delay = 0; /* for no retry, keep it zero */ - if(!curl || !config) return result; + *retryp = FALSE; + *delay = 0; /* for no retry, keep it zero */ + if(per->infdopen) close(per->infd); - if(per->skip) - goto skip; - #ifdef __VMS if(is_vms_shell()) { /* VMS DCL shell behavior */ @@ -536,9 +469,9 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, memset(outs->utf8seq, 0, sizeof(outs->utf8seq)); #endif - /* if retry-max-time is non-zero, make sure we have not exceeded the + /* if retry-max-time is non-zero, make sure we haven't exceeded the time */ - if(per->retry_remaining && + if(per->retry_numretries && (!config->retry_maxtime || (tvdiff(tvnow(), per->retrystart) < config->retry_maxtime*1000L)) ) { @@ -610,7 +543,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, if((scheme == proto_ftp || scheme == proto_ftps) && response / 100 == 4) /* * This is typically when the FTP server only allows a certain - * amount of users and we are not one of them. All 4xx codes + * amount of users and we are not one of them. All 4xx codes * are transient. */ retry = RETRY_FTP; @@ -635,10 +568,10 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, if(RETRY_HTTP == retry) { curl_easy_getinfo(curl, CURLINFO_RETRY_AFTER, &retry_after); if(retry_after) { - /* store in a 'long', make sure it does not overflow */ + /* store in a 'long', make sure it doesn't overflow */ if(retry_after > LONG_MAX/1000) sleeptime = LONG_MAX; - else if((retry_after * 1000) > sleeptime) + else sleeptime = (long)retry_after * 1000; /* milliseconds */ /* if adding retry_after seconds to the process would exceed the @@ -660,9 +593,9 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, warnf(config->global, "Problem %s. " "Will retry in %ld seconds. " "%ld retries left.", - m[retry], sleeptime/1000L, per->retry_remaining); + m[retry], sleeptime/1000L, per->retry_numretries); - per->retry_remaining--; + per->retry_numretries--; if(!config->retry_delay) { per->retry_sleep *= 2; if(per->retry_sleep > RETRY_SLEEP_MAX) @@ -678,7 +611,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, /* truncate file at the position where we started appending */ #ifdef HAVE_FTRUNCATE if(ftruncate(fileno(outs->stream), outs->init)) { - /* when truncate fails, we cannot just append as then we will + /* when truncate fails, we can't just append as then we'll create something strange, bail out */ errorf(config->global, "Failed to truncate file"); return CURLE_WRITE_ERROR; @@ -688,7 +621,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, rc = fseek(outs->stream, 0, SEEK_END); #else /* ftruncate is not available, so just reposition the file - to the location we would have truncated it. This will not + to the location we would have truncated it. This won't work properly with large files on 32-bit systems, but most of those will have ftruncate. */ rc = fseek(outs->stream, (long)outs->init, SEEK_SET); @@ -700,11 +633,10 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, outs->bytes = 0; /* clear for next round */ } *retryp = TRUE; - per->num_retries++; *delay = sleeptime; return CURLE_OK; } - } /* if retry_remaining */ + } /* if retry_numretries */ noretry: if((global->progressmode == CURL_PROGRESS_BAR) && @@ -722,20 +654,13 @@ noretry: errorf(config->global, "curl: (%d) Failed writing body", result); } if(result && config->rm_partial) { - struct_stat st; - if(!stat(outs->filename, &st) && - S_ISREG(st.st_mode)) { - if(!unlink(outs->filename)) - notef(global, "Removed output file: %s", outs->filename); - else - warnf(global, "Failed removing: %s", outs->filename); - } - else - warnf(global, "Skipping removal; not a regular file: %s", - outs->filename); + notef(global, "Removing output file: %s", outs->filename); + unlink(outs->filename); } } + AmigaSetComment(per, result); + /* File time can only be set _after_ the file has been closed */ if(!result && config->remote_time && outs->s_isreg && outs->filename) { /* Ask libcurl if we got a remote file time */ @@ -743,7 +668,7 @@ noretry: curl_easy_getinfo(curl, CURLINFO_FILETIME_T, &filetime); setfiletime(filetime, outs->filename, global); } -skip: + /* Write the --write-out data before cleanup but after result is final */ if(config->writeout) ourWriteOut(config, per, result); @@ -796,7 +721,7 @@ static CURLcode url_proto(char **url, if(curl_strequal(schemep, proto_ipfs) || curl_strequal(schemep, proto_ipns)) { result = ipfs_url_rewrite(uh, schemep, url, config); - /* short-circuit proto_token, we know it is ipfs or ipns */ + /* short-circuit proto_token, we know it's ipfs or ipns */ if(curl_strequal(schemep, proto_ipfs)) proto = proto_ipfs; else if(curl_strequal(schemep, proto_ipns)) @@ -837,17 +762,21 @@ static CURLcode single_transfer(struct GlobalConfig *global, if(config->use_httpget) { if(!httpgetfields) { /* Use the postfields data for an HTTP get */ - httpgetfields = state->httpgetfields = config->postfields; - config->postfields = NULL; - if(SetHTTPrequest(config, - (config->no_body?TOOL_HTTPREQ_HEAD:TOOL_HTTPREQ_GET), - &config->httpreq)) { + httpgetfields = state->httpgetfields = strdup(config->postfields); + Curl_safefree(config->postfields); + if(!httpgetfields) { + errorf(global, "out of memory"); + result = CURLE_OUT_OF_MEMORY; + } + else if(SetHTTPrequest(config, + (config->no_body?HTTPREQ_HEAD:HTTPREQ_GET), + &config->httpreq)) { result = CURLE_FAILED_INIT; } } } else { - if(SetHTTPrequest(config, TOOL_HTTPREQ_SIMPLEPOST, &config->httpreq)) + if(SetHTTPrequest(config, HTTPREQ_SIMPLEPOST, &config->httpreq)) result = CURLE_FAILED_INIT; } if(result) { @@ -949,7 +878,6 @@ static CURLcode single_transfer(struct GlobalConfig *global, urlnum = state->urlnum; if(state->up < state->infilenum) { - char ssl_ver[80] = "no ssl"; struct per_transfer *per = NULL; struct OutStruct *outs; struct OutStruct *heads; @@ -1011,7 +939,7 @@ static CURLcode single_transfer(struct GlobalConfig *global, if(config->etag_save_file) { /* open file for output: */ if(strcmp(config->etag_save_file, "-")) { - FILE *newfile = fopen(config->etag_save_file, "ab"); + FILE *newfile = fopen(config->etag_save_file, "wb"); if(!newfile) { warnf(global, "Failed creating file for saving etags: \"%s\". " "Skip this transfer", config->etag_save_file); @@ -1051,7 +979,7 @@ static CURLcode single_transfer(struct GlobalConfig *global, result = CURLE_OUT_OF_MEMORY; break; } - if(SetHTTPrequest(config, TOOL_HTTPREQ_PUT, &config->httpreq)) { + if(SetHTTPrequest(config, HTTPREQ_PUT, &config->httpreq)) { Curl_safefree(per->uploadfile); curl_easy_cleanup(curl); result = CURLE_FAILED_INIT; @@ -1061,7 +989,7 @@ static CURLcode single_transfer(struct GlobalConfig *global, *added = TRUE; per->config = config; per->curl = curl; - per->urlnum = (unsigned int)urlnode->num; + per->urlnum = urlnode->num; /* default headers output stream is stdout */ heads = &per->heads; @@ -1070,12 +998,7 @@ static CURLcode single_transfer(struct GlobalConfig *global, /* Single header file for all URLs */ if(config->headerfile) { /* open file for output: */ - if(!strcmp(config->headerfile, "%")) { - heads->stream = stderr; - /* use binary mode for protocol header output */ - set_binmode(heads->stream); - } - else if(strcmp(config->headerfile, "-")) { + if(strcmp(config->headerfile, "-")) { FILE *newfile; /* @@ -1152,18 +1075,23 @@ static CURLcode single_transfer(struct GlobalConfig *global, (per->outfile && strcmp("-", per->outfile)))) { /* - * We have specified a filename to store the result in, or we have - * decided we want to use the remote filename. + * We have specified a file name to store the result in, or we have + * decided we want to use the remote file name. */ if(!per->outfile) { - /* extract the filename from the URL */ - result = get_url_file_name(global, &per->outfile, per->this_url); + /* extract the file name from the URL */ + result = get_url_file_name(&per->outfile, per->this_url); if(result) { - errorf(global, "Failed to extract a filename" + errorf(global, "Failed to extract a sensible file name" " from the URL to use for storage"); break; } + if(!*per->outfile && !config->content_disposition) { + errorf(global, "Remote file name has no length"); + result = CURLE_WRITE_ERROR; + break; + } } else if(state->urls) { /* fill '#1' ... '#9' terms from URL pattern */ @@ -1181,7 +1109,6 @@ static CURLcode single_transfer(struct GlobalConfig *global, break; } } - DEBUGASSERT(per->outfile); if(config->output_dir && *config->output_dir) { char *d = aprintf("%s/%s", config->output_dir, per->outfile); @@ -1202,15 +1129,6 @@ static CURLcode single_transfer(struct GlobalConfig *global, break; } - if(config->skip_existing) { - struct_stat fileinfo; - if(!stat(per->outfile, &fileinfo)) { - /* file is present */ - notef(global, "skips transfer, \"%s\" exists locally", - per->outfile); - per->skip = TRUE; - } - } if((urlnode->flags & GETOUT_USEREMOTE) && config->content_disposition) { /* Our header callback MIGHT set the filename */ @@ -1218,7 +1136,7 @@ static CURLcode single_transfer(struct GlobalConfig *global, } if(config->resume_from_current) { - /* We are told to continue from where we are now. Get the size + /* We're told to continue from where we are now. Get the size of the file as it is now and open it for append instead */ struct_stat fileinfo; /* VMS -- Danger, the filesize is only valid for stream files */ @@ -1241,7 +1159,7 @@ static CURLcode single_transfer(struct GlobalConfig *global, FILE *file = fopen(per->outfile, "ab"); #endif if(!file) { - errorf(global, "cannot open '%s'", per->outfile); + errorf(global, "Can't open '%s'", per->outfile); result = CURLE_WRITE_ERROR; break; } @@ -1258,7 +1176,7 @@ static CURLcode single_transfer(struct GlobalConfig *global, if(per->uploadfile && !stdin_upload(per->uploadfile)) { /* - * We have specified a file to upload and it is not "-". + * We have specified a file to upload and it isn't "-". */ result = add_file_name_to_url(per->curl, &per->this_url, per->uploadfile); @@ -1274,7 +1192,7 @@ static CURLcode single_transfer(struct GlobalConfig *global, if(config->authtype & (1UL << bitcheck++)) { authbits++; if(authbits > 1) { - /* more than one, we are done! */ + /* more than one, we're done! */ break; } } @@ -1365,20 +1283,19 @@ static CURLcode single_transfer(struct GlobalConfig *global, if(result) break; + /* result is only used when for ipfs and ipns, ignored otherwise */ result = url_proto(&per->this_url, config, &use_proto); - if(result) + if(result && (use_proto == proto_ipfs || use_proto == proto_ipns)) break; -#ifndef DEBUGBUILD /* On most modern OSes, exiting works thoroughly, - we will clean everything up via exit(), so do not bother with + we'll clean everything up via exit(), so don't bother with slow cleanups. Crappy ones might need to skip this. Note: avoid having this setopt added to the --libcurl source output. */ result = curl_easy_setopt(curl, CURLOPT_QUICK_EXIT, 1L); if(result) break; -#endif if(!config->tcp_nodelay) my_setopt(curl, CURLOPT_TCP_NODELAY, 0L); @@ -1386,10 +1303,6 @@ static CURLcode single_transfer(struct GlobalConfig *global, if(config->tcp_fastopen) my_setopt(curl, CURLOPT_TCP_FASTOPEN, 1L); - if(config->mptcp) - my_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, - tool_socket_open_mptcp_cb); - /* where to store */ my_setopt(curl, CURLOPT_WRITEDATA, per); my_setopt(curl, CURLOPT_INTERLEAVEDATA, per); @@ -1414,7 +1327,7 @@ static CURLcode single_transfer(struct GlobalConfig *global, my_setopt(curl, CURLOPT_SEEKFUNCTION, tool_seek_cb); { -#ifdef DEBUGBUILD +#ifdef CURLDEBUG char *env = getenv("CURL_BUFFERSIZE"); if(env) { long size = strtol(env, NULL, 10); @@ -1513,19 +1426,19 @@ static CURLcode single_transfer(struct GlobalConfig *global, my_setopt(curl, CURLOPT_TIMEOUT_MS, config->timeout_ms); switch(config->httpreq) { - case TOOL_HTTPREQ_SIMPLEPOST: + case HTTPREQ_SIMPLEPOST: if(config->resume_from) { errorf(global, "cannot mix --continue-at with --data"); result = CURLE_FAILED_INIT; } else { my_setopt_str(curl, CURLOPT_POSTFIELDS, - curlx_dyn_ptr(&config->postdata)); + config->postfields); my_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, - (curl_off_t)curlx_dyn_len(&config->postdata)); + config->postfieldsize); } break; - case TOOL_HTTPREQ_MIMEPOST: + case HTTPREQ_MIMEPOST: /* free previous remainders */ curl_mime_free(config->mimepost); config->mimepost = NULL; @@ -1651,14 +1564,6 @@ static CURLcode single_transfer(struct GlobalConfig *global, my_setopt(curl, CURLOPT_SSH_COMPRESSION, 1L); } - { - /* get current SSL backend, chop off multissl */ - const char *v = curl_version_info(CURLVERSION_NOW)->ssl_version; - if(v) - msnprintf(ssl_ver, sizeof(ssl_ver), - "%.*s", (int) strcspn(v, " "), v); - } - if(config->cacert) my_setopt_str(curl, CURLOPT_CAINFO, config->cacert); if(config->proxy_cacert) @@ -1667,10 +1572,9 @@ static CURLcode single_transfer(struct GlobalConfig *global, if(config->capath) { result = res_setopt_str(curl, CURLOPT_CAPATH, config->capath); if(result == CURLE_NOT_BUILT_IN) { - warnf(global, "ignoring %s, not supported by libcurl with %s", - capath_from_env ? - "SSL_CERT_DIR environment variable" : "--capath", - ssl_ver); + warnf(global, "ignoring %s, not supported by libcurl", + capath_from_env? + "SSL_CERT_DIR environment variable":"--capath"); } else if(result) break; @@ -1685,47 +1589,14 @@ static CURLcode single_transfer(struct GlobalConfig *global, if((result == CURLE_NOT_BUILT_IN) || (result == CURLE_UNKNOWN_OPTION)) { if(config->proxy_capath) { - warnf(global, "ignoring %s, not supported by libcurl with %s", - config->proxy_capath ? - "--proxy-capath" : "--capath", - ssl_ver); + warnf(global, + "ignoring --proxy-capath, not supported by libcurl"); } } else if(result) break; } -#ifdef CURL_CA_EMBED - if(!config->cacert && !config->capath) { - struct curl_blob blob; - blob.data = (void *)curl_ca_embed; - blob.len = strlen((const char *)curl_ca_embed); - blob.flags = CURL_BLOB_NOCOPY; - notef(config->global, - "Using embedded CA bundle (%zu bytes)", - blob.len); - result = curl_easy_setopt(curl, CURLOPT_CAINFO_BLOB, &blob); - if(result == CURLE_NOT_BUILT_IN) { - warnf(global, "ignoring %s, not supported by libcurl with %s", - "embedded CA bundle", ssl_ver); - } - } - if(!config->proxy_cacert && !config->proxy_capath) { - struct curl_blob blob; - blob.data = (void *)curl_ca_embed; - blob.len = strlen((const char *)curl_ca_embed); - blob.flags = CURL_BLOB_NOCOPY; - notef(config->global, - "Using embedded CA bundle, for proxies (%zu bytes)", - blob.len); - result = curl_easy_setopt(curl, CURLOPT_PROXY_CAINFO_BLOB, &blob); - if(result == CURLE_NOT_BUILT_IN) { - warnf(global, "ignoring %s, not supported by libcurl with %s", - "embedded CA bundle", ssl_ver); - } - } -#endif - if(config->crlfile) my_setopt_str(curl, CURLOPT_CRLFILE, config->crlfile); if(config->proxy_crlfile) @@ -1733,20 +1604,8 @@ static CURLcode single_transfer(struct GlobalConfig *global, else if(config->crlfile) /* CURLOPT_PROXY_CRLFILE default is crlfile */ my_setopt_str(curl, CURLOPT_PROXY_CRLFILE, config->crlfile); - if(config->pinnedpubkey) { - result = res_setopt_str(curl, CURLOPT_PINNEDPUBLICKEY, - config->pinnedpubkey); - if(result == CURLE_NOT_BUILT_IN) - warnf(global, "ignoring %s, not supported by libcurl with %s", - "--pinnedpubkey", ssl_ver); - } - if(config->proxy_pinnedpubkey) { - result = res_setopt_str(curl, CURLOPT_PROXY_PINNEDPUBLICKEY, - config->proxy_pinnedpubkey); - if(result == CURLE_NOT_BUILT_IN) - warnf(global, "ignoring %s, not supported by libcurl with %s", - "--proxy-pinnedpubkey", ssl_ver); - } + if(config->pinnedpubkey) + my_setopt_str(curl, CURLOPT_PINNEDPUBLICKEY, config->pinnedpubkey); if(config->ssl_ec_curves) my_setopt_str(curl, CURLOPT_SSL_EC_CURVES, config->ssl_ec_curves); @@ -1800,7 +1659,7 @@ static CURLcode single_transfer(struct GlobalConfig *global, * must do the same thing as classic: * --cert <filename>:<password> --cert-type p12 * but is designed to test blob */ -#ifdef DEBUGBUILD +#if defined(CURLDEBUG) || defined(DEBUGBUILD) if(config->cert && (strlen(config->cert) > 8) && (memcmp(config->cert, "loadmem=",8) == 0)) { FILE *fInCert = fopen(config->cert + 8, "rb"); @@ -1828,7 +1687,7 @@ static CURLcode single_transfer(struct GlobalConfig *global, structblob.len = (size_t)filesize; structblob.flags = CURL_BLOB_COPY; my_setopt_str(curl, CURLOPT_SSLCERT_BLOB, &structblob); - /* if test run well, we are sure we do not reuse + /* if test run well, we are sure we don't reuse * original mem pointer */ memset(certdata, 0, (size_t)filesize); } @@ -1843,7 +1702,7 @@ static CURLcode single_transfer(struct GlobalConfig *global, config->proxy_cert_type); -#ifdef DEBUGBUILD +#if defined(CURLDEBUG) || defined(DEBUGBUILD) if(config->key && (strlen(config->key) > 8) && (memcmp(config->key, "loadmem=",8) == 0)) { FILE *fInCert = fopen(config->key + 8, "rb"); @@ -1871,7 +1730,7 @@ static CURLcode single_transfer(struct GlobalConfig *global, structblob.len = (size_t)filesize; structblob.flags = CURL_BLOB_COPY; my_setopt_str(curl, CURLOPT_SSLKEY_BLOB, &structblob); - /* if test run well, we are sure we do not reuse + /* if test run well, we are sure we don't reuse * original mem pointer */ memset(certdata, 0, (size_t)filesize); } @@ -1884,12 +1743,15 @@ static CURLcode single_transfer(struct GlobalConfig *global, my_setopt_str(curl, CURLOPT_SSLKEYTYPE, config->key_type); my_setopt_str(curl, CURLOPT_PROXY_SSLKEYTYPE, config->proxy_key_type); - - /* libcurl default is strict verifyhost -> 1L, verifypeer -> 1L */ if(config->insecure_ok) { my_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); my_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); } + else { + my_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L); + /* libcurl default is strict verifyhost -> 2L */ + /* my_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L); */ + } if(config->doh_insecure_ok) { my_setopt(curl, CURLOPT_DOH_SSL_VERIFYPEER, 0L); @@ -1900,6 +1762,9 @@ static CURLcode single_transfer(struct GlobalConfig *global, my_setopt(curl, CURLOPT_PROXY_SSL_VERIFYPEER, 0L); my_setopt(curl, CURLOPT_PROXY_SSL_VERIFYHOST, 0L); } + else { + my_setopt(curl, CURLOPT_PROXY_SSL_VERIFYPEER, 1L); + } if(config->verifystatus) my_setopt(curl, CURLOPT_SSL_VERIFYSTATUS, 1L); @@ -1910,11 +1775,11 @@ static CURLcode single_transfer(struct GlobalConfig *global, if(config->falsestart) my_setopt(curl, CURLOPT_SSL_FALSESTART, 1L); - my_setopt_SSLVERSION(curl, CURLOPT_SSLVERSION, - config->ssl_version | config->ssl_version_max); + my_setopt_enum(curl, CURLOPT_SSLVERSION, + config->ssl_version | config->ssl_version_max); if(config->proxy) - my_setopt_SSLVERSION(curl, CURLOPT_PROXY_SSLVERSION, - config->proxy_ssl_version); + my_setopt_enum(curl, CURLOPT_PROXY_SSLVERSION, + config->proxy_ssl_version); { long mask = @@ -2063,34 +1928,19 @@ static CURLcode single_transfer(struct GlobalConfig *global, if(config->doh_url) my_setopt_str(curl, CURLOPT_DOH_URL, config->doh_url); - if(config->cipher_list) { - result = res_setopt_str(curl, CURLOPT_SSL_CIPHER_LIST, - config->cipher_list); - if(result == CURLE_NOT_BUILT_IN) - warnf(global, "ignoring %s, not supported by libcurl with %s", - "--ciphers", ssl_ver); - } - if(config->proxy_cipher_list) { - result = res_setopt_str(curl, CURLOPT_PROXY_SSL_CIPHER_LIST, - config->proxy_cipher_list); - if(result == CURLE_NOT_BUILT_IN) - warnf(global, "ignoring %s, not supported by libcurl with %s", - "--proxy-ciphers", ssl_ver); - } - if(config->cipher13_list) { - result = res_setopt_str(curl, CURLOPT_TLS13_CIPHERS, - config->cipher13_list); - if(result == CURLE_NOT_BUILT_IN) - warnf(global, "ignoring %s, not supported by libcurl with %s", - "--tls13-ciphers", ssl_ver); - } - if(config->proxy_cipher13_list) { - result = res_setopt_str(curl, CURLOPT_PROXY_TLS13_CIPHERS, - config->proxy_cipher13_list); - if(result == CURLE_NOT_BUILT_IN) - warnf(global, "ignoring %s, not supported by libcurl with %s", - "--proxy-tls13-ciphers", ssl_ver); - } + if(config->cipher_list) + my_setopt_str(curl, CURLOPT_SSL_CIPHER_LIST, config->cipher_list); + + if(config->proxy_cipher_list) + my_setopt_str(curl, CURLOPT_PROXY_SSL_CIPHER_LIST, + config->proxy_cipher_list); + + if(config->cipher13_list) + my_setopt_str(curl, CURLOPT_TLS13_CIPHERS, config->cipher13_list); + + if(config->proxy_cipher13_list) + my_setopt_str(curl, CURLOPT_PROXY_TLS13_CIPHERS, + config->proxy_cipher13_list); /* new in libcurl 7.9.2: */ if(config->disable_epsv) @@ -2205,8 +2055,6 @@ static CURLcode single_transfer(struct GlobalConfig *global, my_setopt(curl, CURLOPT_TCP_KEEPIDLE, config->alivetime); my_setopt(curl, CURLOPT_TCP_KEEPINTVL, config->alivetime); } - if(config->alivecnt) - my_setopt(curl, CURLOPT_TCP_KEEPCNT, config->alivecnt); } else my_setopt(curl, CURLOPT_TCP_KEEPALIVE, 0L); @@ -2351,39 +2199,10 @@ static CURLcode single_transfer(struct GlobalConfig *global, if(config->hsts) my_setopt_str(curl, CURLOPT_HSTS, config->hsts); -#ifdef USE_ECH - /* only if enabled in configure */ - if(config->ech) /* only if set (optional) */ - my_setopt_str(curl, CURLOPT_ECH, config->ech); - if(config->ech_public) /* only if set (optional) */ - my_setopt_str(curl, CURLOPT_ECH, config->ech_public); - if(config->ech_config) /* only if set (optional) */ - my_setopt_str(curl, CURLOPT_ECH, config->ech_config); -#endif - - /* new in 8.9.0 */ - if(config->ip_tos > 0 || config->vlan_priority > 0) { -#if defined(IP_TOS) || defined(IPV6_TCLASS) || defined(SO_PRIORITY) - my_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback); - my_setopt(curl, CURLOPT_SOCKOPTDATA, config); -#else - if(config->ip_tos > 0) { - errorf(config->global, - "Type of service is not supported in this build."); - result = CURLE_NOT_BUILT_IN; - } - if(config->vlan_priority > 0) { - errorf(config->global, - "VLAN priority is not supported in this build."); - result = CURLE_NOT_BUILT_IN; - } -#endif - } - /* initialize retry vars for loop below */ per->retry_sleep_default = (config->retry_delay) ? config->retry_delay*1000L : RETRY_SLEEP_DEFAULT; /* ms */ - per->retry_remaining = config->req_retry; + per->retry_numretries = config->req_retry; per->retry_sleep = per->retry_sleep_default; /* ms */ per->retrystart = tvnow(); @@ -2477,7 +2296,7 @@ static CURLcode add_parallel_transfers(struct GlobalConfig *global, if(!errorbuf) return CURLE_OUT_OF_MEMORY; - /* parallel connect means that we do not set PIPEWAIT since pipewait + /* parallel connect means that we don't set PIPEWAIT since pipewait will make libcurl prefer multiplexing */ (void)curl_easy_setopt(per->curl, CURLOPT_PIPEWAIT, global->parallel_connect ? 0L : 1L); @@ -2485,10 +2304,6 @@ static CURLcode add_parallel_transfers(struct GlobalConfig *global, (void)curl_easy_setopt(per->curl, CURLOPT_XFERINFOFUNCTION, xferinfo_cb); (void)curl_easy_setopt(per->curl, CURLOPT_XFERINFODATA, per); (void)curl_easy_setopt(per->curl, CURLOPT_NOPROGRESS, 0L); -#ifdef DEBUGBUILD - if(getenv("CURL_FORBID_REUSE")) - (void)curl_easy_setopt(per->curl, CURLOPT_FORBID_REUSE, 1L); -#endif mcode = curl_multi_add_handle(multi, per->curl); if(mcode) { @@ -2513,386 +2328,136 @@ static CURLcode add_parallel_transfers(struct GlobalConfig *global, return CURLE_OK; } -struct parastate { - struct GlobalConfig *global; +static CURLcode parallel_transfers(struct GlobalConfig *global, + CURLSH *share) +{ CURLM *multi; - CURLSH *share; - CURLMcode mcode; - CURLcode result; - int still_running; - struct timeval start; + CURLMcode mcode = CURLM_OK; + CURLcode result = CURLE_OK; + int still_running = 1; + struct timeval start = tvnow(); bool more_transfers; bool added_transfers; /* wrapitup is set TRUE after a critical error occurs to end all transfers */ - bool wrapitup; + bool wrapitup = FALSE; /* wrapitup_processed is set TRUE after the per transfer abort flag is set */ - bool wrapitup_processed; - time_t tick; -}; - -#if defined(DEBUGBUILD) && defined(USE_LIBUV) - -#define DEBUG_UV 0 - -/* object to pass to the callbacks */ -struct datauv { - uv_timer_t timeout; - uv_loop_t *loop; - struct parastate *s; -}; - -struct contextuv { - uv_poll_t poll_handle; - curl_socket_t sockfd; - struct datauv *uv; -}; - -static CURLcode check_finished(struct parastate *s); - -static void check_multi_info(struct datauv *uv) -{ - CURLcode result; - - result = check_finished(uv->s); - if(result && !uv->s->result) - uv->s->result = result; - - if(uv->s->more_transfers) { - result = add_parallel_transfers(uv->s->global, uv->s->multi, - uv->s->share, - &uv->s->more_transfers, - &uv->s->added_transfers); - if(result && !uv->s->result) - uv->s->result = result; - if(result) - uv_stop(uv->loop); - } -} - -/* callback from libuv on socket activity */ -static void on_uv_socket(uv_poll_t *req, int status, int events) -{ - int flags = 0; - struct contextuv *c = (struct contextuv *) req->data; - (void)status; - if(events & UV_READABLE) - flags |= CURL_CSELECT_IN; - if(events & UV_WRITABLE) - flags |= CURL_CSELECT_OUT; - - curl_multi_socket_action(c->uv->s->multi, c->sockfd, flags, - &c->uv->s->still_running); -} - -/* callback from libuv when timeout expires */ -static void on_uv_timeout(uv_timer_t *req) -{ - struct datauv *uv = (struct datauv *) req->data; -#if DEBUG_UV - fprintf(tool_stderr, "parallel_event: on_uv_timeout\n"); -#endif - if(uv && uv->s) { - curl_multi_socket_action(uv->s->multi, CURL_SOCKET_TIMEOUT, 0, - &uv->s->still_running); - check_multi_info(uv); - } -} - -/* callback from libcurl to update the timeout expiry */ -static int cb_timeout(CURLM *multi, long timeout_ms, - struct datauv *uv) -{ - (void)multi; -#if DEBUG_UV - fprintf(tool_stderr, "parallel_event: cb_timeout=%ld\n", timeout_ms); -#endif - if(timeout_ms < 0) - uv_timer_stop(&uv->timeout); - else { - if(timeout_ms == 0) - timeout_ms = 1; /* 0 means call curl_multi_socket_action asap but NOT - within the callback itself */ - uv_timer_start(&uv->timeout, on_uv_timeout, timeout_ms, - 0); /* do not repeat */ - } - return 0; -} - -static struct contextuv *create_context(curl_socket_t sockfd, - struct datauv *uv) -{ - struct contextuv *c; - - c = (struct contextuv *) malloc(sizeof(*c)); - - c->sockfd = sockfd; - c->uv = uv; - - uv_poll_init_socket(uv->loop, &c->poll_handle, sockfd); - c->poll_handle.data = c; - - return c; -} - -static void close_cb(uv_handle_t *handle) -{ - struct contextuv *c = (struct contextuv *) handle->data; - free(c); -} - -static void destroy_context(struct contextuv *c) -{ - uv_close((uv_handle_t *) &c->poll_handle, close_cb); -} - -/* callback from libcurl to update socket activity to wait for */ -static int cb_socket(CURL *easy, curl_socket_t s, int action, - struct datauv *uv, - void *socketp) -{ - struct contextuv *c; - int events = 0; - (void)easy; - - switch(action) { - case CURL_POLL_IN: - case CURL_POLL_OUT: - case CURL_POLL_INOUT: - c = socketp ? - (struct contextuv *) socketp : create_context(s, uv); - - curl_multi_assign(uv->s->multi, s, c); - - if(action != CURL_POLL_IN) - events |= UV_WRITABLE; - if(action != CURL_POLL_OUT) - events |= UV_READABLE; - - uv_poll_start(&c->poll_handle, events, on_uv_socket); - break; - case CURL_POLL_REMOVE: - if(socketp) { - c = (struct contextuv *)socketp; - uv_poll_stop(&c->poll_handle); - destroy_context(c); - curl_multi_assign(uv->s->multi, s, NULL); - /* check if we can do more now */ - check_multi_info(uv); - } - break; - default: - abort(); - } - - return 0; -} - -static CURLcode parallel_event(struct parastate *s) -{ - CURLcode result = CURLE_OK; - struct datauv uv = { 0 }; - - s->result = CURLE_OK; - uv.s = s; - uv.loop = uv_default_loop(); - uv_timer_init(uv.loop, &uv.timeout); - uv.timeout.data = &uv; - - /* setup event callbacks */ - curl_multi_setopt(s->multi, CURLMOPT_SOCKETFUNCTION, cb_socket); - curl_multi_setopt(s->multi, CURLMOPT_SOCKETDATA, &uv); - curl_multi_setopt(s->multi, CURLMOPT_TIMERFUNCTION, cb_timeout); - curl_multi_setopt(s->multi, CURLMOPT_TIMERDATA, &uv); - - /* kickstart the thing */ - curl_multi_socket_action(s->multi, CURL_SOCKET_TIMEOUT, 0, - &s->still_running); - - while(!s->mcode && (s->still_running || s->more_transfers)) { -#if DEBUG_UV - fprintf(tool_stderr, "parallel_event: uv_run(), mcode=%d, %d running, " - "%d more\n", s->mcode, uv.s->still_running, s->more_transfers); -#endif - uv_run(uv.loop, UV_RUN_DEFAULT); -#if DEBUG_UV - fprintf(tool_stderr, "parallel_event: uv_run() returned\n"); -#endif - - result = check_finished(s); - if(result && !s->result) - s->result = result; + bool wrapitup_processed = FALSE; + time_t tick = time(NULL); - /* early exit called */ - if(s->wrapitup) { - if(s->still_running && !s->wrapitup_processed) { - struct per_transfer *per; - for(per = transfers; per; per = per->next) { - if(per->added) - per->abort = TRUE; - } - s->wrapitup_processed = TRUE; - } - break; - } - - if(s->more_transfers) { - result = add_parallel_transfers(s->global, s->multi, s->share, - &s->more_transfers, &s->added_transfers); - if(result && !s->result) - s->result = result; - } - } - -#if DEBUG_UV - fprintf(tool_stderr, "DONE parallel_event -> %d, mcode=%d, %d running, " - "%d more\n", - s->result, s->mcode, uv.s->still_running, s->more_transfers); -#endif - return s->result; -} - -#endif - -static CURLcode check_finished(struct parastate *s) -{ - CURLcode result = CURLE_OK; - int rc; - CURLMsg *msg; - bool checkmore = FALSE; - struct GlobalConfig *global = s->global; - progress_meter(global, &s->start, FALSE); - do { - msg = curl_multi_info_read(s->multi, &rc); - if(msg) { - bool retry; - long delay; - struct per_transfer *ended; - CURL *easy = msg->easy_handle; - CURLcode tres = msg->data.result; - curl_easy_getinfo(easy, CURLINFO_PRIVATE, (void *)&ended); - curl_multi_remove_handle(s->multi, easy); - - if(ended->abort && (tres == CURLE_ABORTED_BY_CALLBACK) && - ended->errorbuffer) { - msnprintf(ended->errorbuffer, CURL_ERROR_SIZE, - "Transfer aborted due to critical error " - "in another transfer"); - } - tres = post_per_transfer(global, ended, tres, &retry, &delay); - progress_finalize(ended); /* before it goes away */ - all_added--; /* one fewer added */ - checkmore = TRUE; - if(retry) { - ended->added = FALSE; /* add it again */ - /* we delay retries in full integer seconds only */ - ended->startat = delay ? time(NULL) + delay/1000 : 0; - } - else { - /* result receives this transfer's error unless the transfer was - marked for abort due to a critical error in another transfer */ - if(tres && (!ended->abort || !result)) - result = tres; - if(is_fatal_error(result) || (result && global->fail_early)) - s->wrapitup = TRUE; - (void)del_per_transfer(ended); - } - } - } while(msg); - if(!s->wrapitup) { - if(!checkmore) { - time_t tock = time(NULL); - if(s->tick != tock) { - checkmore = TRUE; - s->tick = tock; - } - } - if(checkmore) { - /* one or more transfers completed, add more! */ - CURLcode tres = add_parallel_transfers(global, s->multi, s->share, - &s->more_transfers, - &s->added_transfers); - if(tres) - result = tres; - if(s->added_transfers) - /* we added new ones, make sure the loop does not exit yet */ - s->still_running = 1; - } - if(is_fatal_error(result) || (result && global->fail_early)) - s->wrapitup = TRUE; - } - return result; -} - -static CURLcode parallel_transfers(struct GlobalConfig *global, - CURLSH *share) -{ - CURLcode result; - struct parastate p; - struct parastate *s = &p; - s->share = share; - s->mcode = CURLM_OK; - s->result = CURLE_OK; - s->still_running = 1; - s->start = tvnow(); - s->wrapitup = FALSE; - s->wrapitup_processed = FALSE; - s->tick = time(NULL); - s->global = global; - s->multi = curl_multi_init(); - if(!s->multi) + multi = curl_multi_init(); + if(!multi) return CURLE_OUT_OF_MEMORY; - result = add_parallel_transfers(global, s->multi, s->share, - &s->more_transfers, &s->added_transfers); + result = add_parallel_transfers(global, multi, share, + &more_transfers, &added_transfers); if(result) { - curl_multi_cleanup(s->multi); + curl_multi_cleanup(multi); return result; } -#ifdef DEBUGBUILD - if(global->test_event_based) -#ifdef USE_LIBUV - result = parallel_event(s); -#else - errorf(global, "Testing --parallel event-based requires libuv"); -#endif - else -#endif - while(!s->mcode && (s->still_running || s->more_transfers)) { + while(!mcode && (still_running || more_transfers)) { /* If stopping prematurely (eg due to a --fail-early condition) then signal that any transfers in the multi should abort (via progress callback). */ - if(s->wrapitup) { - if(!s->still_running) + if(wrapitup) { + if(!still_running) break; - if(!s->wrapitup_processed) { + if(!wrapitup_processed) { struct per_transfer *per; for(per = transfers; per; per = per->next) { if(per->added) per->abort = TRUE; } - s->wrapitup_processed = TRUE; + wrapitup_processed = TRUE; } } - s->mcode = curl_multi_poll(s->multi, NULL, 0, 1000, NULL); - if(!s->mcode) - s->mcode = curl_multi_perform(s->multi, &s->still_running); - - if(!s->mcode) - result = check_finished(s); + mcode = curl_multi_poll(multi, NULL, 0, 1000, NULL); + if(!mcode) + mcode = curl_multi_perform(multi, &still_running); + + progress_meter(global, &start, FALSE); + + if(!mcode) { + int rc; + CURLMsg *msg; + bool checkmore = FALSE; + do { + msg = curl_multi_info_read(multi, &rc); + if(msg) { + bool retry; + long delay; + struct per_transfer *ended; + CURL *easy = msg->easy_handle; + CURLcode tres = msg->data.result; + curl_easy_getinfo(easy, CURLINFO_PRIVATE, (void *)&ended); + curl_multi_remove_handle(multi, easy); + + if(ended->abort && (tres == CURLE_ABORTED_BY_CALLBACK) && + ended->errorbuffer) { + msnprintf(ended->errorbuffer, CURL_ERROR_SIZE, + "Transfer aborted due to critical error " + "in another transfer"); + } + tres = post_per_transfer(global, ended, tres, &retry, &delay); + progress_finalize(ended); /* before it goes away */ + all_added--; /* one fewer added */ + checkmore = TRUE; + if(retry) { + ended->added = FALSE; /* add it again */ + /* we delay retries in full integer seconds only */ + ended->startat = delay ? time(NULL) + delay/1000 : 0; + } + else { + /* result receives this transfer's error unless the transfer was + marked for abort due to a critical error in another transfer */ + if(tres && (!ended->abort || !result)) + result = tres; + if(is_fatal_error(result) || (result && global->fail_early)) + wrapitup = TRUE; + (void)del_per_transfer(ended); + } + } + } while(msg); + if(wrapitup) { + if(still_running) + continue; + else + break; + } + if(!checkmore) { + time_t tock = time(NULL); + if(tick != tock) { + checkmore = TRUE; + tick = tock; + } + } + if(checkmore) { + /* one or more transfers completed, add more! */ + CURLcode tres = add_parallel_transfers(global, multi, share, + &more_transfers, + &added_transfers); + if(tres) + result = tres; + if(added_transfers) + /* we added new ones, make sure the loop doesn't exit yet */ + still_running = 1; + } + if(is_fatal_error(result) || (result && global->fail_early)) + wrapitup = TRUE; + } } - (void)progress_meter(global, &s->start, TRUE); + (void)progress_meter(global, &start, TRUE); /* Make sure to return some kind of error if there was a multi problem */ - if(s->mcode) { - result = (s->mcode == CURLM_OUT_OF_MEMORY) ? CURLE_OUT_OF_MEMORY : + if(mcode) { + result = (mcode == CURLM_OUT_OF_MEMORY) ? CURLE_OUT_OF_MEMORY : /* The other multi errors should never happen, so return something suitably generic */ CURLE_BAD_FUNCTION_ARGUMENT; } - curl_multi_cleanup(s->multi); + curl_multi_cleanup(multi); return result; } @@ -2917,29 +2482,22 @@ static CURLcode serial_transfers(struct GlobalConfig *global, long delay_ms; bool bailout = FALSE; struct timeval start; + result = pre_transfer(global, per); + if(result) + break; - start = tvnow(); - if(!per->skip) { - result = pre_transfer(global, per); + if(global->libcurl) { + result = easysrc_perform(); if(result) break; - - if(global->libcurl) { - result = easysrc_perform(); - if(result) - break; - } - -#ifdef DEBUGBUILD - if(getenv("CURL_FORBID_REUSE")) - (void)curl_easy_setopt(per->curl, CURLOPT_FORBID_REUSE, 1L); - - if(global->test_event_based) - result = curl_easy_perform_ev(per->curl); - else -#endif - result = curl_easy_perform(per->curl); } + start = tvnow(); +#ifdef CURLDEBUG + if(global->test_event_based) + result = curl_easy_perform_ev(per->curl); + else +#endif + result = curl_easy_perform(per->curl); returncode = post_per_transfer(global, per, result, &retry, &delay_ms); if(retry) { @@ -3002,10 +2560,10 @@ static CURLcode transfer_per_config(struct GlobalConfig *global, return CURLE_FAILED_INIT; } - /* On Windows we cannot set the path to curl-ca-bundle.crt at compile time. - * We look for the file in two ways: + /* On WIN32 we can't set the path to curl-ca-bundle.crt + * at compile time. So we look here for the file in two ways: * 1: look at the environment variable CURL_CA_BUNDLE for a path - * 2: if #1 is not found, use the Windows API function SearchPath() + * 2: if #1 isn't found, use the windows API function SearchPath() * to find it along the app's path (includes app's dir and CWD) * * We support the environment variable thing for non-Windows platforms @@ -3039,33 +2597,34 @@ static CURLcode transfer_per_config(struct GlobalConfig *global, */ if(tls_backend_info->backend != CURLSSLBACKEND_SCHANNEL) { char *env; - env = curl_getenv("CURL_CA_BUNDLE"); + env = curlx_getenv("CURL_CA_BUNDLE"); if(env) { config->cacert = strdup(env); - curl_free(env); if(!config->cacert) { + curl_free(env); curl_easy_cleanup(curltls); errorf(global, "out of memory"); return CURLE_OUT_OF_MEMORY; } } else { - env = curl_getenv("SSL_CERT_DIR"); + env = curlx_getenv("SSL_CERT_DIR"); if(env) { config->capath = strdup(env); - curl_free(env); if(!config->capath) { + curl_free(env); curl_easy_cleanup(curltls); errorf(global, "out of memory"); return CURLE_OUT_OF_MEMORY; } + curl_free(env); capath_from_env = true; } - env = curl_getenv("SSL_CERT_FILE"); + env = curlx_getenv("SSL_CERT_FILE"); if(env) { config->cacert = strdup(env); - curl_free(env); if(!config->cacert) { + curl_free(env); if(capath_from_env) free(config->capath); curl_easy_cleanup(curltls); @@ -3075,10 +2634,13 @@ static CURLcode transfer_per_config(struct GlobalConfig *global, } } + if(env) + curl_free(env); #ifdef _WIN32 - if(!env) + else { result = FindWin32CACert(config, tls_backend_info->backend, TEXT("curl-ca-bundle.crt")); + } #endif } curl_easy_cleanup(curltls); @@ -3135,7 +2697,7 @@ static CURLcode run_all_transfers(struct GlobalConfig *global, long delay; CURLcode result2 = post_per_transfer(global, per, result, &retry, &delay); if(!result) - /* do not overwrite the original error */ + /* don't overwrite the original error */ result = result2; /* Free list of given URLs */ @@ -3166,7 +2728,7 @@ CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[]) /* Parse .curlrc if necessary */ if((argc == 1) || (first_arg && strncmp(first_arg, "-q", 2) && - strcmp(first_arg, "--disable"))) { + !curl_strequal(first_arg, "--disable"))) { parseconfig(NULL, global); /* ignore possible failure */ /* If we had no arguments then make sure a url was specified in .curlrc */ @@ -3196,12 +2758,6 @@ CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[]) /* Check if we were asked to list the SSL engines */ else if(res == PARAM_ENGINES_REQUESTED) tool_list_engines(); - /* Check if we were asked to dump the embedded CA bundle */ - else if(res == PARAM_CA_EMBED_REQUESTED) { -#ifdef CURL_CA_EMBED - printf("%s", curl_ca_embed); -#endif - } else if(res == PARAM_LIBCURL_UNSUPPORTED_PROTOCOL) result = CURLE_UNSUPPORTED_PROTOCOL; else if(res == PARAM_READ_ERROR) diff --git a/contrib/libs/curl/src/tool_operate.h b/contrib/libs/curl/src/tool_operate.h index a2bd83b10b..4993b1c961 100644 --- a/contrib/libs/curl/src/tool_operate.h +++ b/contrib/libs/curl/src/tool_operate.h @@ -35,25 +35,33 @@ struct per_transfer { struct OperationConfig *config; /* for this transfer */ struct curl_certinfo *certinfo; CURL *curl; - long retry_remaining; + long retry_numretries; long retry_sleep_default; long retry_sleep; - long num_retries; /* counts the performed retries */ struct timeval start; /* start of this transfer */ struct timeval retrystart; char *this_url; unsigned int urlnum; /* the index of the given URL */ char *outfile; + bool infdopen; /* TRUE if infd needs closing */ int infd; + bool noprogress; struct ProgressData progressbar; struct OutStruct outs; struct OutStruct heads; struct OutStruct etag_save; struct HdrCbData hdrcbdata; long num_headers; + bool was_last_header_empty; + + bool added; /* set TRUE when added to the multi handle */ time_t startat; /* when doing parallel transfers, this is a retry transfer that has been set to sleep until this time before it should get started (again) */ + bool abort; /* when doing parallel transfers and this is TRUE then a critical + error (eg --fail-early) has occurred in another transfer and + this transfer will be aborted in the progress callback */ + /* for parallel progress bar */ curl_off_t dltotal; curl_off_t dlnow; @@ -68,15 +76,6 @@ struct per_transfer { char *uploadfile; char *errorbuffer; /* allocated and assigned while this is used for a transfer */ - bool infdopen; /* TRUE if infd needs closing */ - bool noprogress; - bool was_last_header_empty; - - bool added; /* set TRUE when added to the multi handle */ - bool abort; /* when doing parallel transfers and this is TRUE then a critical - error (eg --fail-early) has occurred in another transfer and - this transfer will be aborted in the progress callback */ - bool skip; /* considered already done */ }; CURLcode operate(struct GlobalConfig *config, int argc, argv_item_t argv[]); diff --git a/contrib/libs/curl/src/tool_operhlp.c b/contrib/libs/curl/src/tool_operhlp.c index 0ed441c3f6..d1e8352d88 100644 --- a/contrib/libs/curl/src/tool_operhlp.c +++ b/contrib/libs/curl/src/tool_operhlp.c @@ -26,12 +26,13 @@ #include "strcase.h" +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" #include "tool_doswin.h" #include "tool_operhlp.h" -#include "tool_msgs.h" #include "memdebug.h" /* keep this as LAST include */ @@ -85,7 +86,7 @@ CURLcode urlerr_cvt(CURLUcode ucode) } /* - * Adds the filename to the URL if it does not already have one. + * Adds the file name to the URL if it doesn't already have one. * url will be freed before return if the returned pointer is different */ CURLcode add_file_name_to_url(CURL *curl, char **inurlp, const char *filename) @@ -117,7 +118,7 @@ CURLcode add_file_name_to_url(CURL *curl, char **inurlp, const char *filename) } ptr = strrchr(path, '/'); if(!ptr || !*++ptr) { - /* The URL path has no filename part, add the local filename. In order + /* The URL path has no file name part, add the local file name. In order to be able to do so, we have to create a new URL in another buffer.*/ /* We only want the part of the local path that is on the right @@ -133,7 +134,7 @@ CURLcode add_file_name_to_url(CURL *curl, char **inurlp, const char *filename) else filep = filename; - /* URL encode the filename */ + /* URL encode the file name */ encfile = curl_easy_escape(curl, filep, 0 /* use strlen */); if(encfile) { char *newpath; @@ -179,9 +180,9 @@ fail: * Returns a pointer to a heap-allocated string or NULL if * no name part, at location indicated by first argument. */ -CURLcode get_url_file_name(struct GlobalConfig *global, - char **filename, const char *url) +CURLcode get_url_file_name(char **filename, const char *url) { + const char *pc, *pc2; CURLU *uh = curl_url(); char *path = NULL; CURLUcode uerr; @@ -194,31 +195,20 @@ CURLcode get_url_file_name(struct GlobalConfig *global, uerr = curl_url_set(uh, CURLUPART_URL, url, CURLU_GUESS_SCHEME); if(!uerr) { uerr = curl_url_get(uh, CURLUPART_PATH, &path, 0); - curl_url_cleanup(uh); - uh = NULL; if(!uerr) { - int i; - char *pc = NULL, *pc2 = NULL; - for(i = 0; i < 2; i++) { - pc = strrchr(path, '/'); - pc2 = strrchr(pc ? pc + 1 : path, '\\'); - if(pc2) - pc = pc2; - if(pc && !pc[1] && !i) { - /* if the path ends with slash, try removing the trailing one - and get the last directory part */ - *pc = 0; - } - } + curl_url_cleanup(uh); + + pc = strrchr(path, '/'); + pc2 = strrchr(pc ? pc + 1 : path, '\\'); + if(pc2) + pc = pc2; if(pc) /* duplicate the string beyond the slash */ pc++; - else { - /* no slash => empty string, use default */ - pc = (char *)"curl_response"; - warnf(global, "No remote file name, uses \"%s\"", pc); - } + else + /* no slash => empty string */ + pc = ""; *filename = strdup(pc); curl_free(path); @@ -240,12 +230,12 @@ CURLcode get_url_file_name(struct GlobalConfig *global, #endif /* _WIN32 || MSDOS */ /* in case we built debug enabled, we allow an environment variable - * named CURL_TESTDIR to prefix the given filename to put it into a + * named CURL_TESTDIR to prefix the given file name to put it into a * specific directory */ #ifdef DEBUGBUILD { - char *tdir = curl_getenv("CURL_TESTDIR"); + char *tdir = curlx_getenv("CURL_TESTDIR"); if(tdir) { char *alt = aprintf("%s/%s", tdir, *filename); Curl_safefree(*filename); diff --git a/contrib/libs/curl/src/tool_operhlp.h b/contrib/libs/curl/src/tool_operhlp.h index 19daa8e430..1d56fa0408 100644 --- a/contrib/libs/curl/src/tool_operhlp.h +++ b/contrib/libs/curl/src/tool_operhlp.h @@ -35,8 +35,7 @@ bool stdin_upload(const char *uploadfile); CURLcode add_file_name_to_url(CURL *curl, char **inurlp, const char *filename); -CURLcode get_url_file_name(struct GlobalConfig *global, - char **filename, const char *url); +CURLcode get_url_file_name(char **filename, const char *url); CURLcode urlerr_cvt(CURLUcode ucode); diff --git a/contrib/libs/curl/src/tool_paramhlp.c b/contrib/libs/curl/src/tool_paramhlp.c index d4024e1340..d70e80db4b 100644 --- a/contrib/libs/curl/src/tool_paramhlp.c +++ b/contrib/libs/curl/src/tool_paramhlp.c @@ -25,6 +25,8 @@ #include "strcase.h" +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" @@ -61,75 +63,40 @@ struct getout *new_getout(struct OperationConfig *config) return node; } -#define ISCRLF(x) (((x) == '\r') || ((x) == '\n') || ((x) == '\0')) - -/* memcrlf() has two modes. Both operate on a given memory area with - a specified size. - - countcrlf FALSE - return number of bytes from the start that DO NOT include - any CR or LF or NULL - - countcrlf TRUE - return number of bytes from the start that are ONLY CR or - LF or NULL. - -*/ -static size_t memcrlf(char *orig, - bool countcrlf, /* TRUE if we count CRLF, FALSE - if we count non-CRLF */ - size_t max) -{ - char *ptr; - size_t total = max; - for(ptr = orig; max; max--, ptr++) { - bool crlf = ISCRLF(*ptr); - if(countcrlf ^ crlf) - return ptr - orig; - } - return total; /* no delimiter found */ -} - -#define MAX_FILE2STRING MAX_FILE2MEMORY +#define MAX_FILE2STRING (256*1024*1024) /* big enough ? */ ParameterError file2string(char **bufp, FILE *file) { struct curlx_dynbuf dyn; + DEBUGASSERT(MAX_FILE2STRING < INT_MAX); /* needs to fit in an int later */ curlx_dyn_init(&dyn, MAX_FILE2STRING); if(file) { - do { - char buffer[4096]; - char *ptr; - size_t nread = fread(buffer, 1, sizeof(buffer), file); - if(ferror(file)) { - curlx_dyn_free(&dyn); - *bufp = NULL; - return PARAM_READ_ERROR; - } - ptr = buffer; - while(nread) { - size_t nlen = memcrlf(ptr, FALSE, nread); - if(curlx_dyn_addn(&dyn, ptr, nlen)) - return PARAM_NO_MEM; - nread -= nlen; - - if(nread) { - ptr += nlen; - nlen = memcrlf(ptr, TRUE, nread); - ptr += nlen; - nread -= nlen; - } - } - } while(!feof(file)); + char buffer[256]; + + while(fgets(buffer, sizeof(buffer), file)) { + char *ptr = strchr(buffer, '\r'); + if(ptr) + *ptr = '\0'; + ptr = strchr(buffer, '\n'); + if(ptr) + *ptr = '\0'; + if(curlx_dyn_add(&dyn, buffer)) + return PARAM_NO_MEM; + } } *bufp = curlx_dyn_ptr(&dyn); return PARAM_OK; } +#define MAX_FILE2MEMORY (1024*1024*1024) /* big enough ? */ + ParameterError file2memory(char **bufp, size_t *size, FILE *file) { if(file) { size_t nread; struct curlx_dynbuf dyn; /* The size needs to fit in an int later */ + DEBUGASSERT(MAX_FILE2MEMORY < INT_MAX); curlx_dyn_init(&dyn, MAX_FILE2MEMORY); do { char buffer[4096]; @@ -167,8 +134,6 @@ static ParameterError getnum(long *val, const char *str, int base) if(str) { char *endptr = NULL; long num; - if(!str[0]) - return PARAM_BLANK_STRING; errno = 0; num = strtol(str, &endptr, base); if(errno == ERANGE) @@ -395,7 +360,7 @@ ParameterError proto2num(struct OperationConfig *config, protoset_set(protoset, p); } - /* Allow strtok() here since this is not used threaded */ + /* Allow strtok() here since this isn't used threaded */ /* !checksrc! disable BANNEDFUNC 2 */ for(token = strtok(buffer, sep); token; @@ -443,7 +408,7 @@ ParameterError proto2num(struct OperationConfig *config, break; case set: protoset[0] = NULL; - FALLTHROUGH(); + /* FALLTHROUGH */ case allow: protoset_set(protoset, p); break; @@ -504,7 +469,7 @@ ParameterError str2offset(curl_off_t *val, const char *str) { char *endptr; if(str[0] == '-') - /* offsets are not negative, this indicates weird input */ + /* offsets aren't negative, this indicates weird input */ return PARAM_NEGATIVE_NUMERIC; #if(SIZEOF_CURL_OFF_T > SIZEOF_LONG) @@ -557,13 +522,13 @@ static CURLcode checkpasswd(const char *kind, /* for what purpose */ /* build a nice-looking prompt */ if(!i && last) - msnprintf(prompt, sizeof(prompt), - "Enter %s password for user '%s':", - kind, *userpwd); + curlx_msnprintf(prompt, sizeof(prompt), + "Enter %s password for user '%s':", + kind, *userpwd); else - msnprintf(prompt, sizeof(prompt), - "Enter %s password for user '%s' on URL #%zu:", - kind, *userpwd, i + 1); + curlx_msnprintf(prompt, sizeof(prompt), + "Enter %s password for user '%s' on URL #%zu:", + kind, *userpwd, i + 1); /* get password */ getpass_r(prompt, passwd, sizeof(passwd)); diff --git a/contrib/libs/curl/src/tool_paramhlp.h b/contrib/libs/curl/src/tool_paramhlp.h index bd703afc8c..edb8781950 100644 --- a/contrib/libs/curl/src/tool_paramhlp.h +++ b/contrib/libs/curl/src/tool_paramhlp.h @@ -30,12 +30,6 @@ struct getout *new_getout(struct OperationConfig *config); ParameterError file2string(char **bufp, FILE *file); -#if SIZEOF_SIZE_T > 4 -#define MAX_FILE2MEMORY (16LL*1024*1024*1024) -#else -#define MAX_FILE2MEMORY (INT_MAX) -#endif - ParameterError file2memory(char **bufp, size_t *size, FILE *file); ParameterError str2num(long *val, const char *str); diff --git a/contrib/libs/curl/src/tool_parsecfg.c b/contrib/libs/curl/src/tool_parsecfg.c index 6da5a92500..da48700663 100644 --- a/contrib/libs/curl/src/tool_parsecfg.c +++ b/contrib/libs/curl/src/tool_parsecfg.c @@ -23,6 +23,8 @@ ***************************************************************************/ #include "tool_setup.h" +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" @@ -49,7 +51,7 @@ static FILE *execpath(const char *filename, char **pathp) { static char filebuffer[512]; /* Get the filename of our executable. GetModuleFileName is already declared - * via inclusions done in setup header file. We assume that we are using + * via inclusions done in setup header file. We assume that we are using * the ASCII version here. */ unsigned long len = GetModuleFileNameA(0, filebuffer, sizeof(filebuffer)); @@ -123,12 +125,12 @@ int parseconfig(const char *filename, struct GlobalConfig *global) int lineno = 0; bool dashed_option; struct curlx_dynbuf buf; - bool fileerror = FALSE; + bool fileerror; curlx_dyn_init(&buf, MAX_CONFIG_LINE_LENGTH); DEBUGASSERT(filename); - while(!rc && my_get_line(file, &buf, &fileerror)) { - ParameterError res; + while(my_get_line(file, &buf, &fileerror)) { + int res; bool alloced_param = FALSE; lineno++; line = curlx_dyn_ptr(&buf); @@ -194,7 +196,7 @@ int parseconfig(const char *filename, struct GlobalConfig *global) if(*line) { *line = '\0'; /* null-terminate */ - /* to detect mistakes better, see if there is data following */ + /* to detect mistakes better, see if there's data following */ line++; /* pass all spaces */ while(*line && ISSPACE(*line)) @@ -215,7 +217,7 @@ int parseconfig(const char *filename, struct GlobalConfig *global) } if(!*param) /* do this so getparameter can check for required parameters. - Otherwise it always thinks there is a parameter. */ + Otherwise it always thinks there's a parameter. */ param = NULL; } @@ -226,7 +228,7 @@ int parseconfig(const char *filename, struct GlobalConfig *global) operation = global->last; if(!res && param && *param && !usedarg) - /* we passed in a parameter that was not used! */ + /* we passed in a parameter that wasn't used! */ res = PARAM_GOT_EXTRA_PARAMETER; if(res == PARAM_NEXT_OPERATION) { @@ -253,19 +255,17 @@ int parseconfig(const char *filename, struct GlobalConfig *global) } if(res != PARAM_OK && res != PARAM_NEXT_OPERATION) { - /* the help request is not really an error */ + /* the help request isn't really an error */ if(!strcmp(filename, "-")) { filename = "<stdin>"; } if(res != PARAM_HELP_REQUESTED && res != PARAM_MANUAL_REQUESTED && res != PARAM_VERSION_INFO_REQUESTED && - res != PARAM_ENGINES_REQUESTED && - res != PARAM_CA_EMBED_REQUESTED) { + res != PARAM_ENGINES_REQUESTED) { const char *reason = param2text(res); - errorf(operation->global, "%s:%d: '%s' %s", - filename, lineno, option, reason); - rc = (int)res; + warnf(operation->global, "%s:%d: warning: '%s' %s", + filename, lineno, option, reason); } } @@ -281,7 +281,7 @@ int parseconfig(const char *filename, struct GlobalConfig *global) rc = 1; } else - rc = 1; /* could not open the file */ + rc = 1; /* couldn't open the file */ free(pathalloc); return rc; @@ -292,7 +292,7 @@ int parseconfig(const char *filename, struct GlobalConfig *global) * backslash-quoted characters and NUL-terminating the output string. * Stops at the first non-backslash-quoted double quote character or the * end of the input string. param must be at least as long as the input - * string. Returns the pointer after the last handled input character. + * string. Returns the pointer after the last handled input character. */ static const char *unslashquote(const char *line, char *param) { @@ -340,7 +340,7 @@ static bool my_get_line(FILE *fp, struct curlx_dynbuf *db, /* fgets() returns s on success, and NULL on error or when end of file occurs while no characters have been read. */ if(!fgets(buf, sizeof(buf), fp)) - /* only if there is data in the line, return TRUE */ + /* only if there's data in the line, return TRUE */ return curlx_dyn_len(db) ? TRUE : FALSE; if(curlx_dyn_add(db, buf)) { *error = TRUE; /* error */ diff --git a/contrib/libs/curl/src/tool_progress.c b/contrib/libs/curl/src/tool_progress.c index 3fac70a70e..db8679deb0 100644 --- a/contrib/libs/curl/src/tool_progress.c +++ b/contrib/libs/curl/src/tool_progress.c @@ -26,6 +26,8 @@ #include "tool_progress.h" #include "tool_util.h" +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" /* The point of this function would be to return a string of the input data, @@ -46,13 +48,13 @@ static char *max5data(curl_off_t bytes, char *max5) msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "k", bytes/ONE_KILOBYTE); else if(bytes < CURL_OFF_T_C(100) * ONE_MEGABYTE) - /* 'XX.XM' is good as long as we are less than 100 megs */ + /* 'XX.XM' is good as long as we're less than 100 megs */ msnprintf(max5, 6, "%2" CURL_FORMAT_CURL_OFF_T ".%0" CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE, (bytes%ONE_MEGABYTE) / (ONE_MEGABYTE/CURL_OFF_T_C(10)) ); else if(bytes < CURL_OFF_T_C(10000) * ONE_MEGABYTE) - /* 'XXXXM' is good until we are at 10000MB or above */ + /* 'XXXXM' is good until we're at 10000MB or above */ msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE); else if(bytes < CURL_OFF_T_C(100) * ONE_GIGABYTE) @@ -73,7 +75,7 @@ static char *max5data(curl_off_t bytes, char *max5) /* up to 10000PB, display without decimal: XXXXP */ msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "P", bytes/ONE_PETABYTE); - /* 16384 petabytes (16 exabytes) is the maximum a 64-bit unsigned number can + /* 16384 petabytes (16 exabytes) is the maximum a 64 bit unsigned number can hold, but our data type is signed so 8192PB will be the maximum. */ return max5; } diff --git a/contrib/libs/curl/src/tool_sdecls.h b/contrib/libs/curl/src/tool_sdecls.h index 2dee9d3149..b93c324624 100644 --- a/contrib/libs/curl/src/tool_sdecls.h +++ b/contrib/libs/curl/src/tool_sdecls.h @@ -29,7 +29,7 @@ * OutStruct variables keep track of information relative to curl's * output writing, which may take place to a standard stream or a file. * - * 'filename' member is either a pointer to a filename string or NULL + * 'filename' member is either a pointer to a file name string or NULL * when dealing with a standard stream. * * 'alloc_filename' member is TRUE when string pointed by 'filename' has been @@ -40,7 +40,7 @@ * * 's_isreg' member is TRUE when output goes to a regular file, this also * implies that output is 'seekable' and 'appendable' and also that member - * 'filename' points to filename's string. For any standard stream member + * 'filename' points to file name's string. For any standard stream member * 's_isreg' will be FALSE. * * 'fopened' member is TRUE when output goes to a regular file and it @@ -93,7 +93,7 @@ struct getout { #define GETOUT_OUTFILE (1<<0) /* set when outfile is deemed done */ #define GETOUT_URL (1<<1) /* set when URL is deemed done */ -#define GETOUT_USEREMOTE (1<<2) /* use remote filename locally */ +#define GETOUT_USEREMOTE (1<<2) /* use remote file name locally */ #define GETOUT_UPLOAD (1<<3) /* if set, -T has been used */ #define GETOUT_NOUPLOAD (1<<4) /* if set, -T "" has been used */ @@ -114,12 +114,12 @@ typedef enum { */ typedef enum { - TOOL_HTTPREQ_UNSPEC, /* first in list */ - TOOL_HTTPREQ_GET, - TOOL_HTTPREQ_HEAD, - TOOL_HTTPREQ_MIMEPOST, - TOOL_HTTPREQ_SIMPLEPOST, - TOOL_HTTPREQ_PUT + HTTPREQ_UNSPEC, /* first in list */ + HTTPREQ_GET, + HTTPREQ_HEAD, + HTTPREQ_MIMEPOST, + HTTPREQ_SIMPLEPOST, + HTTPREQ_PUT } HttpReq; diff --git a/contrib/libs/curl/src/tool_setopt.c b/contrib/libs/curl/src/tool_setopt.c index 52ae0f9607..de3b78fab5 100644 --- a/contrib/libs/curl/src/tool_setopt.c +++ b/contrib/libs/curl/src/tool_setopt.c @@ -25,6 +25,8 @@ #ifndef CURL_DISABLE_LIBCURL_OPTION +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" @@ -76,6 +78,7 @@ const struct NameValueUnsigned setopt_nv_CURLAUTH[] = { NV(CURLAUTH_GSSNEGOTIATE), NV(CURLAUTH_NTLM), NV(CURLAUTH_DIGEST_IE), + NV(CURLAUTH_NTLM_WB), NV(CURLAUTH_ONLY), NV(CURLAUTH_NONE), NVEND, @@ -104,16 +107,6 @@ const struct NameValue setopt_nv_CURL_SSLVERSION[] = { NVEND, }; -const struct NameValue setopt_nv_CURL_SSLVERSION_MAX[] = { - NV(CURL_SSLVERSION_MAX_NONE), - NV(CURL_SSLVERSION_MAX_DEFAULT), - NV(CURL_SSLVERSION_MAX_TLSv1_0), - NV(CURL_SSLVERSION_MAX_TLSv1_1), - NV(CURL_SSLVERSION_MAX_TLSv1_2), - NV(CURL_SSLVERSION_MAX_TLSv1_3), - NVEND, -}; - const struct NameValue setopt_nv_CURL_TIMECOND[] = { NV(CURL_TIMECOND_IFMODSINCE), NV(CURL_TIMECOND_IFUNMODSINCE), @@ -205,7 +198,7 @@ static const struct NameValue setopt_nv_CURLNONZERODEFAULTS[] = { #define REM1(f,a) ADDF((&easysrc_toohard, f,a)) #define REM3(f,a,b,c) ADDF((&easysrc_toohard, f,a,b,c)) -/* Escape string to C string syntax. Return NULL if out of memory. +/* Escape string to C string syntax. Return NULL if out of memory. * Is this correct for those wacky EBCDIC guys? */ #define MAX_STRING_LENGTH_OUTPUT 2000 @@ -247,10 +240,14 @@ static char *c_escape(const char *str, curl_off_t len) if(p && *p) result = curlx_dyn_addn(&escaped, to + 2 * (p - from), 2); else { - result = curlx_dyn_addf(&escaped, - /* Octal escape to avoid >2 digit hex. */ - (len > 1 && ISXDIGIT(s[1])) ? - "\\%03o" : "\\x%02x", + const char *format = "\\x%02x"; + + if(len > 1 && ISXDIGIT(s[1])) { + /* Octal escape to avoid >2 digit hex. */ + format = "\\%03o"; + } + + result = curlx_dyn_addf(&escaped, format, (unsigned int) *(unsigned char *) s); } } @@ -303,50 +300,6 @@ nomem: return ret; } -/* setopt wrapper for CURLOPT_SSLVERSION */ -CURLcode tool_setopt_SSLVERSION(CURL *curl, struct GlobalConfig *config, - const char *name, CURLoption tag, - long lval) -{ - CURLcode ret = CURLE_OK; - bool skip = FALSE; - - ret = curl_easy_setopt(curl, tag, lval); - if(!lval) - skip = TRUE; - - if(config->libcurl && !skip && !ret) { - /* we only use this for real if --libcurl was used */ - const struct NameValue *nv = NULL; - const struct NameValue *nv2 = NULL; - for(nv = setopt_nv_CURL_SSLVERSION; nv->name; nv++) { - if(nv->value == (lval & 0xffff)) - break; /* found it */ - } - for(nv2 = setopt_nv_CURL_SSLVERSION_MAX; nv2->name; nv2++) { - if(nv2->value == (lval & ~0xffff)) - break; /* found it */ - } - if(!nv->name) { - /* If no definition was found, output an explicit value. - * This could happen if new values are defined and used - * but the NameValue list is not updated. */ - CODE2("curl_easy_setopt(hnd, %s, %ldL);", name, lval); - } - else { - CODE3("curl_easy_setopt(hnd, %s, (long)(%s | %s));", - name, nv->name, nv2->name); - } - } - -#ifdef DEBUGBUILD - if(ret) - warnf(config, "option %s returned error (%d)", name, (int)ret); -#endif -nomem: - return ret; -} - /* setopt wrapper for bitmasks */ CURLcode tool_setopt_bitmask(CURL *curl, struct GlobalConfig *config, const char *name, CURLoption tag, @@ -478,7 +431,7 @@ static CURLcode libcurl_generate_mime_part(CURL *curl, case TOOLMIME_STDIN: if(!filename) filename = "-"; - FALLTHROUGH(); + /* FALLTHROUGH */ case TOOLMIME_STDINDATA: /* Can only be reading stdin in the current context. */ CODE1("curl_mime_data_cb(part%d, -1, (curl_read_callback) fread, \\", @@ -700,7 +653,7 @@ CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *global, if(escape) { curl_off_t len = ZERO_TERMINATED; if(tag == CURLOPT_POSTFIELDS) - len = curlx_dyn_len(&config->postdata); + len = config->postfieldsize; escaped = c_escape(value, len); NULL_CHECK(escaped); CODE2("curl_easy_setopt(hnd, %s, \"%s\");", name, escaped); diff --git a/contrib/libs/curl/src/tool_setopt.h b/contrib/libs/curl/src/tool_setopt.h index 6588da9ced..cd59a74cd8 100644 --- a/contrib/libs/curl/src/tool_setopt.h +++ b/contrib/libs/curl/src/tool_setopt.h @@ -52,7 +52,6 @@ extern const struct NameValue setopt_nv_CURLPROXY[]; extern const struct NameValue setopt_nv_CURL_SOCKS_PROXY[]; extern const struct NameValue setopt_nv_CURL_HTTP_VERSION[]; extern const struct NameValue setopt_nv_CURL_SSLVERSION[]; -extern const struct NameValue setopt_nv_CURL_SSLVERSION_MAX[]; extern const struct NameValue setopt_nv_CURL_TIMECOND[]; extern const struct NameValue setopt_nv_CURLFTPSSL_CCC[]; extern const struct NameValue setopt_nv_CURLUSESSL[]; @@ -82,9 +81,6 @@ extern const struct NameValueUnsigned setopt_nv_CURLHSTS[]; CURLcode tool_setopt_enum(CURL *curl, struct GlobalConfig *config, const char *name, CURLoption tag, const struct NameValue *nv, long lval); -CURLcode tool_setopt_SSLVERSION(CURL *curl, struct GlobalConfig *config, - const char *name, CURLoption tag, - long lval); CURLcode tool_setopt_flags(CURL *curl, struct GlobalConfig *config, const char *name, CURLoption tag, const struct NameValue *nv, long lval); @@ -110,9 +106,6 @@ CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *global, #define my_setopt_enum(x,y,z) \ SETOPT_CHECK(tool_setopt_enum(x, global, #y, y, setopt_nv_ ## y, z), y) -#define my_setopt_SSLVERSION(x,y,z) \ - SETOPT_CHECK(tool_setopt_SSLVERSION(x, global, #y, y, z), y) - #define my_setopt_bitmask(x,y,z) \ SETOPT_CHECK(tool_setopt_bitmask(x, global, #y, y, setopt_nv_ ## y, z), y) @@ -139,9 +132,6 @@ CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *global, #define my_setopt_enum(x,y,z) \ SETOPT_CHECK(curl_easy_setopt(x, y, z), y) -#define my_setopt_SSLVERSION(x,y,z) \ - SETOPT_CHECK(curl_easy_setopt(x, y, z), y) - #define my_setopt_bitmask(x,y,z) \ SETOPT_CHECK(curl_easy_setopt(x, y, z), y) diff --git a/contrib/libs/curl/src/tool_setup.h b/contrib/libs/curl/src/tool_setup.h index 07cba7da2e..c69859ea64 100644 --- a/contrib/libs/curl/src/tool_setup.h +++ b/contrib/libs/curl/src/tool_setup.h @@ -74,17 +74,4 @@ extern bool tool_isVistaOrGreater; extern bool tool_term_has_bold; #endif -#if defined(_WIN32) && !defined(HAVE_FTRUNCATE) - -int tool_ftruncate64(int fd, curl_off_t where); - -#undef ftruncate -#define ftruncate(fd,where) tool_ftruncate64(fd,where) - -#define HAVE_FTRUNCATE 1 -#define USE_TOOL_FTRUNCATE 1 - -#endif /* _WIN32 && ! HAVE_FTRUNCATE */ - - #endif /* HEADER_CURL_TOOL_SETUP_H */ diff --git a/contrib/libs/curl/src/tool_sleep.c b/contrib/libs/curl/src/tool_sleep.c index 31b5f01c92..c24f73729e 100644 --- a/contrib/libs/curl/src/tool_sleep.c +++ b/contrib/libs/curl/src/tool_sleep.c @@ -48,7 +48,7 @@ void tool_go_sleep(long ms) #if defined(MSDOS) delay(ms); #elif defined(_WIN32) - Sleep((DWORD)ms); + Sleep(ms); #elif defined(HAVE_POLL_FINE) (void)poll((void *)0, 0, (int)ms); #else diff --git a/contrib/libs/curl/src/tool_urlglob.c b/contrib/libs/curl/src/tool_urlglob.c index 35f472d4f2..e45c7d10b2 100644 --- a/contrib/libs/curl/src/tool_urlglob.c +++ b/contrib/libs/curl/src/tool_urlglob.c @@ -23,6 +23,8 @@ ***************************************************************************/ #include "tool_setup.h" +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" #include "tool_doswin.h" @@ -78,7 +80,7 @@ static int multiply(curl_off_t *amount, curl_off_t with) #else sum = *amount * with; if(sum/with != *amount) - return 1; /* did not fit, bail out */ + return 1; /* didn't fit, bail out */ #endif } *amount = sum; @@ -121,11 +123,11 @@ static CURLcode glob_set(struct URLGlob *glob, char **patternp, return GLOBERROR("empty string within braces", *posp, CURLE_URL_MALFORMAT); - /* add 1 to size since it will be incremented below */ + /* add 1 to size since it'll be incremented below */ if(multiply(amount, pat->content.Set.size + 1)) return GLOBERROR("range overflow", 0, CURLE_URL_MALFORMAT); - FALLTHROUGH(); + /* FALLTHROUGH */ case ',': *buf = '\0'; @@ -169,7 +171,7 @@ static CURLcode glob_set(struct URLGlob *glob, char **patternp, ++pattern; ++(*posp); } - FALLTHROUGH(); + /* FALLTHROUGH */ default: *buf++ = *pattern++; /* copy character to set element */ ++(*posp); diff --git a/contrib/libs/curl/src/tool_util.c b/contrib/libs/curl/src/tool_util.c index e612bec031..812a689d03 100644 --- a/contrib/libs/curl/src/tool_util.c +++ b/contrib/libs/curl/src/tool_util.c @@ -81,7 +81,7 @@ struct timeval tvnow(void) /* ** Even when the configure process has truly detected monotonic clock ** availability, it might happen that it is not actually available at - ** runtime. When this occurs simply fallback to other time source. + ** run-time. When this occurs simply fallback to other time source. */ #ifdef HAVE_GETTIMEOFDAY else @@ -126,7 +126,7 @@ struct timeval tvnow(void) /* * Make sure that the first argument is the more recent time, as otherwise - * we will get a weird negative time-diff back... + * we'll get a weird negative time-diff back... * * Returns: the time difference in number of milliseconds. */ @@ -159,32 +159,3 @@ int struplocompare4sort(const void *p1, const void *p2) { return struplocompare(* (char * const *) p1, * (char * const *) p2); } - -#ifdef USE_TOOL_FTRUNCATE - -#ifdef _WIN32_WCE -/* 64-bit lseek-like function unavailable */ -# undef _lseeki64 -# define _lseeki64(hnd,ofs,whence) lseek(hnd,ofs,whence) -# undef _get_osfhandle -# define _get_osfhandle(fd) (fd) -#endif - -/* - * Truncate a file handle at a 64-bit position 'where'. - */ - -int tool_ftruncate64(int fd, curl_off_t where) -{ - intptr_t handle = _get_osfhandle(fd); - - if(_lseeki64(fd, where, SEEK_SET) < 0) - return -1; - - if(!SetEndOfFile((HANDLE)handle)) - return -1; - - return 0; -} - -#endif /* USE_TOOL_FTRUNCATE */ diff --git a/contrib/libs/curl/src/tool_version.h b/contrib/libs/curl/src/tool_version.h index e4cfa70249..2eca403c4e 100644 --- a/contrib/libs/curl/src/tool_version.h +++ b/contrib/libs/curl/src/tool_version.h @@ -27,7 +27,7 @@ #define CURL_NAME "curl" #define CURL_COPYRIGHT LIBCURL_COPYRIGHT -#define CURL_VERSION "8.10.1" +#define CURL_VERSION "8.5.0" #define CURL_VERSION_MAJOR LIBCURL_VERSION_MAJOR #define CURL_VERSION_MINOR LIBCURL_VERSION_MINOR #define CURL_VERSION_PATCH LIBCURL_VERSION_PATCH diff --git a/contrib/libs/curl/src/tool_vms.c b/contrib/libs/curl/src/tool_vms.c index 36d05870c9..36d0ebe6ca 100644 --- a/contrib/libs/curl/src/tool_vms.c +++ b/contrib/libs/curl/src/tool_vms.c @@ -30,6 +30,7 @@ #include <unixlib.h> #endif +#define ENABLE_CURLX_PRINTF #include "curlx.h" #error #include "curlmsg_vms.h" @@ -73,7 +74,7 @@ int is_vms_shell(void) } /* - * VMS has two exit() routines. When running under a Unix style shell, then + * VMS has two exit() routines. When running under a Unix style shell, then * Unix style and the __posix_exit() routine is used. * * When running under the DCL shell, then the VMS encoded codes and decc$exit() @@ -93,7 +94,7 @@ void vms_special_exit(int code, int vms_show) { int vms_code; - /* The POSIX exit mode is only available after VMS 7.0 */ + /* The Posix exit mode is only available after VMS 7.0 */ #if __CRTL_VER >= 70000000 if(is_vms_shell() == 0) { decc$__posix_exit(code); @@ -132,9 +133,9 @@ struct decc_feat_t { static const struct decc_feat_t decc_feat_array[] = { /* Preserve command-line case with SET PROCESS/PARSE_STYLE=EXTENDED */ { "DECC$ARGV_PARSE_STYLE", 1 }, - /* Preserve case for filenames on ODS5 disks. */ + /* Preserve case for file names on ODS5 disks. */ { "DECC$EFS_CASE_PRESERVE", 1 }, - /* Enable multiple dots (and most characters) in ODS5 filenames, + /* Enable multiple dots (and most characters) in ODS5 file names, while preserving VMS-ness of ";version". */ { "DECC$EFS_CHARSET", 1 }, /* List terminator. */ @@ -164,14 +165,14 @@ static void decc_init(void) feat_index = decc$feature_get_index(decc_feat_array[i].name); if(feat_index >= 0) { - /* Valid item. Collect its properties. */ + /* Valid item. Collect its properties. */ feat_value = decc$feature_get_value(feat_index, 1); feat_value_min = decc$feature_get_value(feat_index, 2); feat_value_max = decc$feature_get_value(feat_index, 3); if((decc_feat_array[i].value >= feat_value_min) && (decc_feat_array[i].value <= feat_value_max)) { - /* Valid value. Set it if necessary. */ + /* Valid value. Set it if necessary. */ if(feat_value != decc_feat_array[i].value) { sts = decc$feature_set_value(feat_index, 1, decc_feat_array[i].value); @@ -197,7 +198,7 @@ static void decc_init(void) #pragma nostandard /* Establish the LIB$INITIALIZE PSECTs, with proper alignment and - other attributes. Note that "nopic" is significant only on VAX. */ + other attributes. Note that "nopic" is significant only on VAX. */ #pragma extern_model save #pragma extern_model strict_refdef "LIB$INITIALIZ" 2, nopic, nowrt const int spare[8] = {0}; diff --git a/contrib/libs/curl/src/tool_writeout.c b/contrib/libs/curl/src/tool_writeout.c index 141178c332..981065c9ef 100644 --- a/contrib/libs/curl/src/tool_writeout.c +++ b/contrib/libs/curl/src/tool_writeout.c @@ -22,7 +22,8 @@ * ***************************************************************************/ #include "tool_setup.h" - +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" #include "tool_writeout.h" @@ -69,12 +70,12 @@ static const struct httpmap http_version[] = { Yes: "http_version": "1.1" No: "http_version": 1.1 - Variable names MUST be in alphabetical order. + Variable names should be in alphabetical order. */ static const struct writeoutvar variables[] = { {"certs", VAR_CERT, CURLINFO_NONE, writeString}, - {"conn_id", VAR_CONN_ID, CURLINFO_CONN_ID, writeOffset}, {"content_type", VAR_CONTENT_TYPE, CURLINFO_CONTENT_TYPE, writeString}, + {"conn_id", VAR_CONN_ID, CURLINFO_CONN_ID, writeOffset}, {"errormsg", VAR_ERRORMSG, CURLINFO_NONE, writeString}, {"exitcode", VAR_EXITCODE, CURLINFO_NONE, writeLong}, {"filename_effective", VAR_EFFECTIVE_FILENAME, CURLINFO_NONE, writeString}, @@ -91,11 +92,9 @@ static const struct writeoutvar variables[] = { {"num_connects", VAR_NUM_CONNECTS, CURLINFO_NUM_CONNECTS, writeLong}, {"num_headers", VAR_NUM_HEADERS, CURLINFO_NONE, writeLong}, {"num_redirects", VAR_REDIRECT_COUNT, CURLINFO_REDIRECT_COUNT, writeLong}, - {"num_retries", VAR_NUM_RETRY, CURLINFO_NONE, writeLong}, {"onerror", VAR_ONERROR, CURLINFO_NONE, NULL}, {"proxy_ssl_verify_result", VAR_PROXY_SSL_VERIFY_RESULT, CURLINFO_PROXY_SSL_VERIFYRESULT, writeLong}, - {"proxy_used", VAR_PROXY_USED, CURLINFO_USED_PROXY, writeLong}, {"redirect_url", VAR_REDIRECT_URL, CURLINFO_REDIRECT_URL, writeString}, {"referer", VAR_REFERER, CURLINFO_REFERER, writeString}, {"remote_ip", VAR_PRIMARY_IP, CURLINFO_PRIMARY_IP, writeString}, @@ -118,8 +117,6 @@ static const struct writeoutvar variables[] = { {"time_connect", VAR_CONNECT_TIME, CURLINFO_CONNECT_TIME_T, writeTime}, {"time_namelookup", VAR_NAMELOOKUP_TIME, CURLINFO_NAMELOOKUP_TIME_T, writeTime}, - {"time_posttransfer", VAR_POSTTRANSFER_TIME, CURLINFO_POSTTRANSFER_TIME_T, - writeTime}, {"time_pretransfer", VAR_PRETRANSFER_TIME, CURLINFO_PRETRANSFER_TIME_T, writeTime}, {"time_redirect", VAR_REDIRECT_TIME, CURLINFO_REDIRECT_TIME_T, writeTime}, @@ -127,29 +124,30 @@ static const struct writeoutvar variables[] = { writeTime}, {"time_total", VAR_TOTAL_TIME, CURLINFO_TOTAL_TIME_T, writeTime}, {"url", VAR_INPUT_URL, CURLINFO_NONE, writeString}, - {"url.fragment", VAR_INPUT_URLFRAGMENT, CURLINFO_NONE, writeString}, - {"url.host", VAR_INPUT_URLHOST, CURLINFO_NONE, writeString}, - {"url.options", VAR_INPUT_URLOPTIONS, CURLINFO_NONE, writeString}, + {"url.scheme", VAR_INPUT_URLSCHEME, CURLINFO_NONE, writeString}, + {"url.user", VAR_INPUT_URLUSER, CURLINFO_NONE, writeString}, {"url.password", VAR_INPUT_URLPASSWORD, CURLINFO_NONE, writeString}, - {"url.path", VAR_INPUT_URLPATH, CURLINFO_NONE, writeString}, + {"url.options", VAR_INPUT_URLOPTIONS, CURLINFO_NONE, writeString}, + {"url.host", VAR_INPUT_URLHOST, CURLINFO_NONE, writeString}, {"url.port", VAR_INPUT_URLPORT, CURLINFO_NONE, writeString}, + {"url.path", VAR_INPUT_URLPATH, CURLINFO_NONE, writeString}, {"url.query", VAR_INPUT_URLQUERY, CURLINFO_NONE, writeString}, - {"url.scheme", VAR_INPUT_URLSCHEME, CURLINFO_NONE, writeString}, - {"url.user", VAR_INPUT_URLUSER, CURLINFO_NONE, writeString}, + {"url.fragment", VAR_INPUT_URLFRAGMENT, CURLINFO_NONE, writeString}, {"url.zoneid", VAR_INPUT_URLZONEID, CURLINFO_NONE, writeString}, - {"url_effective", VAR_EFFECTIVE_URL, CURLINFO_EFFECTIVE_URL, writeString}, - {"urle.fragment", VAR_INPUT_URLEFRAGMENT, CURLINFO_NONE, writeString}, - {"urle.host", VAR_INPUT_URLEHOST, CURLINFO_NONE, writeString}, - {"urle.options", VAR_INPUT_URLEOPTIONS, CURLINFO_NONE, writeString}, + {"urle.scheme", VAR_INPUT_URLESCHEME, CURLINFO_NONE, writeString}, + {"urle.user", VAR_INPUT_URLEUSER, CURLINFO_NONE, writeString}, {"urle.password", VAR_INPUT_URLEPASSWORD, CURLINFO_NONE, writeString}, - {"urle.path", VAR_INPUT_URLEPATH, CURLINFO_NONE, writeString}, + {"urle.options", VAR_INPUT_URLEOPTIONS, CURLINFO_NONE, writeString}, + {"urle.host", VAR_INPUT_URLEHOST, CURLINFO_NONE, writeString}, {"urle.port", VAR_INPUT_URLEPORT, CURLINFO_NONE, writeString}, + {"urle.path", VAR_INPUT_URLEPATH, CURLINFO_NONE, writeString}, {"urle.query", VAR_INPUT_URLEQUERY, CURLINFO_NONE, writeString}, - {"urle.scheme", VAR_INPUT_URLESCHEME, CURLINFO_NONE, writeString}, - {"urle.user", VAR_INPUT_URLEUSER, CURLINFO_NONE, writeString}, + {"urle.fragment", VAR_INPUT_URLEFRAGMENT, CURLINFO_NONE, writeString}, {"urle.zoneid", VAR_INPUT_URLEZONEID, CURLINFO_NONE, writeString}, + {"url_effective", VAR_EFFECTIVE_URL, CURLINFO_EFFECTIVE_URL, writeString}, {"urlnum", VAR_URLNUM, CURLINFO_NONE, writeLong}, - {"xfer_id", VAR_EASY_ID, CURLINFO_XFER_ID, writeOffset} + {"xfer_id", VAR_EASY_ID, CURLINFO_XFER_ID, writeOffset}, + {NULL, VAR_NONE, CURLINFO_NONE, NULL} }; static int writeTime(FILE *stream, const struct writeoutvar *wovar, @@ -199,7 +197,7 @@ static int urlpart(struct per_transfer *per, writeoutid vid, char *part = NULL; const char *url = NULL; - if(vid >= VAR_INPUT_URLESCHEME) { + if(vid >= VAR_INPUT_URLEHOST) { if(curl_easy_getinfo(per->curl, CURLINFO_EFFECTIVE_URL, &url)) rc = 5; } @@ -270,15 +268,6 @@ static int urlpart(struct per_transfer *per, writeoutid vid, return rc; } -static void certinfo(struct per_transfer *per) -{ - if(!per->certinfo) { - struct curl_certinfo *certinfo; - CURLcode res = curl_easy_getinfo(per->curl, CURLINFO_CERTINFO, &certinfo); - per->certinfo = (!res && certinfo) ? certinfo : NULL; - } -} - static int writeString(FILE *stream, const struct writeoutvar *wovar, struct per_transfer *per, CURLcode per_result, bool use_json) @@ -314,7 +303,6 @@ static int writeString(FILE *stream, const struct writeoutvar *wovar, else { switch(wovar->id) { case VAR_CERT: - certinfo(per); if(per->certinfo) { int i; bool error = FALSE; @@ -445,12 +433,7 @@ static int writeLong(FILE *stream, const struct writeoutvar *wovar, } else { switch(wovar->id) { - case VAR_NUM_RETRY: - longinfo = per->num_retries; - valid = true; - break; case VAR_NUM_CERTS: - certinfo(per); longinfo = per->certinfo ? per->certinfo->num_of_certs : 0; valid = true; break; @@ -459,7 +442,7 @@ static int writeLong(FILE *stream, const struct writeoutvar *wovar, valid = true; break; case VAR_EXITCODE: - longinfo = (long)per_result; + longinfo = per_result; valid = true; break; case VAR_URLNUM: @@ -525,17 +508,6 @@ static int writeOffset(FILE *stream, const struct writeoutvar *wovar, return 1; /* return 1 if anything was written */ } -static int -matchvar(const void *m1, const void *m2) -{ - const struct writeoutvar *v1 = m1; - const struct writeoutvar *v2 = m2; - - return strcmp(v1->name, v2->name); -} - -#define MAX_WRITEOUT_NAME_LENGTH 24 - void ourWriteOut(struct OperationConfig *config, struct per_transfer *per, CURLcode per_result) { @@ -543,13 +515,16 @@ void ourWriteOut(struct OperationConfig *config, struct per_transfer *per, const char *writeinfo = config->writeout; const char *ptr = writeinfo; bool done = FALSE; + struct curl_certinfo *certinfo; + CURLcode res = curl_easy_getinfo(per->curl, CURLINFO_CERTINFO, &certinfo); bool fclose_stream = FALSE; - struct dynbuf name; if(!writeinfo) return; - curlx_dyn_init(&name, MAX_WRITEOUT_NAME_LENGTH); + if(!res && certinfo) + per->certinfo = certinfo; + while(ptr && *ptr && !done) { if('%' == *ptr && ptr[1]) { if('%' == ptr[1]) { @@ -562,8 +537,8 @@ void ourWriteOut(struct OperationConfig *config, struct per_transfer *per, char *end; size_t vlen; if('{' == ptr[1]) { - struct writeoutvar *wv = NULL; - struct writeoutvar find = { 0 }; + int i; + bool match = FALSE; end = strchr(ptr, '}'); ptr += 2; /* pass the % and the { */ if(!end) { @@ -571,47 +546,43 @@ void ourWriteOut(struct OperationConfig *config, struct per_transfer *per, continue; } vlen = end - ptr; - - curlx_dyn_reset(&name); - if(!curlx_dyn_addn(&name, ptr, vlen)) { - find.name = curlx_dyn_ptr(&name); - wv = bsearch(&find, - variables, sizeof(variables)/sizeof(variables[0]), - sizeof(variables[0]), matchvar); - } - if(wv) { - switch(wv->id) { - case VAR_ONERROR: - if(per_result == CURLE_OK) - /* this is not error so skip the rest */ - done = TRUE; - break; - case VAR_STDOUT: - if(fclose_stream) - fclose(stream); - fclose_stream = FALSE; - stream = stdout; - break; - case VAR_STDERR: - if(fclose_stream) - fclose(stream); - fclose_stream = FALSE; - stream = tool_stderr; - break; - case VAR_JSON: - ourWriteOutJSON(stream, variables, - sizeof(variables)/sizeof(variables[0]), - per, per_result); - break; - case VAR_HEADER_JSON: - headerJSON(stream, per); - break; - default: - (void)wv->writefunc(stream, wv, per, per_result, false); + for(i = 0; variables[i].name; i++) { + if((strlen(variables[i].name) == vlen) && + curl_strnequal(ptr, variables[i].name, vlen)) { + match = TRUE; + switch(variables[i].id) { + case VAR_ONERROR: + if(per_result == CURLE_OK) + /* this isn't error so skip the rest */ + done = TRUE; + break; + case VAR_STDOUT: + if(fclose_stream) + fclose(stream); + fclose_stream = FALSE; + stream = stdout; + break; + case VAR_STDERR: + if(fclose_stream) + fclose(stream); + fclose_stream = FALSE; + stream = tool_stderr; + break; + case VAR_JSON: + ourWriteOutJSON(stream, variables, per, per_result); + break; + case VAR_HEADER_JSON: + headerJSON(stream, per); + break; + default: + (void)variables[i].writefunc(stream, &variables[i], + per, per_result, false); + break; + } break; } } - else { + if(!match) { fprintf(tool_stderr, "curl: unknown --write-out variable: '%.*s'\n", (int)vlen, ptr); @@ -646,7 +617,7 @@ void ourWriteOut(struct OperationConfig *config, struct per_transfer *per, } end = strchr(ptr, '}'); if(end) { - char fname[512]; /* holds the longest filename */ + char fname[512]; /* holds the longest file name */ size_t flen = end - ptr; if(flen < sizeof(fname)) { FILE *stream2; @@ -701,5 +672,4 @@ void ourWriteOut(struct OperationConfig *config, struct per_transfer *per, } if(fclose_stream) fclose(stream); - curlx_dyn_free(&name); } diff --git a/contrib/libs/curl/src/tool_writeout.h b/contrib/libs/curl/src/tool_writeout.h index 7b3ca7bd02..4e690a65c9 100644 --- a/contrib/libs/curl/src/tool_writeout.h +++ b/contrib/libs/curl/src/tool_writeout.h @@ -57,7 +57,7 @@ typedef enum { VAR_INPUT_URLFRAGMENT, VAR_INPUT_URLZONEID, /* the same ones again for url *effective* */ - VAR_INPUT_URLESCHEME, /* keep this the first URLE* variable */ + VAR_INPUT_URLESCHEME, VAR_INPUT_URLEUSER, VAR_INPUT_URLEPASSWORD, VAR_INPUT_URLEOPTIONS, @@ -74,14 +74,11 @@ typedef enum { VAR_NUM_CERTS, VAR_NUM_CONNECTS, VAR_NUM_HEADERS, - VAR_NUM_RETRY, VAR_ONERROR, VAR_PRETRANSFER_TIME, - VAR_POSTTRANSFER_TIME, VAR_PRIMARY_IP, VAR_PRIMARY_PORT, VAR_PROXY_SSL_VERIFY_RESULT, - VAR_PROXY_USED, VAR_REDIRECT_COUNT, VAR_REDIRECT_TIME, VAR_REDIRECT_URL, diff --git a/contrib/libs/curl/src/tool_writeout_json.c b/contrib/libs/curl/src/tool_writeout_json.c index 205b702ae1..4ed6b93fb7 100644 --- a/contrib/libs/curl/src/tool_writeout_json.c +++ b/contrib/libs/curl/src/tool_writeout_json.c @@ -23,6 +23,9 @@ ***************************************************************************/ #include "tool_setup.h" +#define ENABLE_CURLX_PRINTF + +/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" #include "tool_writeout_json.h" @@ -69,9 +72,9 @@ int jsonquoted(const char *in, size_t len, if(*i < 32) result = curlx_dyn_addf(out, "\\u%04x", *i); else { - char o = (char)*i; + char o = *i; if(lowercase && (o >= 'A' && o <= 'Z')) - /* do not use tolower() since that is locale specific */ + /* do not use tolower() since that's locale specific */ o |= ('a' - 'A'); result = curlx_dyn_addn(out, &o, 1); } @@ -98,14 +101,13 @@ void jsonWriteString(FILE *stream, const char *in, bool lowercase) } void ourWriteOutJSON(FILE *stream, const struct writeoutvar mappings[], - size_t nentries, struct per_transfer *per, CURLcode per_result) { - size_t i; + int i; fputs("{", stream); - for(i = 0; i < nentries; i++) { + for(i = 0; mappings[i].name != NULL; i++) { if(mappings[i].writefunc && mappings[i].writefunc(stream, &mappings[i], per, per_result, true)) fputs(",", stream); diff --git a/contrib/libs/curl/src/tool_writeout_json.h b/contrib/libs/curl/src/tool_writeout_json.h index 91f5d93dc8..49a28194ff 100644 --- a/contrib/libs/curl/src/tool_writeout_json.h +++ b/contrib/libs/curl/src/tool_writeout_json.h @@ -30,7 +30,6 @@ int jsonquoted(const char *in, size_t len, struct curlx_dynbuf *out, bool lowercase); void ourWriteOutJSON(FILE *stream, const struct writeoutvar mappings[], - size_t nentries, struct per_transfer *per, CURLcode per_result); void headerJSON(FILE *stream, struct per_transfer *per); void jsonWriteString(FILE *stream, const char *in, bool lowercase); diff --git a/contrib/libs/curl/src/tool_xattr.c b/contrib/libs/curl/src/tool_xattr.c index f832e24757..9472194faa 100644 --- a/contrib/libs/curl/src/tool_xattr.c +++ b/contrib/libs/curl/src/tool_xattr.c @@ -55,7 +55,7 @@ char *stripcredentials(const char *url) char *nurl; u = curl_url(); if(u) { - uc = curl_url_set(u, CURLUPART_URL, url, CURLU_GUESS_SCHEME); + uc = curl_url_set(u, CURLUPART_URL, url, 0); if(uc) goto error; @@ -87,11 +87,12 @@ static int xattr(int fd, int err = 0; if(value) { #ifdef DEBUGBUILD + (void)fd; if(getenv("CURL_FAKE_XATTR")) { printf("%s => %s\n", attr, value); - return 0; } -#endif + return 0; +#else #ifdef HAVE_FSETXATTR_6 err = fsetxattr(fd, attr, value, strlen(value), 0, 0); #elif defined(HAVE_FSETXATTR_5) @@ -105,6 +106,7 @@ static int xattr(int fd, err = (rc < 0 ? -1 : 0); } #endif +#endif } return err; } diff --git a/contrib/libs/curl/src/var.c b/contrib/libs/curl/src/var.c index dbcef3c116..388d45592f 100644 --- a/contrib/libs/curl/src/var.c +++ b/contrib/libs/curl/src/var.c @@ -23,6 +23,8 @@ ***************************************************************************/ #include "tool_setup.h" +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" @@ -40,7 +42,6 @@ #include "memdebug.h" /* keep this as LAST include */ #define MAX_EXPAND_CONTENT 10000000 -#define MAX_VAR_LEN 128 /* max length of a name */ static char *Memdup(const char *data, size_t len) { @@ -61,6 +62,7 @@ void varcleanup(struct GlobalConfig *global) struct var *t = list; list = list->next; free((char *)t->content); + free((char *)t->name); free(t); } } @@ -108,7 +110,7 @@ static ParameterError varfunc(struct GlobalConfig *global, if(*f == '}') /* end of functions */ break; - /* On entry, this is known to be a colon already. In subsequent laps, it + /* On entry, this is known to be a colon already. In subsequent laps, it is also known to be a colon since that is part of the FUNCMATCH() checks */ f++; @@ -231,7 +233,7 @@ ParameterError varexpand(struct GlobalConfig *global, line = &envp[2]; } else if(envp) { - char name[MAX_VAR_LEN]; + char name[128]; size_t nlen; size_t i; char *funcp; @@ -340,7 +342,7 @@ ParameterError varexpand(struct GlobalConfig *global, } /* - * Created in a way that is not revealing how variables are actually stored so + * Created in a way that is not revealing how variables is actually stored so * that we can improve this if we want better performance when managing many * at a later point. */ @@ -353,24 +355,29 @@ static ParameterError addvariable(struct GlobalConfig *global, { struct var *p; const struct var *check = varcontent(global, name, nlen); - DEBUGASSERT(nlen); if(check) notef(global, "Overwriting variable '%s'", check->name); - p = calloc(1, sizeof(struct var) + nlen); - if(p) { - memcpy(p->name, name, nlen); + p = calloc(1, sizeof(struct var)); + if(!p) + return PARAM_NO_MEM; - p->content = contalloc ? content: Memdup(content, clen); - if(p->content) { - p->clen = clen; + p->name = Memdup(name, nlen); + if(!p->name) + goto err; - p->next = global->variables; - global->variables = p; - return PARAM_OK; - } - free(p); - } + p->content = contalloc ? content: Memdup(content, clen); + if(!p->content) + goto err; + p->clen = clen; + + p->next = global->variables; + global->variables = p; + return PARAM_OK; +err: + free((char *)p->content); + free((char *)p->name); + free(p); return PARAM_NO_MEM; } @@ -386,7 +393,6 @@ ParameterError setvariable(struct GlobalConfig *global, ParameterError err = PARAM_OK; bool import = FALSE; char *ge = NULL; - char buf[MAX_VAR_LEN]; if(*input == '%') { import = TRUE; @@ -396,20 +402,12 @@ ParameterError setvariable(struct GlobalConfig *global, while(*line && (ISALNUM(*line) || (*line == '_'))) line++; nlen = line - name; - if(!nlen || (nlen >= MAX_VAR_LEN)) { + if(!nlen || (nlen > 128)) { warnf(global, "Bad variable name length (%zd), skipping", nlen); return PARAM_OK; } if(import) { - /* this does not use curl_getenv() because we want "" support for blank - content */ - if(*line) { - /* if there is a default action, we need to copy the name */ - memcpy(buf, name, nlen); - buf[nlen] = 0; - name = buf; - } - ge = getenv(name); + ge = curl_getenv(name); if(!*line && !ge) { /* no assign, no variable, fail */ errorf(global, "Variable '%s' import fail, not set", name); @@ -461,5 +459,6 @@ ParameterError setvariable(struct GlobalConfig *global, if(contalloc) free(content); } + curl_free(ge); return err; } diff --git a/contrib/libs/curl/src/var.h b/contrib/libs/curl/src/var.h index 2ea9797275..4a71943a3c 100644 --- a/contrib/libs/curl/src/var.h +++ b/contrib/libs/curl/src/var.h @@ -29,9 +29,9 @@ struct var { struct var *next; + const char *name; const char *content; size_t clen; /* content length */ - char name[1]; /* allocated as part of the struct */ }; struct GlobalConfig; |