forked from kooohei/sftps
/
entity.go
131 lines (117 loc) · 2.63 KB
/
entity.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
package sftps
import (
"errors"
"regexp"
"strconv"
"strings"
)
type Permission struct {
Read bool
Write bool
Exe bool
}
type Permissions struct {
Type string
Sticky bool
SUID bool
SGID bool
Owner *Permission
Group *Permission
Users *Permission
}
type Entity struct {
Perms *Permissions
Links int
Owner string
Group string
Size int
LastMod string
Name string
}
func stringToEntities (raw string) (ents []*Entity, err error) {
lines := strings.Split(raw, "\r\n")
if len(lines) == 1 {
lines = strings.Split(raw, "\n")
}
for _, line := range lines {
if line != "" {
ent := new(Entity)
var er error
ent.Perms, ent.Links, ent.Owner, ent.Group, ent.Size, ent.LastMod, ent.Name, er = decomposition(line)
if er != nil {
err = er
return
}
ents = append(ents, ent)
}
}
return
}
func decomposition(line string) (perms *Permissions, link int, own string, grp string, size int, modified string, name string, err error) {
if line == "" {
return
}
reg := regexp.MustCompile(`^([dplcbs\-])([rwxstST\-]{3})([rwxstST\-]{3})([rwxstST\-]{3})\S*?\s+?(\d+?)\s+?(\S+?)\s+?(\S+?)\s+?(\d+?)\s+?(\S+?\s+?\d+?\s+?(?:\d{2}\:\d{2}|\d{4}))\s+?(.+?)$`)
cols := reg.FindStringSubmatch(line)
if cols == nil {
return
}
if len(cols) == 0 {
err = errors.New("Failed to parse the unix file format.")
return
}
cols = cols[1:]
if len(cols) != 10 {
err = errors.New("Could not parse to json, passed string is unknown format.")
}
perms = getPermissions(cols[0], cols[1], cols[2], cols[3])
link, err = strconv.Atoi(cols[4])
if err != nil {
return
}
own = cols[5]
grp = cols[6]
size, err = strconv.Atoi(cols[7])
if err != nil {
return
}
modified = cols[8]
name = cols[9]
return
}
func getPermissions(tp string, own string, grp string, usr string) (res *Permissions) {
res = new(Permissions)
res.Type = getFileTypeFromChar(tp)
res.Sticky = (usr[2] == 't' || usr[2] == 'T')
res.SUID = (usr[2] == 's' || usr[2] == 'S')
res.SGID = (grp[2] == 's' || grp[2] == 'G')
res.Users = getPermission(usr)
res.Group = getPermission(grp)
res.Owner = getPermission(own)
return
}
func getPermission(perm string) (res *Permission) {
res = new(Permission)
res.Read = perm[0] == 'r'
res.Write = perm[1] == 'w'
res.Exe = (perm[2] == 'x' || perm[2] == 's')
return
}
func getFileTypeFromChar(ch string) (tp string) {
if ch == "d" {
tp = "Directory"
} else if ch == "-" {
tp = "Regular"
} else if ch == "l" {
tp = "Symlink"
} else if ch == "p" {
tp = "Pipe"
} else if ch == "s" {
tp = "Socket"
} else if ch == "c" {
tp = "CharacterDevice"
} else if ch == "b" {
tp = "BlockDevice"
}
return
}