diff options
author | Přemysl Eric Janouch <p@janouch.name> | 2023-12-27 02:00:23 +0100 |
---|---|---|
committer | Přemysl Eric Janouch <p@janouch.name> | 2023-12-27 02:00:23 +0100 |
commit | 79038a2a6d21681b99cafcfb712b3da7b32d663e (patch) | |
tree | df40dced4319b87bf3c9065ba4337402e148752c /main.go | |
parent | 94399bda33cc4e4bc94c59378027455af12cc56a (diff) | |
download | gallery-79038a2a6d21681b99cafcfb712b3da7b32d663e.tar.gz gallery-79038a2a6d21681b99cafcfb712b3da7b32d663e.tar.xz gallery-79038a2a6d21681b99cafcfb712b3da7b32d663e.zip |
Make check optionally check harder
Diffstat (limited to 'main.go')
-rw-r--r-- | main.go | 53 |
1 files changed, 51 insertions, 2 deletions
@@ -32,6 +32,7 @@ import ( "strconv" "strings" "sync" + "sync/atomic" "syscall" "time" @@ -2023,8 +2024,49 @@ func checkFiles(root, suffix string, hashes []string) (bool, []string, error) { return ok, intersection, nil } +func checkHash(path string) (message string, err error) { + f, err := os.Open(path) + if err != nil { + return err.Error(), nil + } + defer f.Close() + + // We get 2 levels of parent directories in here, just filter them out. + if fi, err := f.Stat(); err != nil { + return err.Error(), nil + } else if fi.IsDir() { + return "", nil + } + + hash := sha1.New() + _, err = io.CopyBuffer(hash, f, make([]byte, 65536)) + if err != nil { + return err.Error(), nil + } + + sha1 := hex.EncodeToString(hash.Sum(nil)) + if sha1 != filepath.Base(path) { + return fmt.Sprintf("mismatch, found %s", sha1), nil + } + return "", nil +} + +func checkHashes(paths []string) (bool, error) { + log.Println("checking image hashes") + var failed atomic.Bool + err := parallelize(paths, func(path string) (string, error) { + message, err := checkHash(path) + if message != "" { + failed.Store(true) + } + return message, err + }) + return !failed.Load(), err +} + // cmdCheck carries out various database consistency checks. func cmdCheck(fs *flag.FlagSet, args []string) error { + full := fs.Bool("full", false, "verify image hashes") if err := fs.Parse(args); err != nil { return err } @@ -2076,8 +2118,6 @@ func cmdCheck(fs *flag.FlagSet, args []string) error { ok = false } - // NOTE: We could also compare mtime, and on mismatch the current SHA1, - // though that's more of a "sync" job. log.Println("checking for dead symlinks") for _, path := range intersection { if _, err := os.Stat(path); err != nil { @@ -2085,6 +2125,15 @@ func cmdCheck(fs *flag.FlagSet, args []string) error { fmt.Printf("%s: %s\n", path, err) } } + + if *full { + if ok2, err := checkHashes(intersection); err != nil { + return err + } else if !ok2 { + ok = false + } + } + if !ok { return errors.New("detected inconsistencies") } |