diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/eina/src/lib/eina_xattr.c | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/libraries/eina/src/lib/eina_xattr.c b/libraries/eina/src/lib/eina_xattr.c index bd5b98e..d4ed139 100644 --- a/libraries/eina/src/lib/eina_xattr.c +++ b/libraries/eina/src/lib/eina_xattr.c | |||
@@ -20,6 +20,7 @@ | |||
20 | # include "config.h" | 20 | # include "config.h" |
21 | #endif | 21 | #endif |
22 | 22 | ||
23 | #include <stdlib.h> | ||
23 | #include <sys/types.h> | 24 | #include <sys/types.h> |
24 | #include <string.h> | 25 | #include <string.h> |
25 | #include <math.h> | 26 | #include <math.h> |
@@ -34,6 +35,7 @@ | |||
34 | #include "eina_safety_checks.h" | 35 | #include "eina_safety_checks.h" |
35 | #include "eina_xattr.h" | 36 | #include "eina_xattr.h" |
36 | #include "eina_convert.h" | 37 | #include "eina_convert.h" |
38 | #include "eina_stringshare.h" | ||
37 | 39 | ||
38 | /*============================================================================* | 40 | /*============================================================================* |
39 | * Local * | 41 | * Local * |
@@ -49,14 +51,83 @@ struct _Eina_Xattr_Iterator | |||
49 | { | 51 | { |
50 | Eina_Iterator iterator; | 52 | Eina_Iterator iterator; |
51 | 53 | ||
54 | const char *file; | ||
55 | Eina_Xattr *attr; | ||
56 | |||
52 | ssize_t length; | 57 | ssize_t length; |
53 | ssize_t offset; | 58 | ssize_t offset; |
54 | 59 | ||
60 | int fd; | ||
61 | |||
55 | char xattr[1]; | 62 | char xattr[1]; |
56 | }; | 63 | }; |
57 | 64 | ||
58 | #ifdef HAVE_XATTR | 65 | #ifdef HAVE_XATTR |
59 | static Eina_Bool | 66 | static Eina_Bool |
67 | _eina_xattr_value_ls_fd_iterator_next(Eina_Xattr_Iterator *it, void **data) | ||
68 | { | ||
69 | char *tmp; | ||
70 | |||
71 | if (it->offset >= it->length) | ||
72 | return EINA_FALSE; | ||
73 | |||
74 | *data = it->attr; | ||
75 | it->attr->name = it->xattr + it->offset; | ||
76 | |||
77 | it->attr->length = fgetxattr(it->fd, it->attr->name, NULL, 0); | ||
78 | if (it->attr->length) | ||
79 | { | ||
80 | tmp = realloc((void*) it->attr->value, it->attr->length); | ||
81 | if (!tmp) | ||
82 | { | ||
83 | free((void*) it->attr->value); | ||
84 | it->attr->value = NULL; | ||
85 | it->attr->length = 0; | ||
86 | } | ||
87 | else | ||
88 | { | ||
89 | it->attr->length = fgetxattr(it->fd, it->attr->name, | ||
90 | (void *) it->attr->value, | ||
91 | it->attr->length); | ||
92 | } | ||
93 | } | ||
94 | |||
95 | return EINA_TRUE; | ||
96 | } | ||
97 | |||
98 | static Eina_Bool | ||
99 | _eina_xattr_value_ls_iterator_next(Eina_Xattr_Iterator *it, void **data) | ||
100 | { | ||
101 | char *tmp; | ||
102 | |||
103 | if (it->offset >= it->length) | ||
104 | return EINA_FALSE; | ||
105 | |||
106 | *data = it->attr; | ||
107 | it->attr->name = it->xattr + it->offset; | ||
108 | |||
109 | it->attr->length = getxattr(it->file, it->attr->name, NULL, 0); | ||
110 | if (it->attr->length) | ||
111 | { | ||
112 | tmp = realloc((void*) it->attr->value, it->attr->length); | ||
113 | if (!tmp) | ||
114 | { | ||
115 | free((void*) it->attr->value); | ||
116 | it->attr->value = NULL; | ||
117 | it->attr->length = 0; | ||
118 | } | ||
119 | else | ||
120 | { | ||
121 | it->attr->length = getxattr(it->file, it->attr->name, | ||
122 | (void*) it->attr->value, | ||
123 | it->attr->length); | ||
124 | } | ||
125 | } | ||
126 | |||
127 | return EINA_TRUE; | ||
128 | } | ||
129 | |||
130 | static Eina_Bool | ||
60 | _eina_xattr_ls_iterator_next(Eina_Xattr_Iterator *it, void **data) | 131 | _eina_xattr_ls_iterator_next(Eina_Xattr_Iterator *it, void **data) |
61 | { | 132 | { |
62 | if (it->offset >= it->length) | 133 | if (it->offset >= it->length) |
@@ -78,6 +149,9 @@ static void | |||
78 | _eina_xattr_ls_iterator_free(Eina_Xattr_Iterator *it) | 149 | _eina_xattr_ls_iterator_free(Eina_Xattr_Iterator *it) |
79 | { | 150 | { |
80 | EINA_MAGIC_SET(&it->iterator, 0); | 151 | EINA_MAGIC_SET(&it->iterator, 0); |
152 | if (it->attr) free((void *) it->attr->value); | ||
153 | eina_stringshare_del(it->file); | ||
154 | free(it->attr); | ||
81 | free(it); | 155 | free(it); |
82 | } | 156 | } |
83 | #endif | 157 | #endif |
@@ -96,6 +170,85 @@ _eina_xattr_ls_iterator_free(Eina_Xattr_Iterator *it) | |||
96 | * API * | 170 | * API * |
97 | *============================================================================*/ | 171 | *============================================================================*/ |
98 | 172 | ||
173 | EAPI Eina_Iterator * | ||
174 | eina_xattr_value_fd_ls(int fd) | ||
175 | { | ||
176 | #ifdef HAVE_XATTR | ||
177 | Eina_Xattr_Iterator *it; | ||
178 | ssize_t length; | ||
179 | |||
180 | if (fd < 0) return NULL; | ||
181 | |||
182 | length = flistxattr(fd, NULL, 0); | ||
183 | if (length <= 0) return NULL; | ||
184 | |||
185 | it = calloc(1, sizeof (Eina_Xattr_Iterator) + length - 1); | ||
186 | if (!it) return NULL; | ||
187 | |||
188 | it->attr = calloc(1, sizeof (Eina_Xattr)); | ||
189 | if (!it->attr) | ||
190 | { | ||
191 | free(it); | ||
192 | return NULL; | ||
193 | } | ||
194 | |||
195 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
196 | |||
197 | it->fd = fd; | ||
198 | it->length = flistxattr(fd, it->xattr, length); | ||
199 | if (it->length != length) | ||
200 | { | ||
201 | free(it); | ||
202 | return NULL; | ||
203 | } | ||
204 | |||
205 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
206 | it->iterator.next = FUNC_ITERATOR_NEXT(_eina_xattr_value_ls_fd_iterator_next); | ||
207 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_xattr_ls_iterator_container); | ||
208 | it->iterator.free = FUNC_ITERATOR_FREE(_eina_xattr_ls_iterator_free); | ||
209 | |||
210 | return &it->iterator; | ||
211 | #else | ||
212 | return NULL; | ||
213 | (void)fd; | ||
214 | #endif | ||
215 | } | ||
216 | |||
217 | EAPI Eina_Iterator * | ||
218 | eina_xattr_fd_ls(int fd) | ||
219 | { | ||
220 | #ifdef HAVE_XATTR | ||
221 | Eina_Xattr_Iterator *it; | ||
222 | ssize_t length; | ||
223 | |||
224 | if (fd < 0) return NULL; | ||
225 | |||
226 | length = flistxattr(fd, NULL, 0); | ||
227 | if (length <= 0) return NULL; | ||
228 | |||
229 | it = calloc(1, sizeof (Eina_Xattr_Iterator) + length - 1); | ||
230 | if (!it) return NULL; | ||
231 | |||
232 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
233 | |||
234 | it->length = flistxattr(fd, it->xattr, length); | ||
235 | if (it->length != length) | ||
236 | { | ||
237 | free(it); | ||
238 | return NULL; | ||
239 | } | ||
240 | |||
241 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
242 | it->iterator.next = FUNC_ITERATOR_NEXT(_eina_xattr_ls_iterator_next); | ||
243 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_xattr_ls_iterator_container); | ||
244 | it->iterator.free = FUNC_ITERATOR_FREE(_eina_xattr_ls_iterator_free); | ||
245 | |||
246 | return &it->iterator; | ||
247 | #else | ||
248 | return NULL; | ||
249 | (void)fd; | ||
250 | #endif | ||
251 | } | ||
99 | 252 | ||
100 | EAPI Eina_Iterator * | 253 | EAPI Eina_Iterator * |
101 | eina_xattr_ls(const char *file) | 254 | eina_xattr_ls(const char *file) |
@@ -133,6 +286,44 @@ eina_xattr_ls(const char *file) | |||
133 | #endif | 286 | #endif |
134 | } | 287 | } |
135 | 288 | ||
289 | EAPI Eina_Iterator * | ||
290 | eina_xattr_value_ls(const char *file) | ||
291 | { | ||
292 | #ifdef HAVE_XATTR | ||
293 | Eina_Xattr_Iterator *it; | ||
294 | ssize_t length; | ||
295 | |||
296 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); | ||
297 | |||
298 | length = listxattr(file, NULL, 0); | ||
299 | if (length <= 0) return NULL; | ||
300 | |||
301 | it = calloc(1, sizeof (Eina_Xattr_Iterator) + length - 1); | ||
302 | if (!it) return NULL; | ||
303 | |||
304 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
305 | |||
306 | it->length = listxattr(file, it->xattr, length); | ||
307 | if (it->length != length) | ||
308 | { | ||
309 | free(it); | ||
310 | return NULL; | ||
311 | } | ||
312 | |||
313 | it->file = eina_stringshare_add(file); | ||
314 | |||
315 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
316 | it->iterator.next = FUNC_ITERATOR_NEXT(_eina_xattr_value_ls_iterator_next); | ||
317 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_xattr_ls_iterator_container); | ||
318 | it->iterator.free = FUNC_ITERATOR_FREE(_eina_xattr_ls_iterator_free); | ||
319 | |||
320 | return &it->iterator; | ||
321 | #else | ||
322 | return NULL; | ||
323 | (void)file; | ||
324 | #endif | ||
325 | } | ||
326 | |||
136 | EAPI void * | 327 | EAPI void * |
137 | eina_xattr_get(const char *file, const char *attribute, ssize_t *size) | 328 | eina_xattr_get(const char *file, const char *attribute, ssize_t *size) |
138 | { | 329 | { |