aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES14
-rw-r--r--RELEASE-NOTES2
-rw-r--r--docs/libcurl/curl_easy_setopt.311
-rw-r--r--include/curl/curl.h16
-rw-r--r--lib/ftp.c10
-rw-r--r--lib/url.c2
-rw-r--r--lib/urldata.h5
-rw-r--r--src/main.c22
8 files changed, 63 insertions, 19 deletions
diff --git a/CHANGES b/CHANGES
index 2ad7ca185..43756b60f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,20 @@
Changelog
+Daniel Stenberg (17 Feb 2009)
+- CURLOPT_FTP_CREATE_MISSING_DIRS can now be set to 2 in addition to 1 for
+ plain FTP connections, and it will then allow MKD to fail once and retry the
+ CWD afterwards. This is especially useful if you're doing many simultanoes
+ connections against the same server and they all have this option enabled,
+ as then CWD may first fail but then another connection does MKD before this
+ connection and thus MKD fails but trying CWD works! The numbers can
+ (should?) now be set with the convenience enums now called
+ CURLFTP_CREATE_DIR and CURLFTP_CREATE_DIR_RETRY.
+
+ Tests has proven that if you're making an application that uploads a set of
+ files to an ftp server, you will get a noticable gain in speed if you're
+ using multiple connections and this option will be then be very useful.
+
Daniel Stenberg (14 Feb 2009)
- Andre Guibert de Bruet found and fixed a memory leak in the content encoding
code, which could happen on libz errors.
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index 59e442635..ebd3c3a42 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -21,6 +21,8 @@ This release includes the following changes:
o Added docs/libcurl/symbols-in-versions
o Added CURLINFO_CONDITION_UNMET
o Added support for Digest and NTLM authentication using GnuTLS
+ o CURLOPT_FTP_CREATE_MISSING_DIRS can now be set to 2 to retry the CWD even
+ when MKD fails
This release includes the following bugfixes:
diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
index e5e35d3d0..59a277d0d 100644
--- a/docs/libcurl/curl_easy_setopt.3
+++ b/docs/libcurl/curl_easy_setopt.3
@@ -1103,6 +1103,17 @@ This setting also applies to SFTP-connections. curl will attempt to create
the remote directory if it can't obtain a handle to the target-location. The
creation will fail if a file of the same name as the directory to create
already exists or lack of permissions prevents creation. (Added in 7.16.3)
+
+Starting with 7.19.4, you can also set this value to 2, which will make
+libcurl retry the CWD command again if the subsequent MKD command fails. This
+is especially useful if you're doing many simultanoes connections against the
+same server and they all have this option enabled, as then CWD may first fail
+but then another connection does MKD before this connection and thus MKD fails
+but trying CWD works! 7.19.4 also introduced the \fICURLFTP_CREATE_DIR\fP and
+\fICURLFTP_CREATE_DIR_RETRY\fP enum names for these arguments.
+
+Before version 7.19.4, libcurl will simply ignore arguments set to 2 and act
+as if 1 was selected.
.IP CURLOPT_FTP_RESPONSE_TIMEOUT
Pass a long. Causes curl to set a timeout period (in seconds) on the amount
of time that the server is allowed to take in order to generate a response
diff --git a/include/curl/curl.h b/include/curl/curl.h
index 3cbf69f7c..69fe45757 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -530,6 +530,17 @@ typedef enum {
CURLFTPAUTH_LAST /* not an option, never use */
} curl_ftpauth;
+/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */
+typedef enum {
+ CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */
+ CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD
+ again if MKD succeeded, for SFTP this does
+ similar magic */
+ CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD
+ again even if MKD failed! */
+ CURLFTP_CREATE_DIR_LAST /* not an option, never use */
+} curl_ftpcreatedir;
+
/* parameter for the CURLOPT_FTP_FILEMETHOD option */
typedef enum {
CURLFTPMETHOD_DEFAULT, /* let libcurl pick */
@@ -936,7 +947,10 @@ typedef enum {
argument */
CINIT(SSL_CTX_DATA, OBJECTPOINT, 109),
- /* FTP Option that causes missing dirs to be created on the remote server */
+ /* FTP Option that causes missing dirs to be created on the remote server.
+ In 7.19.4 we introduced the convenience enums for this option using the
+ CURLFTP_CREATE_DIR prefix.
+ */
CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110),
/* Set this to a bitmask value to enable the particular authentications
diff --git a/lib/ftp.c b/lib/ftp.c
index f76868f0d..08a55a0a4 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -828,7 +828,13 @@ static CURLcode ftp_state_cwd(struct connectdata *conn)
/* already done and fine */
result = ftp_state_post_cwd(conn);
else {
- ftpc->count2 = 0;
+ ftpc->count2 = 0; /* count2 counts failed CWDs */
+
+ /* count3 is set to allow a MKD to fail once. In the case when first CWD
+ fails and then MKD fails (due to another session raced it to create the
+ dir) this then allows for a second try to CWD to it */
+ ftpc->count3 = (conn->data->set.ftp_create_missing_dirs==2)?1:0;
+
if(conn->bits.reuse && ftpc->entrypath) {
/* This is a re-used connection. Since we change directory to where the
transfer is taking place, we must first get back to the original dir
@@ -2834,7 +2840,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
break;
case FTP_MKD:
- if(ftpcode/100 != 2) {
+ if((ftpcode/100 != 2) && !ftpc->count3--) {
/* failure to MKD the dir */
failf(data, "Failed to MKD dir: %03d", ftpcode);
return CURLE_REMOTE_ACCESS_DENIED;
diff --git a/lib/url.c b/lib/url.c
index 6d5bf4207..c16ad97f3 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -922,7 +922,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
* An FTP option that modifies an upload to create missing directories on
* the server.
*/
- data->set.ftp_create_missing_dirs = (bool)(0 != va_arg(param, long));
+ data->set.ftp_create_missing_dirs = (int)va_arg(param, long);
break;
case CURLOPT_FTP_RESPONSE_TIMEOUT:
/*
diff --git a/lib/urldata.h b/lib/urldata.h
index be3f06191..d1851066e 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1474,6 +1474,10 @@ struct UserDefined {
curl_ftpfile ftp_filemethod; /* how to get to a file when FTP is used */
+ int ftp_create_missing_dirs; /* 1 - create directories that don't exist
+ 2 - the same but also allow MKD to fail once
+ */
+
/* Here follows boolean settings that define how to behave during
this session. They are STATIC, set by libcurl users or at least initially
and they don't change during operations. */
@@ -1484,7 +1488,6 @@ struct UserDefined {
bool prefer_ascii; /* ASCII rather than binary */
bool ftp_append; /* append, not overwrite, on upload */
bool ftp_list_only; /* switch FTP command for listing directories */
- bool ftp_create_missing_dirs; /* create directories that don't exist */
bool ftp_use_port; /* use the FTP PORT command */
bool hide_progress; /* don't use the progress meter */
bool http_fail_on_error; /* fail on HTTP error codes >= 300 */
diff --git a/src/main.c b/src/main.c
index 16abdfb7b..958c8b514 100644
--- a/src/main.c
+++ b/src/main.c
@@ -4753,11 +4753,11 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
/* new in curl 7.10 */
my_setopt(curl, CURLOPT_ENCODING,
- (config->encoding) ? "" : NULL);
+ (config->encoding) ? "" : NULL);
- /* new in curl 7.10.7 */
+ /* new in curl 7.10.7, extended in 7.19.4 but this only sets 0 or 1 */
my_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS,
- config->ftp_create_dirs);
+ config->ftp_create_dirs);
if(config->proxyanyauth)
my_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
else if(config->proxynegotiate)
@@ -4925,17 +4925,13 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
}
if(retry) {
- static const char * const m[]={NULL,
- "timeout",
- "HTTP error",
- "FTP error"
+ static const char * const m[]={
+ NULL, "timeout", "HTTP error", "FTP error"
};
warnf(config, "Transient problem: %s "
"Will retry in %ld seconds. "
"%ld retries left.\n",
- m[retry],
- retry_sleep/1000,
- retry_numretries);
+ m[retry], retry_sleep/1000, retry_numretries);
go_sleep(retry_sleep);
retry_numretries--;
@@ -4977,15 +4973,13 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
} while(1);
if((config->progressmode == CURL_PROGRESS_BAR) &&
- progressbar.calls) {
+ progressbar.calls)
/* if the custom progress bar has been displayed, we output a
newline here */
fputs("\n", progressbar.out);
- }
- if(config->writeout) {
+ if(config->writeout)
ourWriteOut(curl, config->writeout);
- }
#ifdef USE_ENVIRONMENT
if (config->writeenv)
ourWriteEnv(curl);