func repairModified(store *storage.Storage, tx *storage.Tx, modified entities.Files, pretend bool, settings entities.Settings) error { log.Infof(2, "repairing modified files") for _, dbFile := range modified { stat, err := os.Stat(dbFile.Path()) if err != nil { return err } fingerprint, err := fingerprint.Create(dbFile.Path(), settings.FileFingerprintAlgorithm(), settings.DirectoryFingerprintAlgorithm(), settings.SymlinkFingerprintAlgorithm()) if err != nil { log.Warnf("%v: could not create fingerprint: %v", dbFile.Path(), err) continue } if !pretend { _, err := store.UpdateFile(tx, dbFile.Id, dbFile.Path(), fingerprint, stat.ModTime(), stat.Size(), stat.IsDir()) if err != nil { return fmt.Errorf("%v: could not update file in database: %v", dbFile.Path(), err) } } fmt.Printf("%v: updated fingerprint\n", dbFile.Path()) } return nil }
func manualRepairFile(store *storage.Storage, tx *storage.Tx, file *entities.File, toPath string) error { var fingerprint fingerprint.Fingerprint var modTime time.Time var size int64 var isDir bool stat, err := os.Stat(toPath) if err != nil { switch { case os.IsPermission(err): return fmt.Errorf("%v: permission denied", toPath) case os.IsNotExist(err): return fmt.Errorf("%v: file not found", toPath) default: return err } modTime = file.ModTime size = file.Size isDir = file.IsDir } else { modTime = stat.ModTime() size = stat.Size() isDir = stat.IsDir() } _, err = store.UpdateFile(tx, file.Id, toPath, fingerprint, modTime, size, isDir) return err }
func repairMoved(store *storage.Storage, tx *storage.Tx, missing entities.Files, searchPaths []string, pretend bool, settings entities.Settings) error { log.Infof(2, "repairing moved files") if len(missing) == 0 || len(searchPaths) == 0 { // don't bother enumerating filesystem if nothing to do return nil } pathsBySize, err := buildPathBySizeMap(searchPaths) if err != nil { return err } for index, dbFile := range missing { log.Infof(2, "%v: searching for new location", dbFile.Path()) pathsOfSize := pathsBySize[dbFile.Size] log.Infof(2, "%v: file is of size %v, identified %v files of this size", dbFile.Path(), dbFile.Size, len(pathsOfSize)) for _, candidatePath := range pathsOfSize { candidateFile, err := store.FileByPath(tx, candidatePath) if err != nil { return err } if candidateFile != nil { // file is already tagged continue } stat, err := os.Stat(candidatePath) if err != nil { return fmt.Errorf("%v: could not stat file: %v", candidatePath, err) } fingerprint, err := fingerprint.Create(candidatePath, settings.FileFingerprintAlgorithm(), settings.DirectoryFingerprintAlgorithm(), settings.SymlinkFingerprintAlgorithm()) if err != nil { return fmt.Errorf("%v: could not create fingerprint: %v", candidatePath, err) } if fingerprint == dbFile.Fingerprint { if !pretend { _, err := store.UpdateFile(tx, dbFile.Id, candidatePath, dbFile.Fingerprint, stat.ModTime(), dbFile.Size, dbFile.IsDir) if err != nil { return fmt.Errorf("%v: could not update file in database: %v", dbFile.Path(), err) } } fmt.Printf("%v: updated path to %v\n", dbFile.Path(), candidatePath) missing[index] = nil break } } } return nil }