changeset 91:8c37d73d3f1f

2003-1-21 Brian Masney <masneyb@gftp.org> * lib/gftp.h - added server type defines. Added server_type field to gftp_request * lib/local.c - use S_ISDIR and S_ISLINK macros * lib/protocols.c - (gftp_parse_ls*) - use hints from server_type for parsing directory listing * lib/rfc959.c - added function rfc959_syst. Call this on startup * lib/protocols.c lib/rfc959.c lib/sshv2.c - pass request structure to gftp_parse_ls * lib/sshv2.c - set server_type to be GFTP_TYPE_UNIX
author masneyb
date Tue, 21 Jan 2003 23:46:03 +0000
parents 49037b88d31c
children c11cef32103e
files ChangeLog lib/gftp.h lib/local.c lib/protocols.c lib/rfc959.c lib/sshv2.c
diffstat 6 files changed, 147 insertions(+), 62 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue Jan 21 05:50:53 2003 +0000
+++ b/ChangeLog	Tue Jan 21 23:46:03 2003 +0000
@@ -1,3 +1,19 @@
+2003-1-21 Brian Masney <masneyb@gftp.org>
+	* lib/gftp.h - added server type defines. Added server_type field to 
+	gftp_request
+
+	* lib/local.c - use S_ISDIR and S_ISLINK macros
+
+	* lib/protocols.c - (gftp_parse_ls*) - use hints from server_type for
+	parsing directory listing
+
+	* lib/rfc959.c - added function rfc959_syst. Call this on startup
+
+	* lib/protocols.c lib/rfc959.c lib/sshv2.c - pass request structure
+	to gftp_parse_ls
+
+	* lib/sshv2.c - set server_type to be GFTP_TYPE_UNIX
+
 2003-1-11 Brian Masney <masneyb@gftp.org>
 	* autogen.sh - removed --intl and --no-changelog flags to gettextize
 
@@ -447,7 +463,7 @@
 
 	* cvsclean - added this script
 
-	* *.[ch] - added $Id: ChangeLog,v 1.52 2003/01/11 15:49:01 masneyb Exp $ tags
+	* *.[ch] - added $Id: ChangeLog,v 1.53 2003/01/21 23:46:01 masneyb Exp $ tags
 
 	* debian/* - updated files from Debian maintainer
 
--- a/lib/gftp.h	Tue Jan 21 05:50:53 2003 +0000
+++ b/lib/gftp.h	Tue Jan 21 23:46:03 2003 +0000
@@ -96,6 +96,15 @@
 #include <dmalloc.h>
 #endif
 
+/* Server types (used by FTP protocol from SYST command) */
+#define GFTP_TYPE_UNIX		1
+#define GFTP_TYPE_EPLF		2
+#define GFTP_TYPE_CRAY		3	
+#define GFTP_TYPE_NOVELL	4	
+#define GFTP_TYPE_DOS		5	
+#define GFTP_TYPE_VMS		6	
+#define GFTP_TYPE_OTHER 	7
+
 /* Error types */
 #define GFTP_ERETRYABLE		-1
 #define GFTP_EFATAL		-2
@@ -217,7 +226,8 @@
   struct hostent host, *hostp;  /* Remote host we are connected to */
 #endif
 
-  int data_type;		/* ASCII or BINARY (FTP only) */
+  int data_type,		/* ASCII or BINARY (FTP only) */
+      server_type;		/* The type of server we are connected to */
   unsigned int use_proxy : 1,           /* Go out of proxy server */
                always_connected : 1,
                need_hostport : 1,
@@ -498,6 +508,7 @@
 extern gftp_config_vars config_file_vars[];
 extern gftp_proxy_type proxy_type[];
 extern gftp_color send_color, recv_color, error_color, misc_color;
+extern struct lconv *my_localeinfo;
 
 /* cache.c */
 int gftp_new_cache_entry 		( gftp_request * request );
@@ -780,7 +791,8 @@
 void gftp_calc_kbs 			( gftp_transfer * tdata, 
 				 	  ssize_t num_read );
 
