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)