aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2009-02-17 09:07:25 +0000
committerDaniel Stenberg <daniel@haxx.se>2009-02-17 09:07:25 +0000
commit8f81fd6be5d3a480eca3f7ebbded5113f66c64be (patch)
tree278ce60a4c12407b3848b146208385c5aba63a6a /lib
parent1472be4d3e55e1f3c0c0d1fdbee77a45630f326b (diff)
- 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.
Diffstat (limited to 'lib')
-rw-r--r--lib/ftp.c10
-rw-r--r--lib/url.c2
-rw-r--r--lib/urldata.h5
3 files changed, 13 insertions, 4 deletions
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 */