tools/llvm: Do not build with symbols
[minix3.git] / lib / libc / gen / extattr.c
blob5499b912ca7a4b026b8003b8a1cf37682d652957
1 /* $NetBSD: extattr.c,v 1.4 2012/03/13 21:13:34 christos Exp $ */
3 /*-
4 * Copyright (c) 2001 Robert N. M. Watson
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
30 * TrustedBSD: Utility functions for extended attributes.
33 #include <sys/cdefs.h>
34 #if defined(LIBC_SCCS) && !defined(lint)
35 __RCSID("$NetBSD: extattr.c,v 1.4 2012/03/13 21:13:34 christos Exp $");
36 #endif /* LIBC_SCCS and not lint */
38 #include "namespace.h"
39 #include <sys/types.h>
40 #include <sys/param.h>
41 #include <sys/extattr.h>
43 #include <errno.h>
44 #include <unistd.h>
45 #include <stdlib.h>
46 #include <string.h>
48 const int extattr_namespaces[] = {
49 EXTATTR_NAMESPACE_USER,
50 EXTATTR_NAMESPACE_SYSTEM,
52 };
54 int
55 extattr_namespace_to_string(int attrnamespace, char **string)
58 switch(attrnamespace) {
59 case EXTATTR_NAMESPACE_USER:
60 if (string != NULL) {
61 if ((*string =
62 strdup(EXTATTR_NAMESPACE_USER_STRING)) == NULL)
63 return (-1);
65 return (0);
67 case EXTATTR_NAMESPACE_SYSTEM:
68 if (string != NULL)
69 if ((*string =
70 strdup(EXTATTR_NAMESPACE_SYSTEM_STRING)) == NULL)
71 return (-1);
72 return (0);
74 default:
75 errno = EINVAL;
76 return (-1);
80 int
81 extattr_string_to_namespace(const char *string, int *attrnamespace)
84 if (strcmp(string, EXTATTR_NAMESPACE_USER_STRING) == 0) {
85 if (attrnamespace != NULL)
86 *attrnamespace = EXTATTR_NAMESPACE_USER;
87 return (0);
88 } else if (strcmp(string, EXTATTR_NAMESPACE_SYSTEM_STRING) == 0) {
89 if (attrnamespace != NULL)
90 *attrnamespace = EXTATTR_NAMESPACE_SYSTEM;
91 return (0);
92 } else {
93 errno = EINVAL;
94 return (-1);
99 int
100 extattr_copy_fd(int from_fd, int to_fd, int namespace)
102 ssize_t llen, vlen, maxvlen;
103 size_t alen;
104 void *alist = NULL;
105 void *aval = NULL;
106 size_t i;
107 int error = -1;
109 llen = extattr_list_fd(from_fd, namespace, NULL, 0);
110 if (llen == -1) {
111 /* Silently ignore when EA are not supported */
112 if (errno == EOPNOTSUPP)
113 error = 0;
114 goto out;
117 if (llen == 0) {
118 error = 0;
119 goto out;
122 if ((alist = malloc((size_t)llen)) == NULL)
123 goto out;
125 llen = extattr_list_fd(from_fd, namespace, alist, (size_t)llen);
126 if (llen == -1)
127 goto out;
129 maxvlen = 1024;
130 if ((aval = malloc((size_t)maxvlen)) == NULL)
131 goto out;
133 for (i = 0; i < (size_t)llen; i += alen + 1) {
134 char aname[NAME_MAX + 1];
135 char *ap;
137 alen = ((uint8_t *)alist)[i];
138 ap = ((char *)alist) + i + 1;
139 (void)memcpy(aname, ap, alen);
140 aname[alen] = '\0';
142 vlen = extattr_get_fd(from_fd, namespace, aname, NULL, 0);
143 if (vlen == -1)
144 goto out;
146 if (vlen > maxvlen) {
147 if ((aval = realloc(aval, (size_t)vlen)) == NULL)
148 goto out;
149 maxvlen = vlen;
152 if ((vlen = extattr_get_fd(from_fd, namespace, aname,
153 aval, (size_t)vlen)) == -1)
154 goto out;
156 if (extattr_set_fd(to_fd, namespace, aname,
157 aval, (size_t)vlen) != vlen)
158 goto out;
161 error = 0;
162 out:
163 if (aval != NULL)
164 free(aval);
166 if (alist != NULL)
167 free(alist);
169 return error;
173 extattr_copy_file(const char *from, const char *to, int namespace)
175 ssize_t llen, vlen, maxvlen;
176 size_t alen;
177 void *alist = NULL;
178 void *aval = NULL;
179 size_t i;
180 int error = -1;
182 llen = extattr_list_file(from, namespace, NULL, 0);
183 if (llen == -1) {
184 /* Silently ignore when EA are not supported */
185 if (errno == EOPNOTSUPP)
186 error = 0;
187 goto out;
190 if (llen == 0) {
191 error = 0;
192 goto out;
195 if ((alist = malloc((size_t)llen)) == NULL)
196 goto out;
198 llen = extattr_list_file(from, namespace, alist, (size_t)llen);
199 if (llen == -1)
200 goto out;
202 maxvlen = 1024;
203 if ((aval = malloc((size_t)maxvlen)) == NULL)
204 goto out;
206 for (i = 0; i < (size_t)llen; i += alen + 1) {
207 char aname[NAME_MAX + 1];
208 char *ap;
210 alen = ((uint8_t *)alist)[i];
211 ap = ((char *)alist) + i + 1;
212 (void)memcpy(aname, ap, alen);
213 aname[alen] = '\0';
215 vlen = extattr_get_file(from, namespace, aname, NULL, 0);
216 if (vlen == -1)
217 goto out;
219 if (vlen > maxvlen) {
220 if ((aval = realloc(aval, (size_t)vlen)) == NULL)
221 goto out;
222 maxvlen = vlen;
225 if ((vlen = extattr_get_file(from, namespace, aname, aval, (size_t)vlen)) == -1)
226 goto out;
228 if (extattr_set_file(to, namespace, aname,
229 aval, (size_t)vlen) != vlen)
230 goto out;
233 error = 0;
234 out:
235 if (aval != NULL)
236 free(aval);
238 if (alist != NULL)
239 free(alist);
241 return error;
245 extattr_copy_link(const char *from, const char *to, int namespace)
247 ssize_t llen, vlen, maxvlen;
248 size_t alen;
249 void *alist = NULL;
250 void *aval = NULL;
251 size_t i;
252 int error = -1;
254 llen = extattr_list_link(from, namespace, NULL, 0);
255 if (llen == -1) {
256 /* Silently ignore when EA are not supported */
257 if (errno == EOPNOTSUPP)
258 error = 0;
259 goto out;
262 if (llen == 0) {
263 error = 0;
264 goto out;
267 if ((alist = malloc((size_t)llen)) == NULL)
268 goto out;
270 llen = extattr_list_link(from, namespace, alist, (size_t)llen);
271 if (llen == -1)
272 goto out;
274 maxvlen = 1024;
275 if ((aval = malloc((size_t)maxvlen)) == NULL)
276 goto out;
278 for (i = 0; i < (size_t)llen; i += alen + 1) {
279 char aname[NAME_MAX + 1];
280 char *ap;
282 alen = ((uint8_t *)alist)[i];
283 ap = ((char *)alist) + i + 1;
284 (void)memcpy(aname, ap, alen);
285 aname[alen] = '\0';
287 vlen = extattr_get_link(from, namespace, aname, NULL, 0);
288 if (vlen == -1)
289 goto out;
291 if (vlen > maxvlen) {
292 if ((aval = realloc(aval, (size_t)vlen)) == NULL)
293 goto out;
294 maxvlen = vlen;
297 if ((vlen = extattr_get_link(from, namespace, aname,
298 aval, (size_t)vlen)) == -1)
299 goto out;
301 if (extattr_set_link(to, namespace, aname,
302 aval, (size_t)vlen) != vlen)
303 goto out;
306 error = 0;
307 out:
308 if (aval != NULL)
309 free(aval);
311 if (alist != NULL)
312 free(alist);
314 return error;
317 static int
318 extattr_namespace_access(int namespace, int mode)
320 switch (namespace) {
321 case EXTATTR_NAMESPACE_SYSTEM:
322 if ((mode & (R_OK|W_OK)) && getuid() != 0)
323 return -1;
324 break;
325 default:
326 break;
329 return 0;
333 fcpxattr(int from_fd, int to_fd)
335 const int *ns;
336 int error;
338 for (ns = extattr_namespaces; *ns; ns++) {
339 if (extattr_namespace_access(*ns, R_OK|W_OK) != 0)
340 continue;
342 if ((error = extattr_copy_fd(from_fd, to_fd, *ns)) != 0)
343 return error;
346 return 0;
350 cpxattr(const char *from, const char *to)
352 const int *ns;
353 int error;
355 for (ns = extattr_namespaces; *ns; ns++) {
356 if (extattr_namespace_access(*ns, R_OK|W_OK) != 0)
357 continue;
359 if ((error = extattr_copy_file(from, to, *ns)) != 0)
360 return error;
363 return 0;
367 lcpxattr(const char *from, const char *to)
369 const int *ns;
370 int error;
372 for (ns = extattr_namespaces; *ns; ns++) {
373 if (extattr_namespace_access(*ns, R_OK|W_OK) != 0)
374 continue;
376 if ((error = extattr_copy_link(from, to, *ns)) != 0)
377 return error;
380 return 0;