diff options
Diffstat (limited to 'libraries/eina/src/lib/eina_xattr.c')
-rw-r--r-- | libraries/eina/src/lib/eina_xattr.c | 483 |
1 files changed, 0 insertions, 483 deletions
diff --git a/libraries/eina/src/lib/eina_xattr.c b/libraries/eina/src/lib/eina_xattr.c deleted file mode 100644 index d4ed139..0000000 --- a/libraries/eina/src/lib/eina_xattr.c +++ /dev/null | |||
@@ -1,483 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2011 Cedric Bail | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #include <stdlib.h> | ||
24 | #include <sys/types.h> | ||
25 | #include <string.h> | ||
26 | #include <math.h> | ||
27 | |||
28 | #ifdef HAVE_XATTR | ||
29 | # include <sys/xattr.h> | ||
30 | #endif | ||
31 | |||
32 | #include "eina_config.h" | ||
33 | #include "eina_private.h" | ||
34 | |||
35 | #include "eina_safety_checks.h" | ||
36 | #include "eina_xattr.h" | ||
37 | #include "eina_convert.h" | ||
38 | #include "eina_stringshare.h" | ||
39 | |||
40 | /*============================================================================* | ||
41 | * Local * | ||
42 | *============================================================================*/ | ||
43 | |||
44 | /** | ||
45 | * @cond LOCAL | ||
46 | */ | ||
47 | |||
48 | typedef struct _Eina_Xattr_Iterator Eina_Xattr_Iterator; | ||
49 | |||
50 | struct _Eina_Xattr_Iterator | ||
51 | { | ||
52 | Eina_Iterator iterator; | ||
53 | |||
54 | const char *file; | ||
55 | Eina_Xattr *attr; | ||
56 | |||
57 | ssize_t length; | ||
58 | ssize_t offset; | ||
59 | |||
60 | int fd; | ||
61 | |||
62 | char xattr[1]; | ||
63 | }; | ||
64 | |||
65 | #ifdef HAVE_XATTR | ||
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 | ||
131 | _eina_xattr_ls_iterator_next(Eina_Xattr_Iterator *it, void **data) | ||
132 | { | ||
133 | if (it->offset >= it->length) | ||
134 | return EINA_FALSE; | ||
135 | |||
136 | *data = it->xattr + it->offset; | ||
137 | it->offset += strlen(it->xattr + it->offset) + 1; | ||
138 | |||
139 | return EINA_TRUE; | ||
140 | } | ||
141 | |||
142 | static void * | ||
143 | _eina_xattr_ls_iterator_container(Eina_Xattr_Iterator *it __UNUSED__) | ||
144 | { | ||
145 | return NULL; | ||
146 | } | ||
147 | |||
148 | static void | ||
149 | _eina_xattr_ls_iterator_free(Eina_Xattr_Iterator *it) | ||
150 | { | ||
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); | ||
155 | free(it); | ||
156 | } | ||
157 | #endif | ||
158 | |||
159 | /** | ||
160 | * @endcond | ||
161 | */ | ||
162 | |||
163 | |||
164 | /*============================================================================* | ||
165 | * Global * | ||
166 | *============================================================================*/ | ||
167 | |||
168 | |||
169 | /*============================================================================* | ||
170 | * API * | ||
171 | *============================================================================*/ | ||
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 | } | ||
252 | |||
253 | EAPI Eina_Iterator * | ||
254 | eina_xattr_ls(const char *file) | ||
255 | { | ||
256 | #ifdef HAVE_XATTR | ||
257 | Eina_Xattr_Iterator *it; | ||
258 | ssize_t length; | ||
259 | |||
260 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); | ||
261 | |||
262 | length = listxattr(file, NULL, 0); | ||
263 | if (length <= 0) return NULL; | ||
264 | |||
265 | it = calloc(1, sizeof (Eina_Xattr_Iterator) + length - 1); | ||
266 | if (!it) return NULL; | ||
267 | |||
268 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
269 | |||
270 | it->length = listxattr(file, it->xattr, length); | ||
271 | if (it->length != length) | ||
272 | { | ||
273 | free(it); | ||
274 | return NULL; | ||
275 | } | ||
276 | |||
277 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
278 | it->iterator.next = FUNC_ITERATOR_NEXT(_eina_xattr_ls_iterator_next); | ||
279 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_xattr_ls_iterator_container); | ||
280 | it->iterator.free = FUNC_ITERATOR_FREE(_eina_xattr_ls_iterator_free); | ||
281 | |||
282 | return &it->iterator; | ||
283 | #else | ||
284 | return NULL; | ||
285 | (void)file; | ||
286 | #endif | ||
287 | } | ||
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 | |||
327 | EAPI void * | ||
328 | eina_xattr_get(const char *file, const char *attribute, ssize_t *size) | ||
329 | { | ||
330 | #ifdef HAVE_XATTR | ||
331 | void *ret = NULL; | ||
332 | ssize_t tmp; | ||
333 | |||
334 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); | ||
335 | EINA_SAFETY_ON_NULL_RETURN_VAL(attribute, NULL); | ||
336 | EINA_SAFETY_ON_TRUE_RETURN_VAL(!size, NULL); | ||
337 | |||
338 | *size = getxattr(file, attribute, NULL, 0); | ||
339 | /* Size should be less than 2MB (already huge in my opinion) */ | ||
340 | if (!(*size > 0 && *size < 2 * 1024 * 1024)) | ||
341 | goto on_error; | ||
342 | |||
343 | ret = malloc(*size); | ||
344 | if (!ret) return NULL; | ||
345 | |||
346 | tmp = getxattr(file, attribute, ret, *size); | ||
347 | if (tmp != *size) | ||
348 | goto on_error; | ||
349 | |||
350 | return ret; | ||
351 | |||
352 | on_error: | ||
353 | free(ret); | ||
354 | *size = 0; | ||
355 | return NULL; | ||
356 | #else | ||
357 | EINA_SAFETY_ON_TRUE_RETURN_VAL(!size, NULL); | ||
358 | *size = 0; | ||
359 | return NULL; | ||
360 | (void)file; | ||
361 | (void)attribute; | ||
362 | #endif | ||
363 | } | ||
364 | |||
365 | EAPI Eina_Bool | ||
366 | eina_xattr_set(const char *file, const char *attribute, const void *data, ssize_t length, Eina_Xattr_Flags flags) | ||
367 | { | ||
368 | #ifdef HAVE_XATTR | ||
369 | int iflags; | ||
370 | |||
371 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE); | ||
372 | EINA_SAFETY_ON_NULL_RETURN_VAL(attribute, EINA_FALSE); | ||
373 | EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE); | ||
374 | EINA_SAFETY_ON_TRUE_RETURN_VAL(!(length > 0 && length < 2 * 1024 * 1024), EINA_FALSE); | ||
375 | |||
376 | switch (flags) | ||
377 | { | ||
378 | case EINA_XATTR_INSERT: iflags = 0; break; | ||
379 | case EINA_XATTR_REPLACE: iflags = XATTR_REPLACE; break; | ||
380 | case EINA_XATTR_CREATED: iflags = XATTR_CREATE; break; | ||
381 | default: | ||
382 | return EINA_FALSE; | ||
383 | } | ||
384 | |||
385 | if (setxattr(file, attribute, data, length, iflags)) | ||
386 | return EINA_FALSE; | ||
387 | return EINA_TRUE; | ||
388 | #else | ||
389 | return EINA_FALSE; | ||
390 | (void)file; | ||
391 | (void)attribute; | ||
392 | (void)data; | ||
393 | (void)length; | ||
394 | (void)flags; | ||
395 | #endif | ||
396 | } | ||
397 | |||
398 | EAPI Eina_Bool | ||
399 | eina_xattr_string_set(const char *file, const char *attribute, const char *data, Eina_Xattr_Flags flags) | ||
400 | { | ||
401 | EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE); | ||
402 | |||
403 | return eina_xattr_set(file, attribute, data, strlen(data) + 1, flags); | ||
404 | } | ||
405 | |||
406 | EAPI char * | ||
407 | eina_xattr_string_get(const char *file, const char *attribute) | ||
408 | { | ||
409 | char *tmp; | ||
410 | ssize_t size; | ||
411 | |||
412 | tmp = eina_xattr_get(file, attribute, &size); | ||
413 | if (!tmp) return NULL; | ||
414 | |||
415 | if (tmp[size - 1] != '\0') | ||
416 | { | ||
417 | free(tmp); | ||
418 | return NULL; | ||
419 | } | ||
420 | |||
421 | return tmp; | ||
422 | } | ||
423 | |||
424 | EAPI Eina_Bool | ||
425 | eina_xattr_double_set(const char *file, const char *attribute, double value, Eina_Xattr_Flags flags) | ||
426 | { | ||
427 | char buffer[128]; | ||
428 | |||
429 | eina_convert_dtoa(value, buffer); | ||
430 | return eina_xattr_string_set(file, attribute, buffer, flags); | ||
431 | } | ||
432 | |||
433 | EAPI Eina_Bool | ||
434 | eina_xattr_double_get(const char *file, const char *attribute, double *value) | ||
435 | { | ||
436 | char *tmp; | ||
437 | long long int m = 0; | ||
438 | long int e = 0; | ||
439 | |||
440 | EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE); | ||
441 | |||
442 | tmp = eina_xattr_string_get(file, attribute); | ||
443 | if (!tmp) return EINA_FALSE; | ||
444 | |||
445 | if (!eina_convert_atod(tmp, strlen(tmp), &m, &e)) | ||
446 | { | ||
447 | free(tmp); | ||
448 | return EINA_FALSE; | ||
449 | } | ||
450 | |||
451 | *value = ldexp((double)m, e); | ||
452 | free(tmp); | ||
453 | |||
454 | return EINA_TRUE; | ||
455 | } | ||
456 | |||
457 | EAPI Eina_Bool | ||
458 | eina_xattr_int_set(const char *file, const char *attribute, int value, Eina_Xattr_Flags flags) | ||
459 | { | ||
460 | char buffer[10]; | ||
461 | |||
462 | eina_convert_itoa(value, buffer); | ||
463 | return eina_xattr_string_set(file, attribute, buffer, flags); | ||
464 | } | ||
465 | |||
466 | EAPI Eina_Bool | ||
467 | eina_xattr_int_get(const char *file, const char *attribute, int *value) | ||
468 | { | ||
469 | char *tmp; | ||
470 | char *eos; | ||
471 | Eina_Bool result; | ||
472 | |||
473 | EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE); | ||
474 | |||
475 | tmp = eina_xattr_string_get(file, attribute); | ||
476 | if (!tmp) return EINA_FALSE; | ||
477 | |||
478 | *value = (int) strtol(tmp, &eos, 10); | ||
479 | result = (*eos == '\0'); | ||
480 | free(tmp); | ||
481 | |||
482 | return result; | ||
483 | } | ||