4e1d13ebd43f4caa84788fa689b42dca25196b9f
max
  Mon Apr 6 12:32:39 2015 -0700
changes after code review, refs #15127

diff --git src/lib/udc.c src/lib/udc.c
index 3d6f46d..d40b845 100644
--- src/lib/udc.c
+++ src/lib/udc.c
@@ -314,30 +314,32 @@
 {
 char *fileName = url + 5;  /* skip over 'slow:' */
 verbose(2, "slow checking remote info on %s\n", url);
 sleep1000(500);
 struct stat status;
 int ret = stat(fileName, &status);
 if (ret < 0)
     return FALSE;
 retInfo->updateTime = status.st_mtime;
 retInfo->size = status.st_size;
 return TRUE;
 }
 
 /********* Section for http protocol **********/
 
+static bool udcCacheEnabled(); // forward declaration
+
 int udcDataViaHttpOrFtp(char *url, bits64 offset, int size, void *buffer, struct connInfo *ci)
 /* Fetch a block of data of given size into buffer using url's protocol,
  * which must be http, https or ftp.  Returns number of bytes actually read.
  * Does an errAbort on error.
  * Typically will be called with size in the 8k-64k range. */
 {
 if (startsWith("http://",url) || startsWith("https://",url) || startsWith("ftp://",url))
     verbose(2, "reading http/https/ftp data - %d bytes at %lld - on %s\n", size, offset, url);
 else
     errAbort("Invalid protocol in url [%s] in udcDataViaFtp, only http, https, or ftp supported",
 	     url); 
 int sd = connInfoGetSocket(ci, url, offset, size);
 if (sd < 0)
     errAbort("Can't get data socket for %s", url);
 int rd = 0, total = 0, remaining = size;
@@ -878,31 +880,31 @@
     freeMem(protocol);
     protocol = cloneString("transparent");
     freeMem(afterProtocol);
     afterProtocol = cloneString(url);
     isTransparent = TRUE;
     }
 struct udcProtocol *prot;
 prot = udcProtocolNew(protocol);
 
 /* Figure out if anything exists. */
 boolean useCacheInfo = FALSE;
 struct udcRemoteFileInfo info;
 ZeroVar(&info);
 if (!isTransparent)
     {
-    if (udcDefaultDir() != NULL)
+    if (udcCacheEnabled())
         useCacheInfo = (udcCacheAge(url, cacheDir) < udcCacheTimeout());
     if (!useCacheInfo)
 	{
 	if (!prot->fetchInfo(url, &info))
 	    {
 	    udcProtocolFree(&prot);
 	    freeMem(protocol);
 	    freeMem(afterProtocol);
 	    return NULL;
 	    }
 	}
     }
 
 /* Allocate file object and start filling it in. */
 struct udcFile *file;
@@ -918,35 +920,35 @@
     struct stat status;
     fstat(fd, &status);
     file->startData = 0;
     file->endData = file->size = status.st_size;
     }
 else 
     {
     udcPathAndFileNames(file, cacheDir, protocol, afterProtocol);
     if (!useCacheInfo)
 	{
 	file->updateTime = info.updateTime;
 	file->size = info.size;
 	memcpy(&(file->connInfo), &(info.ci), sizeof(struct connInfo));
 	// update cache file mod times, so if we're caching we won't do this again
 	// until the timeout has expired again:
-    	if (udcCacheTimeout() > 0 && (udcDefaultDir()!=NULL) && fileExists(file->bitmapFileName))
+    	if (udcCacheTimeout() > 0 && udcCacheEnabled() && fileExists(file->bitmapFileName))
 	    (void)maybeTouchFile(file->bitmapFileName);
 	}
 
-    if (udcDefaultDir() != NULL)
+    if (udcCacheEnabled())
         {
         /* Make directory. */
         makeDirsOnPath(file->cacheDir);
 
         /* Figure out a little bit about the extent of the good cached data if any. Open bits bitmap. */
         setInitialCachedDataBounds(file, useCacheInfo);
 
         file->fdSparse = mustOpenFd(file->sparseFileName, O_RDWR);
         }
 
     }
 freeMem(afterProtocol);
 return file;
 }
 
