]> sjero.net Git - wget/blobdiff - src/ftp-basic.c
[svn] Commit my url.c fix (space as unsafe character) and Jan's
[wget] / src / ftp-basic.c
index dc773d2a4a63869a753b425de9cbad3992009d97..8f6f25e1ba207a4fecf1165ed77c79b62df3a341 100644 (file)
@@ -1,5 +1,5 @@
 /* Basic FTP routines.
-   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
 
 This file is part of Wget.
 
@@ -41,6 +41,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "rbuf.h"
 #include "connect.h"
 #include "host.h"
+#include "ftp.h"
 
 #ifndef errno
 extern int errno;
@@ -138,41 +139,41 @@ ftp_login (struct rbuf *rbuf, const char *acc, const char *pass)
   err = ftp_response (rbuf, &respline);
   if (err != FTPOK)
     {
-      free (respline);
+      xfree (respline);
       return err;
     }
   if (*respline != '2')
     {
-      free (respline);
+      xfree (respline);
       return FTPSRVERR;
     }
-  free (respline);
+  xfree (respline);
   /* Send USER username.  */
   request = ftp_request ("USER", acc);
   nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
   if (nwritten < 0)
     {
-      free (request);
+      xfree (request);
       return WRITEFAILED;
     }
-  free (request);
+  xfree (request);
   /* Get appropriate response.  */
   err = ftp_response (rbuf, &respline);
   if (err != FTPOK)
     {
-      free (respline);
+      xfree (respline);
       return err;
     }
   /* An unprobable possibility of logging without a password.  */
   if (*respline == '2')
     {
-      free (respline);
+      xfree (respline);
       return FTPOK;
     }
   /* Else, only response 3 is appropriate.  */
   if (*respline != '3')
     {
-      free (respline);
+      xfree (respline);
       return FTPLOGREFUSED;
     }
 #ifdef USE_OPIE
@@ -185,7 +186,7 @@ ftp_login (struct rbuf *rbuf, const char *acc, const char *pass)
 
     for (i = 0; i < ARRAY_SIZE (skey_head); i++)
       {
-       if (strncmp (skey_head[i], respline, strlen (skey_head[i])) == 0)
+       if (strncasecmp (skey_head[i], respline, strlen (skey_head[i])) == 0)
          break;
       }
     if (i < ARRAY_SIZE (skey_head))
@@ -204,7 +205,7 @@ ftp_login (struct rbuf *rbuf, const char *acc, const char *pass)
        else
          {
          bad:
-           free (respline);
+           xfree (respline);
            return FTPLOGREFUSED;
          }
        if ((cp = calculate_skey_response (skey_sequence, cp, pass)) == 0)
@@ -213,29 +214,29 @@ ftp_login (struct rbuf *rbuf, const char *acc, const char *pass)
       }
   }
 #endif /* USE_OPIE */
-  free (respline);
+  xfree (respline);
   /* Send PASS password.  */
   request = ftp_request ("PASS", pass);
   nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
   if (nwritten < 0)
     {
-      free (request);
+      xfree (request);
       return WRITEFAILED;
     }
-  free (request);
+  xfree (request);
   /* Get appropriate response.  */
   err = ftp_response (rbuf, &respline);
   if (err != FTPOK)
     {
-      free (respline);
+      xfree (respline);
       return err;
     }
   if (*respline != '2')
     {
-      free (respline);
+      xfree (respline);
       return FTPLOGINC;
     }
-  free (respline);
+  xfree (respline);
   /* All OK.  */
   return FTPOK;
 }
@@ -271,23 +272,23 @@ ftp_port (struct rbuf *rbuf)
   nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
   if (nwritten < 0)
     {
-      free (request);
+      xfree (request);
       return WRITEFAILED;
     }
-  free (request);
+  xfree (request);
   /* Get appropriate response.  */
   err = ftp_response (rbuf, &respline);
   if (err != FTPOK)
     {
-      free (respline);
+      xfree (respline);
       return err;
     }
   if (*respline != '2')
     {
-      free (respline);
+      xfree (respline);
       return FTPPORTERR;
     }
-  free (respline);
+  xfree (respline);
   return FTPOK;
 }
 
@@ -307,20 +308,20 @@ ftp_pasv (struct rbuf *rbuf, unsigned char *addr)
   nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
   if (nwritten < 0)
     {
-      free (request);
+      xfree (request);
       return WRITEFAILED;
     }
-  free (request);
+  xfree (request);
   /* Get the server response.  */
   err = ftp_response (rbuf, &respline);
   if (err != FTPOK)
     {
-      free (respline);
+      xfree (respline);
       return err;
     }
   if (*respline != '2')
     {
-      free (respline);
+      xfree (respline);
       return FTPNOPASV;
     }
   /* Parse the request.  */
@@ -338,11 +339,11 @@ ftp_pasv (struct rbuf *rbuf, unsigned char *addr)
       else if (i < 5)
        {
          /* When on the last number, anything can be a terminator.  */
-         free (respline);
+         xfree (respline);
          return FTPINVPASV;
        }
     }
-  free (respline);
+  xfree (respline);
   return FTPOK;
 }
 
@@ -363,23 +364,23 @@ ftp_type (struct rbuf *rbuf, int type)
   nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
   if (nwritten < 0)
     {
-      free (request);
+      xfree (request);
       return WRITEFAILED;
     }
-  free (request);
+  xfree (request);
   /* Get appropriate response.  */
   err = ftp_response (rbuf, &respline);
   if (err != FTPOK)
     {
-      free (respline);
+      xfree (respline);
       return err;
     }
   if (*respline != '2')
     {
-      free (respline);
+      xfree (respline);
       return FTPUNKNOWNTYPE;
     }
