--- C:\dev\sdk\curl-head\curl-20061228-1548\lib\file.c	2006-10-18 17:47:58.001 +0200
+++ C:\dev\sdk\curl-head\curl\lib\file.c	2006-12-28 16:28:55.000 +0100
@@ -165,7 +165,7 @@
   file->fd = fd;
   if(!conn->data->set.upload && (fd == -1)) {
     failf(conn->data, "Couldn't open file %s", conn->data->reqdata.path);
-    Curl_file_done(conn, CURLE_FILE_COULDNT_READ_FILE);
+    Curl_file_done(conn, CURLE_FILE_COULDNT_READ_FILE, FALSE);
     return CURLE_FILE_COULDNT_READ_FILE;
   }
 
@@ -173,7 +173,7 @@
 }
 
 CURLcode Curl_file_done(struct connectdata *conn,
-                        CURLcode status)
+                        CURLcode status, bool premature)
 {
   struct FILEPROTO *file = conn->data->reqdata.proto.file;
   (void)status; /* not used */

--- C:\dev\sdk\curl-head\curl-20061228-1548\lib\file.h	2005-02-09 14:06:40.001 +0100
+++ C:\dev\sdk\curl-head\curl\lib\file.h	2006-12-28 15:57:29.000 +0100
@@ -25,7 +25,7 @@
  ***************************************************************************/
 #ifndef CURL_DISABLE_FILE
 CURLcode Curl_file(struct connectdata *, bool *done);
-CURLcode Curl_file_done(struct connectdata *, CURLcode);
+CURLcode Curl_file_done(struct connectdata *, CURLcode, bool premature);
 CURLcode Curl_file_connect(struct connectdata *);
 #endif
 #endif

--- C:\dev\sdk\curl-head\curl-20061228-1548\lib\ftp.c	2006-12-22 16:05:00.000 +0100
+++ C:\dev\sdk\curl-head\curl\lib\ftp.c	2006-12-28 16:17:29.000 +0100
@@ -2940,7 +2940,7 @@
  *
  * Input argument is already checked for validity.
  */
-CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status)
+CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status, bool premature)
 {
   struct SessionHandle *data = conn->data;
   struct FTP *ftp = data->reqdata.proto.ftp;
@@ -2974,8 +2974,12 @@
     /* the connection stays alive fine even though this happened */
     /* fall-through */
   case CURLE_OK: /* doesn't affect the control connection's status */
-    ftpc->ctl_valid = was_ctl_valid;
-    break;
+    if (!premature) {
+      ftpc->ctl_valid = was_ctl_valid;
+      break;
+    }
+    /* until we cope better with prematurely ended requests, let them 
+     * fallback as if in complete failure */
   default:       /* by default, an error means the control connection is
                     wedged and should not be used anymore */
     ftpc->ctl_valid = FALSE;
@@ -3024,7 +3028,7 @@
 
   conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
 
-  if(!ftp->no_transfer && !status) {
+  if(!ftp->no_transfer && !status && !premature) {
     /*
      * 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
@@ -3057,7 +3061,7 @@
     }
   }
 
-  if(result)
+  if(result || premature)
     /* the response code from the transfer showed an error already so no
        use checking further */
     ;
@@ -3099,7 +3103,7 @@
   ftpc->dont_check = FALSE;
 
   /* Send any post-transfer QUOTE strings? */
-  if(!status && !result && data->set.postquote)
+  if(!status && !result && !premature && data->set.postquote)
     result = ftp_sendquote(conn, data->set.postquote);
 
   return result;

--- C:\dev\sdk\curl-head\curl-20061228-1548\lib\ftp.h	2006-04-10 18:00:54.000 +0200
+++ C:\dev\sdk\curl-head\curl\lib\ftp.h	2006-12-28 15:56:57.000 +0100
@@ -25,7 +25,7 @@
 
 #ifndef CURL_DISABLE_FTP
 CURLcode Curl_ftp(struct connectdata *conn, bool *done);
-CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode);
+CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode, bool premature);
 CURLcode Curl_ftp_connect(struct connectdata *conn, bool *done);
 CURLcode Curl_ftp_disconnect(struct connectdata *conn);
 CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...);

