* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, 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
# include <fcntl.h>
#endif
-#ifdef HAVE_UTIME_H
-# include <utime.h>
-#elif defined(HAVE_SYS_UTIME_H)
-# include <sys/utime.h>
-#endif
-
#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif
-#ifdef HAVE_NETINET_TCP_H
-# include <netinet/tcp.h>
-#endif
-
#ifdef __VMS
# include <fabdef.h>
#endif
-#include "rawstr.h"
+#include "strcase.h"
#define ENABLE_CURLX_PRINTF
/* use our own printf() functions */
#include "tool_dirhie.h"
#include "tool_doswin.h"
#include "tool_easysrc.h"
+#include "tool_filetime.h"
#include "tool_getparam.h"
#include "tool_helpers.h"
#include "tool_homedir.h"
#include "tool_sleep.h"
#include "tool_urlglob.h"
#include "tool_util.h"
-#include "tool_writeenv.h"
#include "tool_writeout.h"
#include "tool_xattr.h"
#include "tool_vms.h"
# define O_BINARY 0
#endif
-#define CURL_CA_CERT_ERRORMSG1 \
- "More details here: https://curl.haxx.se/docs/sslcerts.html\n\n" \
- "curl performs SSL certificate verification by default, " \
- "using a \"bundle\"\n" \
- " of Certificate Authority (CA) public keys (CA certs). If the default\n" \
- " bundle file isn't adequate, you can specify an alternate file\n" \
- " using the --cacert option.\n"
-
-#define CURL_CA_CERT_ERRORMSG2 \
- "If this HTTPS server uses a certificate signed by a CA represented in\n" \
- " the bundle, the certificate verification probably failed due to a\n" \
- " problem with the certificate (it might be expired, or the name might\n" \
- " not match the domain name in the URL).\n" \
- "If you'd like to turn off curl's verification of the certificate, use\n" \
- " the -k (or --insecure) option.\n"
+#define CURL_CA_CERT_ERRORMSG \
+ "More details here: https://curl.haxx.se/docs/sslcerts.html\n\n" \
+ "curl failed to verify the legitimacy of the server and therefore " \
+ "could not\nestablish a secure connection to it. To learn more about " \
+ "this situation and\nhow to fix it, please visit the web page mentioned " \
+ "above.\n"
static bool is_fatal_error(CURLcode code)
{
* and CD/DVD images should be either a STREAM_LF format or a fixed format.
*
*/
-static curl_off_t vms_realfilesize(const char * name,
- const struct_stat * stat_buf)
+static curl_off_t vms_realfilesize(const char *name,
+ const struct_stat *stat_buf)
{
char buffer[8192];
curl_off_t count;
* if not to call a routine to get the correct size.
*
*/
-static curl_off_t VmsSpecialSize(const char * name,
- const struct_stat * stat_buf)
+static curl_off_t VmsSpecialSize(const char *name,
+ const struct_stat *stat_buf)
{
switch(stat_buf->st_fab_rfm) {
case FAB$C_VAR:
}
#endif /* __VMS */
+#define BUFFER_SIZE (100*1024)
+
static CURLcode operate_do(struct GlobalConfig *global,
struct OperationConfig *config)
{
/* Single header file for all URLs */
if(config->headerfile) {
/* open file for output: */
- if(!curlx_strequal(config->headerfile, "-")) {
+ if(strcmp(config->headerfile, "-")) {
FILE *newfile = fopen(config->headerfile, "wb");
if(!newfile) {
warnf(config->global, "Failed to open %s\n", config->headerfile);
urlnum = 1; /* without globbing, this is a single URL */
/* if multiple files extracted to stdout, insert separators! */
- separator= ((!outfiles || curlx_strequal(outfiles, "-")) && urlnum > 1);
+ separator = ((!outfiles || !strcmp(outfiles, "-")) && urlnum > 1);
/* Here's looping around each globbed URL */
for(li = 0 ; li < urlnum; li++) {
}
if(((urlnode->flags&GETOUT_USEREMOTE) ||
- (outfile && !curlx_strequal("-", outfile))) &&
+ (outfile && strcmp("-", outfile))) &&
(metalink || !config->use_metalink)) {
/*
* to be considered with one appended if implied CC
*/
#ifdef __VMS
- /* Calculate the real upload site for VMS */
+ /* Calculate the real upload size for VMS */
infd = -1;
if(stat(uploadfile, &fileinfo) == 0) {
fileinfo.st_size = VmsSpecialSize(uploadfile, &fileinfo);
- switch (fileinfo.st_fab_rfm) {
+ switch(fileinfo.st_fab_rfm) {
case FAB$C_VAR:
case FAB$C_VFC:
case FAB$C_STMCR:
DEBUGASSERT(infd == STDIN_FILENO);
set_binmode(stdin);
- if(curlx_strequal(uploadfile, ".")) {
+ if(!strcmp(uploadfile, ".")) {
if(curlx_nonblock((curl_socket_t)infd, TRUE) < 0)
warnf(config->global,
"fcntl failed on fd=%d: %s\n", infd, strerror(errno));
if(urlnum > 1 && !global->mute) {
fprintf(global->errors, "\n[%lu/%lu]: %s --> %s\n",
- li+1, urlnum, this_url, outfile ? outfile : "<stdout>");
+ li + 1, urlnum, this_url, outfile ? outfile : "<stdout>");
if(separator)
printf("%s%s\n", CURLseparator, this_url);
}
if(strchr(pc, '?'))
/* Ouch, there's already a question mark in the URL string, we
then append the data with an ampersand separator instead! */
- sep='&';
+ sep = '&';
}
/*
* Then append ? followed by the get fields to the url.
set_binmode(stdout);
}
+ /* explicitly passed to stdout means okaying binary gunk */
+ config->terminal_binary_ok = (outfile && !strcmp(outfile, "-"));
+
if(!config->tcp_nodelay)
my_setopt(curl, CURLOPT_TCP_NODELAY, 0L);
/* where to store */
my_setopt(curl, CURLOPT_WRITEDATA, &outs);
+ my_setopt(curl, CURLOPT_INTERLEAVEDATA, &outs);
if(metalink || !config->use_metalink)
/* what call to write */
my_setopt(curl, CURLOPT_WRITEFUNCTION, tool_write_cb);
my_setopt(curl, CURLOPT_SEEKDATA, &input);
my_setopt(curl, CURLOPT_SEEKFUNCTION, tool_seek_cb);
- if(config->recvpersecond)
- /* tell libcurl to use a smaller sized buffer as it allows us to
- make better sleeps! 7.9.9 stuff! */
+ if(config->recvpersecond &&
+ (config->recvpersecond < BUFFER_SIZE))
+ /* use a smaller sized buffer for better sleeps */
my_setopt(curl, CURLOPT_BUFFERSIZE, (long)config->recvpersecond);
+ else
+ my_setopt(curl, CURLOPT_BUFFERSIZE, (long)BUFFER_SIZE);
/* size of uploaded file: */
if(uploadfilesize != -1)
/* TODO: Make this a run-time check instead of compile-time one. */
my_setopt_str(curl, CURLOPT_PROXY, config->proxy);
+ /* 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(curl, CURLOPT_HTTPPROXYTUNNEL, config->proxytunnel?1L:0L);
- /* new in libcurl 7.5 */
- if(config->proxy)
- my_setopt_enum(curl, CURLOPT_PROXYTYPE, (long)config->proxyver);
-
- /* new in libcurl 7.10 */
- if(config->socksproxy) {
- my_setopt_str(curl, CURLOPT_PROXY, config->socksproxy);
- my_setopt_enum(curl, CURLOPT_PROXYTYPE, (long)config->socksver);
- }
+ /* new in libcurl 7.52.0 */
+ if(config->preproxy)
+ my_setopt_str(curl, CURLOPT_PRE_PROXY, config->preproxy);
/* new in libcurl 7.10.6 */
if(config->proxyanyauth)
/* new in libcurl 7.19.4 */
my_setopt_str(curl, CURLOPT_NOPROXY, config->noproxy);
+
+ my_setopt(curl, CURLOPT_SUPPRESS_CONNECT_HEADERS,
+ config->suppress_connect_headers?1L:0L);
}
-#endif
+#endif /* !CURL_DISABLE_PROXY */
my_setopt(curl, CURLOPT_FAILONERROR, config->failonerror?1L:0L);
+ my_setopt(curl, CURLOPT_REQUEST_TARGET, config->request_target);
my_setopt(curl, CURLOPT_UPLOAD, uploadfile?1L:0L);
my_setopt(curl, CURLOPT_DIRLISTONLY, config->dirlistonly?1L:0L);
my_setopt(curl, CURLOPT_APPEND, config->ftp_append?1L:0L);
my_setopt(curl, CURLOPT_ERRORBUFFER, errorbuffer);
my_setopt(curl, CURLOPT_TIMEOUT_MS, (long)(config->timeout * 1000));
+ switch(config->httpreq) {
+ case HTTPREQ_SIMPLEPOST:
+ my_setopt_str(curl, CURLOPT_POSTFIELDS,
+ config->postfields);
+ my_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE,
+ config->postfieldsize);
+ break;
+ case HTTPREQ_MIMEPOST:
+ my_setopt_mimepost(curl, CURLOPT_MIMEPOST, config->mimepost);
+ break;
+ default:
+ break;
+ }
+
+ /* new in libcurl 7.10.6 (default is Basic) */
+ if(config->authtype)
+ my_setopt_bitmask(curl, CURLOPT_HTTPAUTH, (long)config->authtype);
+
+ my_setopt_slist(curl, CURLOPT_HTTPHEADER, config->headers);
+
+ if(built_in_protos & (CURLPROTO_HTTP | CURLPROTO_RTSP)) {
+ my_setopt_str(curl, CURLOPT_REFERER, config->referer);
+ my_setopt_str(curl, CURLOPT_USERAGENT, config->useragent);
+ }
+
if(built_in_protos & CURLPROTO_HTTP) {
long postRedir = 0;
my_setopt(curl, CURLOPT_UNRESTRICTED_AUTH,
config->unrestricted_auth?1L:0L);
- switch(config->httpreq) {
- case HTTPREQ_SIMPLEPOST:
- my_setopt_str(curl, CURLOPT_POSTFIELDS,
- config->postfields);
- my_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE,
- config->postfieldsize);
- break;
- case HTTPREQ_FORMPOST:
- my_setopt_httppost(curl, CURLOPT_HTTPPOST, config->httppost);
- break;
- default:
- break;
- }
-
- my_setopt_str(curl, CURLOPT_REFERER, config->referer);
my_setopt(curl, CURLOPT_AUTOREFERER, config->autoreferer?1L:0L);
- my_setopt_str(curl, CURLOPT_USERAGENT, config->useragent);
- my_setopt_slist(curl, CURLOPT_HTTPHEADER, config->headers);
/* new in libcurl 7.36.0 */
if(config->proxyheaders) {
my_setopt_enum(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS);
}
- /* new in libcurl 7.10.6 (default is Basic) */
- if(config->authtype)
- my_setopt_bitmask(curl, CURLOPT_HTTPAUTH, (long)config->authtype);
-
/* curl 7.19.1 (the 301 version existed in 7.18.2),
303 was added in 7.26.0 */
if(config->post301)
my_setopt(curl, CURLOPT_RESUME_FROM_LARGE, CURL_OFF_T_C(0));
my_setopt_str(curl, CURLOPT_KEYPASSWD, config->key_passwd);
+ my_setopt_str(curl, CURLOPT_PROXY_KEYPASSWD, config->proxy_key_passwd);
if(built_in_protos & (CURLPROTO_SCP|CURLPROTO_SFTP)) {
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.56.0 */
+ if(config->ssh_compression)
+ my_setopt(curl, CURLOPT_SSH_COMPRESSION, 1L);
}
if(config->cacert)
my_setopt_str(curl, CURLOPT_CAINFO, config->cacert);
+ if(config->proxy_cacert)
+ my_setopt_str(curl, CURLOPT_PROXY_CAINFO, config->proxy_cacert);
+
if(config->capath) {
result = res_setopt_str(curl, CURLOPT_CAPATH, config->capath);
if(result == CURLE_NOT_BUILT_IN) {
else if(result)
goto show_error;
}
+ /* 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 = res_setopt_str(curl, CURLOPT_PROXY_CAPATH,
+ (config->proxy_capath ?
+ config->proxy_capath :
+ config->capath));
+ if(result == CURLE_NOT_BUILT_IN) {
+ if(config->proxy_capath) {
+ warnf(config->global,
+ "ignoring --proxy-capath, not supported by libcurl\n");
+ }
+ }
+ else if(result)
+ goto show_error;
+ }
+
if(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);
if(config->pinnedpubkey)
my_setopt_str(curl, CURLOPT_PINNEDPUBLICKEY, config->pinnedpubkey);
if(curlinfo->features & CURL_VERSION_SSL) {
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);
if(config->insecure_ok) {
my_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
/* libcurl default is strict verifyhost -> 2L */
/* my_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L); */
}
+ if(config->proxy_insecure_ok) {
+ my_setopt(curl, CURLOPT_PROXY_SSL_VERIFYPEER, 0L);
+ my_setopt(curl, CURLOPT_PROXY_SSL_VERIFYHOST, 0L);
+ }
+ else {
+ my_setopt(curl, CURLOPT_PROXY_SSL_VERIFYPEER, 1L);
+ }
if(config->verifystatus)
my_setopt(curl, CURLOPT_SSL_VERIFYSTATUS, 1L);
if(config->falsestart)
my_setopt(curl, CURLOPT_SSL_FALSESTART, 1L);
- my_setopt_enum(curl, CURLOPT_SSLVERSION, config->ssl_version);
+ my_setopt_enum(curl, CURLOPT_SSLVERSION,
+ config->ssl_version | config->ssl_version_max);
+ my_setopt_enum(curl, CURLOPT_PROXY_SSLVERSION,
+ config->proxy_ssl_version);
}
if(config->path_as_is)
my_setopt(curl, CURLOPT_PATH_AS_IS, 1L);
#endif
my_setopt_enum(curl, CURLOPT_TIMECONDITION, (long)config->timecond);
- my_setopt(curl, CURLOPT_TIMEVALUE, (long)config->condtime);
+ my_setopt(curl, CURLOPT_TIMEVALUE_LARGE, config->condtime);
my_setopt_str(curl, CURLOPT_CUSTOMREQUEST, config->customrequest);
customrequest_helper(config, config->httpreq, config->customrequest);
my_setopt(curl, CURLOPT_STDERR, global->errors);
if(config->cipher_list)
my_setopt_str(curl, CURLOPT_SSL_CIPHER_LIST, config->cipher_list);
+ if(config->proxy_cipher_list)
+ my_setopt_str(curl, CURLOPT_PROXY_SSL_CIPHER_LIST,
+ config->proxy_cipher_list);
+
/* new in libcurl 7.9.2: */
if(config->disable_epsv)
/* disable it */
result = res_setopt_str(curl, CURLOPT_SSLENGINE, config->engine);
if(result)
goto show_error;
- my_setopt(curl, CURLOPT_SSLENGINE_DEFAULT, 1L);
}
/* new in curl 7.10.7, extended in 7.19.4. Modified to use
my_setopt_str(curl, CURLOPT_SOCKS5_GSSAPI_NEC,
config->socks5_gssapi_nec);
+ /* new in curl 7.55.0 */
+ if(config->socks5_auth)
+ my_setopt_bitmask(curl, CURLOPT_SOCKS5_AUTH,
+ (long)config->socks5_auth);
+
/* new in curl 7.43.0 */
if(config->proxy_service_name)
my_setopt_str(curl, CURLOPT_PROXY_SERVICE_NAME,
if(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,
+ config->proxy_tls_username);
+ if(config->proxy_tls_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,
+ config->proxy_tls_authtype);
}
/* new in 7.22.0 */
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);
my_setopt(curl, CURLOPT_SSL_ENABLE_ALPN, 0L);
}
- /* new in 7.40.0 */
- if(config->unix_socket_path)
- my_setopt_str(curl, CURLOPT_UNIX_SOCKET_PATH,
- config->unix_socket_path);
-
+ /* new in 7.40.0, abstract support added in 7.53.0 */
+ if(config->unix_socket_path) {
+ 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,
+ config->unix_socket_path);
+ }
+ }
/* new in 7.45.0 */
if(config->proto_default)
my_setopt_str(curl, CURLOPT_DEFAULT_PROTOCOL, config->proto_default);
if(config->tftp_no_options)
my_setopt(curl, CURLOPT_TFTP_NO_OPTIONS, 1L);
+ /* new in 7.59.0 */
+ if(config->happy_eyeballs_timeout_ms != CURL_HET_DEFAULT)
+ my_setopt(curl, CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS,
+ config->happy_eyeballs_timeout_ms);
+
/* initialize retry vars for loop below */
retry_sleep_default = (config->retry_delay) ?
config->retry_delay*1000L : RETRY_SLEEP_DEFAULT; /* ms */
enum {
RETRY_NO,
RETRY_TIMEOUT,
+ RETRY_CONNREFUSED,
RETRY_HTTP,
RETRY_FTP,
RETRY_LAST /* not used */
(CURLE_FTP_ACCEPT_TIMEOUT == result))
/* retry timeout always */
retry = RETRY_TIMEOUT;
+ else if(config->retry_connrefused &&
+ (CURLE_COULDNT_CONNECT == result)) {
+ long oserrno;
+ curl_easy_getinfo(curl, CURLINFO_OS_ERRNO, &oserrno);
+ if(ECONNREFUSED == oserrno)
+ retry = RETRY_CONNREFUSED;
+ }
else if((CURLE_OK == result) ||
(config->failonerror &&
(CURLE_HTTP_RETURNED_ERROR == result))) {
if(retry) {
static const char * const m[]={
- NULL, "timeout", "HTTP error", "FTP error"
+ NULL,
+ "timeout",
+ "connection refused",
+ "HTTP error",
+ "FTP error"
};
warnf(config->global, "Transient problem: %s "
retry_sleep = RETRY_SLEEP_MAX;
}
if(outs.bytes && outs.filename && outs.stream) {
+ int rc;
/* We have written data to a output file, we truncate file
*/
if(!global->mute)
}
/* now seek to the end of the file, the position where we
just truncated the file in a large file-safe way */
- fseek(outs.stream, 0, SEEK_END);
+ rc = fseek(outs.stream, 0, SEEK_END);
#else
/* ftruncate is not available, so just reposition the file
to the location we would have truncated it. This won't
work properly with large files on 32-bit systems, but
most of those will have ftruncate. */
- fseek(outs.stream, (long)outs.init, SEEK_SET);
+ rc = fseek(outs.stream, (long)outs.init, SEEK_SET);
#endif
+ if(rc) {
+ if(!global->mute)
+ fprintf(global->errors,
+ "failed seeking to end of file, exiting\n");
+ result = CURLE_WRITE_ERROR;
+ goto quit_urls;
+ }
outs.bytes = 0; /* clear for next round */
}
continue; /* curl_easy_perform loop */
char *effective_url = NULL;
curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &effective_url);
if(effective_url &&
- curlx_strnequal(effective_url, "http", 4)) {
+ curl_strnequal(effective_url, "http", 4)) {
/* This was HTTP(S) */
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response);
if(response != 200 && response != 206) {
metalink_next_res = 1;
fprintf(global->errors,
"Metalink: fetching (%s) from (%s) FAILED "
- "(HTTP status code %d)\n",
+ "(HTTP status code %ld)\n",
mlfile->filename, this_url, response);
}
}
if(config->writeout)
ourWriteOut(curl, &outs, config->writeout);
- if(config->writeenv)
- ourWriteEnv(curl);
-
/*
** Code within this loop may jump directly here to label 'show_error'
** in order to display an error message for CURLcode stored in 'res'
}
else
#endif
- if(result && global->showerror) {
+ if(config->synthetic_error) {
+ ;
+ }
+ else if(result && global->showerror) {
fprintf(global->errors, "curl: (%d) %s\n", result, (errorbuffer[0]) ?
errorbuffer : curl_easy_strerror(result));
if(result == CURLE_SSL_CACERT)
- fprintf(global->errors, "%s%s",
- CURL_CA_CERT_ERRORMSG1, CURL_CA_CERT_ERRORMSG2);
+ fputs(CURL_CA_CERT_ERRORMSG, global->errors);
}
/* Fall through comment to 'quit_urls' label */
}
#endif
-#ifdef HAVE_UTIME
/* File time can only be set _after_ the file has been closed */
if(!result && config->remote_time && outs.s_isreg && outs.filename) {
/* Ask libcurl if we got a remote file time */
- long filetime = -1;
- curl_easy_getinfo(curl, CURLINFO_FILETIME, &filetime);
- if(filetime >= 0) {
- struct utimbuf times;
- times.actime = (time_t)filetime;
- times.modtime = (time_t)filetime;
- utime(outs.filename, ×); /* set the time we got */
- }
+ curl_off_t filetime = -1;
+ curl_easy_getinfo(curl, CURLINFO_FILETIME_T, &filetime);
+ setfiletime(filetime, outs.filename, config->global->errors);
}
-#endif
#ifdef USE_METALINK
if(!metalink && config->use_metalink && result == CURLE_OK) {
urlnode->flags = 0;
/*
- ** Bail out upon critical errors
+ ** Bail out upon critical errors or --fail-early
*/
- if(is_fatal_error(result))
+ if(is_fatal_error(result) || (result && global->fail_early))
goto quit_curl;
} /* for-loop through all URLs */
/* Parse .curlrc if necessary */
if((argc == 1) ||
- (!curlx_strequal(argv[1], "-q") &&
- !curlx_strequal(argv[1], "--disable"))) {
+ (!curl_strequal(argv[1], "-q") &&
+ !curl_strequal(argv[1], "--disable"))) {
parseconfig(NULL, config); /* ignore possible failure */
/* If we had no arguments then make sure a url was specified in .curlrc */
result = operate_do(config, config->current);
config->current = config->current->next;
+
+ if(config->current && config->current->easy)
+ curl_easy_reset(config->current->easy);
}
#ifndef CURL_DISABLE_LIBCURL_OPTION