diff --git a/node.go b/node.go index aab2aa8a8..249edbb4a 100644 --- a/node.go +++ b/node.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "os" + "os/user" "strconv" "syscall" "time" @@ -337,3 +338,49 @@ func (node *Node) isNewer(path string, fi os.FileInfo) bool { debug.Log("node.isNewer", "node %v is not newer", path) return false } + +func (node *Node) fillUser(stat *syscall.Stat_t) error { + node.UID = stat.Uid + node.GID = stat.Gid + + u, err := user.LookupId(strconv.Itoa(int(stat.Uid))) + if err != nil { + return err + } + + node.User = u.Username + return nil +} + +func (node *Node) fillExtra(path string, fi os.FileInfo) error { + stat, ok := fi.Sys().(*syscall.Stat_t) + if !ok { + return nil + } + + node.Inode = stat.Ino + + node.fillUser(stat) + node.fillTimes(stat) + + var err error + + switch node.Type { + case "file": + node.Size = uint64(stat.Size) + node.Links = uint64(stat.Nlink) + case "dir": + case "symlink": + node.LinkTarget, err = os.Readlink(path) + case "dev": + node.fillDevice(stat) + case "chardev": + node.fillDevice(stat) + case "fifo": + case "socket": + default: + err = fmt.Errorf("invalid node type %q", node.Type) + } + + return err +} diff --git a/node_darwin.go b/node_darwin.go index 666a576ff..183f6201d 100644 --- a/node_darwin.go +++ b/node_darwin.go @@ -15,43 +15,13 @@ func (node *Node) OpenForReading() (*os.File, error) { return os.Open(node.path) } -func (node *Node) fillExtra(path string, fi os.FileInfo) error { - stat, ok := fi.Sys().(*syscall.Stat_t) - if !ok { - return nil - } - +func (node *Node) fillTimes(stat *syscall.Stat_t) { node.ChangeTime = time.Unix(stat.Ctimespec.Unix()) node.AccessTime = time.Unix(stat.Atimespec.Unix()) - node.UID = stat.Uid - node.GID = stat.Gid +} - if u, err := user.LookupId(strconv.Itoa(int(stat.Uid))); err == nil { - node.User = u.Username - } - - node.Inode = stat.Ino - - var err error - - switch node.Type { - case "file": - node.Size = uint64(stat.Size) - node.Links = uint64(stat.Nlink) - case "dir": - case "symlink": - node.LinkTarget, err = os.Readlink(path) - case "dev": - node.Device = uint64(stat.Rdev) - case "chardev": - node.Device = uint64(stat.Rdev) - case "fifo": - case "socket": - default: - err = fmt.Errorf("invalid node type %q", node.Type) - } - - return err +func (node *Node) fillDevice(stat *syscall.Stat_t) { + node.Device = uint64(stat.Rdev) } func (node *Node) createDevAt(path string) error { diff --git a/node_linux.go b/node_linux.go index 7ba11e943..c2b776be1 100644 --- a/node_linux.go +++ b/node_linux.go @@ -1,10 +1,7 @@ package restic import ( - "fmt" "os" - "os/user" - "strconv" "syscall" "time" ) @@ -17,43 +14,13 @@ func (node *Node) OpenForReading() (*os.File, error) { return file, err } -func (node *Node) fillExtra(path string, fi os.FileInfo) error { - stat, ok := fi.Sys().(*syscall.Stat_t) - if !ok { - return nil - } - +func (node *Node) fillTimes(stat *syscall.Stat_t) { node.ChangeTime = time.Unix(stat.Ctim.Unix()) node.AccessTime = time.Unix(stat.Atim.Unix()) - node.UID = stat.Uid - node.GID = stat.Gid +} - if u, err := user.LookupId(strconv.Itoa(int(stat.Uid))); err == nil { - node.User = u.Username - } - - node.Inode = stat.Ino - - var err error - - switch node.Type { - case "file": - node.Size = uint64(stat.Size) - node.Links = uint64(stat.Nlink) - case "dir": - case "symlink": - node.LinkTarget, err = os.Readlink(path) - case "dev": - node.Device = stat.Rdev - case "chardev": - node.Device = stat.Rdev - case "fifo": - case "socket": - default: - err = fmt.Errorf("invalid node type %q", node.Type) - } - - return err +func (node *Node) fillDevice(stat *syscall.Stat_t) { + node.Device = stat.Rdev } func (node *Node) createDevAt(path string) error {