From 84b4e9ff7c1eee735e2653db24fbd1fd0ab72ab5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 29 Mar 2005 11:35:25 +0000 Subject: Fixed the FTP response reader function to properly deal with responses split up in several chunks when read. --- lib/ftp.c | 44 ++++++++++++++++++++++++++------------------ lib/urldata.h | 4 ++++ 2 files changed, 30 insertions(+), 18 deletions(-) (limited to 'lib') diff --git a/lib/ftp.c b/lib/ftp.c index 79d03e979..be4ff413e 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -234,6 +234,17 @@ static CURLcode AllowServerConnect(struct connectdata *conn) 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, struct connectdata *conn, @@ -245,7 +256,6 @@ static CURLcode ftp_readresp(curl_socket_t sockfd, ssize_t gotbytes; char *ptr; struct SessionHandle *data = conn->data; - char *line_start; char *buf = data->state.buffer; CURLcode result = CURLE_OK; struct FTP *ftp = conn->proto.ftp; @@ -254,10 +264,10 @@ static CURLcode ftp_readresp(curl_socket_t sockfd, if (ftpcode) *ftpcode = 0; /* 0 for errors or not done */ - ptr=buf; - line_start = buf; + ptr=buf + ftp->nread_resp; - perline=0; + perline= ptr-ftp->linestart_resp; /* number of bytes in the current line, + so far */ keepon=TRUE; while((ftp->nread_respset.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 @@ -320,24 +331,21 @@ static CURLcode ftp_readresp(curl_socket_t sockfd, * headers. */ result = Curl_client_write(data, CLIENTWRITE_HEADER, - line_start, perline); + ftp->linestart_resp, perline); if(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(ftp->linestart_resp)) { /* 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 krb4)! */ char *meow; int n; - for(meow=line_start, n=0; meowlinestart_resp, n=0; meowlinestart_resp = ptr+1; /* advance pointer */ i++; /* skip this before getting out */ *size = ftp->nread_resp; /* size of the response */ @@ -345,7 +353,7 @@ static CURLcode ftp_readresp(curl_socket_t sockfd, break; } perline=0; /* line starts over here */ - line_start = ptr+1; + ftp->linestart_resp = ptr+1; } } if(!keepon && (i != gotbytes)) { @@ -356,7 +364,7 @@ static CURLcode ftp_readresp(curl_socket_t sockfd, ftp->cache_size = gotbytes - i; ftp->cache = (char *)malloc((int)ftp->cache_size); if(ftp->cache) - memcpy(ftp->cache, line_start, (int)ftp->cache_size); + memcpy(ftp->cache, ftp->linestart_resp, (int)ftp->cache_size); else return CURLE_OUT_OF_MEMORY; /**BANG**/ } @@ -549,9 +557,6 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */ if(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)) { /* This is the end of the last line, copy the last * 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) /* BLOCKING */ Curl_sec_set_protection_level(conn); - + /* We may need to issue a KAUTH here to have access to the files * 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 response */ + ftp_respinit(conn); /* init the response reader stuff */ state(conn, FTP_WAIT220); ftp->response = Curl_tvnow(); /* start response time-out now! */ @@ -3221,6 +3227,8 @@ CURLcode Curl_nbftpsendf(struct connectdata *conn, bytes_written=0; write_len = strlen(s); + ftp_respinit(conn); + res = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len, &bytes_written); diff --git a/lib/urldata.h b/lib/urldata.h index 9b3fcf7dd..6fa65fcdf 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -327,7 +327,11 @@ struct FTP { bool cwddone; /* if it has been determined that the proper CWD combo already has been done */ char *prevpath; /* conn->path from the previous transfer */ + 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 count2; /* general purpose counter for the state machine */ int count3; /* general purpose counter for the state machine */ -- cgit v1.2.3