]> sjero.net Git - wget/blobdiff - src/ftp.c
Automated merge.
[wget] / src / ftp.c
index 9bc92a8945428c1da5721a1c1e08e24375e8d3a9..827e597e75890e6fa31622aa6aa70e146200889b 100644 (file)
--- a/src/ftp.c
+++ b/src/ftp.c
@@ -1,6 +1,6 @@
 /* File Transfer Protocol support.
    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-   2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+   2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 
 This file is part of GNU Wget.
 
@@ -74,6 +74,7 @@ typedef struct
   struct url *proxy;            /* FTWK-style proxy */
 } ccon;
 
+extern int numurls;
 
 /* Look for regexp "( *[0-9]+ *byte" (literal parenthesis) anywhere in
    the string S, and return the number converted to wgint, if found, 0
@@ -221,7 +222,7 @@ print_length (wgint size, wgint start, bool authoritative)
     logprintf (LOG_VERBOSE, " (%s)", human_readable (size));
   if (start > 0)
     {
-      if (start >= 1024)
+      if (size - start >= 1024)
         logprintf (LOG_VERBOSE, _(", %s (%s) remaining"),
                    number_to_static_string (size - start),
                    human_readable (size - start));
@@ -232,6 +233,8 @@ print_length (wgint size, wgint start, bool authoritative)
   logputs (LOG_VERBOSE, !authoritative ? _(" (unauthoritative)\n") : "\n");
 }
 
+static uerr_t ftp_get_listing (struct url *, ccon *, struct fileinfo **);
+
 /* Retrieves a file with denoted parameters through opening an FTP
    connection to the server.  It always closes the data connection,
    and closes the control connection in case of error.  */
@@ -305,7 +308,8 @@ getftp (struct url *u, wgint *len, wgint restval, ccon *con)
         con->csock = -1;
 
       /* Second: Login with proper USER/PASS sequence.  */
-      logprintf (LOG_VERBOSE, _("Logging in as %s ... "), escnonprint (user));
+      logprintf (LOG_VERBOSE, _("Logging in as %s ... "), 
+                 quotearg_style (escape_quoting_style, user));
       if (opt.server_response)
         logputs (LOG_ALWAYS, "\n");
       err = ftp_login (csock, logname, passwd);
@@ -680,9 +684,9 @@ Error in server response, closing control connection.\n"));
            }
 
           if (!opt.server_response)
