]> wimlib.net Git - wimlib/blobdiff - src/unix_apply.c
unix_apply.c: Allow creating symlinks and hardlinks over existing files
[wimlib] / src / unix_apply.c
index e27accff294769c9e95b2114ce0b963d81e3a9f7..bd576ef08c0f872f04ceb77b940bde72fa67b64a 100644 (file)
@@ -81,21 +81,33 @@ unix_create_directory(const tchar *path, struct apply_ctx *ctx)
 }
 
 static int
-unix_create_hardlink(const tchar *oldpath, const tchar *newpath,
-                    struct apply_ctx *ctx)
+unix_makelink(const tchar *oldpath, const tchar *newpath,
+             int (*makelink)(const tchar *oldpath, const tchar *newpath))
 {
-       if (link(oldpath, newpath))
+       if ((*makelink)(oldpath, newpath)) {
+               if (errno == EEXIST) {
+                       if (unlink(newpath))
+                               return WIMLIB_ERR_LINK;
+                       if ((*makelink)(oldpath, newpath))
+                               return WIMLIB_ERR_LINK;
+                       return 0;
+               }
                return WIMLIB_ERR_LINK;
+       }
        return 0;
 }
+static int
+unix_create_hardlink(const tchar *oldpath, const tchar *newpath,
+                    struct apply_ctx *ctx)
+{
+       return unix_makelink(oldpath, newpath, link);
+}
 
 static int
 unix_create_symlink(const tchar *oldpath, const tchar *newpath,
                    struct apply_ctx *ctx)
 {
-       if (symlink(oldpath, newpath))
-               return WIMLIB_ERR_LINK;
-       return 0;
+       return unix_makelink(oldpath, newpath, symlink);
 }
 
 static int
@@ -124,7 +136,7 @@ unix_set_unix_data(const tchar *path, const struct wimlib_unix_data *data,
        struct stat stbuf;
 
        if (lstat(path, &stbuf))
-               return WIMLIB_ERR_STAT;
+               return WIMLIB_ERR_SET_SECURITY;
        if (!S_ISLNK(stbuf.st_mode))
                if (chmod(path, data->mode))
                        return WIMLIB_ERR_SET_SECURITY;