Curl_GetFTPResponse() takes a different set of parameters and now return a
authorDaniel Stenberg <daniel@haxx.se>
Tue, 3 Dec 2002 10:25:31 +0000 (10:25 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 3 Dec 2002 10:25:31 +0000 (10:25 +0000)
proper CURLcode. The default timeout for reading one response is now also
possible to change while running.

lib/ftp.c
lib/ftp.h
lib/krb4.c
lib/security.c
lib/urldata.h

index 4f08a53..07ae210 100644 (file)
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -173,9 +173,9 @@ static CURLcode AllowServerConnect(struct SessionHandle *data,
  * response and extract the relevant return code for the invoking function.
  */
 
-int Curl_GetFTPResponse(char *buf,
-                        struct connectdata *conn,
-                        int *ftpcode)
+CURLcode Curl_GetFTPResponse(int *nreadp, /* return number of bytes read */
+                             struct connectdata *conn,
+                             int *ftpcode) /* return the ftp-code */
 {
   /* Brand new implementation.
    * We cannot read just one byte per read() and then go back to select()
@@ -190,23 +190,17 @@ int Curl_GetFTPResponse(char *buf,
   bool keepon=TRUE;
   ssize_t gotbytes;
   char *ptr;
-  int timeout = 3600; /* default timeout in seconds */
+  int timeout;              /* timeout in seconds */
   struct timeval interval;
   fd_set rkeepfd;
   fd_set readfd;
   struct SessionHandle *data = conn->data;
   char *line_start;
-  int code=0; /* default "error code" to return */
-
-#define SELECT_OK       0
-#define SELECT_ERROR    1 /* select() problems */
-#define SELECT_TIMEOUT  2 /* took too long */
-#define SELECT_MEMORY   3 /* no available memory */
-#define SELECT_CALLBACK 4 /* aborted by callback */
-
-  int error = SELECT_OK;
-
+  int code=0; /* default ftp "error code" to return */
+  char *buf = data->state.buffer;
+  CURLcode result = CURLE_OK;
   struct FTP *ftp = conn->proto.ftp;
+  struct timeval now = Curl_tvnow();
 
   if (ftpcode)
     *ftpcode = 0; /* 0 for errors */
@@ -225,16 +219,21 @@ int Curl_GetFTPResponse(char *buf,
   perline=0;
   keepon=TRUE;
 
-  while((nread<BUFSIZE) && (keepon && !error)) {
+  while((nread<BUFSIZE) && (keepon && !result)) {
     /* check and reset timeout value every lap */
-    if(data->set.timeout) {
+    if(data->set.timeout)
       /* if timeout is requested, find out how much remaining time we have */
       timeout = data->set.timeout - /* timeout time */
         Curl_tvdiff(Curl_tvnow(), conn->now)/1000; /* spent time */
-      if(timeout <=0 ) {
-        failf(data, "Transfer aborted due to timeout");
-        return -SELECT_TIMEOUT; /* already too little time */
-      }
+    else
+      /* Even without a requested timeout, we only wait response_time
+         seconds for the full response to arrive before we bail out */
+      timeout = ftp->response_time -
+        Curl_tvdiff(Curl_tvnow(), now)/1000; /* spent time */
+
+    if(timeout <=0 ) {
+      failf(data, "Transfer aborted due to timeout");
+      return CURLE_OPERATION_TIMEDOUT; /* already too little time */
     }
 
     if(!ftp->cache) {
@@ -244,19 +243,18 @@ int Curl_GetFTPResponse(char *buf,
 
       switch (select (sockfd+1, &readfd, NULL, NULL, &interval)) {
       case -1: /* select() error, stop reading */
-        error = SELECT_ERROR;
-        failf(data, "Transfer aborted due to select() error");
+        result = CURLE_RECV_ERROR;
+        failf(data, "Transfer aborted due to select() error: %d", errno);
         break;
       case 0: /* timeout */
-        error = SELECT_TIMEOUT;
+        result = CURLE_OPERATION_TIMEDOUT;
         failf(data, "Transfer aborted due to timeout");
         break;
       default:
-        error = SELECT_OK;
         break;
       }
     }
-    if(SELECT_OK == error) {
+    if(CURLE_OK == result) {
       /*
        * This code previously didn't use the kerberos sec_read() code
        * to read, but when we use Curl_read() it may do so. Do confirm
@@ -272,8 +270,7 @@ int Curl_GetFTPResponse(char *buf,
         ftp->cache_size = 0; /* zero the size just in case */
       }
       else {
-        int res = Curl_read(conn, sockfd, ptr,
-                            BUFSIZE-nread, &gotbytes);
+        int res = Curl_read(conn, sockfd, ptr, BUFSIZE-nread, &gotbytes);
         if(res < 0)
           /* EWOULDBLOCK */
           continue; /* go looping again */
@@ -286,7 +283,7 @@ int Curl_GetFTPResponse(char *buf,
         ;
       else if(gotbytes <= 0) {
         keepon = FALSE;
-        error = SELECT_ERROR;
+        result = CURLE_RECV_ERROR;
         failf(data, "Connection aborted");
       }
       else {
@@ -315,7 +312,7 @@ int Curl_GetFTPResponse(char *buf,
             result = Curl_client_write(data, CLIENTWRITE_HEADER,
                                        line_start, perline);
             if(result)
-              return -SELECT_CALLBACK;
+              return result;
                                        
 #define lastline(line) (isdigit((int)line[0]) && isdigit((int)line[1]) && \
                        isdigit((int)line[2]) && (' ' == line[3]))
@@ -350,13 +347,13 @@ int Curl_GetFTPResponse(char *buf,
           if(ftp->cache)
             memcpy(ftp->cache, line_start, ftp->cache_size);
           else
-            return -SELECT_MEMORY; /**BANG**/
+            return CURLE_OUT_OF_MEMORY; /**BANG**/
         }
       } /* there was data */
     } /* if(no error) */
   } /* while there's buffer left and loop is requested */
 
-  if(!error)
+  if(!result)
     code = atoi(buf);
 
 #ifdef KRB4
@@ -378,13 +375,11 @@ int Curl_GetFTPResponse(char *buf,
   }
 #endif
 
-  if(error)
-    return -error;
-
   if(ftpcode)
     *ftpcode=code; /* return the initial number like this */
 
-  return nread; /* total amount of bytes read */
+  *nreadp = nread; /* total amount of bytes read */
+  return result;
 }
 
 /*
@@ -418,6 +413,8 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
   ftp->user = data->state.user;
   ftp->passwd = data->state.passwd;
 
+  ftp->response_time = 3600; /* default response time-out */
+
   if (data->set.tunnel_thru_httpproxy) {
     /* We want "seamless" FTP operations through HTTP proxy tunnel */
     result = Curl_ConnectHTTPProxyTunnel(conn, conn->firstsocket,
@@ -436,9 +433,9 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
 
 
   /* The first thing we do is wait for the "220*" line: */
-  nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
-  if(nread < 0)
-    return CURLE_OPERATION_TIMEOUTED;
+  result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+  if(result)
+    return result;
 
   if(ftpcode != 220) {
     failf(data, "This doesn't seem like a nice ftp-server response");
@@ -467,9 +464,9 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
   FTPSENDF(conn, "USER %s", ftp->user);
 
   /* wait for feedback */
-  nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
-  if(nread < 0)
-    return CURLE_OPERATION_TIMEOUTED;
+  result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+  if(result)
+    return result;
 
   if(ftpcode == 530) {
     /* 530 User ... access denied
@@ -481,9 +478,9 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
     /* 331 Password required for ...
        (the server requires to send the user's password too) */
     FTPSENDF(conn, "PASS %s", ftp->passwd);
-    nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
-    if(nread < 0)
-      return CURLE_OPERATION_TIMEOUTED;
+    result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+    if(result)
+      return result;
 
     if(ftpcode == 530) {
       /* 530 Login incorrect.
@@ -516,8 +513,11 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
     /* we may need to issue a KAUTH here to have access to the files
      * do it if user supplied a password
      */
-    if(data->state.passwd && *data->state.passwd)
-      Curl_krb_kauth(conn);
+    if(data->state.passwd && *data->state.passwd) {
+      result = Curl_krb_kauth(conn);
+      if(result)
+        return result;
+    }
 #endif
   }
   else {
@@ -529,9 +529,9 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
   FTPSENDF(conn, "PWD", NULL);
 
   /* wait for feedback */
-  nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
-  if(nread < 0)
-    return CURLE_OPERATION_TIMEOUTED;
+  result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+  if(result)
+    return result;
 
   if(ftpcode == 257) {
     char *dir = (char *)malloc(nread+1);
@@ -596,7 +596,6 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
   struct SessionHandle *data = conn->data;
   struct FTP *ftp = conn->proto.ftp;
   ssize_t nread;
-  char *buf = data->state.buffer; /* this is our buffer */
   int ftpcode;
   CURLcode result=CURLE_OK;
 
@@ -637,9 +636,9 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
   if(!ftp->no_transfer) {
     /* now let's see what the server says about the transfer we just
        performed: */
-    nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
-    if(nread < 0)
-      return CURLE_OPERATION_TIMEOUTED;
+    result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+    if(result)
+      return result;
 
     if(!ftp->dont_check) {
       /* 226 Transfer complete, 250 Requested file action okay, completed. */
@@ -682,9 +681,9 @@ CURLcode ftp_sendquote(struct connectdata *conn, struct curl_slist *quote)
     if (item->data) {
       FTPSENDF(conn, "%s", item->data);
 
-      nread = Curl_GetFTPResponse(conn->data->state.buffer, conn, &ftpcode);
-      if (nread < 0)
-        return CURLE_OPERATION_TIMEOUTED;
+      result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+      if (result)
+        return result;
 
       if (ftpcode >= 400) {
         failf(conn->data, "QUOT string not accepted: %s", item->data);
@@ -713,9 +712,9 @@ CURLcode ftp_cwd(struct connectdata *conn, char *path)
   CURLcode result;
   
   FTPSENDF(conn, "CWD %s", path);
-  nread = Curl_GetFTPResponse(conn->data->state.buffer, conn, &ftpcode);
-  if (nread < 0)
-    return CURLE_OPERATION_TIMEOUTED;
+  result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+  if (result)
+    return result;
 
   if (ftpcode != 250) {
     failf(conn->data, "Couldn't cd to %s", path);
@@ -743,9 +742,9 @@ CURLcode ftp_getfiletime(struct connectdata *conn, char *file)
      again a grey area as the MDTM is not kosher RFC959 */
   FTPSENDF(conn, "MDTM %s", file);
 
-  nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
-  if(nread < 0)
-    return CURLE_OPERATION_TIMEOUTED;
+  result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+  if(result)
+    return result;
 
   if(ftpcode == 213) {
     /* we got a time. Format should be: "YYYYMMDDHHMMSS[.sss]" where the
@@ -780,14 +779,13 @@ static CURLcode ftp_transfertype(struct connectdata *conn,
   struct SessionHandle *data = conn->data;
   int ftpcode;
   ssize_t nread;
-  char *buf=data->state.buffer;
   CURLcode result;
 
   FTPSENDF(conn, "TYPE %s", ascii?"A":"I");
 
-  nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
-  if(nread < 0)
-    return CURLE_OPERATION_TIMEOUTED;
+  result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+  if(result)
+    return result;
   
   if(ftpcode != 200) {
     failf(data, "Couldn't set %s mode",
@@ -816,9 +814,9 @@ CURLcode ftp_getsize(struct connectdata *conn, char *file,
   CURLcode result;
 
   FTPSENDF(conn, "SIZE %s", file);
-  nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
-  if(nread < 0)
-    return CURLE_OPERATION_TIMEOUTED;
+  result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+  if(result)
+    return result;
 
   if(ftpcode == 213) {
     /* get the size from the ascii string: */
@@ -977,7 +975,6 @@ CURLcode ftp_use_port(struct connectdata *conn)
   struct SessionHandle *data=conn->data;
   int portsock=-1;
   ssize_t nread;
-  char *buf = data->state.buffer; /* this is our buffer */
   int ftpcode; /* receive FTP response codes in this */
   CURLcode result;
 
@@ -1157,9 +1154,9 @@ CURLcode ftp_use_port(struct connectdata *conn)
         return result;
     }
     
-    nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
-    if(nread < 0)
-      return CURLE_OPERATION_TIMEOUTED;
+    result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+    if(result)
+      return result;
     
     if (ftpcode != 200) {
       failf(data, "Server does not grok %s", *modep);
@@ -1303,9 +1300,9 @@ CURLcode ftp_use_port(struct connectdata *conn)
       return result;
   }
 
-  nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
-  if(nread < 0)
-    return CURLE_OPERATION_TIMEOUTED;
+  result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+  if(result)
+    return result;
 
   if(ftpcode != 200) {
     failf(data, "Server does not grok PORT, try without it!");
@@ -1377,9 +1374,9 @@ CURLcode ftp_use_pasv(struct connectdata *conn,
     result = Curl_ftpsendf(conn, "%s", mode[modeoff]);
     if(result)
       return result;
-    nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
-    if(nread < 0)
-      return CURLE_OPERATION_TIMEOUTED;
+    result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+    if(result)
+      return result;
     if (ftpcode == results[modeoff])
       break;
   }
@@ -1524,7 +1521,7 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
   ssize_t nread;
   int ftpcode; /* for ftp status */
 
-  /* the ftp struct is already inited in ftp_connect() */
+  /* the ftp struct is already inited in Curl_ftp_connect() */
   struct FTP *ftp = conn->proto.ftp;
   long *bytecountp = ftp->bytecountp;
 
@@ -1625,9 +1622,9 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
       FTPSENDF(conn, "STOR %s", ftp->file);
     }
 
-    nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
-    if(nread < 0)
-      return CURLE_OPERATION_TIMEOUTED;
+    result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+    if(result)
+      return result;
 
     if(ftpcode>=400) {
       failf(data, "Failed FTP upload:%s", buf+3);
@@ -1801,9 +1798,9 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
 
         FTPSENDF(conn, "REST %d", conn->resume_from);
 
-        nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
-        if(nread < 0)
-          return CURLE_OPERATION_TIMEOUTED;
+        result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+        if(result)
+          return result;
 
         if(ftpcode != 350) {
           failf(data, "Couldn't use REST: %s", buf+4);
@@ -1814,9 +1811,9 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
       FTPSENDF(conn, "RETR %s", ftp->file);
     }
 
-    nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
-    if(nread < 0)
-      return CURLE_OPERATION_TIMEOUTED;
+    result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+    if(result)
+      return result;
 
     if((ftpcode == 150) || (ftpcode == 125)) {
 
@@ -1921,7 +1918,7 @@ CURLcode ftp_perform(struct connectdata *conn,
   struct SessionHandle *data=conn->data;
   char *buf = data->state.buffer; /* this is our buffer */
 
-  /* the ftp struct is already inited in ftp_connect() */
+  /* the ftp struct is already inited in Curl_ftp_connect() */
   struct FTP *ftp = conn->proto.ftp;
 
   /* Send any QUOTE strings? */
index 2f8c15a..60440db 100644 (file)
--- a/lib/ftp.h
+++ b/lib/ftp.h
@@ -29,8 +29,8 @@ CURLcode Curl_ftp_done(struct connectdata *conn);
 CURLcode Curl_ftp_connect(struct connectdata *conn);
 CURLcode Curl_ftp_disconnect(struct connectdata *conn);
 CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...);
-int Curl_GetFTPResponse(char *buf, struct connectdata *conn,
-                        int *ftpcode);
+CURLcode Curl_GetFTPResponse(int *nread, struct connectdata *conn,
+                             int *ftpcode);
 CURLcode Curl_ftp_nextconnect(struct connectdata *conn);
 #endif
 
index b596383..88da670 100644 (file)
@@ -202,6 +202,7 @@ krb4_auth(void *app_data, struct connectdata *conn)
   ssize_t nread;
   int l = sizeof(conn->local_addr);
   struct SessionHandle *data = conn->data;
+  CURLcode result;
 
   if(getsockname(conn->firstsocket,
                  (struct sockaddr *)LOCAL_ADDR, &l) < 0)
@@ -246,13 +247,15 @@ krb4_auth(void *app_data, struct connectdata *conn)
     return AUTH_CONTINUE;
   }
 
-  if(Curl_ftpsendf(conn, "ADAT %s", p))
+  result = Curl_ftpsendf(conn, "ADAT %s", p);
+
+  free(p);
+
+  if(result)
     return -2;
 
-  nread = Curl_GetFTPResponse(data->state.buffer, conn, NULL);
-  if(nread < 0)
+  if(Curl_GetFTPResponse(&nread, conn, NULL))
     return -1;
-  free(p);
 
   if(data->state.buffer[0] != '2'){
     Curl_failf(data, "Server didn't accept auth data");
@@ -299,7 +302,7 @@ struct Curl_sec_client_mech Curl_krb4_client_mech = {
     krb4_decode
 };
 
-void Curl_krb_kauth(struct connectdata *conn)
+CURLcode Curl_krb_kauth(struct connectdata *conn)
 {
   des_cblock key;
   des_key_schedule schedule;
@@ -309,18 +312,19 @@ void Curl_krb_kauth(struct connectdata *conn)
   char passwd[100];
   int tmp;
   ssize_t nread;
-       
   int save;
+  CURLcode result;
 
   save = Curl_set_command_prot(conn, prot_private);
 
-  if(Curl_ftpsendf(conn, "SITE KAUTH %s", conn->data->state.user))
-    return;
+  result = Curl_ftpsendf(conn, "SITE KAUTH %s", conn->data->state.user);
+
+  if(result)
+    return result;
 
-  nread = Curl_GetFTPResponse(conn->data->state.buffer,
-                              conn, NULL);
-  if(nread < 0)
-    return /*CURLE_OPERATION_TIMEOUTED*/;
+  result = Curl_GetFTPResponse(&nread, conn, NULL);
+  if(result)
+    return result;
 
   if(conn->data->state.buffer[0] != '3'){
     Curl_set_command_prot(conn, save);
@@ -331,7 +335,7 @@ void Curl_krb_kauth(struct connectdata *conn)
   if(!p) {
     Curl_failf(conn->data, "Bad reply from server");
     Curl_set_command_prot(conn, save);
-    return;
+    return CURLE_FTP_WEIRD_SERVER_REPLY;
   }
 
   p += 2;
@@ -339,7 +343,7 @@ void Curl_krb_kauth(struct connectdata *conn)
   if(tmp < 0) {
     Curl_failf(conn->data, "Failed to decode base64 in reply.\n");
     Curl_set_command_prot(conn, save);
-    return;
+    return CURLE_FTP_WEIRD_SERVER_REPLY;
   }
   tkt.length = tmp;
   tktcopy.length = tkt.length;
@@ -348,7 +352,7 @@ void Curl_krb_kauth(struct connectdata *conn)
   if(!p) {
     Curl_failf(conn->data, "Bad reply from server");
     Curl_set_command_prot(conn, save);
-    return;
+    return CURLE_FTP_WEIRD_SERVER_REPLY;
   }
   name = p + 2;
   for(; *p && *p != ' ' && *p != '\r' && *p != '\n'; p++);
@@ -376,19 +380,21 @@ void Curl_krb_kauth(struct connectdata *conn)
   if(Curl_base64_encode(tktcopy.dat, tktcopy.length, &p) < 0) {
     failf(conn->data, "Out of memory base64-encoding.");
     Curl_set_command_prot(conn, save);
-    return;
+    return CURLE_OUT_OF_MEMORY;
   }
   memset (tktcopy.dat, 0, tktcopy.length);
 
-  if(Curl_ftpsendf(conn, "SITE KAUTH %s %s", name, p))
-    return;
-
-  nread = Curl_GetFTPResponse(conn->data->state.buffer,
-                              conn, NULL);
-  if(nread < 0)
-    return /*CURLE_OPERATION_TIMEOUTED*/;
+  result = Curl_ftpsendf(conn, "SITE KAUTH %s %s", name, p);
   free(p);
+  if(result)
+    return result;
+
+  result = Curl_GetFTPResponse(&nread, conn, NULL);
+  if(result)
+    return result;
   Curl_set_command_prot(conn, save);
+
+  return CURLE_OK;
 }
 
 #endif /* KRB4 */
index 06dec32..653772a 100644 (file)
@@ -414,14 +414,14 @@ sec_prot_internal(struct connectdata *conn, int level)
   }
 
   if(level){
+    int code;
     if(Curl_ftpsendf(conn, "PBSZ %u", s))
       return -1;
 
-    nread = Curl_GetFTPResponse(conn->data->state.buffer, conn, NULL);
-    if(nread < 0)
+    if(Curl_GetFTPResponse(&nread, conn, &code))
       return -1;
 
-    if(conn->data->state.buffer[0] != '2'){
+    if(code/100 != '2'){
       failf(conn->data, "Failed to set protection buffer size.");
       return -1;
     }
@@ -437,8 +437,7 @@ sec_prot_internal(struct connectdata *conn, int level)
   if(Curl_ftpsendf(conn, "PROT %c", level["CSEP"]))
     return -1;
 
-  nread = Curl_GetFTPResponse(conn->data->state.buffer, conn, NULL);
-  if(nread < 0)
+  if(Curl_GetFTPResponse(&nread, conn, NULL))
     return -1;
 
   if(conn->data->state.buffer[0] != '2'){
@@ -496,8 +495,7 @@ Curl_sec_login(struct connectdata *conn)
     if(Curl_ftpsendf(conn, "AUTH %s", (*m)->name))
       return -1;
 
-    nread = Curl_GetFTPResponse(conn->data->state.buffer, conn, &ftpcode);
-    if(nread < 0)
+    if(Curl_GetFTPResponse(&nread, conn, &ftpcode))
       return -1;
 
     if(conn->data->state.buffer[0] != '3'){
index f123a77..d53dc9c 100644 (file)
@@ -190,7 +190,9 @@ struct FTP {
                        read the line, just ignore the result. */
   bool no_transfer; /* nothing was transfered, (possibly because a resumed
                        transfer already was complete) */
-
+  long response_time; /* When no timeout is given, this is the amount of
+                         seconds we await for an FTP response. Initialized
+                         in Curl_ftp_connect() */
 };
 
 /****************************************************************************