1
2
3
4
5
6
7 package unix
8
9 import (
10 "strings"
11 "unsafe"
12 )
13
14
15
16 func xattrnamespace(fullattr string) (ns int, attr string, err error) {
17 s := strings.IndexByte(fullattr, '.')
18 if s == -1 {
19 return -1, "", ENOATTR
20 }
21
22 namespace := fullattr[0:s]
23 attr = fullattr[s+1:]
24
25 switch namespace {
26 case "user":
27 return EXTATTR_NAMESPACE_USER, attr, nil
28 case "system":
29 return EXTATTR_NAMESPACE_SYSTEM, attr, nil
30 default:
31 return -1, "", ENOATTR
32 }
33 }
34
35 func initxattrdest(dest []byte, idx int) (d unsafe.Pointer) {
36 if len(dest) > idx {
37 return unsafe.Pointer(&dest[idx])
38 }
39 if dest != nil {
40
41
42
43 return unsafe.Pointer(&_zero)
44 }
45 return nil
46 }
47
48
49
50 func Getxattr(file string, attr string, dest []byte) (sz int, err error) {
51 d := initxattrdest(dest, 0)
52 destsize := len(dest)
53
54 nsid, a, err := xattrnamespace(attr)
55 if err != nil {
56 return -1, err
57 }
58
59 return ExtattrGetFile(file, nsid, a, uintptr(d), destsize)
60 }
61
62 func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
63 d := initxattrdest(dest, 0)
64 destsize := len(dest)
65
66 nsid, a, err := xattrnamespace(attr)
67 if err != nil {
68 return -1, err
69 }
70
71 return ExtattrGetFd(fd, nsid, a, uintptr(d), destsize)
72 }
73
74 func Lgetxattr(link string, attr string, dest []byte) (sz int, err error) {
75 d := initxattrdest(dest, 0)
76 destsize := len(dest)
77
78 nsid, a, err := xattrnamespace(attr)
79 if err != nil {
80 return -1, err
81 }
82
83 return ExtattrGetLink(link, nsid, a, uintptr(d), destsize)
84 }
85
86
87
88 func Fsetxattr(fd int, attr string, data []byte, flags int) (err error) {
89 var d unsafe.Pointer
90 if len(data) > 0 {
91 d = unsafe.Pointer(&data[0])
92 }
93 datasiz := len(data)
94
95 nsid, a, err := xattrnamespace(attr)
96 if err != nil {
97 return
98 }
99
100 _, err = ExtattrSetFd(fd, nsid, a, uintptr(d), datasiz)
101 return
102 }
103
104 func Setxattr(file string, attr string, data []byte, flags int) (err error) {
105 var d unsafe.Pointer
106 if len(data) > 0 {
107 d = unsafe.Pointer(&data[0])
108 }
109 datasiz := len(data)
110
111 nsid, a, err := xattrnamespace(attr)
112 if err != nil {
113 return
114 }
115
116 _, err = ExtattrSetFile(file, nsid, a, uintptr(d), datasiz)
117 return
118 }
119
120 func Lsetxattr(link string, attr string, data []byte, flags int) (err error) {
121 var d unsafe.Pointer
122 if len(data) > 0 {
123 d = unsafe.Pointer(&data[0])
124 }
125 datasiz := len(data)
126
127 nsid, a, err := xattrnamespace(attr)
128 if err != nil {
129 return
130 }
131
132 _, err = ExtattrSetLink(link, nsid, a, uintptr(d), datasiz)
133 return
134 }
135
136 func Removexattr(file string, attr string) (err error) {
137 nsid, a, err := xattrnamespace(attr)
138 if err != nil {
139 return
140 }
141
142 err = ExtattrDeleteFile(file, nsid, a)
143 return
144 }
145
146 func Fremovexattr(fd int, attr string) (err error) {
147 nsid, a, err := xattrnamespace(attr)
148 if err != nil {
149 return
150 }
151
152 err = ExtattrDeleteFd(fd, nsid, a)
153 return
154 }
155
156 func Lremovexattr(link string, attr string) (err error) {
157 nsid, a, err := xattrnamespace(attr)
158 if err != nil {
159 return
160 }
161
162 err = ExtattrDeleteLink(link, nsid, a)
163 return
164 }
165
166 func Listxattr(file string, dest []byte) (sz int, err error) {
167 destsiz := len(dest)
168
169
170 s, pos := 0, 0
171 for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
172 stmp, e := ListxattrNS(file, nsid, dest[pos:])
173
174
181 if e != nil {
182 if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
183 continue
184 }
185 return s, e
186 }
187
188 s += stmp
189 pos = s
190 if pos > destsiz {
191 pos = destsiz
192 }
193 }
194
195 return s, nil
196 }
197
198 func ListxattrNS(file string, nsid int, dest []byte) (sz int, err error) {
199 d := initxattrdest(dest, 0)
200 destsiz := len(dest)
201
202 s, e := ExtattrListFile(file, nsid, uintptr(d), destsiz)
203 if e != nil {
204 return 0, err
205 }
206
207 return s, nil
208 }
209
210 func Flistxattr(fd int, dest []byte) (sz int, err error) {
211 destsiz := len(dest)
212
213 s, pos := 0, 0
214 for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
215 stmp, e := FlistxattrNS(fd, nsid, dest[pos:])
216
217 if e != nil {
218 if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
219 continue
220 }
221 return s, e
222 }
223
224 s += stmp
225 pos = s
226 if pos > destsiz {
227 pos = destsiz
228 }
229 }
230
231 return s, nil
232 }
233
234 func FlistxattrNS(fd int, nsid int, dest []byte) (sz int, err error) {
235 d := initxattrdest(dest, 0)
236 destsiz := len(dest)
237
238 s, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz)
239 if e != nil {
240 return 0, err
241 }
242
243 return s, nil
244 }
245
246 func Llistxattr(link string, dest []byte) (sz int, err error) {
247 destsiz := len(dest)
248
249 s, pos := 0, 0
250 for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
251 stmp, e := LlistxattrNS(link, nsid, dest[pos:])
252
253 if e != nil {
254 if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
255 continue
256 }
257 return s, e
258 }
259
260 s += stmp
261 pos = s
262 if pos > destsiz {
263 pos = destsiz
264 }
265 }
266
267 return s, nil
268 }
269
270 func LlistxattrNS(link string, nsid int, dest []byte) (sz int, err error) {
271 d := initxattrdest(dest, 0)
272 destsiz := len(dest)
273
274 s, e := ExtattrListLink(link, nsid, uintptr(d), destsiz)
275 if e != nil {
276 return 0, err
277 }
278
279 return s, nil
280 }
281
View as plain text