forked from Foxboron/sbctl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutil.go
128 lines (112 loc) · 2.76 KB
/
util.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
package sbctl
import (
"bytes"
"crypto/sha256"
"encoding/hex"
"errors"
"io"
"os"
"path/filepath"
"strings"
)
func ChecksumFile(file string) (string, error) {
hasher := sha256.New()
s, err := os.ReadFile(file)
if err != nil {
return "", err
}
hasher.Write(s)
return hex.EncodeToString(hasher.Sum(nil)), nil
}
func CreateDirectory(path string) error {
if _, err := os.Stat(path); errors.Is(err, os.ErrExist) {
return nil
} else if errors.Is(err, os.ErrNotExist) {
} else if err != nil {
return err
}
if err := os.MkdirAll(path, os.ModePerm); err != nil {
return err
}
return nil
}
func ReadOrCreateFile(filePath string) ([]byte, error) {
// Try to access or create the file itself
f, err := os.ReadFile(filePath)
if err != nil {
// Errors will mainly happen due to permissions or non-existing file
if os.IsNotExist(err) {
// First, guarantee the directory's existence
// os.MkdirAll simply returns nil if the directory already exists
fileDir := filepath.Dir(filePath)
if err = os.MkdirAll(fileDir, os.ModePerm); err != nil {
return nil, err
}
file, err := os.Create(filePath)
if err != nil {
return nil, err
}
file.Close()
// Create zero-length f, which is equivalent to what would be read from empty file
f = make([]byte, 0)
} else {
if os.IsPermission(err) {
return nil, err
}
return nil, err
}
}
return f, nil
}
var EfivarFSFiles = []string{
"/sys/firmware/efi/efivars/PK-8be4df61-93ca-11d2-aa0d-00e098032b8c",
"/sys/firmware/efi/efivars/KEK-8be4df61-93ca-11d2-aa0d-00e098032b8c",
"/sys/firmware/efi/efivars/db-d719b2cb-3d3a-4596-a3bc-dad00e67656f",
}
var ErrImmutable = errors.New("file is immutable")
var ErrNotImmutable = errors.New("file is not immutable")
func IsImmutable(file string) error {
f, err := os.Open(file)
// Files in efivarfs might not exist. Ignore them
if errors.Is(err, os.ErrNotExist) {
return nil
} else if err != nil {
return err
}
attr, err := GetAttr(f)
if err != nil {
return err
}
if (attr & FS_IMMUTABLE_FL) != 0 {
return ErrImmutable
}
return ErrNotImmutable
}
func CheckMSDos(path string) (bool, error) {
r, err := os.Open(path)
if err != nil {
return false, err
}
defer r.Close()
// We are looking for MS-DOS executables.
// They contain "MZ" as the two first bytes
var header [2]byte
if _, err = io.ReadFull(r, header[:]); err != nil {
return false, err
}
if !bytes.Equal(header[:], []byte{0x4d, 0x5a}) {
return false, nil
}
return true, nil
}
var (
checked = make(map[string]bool)
)
func AddChecked(path string) {
normalized := strings.Join(strings.Split(path, "/")[2:], "/")
checked[normalized] = true
}
func InChecked(path string) bool {
normalized := strings.Join(strings.Split(path, "/")[2:], "/")
return checked[normalized]
}