-int gftp_parse_ls 			( const char *lsoutput, 
+int gftp_parse_ls 			( gftp_request * request,
+					  const char *lsoutput, 
 					  gftp_file *fle );
 
 int gftp_get_all_subdirs 		( gftp_transfer * transfer, 
--- a/lib/local.c	Tue Jan 21 05:50:53 2003 +0000
+++ b/lib/local.c	Tue Jan 21 23:46:03 2003 +0000
@@ -373,8 +373,8 @@
   else
     fle->size = st.st_size;
 
-  fle->isdir = st.st_mode & S_IFDIR;
-  fle->islink = st.st_mode & S_IFLNK;
+  fle->isdir = S_ISDIR (st.st_mode);
+  fle->islink = S_ISLNK (st.st_mode);
   fle->isexe = (st.st_mode & S_IXUSR) || 
                (st.st_mode & S_IXGRP) ||
                (st.st_mode & S_IXOTH);
--- a/lib/protocols.c	Tue Jan 21 05:50:53 2003 +0000
+++ b/lib/protocols.c	Tue Jan 21 23:46:03 2003 +0000
@@ -30,6 +30,7 @@
   request->datafd = -1;
   request->cachefd = -1;
   request->data_type = GFTP_TYPE_BINARY;
+  request->server_type = GFTP_TYPE_OTHER;
   return (request);
 }
 
@@ -1026,6 +1027,7 @@
 static time_t
 parse_time (char **str)
 {
+  /* FIXME - doesn't work with all locales */
   const char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
     "Aug", "Sep", "Oct", "Nov", "Dec" };
   char *startpos, *endpos, *datepos;
@@ -1183,9 +1185,38 @@
 
 
 static int
-gftp_parse_ls_unix (char *str, int cols, gftp_file * fle)
+gftp_parse_ls_unix (gftp_request * request, char *str, gftp_file * fle)
 {
-  char *endpos, *startpos;
+  char *endpos, *startpos, *pos;
+  int cols;
+
+  /* If there is no space between the attribs and links field, just make one */
+  if (strlen (str) > 10)
+    str[10] = ' ';
+
+  /* Determine the number of columns */
+  cols = 0;
+  pos = str;
+  while (*pos != '\0')
+    {
+      while (*pos != '\0' && *pos != ' ' && *pos != '\t')
+        {
+          if (*pos == ':')
+            break;
+          pos++;
+        }
+
+      cols++;
+
+      if (*pos == ':')
+        {
+          cols++;
+          break;
+        }
+
+      while (*pos == ' ' || *pos == '\t')
+        pos++;
+    }
 
   startpos = str;
   /* Copy file attributes */
@@ -1222,13 +1253,16 @@
       startpos = goto_next_token (startpos);
     }
 
-  /* FIXME - this is a bug if there is some extra spaces in the file */
-  /* See if this is a Cray directory listing. It has the following format:
-     drwx------     2 feiliu    g913     DK  common      4096 Sep 24  2001 wv */
-  if (cols == 11 && strstr (str, "->") == NULL)
+  /* FIXME - make this GFTP_TYPE_CRAY */
+  if (request->server_type != GFTP_TYPE_UNIX)
     {
-      startpos = goto_next_token (startpos);
-      startpos = goto_next_token (startpos);
+      /* See if this is a Cray directory listing. It has the following format:
+      drwx------     2 feiliu    g913     DK  common      4096 Sep 24  2001 wv */
+      if (cols == 11 && strstr (str, "->") == NULL)
+        {
+          startpos = goto_next_token (startpos);
+          startpos = goto_next_token (startpos);
+        }
     }
 
   /* See if this is a block or character device. We will store the major number
@@ -1353,10 +1387,11 @@
 
 
 int
-gftp_parse_ls (const char *lsoutput, gftp_file * fle)
+gftp_parse_ls (gftp_request * request, const char *lsoutput, gftp_file * fle)
 {
-  int result, cols;
-  char *str, *pos;
+  int result;
+  size_t len;
+  char *str;
 
   g_return_val_if_fail (lsoutput != NULL, GFTP_EFATAL);
   g_return_val_if_fail (fle != NULL, GFTP_EFATAL);
@@ -1365,52 +1400,37 @@
   strcpy (str, lsoutput);
   memset (fle, 0, sizeof (*fle));
 
-  if (str[strlen (str) - 1] == '\n')
-    str[strlen (str) - 1] = '\0';
-  if (str[strlen (str) - 1] == '\r')
-    str[strlen (str) - 1] = '\0';
-  if (*lsoutput == '+') 			/* EPLF format */
-    result = gftp_parse_ls_eplf (str, fle);
-  else if (isdigit ((int) str[0]) && str[2] == '-') 	/* DOS/WinNT format */
-    result = gftp_parse_ls_nt (str, fle);
-  else if (str[1] == ' ' && str[2] == '[') 	/* Novell format */
-    result = gftp_parse_ls_novell (str, fle);
-  else
-    {
-      /* UNIX/MacOS format */
-
-      /* If there is no space between the attribs and links field, just make one */
-      if (strlen (str) > 10)
-	str[10] = ' ';
+  len = strlen (str);
+  if (str[len - 1] == '\n')
+    str[--len] = '\0';
+  if (len > 0 && str[len - 1] == '\r')
+    str[--len] = '\0';
 
-      /* Determine the number of columns */
-      cols = 0;
-      pos = str;
-      while (*pos != '\0')
-	{
-	  while (*pos != '\0' && *pos != ' ' && *pos != '\t')
-	    {
-	      if (*pos == ':')
-		break;
-	      pos++;
-	    }
-
-	  cols++;
+  switch (request->server_type)
+    {
+      case GFTP_TYPE_UNIX:
+	result = gftp_parse_ls_unix (request, str, fle);
+        break;
+      case GFTP_TYPE_EPLF:
+        result = gftp_parse_ls_eplf (str, fle);
+        break;
+      case GFTP_TYPE_NOVELL:
+        result = gftp_parse_ls_novell (str, fle);
+        break;
+      case GFTP_TYPE_DOS:
+        result = gftp_parse_ls_nt (str, fle);
+        break;
+      default: /* autodetect */
+        if (*lsoutput == '+')
+          result = gftp_parse_ls_eplf (str, fle);
+        else if (isdigit ((int) str[0]) && str[2] == '-')
+          result = gftp_parse_ls_nt (str, fle);
+        else if (str[1] == ' ' && str[2] == '[')
+          result = gftp_parse_ls_novell (str, fle);
+        else
+	  result = gftp_parse_ls_unix (request, str, fle);
 
-	  if (*pos == ':')
-	    {
-	      cols++;
-	      break;
-	    }
-
-	  while (*pos == ' ' || *pos == '\t')
-	    pos++;
-	}
-
-      if (cols > 6)
-	result = gftp_parse_ls_unix (str, cols, fle);
-      else
-	result = GFTP_EFATAL;
+        break;
     }
   g_free (str);
 
--- a/lib/rfc959.c	Tue Jan 21 05:50:53 2003 +0000
+++ b/lib/rfc959.c	Tue Jan 21 23:46:03 2003 +0000
@@ -293,6 +293,39 @@
 
 
 static int
+rfc959_syst (gftp_request * request)
+{
+  char *stpos, *endpos;
+  int ret;
+
+  g_return_val_if_fail (request != NULL, GFTP_EFATAL);
+  g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL);
+  g_return_val_if_fail (request->sockfd > 0, GFTP_EFATAL);
+
+  ret = rfc959_send_command (request, "SYST\r\n");
+
+  if (ret < 0)
+    return (ret);
+  else if (ret != '2')
+    return (GFTP_ERETRYABLE);
+
+  if ((stpos = strchr (request->last_ftp_response, ' ')) == NULL)
+    return (GFTP_ERETRYABLE);
+
+  if ((endpos = strchr (stpos, ' ')) == NULL)
+    return (GFTP_ERETRYABLE);
+
+  *endpos = '\0';
+  if (strcmp (stpos, "UNIX") == 0)
+    request->server_type = GFTP_TYPE_UNIX;
+  else
+    request->server_type = GFTP_TYPE_OTHER;
+
+  return (0);
+}
+
+
+static int
 rfc959_connect (gftp_request * request)
 {
   char tempchar, *startpos, *endpos, *tempstr;
@@ -378,6 +411,9 @@
       return (GFTP_EFATAL);
     }
 
+  if ((ret = rfc959_syst (request)) < 0 && request->sockfd < 0)
+    return (ret);
+
   if (request->data_type == GFTP_TYPE_BINARY)
     tempstr = "TYPE I\r\n";
   else
@@ -915,7 +951,7 @@
 	  return ((int) len);
 	} 
 
-      if (gftp_parse_ls (tempstr, fle) != 0)
+      if (gftp_parse_ls (request, tempstr, fle) != 0)
 	{
 	  if (strncmp (tempstr, "total", strlen ("total")) != 0 &&
 	      strncmp (tempstr, _("total"), strlen (_("total"))) != 0)
--- a/lib/sshv2.c	Tue Jan 21 05:50:53 2003 +0000
+++ b/lib/sshv2.c	Tue Jan 21 23:46:03 2003 +0000
@@ -1010,7 +1010,7 @@
       if (longname[longnamelen - 1] == '/')
         longname[--longnamelen] = '\0';
 
-      if ((ret = gftp_parse_ls (longname, fle)) < 0)
+      if ((ret = gftp_parse_ls (request, longname, fle)) < 0)
         {
           gftp_file_destroy (fle);
           return (ret);
@@ -2011,6 +2011,7 @@
   request->use_threads = 1;
   request->always_connected = 0;
   request->protocol_data = g_malloc0 (sizeof (sshv2_params));
+  request->server_type = GFTP_TYPE_UNIX;
   gftp_set_config_options (request);
 
   params = request->protocol_data;