]> sjero.net Git - wget/blobdiff - src/ftp-basic.c
Automated merge.
[wget] / src / ftp-basic.c
index 9df26849e5d3d010967a240deae0efe084735916..0e11a8d3353a66d9385373dd47ea81be0e6690ad 100644 (file)
@@ -1,6 +1,6 @@
 /* Basic FTP routines.
    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 <assert.h>
 #include <stdio.h>
@@ -38,8 +39,6 @@ so, delete this exception statement from your version.  */
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif
-
-#include "wget.h"
 #include "utils.h"
 #include "connect.h"
 #include "host.h"
@@ -69,7 +68,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';
@@ -77,12 +76,13 @@ 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 (ISDIGIT (line[0]) && ISDIGIT (line[1]) && ISDIGIT (line[2])
+      if (c_isdigit (line[0]) && c_isdigit (line[1]) && c_isdigit (line[2])
           && line[3] == ' ')
         {
           strncpy (ftp_last_respline, line, sizeof (ftp_last_respline));
@@ -117,7 +117,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;
         }
@@ -188,7 +189,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++)
@@ -205,7 +206,7 @@ ftp_login (int csock, const char *acc, const char *pass)
         int skey_sequence = 0;
 
         /* Extract the sequence from SEED.  */
-        for (; ISDIGIT (*seed); seed++)
+        for (; c_isdigit (*seed); seed++)
           skey_sequence = 10 * skey_sequence + *seed - '0';
         if (*seed == ' ')
           ++seed;
@@ -521,14 +522,14 @@ ftp_pasv (int csock, ip_address *addr, int *port)
     }
   /* Parse the request.  */
   s = respline;
-  for (s += 4; *s && !ISDIGIT (*s); s++)
+  for (s += 4; *s && !c_isdigit (*s); s++)
     ;
   if (!*s)
     return FTPINVPASV;
   for (i = 0; i < 6; i++)
     {
       tmp[i] = 0;
-      for (; ISDIGIT (*s); s++)
+      for (; c_isdigit (*s); s++)
         tmp[i] = (*s - '0') + 10 * tmp[i];
       if (*s == ',')
         s++;
@@ -590,14 +591,14 @@ ftp_lpsv (int csock, ip_address *addr, int *port)
 
   /* Parse the response.  */
   s = respline;
-  for (s += 4; *s && !ISDIGIT (*s); s++)
+  for (s += 4; *s && !c_isdigit (*s); s++)
     ;
   if (!*s)
     return FTPINVPASV;
 
   /* First, get the address family */
   af = 0;
-  for (; ISDIGIT (*s); s++)
+  for (; c_isdigit (*s); s++)
     af = (*s - '0') + 10 * af;
 
   if (af != 4 && af != 6)
@@ -614,7 +615,7 @@ ftp_lpsv (int csock, ip_address *addr, int *port)
 
   /* Then, get the address length */
   addrlen = 0;
-  for (; ISDIGIT (*s); s++)
+  for (; c_isdigit (*s); s++)
     addrlen = (*s - '0') + 10 * addrlen;
 
   if (!*s || *s++ != ',')
@@ -640,7 +641,7 @@ ftp_lpsv (int csock, ip_address *addr, int *port)
   for (i = 0; i < addrlen; i++)
     {
       tmp[i] = 0;
-      for (; ISDIGIT (*s); s++)
+      for (; c_isdigit (*s); s++)
         tmp[i] = (*s - '0') + 10 * tmp[i];
       if (*s == ',')
         s++;
@@ -653,7 +654,7 @@ ftp_lpsv (int csock, ip_address *addr, int *port)
 
   /* Now, get the port length */
   portlen = 0;
-  for (; ISDIGIT (*s); s++)
+  for (; c_isdigit (*s); s++)
     portlen = (*s - '0') + 10 * portlen;
 
   if (!*s || *s++ != ',')
@@ -670,7 +671,7 @@ ftp_lpsv (int csock, ip_address *addr, int *port)
 
   /* Finally, we get the port number */
   tmpprt[0] = 0;
-  for (; ISDIGIT (*s); s++)
+  for (; c_isdigit (*s); s++)
     tmpprt[0] = (*s - '0') + 10 * tmpprt[0];
 
   if (!*s || *s++ != ',')
@@ -680,7 +681,7 @@ ftp_lpsv (int csock, ip_address *addr, int *port)
     }
 
   tmpprt[1] = 0;
-  for (; ISDIGIT (*s); s++)
+  for (; c_isdigit (*s); s++)
     tmpprt[1] = (*s - '0') + 10 * tmpprt[1];
 
   assert (s != NULL);
@@ -786,7 +787,7 @@ ftp_epsv (int csock, ip_address *ip, int *port)
 
   /* Finally, get the port number */
   tport = 0; 
-  for (i = 1; ISDIGIT (*s); s++) 
+  for (i = 1; c_isdigit (*s); s++) 
     {
       if (i > 5)
         {
@@ -888,6 +889,42 @@ ftp_cwd (int csock, const char *dir)
   return FTPOK;
 }
 
+/* Sends DELE command to the FTP server.  */
+uerr_t
+ftp_dele (int csock, const char *file)
+{
+  char *request, *respline;
+  int nwritten;
+  uerr_t err;
+
+  /* Send DELE request.  */
+  request = ftp_request ("DELE", file);
+  nwritten = fd_write (csock, request, strlen (request), -1.0);
+  if (nwritten < 0)
+    {
+      xfree (request);
+      return WRITEFAILED;
+    }
+  xfree (request);
+  /* Get appropriate response.  */
+  err = ftp_response (csock, &respline);
+  if (err != FTPOK)
+    return err;                 /* Return with early bad status. */
+
+  /* All OK, so far.  */
+  if (*respline == '5')
+    {
+      err = FTPNSFOD;           /* Permanent Negative Completion. */
+    }
+  else if (*respline != '2')    /* Success might be 226 or 250 (or ???). */
+    {
+      err = FTPRERR;            /* Not Positive Completion. */
+    }
+
+  xfree (respline);             /* Free "respline" storage. */
+  return err;                   /* Return response-based status code. */
+}
+
 /* Sends REST command to the FTP server.  */
 uerr_t
 ftp_rest (int csock, wgint offset)
@@ -957,17 +994,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", 
                                   "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);
@@ -1171,7 +1215,7 @@ ftp_process_type (const char *params)
   if (params
       && 0 == strncasecmp (params, "type=", 5)
       && params[5] != '\0')
-    return TOUPPER (params[5]);
+    return c_toupper (params[5]);
   else
     return 'I';
 }