Immanuel Gregoire fixed KNOWN_BUGS #44: --ftp-method nocwd did not handle
authorDaniel Stenberg <daniel@haxx.se>
Mon, 24 Sep 2007 21:47:35 +0000 (21:47 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 24 Sep 2007 21:47:35 +0000 (21:47 +0000)
URLs ending with a slash properly (it should list the contents of that
directory). Test case 351 brought back and also test 1010 was added.

CHANGES
RELEASE-NOTES
docs/KNOWN_BUGS
lib/ftp.c
tests/data/DISABLED
tests/data/Makefile.am
tests/data/test1010 [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index c1d55e3..47060eb 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,11 @@
 
                                   Changelog
 
+Daniel S (24 September 2007)
+- Immanuel Gregoire fixed KNOWN_BUGS #44: --ftp-method nocwd did not handle
+  URLs ending with a slash properly (it should list the contents of that
+  directory). Test case 351 brought back and also test 1010 was added.
+
 Daniel S (21 September 2007)
 - Mark Davies fixed Negotiate authentication over proxy, and also introduced
   the --proxy-negotiate command line option to allow a user to explicitly
index f0f87f7..f425abd 100644 (file)
@@ -22,6 +22,7 @@ This release includes the following bugfixes:
  o ldap builds with the MSVC makefiles
  o no HOME and no key given caused SSH auth failure
  o Negotiate authentication over proxy
+ o --ftp-method nocwd on directory listings
 
 This release includes the following known bugs:
 
index 5549d04..6d2cb9b 100644 (file)
@@ -17,9 +17,6 @@ may have been fixed since this was written!
   initial suggested function to use for randomizing the response:
     http://curl.haxx.se/mail/lib-2007-07/0178.html
 
-44. --ftp-method nocwd does not handle URLs ending with a slash properly (it
-  should list the contents of that directory). See test case 351.
-
 43. There seems to be a problem when connecting to the Microsoft telnet server.
   http://curl.haxx.se/bug/view.cgi?id=1720605
 
index cf5e590..c92b08e 100644 (file)
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -1279,10 +1279,52 @@ static CURLcode ftp_state_post_listtype(struct connectdata *conn)
      way. It has turned out that the NLST list output is not the same on all
      servers either... */
 
-  NBFTPSENDF(conn, "%s",
-             data->set.str[STRING_CUSTOMREQUEST]?
-             data->set.str[STRING_CUSTOMREQUEST]:
-             (data->set.ftp_list_only?"NLST":"LIST"));
+  /*
+     if FTPFILE_NOCWD was specified, we are currently in
+     the user's home directory, so we should add the path
+     as argument for the LIST / NLST / or custom command.
+     Whether the server will support this, is uncertain.
+
+     The other ftp_filemethods will CWD into dir/dir/ first and
+     then just do LIST (in that case: nothing to do here)
+  */
+  char *cmd,*lstArg,*slashPos;
+
+  lstArg = NULL;
+  if((data->set.ftp_filemethod == FTPFILE_NOCWD) &&
+     data->reqdata.path &&
+     data->reqdata.path[0] &&
+     strchr(data->reqdata.path,'/')) {
+
+    lstArg = strdup(data->reqdata.path);
+    if(!lstArg)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* Check if path does not end with /, as then we cut off the file part */
+    if(lstArg[strlen(lstArg) - 1] != '/')  {
+
+      /* chop off the file part if format is dir/dir/file */
+      slashPos = strrchr(lstArg,'/');
+      *(slashPos+1) = '\0';
+    }
+  }
+
+  cmd = aprintf( "%s%s%s",
+                 data->set.str[STRING_CUSTOMREQUEST]?
+                 data->set.str[STRING_CUSTOMREQUEST]:
+                 (data->set.ftp_list_only?"NLST":"LIST"),
+                 lstArg? " ": "",
+                 lstArg? lstArg: "" );
+
+  if(!cmd)
+    return CURLE_OUT_OF_MEMORY;
+
+  NBFTPSENDF(conn, "%s",cmd);
+
+  if(lstArg)
+    free(lstArg);
+
+  free(cmd);
 
   state(conn, FTP_LIST);
 
@@ -3036,7 +3078,7 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status,
     size_t flen = ftp->file?strlen(ftp->file):0; /* file is "raw" already */
     size_t dlen = strlen(path)-flen;
     if(!ftpc->cwdfail) {
-      if(dlen) {
+      if(dlen && (data->set.ftp_filemethod != FTPFILE_NOCWD)) {
         ftpc->prevpath = path;
         if(flen)
           /* if 'path' is not the whole string */
@@ -3695,7 +3737,26 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
   switch(data->set.ftp_filemethod) {
   case FTPFILE_NOCWD:
     /* fastest, but less standard-compliant */
-    ftp->file = data->reqdata.path;  /* this is a full file path */
+
+    /*
+      The best time to check whether the path is a file or directory is right
+      here. so:
+
+      the first condition in the if() right here, is there just in case
+      someone decides to set path to NULL one day
+   */
+    if(data->reqdata.path &&
+       data->reqdata.path[0] &&
+       (data->reqdata.path[strlen(data->reqdata.path) - 1] != '/') )
+      ftp->file = data->reqdata.path;  /* this is a full file path */
+    else
+      ftp->file = NULL;
+      /*
+        ftp->file is not used anywhere other than for operations on a file.
+        In other words, never for directory operations.
+        So we can safely set it to NULL here and use it as a
+        argument in dir/file decisions.
+      */
     break;
 
   case FTPFILE_SINGLECWD:
index 7db101d..ce6dc95 100644 (file)
@@ -4,4 +4,4 @@
 # per line.
 # Lines starting with '#' letters are treated as comments.
 #230
-351
+
index 9d818b8..260d17b 100644 (file)
@@ -44,4 +44,4 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46           \
  test409 test613 test614 test700 test701 test702 test704 test705 test703   \
  test706 test707 test350 test351 test352 test353 test289 test540 test354   \
  test231 test1000 test1001 test1002 test1003 test1004 test1005 test1006    \
- test615 test1007 test541
+ test615 test1007 test541 test1010
diff --git a/tests/data/test1010 b/tests/data/test1010
new file mode 100644 (file)
index 0000000..1f8bf3a
--- /dev/null
@@ -0,0 +1,56 @@
+<testcase>
+<info>
+<keywords>
+FTP
+PASV
+LIST
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+# When doing LIST, we get the default list output hard-coded in the test
+# FTP server
+<datacheck>
+total 20
+drwxr-xr-x   8 98       98           512 Oct 22 13:06 .
+drwxr-xr-x   8 98       98           512 Oct 22 13:06 ..
+drwxr-xr-x   2 98       98           512 May  2  1996 .NeXT
+-r--r--r--   1 0        1             35 Jul 16  1996 README
+lrwxrwxrwx   1 0        1              7 Dec  9  1999 bin -> usr/bin
+dr-xr-xr-x   2 0        1            512 Oct  1  1997 dev
+drwxrwxrwx   2 98       98           512 May 29 16:04 download.html
+dr-xr-xr-x   2 0        1            512 Nov 30  1995 etc
+drwxrwxrwx   2 98       1            512 Oct 30 14:33 pub
+dr-xr-xr-x   5 0        1            512 Oct  1  1997 usr
+</datacheck>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+ftp
+</server>
+ <name>
+FTP dir list nocwd
+ </name>
+ <command>
+ftp://%HOSTIP:%FTPPORT//list/this/path/1010/ --ftp-method nocwd
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+USER anonymous\r
+PASS ftp@example.com\r
+PWD\r
+EPSV\r
+TYPE A\r
+LIST /list/this/path/1010/\r
+QUIT\r
+</protocol>
+</verify>
+</testcase>