Curl_done() and the protocol-specific conn->curl_done() functions now all
authorDaniel Stenberg <daniel@haxx.se>
Wed, 12 May 2004 12:06:39 +0000 (12:06 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Wed, 12 May 2004 12:06:39 +0000 (12:06 +0000)
take a CURLcode as a second argument, that is non-zero when Curl_done()
is called after an error was returned from Curl_do() (or similar).

lib/ftp.c
lib/ftp.h
lib/http.c
lib/http.h
lib/multi.c
lib/telnet.c
lib/telnet.h
lib/transfer.c
lib/url.c
lib/url.h
lib/urldata.h

index e4a6878..6287b4f 100644 (file)
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -738,13 +738,14 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
  *
  * Input argument is already checked for validity.
  */
-CURLcode Curl_ftp_done(struct connectdata *conn)
+CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status)
 {
   struct SessionHandle *data = conn->data;
   struct FTP *ftp = conn->proto.ftp;
   ssize_t nread;
   int ftpcode;
   CURLcode result=CURLE_OK;
+
   bool was_ctl_valid = ftp->ctl_valid;
 
   /* free the dir tree and file parts */
@@ -784,8 +785,24 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
       result = CURLE_FTP_COULDNT_RETR_FILE;
     }
   }
-  
-  ftp->ctl_valid = was_ctl_valid;
+
+  switch(status) {
+  case CURLE_BAD_DOWNLOAD_RESUME:
+  case CURLE_FTP_WEIRD_PASV_REPLY:
+  case CURLE_FTP_PORT_FAILED:
+  case CURLE_FTP_COULDNT_SET_BINARY:
+  case CURLE_FTP_COULDNT_RETR_FILE:
+  case CURLE_FTP_ACCESS_DENIED:
+    /* the connection stays alive fine even though this happened */
+    /* fall-through */
+  case CURLE_OK: /* doesn't affect the control connection's status */
+    ftp->ctl_valid = was_ctl_valid;
+    break;
+  default:       /* by default, an error means the control connection is
+                    wedged and should not be used anymore */
+    ftp->ctl_valid = FALSE;
+    break;
+  }
 
 #ifdef HAVE_KRB4
   Curl_sec_fflush_fd(conn, conn->sock[SECONDARYSOCKET]);
@@ -794,12 +811,12 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
   sclose(conn->sock[SECONDARYSOCKET]);
   conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
 
-  if(!ftp->no_transfer) {
+  if(!ftp->no_transfer && !status) {
     /* Let's see what the server says about the transfer we just performed,
-       but lower the timeout as sometimes this connection has died while 
-       the data has been transfered. This happens when doing through NATs
-       etc that abandon old silent connections.
-    */
+     * but lower the timeout as sometimes this connection has died while the
+     * data has been transfered. This happens when doing through NATs etc that
+     * abandon old silent connections.
+     */
     ftp->response_time = 60; /* give it only a minute for now */
 
     result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
index 3d0ab7d..dc7cf79 100644 (file)
--- a/lib/ftp.h
+++ b/lib/ftp.h
@@ -25,7 +25,7 @@
 
 #ifndef CURL_DISABLE_FTP
 CURLcode Curl_ftp(struct connectdata *conn);
-CURLcode Curl_ftp_done(struct connectdata *conn);
+CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode);
 CURLcode Curl_ftp_connect(struct connectdata *conn);
 CURLcode Curl_ftp_disconnect(struct connectdata *conn);
 CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...);
index 48bffa9..41b0398 100644 (file)
@@ -1172,10 +1172,12 @@ CURLcode Curl_http_connect(struct connectdata *conn)
  * has been performed.
  */
 
-CURLcode Curl_http_done(struct connectdata *conn)
+CURLcode Curl_http_done(struct connectdata *conn,
+                        CURLcode status)
 {
   struct SessionHandle *data;
   struct HTTP *http;
+  (void)status; /* no use for us */
 
   data=conn->data;
   http=conn->proto.http;
index 944314a..2d3b39d 100644 (file)
@@ -35,7 +35,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
 
 /* protocol-specific functions set up to be called by the main engine */
 CURLcode Curl_http(struct connectdata *conn);
-CURLcode Curl_http_done(struct connectdata *conn);
+CURLcode Curl_http_done(struct connectdata *, CURLcode);
 CURLcode Curl_http_connect(struct connectdata *conn);
 
 /* The following functions are defined in http_chunks.c */
index 0476b1d..fe03a5d 100644 (file)
@@ -329,7 +329,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
         char *gotourl;
         Curl_posttransfer(easy->easy_handle);
 
-        easy->result = Curl_done(easy->easy_conn);
+        easy->result = Curl_done(easy->easy_conn, CURLE_OK);
         if(CURLE_OK == easy->result) {
           gotourl = strdup(easy->easy_handle->change.url);
           easy->easy_handle->change.url_changed = FALSE;
@@ -491,7 +491,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
             easy->easy_conn->sock[SECONDARYSOCKET]=-1;
           }
           Curl_posttransfer(easy->easy_handle);
-          Curl_done(easy->easy_conn);
+          Curl_done(easy->easy_conn, easy->result);
         }
 
         /* after the transfer is done, go DONE */
