310ed9324362faacfdf0ca7d0cd011605ce2e750
galt
  Tue Nov 28 03:05:06 2023 -0800
Improving ability to restore symlinked files back into their wrangle or submit directories so they are not lost. Includes special files such as 2bit under the path "". Handles either one dataset at a time, or can with great care be used to restore all files for all sets. Great care must be used with this command, and observe many caviots as well. We have no real way to preserve our symlinks other than this.

diff --git src/hg/cirm/cdw/cdwUnlockSubmittedFile/cdwUnlockSubmittedFile.c src/hg/cirm/cdw/cdwUnlockSubmittedFile/cdwUnlockSubmittedFile.c
index a3241e0..5842d43 100644
--- src/hg/cirm/cdw/cdwUnlockSubmittedFile/cdwUnlockSubmittedFile.c
+++ src/hg/cirm/cdw/cdwUnlockSubmittedFile/cdwUnlockSubmittedFile.c
@@ -42,33 +42,31 @@
 int result = findSubmitSymlinkExt(submitFileName, submitDir, &path, &lastPath, &symlinkLevels);
 if (result == -1)  // path does not exist
     {
     errAbort("path=[%s] does not exist following submitDir/submitFileName through symlinks.", path);
     }
 if (symlinkLevels < 1)
     {
     errAbort("Too few symlinks followed: %d symlinks. Where is the symlink created by cdwSubmit?", symlinkLevels);
     }
 verbose(3, "lastPath=%s path=%s\n", lastPath, path);
 if (!startsWith(cdwRootDir, path))
     {
     errAbort("expected path=[%s] to start with %s", path, cdwRootDir);
     }
 
-if (unlink(lastPath) == -1)  // drop about to be invalid symlink
-    errnoAbort("unlink failure %s", lastPath);
-copyFile(path, lastPath);
+safeCopyFile(path, lastPath);  // avoid partial copies, only mv temp in after copy is complete, preserves the symlink. helps with control-C or other interruptions.
 touchFileFromFile(path, lastPath);
 chmod(lastPath, 0664);
 
 freeMem(lastPath);
 freeMem(path);
 
 }
 
 int main(int argc, char *argv[])
 /* Process command line. */
 {
 optionInit(&argc, argv, options);
 if (argc != 2)
     usage();
 cdwUnlockSubmittedFile(argv[1]);