diff --git a/CHANGES b/CHANGES index 94a5318a1..95f3d666f 100644 --- 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 diff --git a/include/curl/curl.h b/include/curl/curl.h index 71c490c5a..b646d0e58 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -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 @@ -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; diff --git a/lib/ftp.c b/lib/ftp.c index bb3b9feb3..8d40a8c20 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -99,8 +99,11 @@ #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 */ diff --git a/lib/url.c b/lib/url.c index 84f3bbb0f..4bd02705a 100644 --- 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 diff --git a/lib/urldata.h b/lib/urldata.h index 0218935ab..877c2e98e 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -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; diff --git a/src/version.h b/src/version.h index 90eba9764..81e0a8dbe 100644 --- a/src/version.h +++ b/src/version.h @@ -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 ") "