Merge remote-tracking branch 'origin' into parallel-wget

This commit is contained in:
Giuseppe Scrivano 2013-07-30 01:02:28 +02:00
commit 4445d48471
16 changed files with 386 additions and 91 deletions

View File

@ -6,6 +6,15 @@
* configure.ac: By default disable threads and metalink support.
2013-07-23 Tim Ruehsen <tim.ruehsen@gmx.de>
* configure.ac: Remove AM_CONDITIONAL HAVE_NETTLE.
Reported by: Darshit Shah <darnir@gmail.com>.
2013-07-13 Tim Ruehsen <tim.ruehsen@gmx.de>
* configure.ac: check for libnettle when GNU TLS is used.
2013-05-17 Bykov Aleksey <gnfalex@rambler.ru>
* bootstrap: Add `mkostemp'

View File

@ -351,11 +351,26 @@ then
AC_LIBOBJ([http-ntlm])
fi
else
dnl If SSL is unavailable and the user explicitly requested NTLM,
dnl abort.
if test x"$ENABLE_NTLM" = xyes
AC_CHECK_LIB(nettle, nettle_md4_init, [HAVE_NETTLE=yes], [HAVE_NETTLE=no; AC_MSG_WARN(*** libnettle was not found. You will not be able to use NTLM)])
if test x"$HAVE_NETTLE" = xyes
then
AC_MSG_ERROR([NTLM authorization requested and OpenSSL not found; aborting])
AC_SUBST(NETTLE_LIBS, "-lnettle")
AC_DEFINE([HAVE_NETTLE], [1], [Use libnettle])
if test x"$ENABLE_NTLM" != xno
then
AC_DEFINE([ENABLE_NTLM], 1,
[Define if you want the NTLM authorization support compiled in.])
AC_LIBOBJ([http-ntlm])
LIBS="$NETTLE_LIBS $LIBS"
fi
else
dnl If SSL is unavailable and the user explicitly requested NTLM,
dnl abort.
if test x"$ENABLE_NTLM" = xyes
then
AC_MSG_ERROR([NTLM authorization requested and SSL not enabled; aborting])
fi
fi
fi

View File

@ -1,3 +1,9 @@
2013-07-09 Giuseppe Scrivano <gscrivano@gnu.org>
* wget.texi (Download Options): Add documentation for --backups.
(Wgetrc Commands): Add documentation for backups.
Reported by: Tomas Hozza <thozza@redhat.com>.
2013-07-11 Tomas Hozza <thozza@redhat.com>
* wget.texi: Document --regex-type and --preserve-permissions.

View File

@ -651,6 +651,13 @@ Note that when @samp{-nc} is specified, files with the suffixes
@samp{.html} or @samp{.htm} will be loaded from the local disk and
parsed as if they had been retrieved from the Web.
@cindex backing up files
@item --backups=@var{backups}
Before (over)writing a file, back up an existing file by adding a
@samp{.1} suffix (@samp{_1} on VMS) to the file name. Such backup
files are rotated to @samp{.2}, @samp{.3}, and so on, up to
@var{backups} (and lost beyond that).
@cindex continue retrieval
@cindex incomplete downloads
@cindex resume download
@ -2911,9 +2918,11 @@ enables it).
Enable/disable saving pre-converted files with the suffix
@samp{.orig}---the same as @samp{-K} (which enables it).
@c @item backups = @var{number}
@c #### Document me!
@c
@item backups = @var{number}
Use up to @var{number} backups for a file. Backups are rotated by
adding an incremental counter that starts at @samp{1}. The default is
@samp{0}.
@item base = @var{string}
Consider relative @sc{url}s in input files (specified via the
@samp{input} command or the @samp{--input-file}/@samp{-i} option,

View File

@ -2,6 +2,64 @@
* utils.c (run_with_timeout): abort when there are more threads.
2013-07-16 Darshit Shah <darnir@gmail.com>
* wget.h (err_t): Added new errors, ATTRMISSING and UNKNOWNATTR to
handle missing attributes and Unknown attribute values respectively in
HTTP Headers.
* exits.c (get_status_for_err): ATTRMISSING is a Protocol Error while
UNKNOWNATTR is a general error, presumably because of a feature that
is not yet implemented.
* http.c (gethttp): Call create_authorization_line () separately. In
case the auth_err flag has been set with an error, handle it and exit.
* http.c (create_authorization_line): Pass a pointer, auth_err to set
the flag for different kinds of errors encountered.
* http.c (http_loop): Handle the errors raised by the authentication
handlers.
* http.c (digest_authentication_encode): Pass pointer auth_err to set
the error flags.
Set qop to NULL in case the value of the qop / algorithm attribute is
unknown to Wget. Set an appropriate error too.
2013-07-13 Tim Ruehsen <tim.ruehsen@gmx.de>
* http.c (digest_authentication_encode): Fix a crash when the algorithm
is not specified in the server response. Free dynamic memory used by
the function when the function exits.
* http-ntlm.c [HAVE_NETTLE]: Include <nettle/md4.h> and <nettle/des.h>.
(setup_des_key) [HAVE_NETTLE]: New function to deal with
libnettle.
(calc_resp) [HAVE_NETTLE]: Add support for libnettle.
(mkhash) [HAVE_NETTLE]: Likewise.
Reported by: Tim Ruehsen <tim.ruehsen@gmx.de>.
2013-07-13 Steven M. Schweda <sms@antinode.info>
* warc.c (warc_tempfile): Fix a portability issue on VMS.
2013-07-10 Giuseppe Scrivano <gscrivano@gnu.org>
* http.c (read_response_body) [ALLOW_CLOBBER]: Move definition to..
* options.h (struct options): Make `backups' an int.
* url.h [ALLOW_CLOBBER]: .. Here. Do not clobber when backups are used.
* url.c (url_file_name): Use the ALLOW_CLOBBER macro instead of
repeating the code.
2013-07-08 Steven M. Schweda <sms@antinode.info>
* retr.c (rotate_backups): Support for VMS files.
2013-07-12 Giuseppe Scrivano <gscrivano@gnu.org>
* http.c (digest_authentication_encode): Set default value of
`algorithm' to "MD5". Check if `qop' is not-NULL before access it.
2013-07-11 Karsten Hopp <karsten@redhat.com>
* openssl.c (struct openssl_read_args, struct scwt_context): New struct.
(openssl_read, ssl_connect_with_timeout_callback): New function.
(ssl_connect_wget): respect connect timeout.
2013-07-11 Tim Ruehsen <tim.ruehsen@gmx.de>
* gnutls.c (ssl_connect_wget): respect connect timeout.

