From 0c6ed213ada3cca2d3362c202c0c587b75576fc2 Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Thu, 15 Sep 2011 15:37:28 +0000 Subject: [PATCH] eina: add eina_xattr.{c,h}. SVN revision: 63412 --- legacy/eina/ChangeLog | 6 + legacy/eina/src/include/Eina.h | 1 + legacy/eina/src/include/Makefile.am | 3 +- legacy/eina/src/include/eina_file.h | 48 +---- legacy/eina/src/include/eina_xattr.h | 166 ++++++++++++++++++ legacy/eina/src/lib/Makefile.am | 3 +- legacy/eina/src/lib/eina_file.c | 133 +------------- legacy/eina/src/lib/eina_xattr.c | 251 +++++++++++++++++++++++++++ 8 files changed, 430 insertions(+), 181 deletions(-) create mode 100644 legacy/eina/src/include/eina_xattr.h create mode 100644 legacy/eina/src/lib/eina_xattr.c diff --git a/legacy/eina/ChangeLog b/legacy/eina/ChangeLog index 1b00657235..157e696ef5 100644 --- a/legacy/eina/ChangeLog +++ b/legacy/eina/ChangeLog @@ -136,3 +136,9 @@ * Strbuf + Ustrbuf: Added eina_(u)strbuf_manage_new. This lets us take a string and use it as the string buffer instead of copying and allocating. + +2011-09-15 Cedric Bail + + * Add eina_xattr_ls, eina_xattr_get, eina_xattr_set, eina_xattr_string_set, + eina_xattr_string_get, eina_xattr_double_set, eina_xattr_double_get, + eina_xattr_int_set, eina_xattr_int_get. diff --git a/legacy/eina/src/include/Eina.h b/legacy/eina/src/include/Eina.h index 69e463cbf4..7dcddca636 100644 --- a/legacy/eina/src/include/Eina.h +++ b/legacy/eina/src/include/Eina.h @@ -185,6 +185,7 @@ extern "C" { #include "eina_prefix.h" #include "eina_refcount.h" #include "eina_mmap.h" +#include "eina_xattr.h" #ifdef __cplusplus } diff --git a/legacy/eina/src/include/Makefile.am b/legacy/eina/src/include/Makefile.am index 8fc4763d00..5204db51b8 100644 --- a/legacy/eina/src/include/Makefile.am +++ b/legacy/eina/src/include/Makefile.am @@ -58,7 +58,8 @@ eina_simple_xml_parser.h \ eina_lock.h \ eina_prefix.h \ eina_refcount.h \ -eina_mmap.h +eina_mmap.h \ +eina_xattr.h # Will be back for developper after 1.1. # eina_object.h diff --git a/legacy/eina/src/include/eina_file.h b/legacy/eina/src/include/eina_file.h index c9067c7861..472ff98d49 100644 --- a/legacy/eina/src/include/eina_file.h +++ b/legacy/eina/src/include/eina_file.h @@ -1,5 +1,6 @@ /* EINA - EFL data type library * Copyright (C) 2007-2008 Jorge Luis Zapata Muga + * 2011 Cedric Bail * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -112,12 +113,6 @@ typedef enum { EINA_FILE_WHT /**< Whiteout file type (unused on Windows). */ } Eina_File_Type; -typedef enum { - EINA_XATTR_INSERT, /**< This is the default behaviour, it will either create or replace the extended attribute */ - EINA_XATTR_REPLACE, /**< This will only succeed if the extended attribute previously existed */ - EINA_XATTR_CREATED /**< This will only succeed if the extended attribute wasn't previously set */ -} Eina_Xattr_Flags; - typedef struct _Eina_File Eina_File; typedef enum { @@ -279,47 +274,6 @@ EAPI Eina_Iterator *eina_file_stat_ls(const char *dir) EINA_WARN_UNUSED_RESULT E */ EAPI Eina_Iterator *eina_file_direct_ls(const char *dir) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC; -/** - * @brief Get an iterator that list all extended attribute of a file. - * - * @param file The filename to retrieve the extended attribute list from. - * @return an iterator. - * - * The iterator will not allocate any data during the iteration step, so you need to copy them yourself - * if you need. - * - * @since 1.1 - */ -EAPI Eina_Iterator *eina_xattr_ls(const char *file); - -/** - * @brief Retrieve an extended attribute from a file. - * - * @param file The file to retrieve the extended attribute from. - * @param atttribute The extended attribute name to retrieve. - * @param size The size of the retrieved extended attribute. - * @return the allocated data that hold the extended attribute value. - * - * It will return NULL and *size will be @c 0 if it fails. - * - * @since 1.1 - */ -EAPI void *eina_xattr_get(const char *file, const char *attribute, ssize_t *size); - -/** - * @brief Set an extended attribute on a file. - * - * @param file The file to set the extended attribute to. - * @param attribute The attribute to set. - * @param data The data to set. - * @param length The length of the data to set. - * @param flags Define the set policy - * @return EINA_TRUE on success, EINA_FALSE otherwise. - * - * @since 1.1 - */ -EAPI Eina_Bool eina_xattr_set(const char *file, const char *attribute, const void *data, ssize_t length, Eina_Xattr_Flags flags); - /** * @brief Get a read-only handler to a file. * diff --git a/legacy/eina/src/include/eina_xattr.h b/legacy/eina/src/include/eina_xattr.h new file mode 100644 index 0000000000..80586b7bba --- /dev/null +++ b/legacy/eina/src/include/eina_xattr.h @@ -0,0 +1,166 @@ +/* EINA - EFL data type library + * Copyright (C) 2011 Cedric Bail + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; + * if not, see . + */ + +#ifndef EINA_XATTR_H_ +#define EINA_XATTR_H_ + +#include "eina_types.h" + +/** + * @addtogroup Eina_Tools_Group Tools + * + * @{ + */ + +/** + * @typedef Eina_Xattr_Flags + * define extended attribute creation + */ +typedef enum { + EINA_XATTR_INSERT, /**< This is the default behaviour, it will either create or replace the extended attribute */ + EINA_XATTR_REPLACE, /**< This will only succeed if the extended attribute previously existed */ + EINA_XATTR_CREATED /**< This will only succeed if the extended attribute wasn't previously set */ +} Eina_Xattr_Flags; + + +/** + * @brief Get an iterator that list all extended attribute of a file. + * + * @param file The filename to retrieve the extended attribute list from. + * @return an iterator. + * + * The iterator will not allocate any data during the iteration step, so you need to copy them yourself + * if you need. + * + * @since 1.1 + */ +EAPI Eina_Iterator *eina_xattr_ls(const char *file); + +/** + * @brief Retrieve an extended attribute from a file. + * + * @param file The file to retrieve the extended attribute from. + * @param atttribute The extended attribute name to retrieve. + * @param size The size of the retrieved extended attribute. + * @return the allocated data that hold the extended attribute value. + * + * It will return NULL and *size will be @c 0 if it fails. + * + * @since 1.1 + */ +EAPI void *eina_xattr_get(const char *file, const char *attribute, ssize_t *size); + +/** + * @brief Set an extended attribute on a file. + * + * @param file The file to set the extended attribute to. + * @param attribute The attribute to set. + * @param data The data to set. + * @param length The length of the data to set. + * @param flags Define the set policy. + * @return EINA_TRUE on success, EINA_FALSE otherwise. + * + * @since 1.1 + */ +EAPI Eina_Bool eina_xattr_set(const char *file, const char *attribute, const void *data, ssize_t length, Eina_Xattr_Flags flags); + +/** + * @brief Set a string as a extended attribute properties. + * + * @param file The file to set the string to. + * @param attribute The attribute to set. + * @param data The NULL terminated string to set. + * @param flags Define the set policy. + * @return EINA_TRUE on success, EINA_FALSE otherwise. + * + * @since 1.1 + */ +EAPI Eina_Bool eina_xattr_string_set(const char *file, const char *attribute, const char *data, Eina_Xattr_Flags flags); + +/** + * @brief Get a string from an extended attribute properties. + * + * @param file The file to get the string from. + * @param attribute The attribute to get. + * @return a valid string on success, NULL otherwise. + * + * This call check that the string is properly NULL-terminated before returning it. + * + * @since 1.1 + */ +EAPI char *eina_xattr_string_get(const char *file, const char *attribute); + +/** + * @brief Set a double as a extended attribute properties. + * + * @param file The file to set the double to. + * @param attribute The attribute to set. + * @param data The NULL terminated double to set. + * @param flags Define the set policy. + * @return EINA_TRUE on success, EINA_FALSE otherwise. + * + * @since 1.1 + */ +EAPI Eina_Bool eina_xattr_double_set(const char *file, const char *attribute, double value, Eina_Xattr_Flags flags); + +/** + * @brief Get a double from an extended attribute properties. + * + * @param file The file to get the string from. + * @param attribute The attribute to get. + * @param value Where to put the extracted value + * @return EINA_TRUE on success, EINA_FALSE otherwise. + * + * This call check that the double is correctly set. + * + * @since 1.1 + */ +EAPI Eina_Bool eina_xattr_double_get(const char *file, const char *attribute, double *value); + +/** + * @brief Set an int as a extended attribute properties. + * + * @param file The file to set the int to. + * @param attribute The attribute to set. + * @param data The NULL terminated int to set. + * @param flags Define the set policy. + * @return EINA_TRUE on success, EINA_FALSE otherwise. + * + * @since 1.1 + */ +EAPI Eina_Bool eina_xattr_int_set(const char *file, const char *attribute, int value, Eina_Xattr_Flags flags); + +/** + * @brief Get a int from an extended attribute properties. + * + * @param file The file to get the string from. + * @param attribute The attribute to get. + * @param value Where to put the extracted value + * @return EINA_TRUE on success, EINA_FALSE otherwise. + * + * This call check that the int is correctly set. + * + * @since 1.1 + */ +EAPI Eina_Bool eina_xattr_int_get(const char *file, const char *attribute, int *value); + +/** + * @} + */ + +#endif diff --git a/legacy/eina/src/lib/Makefile.am b/legacy/eina/src/lib/Makefile.am index 7793593ee3..0537a619d2 100644 --- a/legacy/eina/src/lib/Makefile.am +++ b/legacy/eina/src/lib/Makefile.am @@ -49,7 +49,8 @@ eina_tiler.c \ eina_unicode.c \ eina_ustrbuf.c \ eina_ustringshare.c \ -eina_value.c +eina_value.c \ +eina_xattr.c # Will be back for developper after 1.1 # eina_object.c diff --git a/legacy/eina/src/lib/eina_file.c b/legacy/eina/src/lib/eina_file.c index 2c7a6dcc47..a2fedd1a20 100644 --- a/legacy/eina/src/lib/eina_file.c +++ b/legacy/eina/src/lib/eina_file.c @@ -1,6 +1,6 @@ /* EINA - EFL data type library * Copyright (C) 2007-2008 Jorge Luis Zapata Muga, Vincent Torri - * Copyright (C) 2010 Cedric Bail + * Copyright (C) 2010-2011 Cedric Bail * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -47,10 +47,6 @@ void *alloca (size_t); #include #include -#ifdef HAVE_XATTR -# include -#endif - #define PATH_DELIM '/' #ifdef __sun @@ -103,7 +99,6 @@ void *alloca (size_t); typedef struct _Eina_File_Iterator Eina_File_Iterator; typedef struct _Eina_File_Map Eina_File_Map; -typedef struct _Eina_Xattr_Iterator Eina_Xattr_Iterator; struct _Eina_File_Iterator { @@ -115,16 +110,6 @@ struct _Eina_File_Iterator char dir[1]; }; -struct _Eina_Xattr_Iterator -{ - Eina_Iterator iterator; - - ssize_t length; - ssize_t offset; - - char xattr[1]; -}; - struct _Eina_File { const char *filename; @@ -394,33 +379,6 @@ _eina_file_stat_ls_iterator_next(Eina_File_Direct_Iterator *it, void **data) return EINA_TRUE; } -#ifdef HAVE_XATTR -static Eina_Bool -_eina_xattr_ls_iterator_next(Eina_Xattr_Iterator *it, void **data) -{ - if (it->offset >= it->length) - return EINA_FALSE; - - *data = it->xattr + it->offset; - it->offset += strlen(it->xattr + it->offset) + 1; - - return EINA_TRUE; -} - -static void * -_eina_xattr_ls_iterator_container(Eina_Xattr_Iterator *it __UNUSED__) -{ - return NULL; -} - -static void -_eina_xattr_ls_iterator_free(Eina_Xattr_Iterator *it) -{ - EINA_MAGIC_SET(&it->iterator, 0); - free(it); -} -#endif - static void _eina_file_real_close(Eina_File *file) { @@ -775,95 +733,6 @@ eina_file_stat_ls(const char *dir) return &it->iterator; } -EAPI Eina_Iterator * -eina_xattr_ls(const char *file) -{ - Eina_Xattr_Iterator *it; - ssize_t length; - - EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); - -#ifdef HAVE_XATTR - length = listxattr(file, NULL, 0); - if (length <= 0) return NULL; - - it = calloc(1, sizeof (Eina_Xattr_Iterator) + length - 1); - if (!it) return NULL; - - EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); - - it->length = listxattr(file, it->xattr, length); - if (it->length != length) - { - free(it); - return NULL; - } - - it->iterator.version = EINA_ITERATOR_VERSION; - it->iterator.next = FUNC_ITERATOR_NEXT(_eina_xattr_ls_iterator_next); - it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_xattr_ls_iterator_container); - it->iterator.free = FUNC_ITERATOR_FREE(_eina_xattr_ls_iterator_free); - - return &it->iterator; -#else - return NULL; -#endif -} - -EAPI void * -eina_xattr_get(const char *file, const char *attribute, ssize_t *size) -{ - void *ret = NULL; - ssize_t tmp; - - EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(attribute, NULL); - EINA_SAFETY_ON_TRUE_RETURN_VAL(!size, NULL); - - *size = getxattr(file, attribute, NULL, 0); - /* Size should be less than 2MB (already huge in my opinion) */ - if (!(*size > 0 && *size < 2 * 1024 * 1024)) - goto on_error; - - ret = malloc(*size); - if (!ret) return NULL; - - tmp = getxattr(file, attribute, ret, *size); - if (tmp != *size) - goto on_error; - - return ret; - - on_error: - free(ret); - *size = 0; - return NULL; -} - -EAPI Eina_Bool -eina_xattr_set(const char *file, const char *attribute, const void *data, ssize_t length, Eina_Xattr_Flags flags) -{ - int iflags; - - EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(attribute, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE); - EINA_SAFETY_ON_TRUE_RETURN_VAL(!(length > 0 && length < 2 * 1024 * 1024), EINA_FALSE); - - switch (flags) - { - case EINA_XATTR_INSERT: iflags = 0; break; - case EINA_XATTR_REPLACE: iflags = XATTR_REPLACE; break; - case EINA_XATTR_CREATED: iflags = XATTR_CREATE; break; - default: - return EINA_FALSE; - } - - if (setxattr(file, attribute, data, length, iflags)) - return EINA_FALSE; - return EINA_TRUE; -} - EAPI Eina_File * eina_file_open(const char *filename, Eina_Bool shared) { diff --git a/legacy/eina/src/lib/eina_xattr.c b/legacy/eina/src/lib/eina_xattr.c new file mode 100644 index 0000000000..f7e0ddff5e --- /dev/null +++ b/legacy/eina/src/lib/eina_xattr.c @@ -0,0 +1,251 @@ +/* EINA - EFL data type library + * Copyright (C) 2011 Cedric Bail + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; + * if not, see . + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#ifdef HAVE_XATTR +# include +#endif + +#include "eina_config.h" +#include "eina_private.h" + +#include "eina_safety_checks.h" +#include "eina_xattr.h" +#include "eina_convert.h" + +typedef struct _Eina_Xattr_Iterator Eina_Xattr_Iterator; + +struct _Eina_Xattr_Iterator +{ + Eina_Iterator iterator; + + ssize_t length; + ssize_t offset; + + char xattr[1]; +}; + +#ifdef HAVE_XATTR +static Eina_Bool +_eina_xattr_ls_iterator_next(Eina_Xattr_Iterator *it, void **data) +{ + if (it->offset >= it->length) + return EINA_FALSE; + + *data = it->xattr + it->offset; + it->offset += strlen(it->xattr + it->offset) + 1; + + return EINA_TRUE; +} + +static void * +_eina_xattr_ls_iterator_container(Eina_Xattr_Iterator *it __UNUSED__) +{ + return NULL; +} + +static void +_eina_xattr_ls_iterator_free(Eina_Xattr_Iterator *it) +{ + EINA_MAGIC_SET(&it->iterator, 0); + free(it); +} +#endif + +EAPI Eina_Iterator * +eina_xattr_ls(const char *file) +{ + Eina_Xattr_Iterator *it; + ssize_t length; + + EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); + +#ifdef HAVE_XATTR + length = listxattr(file, NULL, 0); + if (length <= 0) return NULL; + + it = calloc(1, sizeof (Eina_Xattr_Iterator) + length - 1); + if (!it) return NULL; + + EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); + + it->length = listxattr(file, it->xattr, length); + if (it->length != length) + { + free(it); + return NULL; + } + + it->iterator.version = EINA_ITERATOR_VERSION; + it->iterator.next = FUNC_ITERATOR_NEXT(_eina_xattr_ls_iterator_next); + it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_xattr_ls_iterator_container); + it->iterator.free = FUNC_ITERATOR_FREE(_eina_xattr_ls_iterator_free); + + return &it->iterator; +#else + return NULL; +#endif +} + +EAPI void * +eina_xattr_get(const char *file, const char *attribute, ssize_t *size) +{ + void *ret = NULL; + ssize_t tmp; + + EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(attribute, NULL); + EINA_SAFETY_ON_TRUE_RETURN_VAL(!size, NULL); + + *size = getxattr(file, attribute, NULL, 0); + /* Size should be less than 2MB (already huge in my opinion) */ + if (!(*size > 0 && *size < 2 * 1024 * 1024)) + goto on_error; + + ret = malloc(*size); + if (!ret) return NULL; + + tmp = getxattr(file, attribute, ret, *size); + if (tmp != *size) + goto on_error; + + return ret; + + on_error: + free(ret); + *size = 0; + return NULL; +} + +EAPI Eina_Bool +eina_xattr_set(const char *file, const char *attribute, const void *data, ssize_t length, Eina_Xattr_Flags flags) +{ + int iflags; + + EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(attribute, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE); + EINA_SAFETY_ON_TRUE_RETURN_VAL(!(length > 0 && length < 2 * 1024 * 1024), EINA_FALSE); + + switch (flags) + { + case EINA_XATTR_INSERT: iflags = 0; break; + case EINA_XATTR_REPLACE: iflags = XATTR_REPLACE; break; + case EINA_XATTR_CREATED: iflags = XATTR_CREATE; break; + default: + return EINA_FALSE; + } + + if (setxattr(file, attribute, data, length, iflags)) + return EINA_FALSE; + return EINA_TRUE; +} + +EAPI Eina_Bool +eina_xattr_string_set(const char *file, const char *attribute, const char *data, Eina_Xattr_Flags flags) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE); + + return eina_xattr_set(file, attribute, data, strlen(data) + 1, flags); +} + +EAPI char * +eina_xattr_string_get(const char *file, const char *attribute) +{ + char *tmp; + ssize_t size; + + tmp = eina_xattr_get(file, attribute, &size); + if (!tmp) return NULL; + + if (tmp[size - 1] != '\0') + { + free(tmp); + return NULL; + } + + return tmp; +} + +EAPI Eina_Bool +eina_xattr_double_set(const char *file, const char *attribute, double value, Eina_Xattr_Flags flags) +{ + char buffer[128]; + + eina_convert_dtoa(value, buffer); + return eina_xattr_string_set(file, attribute, buffer, flags); +} + +EAPI Eina_Bool +eina_xattr_double_get(const char *file, const char *attribute, double *value) +{ + char *tmp; + long long int m = 0; + long int e = 0; + + EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE); + + tmp = eina_xattr_string_get(file, attribute); + if (!tmp) return EINA_FALSE; + + if (!eina_convert_atod(tmp, strlen(tmp), &m, &e)) + { + free(tmp); + return EINA_FALSE; + } + + *value = ldexp((double)m, e); + free(tmp); + + return EINA_TRUE; +} + +EAPI Eina_Bool +eina_xattr_int_set(const char *file, const char *attribute, int value, Eina_Xattr_Flags flags) +{ + char buffer[10]; + + eina_convert_itoa(value, buffer); + return eina_xattr_string_set(file, attribute, buffer, flags); +} + +EAPI Eina_Bool +eina_xattr_int_get(const char *file, const char *attribute, int *value) +{ + char *tmp; + char *eos; + Eina_Bool result; + + EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE); + + tmp = eina_xattr_string_get(file, attribute); + if (!tmp) return EINA_FALSE; + + *value = (int) strtol(tmp, &eos, 10); + result = (*eos == '\0'); + free(tmp); + + return result; +}