mirror of
https://github.com/curl/curl.git
synced 2024-11-21 01:16:58 +08:00
David Balazic's patch to make the FTP operations "do right" according to
RFC1738, which means it'll use one CWD for each pathpart.
This commit is contained in:
parent
b4fa2ff995
commit
bf2b3dbf3e
89
lib/ftp.c
89
lib/ftp.c
@ -1967,10 +1967,13 @@ CURLcode ftp_perform(struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
/* change directory first! */
|
||||
if(ftp->dir && ftp->dir[0]) {
|
||||
if ((result = ftp_cwd(conn, ftp->dir)) != CURLE_OK)
|
||||
{
|
||||
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)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/* Requested time of file or time-depended transfer? */
|
||||
@ -2091,34 +2094,64 @@ CURLcode ftp_perform(struct connectdata *conn,
|
||||
*/
|
||||
CURLcode Curl_ftp(struct connectdata *conn)
|
||||
{
|
||||
CURLcode retcode;
|
||||
CURLcode retcode=CURLE_OK;
|
||||
bool connected=0;
|
||||
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct FTP *ftp;
|
||||
int dirlength=0; /* 0 forces strlen() */
|
||||
|
||||
char *slash_pos; /* position of the first '/' char in curpos */
|
||||
char *cur_pos=conn->ppath; /* current position in ppath. point at the begin
|
||||
of next path component */
|
||||
int path_part=0;/* current path component */
|
||||
|
||||
/* the ftp struct is already inited in ftp_connect() */
|
||||
ftp = conn->proto.ftp;
|
||||
conn->size = -1; /* make sure this is unknown at this point */
|
||||
|
||||
/* We split the path into dir and file parts *before* we URLdecode
|
||||
it */
|
||||
ftp->file = strrchr(conn->ppath, '/');
|
||||
if(ftp->file) {
|
||||
if(ftp->file != conn->ppath)
|
||||
dirlength=ftp->file-conn->ppath; /* don't count the traling slash */
|
||||
/* fixed : initialize ftp->dirs[xxx] to NULL !
|
||||
is done in Curl_ftp_connect() */
|
||||
|
||||
ftp->file++; /* point to the first letter in the file name part or
|
||||
remain NULL */
|
||||
}
|
||||
else {
|
||||
ftp->file = conn->ppath; /* there's only a file part */
|
||||
/* parse the URL path into separate path components */
|
||||
while((slash_pos=strchr(cur_pos, '/'))) {
|
||||
/* seek out the next path component */
|
||||
if (0 == slash_pos-cur_pos) /* empty path component, like "x//y" */
|
||||
ftp->dirs[path_part] = strdup(""); /* empty string */
|
||||
else
|
||||
ftp->dirs[path_part] = curl_unescape(cur_pos,slash_pos-cur_pos);
|
||||
|
||||
if (!ftp->dirs[path_part]) { /* run out of memory ... */
|
||||
failf(data, "no memory");
|
||||
retcode = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
else {
|
||||
cur_pos = slash_pos + 1; /* jump to the rest of the string */
|
||||
if(++path_part >= CURL_MAX_FTP_DIRDEPTH) {
|
||||
/* too deep */
|
||||
failf(data, "too deep dir hierarchy");
|
||||
retcode = CURLE_URL_MALFORMAT;
|
||||
}
|
||||
}
|
||||
if (retcode) {
|
||||
int i;
|
||||
for (i=0;i<path_part;i++) { /* free previous parts */
|
||||
free(ftp->dirs[i]);
|
||||
ftp->dirs[i]=NULL;
|
||||
}
|
||||
return retcode; /* failure */
|
||||
}
|
||||
}
|
||||
|
||||
ftp->file = cur_pos; /* the rest is the file name */
|
||||
|
||||
if(*ftp->file) {
|
||||
ftp->file = curl_unescape(ftp->file, 0);
|
||||
if(NULL == ftp->file) {
|
||||
int i;
|
||||
for (i=0;i<path_part;i++){
|
||||
free(ftp->dirs[i]);
|
||||
ftp->dirs[i]=NULL;
|
||||
}
|
||||
failf(data, "no memory");
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
@ -2126,20 +2159,7 @@ CURLcode Curl_ftp(struct connectdata *conn)
|
||||
else
|
||||
ftp->file=NULL; /* instead of point to a zero byte, we make it a NULL
|
||||
pointer */
|
||||
|
||||
ftp->urlpath = conn->ppath;
|
||||
if(dirlength) {
|
||||
ftp->dir = curl_unescape(ftp->urlpath, dirlength);
|
||||
if(NULL == ftp->dir) {
|
||||
if(ftp->file)
|
||||
free(ftp->file);
|
||||
failf(data, "no memory");
|
||||
return CURLE_OUT_OF_MEMORY; /* failure */
|
||||
}
|
||||
}
|
||||
else
|
||||
ftp->dir = NULL;
|
||||
|
||||
|
||||
retcode = ftp_perform(conn, &connected);
|
||||
|
||||
if(CURLE_OK == retcode) {
|
||||
@ -2219,6 +2239,7 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
|
||||
CURLcode Curl_ftp_disconnect(struct connectdata *conn)
|
||||
{
|
||||
struct FTP *ftp= conn->proto.ftp;
|
||||
int i;
|
||||
|
||||
/* The FTP session may or may not have been allocated/setup at this point! */
|
||||
if(ftp) {
|
||||
@ -2228,10 +2249,12 @@ CURLcode Curl_ftp_disconnect(struct connectdata *conn)
|
||||
free(ftp->cache);
|
||||
if(ftp->file)
|
||||
free(ftp->file);
|
||||
if(ftp->dir)
|
||||
free(ftp->dir);
|
||||
for (i=0;ftp->dirs[i];i++){
|
||||
free(ftp->dirs[i]);
|
||||
ftp->dirs[i]=NULL;
|
||||
}
|
||||
|
||||
ftp->file = ftp->dir = NULL; /* zero */
|
||||
ftp->file = NULL; /* zero */
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user