mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
Early Ehlinger's CURLOPT_FTP_CREATE_MISSING_DIRS patch was applied
This commit is contained in:
parent
a9afe6aa84
commit
f9f1f0e316
73
CHANGES
73
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
|
||||
|
@ -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
124
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 */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 ") "
|
||||
|
Loading…
Reference in New Issue
Block a user