]> sjero.net Git - wget/blobdiff - src/ftp.c
Fixed bug #23238: --no-clobber doesn't work with -O flag
[wget] / src / ftp.c
index 2f5ecd157d88fd449bbab1d3eff848541562a8a0..e6163880ec0c7996cea37c4d2eddeee0e1f3a938 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 Free Software Foundation, Inc.
+   2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 This file is part of GNU Wget.
 
@@ -17,17 +17,18 @@ GNU General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with Wget.  If not, see <http://www.gnu.org/licenses/>.
 
-In addition, as a special exception, the Free Software Foundation
-gives permission to link the code of its release of Wget with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables.  You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL".  If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so.  If you do not wish to do
-so, delete this exception statement from your version.  */
+Additional permission under GNU GPL version 3 section 7
 
-#include <config.h>
+If you modify this program, or any covered work, by linking or
+combining it with the OpenSSL project's OpenSSL library (or a
+modified version of that library), containing parts covered by the
+terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
+grants you additional permission to convey the resulting work.
+Corresponding Source for a non-source form of such a combination
+shall include the source code for the parts of OpenSSL used as well
+as that of the covered work.  */
+
+#include "wget.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -39,7 +40,6 @@ so, delete this exception statement from your version.  */
 #include <errno.h>
 #include <time.h>
 
-#include "wget.h"
 #include "utils.h"
 #include "url.h"
 #include "retr.h"
@@ -51,7 +51,11 @@ so, delete this exception statement from your version.  */
 #include "recur.h"              /* for INFINITE_RECURSION */
 
 /* File where the "ls -al" listing will be saved.  */
+#ifdef MSDOS
+#define LIST_FILENAME "_listing"
+#else
 #define LIST_FILENAME ".listing"
+#endif
 
 typedef struct
 {
@@ -84,11 +88,11 @@ ftp_expected_bytes (const char *s)
       res = str_to_wgint (s, (char **) &s, 10);
       if (!*s)
         return 0;
-      while (*s && ISSPACE (*s))
+      while (*s && c_isspace (*s))
         ++s;
       if (!*s)
         return 0;
-      if (TOLOWER (*s) != 'b')
+      if (c_tolower (*s) != 'b')
         continue;
       if (strncasecmp (s, "byte", 4))
         continue;
@@ -492,7 +496,7 @@ Error in server response, closing control connection.\n"));
 
           if (target[0] != '/'
               && !(con->rs != ST_UNIX
-                   && ISALPHA (target[0])
+                   && c_isalpha (target[0])
                    && target[1] == ':')
               && con->rs != ST_OS400)
             {
@@ -914,7 +918,7 @@ Error in server response, closing control connection.\n"));
       if (opt.backups)
         rotate_backups (con->target);
 
-      if (restval)
+      if (restval && !(con->cmd & DO_LIST))
         fp = fopen (con->target, "ab");
       else if (opt.noclobber || opt.always_rest || opt.timestamping || opt.dirstruct
                || opt.output_document)
@@ -968,7 +972,7 @@ Error in server response, closing control connection.\n"));
                       expected_bytes ? expected_bytes - restval : 0,
                       restval, &rd_size, len, &con->dltime, flags);
 
-  tms = time_str (time (NULL));
+  tms = datetime_str (time (NULL));
   tmrate = retr_rate (rd_size, con->dltime);
   total_download_time += con->dltime;
 
@@ -1087,7 +1091,9 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
   if (!con->target)
     con->target = url_file_name (u);
 
-  if (opt.noclobber && file_exists_p (con->target))
+  /* If the output_document was given, then this check was already done and
+     the file doesn'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);
@@ -1137,7 +1143,9 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
         }
 
       /* Decide whether or not to restart.  */
-      if (opt.always_rest
+      if (con->cmd & DO_LIST)
+        restval = 0;
+      else if (opt.always_rest
           && stat (locf, &st) == 0
           && S_ISREG (st.st_mode))
         /* When -c is used, continue from on-disk size.  (Can't use
@@ -1150,7 +1158,7 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
         restval = 0;
 
       /* Get the current time string.  */
-      tms = time_str (time (NULL));
+      tms = datetime_str (time (NULL));
       /* Print fetch message, if opt.verbose.  */
       if (opt.verbose)
         {
@@ -1214,7 +1222,7 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
           /* Not as great.  */
           abort ();
         }
-      tms = time_str (time (NULL));
+      tms = datetime_str (time (NULL));
       if (!opt.spider)
         tmrate = retr_rate (len - restval, con->dltime);
 
@@ -1319,16 +1327,18 @@ ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
   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"), lf);
+        }
     }
+  else
+    *f = NULL;
   xfree (lf);
   con->cmd &= ~DO_LIST;
   return err;
@@ -1712,31 +1722,47 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
     }
   /* Now weed out the files that do not match our globbing pattern.
      If we are dealing with a globbing pattern, that is.  */
-  if (*u->file && (action == GLOB_GLOBALL || action == GLOB_GETONE))
+  if (*u->file)
     {
-      int (*matcher) (const char *, const char *, int)
-        = opt.ignore_case ? fnmatch_nocase : fnmatch;
-      int matchres = 0;
-
-      f = start;
-      while (f)
+      if (action == GLOB_GLOBALL)
         {
-          matchres = matcher (u->file, f->name, 0);
+          int (*matcher) (const char *, const char *, int)
+            = opt.ignore_case ? fnmatch_nocase : fnmatch;
+          int matchres = 0;
+
+          f = start;
+          while (f)
+            {
+              matchres = matcher (u->file, f->name, 0);
+              if (matchres == -1)
+                {
+                  logprintf (LOG_NOTQUIET, _("Error matching %s against %s: %s\n"),
+                             u->file, escnonprint (f->name), strerror (errno));
+                  break;
+                }
+              if (matchres == FNM_NOMATCH)
+                f = delelement (f, &start); /* delete the element from the list */
+              else
+                f = f->next;        /* leave the element in the list */
+            }
           if (matchres == -1)
             {
-              logprintf (LOG_NOTQUIET, "%s: %s\n", con->target,
-                         strerror (errno));
-              break;
+              freefileinfo (start);
+              return RETRBADPATTERN;
             }
-          if (matchres == FNM_NOMATCH)
-            f = delelement (f, &start); /* delete the element from the list */
-          else
-            f = f->next;        /* leave the element in the list */
         }
-      if (matchres == -1)
+      else if (action == GLOB_GETONE)
         {
-          freefileinfo (start);
-          return RETRBADPATTERN;
+          int (*cmp) (const char *, const char *)
+            = opt.ignore_case ? strcasecmp : strcmp;
+          f = start;
+          while (f)
+            {
+              if (0 != cmp(u->file, f->name))
+                f = delelement (f, &start);
+              else
+                f = f->next;
+            }
         }
     }
   if (start)
@@ -1744,7 +1770,7 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
       /* Just get everything.  */
       ftp_retrieve_list (u, start, con);
     }
-  else if (!start)
+  else
     {
       if (action == GLOB_GLOBALL)
         {