Fixed the FTP response reader function to properly deal with responses split

up in several chunks when read.
This commit is contained in:
Daniel Stenberg
2005-03-29 11:35:25 +00:00
parent 677a74fa1b
commit 84b4e9ff7c
2 changed files with 30 additions and 18 deletions

View File

@@ -234,6 +234,17 @@ static CURLcode AllowServerConnect(struct connectdata *conn)
return CURLE_OK; return CURLE_OK;
} }
/* initialize stuff to prepare for reading a fresh new response */
static void ftp_respinit(struct connectdata *conn)
{
struct FTP *ftp = conn->proto.ftp;
ftp->nread_resp = 0;
ftp->linestart_resp = conn->data->state.buffer;
}
/* macro to check for the last line in an FTP server response */
#define lastline(line) (isdigit((int)line[0]) && isdigit((int)line[1]) && \
isdigit((int)line[2]) && (' ' == line[3]))
static CURLcode ftp_readresp(curl_socket_t sockfd, static CURLcode ftp_readresp(curl_socket_t sockfd,
struct connectdata *conn, struct connectdata *conn,
@@ -245,7 +256,6 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
ssize_t gotbytes; ssize_t gotbytes;
char *ptr; char *ptr;
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
char *line_start;
char *buf = data->state.buffer; char *buf = data->state.buffer;
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
struct FTP *ftp = conn->proto.ftp; struct FTP *ftp = conn->proto.ftp;
@@ -254,10 +264,10 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
if (ftpcode) if (ftpcode)
*ftpcode = 0; /* 0 for errors or not done */ *ftpcode = 0; /* 0 for errors or not done */
ptr=buf; ptr=buf + ftp->nread_resp;
line_start = buf;
perline=0; perline= ptr-ftp->linestart_resp; /* number of bytes in the current line,
so far */
keepon=TRUE; keepon=TRUE;
while((ftp->nread_resp<BUFSIZE) && (keepon && !result)) { while((ftp->nread_resp<BUFSIZE) && (keepon && !result)) {
@@ -312,7 +322,8 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
/* output debug output if that is requested */ /* output debug output if that is requested */
if(data->set.verbose) if(data->set.verbose)
Curl_debug(data, CURLINFO_HEADER_IN, line_start, perline, conn); Curl_debug(data, CURLINFO_HEADER_IN,
ftp->linestart_resp, perline, conn);
/* /*
* We pass all response-lines to the callback function registered * We pass all response-lines to the callback function registered
@@ -320,24 +331,21 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
* headers. * headers.
*/ */
result = Curl_client_write(data, CLIENTWRITE_HEADER, result = Curl_client_write(data, CLIENTWRITE_HEADER,
line_start, perline); ftp->linestart_resp, perline);
if(result) if(result)
return result; return result;
#define lastline(line) (isdigit((int)line[0]) && isdigit((int)line[1]) && \ if(perline>3 && lastline(ftp->linestart_resp)) {
isdigit((int)line[2]) && (' ' == line[3]))
if(perline>3 && lastline(line_start)) {
/* This is the end of the last line, copy the last line to the /* This is the end of the last line, copy the last line to the
start of the buffer and zero terminate, for old times sake (and start of the buffer and zero terminate, for old times sake (and
krb4)! */ krb4)! */
char *meow; char *meow;
int n; int n;
for(meow=line_start, n=0; meow<ptr; meow++, n++) for(meow=ftp->linestart_resp, n=0; meow<ptr; meow++, n++)
buf[n] = *meow; buf[n] = *meow;
*meow=0; /* zero terminate */ *meow=0; /* zero terminate */
keepon=FALSE; keepon=FALSE;
line_start = ptr+1; /* advance pointer */ ftp->linestart_resp = ptr+1; /* advance pointer */
i++; /* skip this before getting out */ i++; /* skip this before getting out */
*size = ftp->nread_resp; /* size of the response */ *size = ftp->nread_resp; /* size of the response */
@@ -345,7 +353,7 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
break; break;
} }
perline=0; /* line starts over here */ perline=0; /* line starts over here */
line_start = ptr+1; ftp->linestart_resp = ptr+1;
} }
} }
if(!keepon && (i != gotbytes)) { if(!keepon && (i != gotbytes)) {
@@ -356,7 +364,7 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
ftp->cache_size = gotbytes - i; ftp->cache_size = gotbytes - i;
ftp->cache = (char *)malloc((int)ftp->cache_size); ftp->cache = (char *)malloc((int)ftp->cache_size);
if(ftp->cache) if(ftp->cache)
memcpy(ftp->cache, line_start, (int)ftp->cache_size); memcpy(ftp->cache, ftp->linestart_resp, (int)ftp->cache_size);
else else
return CURLE_OUT_OF_MEMORY; /**BANG**/ return CURLE_OUT_OF_MEMORY; /**BANG**/
} }
@@ -549,9 +557,6 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
if(result) if(result)
return result; return result;
#define lastline(line) (isdigit((int)line[0]) && isdigit((int)line[1]) && \
isdigit((int)line[2]) && (' ' == line[3]))
if(perline>3 && lastline(line_start)) { if(perline>3 && lastline(line_start)) {
/* This is the end of the last line, copy the last /* This is the end of the last line, copy the last
* line to the start of the buffer and zero terminate, * line to the start of the buffer and zero terminate,
@@ -2166,7 +2171,7 @@ static CURLcode ftp_state_loggedin(struct connectdata *conn)
if(conn->sec_complete) if(conn->sec_complete)
/* BLOCKING */ /* BLOCKING */
Curl_sec_set_protection_level(conn); Curl_sec_set_protection_level(conn);
/* We may need to issue a KAUTH here to have access to the files /* We may need to issue a KAUTH here to have access to the files
* do it if user supplied a password * do it if user supplied a password
*/ */
@@ -2749,6 +2754,7 @@ CURLcode Curl_ftp_connect(struct connectdata *conn,
/* When we connect, we start in the state where we await the 220 /* When we connect, we start in the state where we await the 220
response */ response */
ftp_respinit(conn); /* init the response reader stuff */
state(conn, FTP_WAIT220); state(conn, FTP_WAIT220);
ftp->response = Curl_tvnow(); /* start response time-out now! */ ftp->response = Curl_tvnow(); /* start response time-out now! */
@@ -3221,6 +3227,8 @@ CURLcode Curl_nbftpsendf(struct connectdata *conn,
bytes_written=0; bytes_written=0;
write_len = strlen(s); write_len = strlen(s);
ftp_respinit(conn);
res = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len, res = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len,
&bytes_written); &bytes_written);

View File

@@ -327,7 +327,11 @@ struct FTP {
bool cwddone; /* if it has been determined that the proper CWD combo bool cwddone; /* if it has been determined that the proper CWD combo
already has been done */ already has been done */
char *prevpath; /* conn->path from the previous transfer */ char *prevpath; /* conn->path from the previous transfer */
size_t nread_resp; /* number of bytes currently read of a server response */ size_t nread_resp; /* number of bytes currently read of a server response */
char *linestart_resp; /* line start pointer for the FTP server response
reader function */
int count1; /* general purpose counter for the state machine */ int count1; /* general purpose counter for the state machine */
int count2; /* general purpose counter for the state machine */ int count2; /* general purpose counter for the state machine */
int count3; /* general purpose counter for the state machine */ int count3; /* general purpose counter for the state machine */