From 79038a2a6d21681b99cafcfb712b3da7b32d663e Mon Sep 17 00:00:00 2001 From: Přemysl Eric Janouch
Date: Wed, 27 Dec 2023 02:00:23 +0100 Subject: Make check optionally check harder --- Makefile | 2 +- main.go | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 77d7875..fe30c13 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ outputs = gallery initialize.go public/mithril.js all: $(outputs) gallery: main.go initialize.go - go build -tags "fts5" -gcflags="all=-N -l" -o $@ + go build -tags "" -gcflags="all=-N -l" -o $@ initialize.go: initialize.sql gen-initialize.sh ./gen-initialize.sh initialize.sql > $@ public/mithril.js: diff --git a/main.go b/main.go index bbe6f92..9601164 100644 --- a/main.go +++ b/main.go @@ -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") } -- cgit v1.2.3-70-g09d2