mirror of
https://github.com/jkl1337/duplicacy.git
synced 2026-01-02 11:44:45 -06:00
Factor out hard link code for cross platform build
Move system specific code out of entry so the build continues to work on Windows. Hard links are not currently supported on Windows, the behavior is a no-op.
This commit is contained in:
@@ -18,7 +18,6 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/vmihailenco/msgpack"
|
"github.com/vmihailenco/msgpack"
|
||||||
@@ -752,11 +751,6 @@ func (files FileInfoCompare) Less(i, j int) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type listEntryLinkKey struct {
|
|
||||||
dev uint64
|
|
||||||
ino uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
type ListingState struct {
|
type ListingState struct {
|
||||||
linkIndex int
|
linkIndex int
|
||||||
linkTable map[listEntryLinkKey]int // map unique inode details to initially found path
|
linkTable map[listEntryLinkKey]int // map unique inode details to initially found path
|
||||||
@@ -816,34 +810,30 @@ func ListEntries(top string, path string, patterns []string, nobackupFile string
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
var linkKey *listEntryLinkKey
|
linkKey, isHardLinked := entry.getHardLinkKey(f)
|
||||||
|
if isHardLinked {
|
||||||
if runtime.GOOS != "windows" && !entry.IsDir() {
|
if linkIndex, seen := listingState.linkTable[linkKey]; seen {
|
||||||
if stat := f.Sys().(*syscall.Stat_t); stat != nil && stat.Nlink > 1 {
|
if linkIndex == -1 {
|
||||||
k := listEntryLinkKey{dev: uint64(stat.Dev), ino: uint64(stat.Ino)}
|
LOG_DEBUG("LIST_EXCLUDE", "%s was excluded or skipped (hard link)", entry.Path)
|
||||||
if linkIndex, seen := listingState.linkTable[k]; seen {
|
|
||||||
if linkIndex == -1 {
|
|
||||||
LOG_DEBUG("LIST_EXCLUDE", "%s is excluded by attribute (hard link)", entry.Path)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
entry.Size = 0
|
|
||||||
if entry.IsFile() {
|
|
||||||
entry.Link = strconv.FormatInt(int64(linkIndex), 16)
|
|
||||||
} else {
|
|
||||||
entry.EndChunk = entryHardLinkTargetChunkMarker
|
|
||||||
entry.EndOffset = linkIndex
|
|
||||||
}
|
|
||||||
listingChannel <- entry
|
|
||||||
continue
|
continue
|
||||||
} else {
|
|
||||||
if entry.IsFile() {
|
|
||||||
entry.Link = "/"
|
|
||||||
} else {
|
|
||||||
entry.EndChunk = entryHardLinkRootChunkMarker
|
|
||||||
}
|
|
||||||
listingState.linkTable[k] = -1
|
|
||||||
linkKey = &k
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entry.Size = 0
|
||||||
|
if entry.IsFile() {
|
||||||
|
entry.Link = strconv.FormatInt(int64(linkIndex), 16)
|
||||||
|
} else {
|
||||||
|
entry.EndChunk = entryHardLinkTargetChunkMarker
|
||||||
|
entry.EndOffset = linkIndex
|
||||||
|
}
|
||||||
|
listingChannel <- entry
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
if entry.IsFile() {
|
||||||
|
entry.Link = "/"
|
||||||
|
} else {
|
||||||
|
entry.EndChunk = entryHardLinkRootChunkMarker
|
||||||
|
}
|
||||||
|
listingState.linkTable[linkKey] = -1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -892,8 +882,8 @@ func ListEntries(top string, path string, patterns []string, nobackupFile string
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if linkKey != nil {
|
if isHardLinked {
|
||||||
listingState.linkTable[*linkKey] = listingState.linkIndex
|
listingState.linkTable[linkKey] = listingState.linkIndex
|
||||||
listingState.linkIndex++
|
listingState.linkIndex++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,25 @@ func SetOwner(fullPath string, entry *Entry, fileInfo *os.FileInfo) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type listEntryLinkKey struct {
|
||||||
|
dev uint64
|
||||||
|
ino uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (entry *Entry) getHardLinkKey(f os.FileInfo) (key listEntryLinkKey, linked bool) {
|
||||||
|
if entry.IsDir() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
stat := f.Sys().(*syscall.Stat_t)
|
||||||
|
if stat == nil || stat.Nlink < 2 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
key.dev = uint64(stat.Dev)
|
||||||
|
key.ino = uint64(stat.Ino)
|
||||||
|
linked = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (entry *Entry) ReadSpecial(fileInfo os.FileInfo) bool {
|
func (entry *Entry) ReadSpecial(fileInfo os.FileInfo) bool {
|
||||||
if fileInfo.Mode()&(os.ModeDevice|os.ModeCharDevice) == 0 {
|
if fileInfo.Mode()&(os.ModeDevice|os.ModeCharDevice) == 0 {
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -110,6 +110,12 @@ func SetOwner(fullPath string, entry *Entry, fileInfo *os.FileInfo) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type listEntryLinkKey struct{}
|
||||||
|
|
||||||
|
func (entry *Entry) getHardLinkKey(f os.FileInfo) (key listEntryLinkKey, linked bool) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (entry *Entry) ReadAttributes(top string) {
|
func (entry *Entry) ReadAttributes(top string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user