Add Music Manager's curl 7.21.2 source.

Change-Id: I259a43fa52d581524a5ce8ae1711467acb1d9d50
diff --git a/lib/transfer.c b/lib/transfer.c
index 2d50405..78bd7f1 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -103,6 +103,7 @@
 #include "multiif.h"
 #include "easyif.h" /* for Curl_convert_to_network prototype */
 #include "rtsp.h"
+#include "connect.h"
 
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
@@ -194,7 +195,8 @@
       /* \n will become \r\n later on */
       endofline_native  = "\n";
       endofline_network = "\x0a";
-    } else {
+    }
+    else {
       endofline_native  = "\r\n";
       endofline_network = "\x0d\x0a";
     }
@@ -219,21 +221,20 @@
     if(data->set.prefer_ascii) {
       /* translate the protocol and data */
       length = nread;
-    } else {
+    }
+    else {
       /* just translate the protocol portion */
       length = strlen(hexbuffer);
     }
     res = Curl_convert_to_network(data, data->req.upload_fromhere, length);
     /* Curl_convert_to_network calls failf if unsuccessful */
-    if(res != CURLE_OK) {
+    if(res)
       return(res);
-    }
 #endif /* CURL_DOES_CONVERSIONS */
 
-    if((nread - hexlen) == 0) {
+    if((nread - hexlen) == 0)
       /* mark this as done once this chunk is transfered */
       data->req.upload_done = TRUE;
-    }
 
     nread+=(int)strlen(endofline_native); /* for the added end of line */
   }
@@ -340,11 +341,11 @@
 
     show = CURLMIN(conn->buf_len - conn->read_pos, sizeof(buf)-1);
     if(conn->master_buffer) {
-        memcpy(buf, conn->master_buffer + conn->read_pos, show);
-        buf[show] = '\0';
+      memcpy(buf, conn->master_buffer + conn->read_pos, show);
+      buf[show] = '\0';
     }
     else {
-        buf[0] = '\0';
+      buf[0] = '\0';
     }
 
     DEBUGF(infof(conn->data,
@@ -376,12 +377,11 @@
   *done = FALSE;
 
   /* This is where we loop until we have read everything there is to
-     read or we get a EWOULDBLOCK */
+     read or we get a CURLE_AGAIN */
   do {
     size_t buffersize = data->set.buffer_size?
       data->set.buffer_size : BUFSIZE;
     size_t bytestoread = buffersize;
-    int readrc;
 
     if(k->size != -1 && !k->header) {
       /* make sure we don't read "too much" if we can help it since we
@@ -394,15 +394,12 @@
 
     if(bytestoread) {
       /* receive data from the network! */
-      readrc = Curl_read(conn, conn->sockfd, k->buf, bytestoread, &nread);
+      result = Curl_read(conn, conn->sockfd, k->buf, bytestoread, &nread);
 
-      /* subzero, this would've blocked */
-      if(0 > readrc)
+      /* read would've blocked */
+      if(CURLE_AGAIN == result)
         break; /* get out of loop */
 
-      /* get the CURLcode from the int */
-      result = (CURLcode)readrc;
-
       if(result>0)
         return result;
     }
@@ -598,9 +595,12 @@
 
           dataleft = conn->chunk.dataleft;
           if(dataleft != 0) {
-            infof(conn->data, "Leftovers after chunking. "
-                  " Rewinding %zu bytes\n",dataleft);
-            read_rewind(conn, dataleft);
+            infof(conn->data, "Leftovers after chunking: %zu bytes", dataleft);
+            if(conn->data->multi && Curl_multi_canPipeline(conn->data->multi)) {
+              /* only attempt the rewind if we truly are pipelining */
+              infof(conn->data, "Rewinding %zu bytes\n",dataleft);
+              read_rewind(conn, dataleft);
+            }
           }
         }
         /* If it returned OK, we just keep going */
@@ -623,22 +623,22 @@
             /* The 'excess' amount below can't be more than BUFSIZE which
                always will fit in a size_t */
             infof(data,
-                "Rewinding stream by : %zu"
-                " bytes on url %s (size = %" FORMAT_OFF_T
-                ", maxdownload = %" FORMAT_OFF_T
-                ", bytecount = %" FORMAT_OFF_T ", nread = %zd)\n",
-                excess, data->state.path,
-                k->size, k->maxdownload, k->bytecount, nread);
+                  "Rewinding stream by : %zu"
+                  " bytes on url %s (size = %" FORMAT_OFF_T
+                  ", maxdownload = %" FORMAT_OFF_T
+                  ", bytecount = %" FORMAT_OFF_T ", nread = %zd)\n",
+                  excess, data->state.path,
+                  k->size, k->maxdownload, k->bytecount, nread);
             read_rewind(conn, excess);
           }
           else {
             infof(data,
-                "Excess found in a non pipelined read:"
-                " excess = %zu"
-                ", size = %" FORMAT_OFF_T
-                ", maxdownload = %" FORMAT_OFF_T
-                ", bytecount = %" FORMAT_OFF_T "\n",
-                excess, k->size, k->maxdownload, k->bytecount);
+                  "Excess found in a non pipelined read:"
+                  " excess = %zu"
+                  ", size = %" FORMAT_OFF_T
+                  ", maxdownload = %" FORMAT_OFF_T
+                  ", bytecount = %" FORMAT_OFF_T "\n",
+                  excess, k->size, k->maxdownload, k->bytecount);
           }
         }
 
