1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #include <hurd.h>
21: #include <hurd/xattr.h>
22: #include <string.h>
23: #include <sys/mman.h>
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36: error_t
37: _hurd_xattr_get (io_t port, const char *name, void *value, size_t *size)
38: {
39: if (strncmp (name, "gnu.", 4))
40: return EOPNOTSUPP;
41: name += 4;
42:
43: if (!strcmp (name, "author"))
44: {
45: struct stat64 st;
46: error_t err = __io_stat (port, &st);
47: if (err)
48: return err;
49: if (st.st_author == st.st_uid)
50: *size = 0;
51: else if (value)
52: {
53: if (*size < sizeof st.st_author)
54: return ERANGE;
55: memcpy (value, &st.st_author, sizeof st.st_author);
56: }
57: *size = sizeof st.st_author;
58: return 0;
59: }
60:
61: if (!strcmp (name, "translator"))
62: {
63: char *buf = value;
64: size_t bufsz = value ? *size : 0;
65: error_t err = __file_get_translator (port, &buf, &bufsz);
66: if (err)
67: return err;
68: if (value != NULL && *size < bufsz)
69: {
70: if (buf != value)
71: munmap (buf, bufsz);
72: return -ERANGE;
73: }
74: if (buf != value && bufsz > 0)
75: {
76: if (value != NULL)
77: memcpy (value, buf, bufsz);
78: munmap (buf, bufsz);
79: }
80: *size = bufsz;
81: return 0;
82: }
83:
84: return EOPNOTSUPP;
85: }
86:
87: error_t
88: _hurd_xattr_set (io_t port, const char *name, const void *value, size_t size,
89: int flags)
90: {
91: if (strncmp (name, "gnu.", 4))
92: return EOPNOTSUPP;
93: name += 4;
94:
95: if (!strcmp (name, "author"))
96: switch (size)
97: {
98: default:
99: return EINVAL;
100: case 0:
101: {
102: struct stat64 st;
103: error_t err = __io_stat (port, &st);
104: if (err)
105: return err;
106: if (st.st_author == st.st_uid)
107: {
108:
109: if (flags & XATTR_REPLACE)
110: return ENODATA;
111: return 0;
112: }
113: if (flags & XATTR_CREATE)
114: return EEXIST;
115: return __file_chauthor (port, st.st_uid);
116: }
117: case sizeof (uid_t):
118: {
119: uid_t id;
120: memcpy (&id, value, sizeof id);
121: if (flags & (XATTR_CREATE|XATTR_REPLACE))
122: {
123: struct stat64 st;
124: error_t err = __io_stat (port, &st);
125: if (err)
126: return err;
127: if (st.st_author == st.st_uid)
128: {
129: if (flags & XATTR_REPLACE)
130: return ENODATA;
131: }
132: else if (flags & XATTR_CREATE)
133: return EEXIST;
134: if (st.st_author == id)
135:
136: return 0;
137: }
138: return __file_chauthor (port, id);
139: }
140: }
141:
142: if (!strcmp (name, "translator"))
143: {
144: if (flags & XATTR_REPLACE)
145: {
146:
147: char *buf = NULL;
148: size_t bufsz = 0;
149: error_t err = __file_get_translator (port, &buf, &bufsz);
150: if (err)
151: return err;
152: if (bufsz > 0)
153: {
154: munmap (buf, bufsz);
155: return ENODATA;
156: }
157: }
158: return __file_set_translator (port,
159: FS_TRANS_SET | ((flags & XATTR_CREATE)
160: ? FS_TRANS_EXCL : 0), 0, 0,
161: value, size,
162: MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND);
163: }
164:
165: return EOPNOTSUPP;
166: }
167:
168: error_t
169: _hurd_xattr_remove (io_t port, const char *name)
170: {
171: return _hurd_xattr_set (port, name, NULL, 0, XATTR_REPLACE);
172: }
173:
174: error_t
175: _hurd_xattr_list (io_t port, void *buffer, size_t *size)
176: {
177: size_t total = 0;
178: char *bufp = buffer;
179: inline void add (const char *name, size_t len)
180: {
181: total += len;
182: if (bufp != NULL && total <= *size)
183: bufp = __mempcpy (bufp, name, len);
184: }
185: #define add(s) add (s, sizeof s)
186:
187: struct stat64 st;
188: error_t err = __io_stat (port, &st);
189: if (err)
190: return err;
191:
192: if (st.st_author != st.st_uid)
193: add ("gnu.author");
194: if (st.st_mode & S_IPTRANS)
195: add ("gnu.translator");
196:
197: if (buffer != NULL && total > *size)
198: return ERANGE;
199: *size = total;
200: return 0;
201: }