package app import ( "encoding/json" "os" "path/filepath" "time" ) func normalizeSmartDNSRuntimeState(st smartDNSRuntimeState) smartDNSRuntimeState { if st.Version <= 0 { st.Version = smartdnsRuntimeStateVersion } return st } func inferSmartDNSRuntimeEnabled() bool { enabled, err := smartDNSRuntimeEnabledFromConfig() if err != nil { // Keep historical behavior on first run when config is unavailable. return true } return enabled } func loadSmartDNSRuntimeState(logf func(string, ...any)) smartDNSRuntimeState { if data, err := os.ReadFile(smartdnsRTPath); err == nil { var st smartDNSRuntimeState if json.Unmarshal(data, &st) == nil { return normalizeSmartDNSRuntimeState(st) } if logf != nil { logf("smartdns runtime: invalid state json at %s, rebuilding", smartdnsRTPath) } } st := smartDNSRuntimeState{ Version: smartdnsRuntimeStateVersion, Enabled: inferSmartDNSRuntimeEnabled(), UpdatedAt: time.Now().UTC().Format(time.RFC3339), } _ = saveSmartDNSRuntimeState(st) return st } func saveSmartDNSRuntimeState(st smartDNSRuntimeState) error { st = normalizeSmartDNSRuntimeState(st) st.UpdatedAt = time.Now().UTC().Format(time.RFC3339) data, err := json.MarshalIndent(st, "", " ") if err != nil { return err } if err := os.MkdirAll(filepath.Dir(smartdnsRTPath), 0o755); err != nil { return err } tmp := smartdnsRTPath + ".tmp" if err := os.WriteFile(tmp, data, 0o644); err != nil { return err } return os.Rename(tmp, smartdnsRTPath) } func smartDNSRuntimeEnabled() bool { return loadSmartDNSRuntimeState(nil).Enabled }