@@ -738,7 +738,7 @@
 
       /* Parse the excess data */
       k->str += nread;
-      nread = excess;
+      nread = (ssize_t)excess;
 
       result = Curl_rtsp_rtp_readwrite(data, conn, &nread, &readmore);
       if(result)
@@ -815,6 +815,9 @@
           k->keepon &= ~KEEP_SEND;         /* disable writing */
           k->start100 = Curl_tvnow();       /* timeout count starts now */
           *didwhat &= ~KEEP_SEND;  /* we didn't write anything actually */
+
+          /* set a timeout for the multi interface */
+          Curl_expire(data, CURL_TIMEOUT_EXPECT_100);
           break;
         }
 
@@ -994,7 +997,7 @@
                      status is not known. */
     select_res = Curl_socket_ready(fd_read, fd_write, 0);
 
-  if(select_res == CURL_CSELECT_ERR) {
+  if(select_res & CURL_CSELECT_ERR) {
     failf(data, "select/poll returned error");
     return CURLE_SEND_ERROR;
   }
@@ -1061,16 +1064,17 @@
     return result;
 
   if(k->keepon) {
-    if(data->set.timeout &&
-       (Curl_tvdiff(k->now, k->start) >= data->set.timeout)) {
+    if(0 > Curl_timeleft(conn, &k->now, FALSE)) {
       if(k->size != -1) {
         failf(data, "Operation timed out after %ld milliseconds with %"
               FORMAT_OFF_T " out of %" FORMAT_OFF_T " bytes received",
-              Curl_tvdiff(k->now, k->start), k->bytecount, k->size);
-      } else {
+              Curl_tvdiff(k->now, data->progress.t_startsingle), k->bytecount,
+              k->size);
+      }
+      else {
         failf(data, "Operation timed out after %ld milliseconds with %"
               FORMAT_OFF_T " bytes received",
-              Curl_tvdiff(k->now, k->start), k->bytecount);
+              Curl_tvdiff(k->now, data->progress.t_startsingle), k->bytecount);
       }
       return CURLE_OPERATION_TIMEDOUT;
     }
@@ -1225,7 +1229,7 @@
    */
   if(rv > 0x7fffffff)
     rv = 0x7fffffff;
-  
+
   return (long)rv;
 }
 
@@ -1343,12 +1347,10 @@
          to work with, skip the timeout */
       timeout_ms = 0;
     else {
-      if(data->set.timeout) {
-        totmp = (int)(data->set.timeout - Curl_tvdiff(k->now, k->start));
-        if(totmp < 0)
-          return CURLE_OPERATION_TIMEDOUT;
-      }
-      else
+      totmp = Curl_timeleft(conn, &k->now, FALSE);
+      if(totmp < 0)
+        return CURLE_OPERATION_TIMEDOUT;
+      else if(!totmp)
         totmp = 1000;
 
       if (totmp < timeout_ms)
@@ -1433,6 +1435,12 @@
   Curl_initinfo(data); /* reset session-specific information "variables" */
   Curl_pgrsStartNow(data);
 
+  if(data->set.timeout)
+    Curl_expire(data, data->set.timeout);
+
+  if(data->set.connecttimeout)
+    Curl_expire(data, data->set.connecttimeout);
+
   return CURLE_OK;
 }
 
@@ -2009,12 +2017,7 @@
   return CURLE_OK;
 }
 
