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
|
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)
|
Daniel (3 August)
|
||||||
- When proxy authentication is used in a CONNECT request (as used for all SSL
|
- When proxy authentication is used in a CONNECT request (as used for all SSL
|
||||||
connects and otherwise enforced tunnel-thru-proxy requests), the same
|
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
|
/* This is the version number of the libcurl package from which this header
|
||||||
file origins: */
|
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
|
/* This is the numeric version of the libcurl version number, meant for easier
|
||||||
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
|
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
|
always a greater number in a more recent release. It makes comparisons with
|
||||||
greater than and less than work.
|
greater than and less than work.
|
||||||
*/
|
*/
|
||||||
#define LIBCURL_VERSION_NUM 0x070a06
|
#define LIBCURL_VERSION_NUM 0x070a07
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@ -669,6 +669,9 @@ typedef enum {
|
|||||||
argument */
|
argument */
|
||||||
CINIT(SSL_CTX_DATA, OBJECTPOINT, 109),
|
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 */
|
CURLOPT_LASTENTRY /* the last unused */
|
||||||
} CURLoption;
|
} CURLoption;
|
||||||
|
|
||||||
|
124
lib/ftp.c
124
lib/ftp.c
@ -99,8 +99,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Local API functions */
|
/* 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_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: */
|
/* easy-to-use macro: */
|
||||||
#define FTPSENDF(x,y,z) if((result = Curl_ftpsendf(x,y,z))) return result
|
#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)
|
if(result)
|
||||||
return 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(data->set.prequote) {
|
||||||
if ((result = ftp_sendquote(conn, data->set.prequote)) != CURLE_OK)
|
if ((result = ftp_sendquote(conn, data->set.prequote)) != CURLE_OK)
|
||||||
return result;
|
return result;
|
||||||
@ -2003,20 +2006,21 @@ CURLcode ftp_perform(struct connectdata *conn,
|
|||||||
if ((result = ftp_sendquote(conn, data->set.quote)) != CURLE_OK)
|
if ((result = ftp_sendquote(conn, data->set.quote)) != CURLE_OK)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is a re-used connection. Since we change directory to where the
|
/* 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
|
transfer is taking place, we must now get back to the original dir
|
||||||
where we ended up after login: */
|
where we ended up after login: */
|
||||||
if (conn->bits.reuse && ftp->entrypath) {
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
int i; /* counter for loop */
|
int i; /* counter for loop */
|
||||||
for (i=0; ftp->dirs[i]; i++) {
|
for (i=0; ftp->dirs[i]; i++) {
|
||||||
/* RFC 1738 says empty components should be respected too */
|
/* RFC 1738 says empty components should be respected too, but
|
||||||
if ((result = ftp_cwd(conn, ftp->dirs[i])) != CURLE_OK)
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2025,33 +2029,38 @@ CURLcode ftp_perform(struct connectdata *conn,
|
|||||||
if((data->set.get_filetime || data->set.timecondition) &&
|
if((data->set.get_filetime || data->set.timecondition) &&
|
||||||
ftp->file) {
|
ftp->file) {
|
||||||
result = ftp_getfiletime(conn, ftp->file);
|
result = ftp_getfiletime(conn, ftp->file);
|
||||||
if(result)
|
switch( result )
|
||||||
return result;
|
{
|
||||||
|
case CURLE_FTP_COULDNT_RETR_FILE:
|
||||||
if(data->set.timecondition) {
|
case CURLE_OK:
|
||||||
if((data->info.filetime > 0) && (data->set.timevalue > 0)) {
|
if(data->set.timecondition) {
|
||||||
switch(data->set.timecondition) {
|
if((data->info.filetime > 0) && (data->set.timevalue > 0)) {
|
||||||
case TIMECOND_IFMODSINCE:
|
switch(data->set.timecondition) {
|
||||||
default:
|
case TIMECOND_IFMODSINCE:
|
||||||
if(data->info.filetime < data->set.timevalue) {
|
default:
|
||||||
infof(data, "The requested document is not new enough\n");
|
if(data->info.filetime < data->set.timevalue) {
|
||||||
ftp->no_transfer = TRUE; /* mark this to not transfer data */
|
infof(data, "The requested document is not new enough\n");
|
||||||
return CURLE_OK;
|
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;
|
else {
|
||||||
case TIMECOND_IFUNMODSINCE:
|
infof(data, "Skipping time comparison\n");
|
||||||
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;
|
||||||
}
|
default:
|
||||||
else {
|
return result;
|
||||||
infof(data, "Skipping time comparison\n");
|
} /* switch */
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we have selected NOBODY and HEADER, it means that we only want file
|
/* 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;
|
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 */
|
#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;
|
data->set.get_filetime = va_arg(param, long)?TRUE:FALSE;
|
||||||
break;
|
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:
|
case CURLOPT_FTPLISTONLY:
|
||||||
/*
|
/*
|
||||||
* An FTP option that changes the command to one that asks for a list
|
* 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_append;
|
||||||
bool ftp_ascii;
|
bool ftp_ascii;
|
||||||
bool ftp_list_only;
|
bool ftp_list_only;
|
||||||
|
bool ftp_create_missing_dirs;
|
||||||
bool ftp_use_port;
|
bool ftp_use_port;
|
||||||
bool hide_progress;
|
bool hide_progress;
|
||||||
bool http_fail_on_error;
|
bool http_fail_on_error;
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
#define CURL_NAME "curl"
|
#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 ") "
|
#define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "
|
||||||
|
Loading…
Reference in New Issue
Block a user