--- C:\dev\sdk\curl-head\curl-20061228-1548\lib\http.c	2006-12-21 11:15:39.000 +0100
+++ C:\dev\sdk\curl-head\curl\lib\http.c	2006-12-28 15:55:13.001 +0100
@@ -1488,7 +1488,7 @@
  */
 
 CURLcode Curl_http_done(struct connectdata *conn,
-                        CURLcode status)
+                        CURLcode status, bool premature)
 {
   struct SessionHandle *data = conn->data;
   struct HTTP *http =data->reqdata.proto.http;

--- C:\dev\sdk\curl-head\curl-20061228-1548\lib\http.h	2006-08-19 01:54:58.000 +0200
+++ C:\dev\sdk\curl-head\curl\lib\http.h	2006-12-28 15:57:18.000 +0100
@@ -35,7 +35,7 @@
 
 /* protocol-specific functions set up to be called by the main engine */
 CURLcode Curl_http(struct connectdata *conn, bool *done);
-CURLcode Curl_http_done(struct connectdata *, CURLcode);
+CURLcode Curl_http_done(struct connectdata *, CURLcode, bool premature);
 CURLcode Curl_http_connect(struct connectdata *conn, bool *done);
 CURLcode Curl_https_connecting(struct connectdata *conn, bool *done);
 int Curl_https_getsock(struct connectdata *conn,

--- C:\dev\sdk\curl-head\curl-20061228-1548\lib\multi.c	2006-12-05 16:36:27.001 +0100
+++ C:\dev\sdk\curl-head\curl\lib\multi.c	2006-12-28 16:12:09.000 +0100
@@ -512,9 +512,11 @@
   }
 
   if(easy) {
+    bool premature = easy->state != CURLM_STATE_COMPLETED;
+
     /* If the 'state' is not INIT or COMPLETED, we might need to do something
        nice to put the easy_handle in a good known state when this returns. */
-    if(easy->state != CURLM_STATE_COMPLETED)
+    if(premature)
       /* this handle is "alive" so we need to count down the total number of
          alive connections when this is removed */
       multi->num_alive--;
@@ -547,7 +549,7 @@
 
       /* Curl_done() clears the conn->data field to lose the association
          between the easy handle and the connection */
-      Curl_done(&easy->easy_conn, easy->result);
+      Curl_done(&easy->easy_conn, easy->result, premature);
 
       if(easy->easy_conn)
         /* the connection is still alive, set back the association to enable
@@ -802,7 +804,7 @@
       char *gotourl;
       Curl_posttransfer(easy->easy_handle);
 
-      easy->result = Curl_done(&easy->easy_conn, CURLE_OK);
+      easy->result = Curl_done(&easy->easy_conn, CURLE_OK, FALSE);
       /* We make sure that the pipe broken flag is reset
          because in this case, it isn't an actual break */
       easy->easy_handle->state.pipe_broke = FALSE;
@@ -950,7 +952,7 @@
       else if(easy->result) {
         /* failure detected */
         Curl_posttransfer(easy->easy_handle);
-        Curl_done(&easy->easy_conn, easy->result);
+        Curl_done(&easy->easy_conn, easy->result, FALSE);
         Curl_disconnect(easy->easy_conn); /* close the connection */
         easy->easy_conn = NULL;           /* no more connection */
       }
@@ -1017,7 +1019,7 @@
         else {
           /* failure detected */
           Curl_posttransfer(easy->easy_handle);
-          Curl_done(&easy->easy_conn, easy->result);
+          Curl_done(&easy->easy_conn, easy->result, FALSE);
           Curl_disconnect(easy->easy_conn); /* close the connection */
           easy->easy_conn = NULL;           /* no more connection */
         }
@@ -1050,7 +1052,7 @@
       else {
         /* failure detected */
         Curl_posttransfer(easy->easy_handle);
-        Curl_done(&easy->easy_conn, easy->result);
+        Curl_done(&easy->easy_conn, easy->result, FALSE);
         Curl_disconnect(easy->easy_conn); /* close the connection */
         easy->easy_conn = NULL;           /* no more connection */
       }
@@ -1169,7 +1171,7 @@
           easy->easy_conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
         }
         Curl_posttransfer(easy->easy_handle);
-        Curl_done(&easy->easy_conn, easy->result);
+        Curl_done(&easy->easy_conn, easy->result, FALSE);
       }
       else if(TRUE == done) {
         char *newurl;
@@ -1188,7 +1190,7 @@
             newurl = easy->easy_handle->reqdata.newurl;
             easy->easy_handle->reqdata.newurl = NULL;
           }
