Early Ehlinger's CURLOPT_FTP_CREATE_MISSING_DIRS patch was applied

This commit is contained in:
Daniel Stenberg 2003-08-08 09:13:19 +00:00
parent a9afe6aa84
commit f9f1f0e316
6 changed files with 180 additions and 34 deletions

73
CHANGES
View File

@ -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

View 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;

124
lib/ftp.c
View File

@ -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 */

View File

@ -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

View 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;

View 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 ") "