X-Git-Url: https://ruderich.org/simon/gitweb/?a=blobdiff_plain;ds=sidebyside;f=cmd%2Fsafcm%2Ffixperms.go;fp=cmd%2Fsafcm%2Ffixperms.go;h=6770934f14d176f7ab15f413ea1d9ce8f0accbd3;hb=f2f2bc47e8729548f3c10117f7f008b547c4afc5;hp=0000000000000000000000000000000000000000;hpb=dc0d431a778a50e6732b9eb91384a07a207b772d;p=safcm%2Fsafcm.git diff --git a/cmd/safcm/fixperms.go b/cmd/safcm/fixperms.go new file mode 100644 index 0000000..6770934 --- /dev/null +++ b/cmd/safcm/fixperms.go @@ -0,0 +1,99 @@ +// "fixperms" sub-command: apply proper permissions in files/ directories + +// Copyright (C) 2021 Simon Ruderich +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +package main + +import ( + "fmt" + "io/fs" + "log" + "os" + "path/filepath" + + "ruderich.org/simon/safcm/cmd/safcm/config" +) + +func MainFixperms() error { + _, _, _, err := LoadBaseFiles() + if err != nil { + return fmt.Errorf("not in a safcm directory: %v", err) + } + + xs, err := os.ReadDir(".") + if err != nil { + return err + } + for _, x := range xs { + if !x.IsDir() { + continue + } + path := filepath.Join(x.Name(), "files") + + err := filepath.WalkDir(path, fixpermsWalkDirFunc) + if err != nil { + if os.IsNotExist(err) { + continue + } + return fmt.Errorf("%s: %v", path, err) + } + } + + return nil +} + +func fixpermsWalkDirFunc(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + + info, err := d.Info() + if err != nil { + return err + } + typ := info.Mode().Type() + perm := config.FileModeToFullPerm(info.Mode()) + + if typ == 0 /* regular file */ { + if perm != 0644 && perm != 0755 { + if perm&0111 != 0 /* executable */ { + perm = 0755 + } else { + perm = 0644 + } + log.Printf("chmodding %q to %#o", path, perm) + // This is safe because perm does not include + // setuid/setgid/sticky which use different values in + // FileMode. + err := os.Chmod(path, fs.FileMode(perm)) + if err != nil { + return err + } + } + } else if typ == fs.ModeDir { + if perm != 0755 { + perm = 0755 + log.Printf("chmodding %q to %#o", path, perm) + err := os.Chmod(path, fs.FileMode(perm)) + if err != nil { + return err + } + } + } + // Other file types are caught by regular "sync" + + return nil +}