@@ -504,7 +504,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
           if(easy->easy_conn->newurl) {
             char *newurl = easy->easy_conn->newurl;
             easy->easy_conn->newurl = NULL;
-            easy->result = Curl_done(easy->easy_conn);
+            easy->result = Curl_done(easy->easy_conn, CURLE_OK);
             if(easy->result == CURLE_OK)
               easy->result = Curl_follow(easy->easy_handle, newurl);
             if(CURLE_OK == easy->result) {
@@ -520,7 +520,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
         break;
       case CURLM_STATE_DONE:
         /* post-transfer command */
-        easy->result = Curl_done(easy->easy_conn);
+        easy->result = Curl_done(easy->easy_conn, CURLE_OK);
 
         /* after we have DONE what we're supposed to do, go COMPLETED, and
            it doesn't matter what the Curl_done() returned! */
index 0408d73..fb4ba5e 100644 (file)
@@ -1063,9 +1063,11 @@ void telrcv(struct connectdata *conn,
   }
 }
 
-CURLcode Curl_telnet_done(struct connectdata *conn)
+CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode status)
 {
   struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
+  (void)status; /* unused */
+
   curl_slist_free_all(tn->telnet_vars);
 
   free(conn->proto.telnet);
index 2b6f22b..86dd99b 100644 (file)
@@ -25,6 +25,6 @@
  ***************************************************************************/
 #ifndef CURL_DISABLE_TELNET
 CURLcode Curl_telnet(struct connectdata *conn);
-CURLcode Curl_telnet_done(struct connectdata *conn);
+CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode);
 #endif
 #endif
index 67f3289..95dbf56 100644 (file)
@@ -853,6 +853,8 @@ CURLcode Curl_readwrite(struct connectdata *conn,
                   *ptr = '\0';   /* zero terminate */
                   conn->newurl = strdup(start); /* clone string */
                   *ptr = backup; /* restore ending letter */
+                  if(!conn->newurl)
+                    return CURLE_OUT_OF_MEMORY;
                 }
               }
 #if 0 /* for consideration */
@@ -1967,7 +1969,7 @@ CURLcode Curl_perform(struct SessionHandle *data)
          to the new URL */
       urlchanged = data->change.url_changed;
       if ((CURLE_OK == res) && urlchanged) {
-        res = Curl_done(conn);
+        res = Curl_done(conn, res);
         if(CURLE_OK == res) {
           char *gotourl = strdup(data->change.url);
           res = Curl_follow(data, gotourl);
@@ -2024,14 +2026,14 @@ CURLcode Curl_perform(struct SessionHandle *data)
 
         /* Always run Curl_done(), even if some of the previous calls
            failed, but return the previous (original) error code */
-        res2 = Curl_done(conn);
+        res2 = Curl_done(conn, res);
 
         if(CURLE_OK == res)
           res = res2;
       }
       else
         /* Curl_do() failed, clean up left-overs in the done-call */
-        res2 = Curl_done(conn);
+        res2 = Curl_done(conn, res);
 
       /*
        * Important: 'conn' cannot be used here, since it may have been closed
index 2d10998..96b02f4 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -3229,6 +3229,8 @@ static CURLcode SetupConnection(struct connectdata *conn,
       Curl_safefree(conn->allocptr.uagent);
       conn->allocptr.uagent =
         aprintf("User-Agent: %s\015\012", data->set.useragent);
+      if(!conn->allocptr.uagent)
+        return CURLE_OUT_OF_MEMORY;
     }
   }
 
@@ -3236,6 +3238,8 @@ static CURLcode SetupConnection(struct connectdata *conn,
     Curl_safefree(conn->allocptr.accept_encoding);
     conn->allocptr.accept_encoding =
       aprintf("Accept-Encoding: %s\015\012", data->set.encoding);
+    if(!conn->allocptr.accept_encoding)
+      return CURLE_OUT_OF_MEMORY;
   }
 
   conn->bytecount = 0;
@@ -3340,7 +3344,9 @@ CURLcode Curl_async_resolved(struct connectdata *conn)
 }
 
 
-CURLcode Curl_done(struct connectdata *conn)
+CURLcode Curl_done(struct connectdata *conn,
+                   CURLcode status) /* an error if this is called after an
+                                       error was detected */
 {
   struct SessionHandle *data=conn->data;
   CURLcode result;
@@ -3371,7 +3377,7 @@ CURLcode Curl_done(struct connectdata *conn)
 
   /* this calls the protocol-specific function pointer previously set */
   if(conn->curl_done)
-    result = conn->curl_done(conn);
+    result = conn->curl_done(conn, status);
   else
     result = CURLE_OK;
 
@@ -3423,7 +3429,7 @@ CURLcode Curl_do(struct connectdata **connp)
       infof(data, "Re-used connection seems dead, get a new one\n");
 
       conn->bits.close = TRUE; /* enforce close of this connection */
-      result = Curl_done(conn);   /* we are so done with this */
+      result = Curl_done(conn, result); /* we are so done with this */
 
       /* conn is no longer a good pointer */
 
index 170c107..ff79513 100644 (file)
--- a/lib/url.h
+++ b/lib/url.h
@@ -35,7 +35,7 @@ CURLcode Curl_connect(struct SessionHandle *, struct connectdata **,
 CURLcode Curl_async_resolved(struct connectdata *conn);
 CURLcode Curl_do(struct connectdata **);
 CURLcode Curl_do_more(struct connectdata *);
-CURLcode Curl_done(struct connectdata *);
+CURLcode Curl_done(struct connectdata *, CURLcode);
 CURLcode Curl_disconnect(struct connectdata *);
 CURLcode Curl_protocol_connect(struct connectdata *conn);
 bool Curl_ssl_config_matches(struct ssl_config_data* data,
index f50026a..643d3e7 100644 (file)
@@ -482,7 +482,7 @@ struct connectdata {
   /* These two functions MUST be set by the curl_connect() function to be
      be protocol dependent */
   CURLcode (*curl_do)(struct connectdata *);
-  CURLcode (*curl_done)(struct connectdata *);
+  CURLcode (*curl_done)(struct connectdata *, CURLcode);
 
   /* If the curl_do() function is better made in two halves, this
    * curl_do_more() function will be called afterwards, if set. For example