github.com/artpar/rclone@v1.67.3/backend/local/metadata_bsd.go (about) 1 //go:build darwin || freebsd || netbsd 2 3 package local 4 5 import ( 6 "fmt" 7 "os" 8 "syscall" 9 "time" 10 11 "github.com/artpar/rclone/fs" 12 ) 13 14 // Read the time specified from the os.FileInfo 15 func readTime(t timeType, fi os.FileInfo) time.Time { 16 stat, ok := fi.Sys().(*syscall.Stat_t) 17 if !ok { 18 fs.Debugf(nil, "didn't return Stat_t as expected") 19 return fi.ModTime() 20 } 21 switch t { 22 case aTime: 23 return time.Unix(stat.Atimespec.Unix()) 24 case bTime: 25 return time.Unix(stat.Birthtimespec.Unix()) 26 case cTime: 27 return time.Unix(stat.Ctimespec.Unix()) 28 } 29 return fi.ModTime() 30 } 31 32 // Read the metadata from the file into metadata where possible 33 func (o *Object) readMetadataFromFile(m *fs.Metadata) (err error) { 34 info, err := o.fs.lstat(o.path) 35 if err != nil { 36 return err 37 } 38 stat, ok := info.Sys().(*syscall.Stat_t) 39 if !ok { 40 fs.Debugf(o, "didn't return Stat_t as expected") 41 return nil 42 } 43 m.Set("mode", fmt.Sprintf("%0o", stat.Mode)) 44 m.Set("uid", fmt.Sprintf("%d", stat.Uid)) 45 m.Set("gid", fmt.Sprintf("%d", stat.Gid)) 46 if stat.Rdev != 0 { 47 m.Set("rdev", fmt.Sprintf("%x", stat.Rdev)) 48 } 49 setTime := func(key string, t syscall.Timespec) { 50 m.Set(key, time.Unix(t.Unix()).Format(metadataTimeFormat)) 51 } 52 setTime("atime", stat.Atimespec) 53 setTime("mtime", stat.Mtimespec) 54 setTime("btime", stat.Birthtimespec) 55 return nil 56 }