]> granicus.if.org Git - curl/commitdiff
Early Ehlinger's CURLOPT_FTP_CREATE_MISSING_DIRS patch was applied
authorDaniel Stenberg <daniel@haxx.se>
Fri, 8 Aug 2003 09:13:19 +0000 (09:13 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 8 Aug 2003 09:13:19 +0000 (09:13 +0000)
CHANGES
include/curl/curl.h
lib/ftp.c
lib/url.c
lib/urldata.h
src/version.h

diff --git a/CHANGES b/CHANGES
index 94a5318a103ada8fcfb8bbe4cb6e9424e70b9521..95f3d666ffefa74ebf15bd83ee820125b72559a9 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,79 @@
 
                                   Changelog
 
+Daniel (7 August)
+- Test case 60 failed on ia64 and AMD Opteron. Fixed now.
+
+- Fixed a printf problem that resulted in urlglobbing bugs (bug #203827 in the
+  debian bug tracker). Added test case 74 to verify the fix and to discover if
+  this breaks in the future.
+
+- make distcheck works again.
+
+Version 7.10.7-pre2 (6 August 2003)
+
+Daniel (5 August)
+- Duncan Wilcox helped me verify that the latest incarnation of my ares patch
+  builds fine on Mac OS X (see the new lib/README.ares) file for all details.
+
+- Salvatore Sorrentino filed bug report #783116 and Early Ehlinger posted a
+  bug report to the libcurl list, both identifying a problem with FTP
+  persitent connections and how the dir hiearchy was not properly reset
+  between files.
+
+- David Byron's thoughts on a fixed Makefile in tests/ were applied.
+
+- Jan Sundin reported a case where curl ignored a cookie that browsers don't,
+  which turned up to be due to the number of dots in the 'domain'. I've now
+  made curl follow the the original netscape cookie spec less strict on that
+  part.
+
+Daniel (4 August)
+- Dirk Manske added cookie support for the experimental, hidden and still
+  undocumented share feature!
+
+- Mark Fletcher provided an excellent bug report that identified a problem
+  with FOLLOWLOCATION and chunked transfer-encoding, as libcurl would not
+  properly ignore the body contents of 3XX response that included the
+  Location: header.
+
+Early (6 August)
+- Added option CURLOPT_FTP_CREATE_MISSING_DIRS
+    This option will force the target file's path to be created if it
+    does not already exist on the remote system.
+  Files affected:
+    - include/curl/curl.h
+        Added option CURLOPT_FTP_CREATE_MISSING_DIRS
+    - lib/ftp.c
+        Added function ftp_mkd, which issues a MKD command
+        Added function ftp_force_cwd, which attempts a CWD,
+          and does a MKD and retries the CWD if the original CWD
+          fails
+        Modified ftp_perform() to call its change directory function
+          through a pointer.  The pointer points to ftp_cwd by default,
+          and is modified to point to ftp_force_cwd IFF
+          data->set.ftp_create_missing_dirs is not 0.        
+    - lib/url.c
+        Modified Curl_setopt to recognize CURLOPT_FTP_CREATE_MISSING_DIRS
+    - lib/urldata.h
+        Added ftp_create_missing_dirs to struct UserDefined
+       
+- Minor Bugfix for CURLOPT_TIMECONDITION with FTP - if the file was not
+  present to do the time comparison, it would fail.
+  Files affected:
+    - lib/ftp.c
+        In ftp_perform(), the call to ftp_getfiletime() used to be followed
+        by
+         if (result)
+            return result;
+        And then by the code that actually did the time comparison.
+        The code that did the comparison handled the case where the filetime
+        was not available (as indicated by info.filetime < 0 or set.timevalue 
+        < 0), so I replaced the if (result) return result with a switch(result)
+        that allows CURLE_FTP_COULDNT_RETR_FILE to fall through to the 
+        normal time comparison.
+
 Daniel (3 August)
 - When proxy authentication is used in a CONNECT request (as used for all SSL
   connects and otherwise enforced tunnel-thru-proxy requests), the same
index 71c490c5ac6ce87b9f0e208bd4a383694fc6f0ae..b646d0e583bedd9b33cb4c44018cf2588de80e86 100644 (file)
@@ -29,7 +29,7 @@
 
 /* This is the version number of the libcurl package from which this header
    file origins: */
-#define LIBCURL_VERSION "7.10.6"
+#define LIBCURL_VERSION "7.10.7-pre2"
 
 /* This is the numeric version of the libcurl version number, meant for easier
    parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
@@ -45,7 +45,7 @@
    always a greater number in a more recent release. It makes comparisons with
    greater than and less than work.
 */
-#define LIBCURL_VERSION_NUM 0x070a06
+#define LIBCURL_VERSION_NUM 0x070a07
 
 #include <stdio.h>
 
@@ -669,6 +669,9 @@ typedef enum {
      argument */
   CINIT(SSL_CTX_DATA, OBJECTPOINT, 109),
 
+  /* FTP Option that causes missing dirs to be created on the remote server */
+  CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110),
+
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
 
index bb3b9feb3b45ee21fd8e4899b0facfc1837ec30b..8d40a8c20e538ba32a3990eae9d08f23922ae4e2 100644 (file)
--- a/lib/ftp.c
+++ b/lib/ftp.c
 #endif
 
 /* Local API functions */
-static CURLcode ftp_sendquote(struct connectdata *conn, struct curl_slist *quote);
+static CURLcode ftp_sendquote(struct connectdata *conn,
+                              struct curl_slist *quote);
 static CURLcode ftp_cwd(struct connectdata *conn, char *path);
+static CURLcode ftp_mkd(struct connectdata *conn, char *path);
+static CURLcode cwd_and_mkd(struct connectdata *conn, char *path);
 
 /* easy-to-use macro: */
 #define FTPSENDF(x,y,z) if((result = Curl_ftpsendf(x,y,z))) return result
@@ -1784,7 +1787,7 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
       if(result)
         return result;
 
-      /* Send any PREQUOTE strings after transfer type is set? (Wesley Laxton)*/
+      /* Send any PREQUOTE strings after transfer type is set? */
       if(data->set.prequote) {
         if ((result = ftp_sendquote(conn, data->set.prequote)) != CURLE_OK)
           return result;
@@ -2003,20 +2006,21 @@ CURLcode ftp_perform(struct connectdata *conn,
     if ((result = ftp_sendquote(conn, data->set.quote)) != CURLE_OK)
       return result;
   }
-    
+
   /* This is a re-used connection. Since we change directory to where the
      transfer is taking place, we must now get back to the original dir
      where we ended up after login: */
   if (conn->bits.reuse && ftp->entrypath) {
-    if ((result = ftp_cwd(conn, ftp->entrypath)) != CURLE_OK)
+    if ((result = cwd_and_mkd(conn, ftp->entrypath)) != CURLE_OK)
       return result;
   }
 
   {
     int i; /* counter for loop */
     for (i=0; ftp->dirs[i]; i++) {
-      /* RFC 1738 says empty components should be respected too */
-      if ((result = ftp_cwd(conn, ftp->dirs[i])) != CURLE_OK)
+      /* RFC 1738 says empty components should be respected too, but
+         that is plain stupid since CWD can't be used with an empty argument */
+      if ((result = cwd_and_mkd(conn, ftp->dirs[i])) != CURLE_OK)
         return result;
     }
   }
@@ -2025,33 +2029,38 @@ CURLcode ftp_perform(struct connectdata *conn,
   if((data->set.get_filetime || data->set.timecondition) &&
      ftp->file) {
     result = ftp_getfiletime(conn, ftp->file);
-    if(result)
-      return result;
-
-    if(data->set.timecondition) {
-      if((data->info.filetime > 0) && (data->set.timevalue > 0)) {
-        switch(data->set.timecondition) {
-        case TIMECOND_IFMODSINCE:
-        default:
-          if(data->info.filetime < data->set.timevalue) {
-            infof(data, "The requested document is not new enough\n");
-            ftp->no_transfer = TRUE; /* mark this to not transfer data */
-            return CURLE_OK;
+    switch( result )
+      {
+      case CURLE_FTP_COULDNT_RETR_FILE:
+      case CURLE_OK:
+        if(data->set.timecondition) {
+          if((data->info.filetime > 0) && (data->set.timevalue > 0)) {
+            switch(data->set.timecondition) {
+            case TIMECOND_IFMODSINCE:
+            default:
+              if(data->info.filetime < data->set.timevalue) {
+                infof(data, "The requested document is not new enough\n");
+                ftp->no_transfer = TRUE; /* mark this to not transfer data */
+                return CURLE_OK;
+              }
+              break;
+            case TIMECOND_IFUNMODSINCE:
+              if(data->info.filetime > data->set.timevalue) {
+                infof(data, "The requested document is not old enough\n");
+                ftp->no_transfer = TRUE; /* mark this to not transfer data */
+                return CURLE_OK;
+              }
+              break;
+            } /* switch */
           }
-          break;
-        case TIMECOND_IFUNMODSINCE:
-          if(data->info.filetime > data->set.timevalue) {
-            infof(data, "The requested document is not old enough\n");
-            ftp->no_transfer = TRUE; /* mark this to not transfer data */
-            return CURLE_OK;
+          else {
+            infof(data, "Skipping time comparison\n");
           }
-          break;
-        } /* switch */
-      }
-      else {
-        infof(data, "Skipping time comparison\n");
-      }
-    }
+        }
+        break;
+      default:
+        return result;
+      } /* switch */
   }
 
   /* If we have selected NOBODY and HEADER, it means that we only want file
@@ -2326,4 +2335,57 @@ CURLcode Curl_ftp_disconnect(struct connectdata *conn)
   return CURLE_OK;
 }
 
+/***********************************************************************
+ *
+ * ftp_mkd()
+ *
+ * Makes a directory on the FTP server.
+ */
+CURLcode ftp_mkd(struct connectdata *conn, char *path)
+{
+  CURLcode result=CURLE_OK;
+  int ftpcode; /* for ftp status */
+  ssize_t nread;
+
+  /* Create a directory on the remote server */
+  FTPSENDF(conn, "MKD %s", path);
+
+  result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+  if(result)
+    return result;
+  
+  switch(ftpcode) {
+  case 257:
+    /* success! */
+    infof( conn->data , "Created Remote Directory %s\n" , path );
+    break;
+  default:
+    infof(conn->data, "unrecognized MKD response %d\n", result );
+    result = ~CURLE_OK;
+    break;
+  }
+  return  result;
+}
+
+/***********************************************************************
+ *
+ * ftp_cwd_and_mkd()
+ *
+ * Change to the given directory.  If the directory is not present, and we
+ * have been told to allow it, then create the directory and cd to it.
+ */
+static CURLcode cwd_and_mkd(struct connectdata *conn, char *path)
+{
+  CURLcode result;
+  
+  result = ftp_cwd(conn, path);
+  if ((CURLE_OK != result) && conn->data->set.ftp_create_missing_dirs) {
+    result = ftp_mkd(conn, path);
+    if ( CURLE_OK != result)
+      return result;
+    result = ftp_cwd(conn, path);
+  }
+  return result;
+}
+
 #endif /* CURL_DISABLE_FTP */
index 84f3bbb0f6f64e00aa1bee05ebc7982aa96f2f52..4bd02705afeefcad8ec93dab9e3a8df2c6f03977 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -489,6 +489,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
      */
     data->set.get_filetime = va_arg(param, long)?TRUE:FALSE;
     break;
+  case CURLOPT_FTP_CREATE_MISSING_DIRS:
+    /*
+     * An FTP option that modifies an upload to create missing directories on
+     * the server.
+     */ 
+    data->set.ftp_create_missing_dirs = va_arg( param , long )?TRUE:FALSE;
+    break;
   case CURLOPT_FTPLISTONLY:
     /*
      * An FTP option that changes the command to one that asks for a list
index 0218935abebc721377995d7373299c8ddc98280d..877c2e98ef6a40980a12a92b47bcd40fbf157f64 100644 (file)
@@ -818,6 +818,7 @@ struct UserDefined {
   bool ftp_append;
   bool ftp_ascii;
   bool ftp_list_only;
+  bool ftp_create_missing_dirs;
   bool ftp_use_port;
   bool hide_progress;
   bool http_fail_on_error;
index 90eba976405174a2cac1c7b94eead8604c312dc9..81e0a8dbe85107cc932601da11912d84c856d143 100644 (file)
@@ -1,3 +1,3 @@
 #define CURL_NAME "curl"
-#define CURL_VERSION "7.10.6"
+#define CURL_VERSION "7.10.7-pre2"
 #define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "