]> ruderich.org/simon Gitweb - safcm/safcm.git/blobdiff - cmd/safcm/fixperms.go
Update copyright years
[safcm/safcm.git] / cmd / safcm / fixperms.go
index 6770934f14d176f7ab15f413ea1d9ce8f0accbd3..6532bb40ca4d91518841b3712240426e67515069 100644 (file)
@@ -1,6 +1,6 @@
 // "fixperms" sub-command: apply proper permissions in files/ directories
 
-// Copyright (C) 2021  Simon Ruderich
+// Copyright (C) 2021-2023  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
@@ -25,6 +25,7 @@ import (
        "path/filepath"
 
        "ruderich.org/simon/safcm/cmd/safcm/config"
+       "ruderich.org/simon/safcm/remote/sync"
 )
 
 func MainFixperms() error {
@@ -78,7 +79,7 @@ func fixpermsWalkDirFunc(path string, d fs.DirEntry, err error) error {
                        // This is safe because perm does not include
                        // setuid/setgid/sticky which use different values in
                        // FileMode.
-                       err := os.Chmod(path, fs.FileMode(perm))
+                       err := chmodNoFollow(path, fs.FileMode(perm))
                        if err != nil {
                                return err
                        }
@@ -87,7 +88,7 @@ func fixpermsWalkDirFunc(path string, d fs.DirEntry, err error) error {
                if perm != 0755 {
                        perm = 0755
                        log.Printf("chmodding %q to %#o", path, perm)
-                       err := os.Chmod(path, fs.FileMode(perm))
+                       err := chmodNoFollow(path, fs.FileMode(perm))
                        if err != nil {
                                return err
                        }
@@ -97,3 +98,19 @@ func fixpermsWalkDirFunc(path string, d fs.DirEntry, err error) error {
 
        return nil
 }
+
+// chmodNoFollow works like os.Chmod but doesn't follow symlinks.
+func chmodNoFollow(path string, mode fs.FileMode) error {
+       x, err := sync.OpenFileNoSymlinks(path)
+       if err != nil {
+               return err
+       }
+       defer x.Close()
+
+       err = x.Chmod(mode)
+       if err != nil {
+               return err
+       }
+
+       return nil
+}