0fb02363d1aa5e7d1138fcbea8c9419a830dbd82
galt
  Fri Jun 25 04:09:07 2010 -0700
adding auto-restart
diff --git src/lib/net.c src/lib/net.c
index 5ca731c..6030fdb 100644
--- src/lib/net.c
+++ src/lib/net.c
@@ -16,6 +16,7 @@
 #include "base64.h"
 #include "cheapcgi.h"
 #include "https.h"
+#include "sqlNum.h"
 
 static char const rcsid[] = "$Id: net.c,v 1.80 2010/04/14 07:42:06 galt Exp $";
 
@@ -1308,6 +1309,90 @@
 }
 
 
+boolean readParaFetchStatus(char *origPath, struct parallelConn **pPcList, char **pUrl, off_t *pFileSize, char **pDateString)
+/* Write a status file.
+ * This has two purposes.
+ * First, we can use it to resume a failed transfer.
+ * Second, we can use it to follow progress */
+{
+char outTemp[1024];
+char outStat[1024];
+safef(outStat, sizeof(outStat), "%s.paraFetchStatus", origPath);
+safef(outTemp, sizeof(outTemp), "%s.paraFetch", origPath);
+struct parallelConn *pcList = NULL, *pc = NULL;
+
+if (!fileExists(outStat))
+    {
+    unlink(outTemp);
+    return FALSE;
+    }
+
+if (!fileExists(outTemp))
+    {
+    unlink(outStat);
+    return FALSE;
+    }
+
+char *line, *word;
+struct lineFile *lf = lineFileOpen(outStat, TRUE);
+if (!lineFileNext(lf, &line, NULL))
+    {
+    unlink(outTemp);
+    unlink(outStat);
+    return FALSE;
+    }
+char *url = cloneString(line);
+if (!lineFileNext(lf, &line, NULL))
+    {
+    unlink(outTemp);
+    unlink(outStat);
+    return FALSE;
+    }
+off_t fileSize = sqlLongLong(line);
+if (!lineFileNext(lf, &line, NULL))
+    {
+    unlink(outTemp);
+    unlink(outStat);
+    return FALSE;
+    }
+char *dateString = cloneString(line);
+while (lineFileNext(lf, &line, NULL))
+    {
+    word = nextWord(&line);
+    AllocVar(pc);
+    pc->next = NULL;
+    pc->sd = -4;  /* no connection tried yet */
+    word = nextWord(&line);
+    pc->rangeStart = sqlLongLong(word);
+    word = nextWord(&line);
+    pc->partSize = sqlLongLong(word);
+    word = nextWord(&line);
+    pc->received = sqlLongLong(word);
+    if (pc->received == pc->partSize)
+	pc->sd = -1;  /* part all done already */
+    slAddHead(&pcList, pc);
+    }
+slReverse(&pcList);
+
+lineFileClose(&lf);
+
+if (slCount(pcList) < 1)
+    {
+    unlink(outTemp);
+    unlink(outStat);
+    return FALSE;
+    }
+
+*pPcList = pcList;
+*pUrl = url;
+*pFileSize = fileSize;
+*pDateString = dateString;
+
+return TRUE;
+
+}
+
+
 boolean parallelFetch(char *url, int numConnections, char *outPath)
 /* Open multiple parallel connections to URL to speed downloading */
 {
@@ -1394,14 +1479,30 @@
 verbose(2,"debug partSize=%llu\n", (unsigned long long) partSize); //debug
 
 
-
 /* n is the highest-numbered descriptor */
 int n = 0;
 int connOpen = 0;
 int reOpen = 0;
 
-/* make a list of connections and open them */
+
+struct parallelConn *restartPcList = NULL;
+char *restartUrl = NULL;
+off_t restartFileSize = 0;
+char *restartDateString = "";
+boolean restartable = readParaFetchStatus(origPath, &restartPcList, &restartUrl, &restartFileSize, &restartDateString);
+
 struct parallelConn *pcList = NULL, *pc;
+
+if (restartable 
+ && sameString(url, restartUrl)
+ && fileSize == restartFileSize
+ && sameString(dateString, restartDateString))
+    {
+    pcList = restartPcList;
+    }
+else
+    {
+    /* make a list of connections */
 for (c = 0; c < numConnections; ++c)
     {
     AllocVar(pc);
@@ -1416,9 +1517,7 @@
     slAddHead(&pcList, pc);
     }
 slReverse(&pcList);
-
-
-    
+    }
 
 int out = open(outPath, O_CREAT|O_WRONLY, 0664);
 if (out < 0)