diff options
author | nikita <nikita@NetBSD.org> | 2020-09-14 20:38:16 +0200 |
---|---|---|
committer | nikita <nikita@NetBSD.org> | 2020-09-14 20:38:16 +0200 |
commit | ea5627408e41592ac8750032de41b97038811d88 (patch) | |
tree | 851007eaf0e4e3ec6b97756e209b512792933b88 /src | |
parent | b8e9ccfa48a0b35e2c9dd560334237e591175be8 (diff) | |
parent | 5a1fc8d33808d7b22f57bdf9403cda7ff07b0670 (diff) | |
download | gnurl-ea5627408e41592ac8750032de41b97038811d88.tar.gz gnurl-ea5627408e41592ac8750032de41b97038811d88.tar.bz2 gnurl-ea5627408e41592ac8750032de41b97038811d88.zip |
Merge tag 'curl-7_71_1'
curl 7.71.1
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.inc | 6 | ||||
-rw-r--r-- | src/tool_cb_hdr.c | 30 | ||||
-rw-r--r-- | src/tool_cfgable.c | 5 | ||||
-rw-r--r-- | src/tool_cfgable.h | 15 | ||||
-rw-r--r-- | src/tool_formparse.c | 43 | ||||
-rw-r--r-- | src/tool_formparse.h | 17 | ||||
-rw-r--r-- | src/tool_getparam.c | 33 | ||||
-rw-r--r-- | src/tool_getpass.c | 4 | ||||
-rw-r--r-- | src/tool_help.c | 31 | ||||
-rw-r--r-- | src/tool_main.c | 8 | ||||
-rw-r--r-- | src/tool_metalink.c | 79 | ||||
-rw-r--r-- | src/tool_metalink.h | 52 | ||||
-rw-r--r-- | src/tool_operate.c | 145 | ||||
-rw-r--r-- | src/tool_operate.h | 6 | ||||
-rw-r--r-- | src/tool_paramhlp.c | 2 | ||||
-rw-r--r-- | src/tool_parsecfg.c | 6 | ||||
-rw-r--r-- | src/tool_setopt.c | 61 | ||||
-rw-r--r-- | src/tool_setopt.h | 40 | ||||
-rw-r--r-- | src/tool_urlglob.c | 77 | ||||
-rw-r--r-- | src/tool_urlglob.h | 20 | ||||
-rw-r--r-- | src/tool_vms.c | 8 | ||||
-rw-r--r-- | src/tool_writeout.c | 2 |
22 files changed, 405 insertions, 285 deletions
diff --git a/src/Makefile.inc b/src/Makefile.inc index e90e6d670..559b9983c 100644 --- a/src/Makefile.inc +++ b/src/Makefile.inc @@ -34,14 +34,16 @@ GNURLX_CFILES = \ ../lib/strtoofft.c \ ../lib/nonblock.c \ ../lib/warnless.c \ - ../lib/curl_ctype.c + ../lib/curl_ctype.c \ + ../lib/curl_multibyte.c GNURLX_HFILES = \ ../lib/curl_setup.h \ ../lib/strtoofft.h \ ../lib/nonblock.h \ ../lib/warnless.h \ - ../lib/curl_ctype.h + ../lib/curl_ctype.h \ + ../lib/curl_multibyte.h GNURL_CFILES = \ slist_wc.c \ diff --git a/src/tool_cb_hdr.c b/src/tool_cb_hdr.c index 3b1023888..5741f0aba 100644 --- a/src/tool_cb_hdr.c +++ b/src/tool_cb_hdr.c @@ -119,8 +119,8 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) if(!first) { warnf(per->config->global, - "\nReceived header etag is missing double quote/s\n"); - return 1; + "Received header etag is missing double quote/s\n"); + return failure; } else { /* discard first double quote */ @@ -132,8 +132,8 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) if(!last) { warnf(per->config->global, - "\nReceived header etag is missing double quote/s\n"); - return 1; + "Received header etag is missing double quote/s\n"); + return failure; } /* get length of desired etag */ @@ -186,25 +186,11 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) filename = parse_filename(p, len); if(filename) { if(outs->stream) { - int rc; - /* already opened and possibly written to */ - if(outs->fopened) - fclose(outs->stream); - outs->stream = NULL; - - /* rename the initial file name to the new file name */ - rc = rename(outs->filename, filename); - if(rc != 0) { - warnf(per->config->global, "Failed to rename %s -> %s: %s\n", - outs->filename, filename, strerror(errno)); - } - if(outs->alloc_filename) - Curl_safefree(outs->filename); - if(rc != 0) { - free(filename); - return failure; - } + /* indication of problem, get out! */ + free(filename); + return failure; } + outs->is_cd_filename = TRUE; outs->s_isreg = TRUE; outs->fopened = FALSE; diff --git a/src/tool_cfgable.c b/src/tool_cfgable.c index f802a5a31..63bdeaa46 100644 --- a/src/tool_cfgable.c +++ b/src/tool_cfgable.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 @@ -26,7 +26,7 @@ #include "memdebug.h" /* keep this as LAST include */ -void config_init(struct OperationConfig* config) +void config_init(struct OperationConfig *config) { memset(config, 0, sizeof(struct OperationConfig)); @@ -112,6 +112,7 @@ static void free_config_fields(struct OperationConfig *config) Curl_safefree(config->cert_type); Curl_safefree(config->proxy_cert_type); Curl_safefree(config->cacert); + Curl_safefree(config->login_options); Curl_safefree(config->proxy_cacert); Curl_safefree(config->capath); Curl_safefree(config->proxy_capath); diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h index 2ae7944e3..4a90d0b72 100644 --- a/src/tool_cfgable.h +++ b/src/tool_cfgable.h @@ -37,8 +37,8 @@ struct GlobalConfig; struct State { struct getout *urlnode; - URLGlob *inglob; - URLGlob *urls; + struct URLGlob *inglob; + struct URLGlob *urls; char *outfiles; char *httpgetfields; char *uploadfile; @@ -194,8 +194,8 @@ struct OperationConfig { curl_off_t condtime; struct curl_slist *headers; struct curl_slist *proxyheaders; - tool_mime *mimeroot; - tool_mime *mimecurrent; + struct tool_mime *mimeroot; + struct tool_mime *mimecurrent; curl_mime *mimepost; struct curl_slist *telnet_options; struct curl_slist *resolve; @@ -223,6 +223,7 @@ struct OperationConfig { bool tcp_nodelay; bool tcp_fastopen; long req_retry; /* number of retries */ + bool retry_all_errors; /* retry on any error */ bool retry_connrefused; /* set connection refused as a transient error */ long retry_delay; /* delay between retries (in seconds) */ long retry_maxtime; /* maximum time to keep retrying */ @@ -257,9 +258,11 @@ struct OperationConfig { bool ssl_revoke_best_effort; /* ignore SSL revocation offline/missing revocation list errors */ + bool native_ca_store; /* use the native os ca store */ + bool use_metalink; /* process given URLs as metalink XML file */ - metalinkfile *metalinkfile_list; /* point to the first node */ - metalinkfile *metalinkfile_last; /* point to the last/current node */ + struct metalinkfile *metalinkfile_list; /* point to the first node */ + struct metalinkfile *metalinkfile_last; /* point to the last/current node */ char *oauth_bearer; /* OAuth 2.0 bearer token */ bool nonpn; /* enable/disable TLS NPN extension */ bool noalpn; /* enable/disable TLS ALPN extension */ diff --git a/src/tool_formparse.c b/src/tool_formparse.c index 74d1533e4..8e8fe874e 100644 --- a/src/tool_formparse.c +++ b/src/tool_formparse.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 @@ -42,9 +42,10 @@ #define CONST_SAFEFREE(x) Curl_safefree(*((void **) &(x))) /* tool_mime functions. */ -static tool_mime *tool_mime_new(tool_mime *parent, toolmimekind kind) +static struct tool_mime *tool_mime_new(struct tool_mime *parent, + toolmimekind kind) { - tool_mime *m = (tool_mime *) calloc(1, sizeof(*m)); + struct tool_mime *m = (struct tool_mime *) calloc(1, sizeof(*m)); if(m) { m->kind = kind; @@ -57,14 +58,15 @@ static tool_mime *tool_mime_new(tool_mime *parent, toolmimekind kind) return m; } -static tool_mime *tool_mime_new_parts(tool_mime *parent) +static struct tool_mime *tool_mime_new_parts(struct tool_mime *parent) { return tool_mime_new(parent, TOOLMIME_PARTS); } -static tool_mime *tool_mime_new_data(tool_mime *parent, const char *data) +static struct tool_mime *tool_mime_new_data(struct tool_mime *parent, + const char *data) { - tool_mime *m = NULL; + struct tool_mime *m = NULL; data = strdup(data); if(data) { @@ -77,13 +79,13 @@ static tool_mime *tool_mime_new_data(tool_mime *parent, const char *data) return m; } -static tool_mime *tool_mime_new_filedata(tool_mime *parent, - const char *filename, - bool isremotefile, - CURLcode *errcode) +static struct tool_mime *tool_mime_new_filedata(struct tool_mime *parent, + const char *filename, + bool isremotefile, + CURLcode *errcode) { CURLcode result = CURLE_OK; - tool_mime *m = NULL; + struct tool_mime *m = NULL; *errcode = CURLE_OUT_OF_MEMORY; if(strcmp(filename, "-")) { @@ -159,7 +161,7 @@ static tool_mime *tool_mime_new_filedata(tool_mime *parent, return m; } -void tool_mime_free(tool_mime *mime) +void tool_mime_free(struct tool_mime *mime) { if(mime) { if(mime->subparts) @@ -181,7 +183,7 @@ void tool_mime_free(tool_mime *mime) size_t tool_mime_stdin_read(char *buffer, size_t size, size_t nitems, void *arg) { - tool_mime *sip = (tool_mime *) arg; + struct tool_mime *sip = (struct tool_mime *) arg; curl_off_t bytesleft; (void) size; /* Always 1: ignored. */ @@ -216,7 +218,7 @@ size_t tool_mime_stdin_read(char *buffer, int tool_mime_stdin_seek(void *instream, curl_off_t offset, int whence) { - tool_mime *sip = (tool_mime *) instream; + struct tool_mime *sip = (struct tool_mime *) instream; switch(whence) { case SEEK_CUR: @@ -238,7 +240,8 @@ int tool_mime_stdin_seek(void *instream, curl_off_t offset, int whence) /* Translate an internal mime tree into a libcurl mime tree. */ -static CURLcode tool2curlparts(CURL *curl, tool_mime *m, curl_mime *mime) +static CURLcode tool2curlparts(CURL *curl, struct tool_mime *m, + curl_mime *mime) { CURLcode ret = CURLE_OK; curl_mimepart *part = NULL; @@ -323,7 +326,7 @@ static CURLcode tool2curlparts(CURL *curl, tool_mime *m, curl_mime *mime) return ret; } -CURLcode tool2curlmime(CURL *curl, tool_mime *m, curl_mime **mime) +CURLcode tool2curlmime(CURL *curl, struct tool_mime *m, curl_mime **mime) { CURLcode ret = CURLE_OK; @@ -733,8 +736,8 @@ static int get_param_part(struct OperationConfig *config, char endchar, int formparse(struct OperationConfig *config, const char *input, - tool_mime **mimeroot, - tool_mime **mimecurrent, + struct tool_mime **mimeroot, + struct tool_mime **mimecurrent, bool literal_value) { /* input MUST be a string in the format 'name=contents' and we'll @@ -747,7 +750,7 @@ int formparse(struct OperationConfig *config, char *filename = NULL; char *encoder = NULL; struct curl_slist *headers = NULL; - tool_mime *part = NULL; + struct tool_mime *part = NULL; CURLcode res; /* Allocate the main mime structure if needed. */ @@ -794,7 +797,7 @@ int formparse(struct OperationConfig *config, /* we use the @-letter to indicate file name(s) */ - tool_mime *subparts = NULL; + struct tool_mime *subparts = NULL; do { /* since this was a file, it may have a content-type specifier diff --git a/src/tool_formparse.h b/src/tool_formparse.h index 750fe451f..5c1525e67 100644 --- a/src/tool_formparse.h +++ b/src/tool_formparse.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 @@ -35,12 +35,11 @@ typedef enum { TOOLMIME_STDINDATA } toolmimekind; -typedef struct tool_mime tool_mime; struct tool_mime { /* Structural fields. */ toolmimekind kind; /* Part kind. */ - tool_mime *parent; /* Parent item. */ - tool_mime *prev; /* Previous sibling (reverse order link). */ + struct tool_mime *parent; /* Parent item. */ + struct tool_mime *prev; /* Previous sibling (reverse order link). */ /* Common fields. */ const char *data; /* Actual data or data filename. */ const char *name; /* Part name. */ @@ -49,7 +48,7 @@ struct tool_mime { const char *encoder; /* Part's requested encoding. */ struct curl_slist *headers; /* User-defined headers. */ /* TOOLMIME_PARTS fields. */ - tool_mime *subparts; /* Part's subparts. */ + struct tool_mime *subparts; /* Part's subparts. */ /* TOOLMIME_STDIN/TOOLMIME_STDINDATA fields. */ curl_off_t origin; /* Stdin read origin offset. */ curl_off_t size; /* Stdin data size. */ @@ -63,10 +62,10 @@ int tool_mime_stdin_seek(void *instream, curl_off_t offset, int whence); int formparse(struct OperationConfig *config, const char *input, - tool_mime **mimeroot, - tool_mime **mimecurrent, + struct tool_mime **mimeroot, + struct tool_mime **mimecurrent, bool literal_value); -CURLcode tool2curlmime(CURL *curl, tool_mime *m, curl_mime **mime); -void tool_mime_free(tool_mime *mime); +CURLcode tool2curlmime(CURL *curl, struct tool_mime *m, curl_mime **mime); +void tool_mime_free(struct tool_mime *mime); #endif /* HEADER_CURL_TOOL_FORMPARSE_H */ diff --git a/src/tool_getparam.c b/src/tool_getparam.c index 0252ee029..340962145 100644 --- a/src/tool_getparam.c +++ b/src/tool_getparam.c @@ -197,6 +197,7 @@ static const struct LongShort aliases[]= { {"$Y", "suppress-connect-headers", ARG_BOOL}, {"$Z", "compressed-ssh", ARG_BOOL}, {"$~", "happy-eyeballs-timeout-ms", ARG_STRING}, + {"$!", "retry-all-errors", ARG_BOOL}, {"0", "http1.0", ARG_NONE}, {"01", "http1.1", ARG_NONE}, {"02", "http2", ARG_NONE}, @@ -927,6 +928,9 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ if(err) return err; break; + case '!': /* --retry-all-errors */ + config->retry_all_errors = toggle; + break; case 'k': /* --proxy-negotiate */ if(curlinfo->features & CURL_VERSION_SPNEGO) @@ -962,7 +966,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ if(*p) { /* if there's anything more than a plain decimal number */ rc = sscanf(p, " - %6s", lrange); - *p = 0; /* zero terminate to make str2unum() work below */ + *p = 0; /* null-terminate to make str2unum() work below */ } else rc = 0; @@ -1513,7 +1517,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ /* Automatic referer requested, this may be combined with a set initial one */ config->autoreferer = TRUE; - *ptr = 0; /* zero terminate here */ + *ptr = 0; /* null-terminate here */ } else config->autoreferer = FALSE; @@ -1813,6 +1817,11 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ } break; case 'i': + if(config->content_disposition) { + warnf(global, + "--include and --remote-header-name cannot be combined.\n"); + return PARAM_BAD_USE; + } config->show_headers = toggle; /* show the headers as well in the general output stream */ break; @@ -2244,20 +2253,22 @@ ParameterError parse_args(struct GlobalConfig *global, int argc, struct OperationConfig *config = global->first; for(i = 1, stillflags = TRUE; i < argc && !result; i++) { - orig_opt = argv[i]; + orig_opt = curlx_convert_tchar_to_UTF8(argv[i]); - if(stillflags && ('-' == argv[i][0])) { + if(stillflags && ('-' == orig_opt[0])) { bool passarg; - char *flag = argv[i]; - if(!strcmp("--", argv[i])) + if(!strcmp("--", orig_opt)) /* This indicates the end of the flags and thus enables the following (URL) argument to start with -. */ stillflags = FALSE; else { - char *nextarg = (i < (argc - 1)) ? argv[i + 1] : NULL; + char *nextarg = (i < (argc - 1)) + ? curlx_convert_tchar_to_UTF8(argv[i + 1]) + : NULL; - result = getparameter(flag, nextarg, &passarg, global, config); + result = getparameter(orig_opt, nextarg, &passarg, global, config); + curlx_unicodefree(nextarg); config = global->last; if(result == PARAM_NEXT_OPERATION) { /* Reset result as PARAM_NEXT_OPERATION is only used here and not @@ -2293,9 +2304,12 @@ ParameterError parse_args(struct GlobalConfig *global, int argc, bool used; /* Just add the URL please */ - result = getparameter((char *)"--url", argv[i], &used, global, + result = getparameter("--url", orig_opt, &used, global, config); } + + if(!result) + curlx_unicodefree(orig_opt); } if(result && result != PARAM_HELP_REQUESTED && @@ -2310,5 +2324,6 @@ ParameterError parse_args(struct GlobalConfig *global, int argc, helpf(global->errors, "%s\n", reason); } + curlx_unicodefree(orig_opt); return result; } diff --git a/src/tool_getpass.c b/src/tool_getpass.c index dfe363b21..d3bd4e688 100644 --- a/src/tool_getpass.c +++ b/src/tool_getpass.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 @@ -238,7 +238,7 @@ char *getpass_r(const char *prompt, /* prompt to display */ fputs(prompt, stderr); nread = read(fd, password, buflen); if(nread > 0) - password[--nread] = '\0'; /* zero terminate where enter is stored */ + password[--nread] = '\0'; /* null-terminate where enter is stored */ else password[0] = '\0'; /* got nothing */ diff --git a/src/tool_help.c b/src/tool_help.c index 5afaf822e..ae319271c 100644 --- a/src/tool_help.c +++ b/src/tool_help.c @@ -48,6 +48,7 @@ struct helptxt { const char *desc; }; + static const struct helptxt helptext[] = { {" --abstract-unix-socket <path>", "Connect via abstract Unix domain socket"}, @@ -68,7 +69,7 @@ static const struct helptxt helptext[] = { {" --cert-status", "Verify the status of the server certificate"}, {" --cert-type <type>", - "Certificate file type (DER/PEM/ENG)"}, + "Certificate type (DER/PEM/ENG)"}, {" --ciphers <list of ciphers>", "SSL ciphers to use"}, {" --compressed", @@ -131,10 +132,10 @@ static const struct helptxt helptext[] = { "EGD socket path for random data"}, {" --engine <name>", "Crypto engine to use"}, - {" --etag-save <file>", - "Get an ETag from response header and save it to a FILE"}, {" --etag-compare <file>", - "Get an ETag from a file and send a conditional request"}, + "Pass an ETag from a file as a custom header"}, + {" --etag-save <file>", + "Parse ETag from a request and save it to a file"}, {" --expect100-timeout <seconds>", "How long to wait for 100-continue"}, {"-f, --fail", @@ -174,7 +175,7 @@ static const struct helptxt helptext[] = { {"-g, --globoff", "Disable URL sequences and ranges using {} and []"}, {" --happy-eyeballs-timeout-ms <milliseconds>", - "How long to wait in milliseconds for IPv6 before trying IPv4"}, + "Time for IPv6 before trying IPv4"}, {" --haproxy-protocol", "Send HAProxy PROXY protocol v1 header"}, {"-I, --head", @@ -351,8 +352,8 @@ static const struct helptxt helptext[] = { "SPNEGO proxy service name"}, {" --proxy-ssl-allow-beast", "Allow security flaw for interop for HTTPS proxy"}, - {" --proxy-tls13-ciphers <list>", - "TLS 1.3 ciphersuites for proxy (OpenSSL)"}, + {" --proxy-tls13-ciphers <ciphersuite list>", + "TLS 1.3 proxy cipher suites"}, {" --proxy-tlsauthtype <type>", "TLS authentication type for HTTPS proxy"}, {" --proxy-tlspassword <string>", @@ -391,18 +392,20 @@ static const struct helptxt helptext[] = { "Specify request command to use"}, {" --request-target", "Specify the target for this request"}, - {" --resolve <host:port:address[,address]...>", + {" --resolve <host:port:addr[,addr]...>", "Resolve the host+port to this address"}, {" --retry <num>", "Retry request if transient problems occur"}, + {" --retry-all-errors", + "Retry all errors (use with --retry)"}, {" --retry-connrefused", "Retry on connection refused (use with --retry)"}, {" --retry-delay <seconds>", "Wait time between retries"}, {" --retry-max-time <seconds>", "Retry only within this period"}, - {" --sasl-authzid <identity> ", - "Use this identity to act as during SASL PLAIN authentication"}, + {" --sasl-authzid <identity>", + "Identity for SASL PLAIN authentication"}, {" --sasl-ir", "Enable initial response in SASL authentication"}, {" --service-name <name>", @@ -437,10 +440,10 @@ static const struct helptxt helptext[] = { "Allow security flaw to improve interop"}, {" --ssl-no-revoke", "Disable cert revocation checks (Schannel)"}, - {" --ssl-revoke-best-effort", - "Ignore revocation offline or missing revocation list errors (Schannel)"}, {" --ssl-reqd", "Require SSL/TLS"}, + {" --ssl-revoke-best-effort", + "Ignore missing/offline cert CRL dist points"}, {"-2, --sslv2", "Use SSLv2"}, {"-3, --sslv3", @@ -465,8 +468,8 @@ static const struct helptxt helptext[] = { "Transfer based on a time condition"}, {" --tls-max <VERSION>", "Set maximum allowed TLS version"}, - {" --tls13-ciphers <list>", - "TLS 1.3 ciphersuites (OpenSSL)"}, + {" --tls13-ciphers <ciphersuite list>", + "TLS 1.3 cipher suites to use"}, {" --tlsauthtype <type>", "TLS authentication type"}, {" --tlspassword", diff --git a/src/tool_main.c b/src/tool_main.c index 25042895f..ccf098e94 100644 --- a/src/tool_main.c +++ b/src/tool_main.c @@ -273,22 +273,28 @@ static void restore_terminal(void) /* ** curl tool main function. */ +#ifdef _UNICODE +int wmain(int argc, wchar_t *argv[]) +#else int main(int argc, char *argv[]) +#endif { CURLcode result = CURLE_OK; struct GlobalConfig global; memset(&global, 0, sizeof(global)); #ifdef WIN32 +#ifdef _tcscmp /* Undocumented diagnostic option to list the full paths of all loaded modules. This is purposely pre-init. */ - if(argc == 2 && !strcmp(argv[1], "--dump-module-paths")) { + if(argc == 2 && !_tcscmp(argv[1], _T("--dump-module-paths"))) { struct curl_slist *item, *head = GetLoadedModulePaths(); for(item = head; item; item = item->next) printf("%s\n", item->data); curl_slist_free_all(head); return head ? 0 : 1; } +#endif /* _tcscmp */ /* win32_init must be called before other init routines. */ result = win32_init(); if(result) { diff --git a/src/tool_metalink.c b/src/tool_metalink.c index fce18d5a4..2ad7115db 100644 --- a/src/tool_metalink.c +++ b/src/tool_metalink.c @@ -399,7 +399,7 @@ static void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx) #endif /* CRYPTO LIBS */ -const digest_params MD5_DIGEST_PARAMS[] = { +const struct digest_params MD5_DIGEST_PARAMS[] = { { CURLX_FUNCTION_CAST(digest_init_func, MD5_Init), CURLX_FUNCTION_CAST(digest_update_func, MD5_Update), @@ -409,7 +409,7 @@ const digest_params MD5_DIGEST_PARAMS[] = { } }; -const digest_params SHA1_DIGEST_PARAMS[] = { +const struct digest_params SHA1_DIGEST_PARAMS[] = { { CURLX_FUNCTION_CAST(digest_init_func, SHA1_Init), CURLX_FUNCTION_CAST(digest_update_func, SHA1_Update), @@ -419,7 +419,7 @@ const digest_params SHA1_DIGEST_PARAMS[] = { } }; -const digest_params SHA256_DIGEST_PARAMS[] = { +const struct digest_params SHA256_DIGEST_PARAMS[] = { { CURLX_FUNCTION_CAST(digest_init_func, SHA256_Init), CURLX_FUNCTION_CAST(digest_update_func, SHA256_Update), @@ -429,15 +429,15 @@ const digest_params SHA256_DIGEST_PARAMS[] = { } }; -static const metalink_digest_def SHA256_DIGEST_DEF[] = { +static const struct metalink_digest_def SHA256_DIGEST_DEF[] = { {"sha-256", SHA256_DIGEST_PARAMS} }; -static const metalink_digest_def SHA1_DIGEST_DEF[] = { +static const struct metalink_digest_def SHA1_DIGEST_DEF[] = { {"sha-1", SHA1_DIGEST_PARAMS} }; -static const metalink_digest_def MD5_DIGEST_DEF[] = { +static const struct metalink_digest_def MD5_DIGEST_DEF[] = { {"md5", MD5_DIGEST_PARAMS} }; @@ -448,7 +448,7 @@ static const metalink_digest_def MD5_DIGEST_DEF[] = { * "Hash Function Textual Names". The latter is widely (and * historically) used in Metalink version 3. */ -static const metalink_digest_alias digest_aliases[] = { +static const struct metalink_digest_alias digest_aliases[] = { {"sha-256", SHA256_DIGEST_DEF}, {"sha256", SHA256_DIGEST_DEF}, {"sha-1", SHA1_DIGEST_DEF}, @@ -457,13 +457,9 @@ static const metalink_digest_alias digest_aliases[] = { {NULL, NULL} }; -static digest_context *digest_init(const digest_params *dparams) +static struct digest_context *digest_init(const struct digest_params *dparams) { - digest_context *ctxt; - - /* Create digest context */ - ctxt = malloc(sizeof(*ctxt)); - + struct digest_context *ctxt = malloc(sizeof(*ctxt)); if(!ctxt) return ctxt; @@ -485,7 +481,7 @@ static digest_context *digest_init(const digest_params *dparams) return ctxt; } -static int digest_update(digest_context *context, +static int digest_update(struct digest_context *context, const unsigned char *data, unsigned int len) { @@ -494,7 +490,7 @@ static int digest_update(digest_context *context, return 0; } -static int digest_final(digest_context *context, unsigned char *result) +static int digest_final(struct digest_context *context, unsigned char *result) { if(result) (*context->digest_hash->digest_final)(result, context->digest_hashctx); @@ -531,11 +527,11 @@ static unsigned char hex_to_uint(const char *s) * Hash algorithm not available. */ static int check_hash(const char *filename, - const metalink_digest_def *digest_def, + const struct metalink_digest_def *digest_def, const unsigned char *digest, FILE *error) { unsigned char *result; - digest_context *dctx; + struct digest_context *dctx; int check_ok, flags, fd; flags = O_RDONLY; @@ -597,7 +593,7 @@ static int check_hash(const char *filename, } int metalink_check_hash(struct GlobalConfig *config, - metalinkfile *mlfile, + struct metalinkfile *mlfile, const char *filename) { int rv; @@ -612,11 +608,11 @@ int metalink_check_hash(struct GlobalConfig *config, return rv; } -static metalink_checksum * -checksum_from_hex_digest(const metalink_digest_def *digest_def, +static struct metalink_checksum * +checksum_from_hex_digest(const struct metalink_digest_def *digest_def, const char *hex_digest) { - metalink_checksum *chksum; + struct metalink_checksum *chksum; unsigned char *digest; size_t i; size_t len = strlen(hex_digest); @@ -627,7 +623,7 @@ checksum_from_hex_digest(const metalink_digest_def *digest_def, for(i = 0; i < len; i += 2) { digest[i/2] = hex_to_uint(hex_digest + i); } - chksum = malloc(sizeof(metalink_checksum)); + chksum = malloc(sizeof(struct metalink_checksum)); if(chksum) { chksum->digest_def = digest_def; chksum->digest = digest; @@ -637,10 +633,9 @@ checksum_from_hex_digest(const metalink_digest_def *digest_def, return chksum; } -static metalink_resource *new_metalink_resource(const char *url) +static struct metalink_resource *new_metalink_resource(const char *url) { - metalink_resource *res; - res = malloc(sizeof(metalink_resource)); + struct metalink_resource *res = malloc(sizeof(struct metalink_resource)); if(res) { res->next = NULL; res->url = strdup(url); @@ -656,7 +651,7 @@ static metalink_resource *new_metalink_resource(const char *url) letter is in [0-9A-Za-z] and the length of the string equals to the result length of digest * 2. */ static int check_hex_digest(const char *hex_digest, - const metalink_digest_def *digest_def) + const struct metalink_digest_def *digest_def) { size_t i; for(i = 0; hex_digest[i]; ++i) { @@ -669,10 +664,9 @@ static int check_hex_digest(const char *hex_digest, return digest_def->dparams->digest_resultlen * 2 == i; } -static metalinkfile *new_metalinkfile(metalink_file_t *fileinfo) +static struct metalinkfile *new_metalinkfile(metalink_file_t *fileinfo) { - metalinkfile *f; - f = (metalinkfile*)malloc(sizeof(metalinkfile)); + struct metalinkfile *f = malloc(sizeof(struct metalinkfile)); if(!f) return NULL; @@ -685,7 +679,7 @@ static metalinkfile *new_metalinkfile(metalink_file_t *fileinfo) f->checksum = NULL; f->resource = NULL; if(fileinfo->checksums) { - const metalink_digest_alias *digest_alias; + const struct metalink_digest_alias *digest_alias; for(digest_alias = digest_aliases; digest_alias->alias_name; ++digest_alias) { metalink_checksum_t **p; @@ -705,11 +699,11 @@ static metalinkfile *new_metalinkfile(metalink_file_t *fileinfo) } if(fileinfo->resources) { metalink_resource_t **p; - metalink_resource root, *tail; + struct metalink_resource root, *tail; root.next = NULL; tail = &root; for(p = fileinfo->resources; *p; ++p) { - metalink_resource *res; + struct metalink_resource *res; /* Filter by type if it is non-NULL. In Metalink v3, type includes the type of the resource. In curl, we are only interested in HTTP, HTTPS and FTP. In addition to them, @@ -798,7 +792,7 @@ int parse_metalink(struct OperationConfig *config, struct OutStruct *outs, url = new_getout(config); if(url) { - metalinkfile *mlfile = new_metalinkfile(*files); + struct metalinkfile *mlfile = new_metalinkfile(*files); if(!mlfile) break; @@ -876,24 +870,23 @@ int check_metalink_content_type(const char *content_type) return check_content_type(content_type, "application/metalink+xml"); } -int count_next_metalink_resource(metalinkfile *mlfile) +int count_next_metalink_resource(struct metalinkfile *mlfile) { int count = 0; - metalink_resource *res; + struct metalink_resource *res; for(res = mlfile->resource; res; res = res->next, ++count); return count; } -static void delete_metalink_checksum(metalink_checksum *chksum) +static void delete_metalink_checksum(struct metalink_checksum *chksum) { - if(chksum == NULL) { + if(!chksum) return; - } Curl_safefree(chksum->digest); Curl_safefree(chksum); } -static void delete_metalink_resource(metalink_resource *res) +static void delete_metalink_resource(struct metalink_resource *res) { if(res == NULL) { return; @@ -902,16 +895,16 @@ static void delete_metalink_resource(metalink_resource *res) Curl_safefree(res); } -void delete_metalinkfile(metalinkfile *mlfile) +void delete_metalinkfile(struct metalinkfile *mlfile) { - metalink_resource *res; + struct metalink_resource *res; if(mlfile == NULL) { return; } Curl_safefree(mlfile->filename); delete_metalink_checksum(mlfile->checksum); for(res = mlfile->resource; res;) { - metalink_resource *next; + struct metalink_resource *next; next = res->next; delete_metalink_resource(res); res = next; @@ -923,7 +916,7 @@ void clean_metalink(struct OperationConfig *config) { if(config) { while(config->metalinkfile_list) { - metalinkfile *mlfile = config->metalinkfile_list; + struct metalinkfile *mlfile = config->metalinkfile_list; config->metalinkfile_list = config->metalinkfile_list->next; delete_metalinkfile(mlfile); } diff --git a/src/tool_metalink.h b/src/tool_metalink.h index db2f702e5..abf75dd17 100644 --- a/src/tool_metalink.h +++ b/src/tool_metalink.h @@ -35,46 +35,46 @@ typedef void (*digest_update_func)(void *context, unsigned int len); typedef void (*digest_final_func)(unsigned char *result, void *context); -typedef struct { +struct digest_params { digest_init_func digest_init; /* Initialize context procedure */ digest_update_func digest_update; /* Update context with data */ digest_final_func digest_final; /* Get final result procedure */ unsigned int digest_ctxtsize; /* Context structure size */ unsigned int digest_resultlen; /* Result length (bytes) */ -} digest_params; +}; -typedef struct { - const digest_params *digest_hash; /* Hash function definition */ +struct digest_context { + const struct digest_params *digest_hash; /* Hash function definition */ void *digest_hashctx; /* Hash function context */ -} digest_context; +}; -typedef struct { +struct metalink_digest_def { const char *hash_name; - const digest_params *dparams; -} metalink_digest_def; + const struct digest_params *dparams; +}; -typedef struct { +struct metalink_digest_alias { const char *alias_name; - const metalink_digest_def *digest_def; -} metalink_digest_alias; + const struct metalink_digest_def *digest_def; +}; -typedef struct metalink_checksum { - const metalink_digest_def *digest_def; +struct metalink_checksum { + const struct metalink_digest_def *digest_def; /* raw digest value, not ascii hex digest */ unsigned char *digest; -} metalink_checksum; +}; -typedef struct metalink_resource { +struct metalink_resource { struct metalink_resource *next; char *url; -} metalink_resource; +}; -typedef struct metalinkfile { +struct metalinkfile { struct metalinkfile *next; char *filename; - metalink_checksum *checksum; - metalink_resource *resource; -} metalinkfile; + struct metalink_checksum *checksum; + struct metalink_resource *resource; +}; #ifdef USE_METALINK @@ -89,18 +89,18 @@ typedef struct metalinkfile { (CURL_REQ_LIBMETALINK_MINOR * 100) + \ CURL_REQ_LIBMETALINK_PATCH) -extern const digest_params MD5_DIGEST_PARAMS[1]; -extern const digest_params SHA1_DIGEST_PARAMS[1]; -extern const digest_params SHA256_DIGEST_PARAMS[1]; +extern const struct digest_params MD5_DIGEST_PARAMS[1]; +extern const struct digest_params SHA1_DIGEST_PARAMS[1]; +extern const struct digest_params SHA256_DIGEST_PARAMS[1]; #include <metalink/metalink.h> /* * Counts the resource in the metalinkfile. */ -int count_next_metalink_resource(metalinkfile *mlfile); +int count_next_metalink_resource(struct metalinkfile *mlfile); -void delete_metalinkfile(metalinkfile *mlfile); +void delete_metalinkfile(struct metalinkfile *mlfile); void clean_metalink(struct OperationConfig *config); /* @@ -143,7 +143,7 @@ int check_metalink_content_type(const char *content_type); * Metalink does not contain checksum. */ int metalink_check_hash(struct GlobalConfig *config, - metalinkfile *mlfile, + struct metalinkfile *mlfile, const char *filename); /* diff --git a/src/tool_operate.c b/src/tool_operate.c index 3f83136af..922d81e4d 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -425,10 +425,6 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, metalink_parser_context_delete(outs->metalink_parser); #endif /* USE_METALINK */ - if(outs->is_cd_filename && outs->stream && !global->mute && - outs->filename) - printf("curl: Saved to filename '%s'\n", outs->filename); - /* if retry-max-time is non-zero, make sure we haven't exceeded the time */ if(per->retry_numretries && @@ -437,13 +433,14 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, config->retry_maxtime*1000L)) ) { enum { RETRY_NO, + RETRY_ALL_ERRORS, RETRY_TIMEOUT, RETRY_CONNREFUSED, RETRY_HTTP, RETRY_FTP, RETRY_LAST /* not used */ } retry = RETRY_NO; - long response; + long response = 0; if((CURLE_OPERATION_TIMEDOUT == result) || (CURLE_COULDNT_RESOLVE_HOST == result) || (CURLE_COULDNT_RESOLVE_PROXY == result) || @@ -452,7 +449,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, retry = RETRY_TIMEOUT; else if(config->retry_connrefused && (CURLE_COULDNT_CONNECT == result)) { - long oserrno; + long oserrno = 0; curl_easy_getinfo(curl, CURLINFO_OS_ERRNO, &oserrno); if(ECONNREFUSED == oserrno) retry = RETRY_CONNREFUSED; @@ -463,7 +460,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, /* If it returned OK. _or_ failonerror was enabled and it returned due to such an error, check for HTTP transient errors to retry on. */ - long protocol; + long protocol = 0; curl_easy_getinfo(curl, CURLINFO_PROTOCOL, &protocol); if((protocol == CURLPROTO_HTTP) || (protocol == CURLPROTO_HTTPS)) { /* This was HTTP(S) */ @@ -491,7 +488,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, } } /* if CURLE_OK */ else if(result) { - long protocol; + long protocol = 0; curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response); curl_easy_getinfo(curl, CURLINFO_PROTOCOL, &protocol); @@ -506,11 +503,15 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, retry = RETRY_FTP; } + if(result && !retry && config->retry_all_errors) + retry = RETRY_ALL_ERRORS; + if(retry) { long sleeptime = 0; curl_off_t retry_after = 0; static const char * const m[]={ NULL, + "(retrying all errors)", "timeout", "connection refused", "HTTP error", @@ -584,7 +585,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, else if(per->metalink) { /* Metalink: Decide to try the next resource or not. Try the next resource if download was not successful. */ - long response; + long response = 0; if(CURLE_OK == result) { /* TODO We want to try next resource when download was not successful. How to know that? */ @@ -694,7 +695,7 @@ static CURLcode single_transfer(struct GlobalConfig *global, { CURLcode result = CURLE_OK; struct getout *urlnode; - metalinkfile *mlfile_last = NULL; + struct metalinkfile *mlfile_last = NULL; bool orig_noprogress = global->noprogress; bool orig_isatty = global->isatty; struct State *state = &config->state; @@ -735,10 +736,10 @@ static CURLcode single_transfer(struct GlobalConfig *global, while(config->state.urlnode) { char *infiles; /* might be a glob pattern */ - URLGlob *inglob = state->inglob; + struct URLGlob *inglob = state->inglob; bool metalink = FALSE; /* metalink download? */ - metalinkfile *mlfile; - metalink_resource *mlres; + struct metalinkfile *mlfile; + struct metalink_resource *mlres; urlnode = config->state.urlnode; if(urlnode->flags & GETOUT_METALINK) { @@ -1551,11 +1552,90 @@ static CURLcode single_transfer(struct GlobalConfig *global, } } + /* In debug build of curl tool, using + * --cert loadmem=<filename>:<password> --cert-type p12 + * must do the same thing than classic: + * --cert <filename>:<password> --cert-type p12 + * but is designed to test blob */ +#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"); + void *certdata = NULL; + long filesize = 0; + bool continue_reading = fInCert != NULL; + if(continue_reading) + continue_reading = fseek(fInCert, 0, SEEK_END) == 0; + if(continue_reading) + filesize = ftell(fInCert); + if(filesize < 0) + continue_reading = FALSE; + if(continue_reading) + continue_reading = fseek(fInCert, 0, SEEK_SET) == 0; + if(continue_reading) + certdata = malloc(((size_t)filesize) + 1); + if((!certdata) || + ((int)fread(certdata, (size_t)filesize, 1, fInCert) != 1)) + continue_reading = FALSE; + if(fInCert) + fclose(fInCert); + if((filesize > 0) && continue_reading) { + struct curl_blob structblob; + structblob.data = certdata; + 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 don't reuse + * original mem pointer */ + memset(certdata, 0, (size_t)filesize); + } + free(certdata); + } + else +#endif my_setopt_str(curl, CURLOPT_SSLCERT, config->cert); my_setopt_str(curl, CURLOPT_PROXY_SSLCERT, config->proxy_cert); my_setopt_str(curl, CURLOPT_SSLCERTTYPE, config->cert_type); my_setopt_str(curl, CURLOPT_PROXY_SSLCERTTYPE, config->proxy_cert_type); + + +#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"); + void *certdata = NULL; + long filesize = 0; + bool continue_reading = fInCert != NULL; + if(continue_reading) + continue_reading = fseek(fInCert, 0, SEEK_END) == 0; + if(continue_reading) + filesize = ftell(fInCert); + if(filesize < 0) + continue_reading = FALSE; + if(continue_reading) + continue_reading = fseek(fInCert, 0, SEEK_SET) == 0; + if(continue_reading) + certdata = malloc(((size_t)filesize) + 1); + if((!certdata) || + ((int)fread(certdata, (size_t)filesize, 1, fInCert) != 1)) + continue_reading = FALSE; + if(fInCert) + fclose(fInCert); + if((filesize > 0) && continue_reading) { + struct curl_blob structblob; + structblob.data = certdata; + 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 don't reuse + * original mem pointer */ + memset(certdata, 0, (size_t)filesize); + } + free(certdata); + } + else +#endif my_setopt_str(curl, CURLOPT_SSLKEY, config->key); my_setopt_str(curl, CURLOPT_PROXY_SSLKEY, config->proxy_key); my_setopt_str(curl, CURLOPT_SSLKEYTYPE, config->key_type); @@ -1589,7 +1669,25 @@ static CURLcode single_transfer(struct GlobalConfig *global, config->ssl_version | config->ssl_version_max); my_setopt_enum(curl, CURLOPT_PROXY_SSLVERSION, config->proxy_ssl_version); + + { + long mask = + (config->ssl_allow_beast ? CURLSSLOPT_ALLOW_BEAST : 0) | + (config->ssl_revoke_best_effort ? + CURLSSLOPT_REVOKE_BEST_EFFORT : 0) | + (config->native_ca_store ? + CURLSSLOPT_NATIVE_CA : 0) | + (config->ssl_no_revoke ? CURLSSLOPT_NO_REVOKE : 0); + + if(mask) + my_setopt_bitmask(curl, CURLOPT_SSL_OPTIONS, mask); + } + + if(config->proxy_ssl_allow_beast) + my_setopt(curl, CURLOPT_PROXY_SSL_OPTIONS, + (long)CURLSSLOPT_ALLOW_BEAST); } + if(config->path_as_is) my_setopt(curl, CURLOPT_PATH_AS_IS, 1L); @@ -1900,20 +1998,6 @@ static CURLcode single_transfer(struct GlobalConfig *global, my_setopt_str(curl, CURLOPT_GSSAPI_DELEGATION, config->gssapi_delegation); - /* new in 7.25.0, 7.44.0 and 7.70.0 */ - { - long mask = (config->ssl_allow_beast ? CURLSSLOPT_ALLOW_BEAST : 0) | - (config->ssl_revoke_best_effort ? - CURLSSLOPT_REVOKE_BEST_EFFORT : 0) | - (config->ssl_no_revoke ? CURLSSLOPT_NO_REVOKE : 0); - if(mask) - my_setopt_bitmask(curl, CURLOPT_SSL_OPTIONS, mask); - } - - if(config->proxy_ssl_allow_beast) - my_setopt(curl, CURLOPT_PROXY_SSL_OPTIONS, - (long)CURLSSLOPT_ALLOW_BEAST); - if(config->mail_auth) my_setopt_str(curl, CURLOPT_MAIL_AUTH, config->mail_auth); @@ -2410,6 +2494,7 @@ static CURLcode run_all_transfers(struct GlobalConfig *global, CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[]) { CURLcode result = CURLE_OK; + char *first_arg = curlx_convert_tchar_to_UTF8(argv[1]); /* Setup proper locale from environment */ #ifdef HAVE_SETLOCALE @@ -2418,8 +2503,8 @@ CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[]) /* Parse .curlrc if necessary */ if((argc == 1) || - (!curl_strequal(argv[1], "-q") && - !curl_strequal(argv[1], "--disable"))) { + (!curl_strequal(first_arg, "-q") && + !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 */ @@ -2429,6 +2514,8 @@ CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[]) } } + curlx_unicodefree(first_arg); + if(!result) { /* Parse the command line arguments */ ParameterError res = parse_args(global, argc, argv); diff --git a/src/tool_operate.h b/src/tool_operate.h index 39227c0f3..0fa5adee5 100644 --- a/src/tool_operate.h +++ b/src/tool_operate.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 @@ -38,8 +38,8 @@ struct per_transfer { struct timeval retrystart; bool metalink; /* nonzero for metalink download. */ bool metalink_next_res; - metalinkfile *mlfile; - metalink_resource *mlres; + struct metalinkfile *mlfile; + struct metalink_resource *mlres; char *this_url; char *outfile; bool infdopen; /* TRUE if infd needs closing */ diff --git a/src/tool_paramhlp.c b/src/tool_paramhlp.c index 67702ebe2..c375bcc82 100644 --- a/src/tool_paramhlp.c +++ b/src/tool_paramhlp.c @@ -180,7 +180,7 @@ void cleanarg(char *str) ParameterError str2num(long *val, const char *str) { if(str) { - char *endptr; + char *endptr = NULL; long num; errno = 0; num = strtol(str, &endptr, 10); diff --git a/src/tool_parsecfg.c b/src/tool_parsecfg.c index efb9159e7..5aeb2eebf 100644 --- a/src/tool_parsecfg.c +++ b/src/tool_parsecfg.c @@ -173,7 +173,7 @@ int parseconfig(const char *filename, struct GlobalConfig *global) /* ... and has ended here */ if(*line) - *line++ = '\0'; /* zero terminate, we have a local copy of the data */ + *line++ = '\0'; /* null-terminate, we have a local copy of the data */ #ifdef DEBUG_CONFIG fprintf(stderr, "GOT: %s\n", option); @@ -203,7 +203,7 @@ int parseconfig(const char *filename, struct GlobalConfig *global) line++; if(*line) { - *line = '\0'; /* zero terminate */ + *line = '\0'; /* null-terminate */ /* to detect mistakes better, see if there's data following */ line++; @@ -329,7 +329,7 @@ static const char *unslashquote(const char *line, char *param) else *param++ = *line++; } - *param = '\0'; /* always zero terminate */ + *param = '\0'; /* always null-terminate */ return line; } diff --git a/src/tool_setopt.c b/src/tool_setopt.c index f244ba490..9858d49c9 100644 --- a/src/tool_setopt.c +++ b/src/tool_setopt.c @@ -43,7 +43,7 @@ #define NV1(e, v) {#e, (v)} #define NVEND {NULL, 0} /* sentinel to mark end of list */ -const NameValue setopt_nv_CURLPROXY[] = { +const struct NameValue setopt_nv_CURLPROXY[] = { NV(CURLPROXY_HTTP), NV(CURLPROXY_HTTP_1_0), NV(CURLPROXY_HTTPS), @@ -54,7 +54,7 @@ const NameValue setopt_nv_CURLPROXY[] = { NVEND, }; -const NameValue setopt_nv_CURL_SOCKS_PROXY[] = { +const struct NameValue setopt_nv_CURL_SOCKS_PROXY[] = { NV(CURLPROXY_SOCKS4), NV(CURLPROXY_SOCKS5), NV(CURLPROXY_SOCKS4A), @@ -62,7 +62,7 @@ const NameValue setopt_nv_CURL_SOCKS_PROXY[] = { NVEND, }; -const NameValueUnsigned setopt_nv_CURLAUTH[] = { +const struct NameValueUnsigned setopt_nv_CURLAUTH[] = { NV(CURLAUTH_ANY), /* combination */ NV(CURLAUTH_ANYSAFE), /* combination */ NV(CURLAUTH_BASIC), @@ -76,7 +76,7 @@ const NameValueUnsigned setopt_nv_CURLAUTH[] = { NVEND, }; -const NameValue setopt_nv_CURL_HTTP_VERSION[] = { +const struct NameValue setopt_nv_CURL_HTTP_VERSION[] = { NV(CURL_HTTP_VERSION_NONE), NV(CURL_HTTP_VERSION_1_0), NV(CURL_HTTP_VERSION_1_1), @@ -86,7 +86,7 @@ const NameValue setopt_nv_CURL_HTTP_VERSION[] = { NVEND, }; -const NameValue setopt_nv_CURL_SSLVERSION[] = { +const struct NameValue setopt_nv_CURL_SSLVERSION[] = { NV(CURL_SSLVERSION_DEFAULT), NV(CURL_SSLVERSION_TLSv1), NV(CURL_SSLVERSION_SSLv2), @@ -98,7 +98,7 @@ const NameValue setopt_nv_CURL_SSLVERSION[] = { NVEND, }; -const NameValue setopt_nv_CURL_TIMECOND[] = { +const struct NameValue setopt_nv_CURL_TIMECOND[] = { NV(CURL_TIMECOND_IFMODSINCE), NV(CURL_TIMECOND_IFUNMODSINCE), NV(CURL_TIMECOND_LASTMOD), @@ -106,14 +106,14 @@ const NameValue setopt_nv_CURL_TIMECOND[] = { NVEND, }; -const NameValue setopt_nv_CURLFTPSSL_CCC[] = { +const struct NameValue setopt_nv_CURLFTPSSL_CCC[] = { NV(CURLFTPSSL_CCC_NONE), NV(CURLFTPSSL_CCC_PASSIVE), NV(CURLFTPSSL_CCC_ACTIVE), NVEND, }; -const NameValue setopt_nv_CURLUSESSL[] = { +const struct NameValue setopt_nv_CURLUSESSL[] = { NV(CURLUSESSL_NONE), NV(CURLUSESSL_TRY), NV(CURLUSESSL_CONTROL), @@ -121,15 +121,16 @@ const NameValue setopt_nv_CURLUSESSL[] = { NVEND, }; -const NameValueUnsigned setopt_nv_CURLSSLOPT[] = { +const struct NameValueUnsigned setopt_nv_CURLSSLOPT[] = { NV(CURLSSLOPT_ALLOW_BEAST), NV(CURLSSLOPT_NO_REVOKE), NV(CURLSSLOPT_NO_PARTIALCHAIN), NV(CURLSSLOPT_REVOKE_BEST_EFFORT), + NV(CURLSSLOPT_NATIVE_CA), NVEND, }; -const NameValue setopt_nv_CURL_NETRC[] = { +const struct NameValue setopt_nv_CURL_NETRC[] = { NV(CURL_NETRC_IGNORED), NV(CURL_NETRC_OPTIONAL), NV(CURL_NETRC_REQUIRED), @@ -138,7 +139,7 @@ const NameValue setopt_nv_CURL_NETRC[] = { /* These mappings essentially triplicated - see * tool_libinfo.c and tool_paramhlp.c */ -const NameValue setopt_nv_CURLPROTO[] = { +const struct NameValue setopt_nv_CURLPROTO[] = { NV(CURLPROTO_ALL), /* combination */ NV(CURLPROTO_DICT), NV(CURLPROTO_FILE), @@ -166,7 +167,7 @@ const NameValue setopt_nv_CURLPROTO[] = { }; /* These options have non-zero default values. */ -static const NameValue setopt_nv_CURLNONZERODEFAULTS[] = { +static const struct NameValue setopt_nv_CURLNONZERODEFAULTS[] = { NV1(CURLOPT_SSL_VERIFYPEER, 1), NV1(CURLOPT_SSL_VERIFYHOST, 1), NV1(CURLOPT_SSL_ENABLE_NPN, 1), @@ -272,7 +273,7 @@ static char *c_escape(const char *str, size_t len) /* setopt wrapper for enum types */ CURLcode tool_setopt_enum(CURL *curl, struct GlobalConfig *config, const char *name, CURLoption tag, - const NameValue *nvlist, long lval) + const struct NameValue *nvlist, long lval) { CURLcode ret = CURLE_OK; bool skip = FALSE; @@ -283,7 +284,7 @@ CURLcode tool_setopt_enum(CURL *curl, struct GlobalConfig *config, if(config->libcurl && !skip && !ret) { /* we only use this for real if --libcurl was used */ - const NameValue *nv = NULL; + const struct NameValue *nv = NULL; for(nv = nvlist; nv->name; nv++) { if(nv->value == lval) break; /* found it */ @@ -306,7 +307,7 @@ CURLcode tool_setopt_enum(CURL *curl, struct GlobalConfig *config, /* setopt wrapper for flags */ CURLcode tool_setopt_flags(CURL *curl, struct GlobalConfig *config, const char *name, CURLoption tag, - const NameValue *nvlist, long lval) + const struct NameValue *nvlist, long lval) { CURLcode ret = CURLE_OK; bool skip = FALSE; @@ -319,7 +320,7 @@ CURLcode tool_setopt_flags(CURL *curl, struct GlobalConfig *config, /* we only use this for real if --libcurl was used */ char preamble[80]; /* should accommodate any symbol name */ long rest = lval; /* bits not handled yet */ - const NameValue *nv = NULL; + const struct NameValue *nv = NULL; msnprintf(preamble, sizeof(preamble), "curl_easy_setopt(hnd, %s, ", name); for(nv = nvlist; nv->name; nv++) { @@ -348,7 +349,7 @@ CURLcode tool_setopt_flags(CURL *curl, struct GlobalConfig *config, /* setopt wrapper for bitmasks */ CURLcode tool_setopt_bitmask(CURL *curl, struct GlobalConfig *config, const char *name, CURLoption tag, - const NameValueUnsigned *nvlist, + const struct NameValueUnsigned *nvlist, long lval) { CURLcode ret = CURLE_OK; @@ -362,7 +363,7 @@ CURLcode tool_setopt_bitmask(CURL *curl, struct GlobalConfig *config, /* we only use this for real if --libcurl was used */ char preamble[80]; unsigned long rest = (unsigned long)lval; - const NameValueUnsigned *nv = NULL; + const struct NameValueUnsigned *nv = NULL; msnprintf(preamble, sizeof(preamble), "curl_easy_setopt(hnd, %s, ", name); for(nv = nvlist; nv->name; nv++) { @@ -417,13 +418,13 @@ static CURLcode libcurl_generate_slist(struct curl_slist *slist, int *slistno) static CURLcode libcurl_generate_mime(CURL *curl, struct GlobalConfig *config, - tool_mime *toolmime, + struct tool_mime *toolmime, int *mimeno); /* Forward. */ /* Wrapper to generate source code for a mime part. */ static CURLcode libcurl_generate_mime_part(CURL *curl, struct GlobalConfig *config, - tool_mime *part, + struct tool_mime *part, int mimeno) { CURLcode ret = CURLE_OK; @@ -556,7 +557,7 @@ nomem: /* Wrapper to generate source code for a mime structure. */ static CURLcode libcurl_generate_mime(CURL *curl, struct GlobalConfig *config, - tool_mime *toolmime, + struct tool_mime *toolmime, int *mimeno) { CURLcode ret = CURLE_OK; @@ -640,7 +641,7 @@ CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *config, /* Value is expected to be a long */ long lval = va_arg(arg, long); long defval = 0L; - const NameValue *nv = NULL; + const struct NameValue *nv = NULL; for(nv = setopt_nv_CURLNONZERODEFAULTS; nv->name; nv++) { if(!strcmp(name, nv->name)) { defval = nv->value; @@ -682,7 +683,7 @@ CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *config, ret = curl_easy_setopt(curl, tag, pval); } - else { + else if(tag < CURLOPTTYPE_BLOB) { /* Value is expected to be curl_off_t */ curl_off_t oval = va_arg(arg, curl_off_t); msnprintf(buf, sizeof(buf), @@ -693,6 +694,20 @@ CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *config, if(!oval) skip = TRUE; } + else { + /* Value is a blob */ + void *pblob = va_arg(arg, void *); + + /* blobs are never printable */ + if(pblob) { + value = "blobpointer"; + remark = TRUE; + } + else + skip = TRUE; + + ret = curl_easy_setopt(curl, tag, pblob); + } va_end(arg); diff --git a/src/tool_setopt.h b/src/tool_setopt.h index 48e9e818d..9fe142cf1 100644 --- a/src/tool_setopt.h +++ b/src/tool_setopt.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 @@ -43,27 +43,27 @@ bool tool_setopt_skip(CURLoption tag); #ifndef CURL_DISABLE_LIBCURL_OPTION /* Associate symbolic names with option values */ -typedef struct { +struct NameValue { const char *name; long value; -} NameValue; +}; -typedef struct { +struct NameValueUnsigned { const char *name; unsigned long value; -} NameValueUnsigned; - -extern const NameValue setopt_nv_CURLPROXY[]; -extern const NameValue setopt_nv_CURL_SOCKS_PROXY[]; -extern const NameValue setopt_nv_CURL_HTTP_VERSION[]; -extern const NameValue setopt_nv_CURL_SSLVERSION[]; -extern const NameValue setopt_nv_CURL_TIMECOND[]; -extern const NameValue setopt_nv_CURLFTPSSL_CCC[]; -extern const NameValue setopt_nv_CURLUSESSL[]; -extern const NameValueUnsigned setopt_nv_CURLSSLOPT[]; -extern const NameValue setopt_nv_CURL_NETRC[]; -extern const NameValue setopt_nv_CURLPROTO[]; -extern const NameValueUnsigned setopt_nv_CURLAUTH[]; +}; + +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_TIMECOND[]; +extern const struct NameValue setopt_nv_CURLFTPSSL_CCC[]; +extern const struct NameValue setopt_nv_CURLUSESSL[]; +extern const struct NameValueUnsigned setopt_nv_CURLSSLOPT[]; +extern const struct NameValue setopt_nv_CURL_NETRC[]; +extern const struct NameValue setopt_nv_CURLPROTO[]; +extern const struct NameValueUnsigned setopt_nv_CURLAUTH[]; /* Map options to NameValue sets */ #define setopt_nv_CURLOPT_HTTP_VERSION setopt_nv_CURL_HTTP_VERSION @@ -85,13 +85,13 @@ extern const NameValueUnsigned setopt_nv_CURLAUTH[]; CURLcode tool_setopt_enum(CURL *curl, struct GlobalConfig *config, const char *name, CURLoption tag, - const NameValue *nv, long lval); + const struct NameValue *nv, long lval); CURLcode tool_setopt_flags(CURL *curl, struct GlobalConfig *config, const char *name, CURLoption tag, - const NameValue *nv, long lval); + const struct NameValue *nv, long lval); CURLcode tool_setopt_bitmask(CURL *curl, struct GlobalConfig *config, const char *name, CURLoption tag, - const NameValueUnsigned *nv, long lval); + const struct NameValueUnsigned *nv, long lval); CURLcode tool_setopt_mimepost(CURL *curl, struct GlobalConfig *config, const char *name, CURLoption tag, curl_mime *mimepost); diff --git a/src/tool_urlglob.c b/src/tool_urlglob.c index 6c8716104..430ca88ba 100644 --- a/src/tool_urlglob.c +++ b/src/tool_urlglob.c @@ -34,9 +34,9 @@ #define GLOBERROR(string, column, code) \ glob->error = string, glob->pos = column, code -static CURLcode glob_fixed(URLGlob *glob, char *fixed, size_t len) +static CURLcode glob_fixed(struct URLGlob *glob, char *fixed, size_t len) { - URLPattern *pat = &glob->pattern[glob->size]; + struct URLPattern *pat = &glob->pattern[glob->size]; pat->type = UPTSet; pat->content.Set.size = 1; pat->content.Set.ptr_s = 0; @@ -74,14 +74,14 @@ static int multiply(unsigned long *amount, long with) return 0; } -static CURLcode glob_set(URLGlob *glob, char **patternp, +static CURLcode glob_set(struct URLGlob *glob, char **patternp, size_t *posp, unsigned long *amount, int globindex) { /* processes a set expression with the point behind the opening '{' ','-separated elements are collected until the next closing '}' */ - URLPattern *pat; + struct URLPattern *pat; bool done = FALSE; char *buf = glob->glob_buffer; char *pattern = *patternp; @@ -168,7 +168,7 @@ static CURLcode glob_set(URLGlob *glob, char **patternp, return CURLE_OK; } -static CURLcode glob_range(URLGlob *glob, char **patternp, +static CURLcode glob_range(struct URLGlob *glob, char **patternp, size_t *posp, unsigned long *amount, int globindex) { @@ -178,7 +178,7 @@ static CURLcode glob_range(URLGlob *glob, char **patternp, - num range with leading zeros: e.g. "001-999]" expression is checked for well-formedness and collected until the next ']' */ - URLPattern *pat; + struct URLPattern *pat; int rc; char *pattern = *patternp; char *c; @@ -319,6 +319,8 @@ static CURLcode glob_range(URLGlob *glob, char **patternp, return CURLE_OK; } +#define MAX_IP6LEN 128 + static bool peek_ipv6(const char *str, size_t *skip) { /* @@ -326,30 +328,35 @@ static bool peek_ipv6(const char *str, size_t *skip) * - Valid globs contain a hyphen and <= 1 colon. * - IPv6 literals contain no hyphens and >= 2 colons. */ - size_t i = 0; - size_t colons = 0; - if(str[i++] != '[') { + char hostname[MAX_IP6LEN]; + CURLU *u; + char *endbr = strchr(str, ']'); + size_t hlen; + CURLUcode rc; + if(!endbr) return FALSE; - } - for(;;) { - const char c = str[i++]; - if(ISALNUM(c) || c == '.' || c == '%') { - /* ok */ - } - else if(c == ':') { - colons++; - } - else if(c == ']') { - *skip = i; - return colons >= 2 ? TRUE : FALSE; - } - else { - return FALSE; - } - } + + hlen = endbr - str + 1; + if(hlen >= MAX_IP6LEN) + return FALSE; + + u = curl_url(); + if(!u) + return FALSE; + + memcpy(hostname, str, hlen); + hostname[hlen] = 0; + + /* ask to "guess scheme" as then it works without a https:// prefix */ + rc = curl_url_set(u, CURLUPART_URL, hostname, CURLU_GUESS_SCHEME); + + curl_url_cleanup(u); + if(!rc) + *skip = hlen; + return rc ? FALSE : TRUE; } -static CURLcode glob_parse(URLGlob *glob, char *pattern, +static CURLcode glob_parse(struct URLGlob *glob, char *pattern, size_t pos, unsigned long *amount) { /* processes a literal string component of a URL @@ -427,14 +434,14 @@ static CURLcode glob_parse(URLGlob *glob, char *pattern, return res; } -CURLcode glob_url(URLGlob **glob, char *url, unsigned long *urlnum, +CURLcode glob_url(struct URLGlob **glob, char *url, unsigned long *urlnum, FILE *error) { /* * We can deal with any-size, just make a buffer with the same length * as the specified URL! */ - URLGlob *glob_expand; + struct URLGlob *glob_expand; unsigned long amount = 0; char *glob_buffer; CURLcode res; @@ -446,7 +453,7 @@ CURLcode glob_url(URLGlob **glob, char *url, unsigned long *urlnum, return CURLE_OUT_OF_MEMORY; glob_buffer[0] = 0; - glob_expand = calloc(1, sizeof(URLGlob)); + glob_expand = calloc(1, sizeof(struct URLGlob)); if(!glob_expand) { Curl_safefree(glob_buffer); return CURLE_OUT_OF_MEMORY; @@ -483,7 +490,7 @@ CURLcode glob_url(URLGlob **glob, char *url, unsigned long *urlnum, return CURLE_OK; } -void glob_cleanup(URLGlob* glob) +void glob_cleanup(struct URLGlob *glob) { size_t i; int elem; @@ -506,9 +513,9 @@ void glob_cleanup(URLGlob* glob) Curl_safefree(glob); } -CURLcode glob_next_url(char **globbed, URLGlob *glob) +CURLcode glob_next_url(char **globbed, struct URLGlob *glob) { - URLPattern *pat; + struct URLPattern *pat; size_t i; size_t len; size_t buflen = glob->urllen + 1; @@ -600,7 +607,7 @@ CURLcode glob_next_url(char **globbed, URLGlob *glob) return CURLE_OK; } -CURLcode glob_match_url(char **result, char *filename, URLGlob *glob) +CURLcode glob_match_url(char **result, char *filename, struct URLGlob *glob) { char *target; size_t allocsize; @@ -625,7 +632,7 @@ CURLcode glob_match_url(char **result, char *filename, URLGlob *glob) if(*filename == '#' && ISDIGIT(filename[1])) { char *ptr = filename; unsigned long num = strtoul(&filename[1], &filename, 10); - URLPattern *pat = NULL; + struct URLPattern *pat = NULL; if(num && (num < glob->size)) { unsigned long i; diff --git a/src/tool_urlglob.h b/src/tool_urlglob.h index 82326c0a0..5ed76671e 100644 --- a/src/tool_urlglob.h +++ b/src/tool_urlglob.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 @@ -29,7 +29,7 @@ typedef enum { UPTNumRange } URLPatternType; -typedef struct { +struct URLPattern { URLPatternType type; int globindex; /* the number of this particular glob or -1 if not used within {} or [] */ @@ -53,24 +53,24 @@ typedef struct { unsigned long step; } NumRange; } content; -} URLPattern; +}; /* the total number of globs supported */ #define GLOB_PATTERN_NUM 100 -typedef struct { - URLPattern pattern[GLOB_PATTERN_NUM]; +struct URLGlob { + struct URLPattern pattern[GLOB_PATTERN_NUM]; size_t size; size_t urllen; char *glob_buffer; char beenhere; const char *error; /* error message */ size_t pos; /* column position of error or 0 */ -} URLGlob; +}; -CURLcode glob_url(URLGlob**, char *, unsigned long *, FILE *); -CURLcode glob_next_url(char **, URLGlob *); -CURLcode glob_match_url(char **, char *, URLGlob *); -void glob_cleanup(URLGlob* glob); +CURLcode glob_url(struct URLGlob**, char *, unsigned long *, FILE *); +CURLcode glob_next_url(char **, struct URLGlob *); +CURLcode glob_match_url(char **, char *, struct URLGlob *); +void glob_cleanup(struct URLGlob *glob); #endif /* HEADER_CURL_TOOL_URLGLOB_H */ diff --git a/src/tool_vms.c b/src/tool_vms.c index 7fa0dd62b..7871b20f3 100644 --- a/src/tool_vms.c +++ b/src/tool_vms.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 @@ -122,13 +122,13 @@ void vms_special_exit(int code, int vms_show) */ /* Structure to hold a DECC$* feature name and its desired value. */ -typedef struct { +struct decc_feat_t { char *name; int value; -} decc_feat_t; +}; /* Array of DECC$* feature names and their desired values. */ -static decc_feat_t decc_feat_array[] = { +static 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 file names on ODS5 disks. */ diff --git a/src/tool_writeout.c b/src/tool_writeout.c index 32c95b45f..d8ccbcbda 100644 --- a/src/tool_writeout.c +++ b/src/tool_writeout.c @@ -131,7 +131,7 @@ void ourWriteOut(CURL *curl, struct OutStruct *outs, const char *writeinfo) continue; } keepit = *end; - *end = 0; /* zero terminate */ + *end = 0; /* null-terminate */ for(i = 0; variables[i].name; i++) { if(curl_strequal(ptr, variables[i].name)) { match = TRUE; |