]> granicus.if.org Git - curl/commitdiff
Fixed the FTP response reader function to properly deal with responses split
authorDaniel Stenberg <daniel@haxx.se>
Tue, 29 Mar 2005 11:35:25 +0000 (11:35 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 29 Mar 2005 11:35:25 +0000 (11:35 +0000)
up in several chunks when read.

lib/ftp.c
lib/urldata.h

index 79d03e9796dd934c04238e329713bcd8247c33ad..be4ff413e1f121c77ee55357d0683e97716d4ba0 100644 (file)
--- 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_resp<BUFSIZE) && (keepon && !result)) {
@@ -312,7 +322,8 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
 
           /* output debug output if that is requested */
           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
@@ -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; meow<ptr; meow++, n++)
+            for(meow=ftp->linestart_resp, n=0; meow<ptr; meow++, n++)
               buf[n] = *meow;
             *meow=0; /* zero terminate */
             keepon=FALSE;
-            line_start = ptr+1; /* advance pointer */
+            ftp->linestart_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);
 
index 9b3fcf7dd5cd9d582a01ad9cc6aac4fad4220679..6fa65fcdfacad0d9dd3850810880142110a97c02 100644 (file)
@@ -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 */