1 /* libguestfs - the guestfsd daemon
2 * Copyright (C) 2009 Red Hat Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #ifdef HAVE_ATTR_XATTR_H
25 #include <attr/xattr.h>
27 #include "../src/guestfs_protocol.h"
31 static guestfs_int_xattr_list *getxattrs (char *path, ssize_t (*listxattr) (const char *path, char *list, size_t size), ssize_t (*getxattr) (const char *path, const char *name, void *value, size_t size));
32 static int _setxattr (char *xattr, char *val, int vallen, char *path, int (*setxattr) (const char *path, const char *name, const void *value, size_t size, int flags));
33 static int _removexattr (char *xattr, char *path, int (*removexattr) (const char *path, const char *name));
35 guestfs_int_xattr_list *
36 do_getxattrs (char *path)
38 #if defined(HAVE_LISTXATTR) && defined(HAVE_GETXATTR)
39 return getxattrs (path, listxattr, getxattr);
41 reply_with_error ("getxattrs: no support for listxattr and getxattr");
46 guestfs_int_xattr_list *
47 do_lgetxattrs (char *path)
49 #if defined(HAVE_LLISTXATTR) && defined(HAVE_LGETXATTR)
50 return getxattrs (path, llistxattr, lgetxattr);
52 reply_with_error ("lgetxattrs: no support for llistxattr and lgetxattr");
58 do_setxattr (char *xattr, char *val, int vallen, char *path)
60 #if defined(HAVE_SETXATTR)
61 return _setxattr (xattr, val, vallen, path, setxattr);
63 reply_with_error ("setxattr: no support for setxattr");
69 do_lsetxattr (char *xattr, char *val, int vallen, char *path)
71 #if defined(HAVE_LSETXATTR)
72 return _setxattr (xattr, val, vallen, path, lsetxattr);
74 reply_with_error ("lsetxattr: no support for lsetxattr");
80 do_removexattr (char *xattr, char *path)
82 #if defined(HAVE_REMOVEXATTR)
83 return _removexattr (xattr, path, removexattr);
85 reply_with_error ("removexattr: no support for removexattr");
91 do_lremovexattr (char *xattr, char *path)
93 #if defined(HAVE_LREMOVEXATTR)
94 return _removexattr (xattr, path, lremovexattr);
96 reply_with_error ("lremovexattr: no support for lremovexattr");
101 static guestfs_int_xattr_list *
102 getxattrs (char *path,
103 ssize_t (*listxattr) (const char *path, char *list, size_t size),
104 ssize_t (*getxattr) (const char *path, const char *name,
105 void *value, size_t size))
110 guestfs_int_xattr_list *r = NULL;
113 ABS_PATH (path, NULL);
116 len = listxattr (path, NULL, 0);
119 reply_with_perror ("listxattr");
125 reply_with_perror ("malloc");
130 len = listxattr (path, buf, len);
133 reply_with_perror ("listxattr");
137 r = calloc (1, sizeof (*r));
139 reply_with_perror ("malloc");
143 /* What we get from the kernel is a string "foo\0bar\0baz" of length
144 * len. First count the strings.
146 r->guestfs_int_xattr_list_len = 0;
147 for (i = 0; i < len; i += strlen (&buf[i]) + 1)
148 r->guestfs_int_xattr_list_len++;
150 r->guestfs_int_xattr_list_val =
151 calloc (r->guestfs_int_xattr_list_len, sizeof (guestfs_int_xattr));
152 if (r->guestfs_int_xattr_list_val == NULL) {
153 reply_with_perror ("calloc");
157 for (i = 0, j = 0; i < len; i += strlen (&buf[i]) + 1, ++j) {
159 vlen = getxattr (path, &buf[i], NULL, 0);
162 reply_with_perror ("getxattr");
166 r->guestfs_int_xattr_list_val[j].attrname = strdup (&buf[i]);
167 r->guestfs_int_xattr_list_val[j].attrval.attrval_val = malloc (vlen);
168 r->guestfs_int_xattr_list_val[j].attrval.attrval_len = vlen;
170 if (r->guestfs_int_xattr_list_val[j].attrname == NULL ||
171 r->guestfs_int_xattr_list_val[j].attrval.attrval_val == NULL) {
172 reply_with_perror ("malloc");
177 vlen = getxattr (path, &buf[i],
178 r->guestfs_int_xattr_list_val[j].attrval.attrval_val,
182 reply_with_perror ("getxattr");
194 if (r->guestfs_int_xattr_list_val)
195 for (i = 0; i < r->guestfs_int_xattr_list_len; ++i) {
196 free (r->guestfs_int_xattr_list_val[i].attrname);
197 free (r->guestfs_int_xattr_list_val[i].attrval.attrval_val);
199 free (r->guestfs_int_xattr_list_val);
206 _setxattr (char *xattr, char *val, int vallen, char *path,
207 int (*setxattr) (const char *path, const char *name,
208 const void *value, size_t size, int flags))
213 r = setxattr (path, xattr, val, vallen, 0);
216 reply_with_perror ("setxattr");
224 _removexattr (char *xattr, char *path,
225 int (*removexattr) (const char *path, const char *name))
230 r = removexattr (path, xattr);
233 reply_with_perror ("removexattr");
240 #else /* !HAVE_ATTR_XATTR_H */
242 guestfs_int_xattr_list *
243 do_getxattrs (char *path)
245 reply_with_error ("getxattrs: no support for xattrs");
249 guestfs_int_xattr_list *
250 do_lgetxattrs (char *path)
252 reply_with_error ("lgetxattrs: no support for xattrs");
257 do_setxattr (char *xattr, char *val, int vallen, char *path)
259 reply_with_error ("setxattr: no support for xattrs");
264 do_lsetxattr (char *xattr, char *val, int vallen, char *path)
266 reply_with_error ("lsetxattr: no support for xattrs");
271 do_removexattr (char *xattr, char *path)
273 reply_with_error ("removexattr: no support for xattrs");
278 do_lremovexattr (char *xattr, char *path)
280 reply_with_error ("lremovexattr: no support for xattrs");
284 #endif /* !HAVE_ATTR_XATTR_H */