-            logprintf (LOG_VERBOSE, "==> CWD (%d) %s ... ",
-             cwd_count, escnonprint (target));
-          err = ftp_cwd (csock, targ);
+            logprintf (LOG_VERBOSE, "==> CWD (%d) %s ... ", cwd_count,
+                       quotearg_style (escape_quoting_style, target));
+          err = ftp_cwd (csock, target);
           /* FTPRERR, WRITEFAILED, FTPNSFOD */
           switch (err)
             {
@@ -702,8 +706,8 @@ Error in server response, closing control connection.\n"));
               return err;
             case FTPNSFOD:
               logputs (LOG_VERBOSE, "\n");
-              logprintf (LOG_NOTQUIET, _("No such directory `%s'.\n\n"),
-                         escnonprint (u->dir));
+              logprintf (LOG_NOTQUIET, _("No such directory %s.\n\n"),
+                         quote (u->dir));
               fd_close (csock);
               con->csock = -1;
               return err;
@@ -730,7 +734,8 @@ Error in server response, closing control connection.\n"));
       if (opt.verbose)
         {
           if (!opt.server_response)
-            logprintf (LOG_VERBOSE, "==> SIZE %s ... ", escnonprint (u->file));
+            logprintf (LOG_VERBOSE, "==> SIZE %s ... ", 
+                       quotearg_style (escape_quoting_style, u->file));
         }
 
       err = ftp_size (csock, u->file, len);
@@ -918,12 +923,43 @@ Error in server response, closing control connection.\n"));
 
   if (cmd & DO_RETR)
     {
-      /* If we're in spider mode, don't really retrieve anything.  The
-         fact that we got to this point should be proof enough that
-         the file exists, vaguely akin to HTTP's concept of a "HEAD"
-         request.  */
+      /* If we're in spider mode, don't really retrieve anything except
+        the directory listing and verify whether the given "file" exists.  */
       if (opt.spider)
         {
+         bool exists = false;
+         uerr_t res;
+         struct fileinfo *f;
+         res = ftp_get_listing (u, con, &f);
+         /* Set the DO_RETR command flag again, because it gets unset when 
+            calling ftp_get_listing() and would otherwise cause an assertion 
+            failure earlier on when this function gets repeatedly called 
+            (e.g., when recursing).  */
+         con->cmd |= DO_RETR;
+         if (res == RETROK)
+           {
+             while (f) 
+               {
+                 if (!strcmp (f->name, u->file))
+                   {
+                     exists = true;
+                     break;
+                   }
+                 f = f->next;
+               }
+              if (exists)
+                {
+                  logputs (LOG_VERBOSE, "\n");
+                  logprintf (LOG_NOTQUIET, _("File %s exists.\n"),
+                             quote (u->file));
+                }
+             else
+                {
+                 logputs (LOG_VERBOSE, "\n");
+                 logprintf (LOG_NOTQUIET, _("No such file %s.\n"),
+                            quote (u->file));
+               }
+           }
           fd_close (csock);
           con->csock = -1;
           fd_close (dtsock);
@@ -937,7 +973,8 @@ Error in server response, closing control connection.\n"));
             {
               if (restval)
                 logputs (LOG_VERBOSE, "\n");
-              logprintf (LOG_VERBOSE, "==> RETR %s ... ", escnonprint (u->file));
+              logprintf (LOG_VERBOSE, "==> RETR %s ... ", 
+                         quotearg_style (escape_quoting_style, u->file));
             }
         }
 
@@ -965,8 +1002,8 @@ Error in server response, closing control connection.\n"));
           return err;
         case FTPNSFOD:
           logputs (LOG_VERBOSE, "\n");
-          logprintf (LOG_NOTQUIET, _("No such file `%s'.\n\n"),
-                     escnonprint (u->file));
+          logprintf (LOG_NOTQUIET, _("No such file %s.\n\n"),
+                     quote (u->file));
           fd_close (dtsock);
           fd_close (local_sock);
           return err;
@@ -1016,8 +1053,8 @@ Error in server response, closing control connection.\n"));
           return err;
         case FTPNSFOD:
           logputs (LOG_VERBOSE, "\n");
-          logprintf (LOG_NOTQUIET, _("No such file or directory `%s'.\n\n"),
-                     ".");
+          logprintf (LOG_NOTQUIET, _("No such file or directory %s.\n\n"),
+                     quote ("."));
           fd_close (dtsock);
           fd_close (local_sock);
           return err;
@@ -1053,7 +1090,7 @@ Error in server response, closing control connection.\n"));
       if (dtsock < 0)
         {
           logprintf (LOG_NOTQUIET, "accept: %s\n", strerror (errno));
-          return err;
+          return CONERROR;
         }
     }
 
@@ -1294,7 +1331,8 @@ Error in server response, closing control connection.\n"));
               char *p = strchr (line, '\0');
               while (p > line && (p[-1] == '\n' || p[-1] == '\r'))
                 *--p = '\0';
-              logprintf (LOG_ALWAYS, "%s\n", escnonprint (line));
+              logprintf (LOG_ALWAYS, "%s\n", 
+                         quotearg_style (escape_quoting_style, line));
               xfree (line);
             }
           fclose (fp);
@@ -1335,10 +1373,12 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
         locf = opt.output_document;
     }
 
-  if (opt.noclobber && file_exists_p (con->target))
+  /* If the output_document was given, then this check was already done and
+     the file didn't exist. Hence the !opt.output_document */
+  if (opt.noclobber && !opt.output_document && file_exists_p (con->target))
     {
       logprintf (LOG_VERBOSE,
-                 _("File `%s' already there; not retrieving.\n"), con->target);
+                 _("File %s already there; not retrieving.\n"), quote (con->target));
       /* If the file is there, we suppose it's retrieved OK.  */
       return RETROK;
     }
@@ -1405,8 +1445,8 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
           strcpy (tmp, "        ");
           if (count > 1)
             sprintf (tmp, _("(try:%2d)"), count);
-          logprintf (LOG_VERBOSE, "--%s--  %s\n  %s => `%s'\n",
-                     tms, hurl, tmp, locf);
+          logprintf (LOG_VERBOSE, "--%s--  %s\n  %s => %s\n",
+                     tms, hurl, tmp, quote (locf));
 #ifdef WINDOWS
           ws_changetitle (hurl);
 #endif
@@ -1474,8 +1514,17 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
           con->csock = -1;
         }
       if (!opt.spider)
