]> sjero.net Git - wget/blobdiff - src/ftp.c
[svn] Move fnmatch() to cmpt.c and don't use it under GNU libc.
[wget] / src / ftp.c
index 966b90b56faa3227a3e54dbdf106ffedfcbba9cd..5061d9cff52e87fee4531a14bd1ce0c7aaf69979 100644 (file)
--- a/src/ftp.c
+++ b/src/ftp.c
@@ -52,8 +52,8 @@ so, delete this exception statement from your version.  */
 #include "ftp.h"
 #include "connect.h"
 #include "host.h"
-#include "fnmatch.h"
 #include "netrc.h"
+#include "convert.h"           /* for downloaded_file */
 
 #ifndef errno
 extern int errno;
@@ -397,11 +397,19 @@ Error in server response, closing control connection.\n"));
 
             A relative directory is one that does not begin with '/'
             and, on non-Unix OS'es, one that doesn't begin with
-            "<letter>:".  */
+            "[a-z]:".
+
+            This is not done for OS400, which doesn't use
+            "/"-delimited directories, nor does it support directory
+            hierarchies.  "CWD foo" followed by "CWD bar" leaves us
+            in "bar", not in "foo/bar", as would be customary
+            elsewhere.  */
 
          if (target[0] != '/'
              && !(con->rs != ST_UNIX
-                  && ISALPHA (target[0]) && target[1] == ':'))
+                  && ISALPHA (target[0])
+                  && target[1] == ':')
+             && con->rs != ST_OS400)
            {
              int idlen = strlen (con->id);
              char *ntarget, *p;
@@ -818,6 +826,9 @@ Error in server response, closing control connection.\n"));
       expected_bytes = ftp_expected_bytes (ftp_last_respline);
     } /* cmd & DO_LIST */
 
+  if (!(cmd & (DO_LIST | DO_RETR)) || (opt.spider && !(cmd & DO_LIST)))
+    return RETRFINISHED;
+
   /* Some FTP servers return the total length of file after REST
      command, others just return the remaining size. */
   if (*len && restval && expected_bytes
@@ -828,9 +839,6 @@ Error in server response, closing control connection.\n"));
     }
 
   /* If no transmission was required, then everything is OK.  */
-  if (!(cmd & (DO_LIST | DO_RETR)))
-    return RETRFINISHED;
-
   if (!pasv_mode_open)  /* we are not using pasive mode so we need
                              to accept */
     {
@@ -1020,7 +1028,8 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
 {
   int count, orig_lp;
   long restval, len;
-  char *tms, *tmrate, *locf;
+  char *tms, *locf;
+  char *tmrate = NULL;
   uerr_t err;
   struct stat st;
 
@@ -1153,19 +1162,21 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
        }
       /* Time?  */
       tms = time_str (NULL);
-      tmrate = retr_rate (len - restval, con->dltime, 0);
+      if (!opt.spider)
+        tmrate = retr_rate (len - restval, con->dltime, 0);
 
       /* If we get out of the switch above without continue'ing, we've
         successfully downloaded a file.  Remember this fact. */
-      downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
+      downloaded_file (FILE_DOWNLOADED_NORMALLY, locf);
 
       if (con->st & ON_YOUR_OWN)
        {
          CLOSE (RBUF_FD (&con->rbuf));
          rbuf_uninitialize (&con->rbuf);
        }
-      logprintf (LOG_VERBOSE, _("%s (%s) - `%s' saved [%ld]\n\n"),
-                tms, tmrate, locf, len);
+      if (!opt.spider)
+        logprintf (LOG_VERBOSE, _("%s (%s) - `%s' saved [%ld]\n\n"),
+                  tms, tmrate, locf, len);
       if (!opt.verbose && !opt.quiet)
        {
          /* Need to hide the password from the URL.  The `if' is here
@@ -1192,7 +1203,7 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
             by the more specific option --dont-remove-listing, and the code
             to do this deletion is in another function. */
        }
-      else
+      else if (!opt.spider)
        /* This is not a directory listing file. */
        {
          /* Unlike directory listing files, don't pretend normal files weren't
@@ -1581,6 +1592,18 @@ Not descending to `%s' as it is excluded/not-included.\n"), newdir);
     return RETROK;
 }
 
+/* Return non-zero if S has a leading '/'  or contains '../' */
+static int
+has_insecure_name_p (const char *s)
+{
+  if (*s == '/')
+    return 1;
+
+  if (strstr(s, "../") != 0)
+    return 1;
+
+  return 0;
+}
 
 /* A near-top-level function to retrieve the files in a directory.
    The function calls ftp_get_listing, to get a linked list of files.
@@ -1622,7 +1645,7 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
   f = orig;
   while (f)
     {
-      if (has_insecure_name_p(f->name))
+      if (has_insecure_name_p (f->name))
        {
          logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"), f->name);
          f = delelement (f, &start);
@@ -1718,7 +1741,7 @@ ftp_loop (struct url *u, int *dt, struct url *proxy)
 
       if (res == RETROK)
        {
-         if (opt.htmlify)
+         if (opt.htmlify && !opt.spider)
            {
              char *filename = (opt.output_document
                                ? xstrdup (opt.output_document)