-          easy->result = Curl_done(&easy->easy_conn, CURLE_OK);
+          easy->result = Curl_done(&easy->easy_conn, CURLE_OK, FALSE);
           if(easy->result == CURLE_OK)
             easy->result = Curl_follow(easy->easy_handle, newurl, retry);
           if(CURLE_OK == easy->result) {
@@ -1224,7 +1226,7 @@
 
       if (!easy->easy_handle->state.cancelled) {
         /* post-transfer command */
-        easy->result = Curl_done(&easy->easy_conn, CURLE_OK);
+        easy->result = Curl_done(&easy->easy_conn, CURLE_OK, FALSE);
 
         /* after we have DONE what we're supposed to do, go COMPLETED, and
            it doesn't matter what the Curl_done() returned! */

--- C:\dev\sdk\curl-head\curl-20061228-1548\lib\telnet.c	2006-10-21 15:36:10.000 +0200
+++ C:\dev\sdk\curl-head\curl\lib\telnet.c	2006-12-28 15:56:58.001 +0100
@@ -1073,7 +1073,7 @@
   }
 }
 
-CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode status)
+CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode status, bool premature)
 {
   struct TELNET *tn = (struct TELNET *)conn->data->reqdata.proto.telnet;
   (void)status; /* unused */

--- C:\dev\sdk\curl-head\curl-20061228-1548\lib\telnet.h	2005-02-09 14:06:40.001 +0100
+++ C:\dev\sdk\curl-head\curl\lib\telnet.h	2006-12-28 15:56:58.001 +0100
@@ -25,6 +25,6 @@
  ***************************************************************************/
 #ifndef CURL_DISABLE_TELNET
 CURLcode Curl_telnet(struct connectdata *conn, bool *done);
-CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode);
+CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode, bool premature);
 #endif
 #endif

--- C:\dev\sdk\curl-head\curl-20061228-1548\lib\tftp.c	2006-11-09 22:36:19.001 +0100
+++ C:\dev\sdk\curl-head\curl\lib\tftp.c	2006-12-28 15:56:57.000 +0100
@@ -622,7 +622,7 @@
  * The done callback
  *
  **********************************************************/
