diff --git a/files/set.go b/files/set.go index 084b712b..4b4c285f 100644 --- a/files/set.go +++ b/files/set.go @@ -76,7 +76,7 @@ func (m *Set) ReplaceWithDelete(id uint, fs []scanner.File) { for _, ck := range m.remoteKey[cid.LocalID] { if _, ok := nf[ck.Name]; !ok { cf := m.files[ck].File - if cf.Flags&protocol.FlagDeleted != protocol.FlagDeleted { + if !protocol.IsDeleted(cf.Flags) { cf.Flags |= protocol.FlagDeleted cf.Blocks = nil cf.Size = 0 @@ -193,7 +193,7 @@ func (m *Set) equals(id uint, fs []scanner.File) bool { curWithoutDeleted := make(map[string]key) for _, k := range m.remoteKey[id] { f := m.files[k].File - if f.Flags&protocol.FlagDeleted == 0 { + if !protocol.IsDeleted(f.Flags) { curWithoutDeleted[f.Name] = k } } diff --git a/model/model.go b/model/model.go index 1be2ebbf..4f60aedd 100644 --- a/model/model.go +++ b/model/model.go @@ -149,9 +149,9 @@ func (m *Model) ConnectionStats() map[string]ConnectionInfo { for _, repo := range m.nodeRepos[node] { for _, f := range m.repoFiles[repo].Global() { - if f.Flags&protocol.FlagDeleted == 0 { + if !protocol.IsDeleted(f.Flags) { size := f.Size - if f.Flags&protocol.FlagDirectory != 0 { + if protocol.IsDirectory(f.Flags) { size = zeroEntrySize } tot += size @@ -160,9 +160,9 @@ func (m *Model) ConnectionStats() map[string]ConnectionInfo { } for _, f := range m.repoFiles[repo].Need(m.cm.Get(node)) { - if f.Flags&protocol.FlagDeleted == 0 { + if !protocol.IsDeleted(f.Flags) { size := f.Size - if f.Flags&protocol.FlagDirectory != 0 { + if protocol.IsDirectory(f.Flags) { size = zeroEntrySize } have -= size @@ -186,9 +186,9 @@ func (m *Model) ConnectionStats() map[string]ConnectionInfo { func sizeOf(fs []scanner.File) (files, deleted int, bytes int64) { for _, f := range fs { - if f.Flags&protocol.FlagDeleted == 0 { + if !protocol.IsDeleted(f.Flags) { files++ - if f.Flags&protocol.FlagDirectory == 0 { + if !protocol.IsDirectory(f.Flags) { bytes += f.Size } else { bytes += zeroEntrySize @@ -252,7 +252,7 @@ func (m *Model) Index(nodeID string, repo string, fs []protocol.FileInfo) { lamport.Default.Tick(f.Version) if debug { var flagComment string - if f.Flags&protocol.FlagDeleted != 0 { + if protocol.IsDeleted(f.Flags) { flagComment = " (deleted)" } l.Debugf("IDX(in): %s %q/%q m=%d f=%o%s v=%d (%d blocks)", nodeID, repo, f.Name, f.Modified, f.Flags, flagComment, f.Version, len(f.Blocks)) @@ -283,7 +283,7 @@ func (m *Model) IndexUpdate(nodeID string, repo string, fs []protocol.FileInfo) lamport.Default.Tick(f.Version) if debug { var flagComment string - if f.Flags&protocol.FlagDeleted != 0 { + if protocol.IsDeleted(f.Flags) { flagComment = " (deleted)" } l.Debugf("IDXUP(in): %s %q/%q m=%d f=%o%s v=%d (%d blocks)", nodeID, repo, f.Name, f.Modified, f.Flags, flagComment, f.Version, len(f.Blocks)) @@ -368,7 +368,7 @@ func (m *Model) Request(nodeID, repo, name string, offset int64, size int) ([]by } lf := r.Get(cid.LocalID, name) - if lf.Suppressed || lf.Flags&protocol.FlagDeleted != 0 { + if lf.Suppressed || protocol.IsDeleted(lf.Flags) { if debug { l.Debugf("REQ(in): %s: %q / %q o=%d s=%d; invalid: %v", nodeID, repo, name, offset, size, lf) } @@ -502,7 +502,7 @@ func (m *Model) protocolIndex(repo string) []protocol.FileInfo { mf := fileInfoFromFile(f) if debug { var flagComment string - if mf.Flags&protocol.FlagDeleted != 0 { + if protocol.IsDeleted(mf.Flags) { flagComment = " (deleted)" } l.Debugf("IDX(out): %q/%q m=%d f=%o%s v=%d (%d blocks)", repo, mf.Name, mf.Modified, mf.Flags, flagComment, mf.Version, len(mf.Blocks)) diff --git a/model/puller.go b/model/puller.go index d3e1b0dd..5c525766 100644 --- a/model/puller.go +++ b/model/puller.go @@ -232,7 +232,7 @@ func (p *puller) fixupDirectories() { return nil } - if cur.Flags&protocol.FlagDeleted != 0 { + if protocol.IsDeleted(cur.Flags) { if debug { l.Debugf("queue delete dir: %v", cur) } @@ -245,7 +245,7 @@ func (p *puller) fixupDirectories() { return nil } - if cur.Flags&uint32(os.ModePerm) != uint32(info.Mode()&os.ModePerm) { + if !permsEqual(cur.Flags, uint32(info.Mode())) { err := os.Chmod(path, os.FileMode(cur.Flags)&os.ModePerm) if err != nil { l.Warnln("Restoring folder flags: %q: %v", path, err) @@ -336,8 +336,8 @@ func (p *puller) handleBlock(b bqBlock) bool { // For directories, making sure they exist is enough. // Deleted directories we mark as handled and delete later. - if f.Flags&protocol.FlagDirectory != 0 { - if f.Flags&protocol.FlagDeleted == 0 { + if protocol.IsDirectory(f.Flags) { + if !protocol.IsDeleted(f.Flags) { path := filepath.Join(p.dir, f.Name) _, err := os.Stat(path) if err != nil && os.IsNotExist(err) { @@ -520,7 +520,7 @@ func (p *puller) handleEmptyBlock(b bqBlock) { } } - if f.Flags&protocol.FlagDeleted != 0 { + if protocol.IsDeleted(f.Flags) { if debug { l.Debugf("pull: delete %q", f.Name) } diff --git a/model/util.go b/model/util.go index e9290531..d692006f 100644 --- a/model/util.go +++ b/model/util.go @@ -109,3 +109,15 @@ func compareClusterConfig(local, remote protocol.ClusterConfigMessage) error { return nil } + +func permsEqual(a, b uint32) bool { + switch runtime.GOOS { + case "windows": + // There is only writeable and read only, represented for user, group + // and other equally. We only compare against user. + return a&0600 == b&0600 + default: + // All bits count + return a&0777 == b&0777 + } +} diff --git a/protocol/protocol.go b/protocol/protocol.go index 55bc4735..442b185a 100644 --- a/protocol/protocol.go +++ b/protocol/protocol.go @@ -516,3 +516,19 @@ func (c *rawConnection) Statistics() Statistics { OutBytesTotal: int(c.cw.Tot()), } } + +func IsDeleted(bits uint32) bool { + return bits&FlagDeleted != 0 +} + +func IsInvalid(bits uint32) bool { + return bits&FlagInvalid != 0 +} + +func IsDirectory(bits uint32) bool { + return bits&FlagDirectory != 0 +} + +func HasPermissionBits(bits uint32) bool { + return bits&FlagNoPermBits == 0 +} diff --git a/scanner/walk.go b/scanner/walk.go index a9465009..bebd92e4 100644 --- a/scanner/walk.go +++ b/scanner/walk.go @@ -162,7 +162,7 @@ func (w *Walker) walkAndHashFiles(res *[]File, ign map[string][]string) filepath if info.Mode().IsDir() { if w.CurrentFiler != nil { cf := w.CurrentFiler.CurrentFile(rn) - if cf.Modified == info.ModTime().Unix() && cf.Flags&protocol.FlagDirectory != 0 && permsEqual(cf.Flags, uint32(info.Mode())) { + if cf.Modified == info.ModTime().Unix() && protocol.IsDirectory(cf.Flags) && permsEqual(cf.Flags, uint32(info.Mode())) { if debug { l.Debugln("unchanged:", cf) } @@ -186,7 +186,7 @@ func (w *Walker) walkAndHashFiles(res *[]File, ign map[string][]string) filepath if info.Mode().IsRegular() { if w.CurrentFiler != nil { cf := w.CurrentFiler.CurrentFile(rn) - if cf.Flags&protocol.FlagDeleted == 0 && cf.Modified == info.ModTime().Unix() && permsEqual(cf.Flags, uint32(info.Mode())) { + if !protocol.IsDeleted(cf.Flags) && cf.Modified == info.ModTime().Unix() && permsEqual(cf.Flags, uint32(info.Mode())) { if debug { l.Debugln("unchanged:", cf) }