]> sjero.net Git - wget/blobdiff - src/ftp-basic.c
mass change: update copyright years.
[wget] / src / ftp-basic.c
index dd3ee3afa710c186c057f46b01ac6c58cb89f308..178fdfea4fa08d94afa36fb85a1b864909b63689 100644 (file)
@@ -1,6 +1,7 @@
 /* Basic FTP routines.
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-   2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+   2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
+   Inc.
 
 This file is part of GNU Wget.
 
@@ -36,9 +37,7 @@ as that of the covered work.  */
 #include <errno.h>
 
 #include <string.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
+#include <unistd.h>
 #include "utils.h"
 #include "connect.h"
 #include "host.h"
@@ -68,7 +67,7 @@ ftp_response (int fd, char **ret_line)
         return FTPRERR;
 
       /* Strip trailing CRLF before printing the line, so that
-         escnonprint doesn't include bogus \012 and \015. */
+         quotting doesn't include bogus \012 and \015. */
       p = strchr (line, '\0');
       if (p > line && p[-1] == '\n')
         *--p = '\0';
@@ -76,9 +75,10 @@ ftp_response (int fd, char **ret_line)
         *--p = '\0';
 
       if (opt.server_response)
-        logprintf (LOG_NOTQUIET, "%s\n", escnonprint (line));
+        logprintf (LOG_NOTQUIET, "%s\n",
+                   quotearg_style (escape_quoting_style, line));
       else
-        DEBUGP (("%s\n", escnonprint (line)));
+        DEBUGP (("%s\n", quotearg_style (escape_quoting_style, line)));
 
       /* The last line of output is the one that begins with "ddd ". */
       if (c_isdigit (line[0]) && c_isdigit (line[1]) && c_isdigit (line[2])
@@ -116,7 +116,8 @@ ftp_request (const char *command, const char *value)
             if (*p == '\r' || *p == '\n')
               *p = ' ';
           DEBUGP (("\nDetected newlines in %s \"%s\"; changing to %s \"%s\"\n",
-                   command, escnonprint (value), command, escnonprint (defanged)));
+                   command, quotearg_style (escape_quoting_style, value),
+                   command, quotearg_style (escape_quoting_style, defanged)));
           /* Make VALUE point to the defanged copy of the string. */
           value = defanged;
         }
@@ -187,7 +188,7 @@ ftp_login (int csock, const char *acc, const char *pass)
       "331 s/key ",
       "331 opiekey "
     };
-    int i;
+    size_t i;
     const char *seed = NULL;
 
     for (i = 0; i < countof (skey_head); i++)
@@ -244,7 +245,7 @@ ftp_login (int csock, const char *acc, const char *pass)
 }
 
 static void
-ip_address_to_port_repr (const ip_address *addr, int port, char *buf, 
+ip_address_to_port_repr (const ip_address *addr, int port, char *buf,
                          size_t buflen)
 {
   unsigned char *ptr;
@@ -320,7 +321,7 @@ ftp_port (int csock, int *local_sock)
 
 #ifdef ENABLE_IPV6
 static void
-ip_address_to_lprt_repr (const ip_address *addr, int port, char *buf, 
+ip_address_to_lprt_repr (const ip_address *addr, int port, char *buf,
                          size_t buflen)
 {
   unsigned char *ptr = IP_INADDR_DATA (addr);
@@ -329,18 +330,18 @@ ip_address_to_lprt_repr (const ip_address *addr, int port, char *buf,
   assert (buflen >= 21 * 4);
 
   /* Construct the argument of LPRT (of the form af,n,h1,h2,...,hn,p1,p2). */
-  switch (addr->family) 
+  switch (addr->family)
     {
-    case AF_INET: 
-      snprintf (buf, buflen, "%d,%d,%d,%d,%d,%d,%d,%d,%d", 4, 4, 
+    case AF_INET:
+      snprintf (buf, buflen, "%d,%d,%d,%d,%d,%d,%d,%d,%d", 4, 4,
                 ptr[0], ptr[1], ptr[2], ptr[3], 2,
                 (port & 0xff00) >> 8, port & 0xff);
       break;
-    case AF_INET6: 
+    case AF_INET6:
       snprintf (buf, buflen,
                 "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
                 6, 16,
-                ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7], 
+                ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7],
                 ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15],
                 2, (port & 0xff00) >> 8, port & 0xff);
       break;
@@ -408,15 +409,15 @@ ftp_lprt (int csock, int *local_sock)
 }
 
 static void
-ip_address_to_eprt_repr (const ip_address *addr, int port, char *buf, 
+ip_address_to_eprt_repr (const ip_address *addr, int port, char *buf,
                          size_t buflen)
 {
   int afnum;
 
-  /* buf must contain the argument of EPRT (of the form |af|addr|port|). 
-   * 4 chars for the | separators, INET6_ADDRSTRLEN chars for addr  
+  /* buf must contain the argument of EPRT (of the form |af|addr|port|).
+   * 4 chars for the | separators, INET6_ADDRSTRLEN chars for addr
    * 1 char for af (1-2) and 5 chars for port (0-65535) */
-  assert (buflen >= 4 + INET6_ADDRSTRLEN + 1 + 5); 
+  assert (buflen >= 4 + INET6_ADDRSTRLEN + 1 + 5);
 
   /* Construct the argument of EPRT (of the form |af|addr|port|). */
   afnum = (addr->family == AF_INET ? 1 : 2);
@@ -435,8 +436,8 @@ ftp_eprt (int csock, int *local_sock)
   ip_address addr;
   int nwritten;
   int port;
-  /* Must contain the argument of EPRT (of the form |af|addr|port|). 
-   * 4 chars for the | separators, INET6_ADDRSTRLEN chars for addr  
+  /* Must contain the argument of EPRT (of the form |af|addr|port|).
+   * 4 chars for the | separators, INET6_ADDRSTRLEN chars for addr
    * 1 char for af (1-2) and 5 chars for port (0-65535) */
   char bytes[4 + INET6_ADDRSTRLEN + 1 + 5 + 1];
 
@@ -585,7 +586,7 @@ ftp_lpsv (int csock, ip_address *addr, int *port)
     {
       xfree (respline);
       return FTPNOPASV;
-    }  
+    }
 
   /* Parse the response.  */
   s = respline;
@@ -748,22 +749,19 @@ ftp_epsv (int csock, ip_address *ip, int *port)
     {
       xfree (respline);
       return FTPNOPASV;
-    }  
+    }
 
   assert (respline != NULL);
 
   DEBUGP(("respline is %s\n", respline));
 
-  /* Parse the response.  */
-  s = respline;
-
   /* Skip the useless stuff and get what's inside the parentheses */
   start = strchr (respline, '(');
   if (start == NULL)
     {
       xfree (respline);
       return FTPINVPASV;
-    }  
+    }
 
   /* Skip the first two void fields */
   s = start + 1;
@@ -772,26 +770,26 @@ ftp_epsv (int csock, ip_address *ip, int *port)
     {
       xfree (respline);
       return FTPINVPASV;
-    }  
+    }
 
   for (i = 0; i < 2; i++)
     {
-      if (*s++ != delim) 
+      if (*s++ != delim)
         {
           xfree (respline);
         return FTPINVPASV;
-        }  
+        }
     }
 
   /* Finally, get the port number */