-        logprintf (LOG_VERBOSE, _("%s (%s) - `%s' saved [%s]\n\n"),
-                   tms, tmrate, locf, number_to_static_string (len));
+        {
+          bool write_to_stdout = (opt.output_document && HYPHENP (opt.output_document));
+
+          logprintf (LOG_VERBOSE,
+                     write_to_stdout
+                     ? _("%s (%s) - written to stdout %s[%s]\n\n")
+                     : _("%s (%s) - %s saved [%s]\n\n"),
+                     tms, tmrate,
+                     write_to_stdout ? "" : quote (locf),
+                     number_to_static_string (len));
+        }
       if (!opt.verbose && !opt.quiet)
         {
           /* Need to hide the password from the URL.  The `if' is here
@@ -1495,7 +1544,7 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
                number of bytes and files downloaded. */
             {
               total_downloaded_bytes += len;
-              opt.numurls++;
+              numurls++;
             }
 
           /* Deletion of listing files is not controlled by --delete-after, but
@@ -1510,7 +1559,7 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
              for instance, may want to know how many bytes and files they've
              downloaded through it. */
           total_downloaded_bytes += len;
-          opt.numurls++;
+          numurls++;
 
           if (opt.delete_after)
             {
@@ -1558,23 +1607,28 @@ ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
   uf = url_file_name (u);
   lf = file_merge (uf, LIST_FILENAME);
   xfree (uf);
-  DEBUGP ((_("Using `%s' as listing tmp file.\n"), lf));
+  DEBUGP ((_("Using %s as listing tmp file.\n"), quote (lf)));
 
-  con->target = lf;
+  con->target = xstrdup (lf);
+  xfree (lf);
   err = ftp_loop_internal (u, NULL, con);
+  lf = xstrdup (con->target);
+  xfree (con->target);
   con->target = old_target;
 
   if (err == RETROK)
-    *f = ftp_parse_ls (lf, con->rs);
-  else
-    *f = NULL;
-  if (opt.remove_listing)
     {
-      if (unlink (lf))
-        logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
-      else
-        logprintf (LOG_VERBOSE, _("Removed `%s'.\n"), lf);
+      *f = ftp_parse_ls (lf, con->rs);
+      if (opt.remove_listing)
+        {
+          if (unlink (lf))
+            logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
+          else
+            logprintf (LOG_VERBOSE, _("Removed %s.\n"), quote (lf));
+        }
     }
+  else
+    *f = NULL;
   xfree (lf);
   con->cmd &= ~DO_LIST;
   return err;
@@ -1678,15 +1732,15 @@ ftp_retrieve_list (struct url *u, struct fileinfo *f, ccon *con)
                   /* Remote file is older, file sizes can be compared and
                      are both equal. */
                   logprintf (LOG_VERBOSE, _("\
-Remote file no newer than local file `%s' -- not retrieving.\n"), con->target);
+Remote file no newer than local file %s -- not retrieving.\n"), quote (con->target));
                   dlthis = false;
                 }
               else if (eq_size)
                 {
                   /* Remote file is newer or sizes cannot be matched */
                   logprintf (LOG_VERBOSE, _("\
-Remote file is newer than local file `%s' -- retrieving.\n\n"),
-                             con->target);
+Remote file is newer than local file %s -- retrieving.\n\n"),
+                             quote (con->target));
                 }
               else
                 {
@@ -1728,14 +1782,15 @@ The sizes do not match (local %s) -- retrieving.\n\n"),
                             {
                               logprintf (LOG_VERBOSE, _("\
 Already have correct symlink %s -> %s\n\n"),
-                                         con->target, escnonprint (f->linkto));
+                                         quote (con->target),
+                                         quote (f->linkto));
                               dlthis = false;
                               break;
                             }
                         }
                     }
                   logprintf (LOG_VERBOSE, _("Creating symlink %s -> %s\n"),
-                             con->target, escnonprint (f->linkto));
+                             quote (con->target), quote (f->linkto));
                   /* Unlink before creating symlink!  */
                   unlink (con->target);
                   if (symlink (f->linkto, con->target) == -1)
@@ -1744,8 +1799,8 @@ Already have correct symlink %s -> %s\n\n"),
                 } /* have f->linkto */
 #else  /* not HAVE_SYMLINK */
               logprintf (LOG_NOTQUIET,
-                         _("Symlinks not supported, skipping symlink `%s'.\n"),
-                         con->target);
+                         _("Symlinks not supported, skipping symlink %s.\n"),
+                         quote (con->target));
 #endif /* not HAVE_SYMLINK */
             }
           else                /* opt.retr_symlinks */
@@ -1756,8 +1811,8 @@ Already have correct symlink %s -> %s\n\n"),
           break;
         case FT_DIRECTORY:
           if (!opt.recursive)
