xref: /minix3/lib/libc/gen/extattr.c (revision f14fb602092e015ff630df58e17c2a9cd57d29b3)
1*f14fb602SLionel Sambuc /*	$NetBSD: extattr.c,v 1.4 2012/03/13 21:13:34 christos Exp $	*/
22fe8fb19SBen Gras 
32fe8fb19SBen Gras /*-
42fe8fb19SBen Gras  * Copyright (c) 2001 Robert N. M. Watson
52fe8fb19SBen Gras  * All rights reserved.
62fe8fb19SBen Gras  *
72fe8fb19SBen Gras  * Redistribution and use in source and binary forms, with or without
82fe8fb19SBen Gras  * modification, are permitted provided that the following conditions
92fe8fb19SBen Gras  * are met:
102fe8fb19SBen Gras  * 1. Redistributions of source code must retain the above copyright
112fe8fb19SBen Gras  *    notice, this list of conditions and the following disclaimer.
122fe8fb19SBen Gras  * 2. Redistributions in binary form must reproduce the above copyright
132fe8fb19SBen Gras  *    notice, this list of conditions and the following disclaimer in the
142fe8fb19SBen Gras  *    documentation and/or other materials provided with the distribution.
152fe8fb19SBen Gras  *
162fe8fb19SBen Gras  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
172fe8fb19SBen Gras  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
182fe8fb19SBen Gras  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
192fe8fb19SBen Gras  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
202fe8fb19SBen Gras  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
212fe8fb19SBen Gras  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
222fe8fb19SBen Gras  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
232fe8fb19SBen Gras  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
242fe8fb19SBen Gras  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
252fe8fb19SBen Gras  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
262fe8fb19SBen Gras  * SUCH DAMAGE.
272fe8fb19SBen Gras  */
282fe8fb19SBen Gras 
292fe8fb19SBen Gras /*
302fe8fb19SBen Gras  * TrustedBSD: Utility functions for extended attributes.
312fe8fb19SBen Gras  */
322fe8fb19SBen Gras 
332fe8fb19SBen Gras #include <sys/cdefs.h>
342fe8fb19SBen Gras #if defined(LIBC_SCCS) && !defined(lint)
35*f14fb602SLionel Sambuc __RCSID("$NetBSD: extattr.c,v 1.4 2012/03/13 21:13:34 christos Exp $");
362fe8fb19SBen Gras #endif /* LIBC_SCCS and not lint */
372fe8fb19SBen Gras 
382fe8fb19SBen Gras #include "namespace.h"
392fe8fb19SBen Gras #include <sys/types.h>
40*f14fb602SLionel Sambuc #include <sys/param.h>
412fe8fb19SBen Gras #include <sys/extattr.h>
422fe8fb19SBen Gras 
432fe8fb19SBen Gras #include <errno.h>
44*f14fb602SLionel Sambuc #include <unistd.h>
45*f14fb602SLionel Sambuc #include <stdlib.h>
462fe8fb19SBen Gras #include <string.h>
472fe8fb19SBen Gras 
48*f14fb602SLionel Sambuc const int extattr_namespaces[] = {
49*f14fb602SLionel Sambuc 	EXTATTR_NAMESPACE_USER,
50*f14fb602SLionel Sambuc 	EXTATTR_NAMESPACE_SYSTEM,
51*f14fb602SLionel Sambuc 	0,
52*f14fb602SLionel Sambuc };
53*f14fb602SLionel Sambuc 
542fe8fb19SBen Gras int
extattr_namespace_to_string(int attrnamespace,char ** string)552fe8fb19SBen Gras extattr_namespace_to_string(int attrnamespace, char **string)
562fe8fb19SBen Gras {
572fe8fb19SBen Gras 
582fe8fb19SBen Gras 	switch(attrnamespace) {
592fe8fb19SBen Gras 	case EXTATTR_NAMESPACE_USER:
602fe8fb19SBen Gras 		if (string != NULL) {
612fe8fb19SBen Gras 			if ((*string =
622fe8fb19SBen Gras 			     strdup(EXTATTR_NAMESPACE_USER_STRING)) == NULL)
632fe8fb19SBen Gras 				return (-1);
642fe8fb19SBen Gras 		}
652fe8fb19SBen Gras 		return (0);
662fe8fb19SBen Gras 
672fe8fb19SBen Gras 	case EXTATTR_NAMESPACE_SYSTEM:
682fe8fb19SBen Gras 		if (string != NULL)
692fe8fb19SBen Gras 			if ((*string =
702fe8fb19SBen Gras 			     strdup(EXTATTR_NAMESPACE_SYSTEM_STRING)) == NULL)
712fe8fb19SBen Gras 				return (-1);
722fe8fb19SBen Gras 		return (0);
732fe8fb19SBen Gras 
742fe8fb19SBen Gras 	default:
752fe8fb19SBen Gras 		errno = EINVAL;
762fe8fb19SBen Gras 		return (-1);
772fe8fb19SBen Gras 	}
782fe8fb19SBen Gras }
792fe8fb19SBen Gras 
802fe8fb19SBen Gras int
extattr_string_to_namespace(const char * string,int * attrnamespace)812fe8fb19SBen Gras extattr_string_to_namespace(const char *string, int *attrnamespace)
822fe8fb19SBen Gras {
832fe8fb19SBen Gras 
842fe8fb19SBen Gras 	if (strcmp(string, EXTATTR_NAMESPACE_USER_STRING) == 0) {
852fe8fb19SBen Gras 		if (attrnamespace != NULL)
862fe8fb19SBen Gras 			*attrnamespace = EXTATTR_NAMESPACE_USER;
872fe8fb19SBen Gras 		return (0);
882fe8fb19SBen Gras 	} else if (strcmp(string, EXTATTR_NAMESPACE_SYSTEM_STRING) == 0) {
892fe8fb19SBen Gras 		if (attrnamespace != NULL)
902fe8fb19SBen Gras 			*attrnamespace = EXTATTR_NAMESPACE_SYSTEM;
912fe8fb19SBen Gras 		return (0);
922fe8fb19SBen Gras 	} else {
932fe8fb19SBen Gras 		errno = EINVAL;
942fe8fb19SBen Gras 		return (-1);
952fe8fb19SBen Gras 	}
962fe8fb19SBen Gras }
97*f14fb602SLionel Sambuc 
98*f14fb602SLionel Sambuc 
99*f14fb602SLionel Sambuc int
extattr_copy_fd(int from_fd,int to_fd,int namespace)100*f14fb602SLionel Sambuc extattr_copy_fd(int from_fd, int to_fd, int namespace)
101*f14fb602SLionel Sambuc {
102*f14fb602SLionel Sambuc 	ssize_t llen, vlen, maxvlen;
103*f14fb602SLionel Sambuc 	size_t alen;
104*f14fb602SLionel Sambuc 	void *alist = NULL;
105*f14fb602SLionel Sambuc 	void *aval = NULL;
106*f14fb602SLionel Sambuc 	size_t i;
107*f14fb602SLionel Sambuc 	int error = -1;
108*f14fb602SLionel Sambuc 
109*f14fb602SLionel Sambuc 	llen = extattr_list_fd(from_fd, namespace, NULL, 0);
110*f14fb602SLionel Sambuc 	if (llen == -1) {
111*f14fb602SLionel Sambuc 		/* Silently ignore when EA are not supported */
112*f14fb602SLionel Sambuc 		if (errno == EOPNOTSUPP)
113*f14fb602SLionel Sambuc 			error = 0;
114*f14fb602SLionel Sambuc 		goto out;
115*f14fb602SLionel Sambuc 	}
116*f14fb602SLionel Sambuc 
117*f14fb602SLionel Sambuc 	if (llen == 0) {
118*f14fb602SLionel Sambuc 		error = 0;
119*f14fb602SLionel Sambuc 		goto out;
120*f14fb602SLionel Sambuc 	}
121*f14fb602SLionel Sambuc 
122*f14fb602SLionel Sambuc 	if ((alist = malloc((size_t)llen)) == NULL)
123*f14fb602SLionel Sambuc 		goto out;
124*f14fb602SLionel Sambuc 
125*f14fb602SLionel Sambuc 	llen = extattr_list_fd(from_fd, namespace, alist, (size_t)llen);
126*f14fb602SLionel Sambuc 	if (llen == -1)
127*f14fb602SLionel Sambuc 		goto out;
128*f14fb602SLionel Sambuc 
129*f14fb602SLionel Sambuc 	maxvlen = 1024;
130*f14fb602SLionel Sambuc 	if ((aval = malloc((size_t)maxvlen)) == NULL)
131*f14fb602SLionel Sambuc 		goto out;
132*f14fb602SLionel Sambuc 
133*f14fb602SLionel Sambuc 	for (i = 0; i < (size_t)llen; i += alen + 1) {
134*f14fb602SLionel Sambuc 		char aname[NAME_MAX + 1];
135*f14fb602SLionel Sambuc 		char *ap;
136*f14fb602SLionel Sambuc 
137*f14fb602SLionel Sambuc 		alen = ((uint8_t *)alist)[i];
138*f14fb602SLionel Sambuc 		ap = ((char *)alist) + i + 1;
139*f14fb602SLionel Sambuc 		(void)memcpy(aname, ap, alen);
140*f14fb602SLionel Sambuc 		aname[alen] = '\0';
141*f14fb602SLionel Sambuc 
142*f14fb602SLionel Sambuc 		vlen = extattr_get_fd(from_fd, namespace, aname, NULL, 0);
143*f14fb602SLionel Sambuc 		if (vlen == -1)
144*f14fb602SLionel Sambuc 			goto out;
145*f14fb602SLionel Sambuc 
146*f14fb602SLionel Sambuc 		if (vlen > maxvlen) {
147*f14fb602SLionel Sambuc 			if ((aval = realloc(aval, (size_t)vlen)) == NULL)
148*f14fb602SLionel Sambuc 				goto out;
149*f14fb602SLionel Sambuc 			maxvlen = vlen;
150*f14fb602SLionel Sambuc 		}
151*f14fb602SLionel Sambuc 
152*f14fb602SLionel Sambuc 		if ((vlen = extattr_get_fd(from_fd, namespace, aname,
153*f14fb602SLionel Sambuc 				      aval, (size_t)vlen)) == -1)
154*f14fb602SLionel Sambuc 			goto out;
155*f14fb602SLionel Sambuc 
156*f14fb602SLionel Sambuc 		if (extattr_set_fd(to_fd, namespace, aname,
157*f14fb602SLionel Sambuc 				   aval, (size_t)vlen) != vlen)
158*f14fb602SLionel Sambuc 			goto out;
159*f14fb602SLionel Sambuc 	}
160*f14fb602SLionel Sambuc 
161*f14fb602SLionel Sambuc 	error = 0;
162*f14fb602SLionel Sambuc out:
163*f14fb602SLionel Sambuc 	if (aval != NULL)
164*f14fb602SLionel Sambuc 		free(aval);
165*f14fb602SLionel Sambuc 
166*f14fb602SLionel Sambuc 	if (alist != NULL)
167*f14fb602SLionel Sambuc 		free(alist);
168*f14fb602SLionel Sambuc 
169*f14fb602SLionel Sambuc 	return error;
170*f14fb602SLionel Sambuc }
171*f14fb602SLionel Sambuc 
172*f14fb602SLionel Sambuc int
extattr_copy_file(const char * from,const char * to,int namespace)173*f14fb602SLionel Sambuc extattr_copy_file(const char *from, const char *to, int namespace)
174*f14fb602SLionel Sambuc {
175*f14fb602SLionel Sambuc 	ssize_t llen, vlen, maxvlen;
176*f14fb602SLionel Sambuc 	size_t alen;
177*f14fb602SLionel Sambuc 	void *alist = NULL;
178*f14fb602SLionel Sambuc 	void *aval = NULL;
179*f14fb602SLionel Sambuc 	size_t i;
180*f14fb602SLionel Sambuc 	int error = -1;
181*f14fb602SLionel Sambuc 
182*f14fb602SLionel Sambuc 	llen = extattr_list_file(from, namespace, NULL, 0);
183*f14fb602SLionel Sambuc 	if (llen == -1) {
184*f14fb602SLionel Sambuc 		/* Silently ignore when EA are not supported */
185*f14fb602SLionel Sambuc 		if (errno == EOPNOTSUPP)
186*f14fb602SLionel Sambuc 			error = 0;
187*f14fb602SLionel Sambuc 		goto out;
188*f14fb602SLionel Sambuc 	}
189*f14fb602SLionel Sambuc 
190*f14fb602SLionel Sambuc 	if (llen == 0) {
191*f14fb602SLionel Sambuc 		error = 0;
192*f14fb602SLionel Sambuc 		goto out;
193*f14fb602SLionel Sambuc 	}
194*f14fb602SLionel Sambuc 
195*f14fb602SLionel Sambuc 	if ((alist = malloc((size_t)llen)) == NULL)
196*f14fb602SLionel Sambuc 		goto out;
197*f14fb602SLionel Sambuc 
198*f14fb602SLionel Sambuc 	llen = extattr_list_file(from, namespace, alist, (size_t)llen);
199*f14fb602SLionel Sambuc 	if (llen == -1)
200*f14fb602SLionel Sambuc 		goto out;
201*f14fb602SLionel Sambuc 
202*f14fb602SLionel Sambuc 	maxvlen = 1024;
203*f14fb602SLionel Sambuc 	if ((aval = malloc((size_t)maxvlen)) == NULL)
204*f14fb602SLionel Sambuc 		goto out;
205*f14fb602SLionel Sambuc 
206*f14fb602SLionel Sambuc 	for (i = 0; i < (size_t)llen; i += alen + 1) {
207*f14fb602SLionel Sambuc 		char aname[NAME_MAX + 1];
208*f14fb602SLionel Sambuc 		char *ap;
209*f14fb602SLionel Sambuc 
210*f14fb602SLionel Sambuc 		alen = ((uint8_t *)alist)[i];
211*f14fb602SLionel Sambuc 		ap = ((char *)alist) + i + 1;
212*f14fb602SLionel Sambuc 		(void)memcpy(aname, ap, alen);
213*f14fb602SLionel Sambuc 		aname[alen] = '\0';
214*f14fb602SLionel Sambuc 
215*f14fb602SLionel Sambuc 		vlen = extattr_get_file(from, namespace, aname, NULL, 0);
216*f14fb602SLionel Sambuc 		if (vlen == -1)
217*f14fb602SLionel Sambuc 			goto out;
218*f14fb602SLionel Sambuc 
219*f14fb602SLionel Sambuc 		if (vlen > maxvlen) {
220*f14fb602SLionel Sambuc 			if ((aval = realloc(aval, (size_t)vlen)) == NULL)
221*f14fb602SLionel Sambuc 				goto out;
222*f14fb602SLionel Sambuc 			maxvlen = vlen;
223*f14fb602SLionel Sambuc 		}
224*f14fb602SLionel Sambuc 
225*f14fb602SLionel Sambuc 		if ((vlen = extattr_get_file(from, namespace, aname,							     aval, (size_t)vlen)) == -1)
226*f14fb602SLionel Sambuc 			goto out;
227*f14fb602SLionel Sambuc 
228*f14fb602SLionel Sambuc 		if (extattr_set_file(to, namespace, aname,
229*f14fb602SLionel Sambuc 				     aval, (size_t)vlen) != vlen)
230*f14fb602SLionel Sambuc 			goto out;
231*f14fb602SLionel Sambuc 	}
232*f14fb602SLionel Sambuc 
233*f14fb602SLionel Sambuc 	error = 0;
234*f14fb602SLionel Sambuc out:
235*f14fb602SLionel Sambuc 	if (aval != NULL)
236*f14fb602SLionel Sambuc 		free(aval);
237*f14fb602SLionel Sambuc 
238*f14fb602SLionel Sambuc 	if (alist != NULL)
239*f14fb602SLionel Sambuc 		free(alist);
240*f14fb602SLionel Sambuc 
241*f14fb602SLionel Sambuc 	return error;
242*f14fb602SLionel Sambuc }
243*f14fb602SLionel Sambuc 
244*f14fb602SLionel Sambuc int
extattr_copy_link(const char * from,const char * to,int namespace)245*f14fb602SLionel Sambuc extattr_copy_link(const char *from, const char *to, int namespace)
246*f14fb602SLionel Sambuc {
247*f14fb602SLionel Sambuc 	ssize_t llen, vlen, maxvlen;
248*f14fb602SLionel Sambuc 	size_t alen;
249*f14fb602SLionel Sambuc 	void *alist = NULL;
250*f14fb602SLionel Sambuc 	void *aval = NULL;
251*f14fb602SLionel Sambuc 	size_t i;
252*f14fb602SLionel Sambuc 	int error = -1;
253*f14fb602SLionel Sambuc 
254*f14fb602SLionel Sambuc 	llen = extattr_list_link(from, namespace, NULL, 0);
255*f14fb602SLionel Sambuc 	if (llen == -1) {
256*f14fb602SLionel Sambuc 		/* Silently ignore when EA are not supported */
257*f14fb602SLionel Sambuc 		if (errno == EOPNOTSUPP)
258*f14fb602SLionel Sambuc 			error = 0;
259*f14fb602SLionel Sambuc 		goto out;
260*f14fb602SLionel Sambuc 	}
261*f14fb602SLionel Sambuc 
262*f14fb602SLionel Sambuc 	if (llen == 0) {
263*f14fb602SLionel Sambuc 		error = 0;
264*f14fb602SLionel Sambuc 		goto out;
265*f14fb602SLionel Sambuc 	}
266*f14fb602SLionel Sambuc 
267*f14fb602SLionel Sambuc 	if ((alist = malloc((size_t)llen)) == NULL)
268*f14fb602SLionel Sambuc 		goto out;
269*f14fb602SLionel Sambuc 
270*f14fb602SLionel Sambuc 	llen = extattr_list_link(from, namespace, alist, (size_t)llen);
271*f14fb602SLionel Sambuc 	if (llen == -1)
272*f14fb602SLionel Sambuc 		goto out;
273*f14fb602SLionel Sambuc 
274*f14fb602SLionel Sambuc 	maxvlen = 1024;
275*f14fb602SLionel Sambuc 	if ((aval = malloc((size_t)maxvlen)) == NULL)
276*f14fb602SLionel Sambuc 		goto out;
277*f14fb602SLionel Sambuc 
278*f14fb602SLionel Sambuc 	for (i = 0; i < (size_t)llen; i += alen + 1) {
279*f14fb602SLionel Sambuc 		char aname[NAME_MAX + 1];
280*f14fb602SLionel Sambuc 		char *ap;
281*f14fb602SLionel Sambuc 
282*f14fb602SLionel Sambuc 		alen = ((uint8_t *)alist)[i];
283*f14fb602SLionel Sambuc 		ap = ((char *)alist) + i + 1;
284*f14fb602SLionel Sambuc 		(void)memcpy(aname, ap, alen);
285*f14fb602SLionel Sambuc 		aname[alen] = '\0';
286*f14fb602SLionel Sambuc 
287*f14fb602SLionel Sambuc 		vlen = extattr_get_link(from, namespace, aname, NULL, 0);
288*f14fb602SLionel Sambuc 		if (vlen == -1)
289*f14fb602SLionel Sambuc 			goto out;
290*f14fb602SLionel Sambuc 
291*f14fb602SLionel Sambuc 		if (vlen > maxvlen) {
292*f14fb602SLionel Sambuc 			if ((aval = realloc(aval, (size_t)vlen)) == NULL)
293*f14fb602SLionel Sambuc 				goto out;
294*f14fb602SLionel Sambuc 			maxvlen = vlen;
295*f14fb602SLionel Sambuc 		}
296*f14fb602SLionel Sambuc 
297*f14fb602SLionel Sambuc 		if ((vlen = extattr_get_link(from, namespace, aname,
298*f14fb602SLionel Sambuc 					     aval, (size_t)vlen)) == -1)
299*f14fb602SLionel Sambuc 			goto out;
300*f14fb602SLionel Sambuc 
301*f14fb602SLionel Sambuc 		if (extattr_set_link(to, namespace, aname,
302*f14fb602SLionel Sambuc 				     aval, (size_t)vlen) != vlen)
303*f14fb602SLionel Sambuc 			goto out;
304*f14fb602SLionel Sambuc 	}
305*f14fb602SLionel Sambuc 
306*f14fb602SLionel Sambuc 	error = 0;
307*f14fb602SLionel Sambuc out:
308*f14fb602SLionel Sambuc 	if (aval != NULL)
309*f14fb602SLionel Sambuc 		free(aval);
310*f14fb602SLionel Sambuc 
311*f14fb602SLionel Sambuc 	if (alist != NULL)
312*f14fb602SLionel Sambuc 		free(alist);
313*f14fb602SLionel Sambuc 
314*f14fb602SLionel Sambuc 	return error;
315*f14fb602SLionel Sambuc }
316*f14fb602SLionel Sambuc 
317*f14fb602SLionel Sambuc static int
extattr_namespace_access(int namespace,int mode)318*f14fb602SLionel Sambuc extattr_namespace_access(int namespace, int mode)
319*f14fb602SLionel Sambuc {
320*f14fb602SLionel Sambuc 	switch (namespace) {
321*f14fb602SLionel Sambuc 	case EXTATTR_NAMESPACE_SYSTEM:
322*f14fb602SLionel Sambuc 		if ((mode & (R_OK|W_OK)) && getuid() != 0)
323*f14fb602SLionel Sambuc 			return -1;
324*f14fb602SLionel Sambuc 		break;
325*f14fb602SLionel Sambuc 	default:
326*f14fb602SLionel Sambuc 		break;
327*f14fb602SLionel Sambuc 	}
328*f14fb602SLionel Sambuc 
329*f14fb602SLionel Sambuc 	return 0;
330*f14fb602SLionel Sambuc }
331*f14fb602SLionel Sambuc 
332*f14fb602SLionel Sambuc int
fcpxattr(int from_fd,int to_fd)333*f14fb602SLionel Sambuc fcpxattr(int from_fd, int to_fd)
334*f14fb602SLionel Sambuc {
335*f14fb602SLionel Sambuc 	const int *ns;
336*f14fb602SLionel Sambuc 	int error;
337*f14fb602SLionel Sambuc 
338*f14fb602SLionel Sambuc 	for (ns = extattr_namespaces; *ns; ns++) {
339*f14fb602SLionel Sambuc 		if (extattr_namespace_access(*ns, R_OK|W_OK) != 0)
340*f14fb602SLionel Sambuc 			continue;
341*f14fb602SLionel Sambuc 
342*f14fb602SLionel Sambuc 		if ((error = extattr_copy_fd(from_fd, to_fd, *ns)) != 0)
343*f14fb602SLionel Sambuc 			return error;
344*f14fb602SLionel Sambuc 	}
345*f14fb602SLionel Sambuc 
346*f14fb602SLionel Sambuc 	return 0;
347*f14fb602SLionel Sambuc }
348*f14fb602SLionel Sambuc 
349*f14fb602SLionel Sambuc int
cpxattr(const char * from,const char * to)350*f14fb602SLionel Sambuc cpxattr(const char *from, const char *to)
351*f14fb602SLionel Sambuc {
352*f14fb602SLionel Sambuc 	const int *ns;
353*f14fb602SLionel Sambuc 	int error;
354*f14fb602SLionel Sambuc 
355*f14fb602SLionel Sambuc 	for (ns = extattr_namespaces; *ns; ns++) {
356*f14fb602SLionel Sambuc 		if (extattr_namespace_access(*ns, R_OK|W_OK) != 0)
357*f14fb602SLionel Sambuc 			continue;
358*f14fb602SLionel Sambuc 
359*f14fb602SLionel Sambuc 		if ((error = extattr_copy_file(from, to, *ns)) != 0)
360*f14fb602SLionel Sambuc 			return error;
361*f14fb602SLionel Sambuc 	}
362*f14fb602SLionel Sambuc 
363*f14fb602SLionel Sambuc 	return 0;
364*f14fb602SLionel Sambuc }
365*f14fb602SLionel Sambuc 
366*f14fb602SLionel Sambuc int
lcpxattr(const char * from,const char * to)367*f14fb602SLionel Sambuc lcpxattr(const char *from, const char *to)
368*f14fb602SLionel Sambuc {
369*f14fb602SLionel Sambuc 	const int *ns;
370*f14fb602SLionel Sambuc 	int error;
371*f14fb602SLionel Sambuc 
372*f14fb602SLionel Sambuc 	for (ns = extattr_namespaces; *ns; ns++) {
373*f14fb602SLionel Sambuc 		if (extattr_namespace_access(*ns, R_OK|W_OK) != 0)
374*f14fb602SLionel Sambuc 			continue;
375*f14fb602SLionel Sambuc 
376*f14fb602SLionel Sambuc 		if ((error = extattr_copy_link(from, to, *ns)) != 0)
377*f14fb602SLionel Sambuc 			return error;
378*f14fb602SLionel Sambuc 	}
379*f14fb602SLionel Sambuc 
380*f14fb602SLionel Sambuc 	return 0;
381*f14fb602SLionel Sambuc }
382