aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2023-12-27 02:00:23 +0100
committerPřemysl Eric Janouch <p@janouch.name>2023-12-27 02:00:23 +0100
commit79038a2a6d21681b99cafcfb712b3da7b32d663e (patch)
treedf40dced4319b87bf3c9065ba4337402e148752c
parent94399bda33cc4e4bc94c59378027455af12cc56a (diff)
downloadgallery-79038a2a6d21681b99cafcfb712b3da7b32d663e.tar.gz
gallery-79038a2a6d21681b99cafcfb712b3da7b32d663e.tar.xz
gallery-79038a2a6d21681b99cafcfb712b3da7b32d663e.zip
Make check optionally check harder
-rw-r--r--Makefile2
-rw-r--r--main.go53
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")
}