@@ -1249,31 +1251,31 @@
 if (rangeIntersectOrTouch64(file->startData, file->endData, fetchedStart, fetchedEnd))
     {
     if (fetchedStart > file->startData)
         fetchedStart = file->startData;
     if (fetchedEnd < file->endData)
         fetchedEnd = file->endData;
     }
 file->startData = fetchedStart;
 file->endData = fetchedEnd;
 }
 
 static boolean udcCachePreload(struct udcFile *file, bits64 offset, bits64 size)
 /* Make sure that given data is in cache - fetching it remotely if need be. 
  * Return TRUE on success. */
 {
-if (udcDefaultDir() == NULL)
+if (!udcCacheEnabled())
     return TRUE;
 
 boolean ok = TRUE;
 /* We'll break this operation into blocks of a reasonable size to allow
  * other processes to get cache access, since we have to lock the cache files. */
 bits64 s,e, endPos=offset+size;
 for (s = offset; s < endPos; s = e)
     {
     /* Figure out bounds of this section. */
     e = s + udcMaxBytesPerRemoteFetch;
     if (e > endPos)
 	e = endPos;
 
     struct udcBitmap *bits = file->bits;
     if (bits->version == file->bitmapVersion)
@@ -1284,32 +1286,32 @@
 	{
 	ok = FALSE;
 	verbose(2, "udcCachePreload version check failed %d vs %d", 
 		bits->version, file->bitmapVersion);
 	}
     if (!ok)
         break;
     }
 return ok;
 }
 
 #define READAHEADBUFSIZE 4096
 bits64 udcRead(struct udcFile *file, void *buf, bits64 size)
 /* Read a block from file.  Return amount actually read. */
 {
-// if udcDefaultDir is NULL, don't do local caching, just fetch the data
-if (udcDefaultDir()==NULL && !sameString(file->protocol, "transparent"))
+// if not caching, just fetch the data
+if (!udcCacheEnabled() && !sameString(file->protocol, "transparent"))
     {
     int actualSize = file->prot->fetchData(file->url, file->offset, size, buf, &(file->connInfo));
     file->offset += actualSize;
     return actualSize;
     }
 
 /* Figure out region of file we're going to read, and clip it against file size. */
 bits64 start = file->offset;
 if (start > file->size)
     return 0;
 bits64 end = start + size;
 if (end > file->size)
     end = file->size;
 size = end - start;
 char *cbuf = buf;
@@ -1550,39 +1552,39 @@
 
 struct lineFile *udcWrapShortLineFile(char *url, char *cacheDir, size_t maxSize)
 /* Read in entire short (up to maxSize) url into memory and wrap a line file around it.
  * The cacheDir may be null in which case udcDefaultDir() will be used.  If maxSize
  * is zero then a default value (currently 64 meg) will be used. */
 {
 if (maxSize == 0) maxSize = 64 * 1024 * 1024;
 char *buf = udcFileReadAll(url, cacheDir, maxSize, NULL);
 return lineFileOnString(url, TRUE, buf);
 }
 
 void udcSeekCur(struct udcFile *file, bits64 offset)
 /* Seek to a particular position in file. */
 {
 file->offset += offset;
-if (udcDefaultDir())
+if (udcCacheEnabled())
     mustLseek(file->fdSparse, offset, SEEK_CUR);
 }
 
 void udcSeek(struct udcFile *file, bits64 offset)
 /* Seek to a particular position in file. */
 {
 file->offset = offset;
-if (udcDefaultDir())
+if (udcCacheEnabled())
     mustLseek(file->fdSparse, offset, SEEK_SET);
 }
 
 bits64 udcTell(struct udcFile *file)
 /* Return current file position. */
 {
 return file->offset;
 }
 
 static long bitRealDataSize(char *fileName)
 /* Return number of real bytes indicated by bitmaps */
 {
 struct udcBitmap *bits = udcBitmapOpen(fileName);
 int blockSize = bits->blockSize;
 long byteSize = 0;
@@ -1657,36 +1659,46 @@
 time_t deleteTime = time(NULL) - maxSeconds;
 bits64 result = rCleanup(deleteTime, testOnly);
 setCurrentDir(curPath);
 return result;
 }
 
 static char *defaultDir = "/tmp/udcCache";
 
 char *udcDefaultDir()
 /* Get default directory for cache */
 {
 return defaultDir;
 }
 
 void udcSetDefaultDir(char *path)
-/* Set default directory for cache. 
- * Set to NULL to deactivate the local caching. */
+/* Set default directory for cache.  */
 {
 defaultDir = cloneString(path);
 }
 
+void udcDisableCache()
+/* Switch off caching. Re-enable with udcSetDefaultDir */
+{
+defaultDir = NULL;
+}
+
+static bool udcCacheEnabled()
+/* TRUE if caching is activated */
+{
+return (defaultDir != NULL);
+}
 
 int udcCacheTimeout()
 /* Get cache timeout (if local cache files are newer than this many seconds,
  * we won't ping the remote server to check the file size and update time). */
 {
 return cacheTimeout;
 }
 
 void udcSetCacheTimeout(int timeout)
 /* Set cache timeout (if local cache files are newer than this many seconds,
  * we won't ping the remote server to check the file size and update time). */
 {
 cacheTimeout = timeout;
 }