1b380f11932d8dd14c1ae935cdf9cdcced61f9f6
galt
  Wed Dec 20 12:04:52 2017 -0800
Fixing cdw utils to preserve the original date of the submitted file, which helps speed up cdwSubmit for old files as well. They will not have to run md5sum manually if the file date has not changed so it can use the md5 from the record in the database.

diff --git src/lib/osunix.c src/lib/osunix.c
index 2e6b9f2..afa507c 100644
--- src/lib/osunix.c
+++ src/lib/osunix.c
@@ -703,35 +703,77 @@
 	warn("utime(%s) failed (ownership?)", fileName);
 	return FALSE;
 	}
     }
 else
     {
     FILE *f = fopen(fileName, "w");
     if (f == NULL)
 	return FALSE;
     else
 	carefulClose(&f);
     }
 return TRUE;
 }
 
+void touchFileFromFile(const char *oldFile, const char *newFile)
+/* Set access and mod time of newFile from oldFile. */
+{
+    struct stat buf;
+    if (stat(oldFile, &buf) != 0)
+        errnoAbort("stat failed on %s", oldFile);
+    struct utimbuf puttime;
+    puttime.modtime = buf.st_mtime;
+    puttime.actime = buf.st_atime;
+    if (utime(newFile, &puttime) != 0)
+	errnoAbort("utime failed on %s", newFile);
+}
+
+
 boolean isRegularFile(char *fileName)
 /* Return TRUE if fileName is a regular file. */
 {
 struct stat st;
 
 if (stat(fileName, &st) < 0)
     return FALSE;
 if (S_ISREG(st.st_mode))
     return TRUE;
 return FALSE;
 }
 
+char *mustReadSymlinkExt(char *path, struct stat *sb)
+/* Read symlink or abort. FreeMem the returned value. */
+{
+ssize_t nbytes, bufsiz;
+// determine whether the buffer returned was truncated.
+bufsiz = sb->st_size + 1;
+char *symPath = needMem(bufsiz);
+nbytes = readlink(path, symPath, bufsiz);
+if (nbytes == -1) 
+    errnoAbort("readlink failure on symlink %s", path);
+if (nbytes == bufsiz)
+    errAbort("readlink returned buffer truncated\n");
+return symPath;
+}
+
+char *mustReadSymlink(char *path)
+/* Read symlink or abort. Checks that path is a symlink. 
+FreeMem the returned value. */
+{
+struct stat sb;
+if (lstat(path, &sb) == -1)
+    errnoAbort("lstat failure on %s", path);
+if ((sb.st_mode & S_IFMT) != S_IFLNK)
+    errnoAbort("path %s not a symlink.", path);
+return mustReadSymlinkExt(path, &sb);
+}
+
+
 void makeSymLink(char *oldName, char *newName)
 /* Return a symbolic link from newName to oldName or die trying */
 {
 int err = symlink(oldName, newName);
 if (err < 0)
      errnoAbort("Couldn't make symbolic link from %s to %s\n", oldName, newName);
 }