1 // Config: load files/ directory tree
3 // Copyright (C) 2021 Simon Ruderich
5 // This program is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program. If not, see <http://www.gnu.org/licenses/>.
28 "ruderich.org/simon/safcm"
31 func LoadFiles(group string) (map[string]*safcm.File, error) {
32 basePath := filepath.Join(group, "files")
36 The actual permissions and user/group of files and directories are not used
37 (except for +x on files). 0644/0755 and current remote user/group is used per
38 default. Apply different file permissions via permissions.yaml. To prevent
39 confusion files must be manually chmodded 0644/0755 and directories 0755 or
43 // No permission checks on windows which doesn't track them.
44 windows := runtime.GOOS == "windows"
46 files := make(map[string]*safcm.File)
47 err := filepath.WalkDir(basePath, func(path string, d fs.DirEntry,
58 typ := info.Mode().Type()
59 perm := FileModeToFullPerm(info.Mode())
62 // See errMsg above. If a user stores a file with stricter
63 // permissions they could assume that these permissions are
64 // respected. This is not the case.
65 if typ == 0 /* regular file */ {
68 // 0755 must be set via permissions.yaml if
71 if perm != 0644 && perm != 0755 {
73 "%q: invalid permissions %#o%s",
76 data, err = os.ReadFile(path)
80 } else if typ == fs.ModeDir {
86 "%q: invalid permissions %#o%s",
89 } else if typ == fs.ModeSymlink {
90 x, err := os.Readlink(path)
95 perm |= 0777 // see cmd/safcm-remote/sync/files.go
97 return fmt.Errorf("%q: file type not supported", path)
100 // Convert to absolute and slash-separated path as used on the
102 x, err := filepath.Rel(basePath, path)
106 x = slashpath.Join("/", filepath.ToSlash(x))
108 files[x] = &safcm.File{
110 Mode: typ | (fs.FileMode(perm) & fs.ModePerm),
118 if os.IsNotExist(err) {
121 return nil, fmt.Errorf("%s: %v", group, err)