package main import ( "errors" "fmt" "os" "strconv" "time" "github.com/mathiasbq/hyperguild/ingestion/internal/symlinkguard" ) // startupSymlinkCheck is the hyperguild#157 tripwire at boot: a symlink in the // brain dir would let brain readers serve a file from outside the brain, so // the server does not start until it is removed. A directory the scan cannot // read could hide one, so it refuses on that too. A missing brain dir (first // boot) is the only case it lets pass. func startupSymlinkCheck(brainDir string) error { r, err := symlinkguard.Scan(brainDir) if err != nil { if errors.Is(err, os.ErrNotExist) { return nil } return fmt.Errorf("refusing to start: cannot scan the brain dir %s (hyperguild#157): %w", brainDir, err) } if !r.Clean() { return fmt.Errorf("refusing to start: brain dir %s has %s (hyperguild#157); fix them first", brainDir, r) } return nil } // symlinkScanInterval reads BRAIN_SYMLINK_SCAN_INTERVAL (seconds), falling // back to the default on an unset, non-numeric or non-positive value. func symlinkScanInterval(getenv func(string) string) time.Duration { if s, err := strconv.Atoi(getenv("BRAIN_SYMLINK_SCAN_INTERVAL")); err == nil && s > 0 { return time.Duration(s) * time.Second } return symlinkguard.DefaultInterval }