Index: nsinstall.c
===================================================================
RCS file: /cvsroot/buildtools/windows/source/shmsdos/nsinstall.c,v
retrieving revision 1.1
diff -u2 -r1.1 nsinstall.c
--- nsinstall.c
+++ nsinstall.c
@@ -35,4 +35,8 @@
         WIN32_FIND_DATA *fileData,
         void *arg);
+typedef BOOL (*CreateHardLinkFn)(
+        LPCSTR,
+        LPCSTR,
+        LPSECURITY_ATTRIBUTES);
 
 static int shellCp (char **pArgv); 
@@ -45,5 +49,12 @@
         char *dstFileName, DWORD dstFileAttributes,
         int force, int recursive);
+char *MoveToTemp(const char * filename);
 
+BOOL NoCreateHardLink(
+        LPCSTR lpFileName,
+        LPCSTR lpExistingFileName,
+        LPSECURITY_ATTRIBUTES lpSecurityAttributes){
+    return FALSE;
+};
 /* changes all forward slashes in token to back slashes */
 void changeForwardSlashesTpBackSlashes ( char *arg )
@@ -237,4 +248,51 @@
 )
 {
+    HANDLE hSrc, hDst;
+    HINSTANCE hInstLib;
+    BY_HANDLE_FILE_INFORMATION hSrcInfo, hDstInfo;
+    CreateHardLinkFn CreateHardLinkA;
+    char *backupFileName = 0;
+    if (srcFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+        fprintf(stderr, "nsinstall: %s is a directory\n",
+                srcFileName);
+        return FALSE;
+    }
+    hDst = CreateFile(dstFileName, 0, 0, 0, OPEN_EXISTING, 0, 0);
+    if (hDst != INVALID_HANDLE_VALUE) {
+        hSrc = CreateFile(srcFileName, 0, 0, 0, OPEN_EXISTING, 0, 0);
+        GetFileInformationByHandle(hSrc, &hSrcInfo);
+        GetFileInformationByHandle(hDst, &hDstInfo);
+        CloseHandle(hSrc);
+        CloseHandle(hDst);
+        if (   hSrcInfo.dwVolumeSerialNumber == hDstInfo.dwVolumeSerialNumber
+            && hSrcInfo.nFileIndexHigh == hDstInfo.nFileIndexHigh
+            && hSrcInfo.nFileIndexLow == hDstInfo.nFileIndexLow
+        ) {
+            return TRUE;
+        }
+        backupFileName = MoveToTemp(dstFileName);
+    }
+    hInstLib = LoadLibrary("kernel32");
+    CreateHardLinkA = (CreateHardLinkFn)GetProcAddress(hInstLib, "CreateHardLinkA");
+    if (!CreateHardLinkA)
+        CreateHardLinkA = NoCreateHardLink;
+#if 0
+    if (
+        !CreateHardLinkA(dstFileName, srcFileName, NULL)
+     && !CopyFile(srcFileName, dstFileName, FALSE)
+    )
+#else
+    if (!CreateHardLinkA(dstFileName, srcFileName, NULL) &&
+        !CopyFile(srcFileName, dstFileName, FALSE))
+#endif
+    {
+        if (backupFileName) {
+            MoveFile(dstFileName, backupFileName);
+            free(backupFileName);
+        }
+        fprintf(stderr, "nsinstall: cannot copy %s to %s: [%d] %s\n",
+                srcFileName, dstFileName, GetLastError(), sh_GetLastErrorMessage());
+        return FALSE;
+    }
     if (dstFileAttributes != 0xFFFFFFFF) {
         if ((dstFileAttributes & FILE_ATTRIBUTE_READONLY) && force) {
@@ -243,15 +301,7 @@
         }
     }
-
-    if (srcFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
-        fprintf(stderr, "nsinstall: %s is a directory\n",
-                srcFileName);
-        return FALSE;
-    } else {
-        if (!CopyFile(srcFileName, dstFileName, FALSE)) {
-            fprintf(stderr, "nsinstall: cannot copy %s to %s: %s\n",
-                    srcFileName, dstFileName, sh_GetLastErrorMessage());
-            return FALSE;
-        }
+    if (backupFileName) {
+        DeleteFile(backupFileName);
+        free(backupFileName);
     }
     return TRUE;
@@ -695,3 +745,29 @@
     FindClose(hSearch);
     return retVal;
+}
+
+/*limit for backup names:*/
+#define TOL  1000
+/*length of longest backup name:*/
+#define TLG   3
+/*length for use in sprintf:*/
+#define TLS "3"
+char *MoveToTemp(const char * filename)
+{
+    const int length = strlen(filename);
+    char * newFilename = malloc(length + 2 + TLG);
+    char * number = newFilename + length + 1;
+    int count = 0;
+    if (!newFilename)
+        return FALSE;
+    memcpy(newFilename, filename, length);
+    newFilename[length] = '.';
+    while (++count < TOL) {
+        sprintf(number, "%0" TLS "d", count);
+        if (MoveFile(filename, newFilename)) {
+            return newFilename;
+        }
+    }
+    free(newFilename);
+    return 0;
 }
Index: nsinstall.mak
===================================================================
RCS file: /cvsroot/buildtools/windows/source/shmsdos/nsinstall.mak,v
retrieving revision 1.1
diff -u2 -r1.1 nsinstall.mak