-            logprintf (LOG_NOTQUIET, _("Skipping directory `%s'.\n"),
-                       escnonprint (f->name));
+            logprintf (LOG_NOTQUIET, _("Skipping directory %s.\n"),
+                       quote (f->name));
           break;
         case FT_PLAINFILE:
           /* Call the retrieve loop.  */
@@ -1766,7 +1821,7 @@ Already have correct symlink %s -> %s\n\n"),
           break;
         case FT_UNKNOWN:
           logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
-                     escnonprint (f->name));
+                     quote (f->name));
           break;
         }       /* switch */
 
@@ -1778,16 +1833,7 @@ Already have correct symlink %s -> %s\n\n"),
        * appropriate.  (Do the test once, and save the result.)
        */
 
-      /* #### This code repeats in http.c and ftp.c.  Move it to a
-         function!  */
-      actual_target = NULL;
-      if (opt.output_document)
-        {
-          if (output_stream_regular)
-            actual_target = opt.output_document;
-        }
-      else
-        actual_target = con->target;
+      set_local_file (&actual_target, con->target);
 
       /* If downloading a plain file, set valid (non-zero) permissions. */
       if (dlthis && (actual_target != NULL) && (f->type == FT_PLAINFILE))
@@ -1801,7 +1847,6 @@ Already have correct symlink %s -> %s\n\n"),
       /* Set the time-stamp information to the local file.  Symlinks
          are not to be stamped because it sets the stamp on the
          original.  :( */
-
       if (actual_target != NULL)
         {
           if (!(f->type == FT_SYMLINK && !opt.retr_symlinks)
@@ -1813,7 +1858,7 @@ Already have correct symlink %s -> %s\n\n"),
             }
           else if (f->tstamp == -1)
             logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"),
-            actual_target);
+                       actual_target);
         }
 
       xfree (con->target);
@@ -1885,8 +1930,8 @@ ftp_retrieve_dirs (struct url *u, struct fileinfo *f, ccon *con)
       if (!accdir (newdir))
         {
           logprintf (LOG_VERBOSE, _("\
-Not descending to `%s' as it is excluded/not-included.\n"),
-                     escnonprint (newdir));
+Not descending to %s as it is excluded/not-included.\n"),
+                     quote (newdir));
           continue;
         }
 
@@ -1950,8 +1995,8 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
         {
           if (f->type != FT_DIRECTORY && !acceptable (f->name))
             {
-              logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"),
-                         escnonprint (f->name));
+              logprintf (LOG_VERBOSE, _("Rejecting %s.\n"),
+                         quote (f->name));
               f = delelement (f, &start);
             }
           else
@@ -1964,8 +2009,8 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
     {
       if (has_insecure_name_p (f->name))
         {
-          logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"),
-                     escnonprint (f->name));
+          logprintf (LOG_VERBOSE, _("Rejecting %s.\n"),
+                     quote (f->name));
           f = delelement (f, &start);
         }
       else
@@ -1988,7 +2033,8 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
               if (matchres == -1)
                 {
                   logprintf (LOG_NOTQUIET, _("Error matching %s against %s: %s\n"),
-                             u->file, escnonprint (f->name), strerror (errno));
+                             u->file, quotearg_style (escape_quoting_style, f->name), 
+                             strerror (errno));
                   break;
                 }
               if (matchres == FNM_NOMATCH)
@@ -2028,8 +2074,8 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
           /* No luck.  */
           /* #### This message SUCKS.  We should see what was the
              reason that nothing was retrieved.  */
-          logprintf (LOG_VERBOSE, _("No matches on pattern `%s'.\n"),
-                     escnonprint (u->file));
+          logprintf (LOG_VERBOSE, _("No matches on pattern %s.\n"),
+                     quote (u->file));
         }
       else if (action == GLOB_GETONE) /* GLOB_GETONE or GLOB_GETALL */
         {
@@ -2099,13 +2145,13 @@ ftp_loop (struct url *u, int *dt, struct url *proxy, bool recursive, bool glob)
                       else
                         sz = -1;
                       logprintf (LOG_NOTQUIET,
-                                 _("Wrote HTML-ized index to `%s' [%s].\n"),
-                                 filename, number_to_static_string (sz));
+                                 _("Wrote HTML-ized index to %s [%s].\n"),
+                                 quote (filename), number_to_static_string (sz));
                     }
                   else
                     logprintf (LOG_NOTQUIET,
-                               _("Wrote HTML-ized index to `%s'.\n"),
-                               filename);
+                               _("Wrote HTML-ized index to %s.\n"),
+                               quote (filename));
                 }
               xfree (filename);
             }