package agent import ( "encoding/json" "fmt" "os" "path/filepath" "strings" ) func writeJSONAtomic(path string, value any) error { data, err := json.MarshalIndent(value, "", " ") if err != nil { return err } file, err := os.CreateTemp(filepath.Dir(path), ".state-*.tmp") if err != nil { return err } tmp := file.Name() defer os.Remove(tmp) if _, err := file.Write(append(data, '\n')); err != nil { _ = file.Close() return err } if err := file.Sync(); err != nil { _ = file.Close() _ = os.Remove(tmp) return err } if err := file.Close(); err != nil { _ = os.Remove(tmp) return err } if err := os.Rename(tmp, path); err != nil { _ = os.Remove(tmp) return err } return syncDirectory(filepath.Dir(path)) } func syncDirectory(path string) error { dir, err := os.Open(path) if err != nil { return err } syncErr := dir.Sync() return firstError(syncErr, dir.Close()) } func validateName(name string) error { if name == "" || name == "." || name == ".." || strings.ContainsAny(name, `/\\`) || strings.Contains(name, "..") || strings.TrimSpace(name) != name { return fmt.Errorf("unsafe file name %q", name) } return nil } func firstError(errs ...error) error { for _, err := range errs { if err != nil { return err } } return nil }