-CURLcode Curl_tftp_done(struct connectdata *conn, CURLcode status)
+CURLcode Curl_tftp_done(struct connectdata *conn, CURLcode status, bool premature)
 {
   (void)status; /* unused */
 

--- C:\dev\sdk\curl-head\curl-20061228-1548\lib\tftp.h	2005-09-02 18:11:09.001 +0200
+++ C:\dev\sdk\curl-head\curl\lib\tftp.h	2006-12-28 15:56:58.001 +0100
@@ -26,6 +26,6 @@
 #ifndef CURL_DISABLE_TFTP
 CURLcode Curl_tftp_connect(struct connectdata *conn, bool *done);
 CURLcode Curl_tftp(struct connectdata *conn, bool *done);
-CURLcode Curl_tftp_done(struct connectdata *conn, CURLcode);
+CURLcode Curl_tftp_done(struct connectdata *conn, CURLcode, bool premature);
 #endif
 #endif

--- C:\dev\sdk\curl-head\curl-20061228-1548\lib\transfer.c	2006-12-21 11:18:15.000 +0100
+++ C:\dev\sdk\curl-head\curl\lib\transfer.c	2006-12-28 16:12:09.000 +0100
@@ -2225,7 +2225,7 @@
        to the new URL */
     urlchanged = data->change.url_changed;
     if ((CURLE_OK == res) && urlchanged) {
-      res = Curl_done(conn, res);
+      res = Curl_done(conn, res, FALSE);
       if(CURLE_OK == res) {
         char *gotourl = strdup(data->change.url);
         res = Curl_follow(data, gotourl, FALSE);
@@ -2301,7 +2301,7 @@
       if(data->set.connect_only) {
         /* keep connection open for application to use the socket */
         conn->bits.close = FALSE;
-        res = Curl_done(&conn, CURLE_OK);
+        res = Curl_done(&conn, CURLE_OK, FALSE);
         break;
       }
       res = Curl_do(&conn, &do_done);
@@ -2334,14 +2334,14 @@
 
         /* Always run Curl_done(), even if some of the previous calls
            failed, but return the previous (original) error code */
-        res2 = Curl_done(&conn, res);
+        res2 = Curl_done(&conn, res, FALSE);
 
         if(CURLE_OK == res)
           res = res2;
       }
       else
         /* Curl_do() failed, clean up left-overs in the done-call */
-        res2 = Curl_done(&conn, res);
+        res2 = Curl_done(&conn, res, FALSE);
 
       /*
        * Important: 'conn' cannot be used here, since it may have been closed

--- C:\dev\sdk\curl-head\curl-20061228-1548\lib\url.c	2006-12-22 16:05:00.000 +0100
+++ C:\dev\sdk\curl-head\curl\lib\url.c	2006-12-28 16:12:09.000 +0100
@@ -4083,7 +4083,7 @@
 
 
 CURLcode Curl_done(struct connectdata **connp,
-                   CURLcode status) /* an error if this is called after an
+                   CURLcode status, bool premature) /* an error if this is called after an
                                        error was detected */
 {
   CURLcode result;
@@ -4123,7 +4123,7 @@
 
   /* this calls the protocol-specific function pointer previously set */
   if(conn->curl_done)
-    result = conn->curl_done(conn, status);
+    result = conn->curl_done(conn, status, premature);
   else
     result = CURLE_OK;
 
@@ -4189,7 +4189,7 @@
       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, result); /* we are so done with this */
+      result = Curl_done(&conn, result, FALSE); /* we are so done with this */
 
       /* conn may no longer be a good pointer */
 

--- C:\dev\sdk\curl-head\curl-20061228-1548\lib\url.h	2006-12-05 16:36:27.001 +0100
+++ C:\dev\sdk\curl-head\curl\lib\url.h	2006-12-28 16:05:07.000 +0100
@@ -39,7 +39,7 @@
                              bool *protocol_connect);
 CURLcode Curl_do(struct connectdata **, bool *done);
 CURLcode Curl_do_more(struct connectdata *);
-CURLcode Curl_done(struct connectdata **, CURLcode);
+CURLcode Curl_done(struct connectdata **, CURLcode, bool premature);
 CURLcode Curl_disconnect(struct connectdata *);
 CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done);
 CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done);

--- C:\dev\sdk\curl-head\curl-20061228-1548\lib\urldata.h	2006-12-22 16:05:00.000 +0100
+++ C:\dev\sdk\curl-head\curl\lib\urldata.h	2006-12-28 15:54:53.000 +0100
@@ -613,7 +613,7 @@
    within the source when we need to cast between data pointers (such as NULL)
    and function pointers. */
 typedef CURLcode (*Curl_do_more_func)(struct connectdata *);
-typedef CURLcode (*Curl_done_func)(struct connectdata *, CURLcode);
+typedef CURLcode (*Curl_done_func)(struct connectdata *, CURLcode, bool);
 
 
 /*