-  tport = 0; 
-  for (i = 1; c_isdigit (*s); s++) 
+  tport = 0;
+  for (i = 1; c_isdigit (*s); s++)
     {
       if (i > 5)
         {
           xfree (respline);
           return FTPINVPASV;
-        }  
+        }
       tport = (*s - '0') + 10 * tport;
     }
 
@@ -800,13 +798,13 @@ ftp_epsv (int csock, ip_address *ip, int *port)
     {
       xfree (respline);
       return FTPINVPASV;
-    }  
+    }
 
-  if (*s++ != ')')
+  if (*s != ')')
     {
       xfree (respline);
       return FTPINVPASV;
-    }  
+    }
 
   *port = tport;
 
@@ -956,17 +954,24 @@ ftp_retr (int csock, const char *file)
 /* Sends the LIST command to the server.  If FILE is NULL, send just
    `LIST' (no space).  */
 uerr_t
-ftp_list (int csock, const char *file)
+ftp_list (int csock, const char *file, enum stype rs)
 {
   char *request, *respline;
   int nwritten;
   uerr_t err;
   bool ok = false;
-  int i = 0;
+  size_t i = 0;
   /* Try `LIST -a' first and revert to `LIST' in case of failure.  */
-  const char *list_commands[] = { "LIST -a", 
+  const char *list_commands[] = { "LIST -a",
                                   "LIST" };
 
+  /* 2008-01-29  SMS.  For a VMS FTP server, where "LIST -a" may not
+     fail, but will never do what is desired here, skip directly to the
+     simple "LIST" command (assumed to be the last one in the list).
+  */
+  if (rs == ST_VMS)
+    i = countof (list_commands)- 1;
+
   do {
     /* Send request.  */
     request = ftp_request (list_commands[i], file);
@@ -990,7 +995,7 @@ ftp_list (int csock, const char *file)
             err = FTPOK;
             ok = true;
           }
-        else 
+        else
           {
             err = FTPRERR;
           }
@@ -998,7 +1003,7 @@ ftp_list (int csock, const char *file)
       }
     ++i;
   } while (i < countof (list_commands) && !ok);
-  
+
   return err;
 }
 
@@ -1133,9 +1138,9 @@ ftp_size (int csock, const char *file, wgint *size)
     }
   if (*respline == '5')
     {
-      /* 
+      /*
        * Probably means SIZE isn't supported on this server.
-       * Error is nonfatal since SIZE isn't in RFC 959 
+       * Error is nonfatal since SIZE isn't in RFC 959
        */
       xfree (respline);
       *size = 0;
@@ -1146,7 +1151,7 @@ ftp_size (int csock, const char *file, wgint *size)
   *size = str_to_wgint (respline + 4, NULL, 10);
   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