-  free (respline);
+  xfree (respline);
   /* All OK.  */
   return FTPOK;
 }
@@ -398,28 +399,28 @@ ftp_cwd (struct rbuf *rbuf, const char *dir)
   nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
   if (nwritten < 0)
     {
-      free (request);
+      xfree (request);
       return WRITEFAILED;
     }
-  free (request);
+  xfree (request);
   /* Get appropriate response.  */
   err = ftp_response (rbuf, &respline);
   if (err != FTPOK)
     {
-      free (respline);
+      xfree (respline);
       return err;
     }
   if (*respline == '5')
     {
-      free (respline);
+      xfree (respline);
       return FTPNSFOD;
     }
   if (*respline != '2')
     {
-      free (respline);
+      xfree (respline);
       return FTPRERR;
     }
-  free (respline);
+  xfree (respline);
   /* All OK.  */
   return FTPOK;
 }
@@ -438,23 +439,23 @@ ftp_rest (struct rbuf *rbuf, long offset)
   nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
   if (nwritten < 0)
     {
-      free (request);
+      xfree (request);
       return WRITEFAILED;
     }
-  free (request);
+  xfree (request);
   /* Get appropriate response.  */
   err = ftp_response (rbuf, &respline);
   if (err != FTPOK)
     {
-      free (respline);
+      xfree (respline);
       return err;
     }
   if (*respline != '3')
     {
-      free (respline);
+      xfree (respline);
       return FTPRESTFAIL;
     }
-  free (respline);
+  xfree (respline);
   /* All OK.  */
   return FTPOK;
 }
@@ -472,28 +473,28 @@ ftp_retr (struct rbuf *rbuf, const char *file)
   nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
   if (nwritten < 0)
     {
-      free (request);
+      xfree (request);
       return WRITEFAILED;
     }
-  free (request);
+  xfree (request);
   /* Get appropriate response.  */
   err = ftp_response (rbuf, &respline);
   if (err != FTPOK)
     {
-      free (respline);
+      xfree (respline);
       return err;
     }
   if (*respline == '5')
     {
-      free (respline);
+      xfree (respline);
       return FTPNSFOD;
     }
   if (*respline != '1')
     {
-      free (respline);
+      xfree (respline);
       return FTPRERR;
     }
-  free (respline);
+  xfree (respline);
   /* All OK.  */
   return FTPOK;
 }
@@ -512,28 +513,126 @@ ftp_list (struct rbuf *rbuf, const char *file)
   nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
   if (nwritten < 0)
     {
-      free (request);
+      xfree (request);
       return WRITEFAILED;
     }
-  free (request);
+  xfree (request);
   /* Get appropriate respone.  */
   err = ftp_response (rbuf, &respline);
   if (err != FTPOK)
     {
-      free (respline);
+      xfree (respline);
       return err;
     }
   if (*respline == '5')
     {
-      free (respline);
+      xfree (respline);
       return FTPNSFOD;
     }
   if (*respline != '1')
     {
-      free (respline);
+      xfree (respline);
       return FTPRERR;
     }
-  free (respline);
+  xfree (respline);
+  /* All OK.  */
+  return FTPOK;
+}
+
+/* Sends the SYST command to the server. */
+uerr_t
+ftp_syst (struct rbuf *rbuf, enum stype *server_type)
+{
+  char *request, *respline;
+  int nwritten;
+  uerr_t err;
+
+  /* Send SYST request.  */
+  request = ftp_request ("SYST", NULL);
+  nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+  if (nwritten < 0)
+    {
+      xfree (request);
+      return WRITEFAILED;
+    }
+  xfree (request);
+  /* Get appropriate response.  */
+  err = ftp_response (rbuf, &respline);
+  if (err != FTPOK)
+    {
+      xfree (respline);
+      return err;
+    }
+  if (*respline == '5')
+    {
+      xfree (respline);
+      return FTPSRVERR;
+    }
+
+  /* Skip the number (215, but 200 (!!!) in case of VMS) */
+  strtok (respline, " ");
+  
+  /* Which system type has been reported (we are interested just in the
+     first word of the server response)?  */
+  request = strtok (NULL, " ");
+
+  if (!strcasecmp (request, "VMS"))
+    *server_type = ST_VMS;
+  else
+    if (!strcasecmp (request, "UNIX"))
+      *server_type = ST_UNIX;
+    else
+      if (!strcasecmp (request, "WINDOWS_NT"))
+        *server_type = ST_WINNT;
+      else
+        *server_type = ST_OTHER;
+
+  xfree (respline);
+  /* All OK.  */
+  return FTPOK;
+}
+
+/* Sends the PWD command to the server. */
+uerr_t
+ftp_pwd (struct rbuf *rbuf, char **pwd)
+{
+  char *request, *respline;
+  int nwritten;
+  uerr_t err;
+
+  /* Send PWD request.  */
+  request = ftp_request ("PWD", NULL);
+  nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+  if (nwritten < 0)
+    {
+      xfree (request);
+      return WRITEFAILED;
+    }
+  xfree (request);
+  /* Get appropriate response.  */
+  err = ftp_response (rbuf, &respline);
+  if (err != FTPOK)
+    {
+      xfree (respline);
+      return err;
+    }
+  if (*respline == '5')
+    {
+      xfree (respline);
+      return FTPSRVERR;
+    }
+
+  /* Skip the number (257), leading citation mark, trailing citation mark
+     and everything following it. */
+  strtok (respline, "\"");
+  request = strtok (NULL, "\"");
+  
+  /* Has the `pwd' been already allocated?  Free! */
+  FREE_MAYBE (*pwd);
+
+  *pwd = xstrdup (request);
+
+  xfree (respline);
   /* All OK.  */
   return FTPOK;
 }