1 // Config: load files/ directory tree
3 // SPDX-License-Identifier: GPL-3.0-or-later
4 // Copyright (C) 2021-2024 Simon Ruderich
16 "ruderich.org/simon/safcm"
19 func LoadFiles(group string) (map[string]*safcm.File, error) {
20 basePath := filepath.Join(group, "files")
24 The actual permissions and user/group of files and directories are not used
25 (except for +x on files). 0644/0755 and current remote user/group is used per
26 default. Apply different file permissions via permissions.yaml. To prevent
27 confusion files must be manually chmodded 0644/0755 and directories 0755 or
31 // No permission checks on windows which doesn't track them.
32 windows := runtime.GOOS == "windows"
34 files := make(map[string]*safcm.File)
35 err := filepath.WalkDir(basePath, func(path string, d fs.DirEntry,
46 typ := info.Mode().Type()
47 perm := FileModeToFullPerm(info.Mode())
50 // See errMsg above. If a user stores a file with stricter
51 // permissions they could assume that these permissions are
52 // respected. This is not the case.
53 if typ == 0 /* regular file */ {
56 // 0755 must be set via permissions.yaml if
59 if perm != 0644 && perm != 0755 {
61 "%q: invalid permissions %#o%s",
64 data, err = os.ReadFile(path)
68 } else if typ == fs.ModeDir {
74 "%q: invalid permissions %#o%s",
77 } else if typ == fs.ModeSymlink {
78 x, err := os.Readlink(path)
83 perm |= 0777 // see cmd/safcm-remote/sync/files.go
85 return fmt.Errorf("%q: file type not supported", path)
88 // Convert to absolute and slash-separated path as used on the
90 x, err := filepath.Rel(basePath, path)
94 x = slashpath.Join("/", filepath.ToSlash(x))
96 files[x] = &safcm.File{
98 Mode: typ | (fs.FileMode(perm) & fs.ModePerm),
106 if os.IsNotExist(err) {
109 return nil, fmt.Errorf("%s: %v", group, err)