//go:build darwin package repository import ( "fmt" "os" "syscall" "golang.org/x/sys/unix" ) // immutableFlagSupported meldet, ob dieses System ein Unveraenderlich-Kennzeichen kennt. // // macOS und die BSDs kennen Dateikennzeichen (chflags). Verwendet wird // UF_IMMUTABLE — das Kennzeichen des Eigentuemers. SF_IMMUTABLE waere staerker, // laesst sich aber nur von root und nur bei niedrigem securelevel wieder // entfernen; ein Backup-Dienst koennte danach selbst nach Fristablauf nicht // mehr aufraeumen. func immutableFlagSupported() bool { return true } // setImmutableFlag setzt oder entfernt das Unveraenderlich-Kennzeichen. func setImmutableFlag(filePath string, shouldBeImmutable bool) error { fileInformation, statError := os.Stat(filePath) if statError != nil { return statError } // os.FileInfo.Sys liefert ein *syscall.Stat_t, nicht den gleichnamigen Typ // aus x/sys/unix. Die beiden sind binaerkompatibel, aber nicht identisch — // eine Typzusicherung auf den falschen schlaegt stillschweigend fehl. Genau // das geschah hier zuerst: Das Kennzeichen wurde nie gesetzt, und die // Messung meldete folgerichtig „nur diese Software". systemInformation, isSystemInformation := fileInformation.Sys().(*syscall.Stat_t) if !isSystemInformation { return fmt.Errorf("die dateikennzeichen von %s sind nicht lesbar", filePath) } currentFlags := systemInformation.Flags updatedFlags := currentFlags &^ uint32(unix.UF_IMMUTABLE) if shouldBeImmutable { updatedFlags = currentFlags | uint32(unix.UF_IMMUTABLE) } if updatedFlags == currentFlags { return nil } if chflagsError := unix.Chflags(filePath, int(updatedFlags)); chflagsError != nil { return &os.PathError{Op: "chflags", Path: filePath, Err: chflagsError} } return nil }