From 40b1724f58311a472b195dedd269deb1fd84405e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 6 Nov 2025 16:34:23 +0100 Subject: [PATCH] tool: consider (some) curl_easy_setopt errors fatal Instead of happily ignoring return codes. Calls that allocate data, like duplicating strings, can fail because of lack of memory which could then leave the option unset and curl would unknowingly continue (if the memory shortage was momentary). Closes #19385 --- src/config2setopts.c | 361 +++++++++++++++++++------------------------ src/tool_findfile.c | 3 +- src/tool_setopt.c | 92 +++++++---- src/tool_setopt.h | 82 +++++----- src/tool_ssls.c | 5 +- 5 files changed, 261 insertions(+), 282 deletions(-) diff --git a/src/config2setopts.c b/src/config2setopts.c index c367959ccb..929123cfbf 100644 --- a/src/config2setopts.c +++ b/src/config2setopts.c @@ -175,32 +175,26 @@ static CURLcode ssh_setopts(struct OperationConfig *config, CURL *curl) CURLcode result; /* SSH and SSL private key uses same command-line option */ - /* new in libcurl 7.16.1 */ - my_setopt_str(curl, CURLOPT_SSH_PRIVATE_KEYFILE, config->key); - /* new in libcurl 7.16.1 */ - my_setopt_str(curl, CURLOPT_SSH_PUBLIC_KEYFILE, config->pubkey); - - /* new in libcurl 7.17.1: SSH host key md5 checking allows us - to fail if we are not talking to who we think we should */ - my_setopt_str(curl, CURLOPT_SSH_HOST_PUBLIC_KEY_MD5, - config->hostpubmd5); - - /* new in libcurl 7.80.0: SSH host key sha256 checking allows us - to fail if we are not talking to who we think we should */ - my_setopt_str(curl, CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256, + MY_SETOPT_STR(curl, CURLOPT_SSH_PRIVATE_KEYFILE, config->key); + MY_SETOPT_STR(curl, CURLOPT_SSH_PUBLIC_KEYFILE, config->pubkey); + + /* SSH host key md5 checking allows us to fail if we are not talking to who + we think we should */ + MY_SETOPT_STR(curl, CURLOPT_SSH_HOST_PUBLIC_KEY_MD5, config->hostpubmd5); + + /* SSH host key sha256 checking allows us to fail if we are not talking to + who we think we should */ + MY_SETOPT_STR(curl, CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256, config->hostpubsha256); - /* new in libcurl 7.56.0 */ if(config->ssh_compression) my_setopt_long(curl, CURLOPT_SSH_COMPRESSION, 1); if(!config->insecure_ok) { char *known = config->knownhosts; - if(!known) known = findfile(".ssh/known_hosts", FALSE); if(known) { - /* new in curl 7.19.6 */ result = my_setopt_str(curl, CURLOPT_SSH_KNOWNHOSTS, known); if(result) { config->knownhosts = NULL; @@ -280,32 +274,26 @@ static CURLcode ssl_setopts(struct OperationConfig *config, CURL *curl) CURLcode result = CURLE_OK; if(config->cacert) - my_setopt_str(curl, CURLOPT_CAINFO, config->cacert); + MY_SETOPT_STR(curl, CURLOPT_CAINFO, config->cacert); if(config->proxy_cacert) - my_setopt_str(curl, CURLOPT_PROXY_CAINFO, config->proxy_cacert); + MY_SETOPT_STR(curl, CURLOPT_PROXY_CAINFO, config->proxy_cacert); + if(config->capath) + MY_SETOPT_STR(curl, CURLOPT_CAPATH, config->capath); - if(config->capath) { - result = my_setopt_str(curl, CURLOPT_CAPATH, config->capath); - if(result) - return result; - } /* For the time being if --proxy-capath is not set then we use the --capath value for it, if any. See #1257 */ if(config->proxy_capath || config->capath) { - result = my_setopt_str(curl, CURLOPT_PROXY_CAPATH, - (config->proxy_capath ? config->proxy_capath : - config->capath)); - if((result == CURLE_NOT_BUILT_IN) || - (result == CURLE_UNKNOWN_OPTION)) { - if(config->proxy_capath) { - warnf("ignoring %s, not supported by libcurl with %s", - config->proxy_capath ? "--proxy-capath" : "--capath", - ssl_backend()); - } + MY_SETOPT_STR(curl, CURLOPT_PROXY_CAPATH, + (config->proxy_capath ? config->proxy_capath : + config->capath)); + if(result && config->proxy_capath) { + warnf("ignoring %s, not supported by libcurl with %s", + config->proxy_capath ? "--proxy-capath" : "--capath", + ssl_backend()); } - else if(result) - return result; } + if(result) + return result; #ifdef CURL_CA_EMBED if(!config->cacert && !config->capath) { @@ -335,47 +323,46 @@ static CURLcode ssl_setopts(struct OperationConfig *config, CURL *curl) #endif if(config->crlfile) - my_setopt_str(curl, CURLOPT_CRLFILE, config->crlfile); + MY_SETOPT_STR(curl, CURLOPT_CRLFILE, config->crlfile); if(config->proxy_crlfile) - my_setopt_str(curl, CURLOPT_PROXY_CRLFILE, config->proxy_crlfile); - else if(config->crlfile) /* CURLOPT_PROXY_CRLFILE default is crlfile */ - my_setopt_str(curl, CURLOPT_PROXY_CRLFILE, config->crlfile); + MY_SETOPT_STR(curl, CURLOPT_PROXY_CRLFILE, config->proxy_crlfile); + else if(config->crlfile) + /* CURLOPT_PROXY_CRLFILE default is crlfile */ + MY_SETOPT_STR(curl, CURLOPT_PROXY_CRLFILE, config->crlfile); if(config->pinnedpubkey) { - result = my_setopt_str(curl, CURLOPT_PINNEDPUBLICKEY, - config->pinnedpubkey); - if(result == CURLE_NOT_BUILT_IN) + MY_SETOPT_STR(curl, CURLOPT_PINNEDPUBLICKEY, + config->pinnedpubkey); + if(result) warnf("ignoring %s, not supported by libcurl with %s", "--pinnedpubkey", ssl_backend()); } if(config->proxy_pinnedpubkey) { - result = my_setopt_str(curl, CURLOPT_PROXY_PINNEDPUBLICKEY, - config->proxy_pinnedpubkey); - if(result == CURLE_NOT_BUILT_IN) + MY_SETOPT_STR(curl, CURLOPT_PROXY_PINNEDPUBLICKEY, + config->proxy_pinnedpubkey); + if(result) warnf("ignoring %s, not supported by libcurl with %s", "--proxy-pinnedpubkey", ssl_backend()); } if(config->ssl_ec_curves) - my_setopt_str(curl, CURLOPT_SSL_EC_CURVES, config->ssl_ec_curves); + MY_SETOPT_STR(curl, CURLOPT_SSL_EC_CURVES, config->ssl_ec_curves); if(config->ssl_signature_algorithms) - my_setopt_str(curl, CURLOPT_SSL_SIGNATURE_ALGORITHMS, + MY_SETOPT_STR(curl, CURLOPT_SSL_SIGNATURE_ALGORITHMS, config->ssl_signature_algorithms); if(config->writeout) my_setopt_long(curl, CURLOPT_CERTINFO, 1); - 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); - 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); - my_setopt_str(curl, CURLOPT_PROXY_SSLKEYTYPE, - config->proxy_key_type); + 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); + 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); + MY_SETOPT_STR(curl, CURLOPT_PROXY_SSLKEYTYPE, config->proxy_key_type); /* libcurl default is strict verifyhost -> 1L, verifypeer -> 1L */ if(config->insecure_ok) { @@ -431,30 +418,28 @@ static CURLcode ssl_setopts(struct OperationConfig *config, CURL *curl) } if(config->cipher_list) { - result = my_setopt_str(curl, CURLOPT_SSL_CIPHER_LIST, - config->cipher_list); - if(result == CURLE_NOT_BUILT_IN) + MY_SETOPT_STR(curl, CURLOPT_SSL_CIPHER_LIST, config->cipher_list); + if(result) warnf("ignoring %s, not supported by libcurl with %s", "--ciphers", ssl_backend()); } if(config->proxy_cipher_list) { - result = my_setopt_str(curl, CURLOPT_PROXY_SSL_CIPHER_LIST, - config->proxy_cipher_list); - if(result == CURLE_NOT_BUILT_IN) + MY_SETOPT_STR(curl, CURLOPT_PROXY_SSL_CIPHER_LIST, + config->proxy_cipher_list); + if(result) warnf("ignoring %s, not supported by libcurl with %s", "--proxy-ciphers", ssl_backend()); } if(config->cipher13_list) { - result = my_setopt_str(curl, CURLOPT_TLS13_CIPHERS, - config->cipher13_list); - if(result == CURLE_NOT_BUILT_IN) + MY_SETOPT_STR(curl, CURLOPT_TLS13_CIPHERS, config->cipher13_list); + if(result) warnf("ignoring %s, not supported by libcurl with %s", "--tls13-ciphers", ssl_backend()); } if(config->proxy_cipher13_list) { - result = my_setopt_str(curl, CURLOPT_PROXY_TLS13_CIPHERS, - config->proxy_cipher13_list); - if(result == CURLE_NOT_BUILT_IN) + MY_SETOPT_STR(curl, CURLOPT_PROXY_TLS13_CIPHERS, + config->proxy_cipher13_list); + if(result) warnf("ignoring %s, not supported by libcurl with %s", "--proxy-tls13-ciphers", ssl_backend()); } @@ -467,29 +452,22 @@ static CURLcode ssl_setopts(struct OperationConfig *config, CURL *curl) if(feature_ech) { /* only if enabled in libcurl */ if(config->ech) /* only if set (optional) */ - my_setopt_str(curl, CURLOPT_ECH, config->ech); + 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); + 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); + MY_SETOPT_STR(curl, CURLOPT_ECH, config->ech_config); } - /* new in curl 7.9.3 */ - if(config->engine) { - result = my_setopt_str(curl, CURLOPT_SSLENGINE, config->engine); - if(result) - return result; - } + if(config->engine) + MY_SETOPT_STR(curl, CURLOPT_SSLENGINE, config->engine); - /* new in curl 7.15.5 */ if(config->ftp_ssl_reqd) my_setopt_enum(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL); - /* new in curl 7.11.0 */ else if(config->ftp_ssl) my_setopt_enum(curl, CURLOPT_USE_SSL, CURLUSESSL_TRY); - /* new in curl 7.16.0 */ else if(config->ftp_ssl_control) my_setopt_enum(curl, CURLOPT_USE_SSL, CURLUSESSL_CONTROL); @@ -503,28 +481,25 @@ static CURLcode ssl_setopts(struct OperationConfig *config, CURL *curl) static CURLcode http_setopts(struct OperationConfig *config, CURL *curl) { + CURLcode result; long postRedir = 0; my_setopt_long(curl, CURLOPT_FOLLOWLOCATION, config->followlocation); my_setopt_long(curl, CURLOPT_UNRESTRICTED_AUTH, config->unrestricted_auth); - my_setopt_str(curl, CURLOPT_AWS_SIGV4, config->aws_sigv4); + MY_SETOPT_STR(curl, CURLOPT_AWS_SIGV4, config->aws_sigv4); my_setopt_long(curl, CURLOPT_AUTOREFERER, config->autoreferer); - /* new in libcurl 7.36.0 */ if(config->proxyheaders) { my_setopt_slist(curl, CURLOPT_PROXYHEADER, config->proxyheaders); my_setopt_long(curl, CURLOPT_HEADEROPT, CURLHEADER_SEPARATE); } - /* new in libcurl 7.5 */ my_setopt_long(curl, CURLOPT_MAXREDIRS, config->maxredirs); if(config->httpversion) my_setopt_enum(curl, CURLOPT_HTTP_VERSION, config->httpversion); - /* curl 7.19.1 (the 301 version existed in 7.18.2), - 303 was added in 7.26.0 */ if(config->post301) postRedir |= CURL_REDIR_POST_301; if(config->post302) @@ -533,28 +508,25 @@ static CURLcode http_setopts(struct OperationConfig *config, postRedir |= CURL_REDIR_POST_303; my_setopt_long(curl, CURLOPT_POSTREDIR, postRedir); - /* new in libcurl 7.21.6 */ if(config->encoding) - my_setopt_str(curl, CURLOPT_ACCEPT_ENCODING, ""); + MY_SETOPT_STR(curl, CURLOPT_ACCEPT_ENCODING, ""); - /* new in libcurl 7.21.6 */ if(config->tr_encoding) my_setopt_long(curl, CURLOPT_TRANSFER_ENCODING, 1); - /* new in libcurl 7.64.0 */ + my_setopt_long(curl, CURLOPT_HTTP09_ALLOWED, config->http09_allowed); if(config->altsvc) - my_setopt_str(curl, CURLOPT_ALTSVC, config->altsvc); + MY_SETOPT_STR(curl, CURLOPT_ALTSVC, config->altsvc); if(config->hsts) - my_setopt_str(curl, CURLOPT_HSTS, config->hsts); + MY_SETOPT_STR(curl, CURLOPT_HSTS, config->hsts); - /* new in 7.47.0 */ if(config->expect100timeout_ms > 0) my_setopt_long(curl, CURLOPT_EXPECT_100_TIMEOUT_MS, config->expect100timeout_ms); - return CURLE_OK; + return result; } static CURLcode cookie_setopts(struct OperationConfig *config, CURL *curl) @@ -580,29 +552,28 @@ static CURLcode cookie_setopts(struct OperationConfig *config, CURL *curl) } } - my_setopt_str(curl, CURLOPT_COOKIE, curlx_dyn_ptr(&cookies)); + result = my_setopt_str(curl, CURLOPT_COOKIE, curlx_dyn_ptr(&cookies)); curlx_dyn_free(&cookies); + if(result) + return result; } if(config->cookiefiles) { struct curl_slist *cfl; for(cfl = config->cookiefiles; cfl; cfl = cfl->next) - my_setopt_str(curl, CURLOPT_COOKIEFILE, cfl->data); + MY_SETOPT_STR(curl, CURLOPT_COOKIEFILE, cfl->data); } - /* new in libcurl 7.9 */ if(config->cookiejar) - my_setopt_str(curl, CURLOPT_COOKIEJAR, config->cookiejar); + MY_SETOPT_STR(curl, CURLOPT_COOKIEJAR, config->cookiejar); - /* new in libcurl 7.9.7 */ my_setopt_long(curl, CURLOPT_COOKIESESSION, config->cookiesession); return result; } -static CURLcode tcp_setopts(struct OperationConfig *config, - CURL *curl) +static void tcp_setopts(struct OperationConfig *config, CURL *curl) { if(!config->tcp_nodelay) my_setopt_long(curl, CURLOPT_TCP_NODELAY, 0); @@ -611,7 +582,8 @@ static CURLcode tcp_setopts(struct OperationConfig *config, my_setopt_long(curl, CURLOPT_TCP_FASTOPEN, 1); if(config->mptcp) - my_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, tool_socket_open_mptcp_cb); + my_setopt_ptr(curl, CURLOPT_OPENSOCKETFUNCTION, + tool_socket_open_mptcp_cb); /* curl 7.17.1 */ if(!config->nokeepalive) { @@ -625,51 +597,41 @@ static CURLcode tcp_setopts(struct OperationConfig *config, } else my_setopt_long(curl, CURLOPT_TCP_KEEPALIVE, 0); - return CURLE_OK; } static CURLcode ftp_setopts(struct OperationConfig *config, CURL *curl) { - my_setopt_str(curl, CURLOPT_FTPPORT, config->ftpport); + CURLcode result; + MY_SETOPT_STR(curl, CURLOPT_FTPPORT, config->ftpport); - /* new in libcurl 7.9.2: */ if(config->disable_epsv) /* disable it */ my_setopt_long(curl, CURLOPT_FTP_USE_EPSV, 0); - /* new in libcurl 7.10.5 */ if(config->disable_eprt) /* disable it */ my_setopt_long(curl, CURLOPT_FTP_USE_EPRT, 0); - /* new in curl 7.16.1 */ if(config->ftp_ssl_ccc) my_setopt_enum(curl, CURLOPT_FTP_SSL_CCC, config->ftp_ssl_ccc_mode); - my_setopt_str(curl, CURLOPT_FTP_ACCOUNT, config->ftp_account); - - /* curl 7.14.2 */ + MY_SETOPT_STR(curl, CURLOPT_FTP_ACCOUNT, config->ftp_account); my_setopt_long(curl, CURLOPT_FTP_SKIP_PASV_IP, config->ftp_skip_ip); - - /* curl 7.15.1 */ my_setopt_long(curl, CURLOPT_FTP_FILEMETHOD, config->ftp_filemethod); - - /* curl 7.15.5 */ - my_setopt_str(curl, CURLOPT_FTP_ALTERNATIVE_TO_USER, + MY_SETOPT_STR(curl, CURLOPT_FTP_ALTERNATIVE_TO_USER, config->ftp_alternative_to_user); - /* curl 7.20.x */ if(config->ftp_pret) my_setopt_long(curl, CURLOPT_FTP_USE_PRET, 1); - return CURLE_OK; + return result; } static void gen_trace_setopts(struct OperationConfig *config, CURL *curl) { if(global->tracetype != TRACE_NONE) { - my_setopt(curl, CURLOPT_DEBUGFUNCTION, tool_debug_cb); - my_setopt(curl, CURLOPT_DEBUGDATA, config); + my_setopt_ptr(curl, CURLOPT_DEBUGFUNCTION, tool_debug_cb); + my_setopt_ptr(curl, CURLOPT_DEBUGDATA, config); my_setopt_long(curl, CURLOPT_VERBOSE, 1L); } } @@ -681,45 +643,45 @@ static void gen_cb_setopts(struct OperationConfig *config, (void)config; /* when --libcurl is disabled */ /* where to store */ - my_setopt(curl, CURLOPT_WRITEDATA, per); - my_setopt(curl, CURLOPT_INTERLEAVEDATA, per); + my_setopt_ptr(curl, CURLOPT_WRITEDATA, per); + my_setopt_ptr(curl, CURLOPT_INTERLEAVEDATA, per); /* what call to write */ - my_setopt(curl, CURLOPT_WRITEFUNCTION, tool_write_cb); + my_setopt_ptr(curl, CURLOPT_WRITEFUNCTION, tool_write_cb); /* what to read */ - my_setopt(curl, CURLOPT_READDATA, per); - my_setopt(curl, CURLOPT_READFUNCTION, tool_read_cb); + my_setopt_ptr(curl, CURLOPT_READDATA, per); + my_setopt_ptr(curl, CURLOPT_READFUNCTION, tool_read_cb); /* in 7.18.0, the CURLOPT_SEEKFUNCTION/DATA pair is taking over what CURLOPT_IOCTLFUNCTION/DATA pair previously provided for seeking */ - my_setopt(curl, CURLOPT_SEEKDATA, per); - my_setopt(curl, CURLOPT_SEEKFUNCTION, tool_seek_cb); + my_setopt_ptr(curl, CURLOPT_SEEKDATA, per); + my_setopt_ptr(curl, CURLOPT_SEEKFUNCTION, tool_seek_cb); if((global->progressmode == CURL_PROGRESS_BAR) && !global->noprogress && !global->silent) { /* we want the alternative style, then we have to implement it ourselves! */ - my_setopt(curl, CURLOPT_XFERINFOFUNCTION, tool_progress_cb); - my_setopt(curl, CURLOPT_XFERINFODATA, per); + my_setopt_ptr(curl, CURLOPT_XFERINFOFUNCTION, tool_progress_cb); + my_setopt_ptr(curl, CURLOPT_XFERINFODATA, per); } else if(per->uploadfile && !strcmp(per->uploadfile, ".")) { /* when reading from stdin in non-blocking mode, we use the progress function to unpause a busy read */ my_setopt_long(curl, CURLOPT_NOPROGRESS, 0); - my_setopt(curl, CURLOPT_XFERINFOFUNCTION, tool_readbusy_cb); - my_setopt(curl, CURLOPT_XFERINFODATA, per); + my_setopt_ptr(curl, CURLOPT_XFERINFOFUNCTION, tool_readbusy_cb); + my_setopt_ptr(curl, CURLOPT_XFERINFODATA, per); } - my_setopt(curl, CURLOPT_HEADERFUNCTION, tool_header_cb); - my_setopt(curl, CURLOPT_HEADERDATA, per); + my_setopt_ptr(curl, CURLOPT_HEADERFUNCTION, tool_header_cb); + my_setopt_ptr(curl, CURLOPT_HEADERDATA, per); } static CURLcode proxy_setopts(struct OperationConfig *config, CURL *curl) { + CURLcode result; if(config->proxy) { - CURLcode result = my_setopt_str(curl, CURLOPT_PROXY, config->proxy); - + result = my_setopt_str(curl, CURLOPT_PROXY, config->proxy); if(result) { errorf("proxy support is disabled in this libcurl"); config->synthetic_error = TRUE; @@ -727,20 +689,14 @@ static CURLcode proxy_setopts(struct OperationConfig *config, CURL *curl) } } - /* new in libcurl 7.5 */ if(config->proxy) my_setopt_enum(curl, CURLOPT_PROXYTYPE, config->proxyver); - my_setopt_str(curl, CURLOPT_PROXYUSERPWD, config->proxyuserpwd); - - /* new in libcurl 7.3 */ + MY_SETOPT_STR(curl, CURLOPT_PROXYUSERPWD, config->proxyuserpwd); my_setopt_long(curl, CURLOPT_HTTPPROXYTUNNEL, config->proxytunnel); - - /* new in libcurl 7.52.0 */ if(config->preproxy) - my_setopt_str(curl, CURLOPT_PRE_PROXY, config->preproxy); + MY_SETOPT_STR(curl, CURLOPT_PRE_PROXY, config->preproxy); - /* new in libcurl 7.10.6 */ if(config->proxyanyauth) my_setopt_bitmask(curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY); else if(config->proxynegotiate) @@ -752,45 +708,42 @@ static CURLcode proxy_setopts(struct OperationConfig *config, CURL *curl) else if(config->proxybasic) my_setopt_bitmask(curl, CURLOPT_PROXYAUTH, CURLAUTH_BASIC); - /* new in libcurl 7.19.4 */ - my_setopt_str(curl, CURLOPT_NOPROXY, config->noproxy); - + MY_SETOPT_STR(curl, CURLOPT_NOPROXY, config->noproxy); my_setopt_long(curl, CURLOPT_SUPPRESS_CONNECT_HEADERS, config->suppress_connect_headers); - /* new in curl 7.43.0 */ if(config->proxy_service_name) - my_setopt_str(curl, CURLOPT_PROXY_SERVICE_NAME, + MY_SETOPT_STR(curl, CURLOPT_PROXY_SERVICE_NAME, config->proxy_service_name); - /* new in 7.60.0 */ if(config->haproxy_protocol) my_setopt_long(curl, CURLOPT_HAPROXYPROTOCOL, 1); - /* new in 8.2.0 */ if(config->haproxy_clientip) - my_setopt_str(curl, CURLOPT_HAPROXY_CLIENT_IP, config->haproxy_clientip); + MY_SETOPT_STR(curl, CURLOPT_HAPROXY_CLIENT_IP, config->haproxy_clientip); - return CURLE_OK; + return result; } -static void tls_srp_setopts(struct OperationConfig *config, CURL *curl) +static CURLcode tls_srp_setopts(struct OperationConfig *config, CURL *curl) { + CURLcode result = CURLE_OK; if(config->tls_username) - my_setopt_str(curl, CURLOPT_TLSAUTH_USERNAME, config->tls_username); + MY_SETOPT_STR(curl, CURLOPT_TLSAUTH_USERNAME, config->tls_username); if(config->tls_password) - my_setopt_str(curl, CURLOPT_TLSAUTH_PASSWORD, config->tls_password); + MY_SETOPT_STR(curl, CURLOPT_TLSAUTH_PASSWORD, config->tls_password); if(config->tls_authtype) - my_setopt_str(curl, CURLOPT_TLSAUTH_TYPE, config->tls_authtype); + MY_SETOPT_STR(curl, CURLOPT_TLSAUTH_TYPE, config->tls_authtype); if(config->proxy_tls_username) - my_setopt_str(curl, CURLOPT_PROXY_TLSAUTH_USERNAME, + MY_SETOPT_STR(curl, CURLOPT_PROXY_TLSAUTH_USERNAME, config->proxy_tls_username); if(config->proxy_tls_password) - my_setopt_str(curl, CURLOPT_PROXY_TLSAUTH_PASSWORD, + MY_SETOPT_STR(curl, CURLOPT_PROXY_TLSAUTH_PASSWORD, config->proxy_tls_password); if(config->proxy_tls_authtype) - my_setopt_str(curl, CURLOPT_PROXY_TLSAUTH_TYPE, + MY_SETOPT_STR(curl, CURLOPT_PROXY_TLSAUTH_TYPE, config->proxy_tls_authtype); + return result; } CURLcode config2setopts(struct OperationConfig *config, @@ -838,21 +791,20 @@ CURLcode config2setopts(struct OperationConfig *config, my_setopt_long(curl, CURLOPT_BUFFERSIZE, BUFFER_SIZE); } - my_setopt_str(curl, CURLOPT_URL, per->url); + MY_SETOPT_STR(curl, CURLOPT_URL, per->url); my_setopt_long(curl, CURLOPT_NOPROGRESS, global->noprogress || global->silent); /* call after the line above. It may override CURLOPT_NOPROGRESS */ gen_cb_setopts(config, per, curl); my_setopt_long(curl, CURLOPT_NOBODY, config->no_body); - my_setopt_str(curl, CURLOPT_XOAUTH2_BEARER, config->oauth_bearer); - + MY_SETOPT_STR(curl, CURLOPT_XOAUTH2_BEARER, config->oauth_bearer); result = proxy_setopts(config, curl); - if(result) + if(setopt_bad(result) || config->synthetic_error) return result; my_setopt_long(curl, CURLOPT_FAILONERROR, config->fail == FAIL_WO_BODY); - my_setopt_str(curl, CURLOPT_REQUEST_TARGET, config->request_target); + MY_SETOPT_STR(curl, CURLOPT_REQUEST_TARGET, config->request_target); my_setopt_long(curl, CURLOPT_UPLOAD, !!per->uploadfile); my_setopt_long(curl, CURLOPT_DIRLISTONLY, config->dirlistonly); my_setopt_long(curl, CURLOPT_APPEND, config->ftp_append); @@ -864,12 +816,12 @@ CURLcode config2setopts(struct OperationConfig *config, else my_setopt_enum(curl, CURLOPT_NETRC, CURL_NETRC_IGNORED); - my_setopt_str(curl, CURLOPT_NETRC_FILE, config->netrc_file); + MY_SETOPT_STR(curl, CURLOPT_NETRC_FILE, config->netrc_file); my_setopt_long(curl, CURLOPT_TRANSFERTEXT, config->use_ascii); - my_setopt_str(curl, CURLOPT_LOGIN_OPTIONS, config->login_options); - my_setopt_str(curl, CURLOPT_USERPWD, config->userpwd); - my_setopt_str(curl, CURLOPT_RANGE, config->range); - my_setopt(curl, CURLOPT_ERRORBUFFER, per->errorbuffer); + MY_SETOPT_STR(curl, CURLOPT_LOGIN_OPTIONS, config->login_options); + MY_SETOPT_STR(curl, CURLOPT_USERPWD, config->userpwd); + MY_SETOPT_STR(curl, CURLOPT_RANGE, config->range); + my_setopt_ptr(curl, CURLOPT_ERRORBUFFER, per->errorbuffer); my_setopt_long(curl, CURLOPT_TIMEOUT_MS, config->timeout_ms); switch(config->httpreq) { @@ -879,7 +831,7 @@ CURLcode config2setopts(struct OperationConfig *config, result = CURLE_FAILED_INIT; } else { - my_setopt_str(curl, CURLOPT_POSTFIELDS, + MY_SETOPT_STR(curl, CURLOPT_POSTFIELDS, curlx_dyn_ptr(&config->postdata)); my_setopt_offt(curl, CURLOPT_POSTFIELDSIZE_LARGE, curlx_dyn_len(&config->postdata)); @@ -914,8 +866,8 @@ CURLcode config2setopts(struct OperationConfig *config, my_setopt_slist(curl, CURLOPT_HTTPHEADER, config->headers); if(proto_http || proto_rtsp) { - my_setopt_str(curl, CURLOPT_REFERER, config->referer); - my_setopt_str(curl, CURLOPT_USERAGENT, config->useragent); + MY_SETOPT_STR(curl, CURLOPT_REFERER, config->referer); + MY_SETOPT_STR(curl, CURLOPT_USERAGENT, config->useragent); } if(use_proto == proto_http || use_proto == proto_https) { @@ -942,28 +894,26 @@ CURLcode config2setopts(struct OperationConfig *config, else my_setopt_offt(curl, CURLOPT_RESUME_FROM_LARGE, 0); - my_setopt_str(curl, CURLOPT_KEYPASSWD, config->key_passwd); - my_setopt_str(curl, CURLOPT_PROXY_KEYPASSWD, config->proxy_key_passwd); + MY_SETOPT_STR(curl, CURLOPT_KEYPASSWD, config->key_passwd); + MY_SETOPT_STR(curl, CURLOPT_PROXY_KEYPASSWD, config->proxy_key_passwd); if(use_proto == proto_scp || use_proto == proto_sftp) { result = ssh_setopts(config, curl); - if(result) + if(setopt_bad(result)) return result; } - if(feature_ssl) { result = ssl_setopts(config, curl); - if(result) + if(setopt_bad(result)) return result; } if(config->path_as_is) my_setopt_long(curl, CURLOPT_PATH_AS_IS, 1); - if(config->no_body || config->remote_time) { + if(config->no_body || config->remote_time) /* no body or use remote time */ my_setopt_long(curl, CURLOPT_FILETIME, 1); - } my_setopt_long(curl, CURLOPT_CRLF, config->crlf); my_setopt_slist(curl, CURLOPT_QUOTE, config->quote); @@ -972,18 +922,18 @@ CURLcode config2setopts(struct OperationConfig *config, my_setopt_enum(curl, CURLOPT_TIMECONDITION, config->timecond); my_setopt_offt(curl, CURLOPT_TIMEVALUE_LARGE, config->condtime); - my_setopt_str(curl, CURLOPT_CUSTOMREQUEST, config->customrequest); + MY_SETOPT_STR(curl, CURLOPT_CUSTOMREQUEST, config->customrequest); customrequest_helper(config->httpreq, config->customrequest); - my_setopt(curl, CURLOPT_STDERR, tool_stderr); - my_setopt_str(curl, CURLOPT_INTERFACE, config->iface); + my_setopt_ptr(curl, CURLOPT_STDERR, tool_stderr); + MY_SETOPT_STR(curl, CURLOPT_INTERFACE, config->iface); progressbarinit(&per->progressbar, config); - my_setopt_str(curl, CURLOPT_DNS_SERVERS, config->dns_servers); - my_setopt_str(curl, CURLOPT_DNS_INTERFACE, config->dns_interface); - my_setopt_str(curl, CURLOPT_DNS_LOCAL_IP4, config->dns_ipv4_addr); - my_setopt_str(curl, CURLOPT_DNS_LOCAL_IP6, config->dns_ipv6_addr); + MY_SETOPT_STR(curl, CURLOPT_DNS_SERVERS, config->dns_servers); + MY_SETOPT_STR(curl, CURLOPT_DNS_INTERFACE, config->dns_interface); + MY_SETOPT_STR(curl, CURLOPT_DNS_LOCAL_IP4, config->dns_ipv4_addr); + MY_SETOPT_STR(curl, CURLOPT_DNS_LOCAL_IP6, config->dns_ipv6_addr); my_setopt_slist(curl, CURLOPT_TELNETOPTIONS, config->telnet_options); my_setopt_long(curl, CURLOPT_CONNECTTIMEOUT_MS, config->connecttimeout_ms); - my_setopt_str(curl, CURLOPT_DOH_URL, config->doh_url); + MY_SETOPT_STR(curl, CURLOPT_DOH_URL, config->doh_url); my_setopt_long(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, (config->ftp_create_dirs ? CURLFTP_CREATE_DIR_RETRY : CURLFTP_CREATE_DIR_NONE)); @@ -994,7 +944,7 @@ CURLcode config2setopts(struct OperationConfig *config, my_setopt_long(curl, CURLOPT_SOCKS5_GSSAPI_NEC, 1); if(config->socks5_auth) my_setopt_bitmask(curl, CURLOPT_SOCKS5_AUTH, config->socks5_auth); - my_setopt_str(curl, CURLOPT_SERVICE_NAME, config->service_name); + MY_SETOPT_STR(curl, CURLOPT_SERVICE_NAME, config->service_name); my_setopt_long(curl, CURLOPT_IGNORE_CONTENT_LENGTH, config->ignorecl); if(config->localport) { @@ -1007,14 +957,12 @@ CURLcode config2setopts(struct OperationConfig *config, my_setopt_long(curl, CURLOPT_HTTP_TRANSFER_DECODING, 0); } - result = tcp_setopts(config, curl); - if(result) - return result; + tcp_setopts(config, curl); if(config->tftp_blksize && proto_tftp) my_setopt_long(curl, CURLOPT_TFTP_BLKSIZE, config->tftp_blksize); - my_setopt_str(curl, CURLOPT_MAIL_FROM, config->mail_from); + MY_SETOPT_STR(curl, CURLOPT_MAIL_FROM, config->mail_from); my_setopt_slist(curl, CURLOPT_MAIL_RCPT, config->mail_rcpt); my_setopt_long(curl, CURLOPT_MAIL_RCPT_ALLOWFAILS, config->mail_rcpt_allowfails); @@ -1022,35 +970,36 @@ CURLcode config2setopts(struct OperationConfig *config, my_setopt_long(curl, CURLOPT_NEW_FILE_PERMS, config->create_file_mode); if(config->proto_present) - my_setopt_str(curl, CURLOPT_PROTOCOLS_STR, config->proto_str); + MY_SETOPT_STR(curl, CURLOPT_PROTOCOLS_STR, config->proto_str); if(config->proto_redir_present) - my_setopt_str(curl, CURLOPT_REDIR_PROTOCOLS_STR, config->proto_redir_str); + MY_SETOPT_STR(curl, CURLOPT_REDIR_PROTOCOLS_STR, config->proto_redir_str); my_setopt_slist(curl, CURLOPT_RESOLVE, config->resolve); my_setopt_slist(curl, CURLOPT_CONNECT_TO, config->connect_to); - if(feature_tls_srp) - tls_srp_setopts(config, curl); + if(feature_tls_srp) { + result = tls_srp_setopts(config, curl); + if(setopt_bad(result)) + return result; + } if(config->gssapi_delegation) my_setopt_long(curl, CURLOPT_GSSAPI_DELEGATION, config->gssapi_delegation); - my_setopt_str(curl, CURLOPT_MAIL_AUTH, config->mail_auth); - my_setopt_str(curl, CURLOPT_SASL_AUTHZID, config->sasl_authzid); + MY_SETOPT_STR(curl, CURLOPT_MAIL_AUTH, config->mail_auth); + MY_SETOPT_STR(curl, CURLOPT_SASL_AUTHZID, config->sasl_authzid); my_setopt_long(curl, CURLOPT_SASL_IR, config->sasl_ir); if(config->unix_socket_path) { - if(config->abstract_unix_socket) { - my_setopt_str(curl, CURLOPT_ABSTRACT_UNIX_SOCKET, + if(config->abstract_unix_socket) + MY_SETOPT_STR(curl, CURLOPT_ABSTRACT_UNIX_SOCKET, config->unix_socket_path); - } - else { - my_setopt_str(curl, CURLOPT_UNIX_SOCKET_PATH, + else + MY_SETOPT_STR(curl, CURLOPT_UNIX_SOCKET_PATH, config->unix_socket_path); - } } - my_setopt_str(curl, CURLOPT_DEFAULT_PROTOCOL, config->proto_default); + MY_SETOPT_STR(curl, CURLOPT_DEFAULT_PROTOCOL, config->proto_default); my_setopt_long(curl, CURLOPT_TFTP_NO_OPTIONS, config->tftp_no_options && proto_tftp); @@ -1063,8 +1012,8 @@ CURLcode config2setopts(struct OperationConfig *config, 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); + my_setopt_ptr(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback); + my_setopt_ptr(curl, CURLOPT_SOCKOPTDATA, config); #else if(config->ip_tos > 0) { errorf("Type of service is not supported in this build."); diff --git a/src/tool_findfile.c b/src/tool_findfile.c index 02898a8fb1..6e9fbdfd60 100644 --- a/src/tool_findfile.c +++ b/src/tool_findfile.c @@ -87,7 +87,8 @@ static char *checkhome(const char *home, const char *fname, bool dotscore) } /* - * findfile() - return the full path name of the file. + * findfile() - returns the full path name of the file. It must be freed with + * curl_free(). * * If 'dotscore' is TRUE, then check for the file first with a leading dot * and then with a leading underscore. diff --git a/src/tool_setopt.c b/src/tool_setopt.c index c3e7213dc8..ccecd3a7e0 100644 --- a/src/tool_setopt.c +++ b/src/tool_setopt.c @@ -23,11 +23,12 @@ ***************************************************************************/ #include "tool_setup.h" -#ifndef CURL_DISABLE_LIBCURL_OPTION - #include "tool_cfgable.h" #include "tool_easysrc.h" #include "tool_setopt.h" + +#ifndef CURL_DISABLE_LIBCURL_OPTION + #include "tool_msgs.h" #include "memdebug.h" /* keep this as LAST include */ @@ -628,56 +629,79 @@ CURLcode tool_setopt_offt(CURL *curl, const char *name, CURLoption tag, return ret; } -/* setopt wrapper for setting object and function pointer options */ -CURLcode tool_setopt(CURL *curl, struct OperationConfig *config, - bool str, const char *name, CURLoption tag, - ...) +/* setopt wrapper for setting object and function pointers */ +CURLcode tool_setopt_ptr(CURL *curl, const char *name, CURLoption tag, ...) { - va_list arg; - CURLcode ret = CURLE_OK; void *pval; - - va_start(arg, tag); + va_list arg; + CURLcode result; DEBUGASSERT(tag >= CURLOPTTYPE_OBJECTPOINT); DEBUGASSERT((tag < CURLOPTTYPE_OFF_T) || (tag >= CURLOPTTYPE_BLOB)); - /* we never set _BLOB options in the curl tool */ DEBUGASSERT(tag < CURLOPTTYPE_BLOB); + va_start(arg, tag); /* argument is an object or function pointer */ pval = va_arg(arg, void *); - ret = curl_easy_setopt(curl, tag, pval); + result = curl_easy_setopt(curl, tag, pval); + if(global->libcurl && pval && !result) { + /* we only use this if --libcurl was used */ + const char *remark = (tag >= CURLOPTTYPE_FUNCTIONPOINT) ? + "function" : "object"; + result = easysrc_addf(&easysrc_toohard, + "%s was set to a%s %s pointer", name, + (*remark == 'o' ? "n" : ""), remark); + } va_end(arg); + return result; +} - if(global->libcurl && pval && !ret) { - /* we only use this if --libcurl was used */ +/* setopt wrapper for setting strings */ +CURLcode tool_setopt_str(CURL *curl, struct OperationConfig *config, + const char *name, CURLoption tag, ...) +{ + char *str; + va_list arg; + CURLcode result; + DEBUGASSERT(tag >= CURLOPTTYPE_OBJECTPOINT); + DEBUGASSERT((tag < CURLOPTTYPE_OFF_T) || (tag >= CURLOPTTYPE_BLOB)); + DEBUGASSERT(tag < CURLOPTTYPE_BLOB); + DEBUGASSERT(tag < CURLOPTTYPE_FUNCTIONPOINT); - if(!str) { - /* function pointers are never printable */ - const char *remark = (tag >= CURLOPTTYPE_FUNCTIONPOINT) ? - "function" : "object"; - ret = easysrc_addf(&easysrc_toohard, - "%s was set to a%s %s pointer", name, - (*remark == 'o' ? "n" : ""), remark); - } - else { - curl_off_t len = ZERO_TERMINATED; - char *escaped; - if(tag == CURLOPT_POSTFIELDS) - len = curlx_dyn_len(&config->postdata); - escaped = c_escape(pval, len); - if(escaped) { - ret = easysrc_addf(&easysrc_code, "curl_easy_setopt(hnd, %s, \"%s\");", - name, escaped); - free(escaped); - } + va_start(arg, tag); + /* argument is a string */ + str = va_arg(arg, char *); + + result = curl_easy_setopt(curl, tag, str); + if(global->libcurl && str && !result) { + /* we only use this if --libcurl was used */ + curl_off_t len = ZERO_TERMINATED; + char *escaped; + if(tag == CURLOPT_POSTFIELDS) + len = curlx_dyn_len(&config->postdata); + escaped = c_escape(str, len); + if(escaped) { + result = easysrc_addf(&easysrc_code, + "curl_easy_setopt(hnd, %s, \"%s\");", + name, escaped); + free(escaped); } + else + result = CURLE_OUT_OF_MEMORY; } - return ret; + va_end(arg); + return result; } #endif /* CURL_DISABLE_LIBCURL_OPTION */ + +/* return TRUE if the error code is "lethal" */ +bool setopt_bad(CURLcode result) +{ + return (result && (result != CURLE_NOT_BUILT_IN) && + (result != CURLE_UNKNOWN_OPTION)); +} diff --git a/src/tool_setopt.h b/src/tool_setopt.h index 4f28df980e..5ca7188841 100644 --- a/src/tool_setopt.h +++ b/src/tool_setopt.h @@ -31,6 +31,9 @@ * Macros used in operate() */ +/* return TRUE if the error code is "lethal" */ +bool setopt_bad(CURLcode result); + #ifndef CURL_DISABLE_LIBCURL_OPTION /* Associate symbolic names with option values */ @@ -95,67 +98,68 @@ CURLcode tool_setopt_long(CURL *curl, const char *name, CURLoption tag, long lval); CURLcode tool_setopt_offt(CURL *curl, const char *name, CURLoption tag, curl_off_t lval); -CURLcode tool_setopt(CURL *curl, struct OperationConfig *config, - bool str, const char *name, CURLoption tag, - ...); +CURLcode tool_setopt_str(CURL *curl, struct OperationConfig *config, + const char *name, CURLoption tag, + ...) WARN_UNUSED_RESULT; +CURLcode tool_setopt_ptr(CURL *curl, const char *name, CURLoption tag, ...); -#define my_setopt(x,y,z) \ - tool_setopt(x, config, FALSE, #y, y, z) +#define my_setopt_ptr(x,y,z) \ + tool_setopt_ptr(x, #y, y, z) -#define my_setopt_long(x,y,z) \ +#define my_setopt_long(x,y,z) \ tool_setopt_long(x, #y, y, z) -#define my_setopt_offt(x,y,z) \ +#define my_setopt_offt(x,y,z) \ tool_setopt_offt(x, #y, y, z) -#define my_setopt_str(x,y,z) \ - tool_setopt(x, config, TRUE, #y, y, z) +#define my_setopt_str(x,y,z) \ + tool_setopt_str(x, config, #y, y, z) + +/* assumes a 'result' variable to use. If the return code is benign it is left + in 'result' after this call, otherwise the function returns the error */ +#define MY_SETOPT_STR(x,y,z) \ + do { \ + result = tool_setopt_str(x, config, #y, y, z); \ + if(setopt_bad(result)) \ + return result; \ + } while(0) -#define my_setopt_enum(x,y,z) \ +#define my_setopt_enum(x,y,z) \ tool_setopt_enum(x, #y, y, setopt_nv_ ## y, z) -#define my_setopt_SSLVERSION(x,y,z) \ +#define my_setopt_SSLVERSION(x,y,z) \ tool_setopt_SSLVERSION(x, #y, y, z) -#define my_setopt_bitmask(x,y,z) \ +#define my_setopt_bitmask(x,y,z) \ tool_setopt_bitmask(x, #y, y, setopt_nv_ ## y, z) -#define my_setopt_mimepost(x,y,z) \ +#define my_setopt_mimepost(x,y,z) \ tool_setopt_mimepost(x, config, #y, y, z) -#define my_setopt_slist(x,y,z) \ +#define my_setopt_slist(x,y,z) \ tool_setopt_slist(x, #y, y, z) #else /* CURL_DISABLE_LIBCURL_OPTION */ /* No --libcurl, so pass options directly to library */ -#define my_setopt(x,y,z) \ - curl_easy_setopt(x, y, z) - -#define my_setopt_long(x,y,z) \ - curl_easy_setopt(x, y, (long)(z)) - -#define my_setopt_offt(x,y,z) \ - curl_easy_setopt(x, y, (curl_off_t)(z)) - -#define my_setopt_str(x,y,z) \ - curl_easy_setopt(x, y, z) - -#define my_setopt_enum(x,y,z) \ - curl_easy_setopt(x, y, z) - -#define my_setopt_SSLVERSION(x,y,z) \ - curl_easy_setopt(x, y, z) - -#define my_setopt_bitmask(x,y,z) \ - curl_easy_setopt(x, y, (long)z) - -#define my_setopt_mimepost(x,y,z) \ - curl_easy_setopt(x, y, z) +#define my_setopt_long(x,y,z) curl_easy_setopt(x, y, (long)(z)) +#define my_setopt_offt(x,y,z) curl_easy_setopt(x, y, (curl_off_t)(z)) +#define my_setopt_ptr(x,y,z) curl_easy_setopt(x, y, z) +#define my_setopt_str(x,y,z) curl_easy_setopt(x, y, z) +#define my_setopt_enum(x,y,z) curl_easy_setopt(x, y, z) +#define my_setopt_SSLVERSION(x,y,z) curl_easy_setopt(x, y, z) +#define my_setopt_bitmask(x,y,z) curl_easy_setopt(x, y, (long)z) +#define my_setopt_mimepost(x,y,z) curl_easy_setopt(x, y, z) +#define my_setopt_slist(x,y,z) curl_easy_setopt(x, y, z) + +#define MY_SETOPT_STR(x,y,z) \ + do { \ + result = curl_easy_setopt(x, y, z); \ + if(setopt_bad(result)) \ + return result; \ + } while(0) -#define my_setopt_slist(x,y,z) \ - curl_easy_setopt(x, y, z) #endif /* CURL_DISABLE_LIBCURL_OPTION */ diff --git a/src/tool_ssls.c b/src/tool_ssls.c index 6fb0180455..2b8cc10672 100644 --- a/src/tool_ssls.c +++ b/src/tool_ssls.c @@ -45,8 +45,9 @@ static CURLcode tool_ssls_easy(struct OperationConfig *config, result = curl_easy_setopt(*peasy, CURLOPT_SHARE, share); if(!result && (global->tracetype != TRACE_NONE)) { - my_setopt(*peasy, CURLOPT_DEBUGFUNCTION, tool_debug_cb); - my_setopt(*peasy, CURLOPT_DEBUGDATA, config); + result = my_setopt_ptr(*peasy, CURLOPT_DEBUGFUNCTION, tool_debug_cb); + if(!result) + result = my_setopt_ptr(*peasy, CURLOPT_DEBUGDATA, config); my_setopt_long(*peasy, CURLOPT_VERBOSE, 1L); } return result; -- 2.47.3