On 17 Nov 2001, at 14:24, Hrvoje Niksic wrote:

> Ferenc VERES <[EMAIL PROTECTED]> writes:
> 
> > My download stopped, then next day I continued with -c, from 34%.
> > At the end I saw: 134% downloaded, in end of the lines ;-) (it was
> > FTP:// transfer, a 680MB iso image)
> > 
> > GNU Wget
> > 1.5.3
> 
> Try it with a later version.  I believe that this bug has been fixed
> in most of its variations.

That stuff only works for recursive transfers, not when resuming
transfer of a single file. 

For a recursive resume, wget knows what size the file is supposed
to be based on a previous directory listing, and can therefore
compensate for the two different ways in which a server can report
the size of a REST transfer. However, when resuming transfer of a
single file, wget currently has no idea what the size of the file
is supposed to be and assumes that the size reported by the server
for a REST transfer is the total size of the file. If the server
actually reports the remaining size, the transfer log will show
incorrect percentages.

Dave Turner wrote a patch back in the middle of August which I
modified slightly. The patch attempts to use the SIZE command which
is commonly supported by servers, but not mentioned in RFC959. I
suppose an alternative would be to do a directory listing for the
file. See these messages:

<http://www.mail-archive.com/wget@sunsite.dk/msg01463.html>
<http://www.mail-archive.com/wget@sunsite.dk/msg01468.html>
<http://www.mail-archive.com/wget@sunsite.dk/msg01469.html>
<http://www.mail-archive.com/wget@sunsite.dk/msg01481.html>
<http://www.mail-archive.com/wget@sunsite.dk/msg01480.html>

The patch in msg01481 (my modified version) still applies okay
against the current CVS, but I have recreated it against the
current revisions in the repository below.

Here is the ChangeLog entry from August (you may wish to change the
date):


2001-08-21  Dave Turner <[EMAIL PROTECTED]>

        * ftp-basic.c (ftp_size): New function to send non-standard SIZE
          command to server to request file size.
        * ftp.h (ftp_size): Export it.
        * ftp.c (getftp): Use new ftp_size function if restoring
          transfer of a file with unknown size.

And here is the patch against the current repository:

Index: src/ftp-basic.c
===================================================================
RCS file: /pack/anoncvs/wget/src/ftp-basic.c,v
retrieving revision 1.10
diff -u -r1.10 ftp-basic.c
--- src/ftp-basic.c     2001/05/27 19:34:57     1.10
+++ src/ftp-basic.c     2001/11/20 17:01:32
@@ -21,6 +21,8 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <errno.h>
+
 #ifdef HAVE_STRING_H
 # include <string.h>
 #else
@@ -626,6 +628,63 @@
   FREE_MAYBE (*pwd);
 
   *pwd = xstrdup (request);
+
+  xfree (respline);
+  /* All OK.  */
+  return FTPOK;
+}
+/* Sends the SIZE command to the server, and returns the value in 'size'.
+ * If an error occurs, size is set to zero. */
+uerr_t
+ftp_size (struct rbuf *rbuf, const char *file, long int *size)
+{
+  char *request, *respline;
+  int nwritten;
+  uerr_t err;
+
+  /* Send PWD request.  */
+  request = ftp_request ("SIZE", file);
+  nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+  if (nwritten < 0)
+    {
+      xfree (request);
+      *size = 0;
+      return WRITEFAILED;
+    }
+  xfree (request);
+  /* Get appropriate response.  */
+  err = ftp_response (rbuf, &respline);
+  if (err != FTPOK)
+    {
+      xfree (respline);
+      *size = 0;
+      return err;
+    }
+  if (*respline == '5')
+    {
+      /* 
+       * Probably means SIZE isn't supported on this server.
+       * Error is nonfatal since SIZE isn't in RFC 959 
+       */
+      xfree (respline);
+      *size = 0;
+      return FTPOK;
+    }
+
+  errno = 0;
+  *size = strtol (respline + 4, NULL, 0);
+  if (errno) 
+    {
+      /* 
+       * Couldn't parse the response for some reason.  On the (few)
+       * tests I've done, the response is 213 <SIZE> with nothing else -
+       * maybe something a bit more resilient is necessary.  It's not a
+       * fatal error, however.
+       */
+      xfree (respline);
+      *size = 0;
+      return FTPOK;
+    }
 
   xfree (respline);
   /* All OK.  */
Index: src/ftp.c
===================================================================
RCS file: /pack/anoncvs/wget/src/ftp.c,v
retrieving revision 1.44
diff -u -r1.44 ftp.c
--- src/ftp.c   2001/11/16 19:38:03     1.44
+++ src/ftp.c   2001/11/20 17:01:36
@@ -462,6 +462,38 @@
   else /* do not CWD */
     logputs (LOG_VERBOSE, _("==> CWD not required.\n"));
 
+  if ((cmd & DO_RETR) && restval && *len == 0)
+    {
+      if (opt.verbose)
+       {
+          if (!opt.server_response)
+           logprintf (LOG_VERBOSE, "==> SIZE %s ... ", u->file);
+       }
+
+      err = ftp_size(&con->rbuf, u->file, len);
+      /* FTPRERR */
+      switch (err)
+       {
+       case FTPRERR:
+       case FTPSRVERR :
+         logputs (LOG_VERBOSE, "\n");
+         logputs (LOG_NOTQUIET, _("\
+Error in server response, closing control connection.\n"));
+         CLOSE (csock);
+         rbuf_uninitialize (&con->rbuf);
+         return err;
+         break;
+       case FTPOK:
+         /* Everything is OK.  */
+         break;
+       default:
+         abort ();
+         break;
+       }
+       if (!opt.server_response)
+         logputs (LOG_VERBOSE, _("done.\n"));
+    }
+
   /* If anything is to be retrieved, PORT (or PASV) must be sent.  */
   if (cmd & (DO_LIST | DO_RETR))
     {
Index: src/ftp.h
===================================================================
RCS file: /pack/anoncvs/wget/src/ftp.h,v
retrieving revision 1.9
diff -u -r1.9 ftp.h
--- src/ftp.h   2001/06/09 17:44:07     1.9
+++ src/ftp.h   2001/11/20 17:01:36
@@ -44,6 +44,7 @@
 uerr_t ftp_list PARAMS ((struct rbuf *, const char *));
 uerr_t ftp_syst PARAMS ((struct rbuf *, enum stype *));
 uerr_t ftp_pwd PARAMS ((struct rbuf *, char **));
+uerr_t ftp_size PARAMS ((struct rbuf *, const char *, long int *));
 
 struct urlinfo;
 

Reply via email to