aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
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 */