-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathpasswd.go
71 lines (62 loc) · 1.47 KB
/
passwd.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
// Package passwd parsed content and files in form of /etc/passwd
package passwd
import (
"bufio"
"errors"
"io"
"os"
"strings"
)
// An Entry contains all the fields for a specific user
type Entry struct {
Pass string
Uid string
Gid string
Gecos string
Home string
Shell string
}
// Parse opens the '/etc/passwd' file and parses it into a map from usernames
// to Entries
func Parse() (map[string]Entry, error) {
return ParseFile("/etc/passwd")
}
// ParseFile opens the file and parses it into a map from usernames to Entries
func ParseFile(path string) (map[string]Entry, error) {
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer file.Close()
return ParseReader(file)
}
// ParseReader consumes the contents of r and parses it into a map from
// usernames to Entries
func ParseReader(r io.Reader) (map[string]Entry, error) {
lines := bufio.NewReader(r)
entries := make(map[string]Entry)
for {
line, _, err := lines.ReadLine()
if err != nil {
break
}
name, entry, err := parseLine(string(copyBytes(line)))
if err != nil {
return nil, err
}
entries[name] = entry
}
return entries, nil
}
func parseLine(line string) (string, Entry, error) {
fs := strings.Split(line, ":")
if len(fs) != 7 {
return "", Entry{}, errors.New("Unexpected number of fields in /etc/passwd")
}
return fs[0], Entry{fs[1], fs[2], fs[3], fs[4], fs[5], fs[6]}, nil
}
func copyBytes(x []byte) []byte {
y := make([]byte, len(x))
copy(y, x)
return y
}