func (sync *Unidirectional) syncDir(entry storage.DirectoryEntry) error { path := entry.Path() var ( targetEntry storage.Entry targetDirEntry storage.DirectoryEntry targetDir storage.Directory err error ok bool ) targetEntry, err = sync.to.Stat(path) if err != nil { return err } if targetDirEntry, ok = targetEntry.(storage.DirectoryEntry); !ok && targetEntry != nil { if err := targetEntry.Remove(); err != nil { return err } targetDirEntry = nil } if targetDirEntry != nil { return nil } sync.events <- &EventStartSyncing{entry: entry} targetDir, err = sync.to.Mkdir(path) if err != nil { return err } defer func() { sync.setLastErrorIfApplicable(targetDir.Close()) }() return nil }
func (sync *Unidirectional) syncFile(dirEntry storage.DirectoryEntry, entry storage.FileEntry) error { path := entry.Path() mustSync := false targetEntry, err := sync.to.Stat(path) if err != nil { return err } if targetEntry == nil { mustSync = true } else if _, ok := targetEntry.(storage.FileEntry); !ok { mustSync = true } else if targetEntry.Mtime().Before(entry.Mtime()) { mustSync = true } if !mustSync { return nil } sync.events <- &EventStartSyncing{entry: entry} targetDirEntry, err := sync.to.Stat(dirEntry.Path()) if err != nil { return err } targetDir, err := targetDirEntry.(storage.DirectoryEntry).Open() if err != nil { return err } defer func() { _ = targetDir.Close() }() tempFile, err := targetDir.CreateFile(sync.tempFileNameFor(entry)) if err != nil { return err } defer func() { entry, err := sync.to.Stat(tempFile.Entry().Path()) if err != nil { sync.setLastErrorIfApplicable(err) return } if entry != nil { sync.setLastErrorIfApplicable(tempFile.Close()) sync.setLastErrorIfApplicable(tempFile.Entry().Remove()) } }() soureFile, err := entry.Open() if err != nil { return err } defer func() { sync.setLastErrorIfApplicable(soureFile.Close()) }() if _, err := io.Copy(tempFile, soureFile); err != nil { return err } if err := tempFile.Close(); err != nil { return err } if err := soureFile.Close(); err != nil { return err } if err := tempFile.Entry().SetMtime(entry.Mtime()); err != nil { return err } if targetEntry != nil { if err := targetEntry.Remove(); err != nil { return err } } if _, err := tempFile.Entry().Rename(entry.Name()); err != nil { return err } return nil }