Skip to content

Commit

Permalink
Alexander Krasnostavsky made the CURLOPT_FTP_CREATE_MISSING_DIRS opti…
Browse files Browse the repository at this point in the history
…on work

fine even for third party transfers.
  • Loading branch information
bagder committed Oct 16, 2004
1 parent f40c9b8 commit 21d5aea
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 33 deletions.
3 changes: 3 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
Changelog

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
memory for cookies with the "max-age" field set.

Expand Down
118 changes: 85 additions & 33 deletions lib/ftp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_3rdparty_pretransfer(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_3rdparty(struct connectdata *conn);

Expand Down Expand Up @@ -2109,23 +2111,9 @@ CURLcode ftp_perform(struct connectdata *conn,
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_and_mkd(conn, ftp->entrypath)) != CURLE_OK)
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;
}
}
result = ftp_cwd_and_create_path(conn);
if (result)
return result;

/* Requested time of file or time-depended transfer? */
if((data->set.get_filetime || data->set.timecondition) &&
Expand Down Expand Up @@ -2268,6 +2256,10 @@ CURLcode Curl_ftp(struct connectdata *conn)
{
CURLcode retcode = CURLE_OK;

retcode = ftp_parse_url_path(conn);
if (retcode)
return retcode;

if (conn->sec_conn) /* 3rd party transfer */
retcode = ftp_3rdparty(conn);
else
Expand Down Expand Up @@ -2546,6 +2538,10 @@ static CURLcode ftp_3rdparty_transfer(struct connectdata *conn)
port_conn = conn;
}

result = ftp_cwd_and_create_path(conn);
if (result)
return result;

/* sets the passive mode */
FTPSENDF(pasv_conn, "%s", "PASV");
result = Curl_GetFTPResponse(&nread, pasv_conn, &ftpcode);
Expand Down Expand Up @@ -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.
* Performs a regular transfer between local and remote hosts.
* Parse the URL path into separate path components.
*
* 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 ftp_parse_url_path(struct connectdata *conn)
{
CURLcode retcode=CURLE_OK;
bool connected=0;
CURLcode retcode = CURLE_OK;
struct SessionHandle *data = conn->data;
struct FTP *ftp;

char *slash_pos; /* position of the first '/' char in curpos */
char *cur_pos=conn->path; /* current position in ppath. point at the begin
of next path component */
char *cur_pos = conn->path; /* current position in path. point at the begin
of next path component */

/* the ftp struct is already inited in ftp_connect() */
ftp = conn->proto.ftp;
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->diralloc = 5; /* default dir depth to allocate */
Expand Down Expand Up @@ -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
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);

if(CURLE_OK == retcode) {
Expand Down

0 comments on commit 21d5aea

Please sign in to comment.