View File

@ -68,7 +68,7 @@ get_status_for_err (uerr_t err)
return WGET_EXIT_SSL_AUTH_FAIL;
case FTPLOGINC: case FTPLOGREFUSED: case AUTHFAILED:
return WGET_EXIT_SERVER_AUTH_FAIL;
case HEOF: case HERR:
case HEOF: case HERR: case ATTRMISSING:
return WGET_EXIT_PROTOCOL_ERROR;
case WRONGCODE: case FTPPORTERR: case FTPSYSERR:
case FTPNSFOD: case FTPUNKNOWNTYPE: case FTPSRVERR:
@ -76,7 +76,7 @@ get_status_for_err (uerr_t err)
case CONTNOTSUPPORTED: case RANGEERR: case RETRBADPATTERN:
case PROXERR:
return WGET_EXIT_SERVER_ERROR;
case URLERROR: case QUOTEXC: case SSLINITFAILED:
case URLERROR: case QUOTEXC: case SSLINITFAILED: case UNKNOWNATTR:
default:
return WGET_EXIT_UNKNOWN;
}

View File

@ -42,27 +42,33 @@ as that of the covered work. */
#include <string.h>
#include <stdlib.h>
#include <openssl/des.h>
#include <openssl/md4.h>
#include <openssl/opensslv.h>
#include "utils.h"
#include "http-ntlm.h"
#if OPENSSL_VERSION_NUMBER < 0x00907001L
#define DES_key_schedule des_key_schedule
#define DES_cblock des_cblock
#define DES_set_odd_parity des_set_odd_parity
#define DES_set_key des_set_key
#define DES_ecb_encrypt des_ecb_encrypt
#ifdef HAVE_NETTLE
# include <nettle/md4.h>
# include <nettle/des.h>
#else
# include <openssl/des.h>
# include <openssl/md4.h>
# include <openssl/opensslv.h>
# if OPENSSL_VERSION_NUMBER < 0x00907001L
# define DES_key_schedule des_key_schedule
# define DES_cblock des_cblock
# define DES_set_odd_parity des_set_odd_parity
# define DES_set_key des_set_key
# define DES_ecb_encrypt des_ecb_encrypt
/* This is how things were done in the old days */
#define DESKEY(x) x
#define DESKEYARG(x) x
#else
# define DESKEY(x) x
# define DESKEYARG(x) x
# else
/* Modern version */
#define DESKEYARG(x) *x
#define DESKEY(x) &x
# define DESKEYARG(x) *x
# define DESKEY(x) &x
# endif
#endif
/* Define this to make the type-3 message include the NT response message */
@ -176,6 +182,25 @@ ntlm_input (struct ntlmdata *ntlm, const char *header)
* Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The
* key schedule ks is also set.
*/
#ifdef HAVE_NETTLE
static void
setup_des_key(unsigned char *key_56,
struct des_ctx *des)
{
unsigned char key[8];
key[0] = key_56[0];
key[1] = ((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1);
key[2] = ((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2);
key[3] = ((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3);
key[4] = ((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4);
key[5] = ((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5);
key[6] = ((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6);
key[7] = (key_56[6] << 1) & 0xFF;
nettle_des_set_key(des, key);
}
#else
static void
setup_des_key(unsigned char *key_56,
DES_key_schedule DESKEYARG(ks))
@ -194,6 +219,7 @@ setup_des_key(unsigned char *key_56,
DES_set_odd_parity(&key);
DES_set_key(&key, ks);
}
#endif
/*
* takes a 21 byte array and treats it as 3 56-bit DES keys. The
@ -203,6 +229,18 @@ setup_des_key(unsigned char *key_56,
static void
calc_resp(unsigned char *keys, unsigned char *plaintext, unsigned char *results)
{
#ifdef HAVE_NETTLE
struct des_ctx des;
setup_des_key(keys, &des);
nettle_des_encrypt(&des, 8, results, plaintext);
setup_des_key(keys + 7, &des);
nettle_des_encrypt(&des, 8, results + 8, plaintext);
setup_des_key(keys + 14, &des);
nettle_des_encrypt(&des, 8, results + 16, plaintext);
#else
DES_key_schedule ks;
setup_des_key(keys, DESKEY(ks));
@ -216,6 +254,7 @@ calc_resp(unsigned char *keys, unsigned char *plaintext, unsigned char *results)
setup_des_key(keys+14, DESKEY(ks));
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+16),
DESKEY(ks), DES_ENCRYPT);
#endif
}
/*
@ -255,6 +294,15 @@ mkhash(const char *password,
{
/* create LanManager hashed password */
#ifdef HAVE_NETTLE
struct des_ctx des;
setup_des_key(pw, &des);
nettle_des_encrypt(&des, 8, lmbuffer, magic);
setup_des_key(pw + 7, &des);
nettle_des_encrypt(&des, 8, lmbuffer + 8, magic);
#else
DES_key_schedule ks;
setup_des_key(pw, DESKEY(ks));
@ -264,6 +312,7 @@ mkhash(const char *password,
setup_des_key(pw+7, DESKEY(ks));
DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer+8),
DESKEY(ks), DES_ENCRYPT);
#endif
memset(lmbuffer+16, 0, 5);
}
@ -272,8 +321,11 @@ mkhash(const char *password,
#ifdef USE_NTRESPONSES
{
/* create NT hashed password */
#ifdef HAVE_NETTLE
struct md4_ctx MD4;
#else
MD4_CTX MD4;
#endif
len = strlen(password);
@ -282,9 +334,16 @@ mkhash(const char *password,
pw[2*i+1] = 0;
}
#ifdef HAVE_NETTLE
nettle_md4_init(&MD4);
nettle_md4_update(&MD4, 2*len, pw);
nettle_md4_digest(&MD4, MD4_DIGEST_SIZE, ntbuffer);
#else
/* create NT hashed password */
MD4_Init(&MD4);
MD4_Update(&MD4, pw, 2*len);
MD4_Final(ntbuffer, &MD4);
#endif
memset(ntbuffer+16, 0, 5);
}

View File

@ -78,7 +78,7 @@ extern char *version_string;
struct http_stat;
static char *create_authorization_line (const char *, const char *,
const char *, const char *,
const char *, bool *);
const char *, bool *, uerr_t *);
static char *basic_authentication_encode (const char *, const char *);
static bool known_authentication_scheme_p (const char *, const char *);
static void ensure_extension (struct http_stat *, const char *, int *);
@ -1860,12 +1860,6 @@ read_response_body (struct http_stat *hs, int sock, FILE *fp, wgint contlen,
} while (0)
#endif /* def __VMS [else] */
/* The flags that allow clobbering the file (opening with "wb").
Defined here to avoid repetition later. #### This will require
rework. */
#define ALLOW_CLOBBER (opt.noclobber || opt.always_rest || opt.timestamping \
|| opt.dirstruct || opt.output_document)
/* Retrieve a document through HTTP protocol. It recognizes status
code, and correctly handles redirections. It closes the network
socket. If it receives an error from the functions below it, it
@ -2625,6 +2619,7 @@ read_header:
if (pconn)
pconn->authorized = false;
#endif
uerr_t auth_err = RETROK;
if (!auth_finished && (user && passwd))
{
/* IIS sends multiple copies of WWW-Authenticate, one with
@ -2652,28 +2647,44 @@ read_header:
else if (!basic_auth_finished
|| !BEGINS_WITH (www_authenticate, "Basic"))
{
char *pth;
pth = url_full_path (u);
request_set_header (req, "Authorization",
create_authorization_line (www_authenticate,
user, passwd,
request_method (req),
pth,
&auth_finished),
rel_value);
if (BEGINS_WITH (www_authenticate, "NTLM"))
ntlm_seen = true;
else if (!u->user && BEGINS_WITH (www_authenticate, "Basic"))
char *pth = url_full_path (u);
const char *value;
uerr_t *auth_stat;
auth_stat = xmalloc (sizeof (uerr_t));
*auth_stat = RETROK;
value = create_authorization_line (www_authenticate,
user, passwd,
request_method (req),
pth,
&auth_finished,
auth_stat);
auth_err = *auth_stat;
if (auth_err == RETROK)
{
/* Need to register this host as using basic auth,
* so we automatically send creds next time. */
register_basic_auth_host (u->host);
request_set_header (req, "Authorization", value, rel_value);
if (BEGINS_WITH (www_authenticate, "NTLM"))
ntlm_seen = true;
else if (!u->user && BEGINS_WITH (www_authenticate, "Basic"))
{
/* Need to register this host as using basic auth,
* so we automatically send creds next time. */
register_basic_auth_host (u->host);
}
xfree (pth);
xfree_null (message);
resp_free (resp);
xfree (head);
xfree (auth_stat);
goto retry_with_auth;
}
else
{
/* Creating the Authorization header went wrong */
}
xfree (pth);
xfree_null (message);
resp_free (resp);
xfree (head);
goto retry_with_auth;
}
else
{
@ -2681,13 +2692,16 @@ read_header:
* give up. */
}
}
logputs (LOG_NOTQUIET, _("Authorization failed.\n"));
request_free (req);
xfree_null (message);
resp_free (resp);
xfree (head);
REGISTER_PERSISTENT_CONNECTION ();
return AUTHFAILED;
if (auth_err == RETROK)
return AUTHFAILED;
else
return auth_err;
}
else /* statcode != HTTP_STATUS_UNAUTHORIZED */
{
@ -3439,12 +3453,23 @@ Spider mode enabled. Check if remote file exists.\n"));
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET, _("Cannot write to %s (%s).\n"),
quote (hstat.local_file), strerror (errno));
case HOSTERR: case CONIMPOSSIBLE: case PROXERR: case AUTHFAILED:
case SSLINITFAILED: case CONTNOTSUPPORTED: case VERIFCERTERR:
case FILEBADFILE:
case HOSTERR: case CONIMPOSSIBLE: case PROXERR: case SSLINITFAILED:
case CONTNOTSUPPORTED: case VERIFCERTERR: case FILEBADFILE:
case UNKNOWNATTR:
/* Fatal errors just return from the function. */
ret = err;
goto exit;
case ATTRMISSING:
/* A missing attribute in a Header is a fatal Protocol error. */
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET, _("Required attribute missing from Header received.\n"));
ret = err;
goto exit;
case AUTHFAILED:
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET, _("Username/Password Authentication Failed.\n"));
ret = err;
goto exit;
case WARC_ERR:
/* A fatal WARC error. */
logputs (LOG_VERBOSE, "\n");
@ -3983,7 +4008,7 @@ dump_hash (char *buf, const unsigned char *hash)
static char *
digest_authentication_encode (const char *au, const char *user,
const char *passwd, const char *method,
const char *path)
const char *path, uerr_t *auth_err)
{
static char *realm, *opaque, *nonce, *qop, *algorithm;
static struct {
@ -4003,7 +4028,7 @@ digest_authentication_encode (const char *au, const char *user,
param_token name, value;
realm = opaque = nonce = qop = algorithm = NULL;
realm = opaque = nonce = algorithm = qop = NULL;
au += 6; /* skip over `Digest' */
while (extract_param (&au, &name, &value, ','))
@ -4023,22 +4048,27 @@ digest_authentication_encode (const char *au, const char *user,
if (qop != NULL && strcmp(qop,"auth"))
{
logprintf (LOG_NOTQUIET, _("Unsupported quality of protection '%s'.\n"), qop);
user = NULL; /* force freeing mem and return */
xfree_null (qop); /* force freeing mem and return */
qop = NULL;
}
if (algorithm != NULL && strcmp (algorithm,"MD5") && strcmp (algorithm,"MD5-sess"))
else if (algorithm != NULL && strcmp (algorithm,"MD5") && strcmp (algorithm,"MD5-sess"))
{
logprintf (LOG_NOTQUIET, _("Unsupported algorithm '%s'.\n"), algorithm);
user = NULL; /* force freeing mem and return */
xfree_null (qop); /* force freeing mem and return */
qop = NULL;
}
if (!realm || !nonce || !user || !passwd || !path || !method)
if (!realm || !nonce || !user || !passwd || !path || !method || !qop)
{
xfree_null (realm);
xfree_null (opaque);
xfree_null (nonce);
xfree_null (qop);
xfree_null (algorithm);
if (!qop)
*auth_err = UNKNOWNATTR;
else
*auth_err = ATTRMISSING;
return NULL;
}
@ -4060,7 +4090,7 @@ digest_authentication_encode (const char *au, const char *user,
dump_hash (a1buf, hash);
if (! strcmp (algorithm, "MD5-sess"))
if (algorithm && !strcmp (algorithm, "MD5-sess"))
{
/* A1BUF = H( H(user ":" realm ":" password) ":" nonce ":" cnonce ) */
snprintf (cnonce, sizeof (cnonce), "%08x", random_number(INT_MAX));
@ -4085,7 +4115,7 @@ digest_authentication_encode (const char *au, const char *user,
md5_finish_ctx (&ctx, hash);
dump_hash (a2buf, hash);
if (!strcmp(qop, "auth") || !strcmp (qop, "auth-int"))
if (qop && (!strcmp(qop, "auth") || !strcmp (qop, "auth-int")))
{
/* RFC 2617 Digest Access Authentication */
/* generate random hex string */
@ -4135,7 +4165,7 @@ digest_authentication_encode (const char *au, const char *user,
res = xmalloc (res_size);
if (!strcmp(qop,"auth"))
if (qop && !strcmp (qop, "auth"))
{
res_len = snprintf (res, res_size, "Digest "\
"username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\""\
@ -4160,6 +4190,13 @@ digest_authentication_encode (const char *au, const char *user,
snprintf(res + res_len, res_size - res_len, ", algorithm=\"%s\"", algorithm);
}
}
xfree_null (realm);
xfree_null (opaque);
xfree_null (nonce);
xfree_null (qop);
xfree_null (algorithm);
return res;
}
#endif /* ENABLE_DIGEST */
@ -4201,7 +4238,7 @@ known_authentication_scheme_p (const char *hdrbeg, const char *hdrend)
static char *
create_authorization_line (const char *au, const char *user,
const char *passwd, const char *method,
const char *path, bool *finished)
const char *path, bool *finished, uerr_t *auth_err)
{
/* We are called only with known schemes, so we can dispatch on the
first letter. */
@ -4213,7 +4250,7 @@ create_authorization_line (const char *au, const char *user,
#ifdef ENABLE_DIGEST
case 'D': /* Digest */
*finished = true;
return digest_authentication_encode (au, user, passwd, method, path);
return digest_authentication_encode (au, user, passwd, method, path, auth_err);
#endif
#if defined ENABLE_NTLM && defined ENABLE_THREADS

View File

@ -735,6 +735,9 @@ Recursive download:\n"),
N_("\
-k, --convert-links make links in downloaded HTML or CSS point to\n\
local files.\n"),
N_("\
--backups=N before writing file X, rotate up to N backup files.\n"),
#ifdef __VMS
N_("\
-K, --backup-converted before converting file X, back up as X_orig.\n"),

View File

@ -251,24 +251,50 @@ ssl_init (void)
return false;
}
struct openssl_transport_context {
struct openssl_transport_context
{
SSL *conn; /* SSL connection handle */
char *last_error; /* last error printed with openssl_errstr */
};
struct openssl_read_args
{
int fd;
struct openssl_transport_context *ctx;
char *buf;
int bufsize;
int retval;
};
static void openssl_read_callback(void *arg)
{
struct openssl_read_args *args = (struct openssl_read_args *) arg;
struct openssl_transport_context *ctx = args->ctx;
SSL *conn = ctx->conn;
char *buf = args->buf;
int bufsize = args->bufsize;
int ret;
do
ret = SSL_read (conn, buf, bufsize);
while (ret == -1 && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
&& errno == EINTR);
args->retval = ret;
}
static int
openssl_read (int fd, char *buf, int bufsize, void *arg)
{
int ret;
struct openssl_transport_context *ctx = arg;
SSL *conn = ctx->conn;
do
ret = SSL_read (conn, buf, bufsize);
while (ret == -1
&& SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
&& errno == EINTR);
struct openssl_read_args args;
args.fd = fd;
args.buf = buf;
args.bufsize = bufsize;
args.ctx = (struct openssl_transport_context*) arg;
return ret;
if (run_with_timeout(opt.read_timeout, openssl_read_callback, &args)) {
return -1;
}
return args.retval;
}
static int
@ -386,6 +412,19 @@ static struct transport_implementation openssl_transport = {
openssl_peek, openssl_errstr, openssl_close
};
struct scwt_context
{
SSL *ssl;
int result;
};
static void
ssl_connect_with_timeout_callback(void *arg)
{
struct scwt_context *ctx = (struct scwt_context *)arg;
ctx->result = SSL_connect(ctx->ssl);
}
/* Perform the SSL handshake on file descriptor FD, which is assumed
to be connected to an SSL server. The SSL handle provided by
OpenSSL is registered with the file descriptor FD using
@ -398,6 +437,7 @@ bool
ssl_connect_wget (int fd, const char *hostname)
{
SSL *conn;
struct scwt_context scwt_ctx;
struct openssl_transport_context *ctx;
DEBUGP (("Initiating SSL handshake.\n"));
@ -425,7 +465,14 @@ ssl_connect_wget (int fd, const char *hostname)
if (!SSL_set_fd (conn, FD_TO_SOCKET (fd)))
goto error;
SSL_set_connect_state (conn);
if (SSL_connect (conn) <= 0 || conn->state != SSL_ST_OK)
scwt_ctx.ssl = conn;
if (run_with_timeout(opt.read_timeout, ssl_connect_with_timeout_callback,
&scwt_ctx)) {
DEBUGP (("SSL handshake timed out.\n"));
goto timeout;
}
if (scwt_ctx.result <= 0 || conn->state != SSL_ST_OK)
goto error;
ctx = xnew0 (struct openssl_transport_context);
@ -441,6 +488,7 @@ ssl_connect_wget (int fd, const char *hostname)
error:
DEBUGP (("SSL handshake failed.\n"));
print_errors ();
timeout:
if (conn)
SSL_free (conn);
return false;

View File

@ -171,7 +171,7 @@ struct options
bool timestamping; /* Whether to use time-stamping. */
bool backup_converted; /* Do we save pre-converted files as *.orig? */
bool backups; /* Are numeric backups made? */
int backups; /* Are numeric backups made? */
char *useragent; /* User-Agent string, which can be set
to something other than Wget. */

View File

@ -44,6 +44,9 @@ as that of the covered work. */
#ifdef ENABLE_METALINK
#include <metalink/metalink_parser.h>
#include <metalink/metalink_types.h>
#ifdef VMS
# include <unixio.h> /* For delete(). */
#endif
#include "metalink.h"
#endif
@ -1434,7 +1437,16 @@ free_urlpos (struct urlpos *l)
void
rotate_backups(const char *fname)
{
int maxlen = strlen (fname) + 1 + numdigit (opt.backups) + 1;
#ifdef __VMS
# define SEP "_"
# define AVS ";*" /* All-version suffix. */
# define AVSL (sizeof (AVS) - 1)
#else
# define SEP "."
# define AVSL 0
#endif
int maxlen = strlen (fname) + sizeof (SEP) + numdigit (opt.backups) + AVSL;
char *from = (char *)alloca (maxlen);
char *to = (char *)alloca (maxlen);
struct_stat sb;
@ -1446,12 +1458,24 @@ rotate_backups(const char *fname)
for (i = opt.backups; i > 1; i--)
{
sprintf (from, "%s.%d", fname, i - 1);
sprintf (to, "%s.%d", fname, i);
#ifdef VMS
/* Delete (all versions of) any existing max-suffix file, to avoid
* creating multiple versions of it. (On VMS, rename() will
* create a new version of an existing destination file, not
* destroy/overwrite it.)
*/
if (i == opt.backups)
{
sprintf (to, "%s%s%d%s", fname, SEP, i, AVS);
delete (to);
}
#endif
sprintf (to, "%s%s%d", fname, SEP, i);
sprintf (from, "%s%s%d", fname, SEP, i - 1);
rename (from, to);
}
sprintf (to, "%s.%d", fname, 1);
sprintf (to, "%s%s%d", fname, SEP, 1);
rename(fname, to);
}

View File

@ -1670,11 +1670,12 @@ url_file_name (const struct url *u, char *replaced_filename)
2) Retrieval with regetting.
3) Timestamping is used.
4) Hierarchy is built.
5) Backups are specified.
The exception is the case when file does exist and is a
directory (see `mkalldirs' for explanation). */
if ((opt.noclobber || opt.always_rest || opt.timestamping || opt.dirstruct)
if (ALLOW_CLOBBER
&& !(file_exists_p (fname) && !file_non_directory_p (fname)))
{
unique = fname;

View File

@ -47,6 +47,12 @@ as that of the covered work. */
* file descriptor. */
#define CHOMP_BUFFER 19
/* The flags that allow clobbering the file (opening with "wb").
Defined here to avoid repetition later. #### This will require
rework. */
#define ALLOW_CLOBBER (opt.noclobber || opt.always_rest || opt.timestamping \
|| opt.dirstruct || opt.output_document || opt.backups > 0)
/* Specifies how, or whether, user auth information should be included
* in URLs regenerated from URL parse structures. */
enum url_auth_mode {

View File

@ -738,8 +738,14 @@ warc_start_new_file (bool meta)
char *new_filename = malloc (base_filename_length + 1 + 5 + 8 + 1);
warc_current_filename = new_filename;
#ifdef __VMS
# define WARC_GZ "warc-gz"
#else /* def __VMS */
# define WARC_GZ "warc.gz"
#endif /* def __VMS [else] */
#ifdef HAVE_LIBZ
const char *extension = (opt.warc_compression_enabled ? "warc.gz" : "warc");
const char *extension = (opt.warc_compression_enabled ? WARC_GZ : "warc");
#else
const char *extension = "warc";
#endif
@ -1153,6 +1159,21 @@ warc_tempfile (void)
if (path_search (filename, 100, opt.warc_tempdir, "wget", true) == -1)
return NULL;
#ifdef __VMS
/* 2013-07-12 SMS.
* mkostemp()+unlink()+fdopen() scheme causes trouble on VMS, so use
* mktemp() to uniquify the (VMS-style) name, and then use a normal
* fopen() with a "create temp file marked for delete" option.
*/
{
char *tfn;
tfn = mktemp (filename); /* Get unique name from template. */
if (tfn == NULL)
return NULL;
return fopen (tfn, "w+", "fop=tmd"); /* Create auto-delete temp file. */
}
#else /* def __VMS */
int fd = mkostemp (filename, O_TEMPORARY);
if (fd < 0)
return NULL;
@ -1162,8 +1183,8 @@ warc_tempfile (void)
return NULL;
#endif
return fdopen (fd, "wb+");
#endif /* def __VMS [else] */
}

View File

@ -357,10 +357,9 @@ typedef enum
PROXERR,
/* 50 */
AUTHFAILED, QUOTEXC, WRITEFAILED, SSLINITFAILED, VERIFCERTERR,
UNLINKERR, NEWLOCATION_KEEP_POST, CLOSEFAILED, WARC_ERR,
WARC_TMP_FOPENERR,
UNLINKERR, NEWLOCATION_KEEP_POST, CLOSEFAILED, ATTRMISSING, UNKNOWNATTR,
/* 60 */
WARC_TMP_FWRITEERR, THREADS_ERR, SEM_ERR
WARC_ERR, WARC_TMP_FOPENERR, WARC_TMP_FWRITEERR, THREADS_ERR, SEM_ERR
} uerr_t;
struct range {