-/*
- * Curl_perform() is the internal high-level function that gets called by the
- * external curl_easy_perform() function. It inits, performs and cleans up a
- * single file transfer.
- */
-CURLcode Curl_perform(struct SessionHandle *data)
+static CURLcode Curl_do_perform(struct SessionHandle *data)
 {
   CURLcode res;
   CURLcode res2;
@@ -2049,6 +2052,15 @@
       res = Curl_do(&conn, &do_done);
 
       if(res == CURLE_OK) {
+        if(conn->data->set.wildcardmatch) {
+          if(conn->data->wildcard.state == CURLWC_DONE ||
+             conn->data->wildcard.state == CURLWC_SKIP) {
+            /* keep connection open for application to use the socket */
+            conn->bits.close = FALSE;
+            res = Curl_done(&conn, CURLE_OK, FALSE);
+            break;
+          }
+        }
         res = Transfer(conn); /* now fetch that URL please */
         if((res == CURLE_OK) || (res == CURLE_RECV_ERROR)) {
           bool retry = FALSE;
@@ -2056,13 +2068,12 @@
           if(rc)
             res = rc;
           else
-            retry = (bool)(newurl?TRUE:FALSE);
+            retry = (newurl?TRUE:FALSE);
 
           if(retry) {
+            /* we know (newurl != NULL) at this point */
             res = CURLE_OK;
             follow = FOLLOW_RETRY;
-            if (!newurl)
-              res = CURLE_OUT_OF_MEMORY;
           }
           else if (res == CURLE_OK) {
             /*
@@ -2113,9 +2124,9 @@
         /* Curl_do() failed, clean up left-overs in the done-call, but note
            that at some cases the conn pointer is NULL when Curl_do() failed
            and the connection cache is very small so only call Curl_done() if
-           conn is still "alive".
-        */
-        res2 = Curl_done(&conn, res, FALSE);
+           conn is still "alive". */
+        /* ignore return code since we already have an error to return */
+        (void)Curl_done(&conn, res, FALSE);
 
       /*
        * Important: 'conn' cannot be used here, since it may have been closed
@@ -2166,10 +2177,43 @@
 }
 
 /*
+ * Curl_perform() is the internal high-level function that gets called by the
+ * external curl_easy_perform() function. It inits, performs and cleans up a
+ * single file transfer.
+ */
+CURLcode Curl_perform(struct SessionHandle *data)
+{
+  CURLcode res;
+  if(!data->set.wildcardmatch)
+    return Curl_do_perform(data);
+
+  /* init main wildcard structures */
+  res = Curl_wildcard_init(&data->wildcard);
+  if(res)
+    return res;
+
+  res = Curl_do_perform(data);
+  if(res) {
+    Curl_wildcard_dtor(&data->wildcard);
+    return res;
+  }
+
+  /* wildcard loop */
+  while(!res && data->wildcard.state != CURLWC_DONE)
+    res = Curl_do_perform(data);
+
+  Curl_wildcard_dtor(&data->wildcard);
+
+  /* wildcard download finished or failed */
+  data->wildcard.state = CURLWC_INIT;
+  return res;
+}
+
+/*
  * Curl_setup_transfer() is called to setup some basic properties for the
  * upcoming transfer.
  */
-CURLcode
+void
 Curl_setup_transfer(
   struct connectdata *conn, /* connection data */
   int sockindex,            /* socket index to read from or -1 */
@@ -2214,9 +2258,8 @@
   /* we want header and/or body, if neither then don't do this! */
   if(k->getheader || !data->set.opt_no_body) {
 
-    if(conn->sockfd != CURL_SOCKET_BAD) {
+    if(conn->sockfd != CURL_SOCKET_BAD)
       k->keepon |= KEEP_RECV;
-    }
 
     if(conn->writesockfd != CURL_SOCKET_BAD) {
       /* HTTP 1.1 magic:
@@ -2233,6 +2276,9 @@
         /* wait with write until we either got 100-continue or a timeout */
         k->exp100 = EXP100_AWAITING_CONTINUE;
         k->start100 = k->start;
+
+        /* set a timeout for the multi interface */
+        Curl_expire(data, CURL_TIMEOUT_EXPECT_100);
       }
       else {
         if(data->state.expect100header)
@@ -2246,5 +2292,4 @@
     } /* if(conn->writesockfd != CURL_SOCKET_BAD) */
   } /* if(k->getheader || !data->set.opt_no_body) */
 
-  return CURLE_OK;
 }