mirror of https://github.com/moparisthebest/curl
Alexander Krasnostavsky made the CURLOPT_FTP_CREATE_MISSING_DIRS option work
fine even for third party transfers.
This commit is contained in:
parent
f40c9b83df
commit
21d5aead47
3
CHANGES
3
CHANGES
|
@ -7,6 +7,9 @@
|
||||||
Changelog
|
Changelog
|
||||||
|
|
||||||
Daniel (16 October 2004)
|
Daniel (16 October 2004)
|
||||||
|
- Alexander Krasnostavsky made the CURLOPT_FTP_CREATE_MISSING_DIRS option work
|
||||||
|
fine even for third party transfers.
|
||||||
|
|
||||||
- runekl at opoint.com found out (and provided a fix) that libcurl leaked
|
- runekl at opoint.com found out (and provided a fix) that libcurl leaked
|
||||||
memory for cookies with the "max-age" field set.
|
memory for cookies with the "max-age" field set.
|
||||||
|
|
||||||
|
|
114
lib/ftp.c
114
lib/ftp.c
|
@ -122,6 +122,8 @@ static CURLcode ftp_cwd_and_mkd(struct connectdata *conn, char *path);
|
||||||
static CURLcode ftp_quit(struct connectdata *conn);
|
static CURLcode ftp_quit(struct connectdata *conn);
|
||||||
static CURLcode ftp_3rdparty_pretransfer(struct connectdata *conn);
|
static CURLcode ftp_3rdparty_pretransfer(struct connectdata *conn);
|
||||||
static CURLcode ftp_3rdparty_transfer(struct connectdata *conn);
|
static CURLcode ftp_3rdparty_transfer(struct connectdata *conn);
|
||||||
|
static CURLcode ftp_parse_url_path(struct connectdata *conn);
|
||||||
|
static CURLcode ftp_cwd_and_create_path(struct connectdata *conn);
|
||||||
static CURLcode ftp_regular_transfer(struct connectdata *conn);
|
static CURLcode ftp_regular_transfer(struct connectdata *conn);
|
||||||
static CURLcode ftp_3rdparty(struct connectdata *conn);
|
static CURLcode ftp_3rdparty(struct connectdata *conn);
|
||||||
|
|
||||||
|
@ -2109,23 +2111,9 @@ CURLcode ftp_perform(struct connectdata *conn,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is a re-used connection. Since we change directory to where the
|
result = ftp_cwd_and_create_path(conn);
|
||||||
transfer is taking place, we must now get back to the original dir
|
if (result)
|
||||||
where we ended up after login: */
|
|
||||||
if (conn->bits.reuse && ftp->entrypath) {
|
|
||||||
if ((result = ftp_cwd_and_mkd(conn, ftp->entrypath)) != CURLE_OK)
|
|
||||||
return result;
|
return result;
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
int i; /* counter for loop */
|
|
||||||
for (i=0; i < ftp->dirdepth; i++) {
|
|
||||||
/* 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 = ftp_cwd_and_mkd(conn, ftp->dirs[i])) != CURLE_OK)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Requested time of file or time-depended transfer? */
|
/* Requested time of file or time-depended transfer? */
|
||||||
if((data->set.get_filetime || data->set.timecondition) &&
|
if((data->set.get_filetime || data->set.timecondition) &&
|
||||||
|
@ -2268,6 +2256,10 @@ CURLcode Curl_ftp(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
CURLcode retcode = CURLE_OK;
|
CURLcode retcode = CURLE_OK;
|
||||||
|
|
||||||
|
retcode = ftp_parse_url_path(conn);
|
||||||
|
if (retcode)
|
||||||
|
return retcode;
|
||||||
|
|
||||||
if (conn->sec_conn) /* 3rd party transfer */
|
if (conn->sec_conn) /* 3rd party transfer */
|
||||||
retcode = ftp_3rdparty(conn);
|
retcode = ftp_3rdparty(conn);
|
||||||
else
|
else
|
||||||
|
@ -2546,6 +2538,10 @@ static CURLcode ftp_3rdparty_transfer(struct connectdata *conn)
|
||||||
port_conn = conn;
|
port_conn = conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = ftp_cwd_and_create_path(conn);
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
|
||||||
/* sets the passive mode */
|
/* sets the passive mode */
|
||||||
FTPSENDF(pasv_conn, "%s", "PASV");
|
FTPSENDF(pasv_conn, "%s", "PASV");
|
||||||
result = Curl_GetFTPResponse(&nread, pasv_conn, &ftpcode);
|
result = Curl_GetFTPResponse(&nread, pasv_conn, &ftpcode);
|
||||||
|
@ -2640,35 +2636,25 @@ static CURLcode ftp_3rdparty_transfer(struct connectdata *conn)
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
*
|
*
|
||||||
* ftp_regular_transfer()
|
* ftp_parse_url_path()
|
||||||
*
|
*
|
||||||
* The input argument is already checked for validity.
|
* Parse the URL path into separate path components.
|
||||||
* Performs a regular transfer between local and remote hosts.
|
|
||||||
*
|
*
|
||||||
* ftp->ctl_valid starts out as FALSE, and gets set to TRUE if we reach the
|
|
||||||
* Curl_ftp_done() function without finding any major problem.
|
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
CURLcode ftp_regular_transfer(struct connectdata *conn)
|
CURLcode ftp_parse_url_path(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
CURLcode retcode=CURLE_OK;
|
CURLcode retcode = CURLE_OK;
|
||||||
bool connected=0;
|
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
struct FTP *ftp;
|
struct FTP *ftp;
|
||||||
|
|
||||||
char *slash_pos; /* position of the first '/' char in curpos */
|
char *slash_pos; /* position of the first '/' char in curpos */
|
||||||
char *cur_pos=conn->path; /* current position in ppath. point at the begin
|
char *cur_pos = conn->path; /* current position in path. point at the begin
|
||||||
of next path component */
|
of next path component */
|
||||||
|
|
||||||
/* the ftp struct is already inited in ftp_connect() */
|
/* the ftp struct is already inited in ftp_connect() */
|
||||||
ftp = conn->proto.ftp;
|
ftp = conn->proto.ftp;
|
||||||
ftp->ctl_valid = FALSE;
|
ftp->ctl_valid = FALSE;
|
||||||
conn->size = -1; /* make sure this is unknown at this point */
|
|
||||||
|
|
||||||
Curl_pgrsSetUploadCounter(data, 0);
|
|
||||||
Curl_pgrsSetDownloadCounter(data, 0);
|
|
||||||
Curl_pgrsSetUploadSize(data, 0);
|
|
||||||
Curl_pgrsSetDownloadSize(data, 0);
|
|
||||||
|
|
||||||
ftp->dirdepth = 0;
|
ftp->dirdepth = 0;
|
||||||
ftp->diralloc = 5; /* default dir depth to allocate */
|
ftp->diralloc = 5; /* default dir depth to allocate */
|
||||||
|
@ -2731,6 +2717,72 @@ CURLcode ftp_regular_transfer(struct connectdata *conn)
|
||||||
ftp->file=NULL; /* instead of point to a zero byte, we make it a NULL
|
ftp->file=NULL; /* instead of point to a zero byte, we make it a NULL
|
||||||
pointer */
|
pointer */
|
||||||
|
|
||||||
|
return retcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* ftp_cwd_and_create_path()
|
||||||
|
*
|
||||||
|
* Creates full path on remote target host.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
CURLcode ftp_cwd_and_create_path(struct connectdata *conn)
|
||||||
|
{
|
||||||
|
CURLcode result = CURLE_OK;
|
||||||
|
/* the ftp struct is already inited in Curl_ftp_connect() */
|
||||||
|
struct FTP *ftp = conn->proto.ftp;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* 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_and_mkd(conn, ftp->entrypath)) != CURLE_OK)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i < ftp->dirdepth; i++) {
|
||||||
|
/* 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 = ftp_cwd_and_mkd(conn, ftp->dirs[i])) != CURLE_OK)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* ftp_regular_transfer()
|
||||||
|
*
|
||||||
|
* The input argument is already checked for validity.
|
||||||
|
* Performs a regular transfer between local and remote hosts.
|
||||||
|
*
|
||||||
|
* ftp->ctl_valid starts out as FALSE, and gets set to TRUE if we reach the
|
||||||
|
* Curl_ftp_done() function without finding any major problem.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
CURLcode ftp_regular_transfer(struct connectdata *conn)
|
||||||
|
{
|
||||||
|
CURLcode retcode=CURLE_OK;
|
||||||
|
bool connected=0;
|
||||||
|
struct SessionHandle *data = conn->data;
|
||||||
|
struct FTP *ftp;
|
||||||
|
|
||||||
|
/* the ftp struct is already inited in ftp_connect() */
|
||||||
|
ftp = conn->proto.ftp;
|
||||||
|
conn->size = -1; /* make sure this is unknown at this point */
|
||||||
|
|
||||||
|
Curl_pgrsSetUploadCounter(data, 0);
|
||||||
|
Curl_pgrsSetDownloadCounter(data, 0);
|
||||||
|
Curl_pgrsSetUploadSize(data, 0);
|
||||||
|
Curl_pgrsSetDownloadSize(data, 0);
|
||||||
|
|
||||||
retcode = ftp_perform(conn, &connected);
|
retcode = ftp_perform(conn, &connected);
|
||||||
|
|
||||||
if(CURLE_OK == retcode) {
|
if(CURLE_OK == retcode) {
|
||||||
|
|
Loading…
Reference in New Issue