]> ruderich.org/simon Gitweb - safcm/safcm.git/blobdiff - cmd/safcm/fixperms.go
Use SPDX license identifiers
[safcm/safcm.git] / cmd / safcm / fixperms.go
index 6770934f14d176f7ab15f413ea1d9ce8f0accbd3..c9a18a80e0ac3683f0aa7af047a312bae4ad87d2 100644 (file)
@@ -1,19 +1,7 @@
 // "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 <http://www.gnu.org/licenses/>.
+// SPDX-License-Identifier: GPL-3.0-or-later
+// Copyright (C) 2021-2024  Simon Ruderich
 
 package main
 
@@ -25,6 +13,7 @@ import (
        "path/filepath"
 
        "ruderich.org/simon/safcm/cmd/safcm/config"
+       "ruderich.org/simon/safcm/remote/sync"
 )
 
 func MainFixperms() error {
@@ -78,7 +67,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 +76,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 +86,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
+}