From a7d2a941bec536b54f89c8c1656598e3edf16fa8 Mon Sep 17 00:00:00 2001 From: Gilbert Chen Date: Wed, 29 Aug 2018 17:10:35 -0400 Subject: [PATCH] Restore UID and GID of symlinks --- src/duplicacy_backupmanager.go | 2 ++ src/duplicacy_entry.go | 8 +++++--- src/duplicacy_utils_others.go | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/duplicacy_backupmanager.go b/src/duplicacy_backupmanager.go index 80e550c..0b908dd 100644 --- a/src/duplicacy_backupmanager.go +++ b/src/duplicacy_backupmanager.go @@ -825,6 +825,7 @@ func (manager *BackupManager) Restore(top string, revision int, inPlace bool, qu if stat.Mode()&os.ModeSymlink != 0 { isRegular, link, err := Readlink(fullPath) if err == nil && link == entry.Link && !isRegular { + entry.RestoreMetadata(fullPath, nil, setOwner) continue } } @@ -837,6 +838,7 @@ func (manager *BackupManager) Restore(top string, revision int, inPlace bool, qu LOG_ERROR("RESTORE_SYMLINK", "Can't create symlink %s: %v", entry.Path, err) return false } + entry.RestoreMetadata(fullPath, nil, setOwner) LOG_TRACE("DOWNLOAD_DONE", "Symlink %s updated", entry.Path) } else if entry.IsDir() { stat, err := os.Stat(fullPath) diff --git a/src/duplicacy_entry.go b/src/duplicacy_entry.go index 64d8c3a..1f1b795 100644 --- a/src/duplicacy_entry.go +++ b/src/duplicacy_entry.go @@ -292,7 +292,7 @@ func (entry *Entry) String(maxSizeDigits int) string { func (entry *Entry) RestoreMetadata(fullPath string, fileInfo *os.FileInfo, setOwner bool) bool { if fileInfo == nil { - stat, err := os.Stat(fullPath) + stat, err := os.Lstat(fullPath) fileInfo = &stat if err != nil { LOG_ERROR("RESTORE_STAT", "Failed to retrieve the file info: %v", err) @@ -307,7 +307,8 @@ func (entry *Entry) RestoreMetadata(fullPath string, fileInfo *os.FileInfo, setO } } - if (*fileInfo).Mode()&fileModeMask != entry.GetPermissions() { + // Only set the permission if the file is not a symlink + if !entry.IsLink() && (*fileInfo).Mode() & fileModeMask != entry.GetPermissions() { err := os.Chmod(fullPath, entry.GetPermissions()) if err != nil { LOG_ERROR("RESTORE_CHMOD", "Failed to set the file permissions: %v", err) @@ -315,7 +316,8 @@ func (entry *Entry) RestoreMetadata(fullPath string, fileInfo *os.FileInfo, setO } } - if (*fileInfo).ModTime().Unix() != entry.Time { + // Only set the time if the file is not a symlink + if !entry.IsLink() && (*fileInfo).ModTime().Unix() != entry.Time { modifiedTime := time.Unix(entry.Time, 0) err := os.Chtimes(fullPath, modifiedTime, modifiedTime) if err != nil { diff --git a/src/duplicacy_utils_others.go b/src/duplicacy_utils_others.go index b3d9f2b..64398dd 100644 --- a/src/duplicacy_utils_others.go +++ b/src/duplicacy_utils_others.go @@ -35,7 +35,7 @@ func SetOwner(fullPath string, entry *Entry, fileInfo *os.FileInfo) bool { stat, ok := (*fileInfo).Sys().(*syscall.Stat_t) if ok && stat != nil && (int(stat.Uid) != entry.UID || int(stat.Gid) != entry.GID) { if entry.UID != -1 && entry.GID != -1 { - err := os.Chown(fullPath, entry.UID, entry.GID) + err := os.Lchown(fullPath, entry.UID, entry.GID) if err != nil { LOG_ERROR("RESTORE_CHOWN", "Failed to change uid or gid: %v", err) return false