/
files.go
147 lines (127 loc) · 3.75 KB
/
files.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package utils
import (
"io"
"io/ioutil"
"os"
"syscall"
"github.com/vordev/VOR/core/logger"
"github.com/pkg/errors"
)
// FileExists returns true if a file at the passed string exists.
func FileExists(name string) bool {
if _, err := os.Stat(name); os.IsNotExist(err) {
return false
}
return true
}
func TooPermissive(fileMode, maxAllowedPerms os.FileMode) bool {
return fileMode&^maxAllowedPerms != 0
}
func IsFileOwnedByChainlink(fileInfo os.FileInfo) (bool, error) {
stat, ok := fileInfo.Sys().(*syscall.Stat_t)
if !ok {
return false, errors.Errorf("Unable to determine file owner of %s", fileInfo.Name())
}
return int(stat.Uid) == os.Getuid(), nil
}
// Ensures that the given path exists, that it's a directory, and that it has
// permissions that are no more permissive than the given ones.
//
// - If the path does not exist, it is created
// - If the path exists, but is not a directory, an error is returned
// - If the path exists, and is a directory, but has the wrong perms, it is chmod'ed
func EnsureDirAndMaxPerms(path string, perms os.FileMode) error {
stat, err := os.Stat(path)
if err != nil && !os.IsNotExist(err) {
// Regular error
return err
} else if os.IsNotExist(err) {
// Dir doesn't exist, create it with desired perms
return os.MkdirAll(path, perms|os.ModeDir)
} else if !stat.IsDir() {
// Path exists, but it's a file, so don't clobber
return errors.Errorf("%v already exists and is not a directory", path)
} else if stat.Mode() != perms {
// Dir exists, but wrong perms, so chmod
return os.Chmod(path, (stat.Mode()&perms)|os.ModeDir)
}
return nil
}
// Writes `data` to `path` and ensures that the file has permissions that
// are no more permissive than the given ones.
func WriteFileWithMaxPerms(path string, data []byte, perms os.FileMode) error {
f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, perms)
if err != nil {
return err
}
defer logger.ErrorIfCalling(f.Close)
err = EnsureFileMaxPerms(f, perms)
if err != nil {
return err
}
_, err = f.Write(data)
return err
}
// Copies the file at `srcPath` to `dstPath` and ensures that it has
// permissions that are no more permissive than the given ones.
func CopyFileWithMaxPerms(srcPath, dstPath string, perms os.FileMode) error {
src, err := os.Open(srcPath)
if err != nil {
return err
}
defer logger.ErrorIfCalling(src.Close)
dst, err := os.OpenFile(dstPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, perms)
if err != nil {
return err
}
defer logger.ErrorIfCalling(dst.Close)
err = EnsureFileMaxPerms(dst, perms)
if err != nil {
return err
}
_, err = io.Copy(dst, src)
return err
}
// Ensures that the given file has permissions that are no more
// permissive than the given ones.
func EnsureFileMaxPerms(file *os.File, perms os.FileMode) error {
stat, err := file.Stat()
if err != nil {
return err
}
if stat.Mode() == perms {
return nil
}
return file.Chmod(stat.Mode() & perms)
}
// Ensures that the file at the given filepath has permissions that are
// no more permissive than the given ones.
func EnsureFilepathMaxPerms(filepath string, perms os.FileMode) error {
dst, err := os.OpenFile(filepath, os.O_RDWR, perms)
if err != nil {
return err
}
defer logger.ErrorIfCalling(dst.Close)
return EnsureFileMaxPerms(dst, perms)
}
// FilesInDir returns an array of filenames in the directory.
func FilesInDir(dir string) ([]string, error) {
f, err := os.Open(dir)
if err != nil {
return []string{}, err
}
defer logger.ErrorIfCalling(f.Close)
r, err := f.Readdirnames(-1)
if err != nil {
return []string{}, err
}
return r, nil
}
// FileContents returns the contents of a file as a string.
func FileContents(path string) (string, error) {
dat, err := ioutil.ReadFile(path)
if err != nil {
return "", err
}
return string(dat), nil
}