[svn] Make sure -c doesn't truncate the file.

Published in <sxsofuhi4kc.fsf@florida.arsdigita.de>.
This commit is contained in:
hniksic 2001-04-01 13:04:21 -07:00
parent b4394a057b
commit a52aaeb451
5 changed files with 113 additions and 15 deletions

View File

@ -1,3 +1,13 @@
2001-04-01 Hrvoje Niksic <hniksic@arsdigita.com>
* ftp.c (getftp): Don't start the download from scratch if `-c'
was specified, but the file is already fully downloaded.
* http.c (gethttp): Don't truncate a pre-existing file if `-c' was
specified and the server doesn't support continued download.
(gethttp): Don't start the download from scratch if `-c' was
specified, but the file is already fully downloaded.
2001-03-31 Hrvoje Niksic <hniksic@arsdigita.com>
(recursive_retrieve): Don't clear the hash tables at this point at

View File

@ -281,8 +281,9 @@ Error in server response, closing control connection.\n"));
err = ftp_pwd(&con->rbuf, &con->id);
/* FTPRERR */
switch (err)
{
case FTPRERR || FTPSRVERR :
{
case FTPRERR:
case FTPSRVERR :
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET, _("\
Error in server response, closing control connection.\n"));
@ -296,7 +297,7 @@ Error in server response, closing control connection.\n"));
default:
abort ();
break;
}
}
if (!opt.server_response)
logputs (LOG_VERBOSE, _("done.\n"));
@ -639,6 +640,19 @@ Error in server response, closing control connection.\n"));
return err;
break;
case FTPRESTFAIL:
/* If `-c' is specified and the file already existed when
Wget was started, it would be a bad idea for us to start
downloading it from scratch, effectively truncating it. */
if (opt.always_rest && (cmd & NO_TRUNCATE))
{
logprintf (LOG_NOTQUIET,
_("\nREST failed; will not truncate `%s'.\n"),
u->local);
CLOSE (csock);
closeport (dtsock);
rbuf_uninitialize (&con->rbuf);
return CONTNOTSUPPORTED;
}
logputs (LOG_VERBOSE, _("\nREST failed, starting from scratch.\n"));
restval = 0L;
break;
@ -944,7 +958,7 @@ Error in server response, closing control connection.\n"));
static uerr_t
ftp_loop_internal (struct urlinfo *u, struct fileinfo *f, ccon *con)
{
int count, orig_lp;
int count, orig_lp, no_truncate;
long restval, len;
char *tms, *tmrate, *locf;
uerr_t err;
@ -975,6 +989,13 @@ ftp_loop_internal (struct urlinfo *u, struct fileinfo *f, ccon *con)
orig_lp = con->cmd & LEAVE_PENDING ? 1 : 0;
/* In `-c' is used, check whether the file we're writing to exists
before we've done anything. If so, we'll refuse to truncate it
if the server doesn't support continued downloads. */
no_truncate = 0;
if (opt.always_rest)
no_truncate = file_exists_p (locf);
/* THE loop. */
do
{
@ -1001,6 +1022,8 @@ ftp_loop_internal (struct urlinfo *u, struct fileinfo *f, ccon *con)
else
con->cmd |= DO_CWD;
}
if (no_truncate)
con->cmd |= NO_TRUNCATE;
/* Assume no restarting. */
restval = 0L;
if ((count > 1 || opt.always_rest)
@ -1043,7 +1066,7 @@ ftp_loop_internal (struct urlinfo *u, struct fileinfo *f, ccon *con)
switch (err)
{
case HOSTERR: case CONREFUSED: case FWRITEERR: case FOPENERR:
case FTPNSFOD: case FTPLOGINC: case FTPNOPASV:
case FTPNSFOD: case FTPLOGINC: case FTPNOPASV: case CONTNOTSUPPORTED:
/* Fatal errors, give up. */
return err;
break;

View File

@ -81,7 +81,9 @@ enum wget_ftp_command
DO_CWD = 0x0002, /* Change current directory. */
DO_RETR = 0x0004, /* Retrieve the file. */
DO_LIST = 0x0008, /* Retrieve the directory list. */
LEAVE_PENDING = 0x0010 /* Do not close the socket. */
LEAVE_PENDING = 0x0010, /* Do not close the socket. */
NO_TRUNCATE = 0x0020 /* Don't truncate the file if REST
malfunctions. */
};
enum wget_ftp_fstatus

View File

@ -462,6 +462,8 @@ struct http_stat
char *error; /* textual HTTP error */
int statcode; /* status code */
long dltime; /* time of the download */
int no_truncate; /* whether truncating the file is
forbidden. */
};
/* Free the elements of hstat X. */
@ -1128,7 +1130,58 @@ Accept: %s\r\n\
}
if (contrange == -1)
hs->restval = 0;
{
/* We did not get a content-range header. This means that the
server did not honor our `Range' request. Normally, this
means we should reset hs->restval and continue normally. */
/* However, if `-c' is used, we need to be a bit more careful:
1. If `-c' is specified and the file already existed when
Wget was started, it would be a bad idea for us to start
downloading it from scratch, effectively truncating it. I
believe this cannot happen unless `-c' was specified.
2. If `-c' is used on a file that is already fully
downloaded, we're requesting bytes after the end of file,
which can result in server not honoring `Range'. If this is
the case, `Content-Length' will be equal to the length of the
file. */
if (opt.always_rest)
{
/* Check for condition #2. */
if (hs->restval == contlen)
{
logputs (LOG_VERBOSE, _("\
\n The file is already fully retrieved; nothing to do.\n\n"));
/* In case the caller inspects. */
hs->len = contlen;
hs->res = 0;
FREE_MAYBE (type);
FREE_MAYBE (hs->newloc);
FREE_MAYBE (all_headers);
CLOSE_INVALIDATE (sock); /* would be CLOSE_FINISH, but there
might be more bytes in the body. */
return RETRFINISHED;
}
/* Check for condition #1. */
if (hs->no_truncate)
{
logprintf (LOG_NOTQUIET,
_("\
The server does not support continued download;
refusing to truncate `%s'.\n\n"), u->local);
return CONTNOTSUPPORTED;
}
/* Fallthrough */
}
hs->restval = 0;
}
else if (contrange != hs->restval ||
(H_PARTIAL (statcode) && contrange == -1))
{
@ -1204,7 +1257,7 @@ Accept: %s\r\n\
/* Return if we have no intention of further downloading. */
if (!(*dt & RETROKF) || (*dt & HEAD_ONLY))
{
/* In case someone cares to look... */
/* In case the caller cares to look... */
hs->len = 0L;
hs->res = 0;
FREE_MAYBE (type);
@ -1347,8 +1400,10 @@ File `%s' already there, will not retrieve.\n"), u->local);
{
/* Would a single s[n]printf() call be faster? --dan
It wouldn't. sprintf() is horribly slow. At one point I
profiled Wget, and found that a measurable and
Definitely not. sprintf() is horribly slow. It's a
different question whether the difference between the two
affects a program. Usually I'd say "no", but at one
point I profiled Wget, and found that a measurable and
non-negligible amount of time was lost calling sprintf()
in url.c. Replacing sprintf with inline calls to
strcpy() and long_to_string() made a difference.
@ -1439,6 +1494,13 @@ File `%s' already there, will not retrieve.\n"), u->local);
else
locf = opt.output_document;
/* In `-c' is used, check whether the file we're writing to
exists before we've done anything. If so, we'll refuse to
truncate it if the server doesn't support continued
downloads. */
if (opt.always_rest)
hstat.no_truncate = file_exists_p (locf);
/* Time? */
tms = time_str (NULL);
/* Get the new location (with or without the redirection). */
@ -1457,7 +1519,7 @@ File `%s' already there, will not retrieve.\n"), u->local);
continue;
break;
case HOSTERR: case CONREFUSED: case PROXERR: case AUTHFAILED:
case SSLERRCTXCREATE:
case SSLERRCTXCREATE: case CONTNOTSUPPORTED:
/* Fatal errors just return from the function. */
FREEHSTAT (hstat);
xfree (filename_plus_orig_suffix); /* must precede every return! */
@ -1471,7 +1533,7 @@ File `%s' already there, will not retrieve.\n"), u->local);
FREEHSTAT (hstat);
return err;
break;
case CONSSLERR:
case CONSSLERR:
/* Another fatal error. */
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET, _("Unable to establish SSL connection.\n"));

View File

@ -257,9 +257,10 @@ typedef enum
URLBADHOST, FOPENERR, FWRITEERR, HOK, HLEXC, HEOF,
HERR, RETROK, RECLEVELEXC, FTPACCDENIED, WRONGCODE,
FTPINVPASV, FTPNOPASV,
RETRFINISHED, READERR, TRYLIMEXC, URLBADPATTERN,
FILEBADFILE, RANGEERR, RETRBADPATTERN, RETNOTSUP,
ROBOTSOK, NOROBOTS, PROXERR, AUTHFAILED, QUOTEXC, WRITEFAILED,
CONTNOTSUPPORTED, RETRFINISHED, READERR, TRYLIMEXC,
URLBADPATTERN, FILEBADFILE, RANGEERR, RETRBADPATTERN,
RETNOTSUP, ROBOTSOK, NOROBOTS, PROXERR, AUTHFAILED,
QUOTEXC, WRITEFAILED,
SSLERRCERTFILE,SSLERRCERTKEY,SSLERRCTXCREATE
} uerr_t;