aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/eina/src/lib/eina_xattr.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/eina/src/lib/eina_xattr.c')
-rw-r--r--libraries/eina/src/lib/eina_xattr.c292
1 files changed, 292 insertions, 0 deletions
diff --git a/libraries/eina/src/lib/eina_xattr.c b/libraries/eina/src/lib/eina_xattr.c
new file mode 100644
index 0000000..bd5b98e
--- /dev/null
+++ b/libraries/eina/src/lib/eina_xattr.c
@@ -0,0 +1,292 @@
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 <sys/types.h>
24#include <string.h>
25#include <math.h>
26
27#ifdef HAVE_XATTR
28# include <sys/xattr.h>
29#endif
30
31#include "eina_config.h"
32#include "eina_private.h"
33
34#include "eina_safety_checks.h"
35#include "eina_xattr.h"
36#include "eina_convert.h"
37
38/*============================================================================*
39 * Local *
40 *============================================================================*/
41
42/**
43 * @cond LOCAL
44 */
45
46typedef struct _Eina_Xattr_Iterator Eina_Xattr_Iterator;
47
48struct _Eina_Xattr_Iterator
49{
50 Eina_Iterator iterator;
51
52 ssize_t length;
53 ssize_t offset;
54
55 char xattr[1];
56};
57
58#ifdef HAVE_XATTR
59static Eina_Bool
60_eina_xattr_ls_iterator_next(Eina_Xattr_Iterator *it, void **data)
61{
62 if (it->offset >= it->length)
63 return EINA_FALSE;
64
65 *data = it->xattr + it->offset;
66 it->offset += strlen(it->xattr + it->offset) + 1;
67
68 return EINA_TRUE;
69}
70
71static void *
72_eina_xattr_ls_iterator_container(Eina_Xattr_Iterator *it __UNUSED__)
73{
74 return NULL;
75}
76
77static void
78_eina_xattr_ls_iterator_free(Eina_Xattr_Iterator *it)
79{
80 EINA_MAGIC_SET(&it->iterator, 0);
81 free(it);
82}
83#endif
84
85/**
86 * @endcond
87 */
88
89
90/*============================================================================*
91 * Global *
92 *============================================================================*/
93
94
95/*============================================================================*
96 * API *
97 *============================================================================*/
98
99
100EAPI Eina_Iterator *
101eina_xattr_ls(const char *file)
102{
103#ifdef HAVE_XATTR
104 Eina_Xattr_Iterator *it;
105 ssize_t length;
106
107 EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
108
109 length = listxattr(file, NULL, 0);
110 if (length <= 0) return NULL;
111
112 it = calloc(1, sizeof (Eina_Xattr_Iterator) + length - 1);
113 if (!it) return NULL;
114
115 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
116
117 it->length = listxattr(file, it->xattr, length);
118 if (it->length != length)
119 {
120 free(it);
121 return NULL;
122 }
123
124 it->iterator.version = EINA_ITERATOR_VERSION;
125 it->iterator.next = FUNC_ITERATOR_NEXT(_eina_xattr_ls_iterator_next);
126 it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_xattr_ls_iterator_container);
127 it->iterator.free = FUNC_ITERATOR_FREE(_eina_xattr_ls_iterator_free);
128
129 return &it->iterator;
130#else
131 return NULL;
132 (void)file;
133#endif
134}
135
136EAPI void *
137eina_xattr_get(const char *file, const char *attribute, ssize_t *size)
138{
139#ifdef HAVE_XATTR
140 void *ret = NULL;
141 ssize_t tmp;
142
143 EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
144 EINA_SAFETY_ON_NULL_RETURN_VAL(attribute, NULL);
145 EINA_SAFETY_ON_TRUE_RETURN_VAL(!size, NULL);
146
147 *size = getxattr(file, attribute, NULL, 0);
148 /* Size should be less than 2MB (already huge in my opinion) */
149 if (!(*size > 0 && *size < 2 * 1024 * 1024))
150 goto on_error;
151
152 ret = malloc(*size);
153 if (!ret) return NULL;
154
155 tmp = getxattr(file, attribute, ret, *size);
156 if (tmp != *size)
157 goto on_error;
158
159 return ret;
160
161 on_error:
162 free(ret);
163 *size = 0;
164 return NULL;
165#else
166 EINA_SAFETY_ON_TRUE_RETURN_VAL(!size, NULL);
167 *size = 0;
168 return NULL;
169 (void)file;
170 (void)attribute;
171#endif
172}
173
174EAPI Eina_Bool
175eina_xattr_set(const char *file, const char *attribute, const void *data, ssize_t length, Eina_Xattr_Flags flags)
176{
177#ifdef HAVE_XATTR
178 int iflags;
179
180 EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE);
181 EINA_SAFETY_ON_NULL_RETURN_VAL(attribute, EINA_FALSE);
182 EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE);
183 EINA_SAFETY_ON_TRUE_RETURN_VAL(!(length > 0 && length < 2 * 1024 * 1024), EINA_FALSE);
184
185 switch (flags)
186 {
187 case EINA_XATTR_INSERT: iflags = 0; break;
188 case EINA_XATTR_REPLACE: iflags = XATTR_REPLACE; break;
189 case EINA_XATTR_CREATED: iflags = XATTR_CREATE; break;
190 default:
191 return EINA_FALSE;
192 }
193
194 if (setxattr(file, attribute, data, length, iflags))
195 return EINA_FALSE;
196 return EINA_TRUE;
197#else
198 return EINA_FALSE;
199 (void)file;
200 (void)attribute;
201 (void)data;
202 (void)length;
203 (void)flags;
204#endif
205}
206
207EAPI Eina_Bool
208eina_xattr_string_set(const char *file, const char *attribute, const char *data, Eina_Xattr_Flags flags)
209{
210 EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE);
211
212 return eina_xattr_set(file, attribute, data, strlen(data) + 1, flags);
213}
214
215EAPI char *
216eina_xattr_string_get(const char *file, const char *attribute)
217{
218 char *tmp;
219 ssize_t size;
220
221 tmp = eina_xattr_get(file, attribute, &size);
222 if (!tmp) return NULL;
223
224 if (tmp[size - 1] != '\0')
225 {
226 free(tmp);
227 return NULL;
228 }
229
230 return tmp;
231}
232
233EAPI Eina_Bool
234eina_xattr_double_set(const char *file, const char *attribute, double value, Eina_Xattr_Flags flags)
235{
236 char buffer[128];
237
238 eina_convert_dtoa(value, buffer);
239 return eina_xattr_string_set(file, attribute, buffer, flags);
240}
241
242EAPI Eina_Bool
243eina_xattr_double_get(const char *file, const char *attribute, double *value)
244{
245 char *tmp;
246 long long int m = 0;
247 long int e = 0;
248
249 EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE);
250
251 tmp = eina_xattr_string_get(file, attribute);
252 if (!tmp) return EINA_FALSE;
253
254 if (!eina_convert_atod(tmp, strlen(tmp), &m, &e))
255 {
256 free(tmp);
257 return EINA_FALSE;
258 }
259
260 *value = ldexp((double)m, e);
261 free(tmp);
262
263 return EINA_TRUE;
264}
265
266EAPI Eina_Bool
267eina_xattr_int_set(const char *file, const char *attribute, int value, Eina_Xattr_Flags flags)
268{
269 char buffer[10];
270
271 eina_convert_itoa(value, buffer);
272 return eina_xattr_string_set(file, attribute, buffer, flags);
273}
274
275EAPI Eina_Bool
276eina_xattr_int_get(const char *file, const char *attribute, int *value)
277{
278 char *tmp;
279 char *eos;
280 Eina_Bool result;
281
282 EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE);
283
284 tmp = eina_xattr_string_get(file, attribute);
285 if (!tmp) return EINA_FALSE;
286
287 *value = (int) strtol(tmp, &eos, 10);
288 result = (*eos == '\0');
289 free(tmp);
290
291 return result;
292}