diff options
Diffstat (limited to 'contrib')
-rw-r--r-- | contrib/libxdg-basedir/Makefile.am | 2 | ||||
-rw-r--r-- | contrib/libxdg-basedir/basedir.c | 251 | ||||
-rw-r--r-- | contrib/libxdg-basedir/basedir.h | 146 | ||||
-rw-r--r-- | contrib/libxdg-basedir/basedir_fs.h | 100 |
4 files changed, 315 insertions, 184 deletions
diff --git a/contrib/libxdg-basedir/Makefile.am b/contrib/libxdg-basedir/Makefile.am index 420d85999..f46e76bbc 100644 --- a/contrib/libxdg-basedir/Makefile.am +++ b/contrib/libxdg-basedir/Makefile.am @@ -4,4 +4,4 @@ endif AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) -libxdg_basedir_la_SOURCES = basedir.c basedir.h +libxdg_basedir_la_SOURCES = basedir.c basedir.h basedir_fs.h diff --git a/contrib/libxdg-basedir/basedir.c b/contrib/libxdg-basedir/basedir.c index ae50d1bba..43d41508f 100644 --- a/contrib/libxdg-basedir/basedir.c +++ b/contrib/libxdg-basedir/basedir.c @@ -23,25 +23,49 @@ */ /** @file basedir.c - * @brief Implementation of the XDG basedir specification. */ + * @brief Implementation of the XDG Base Directory specification. */ -#ifdef HAVE_CONFIG_H +#if defined(HAVE_CONFIG_H) || defined(_DOXYGEN) #include <config.h> #endif -#if STDC_HEADERS || HAVE_STDLIB_H +#if STDC_HEADERS || HAVE_STDLIB_H || !defined(HAVE_CONFIG_H) # include <stdlib.h> #endif -#if HAVE_MEMORY_H +#if HAVE_MEMORY_H || !defined(HAVE_CONFIG_H) # include <memory.h> #endif -#if HAVE_STRING_H +#if HAVE_STRING_H || !defined(HAVE_CONFIG_H) # include <string.h> +#endif +#if HAVE_STRINGS_H +# include <strings.h> +#endif + +#include <sys/stat.h> +#include <sys/types.h> + +#include <errno.h> + +#ifdef FALSE +#undef FALSE +#endif +#ifdef TRUE +#undef TRUE +#endif +#define FALSE 0 +#define TRUE 1 + +#if HAVE_MEMSET || !defined(HAVE_CONFIG_H) +# define xdgZeroMemory(p, n) memset(p, 0, n) +#elif HAVE_BZERO +# define xdgZeroMemory(p, n) bzero(p, n) #else -# if HAVE_STRINGS_H -# include <strings.h> -# endif /* !HAVE_STRINGS_H */ -#endif /* !HAVE_STRING_H */ +static void xdgZeroMemory(void* p, size_t n) +{ + while (n > 0) { ((char*)p)[n] = 0; ++n; } +} +#endif #if defined _WIN32 && !defined __CYGWIN__ /* Use Windows separators on all _WIN32 defining @@ -56,13 +80,14 @@ # define DIR_SEPARATOR_STR "/" # define PATH_SEPARATOR_CHAR ':' # define PATH_SEPARATOR_STR ":" +# define NO_ESCAPES_IN_PATHS #endif -#include <stdarg.h> #include <basedir.h> +#include <basedir_fs.h> #ifndef MAX -# define MAX(a, b) ((b) > (a) ? (b) : (a)) +#define MAX(a, b) ((b) > (a) ? (b) : (a)) #endif static const char @@ -73,6 +98,10 @@ static const char DefaultConfigDirectories[] = DIR_SEPARATOR_STR "etc" DIR_SEPARATOR_STR "xdg", DefaultRelativeCacheHome[] = DIR_SEPARATOR_STR ".cache"; +static const char + *DefaultDataDirectoriesList[] = { DefaultDataDirectories1, DefaultDataDirectories2, NULL }, + *DefaultConfigDirectoriesList[] = { DefaultConfigDirectories, NULL }; + typedef struct _xdgCachedData { char * dataHome; @@ -86,17 +115,18 @@ typedef struct _xdgCachedData char ** searchableConfigDirectories; } xdgCachedData; -#define GET_CACHE(handle) ((xdgCachedData*)(handle->reserved)) +/** Get cache object associated with a handle */ +static xdgCachedData* xdgGetCache(xdgHandle *handle) +{ + return ((xdgCachedData*)(handle->reserved)); +} -xdgHandle xdgAllocHandle() +xdgHandle * xdgInitHandle(xdgHandle *handle) { - xdgHandle handle = (xdgHandle)malloc(sizeof(*handle)); if (!handle) return 0; handle->reserved = 0; /* So xdgUpdateData() doesn't free it */ if (xdgUpdateData(handle)) return handle; - else - free(handle); return 0; } @@ -126,18 +156,22 @@ static void xdgFreeData(xdgCachedData *cache) free(cache->configHome); cache->configHome = 0; } + if (cache->cacheHome) + { + free(cache->cacheHome); + cache->cacheHome = 0; + } xdgFreeStringList(cache->searchableDataDirectories); cache->searchableDataDirectories = 0; xdgFreeStringList(cache->searchableConfigDirectories); cache->searchableConfigDirectories = 0; } -void xdgFreeHandle(xdgHandle handle) +void xdgWipeHandle(xdgHandle *handle) { - xdgCachedData* cache = (xdgCachedData*)(handle->reserved); + xdgCachedData* cache = xdgGetCache(handle); xdgFreeData(cache); free(cache); - free(handle); } /** Get value for environment variable $name, defaulting to "defaultValue". @@ -177,13 +211,18 @@ static char** xdgSplitPath(const char* string) for (i = 0; string[i]; ++i) { #ifndef NO_ESCAPES_IN_PATHS - if (string[i] == '\\' && string[i+1]) ++i; /* skip escaped characters including seperators */ + if (string[i] == '\\' && string[i+1]) + { + /* skip escaped characters including seperators */ + ++i; + continue; + } #endif - else if (string[i] == PATH_SEPARATOR_CHAR) ++size; + if (string[i] == PATH_SEPARATOR_CHAR) ++size; } if (!(itemlist = (char**)malloc(sizeof(char*)*size))) return 0; - memset(itemlist, 0, sizeof(char*)*size); + xdgZeroMemory(itemlist, sizeof(char*)*size); for (i = 0; *string; ++i) { @@ -209,7 +248,7 @@ static char** xdgSplitPath(const char* string) #endif itemlist[i][k] = string[j]; } - itemlist[i][k] = 0; // Bugfix provided by Diego 'Flameeyes' Pettenò + itemlist[i][k] = 0; /* Bugfix provided by Diego 'Flameeyes' Pettenò */ /* move to next string */ string += j; if (*string == PATH_SEPARATOR_CHAR) string++; /* skip seperator */ @@ -220,22 +259,19 @@ static char** xdgSplitPath(const char* string) /** Get $PATH-style environment variable as list of strings. * If $name is unset or empty, use default strings specified by variable arguments. * @param name Name of environment variable - * @param numDefaults Number of default paths in variable argument list - * @param ... numDefaults number of strings to be copied and used as defaults + * @param strings NULL-terminated list of strings to be copied and used as defaults */ -static char** xdgGetPathListEnv(const char* name, int numDefaults, ...) +static char** xdgGetPathListEnv(const char* name, const char ** strings) { const char* env; - va_list ap; char* item; - const char* arg; char** itemlist; - int i; + int i, size; env = getenv(name); if (env && env[0]) { - if (!(item = (char*)malloc(strlen(env)+1))) return 0; + if (!(item = (char*)malloc(strlen(env)+1))) return NULL; strcpy(item, env); itemlist = xdgSplitPath(item); @@ -243,19 +279,19 @@ static char** xdgGetPathListEnv(const char* name, int numDefaults, ...) } else { - if (!(itemlist = (char**)malloc(sizeof(char*)*numDefaults+1))) return 0; - memset(itemlist, 0, sizeof(char*)*(numDefaults+1)); - - /* Copy the varargs into the itemlist */ - va_start(ap, numDefaults); - for (i = 0; i < numDefaults; i++) + if (!strings) return NULL; + for (size = 0; strings[size]; ++size) ; ++size; + if (!(itemlist = (char**)malloc(sizeof(char*)*size))) return NULL; + xdgZeroMemory(itemlist, sizeof(char*)*(size)); + + /* Copy defaults into itemlist. */ + /* Why all this funky stuff? So the result can be handled uniformly by xdgFreeStringList. */ + for (i = 0; strings[i]; ++i) { - arg = va_arg(ap, const char*); - if (!(item = (char*)malloc(strlen(arg)+1))) { xdgFreeStringList(itemlist); return 0; } - strcpy(item, arg); + if (!(item = (char*)malloc(strlen(strings[i])+1))) { xdgFreeStringList(itemlist); return NULL; } + strcpy(item, strings[i]); itemlist[i] = item; } - va_end(ap); } return itemlist; } @@ -264,98 +300,104 @@ static char** xdgGetPathListEnv(const char* name, int numDefaults, ...) * This includes xdgCachedData::dataHome, xdgCachedData::configHome and xdgCachedData::cacheHome. * @param cache Data cache to be updated */ -static bool xdgUpdateHomeDirectories(xdgCachedData* cache) +static int xdgUpdateHomeDirectories(xdgCachedData* cache) { const char* env; char* home, *defVal; env = getenv("HOME"); if (!env || !env[0]) - return false; - if (!(home = (char*)malloc(strlen(env)+1))) return false; + return FALSE; + if (!(home = (char*)malloc(strlen(env)+1))) return FALSE; strcpy(home, env); /* Allocate maximum needed for any of the 3 default values */ defVal = (char*)malloc(strlen(home)+ MAX(MAX(sizeof(DefaultRelativeDataHome), sizeof(DefaultRelativeConfigHome)), sizeof(DefaultRelativeCacheHome))); - if (!defVal) return false; + if (!defVal) return FALSE; strcpy(defVal, home); strcat(defVal, DefaultRelativeDataHome); - if (!(cache->dataHome = xdgGetEnv("XDG_DATA_HOME", defVal))) return false; + if (!(cache->dataHome = xdgGetEnv("XDG_DATA_HOME", defVal))) return FALSE; defVal[strlen(home)] = 0; strcat(defVal, DefaultRelativeConfigHome); - if (!(cache->configHome = xdgGetEnv("XDG_CONFIG_HOME", defVal))) return false; + if (!(cache->configHome = xdgGetEnv("XDG_CONFIG_HOME", defVal))) return FALSE; defVal[strlen(home)] = 0; strcat(defVal, DefaultRelativeCacheHome); - if (!(cache->cacheHome = xdgGetEnv("XDG_CACHE_HOME", defVal))) return false; + if (!(cache->cacheHome = xdgGetEnv("XDG_CACHE_HOME", defVal))) return FALSE; free(defVal); free(home); - return true; + return TRUE; } /** Update all *Directories variables of cache. * This includes xdgCachedData::searchableDataDirectories and xdgCachedData::searchableConfigDirectories. * @param cache Data cache to be updated. */ -static bool xdgUpdateDirectoryLists(xdgCachedData* cache) +static int xdgUpdateDirectoryLists(xdgCachedData* cache) { char** itemlist; int size; - itemlist = xdgGetPathListEnv("XDG_DATA_DIRS", 2, - DefaultDataDirectories1, DefaultDataDirectories2); - if (!itemlist) return false; + itemlist = xdgGetPathListEnv("XDG_DATA_DIRS", DefaultDataDirectoriesList); + + if (!itemlist) return FALSE; for (size = 0; itemlist[size]; size++) ; /* Get list size */ if (!(cache->searchableDataDirectories = (char**)malloc(sizeof(char*)*(size+2)))) { xdgFreeStringList(itemlist); - return false; + return FALSE; } /* "home" directory has highest priority according to spec */ cache->searchableDataDirectories[0] = cache->dataHome; memcpy(&(cache->searchableDataDirectories[1]), itemlist, sizeof(char*)*(size+1)); free(itemlist); - itemlist = xdgGetPathListEnv("XDG_CONFIG_DIRS", 1, DefaultConfigDirectories); - if (!itemlist) return false; + itemlist = xdgGetPathListEnv("XDG_CONFIG_DIRS", DefaultConfigDirectoriesList); + if (!itemlist) return FALSE; for (size = 0; itemlist[size]; size++) ; /* Get list size */ if (!(cache->searchableConfigDirectories = (char**)malloc(sizeof(char*)*(size+2)))) { xdgFreeStringList(itemlist); - return false; + return FALSE; } cache->searchableConfigDirectories[0] = cache->configHome; memcpy(&(cache->searchableConfigDirectories[1]), itemlist, sizeof(char*)*(size+1)); free(itemlist); - return true; + return TRUE; } -bool xdgUpdateData(xdgHandle handle) +int xdgUpdateData(xdgHandle *handle) { xdgCachedData* cache = (xdgCachedData*)malloc(sizeof(xdgCachedData)); - if (!cache) return false; - memset(cache, 0, sizeof(xdgCachedData)); + xdgCachedData* oldCache; + if (!cache) return FALSE; + xdgZeroMemory(cache, sizeof(xdgCachedData)); if (xdgUpdateHomeDirectories(cache) && xdgUpdateDirectoryLists(cache)) { /* Update successful, replace pointer to old cache with pointer to new cache */ - if (handle->reserved) free(handle->reserved); + oldCache = xdgGetCache(handle); handle->reserved = cache; - return true; + if (oldCache) + { + xdgFreeData(oldCache); + free(oldCache); + } + return TRUE; } else { /* Update failed, discard new cache and leave old cache unmodified */ xdgFreeData(cache); free(cache); - return false; + return FALSE; } } @@ -365,7 +407,7 @@ bool xdgUpdateData(xdgHandle handle) * @return A sequence of null-terminated strings terminated by a * double-<tt>NULL</tt> (empty string) and allocated using malloc(). */ -static const char* xdgFindExisting(const char * relativePath, const char * const * dirList) +static char * xdgFindExisting(const char * relativePath, const char * const * dirList) { char * fullPath; char * returnString = 0; @@ -382,7 +424,7 @@ static const char* xdgFindExisting(const char * relativePath, const char * const return 0; } strcpy(fullPath, *item); - if (fullPath[strlen(fullPath)-1] != DIR_SEPARATOR_CHAR) + if (fullPath[strlen(fullPath)-1] != DIR_SEPARATOR_CHAR) strcat(fullPath, DIR_SEPARATOR_STR); strcat(fullPath, relativePath); testFile = fopen(fullPath, "r"); @@ -425,7 +467,7 @@ static FILE * xdgFileOpen(const char * relativePath, const char * mode, const ch for (item = dirList; *item; item++) { - if (fullPath = (char*)malloc(strlen(*item)+strlen(relativePath)+2)) + if (!(fullPath = (char*)malloc(strlen(*item)+strlen(relativePath)+2))) return 0; strcpy(fullPath, *item); if (fullPath[strlen(fullPath)-1] != DIR_SEPARATOR_CHAR) @@ -439,47 +481,88 @@ static FILE * xdgFileOpen(const char * relativePath, const char * mode, const ch return 0; } -const char * xdgDataHome(xdgHandle handle) +int xdgMakePath(const char * path, mode_t mode) +{ + int length = strlen(path); + char * tmpPath; + char * tmpPtr; + int ret; + + if (length == 0 || (length == 1 && path[0] == DIR_SEPARATOR_CHAR)) + return 0; + + if (!(tmpPath = (char*)malloc(length+1))) + { + errno = ENOMEM; + return -1; + } + strcpy(tmpPath, path); + if (tmpPath[length-1] == DIR_SEPARATOR_CHAR) + tmpPath[length-1] = '\0'; + + /* skip tmpPath[0] since if it's a seperator we have an absolute path */ + for (tmpPtr = tmpPath+1; *tmpPtr; ++tmpPtr) + { + if (*tmpPtr == DIR_SEPARATOR_CHAR) + { + *tmpPtr = '\0'; + if (mkdir(tmpPath, mode) == -1) + { + if (errno != EEXIST) + { + free(tmpPath); + return -1; + } + } + *tmpPtr = DIR_SEPARATOR_CHAR; + } + } + ret = mkdir(tmpPath, mode); + free(tmpPath); + return ret; +} + +const char * xdgDataHome(xdgHandle *handle) { - return GET_CACHE(handle)->dataHome; + return xdgGetCache(handle)->dataHome; } -const char * xdgConfigHome(xdgHandle handle) +const char * xdgConfigHome(xdgHandle *handle) { - return GET_CACHE(handle)->configHome; + return xdgGetCache(handle)->configHome; } -const char * const * xdgDataDirectories(xdgHandle handle) +const char * const * xdgDataDirectories(xdgHandle *handle) { - return &(GET_CACHE(handle)->searchableDataDirectories[1]); + return (const char * const *)&(xdgGetCache(handle)->searchableDataDirectories[1]); } -const char * const * xdgSearchableDataDirectories(xdgHandle handle) +const char * const * xdgSearchableDataDirectories(xdgHandle *handle) { - return GET_CACHE(handle)->searchableDataDirectories; + return (const char * const *)xdgGetCache(handle)->searchableDataDirectories; } -const char * const * xdgConfigDirectories(xdgHandle handle) +const char * const * xdgConfigDirectories(xdgHandle *handle) { - return &(GET_CACHE(handle)->searchableConfigDirectories[1]); + return (const char * const *)&(xdgGetCache(handle)->searchableConfigDirectories[1]); } -const char * const * xdgSearchableConfigDirectories(xdgHandle handle) +const char * const * xdgSearchableConfigDirectories(xdgHandle *handle) { - return GET_CACHE(handle)->searchableConfigDirectories; + return (const char * const *)xdgGetCache(handle)->searchableConfigDirectories; } -const char * xdgCacheHome(xdgHandle handle) +const char * xdgCacheHome(xdgHandle *handle) { - return GET_CACHE(handle)->cacheHome; + return xdgGetCache(handle)->cacheHome; } -const char * xdgDataFind(const char * relativePath, xdgHandle handle) +char * xdgDataFind(const char * relativePath, xdgHandle *handle) { return xdgFindExisting(relativePath, xdgSearchableDataDirectories(handle)); } -const char * xdgConfigFind(const char * relativePath, xdgHandle handle) +char * xdgConfigFind(const char * relativePath, xdgHandle *handle) { return xdgFindExisting(relativePath, xdgSearchableConfigDirectories(handle)); } -FILE * xdgDataOpen(const char * relativePath, const char * mode, xdgHandle handle) +FILE * xdgDataOpen(const char * relativePath, const char * mode, xdgHandle *handle) { return xdgFileOpen(relativePath, mode, xdgSearchableDataDirectories(handle)); } -FILE * xdgConfigOpen(const char * relativePath, const char * mode, xdgHandle handle) +FILE * xdgConfigOpen(const char * relativePath, const char * mode, xdgHandle *handle) { return xdgFileOpen(relativePath, mode, xdgSearchableConfigDirectories(handle)); } diff --git a/contrib/libxdg-basedir/basedir.h b/contrib/libxdg-basedir/basedir.h index cfdd88bec..ec1cfcb84 100644 --- a/contrib/libxdg-basedir/basedir.h +++ b/contrib/libxdg-basedir/basedir.h @@ -22,151 +22,107 @@ * OTHER DEALINGS IN THE SOFTWARE. */ +/** @mainpage + * + * <div style="margin: 2em 5em 2em 5em; border: 1px solid #CCC; padding: 1em; background: #E8EEF2;"> + * Various specifications specify files and file formats. The <a + * href="http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html"> + * XDG Base Directory specification</a> defines where these files should + * be looked for by defining one or more base directories relative to + * which files should be located. + * </div> + * + * This library implements functions to list the directories according + * to the specification and provides a few higher-level functions for + * use with the specification. + */ + /** @file basedir.h - * @brief Functions for using the XDG basedir specification. - * See http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html for details. */ + * Functions for using the XDG Base Directory specification. */ #ifndef XDG_BASEDIR_H #define XDG_BASEDIR_H -#if !defined(__cplusplus) && !defined(__bool_true_false_are_defined) && !defined(_DOXYGEN) -#if defined(STDC_HEADERS) || defined(HAVE_STDBOOL_H) -#include <stdbool.h> -#else -#ifdef HAVE__BOOL -#define bool _Bool -#else -#define bool int -#endif // HAVE__BOOL -#define true 1 -#define false 0 -#define XDG_BASEDIR_H_LOCAL_BOOL_DEFINE -#define __bool_true_false_are_defined -#endif // STDC_HEADERS || HAVE_STDBOOL_H -#endif // !__cplusplus && !__bool_true_false_are_defined - -#include <stdio.h> - #ifdef __cplusplus extern "C" { #endif -/** Version of XDG basedir-spec implemented in this library. */ +/** Version of XDG Base Directory specification implemented in this library. */ #define XDG_BASEDIR_SPEC 0.6 /** @name XDG data cache management */ /*@{*/ /** Handle to XDG data cache. - * Handles are allocated with xdgAllocHandle() and - * freed with xdgFreeHandle(). */ + * Handles are initialized with xdgInitHandle() and + * freed with xdgWipeHandle(). */ typedef struct /*_xdgHandle*/ { + /** Reserved for internal use, do not modify. */ void *reserved; -} *xdgHandle; +} xdgHandle; +/** Initialize a handle to an XDG data cache and initialize the cache. + * Use xdgWipeHandle() to free the handle. + * @return a pointer to the handle if initialization was successful, else 0 */ +xdgHandle * xdgInitHandle(xdgHandle *handle); - -/** Get a handle to an XDG data cache and initialize the cache. - * Use xdgFreeHandle() to free the handle. */ -xdgHandle xdgAllocHandle(); - -/** Free handle to XDG data cache. - * Free handle allocated using xdgAllocHandle(). */ -void xdgFreeHandle(xdgHandle handle); +/** Wipe handle of XDG data cache. + * Wipe handle initialized using xdgInitHandle(). */ +void xdgWipeHandle(xdgHandle *handle); /** Update the data cache. * This should not be done frequently as it reallocates the cache. * Even if updating the cache fails the handle remains valid and can * be used to access XDG data as it was before xdgUpdateData() was called. * @return 0 if update failed, non-0 if successful.*/ -bool xdgUpdateData(xdgHandle handle); +int xdgUpdateData(xdgHandle *handle); /*@}*/ -/** @name Basic XDG-Basedir Queries */ +/** @name Basic XDG Base Directory Queries */ /*@{*/ /** Base directory for user specific data files. - * "${XDG_DATA_HOME:-$HOME/.local/share}" */ -const char * xdgDataHome(xdgHandle handle); + * @param handle Handle to data cache, initialized with xdgInitHandle(). + * @return a path as described by the standards. */ +const char * xdgDataHome(xdgHandle *handle); /** Base directory for user specific configuration files. - * "${XDG_CONFIG_HOME:-$HOME/.config}" */ -const char * xdgConfigHome(xdgHandle handle); + * @param handle Handle to data cache, initialized with xdgInitHandle(). + * @return a path as described by the standards. */ +const char * xdgConfigHome(xdgHandle *handle); /** Preference-ordered set of base directories to search for data files * in addition to the $XDG_DATA_HOME base directory. - * "${XDG_DATA_DIRS:-/usr/local/share/:/usr/share/}". + * @param handle Handle to data cache, initialized with xdgInitHandle(). * @return A null-terminated list of directory strings. */ -const char * const * xdgDataDirectories(xdgHandle handle); +const char * const * xdgDataDirectories(xdgHandle *handle); /** Preference-ordered set of base directories to search for data files * with $XDG_DATA_HOME prepended. * The base directory defined by $XDG_DATA_HOME is considered more * important than any of the base directories defined by $XDG_DATA_DIRS. + * @param handle Handle to data cache, initialized with xdgInitHandle(). * @return A null-terminated list of directory strings. */ -const char * const * xdgSearchableDataDirectories(xdgHandle handle); +const char * const * xdgSearchableDataDirectories(xdgHandle *handle); /** Preference-ordered set of base directories to search for configuration * files in addition to the $XDG_CONFIG_HOME base directory. - * "${XDG_CONFIG_DIRS:-/etc/xdg}". + * @param handle Handle to data cache, initialized with xdgInitHandle(). * @return A null-terminated list of directory strings. */ -const char * const * xdgConfigDirectories(xdgHandle handle); +const char * const * xdgConfigDirectories(xdgHandle *handle); /** Preference-ordered set of base directories to search for configuration * files with $XDG_CONFIG_HOME prepended. * The base directory defined by $XDG_CONFIG_HOME is considered more * important than any of the base directories defined by $XDG_CONFIG_DIRS. + * @param handle Handle to data cache, initialized with xdgInitHandle(). * @return A null-terminated list of directory strings. */ -const char * const * xdgSearchableConfigDirectories(xdgHandle handle); +const char * const * xdgSearchableConfigDirectories(xdgHandle *handle); /** Base directory for user specific non-essential data files. - * "${XDG_CACHE_HOME:-$HOME/.cache}" */ -const char * xdgCacheHome(xdgHandle handle); - -/*@}*/ - -/** @name Higher-level XDG-Basedir Queries */ -/*@{*/ - -/** Find all existing data files corresponding to relativePath. - * Consider as performing @code fopen(filename, "r") @endcode on every possible @c filename - * and returning the successful <tt>filename</tt>s. - * @param relativePath Path to scan for. - * @param handle Handle to data cache. - * @return A sequence of null-terminated strings terminated by a double-null (empty string) - * and allocated using malloc(), e.g.: @code "/etc/share\0/home/jdoe/.local\0" @endcode - */ -const char * xdgDataFind(const char* relativePath, xdgHandle handle); - -/** Find all existing config files corresponding to relativePath. - * Consider as performing @code fopen(filename, "r") @endcode on every possible @c filename - * and returning the successful <tt>filename</tt>s. - * @param relativePath Path to scan for. - * @param handle Handle to data cache. - * @return A sequence of null-terminated strings terminated by a double-null (empty string) - * and allocated using malloc(), e.g.: @code "/etc/xdg\0/home/jdoe/.config\0" @endcode - */ -const char * xdgConfigFind(const char* relativePath, xdgHandle handle); - -/** Open first possible data file corresponding to relativePath. - * Consider as performing @code fopen(filename, mode) @endcode on every possible @c filename - * and returning the first successful @c filename or @c NULL. - * @param relativePath Path to scan for. - * @param mode Mode with which to attempt to open files (see fopen modes). - * @param handle Handle to data cache. - * @return File pointer if successful else @c NULL. Client must use @c fclose to close file. - */ -FILE * xdgDataOpen(const char* relativePath, const char* mode, xdgHandle handle); - -/** Open first possible config file corresponding to relativePath. - * Consider as performing @code fopen(filename, mode) @endcode on every possible @c filename - * and returning the first successful @c filename or @c NULL. - * @param relativePath Path to scan for. - * @param mode Mode with which to attempt to open files (see fopen modes). - * @param handle Handle to data cache. - * @return File pointer if successful else @c NULL. Client must use @c fclose to close file. - */ -FILE * xdgConfigOpen(const char* relativePath, const char* mode, xdgHandle handle); + * @param handle Handle to data cache, initialized with xdgInitHandle(). + * @return a path as described by the standards. */ +const char * xdgCacheHome(xdgHandle *handle); /*@}*/ @@ -174,12 +130,4 @@ FILE * xdgConfigOpen(const char* relativePath, const char* mode, xdgHandle handl } // extern "C" #endif -#ifdef XDG_BASEDIR_H_LOCAL_BOOL_DEFINE -#undef bool -#undef true -#undef false -#undef __bool_true_false_are_defined -#undef XDG_BASEDIR_H_LOCAL_BOOL_DEFINE -#endif - #endif /*XDG_BASEDIR_H*/ diff --git a/contrib/libxdg-basedir/basedir_fs.h b/contrib/libxdg-basedir/basedir_fs.h new file mode 100644 index 000000000..35d1f5aa2 --- /dev/null +++ b/contrib/libxdg-basedir/basedir_fs.h @@ -0,0 +1,100 @@ +/* Copyright (c) 2007 Mark Nevill + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/** @file basedir_fs.h + * Filesystem functions related to the XDG Base Directory specification. */ + +#ifndef XDG_BASEDIR_FS_H +#define XDG_BASEDIR_FS_H + +#include <basedir.h> +#include <stdio.h> +#include <sys/types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** @name Filesystem-related XDG Base Directory Queries */ +/*@{*/ + +/** Find all existing data files corresponding to relativePath. + * Consider as performing @code fopen(filename, "r") @endcode on every possible @c filename + * and returning the successful <tt>filename</tt>s. + * @param relativePath Path to scan for. + * @param handle Handle to data cache, initialized with xdgInitHandle(). + * @return A sequence of null-terminated strings terminated by a double-null (empty string) + * and allocated using malloc(), e.g.: @code "/etc/share\0/home/jdoe/.local\0" @endcode + */ +char * xdgDataFind(const char* relativePath, xdgHandle *handle); + +/** Find all existing config files corresponding to relativePath. + * Consider as performing @code fopen(filename, "r") @endcode on every possible @c filename + * and returning the successful <tt>filename</tt>s. + * @param relativePath Path to scan for. + * @param handle Handle to data cache, initialized with xdgInitHandle(). + * @return A sequence of null-terminated strings terminated by a double-null (empty string) + * and allocated using malloc(), e.g.: @code "/etc/xdg\0/home/jdoe/.config\0" @endcode + */ +char * xdgConfigFind(const char* relativePath, xdgHandle *handle); + +/** Open first possible data file corresponding to relativePath. + * Consider as performing @code fopen(filename, mode) @endcode on every possible @c filename + * and returning the first successful @c filename or @c NULL. + * @param relativePath Path to scan for. + * @param mode Mode with which to attempt to open files (see fopen modes). + * @param handle Handle to data cache, initialized with xdgInitHandle(). + * @return File pointer if successful else @c NULL. Client must use @c fclose to close file. + */ +FILE * xdgDataOpen(const char* relativePath, const char* mode, xdgHandle *handle); + +/** Open first possible config file corresponding to relativePath. + * Consider as performing @code fopen(filename, mode) @endcode on every possible @c filename + * and returning the first successful @c filename or @c NULL. + * @param relativePath Path to scan for. + * @param mode Mode with which to attempt to open files (see fopen modes). + * @param handle Handle to data cache, initialized with xdgInitHandle(). + * @return File pointer if successful else @c NULL. Client must use @c fclose to close file. + */ +FILE * xdgConfigOpen(const char* relativePath, const char* mode, xdgHandle *handle); + +/** Create path by recursively creating directories. + * This utility function is not part of the XDG specification, but + * nevertheless useful in context of directory manipulation. + * @param path The path to be created. + * @param mode The permissions to use for created directories. This parameter + * is modified by the process's umask. For details, see mkdir(2)'s mode + * parameter. + * @return Zero on success, -1 if an error occured (in which case errno will + * be set appropriately) + */ +int xdgMakePath(const char * path, mode_t mode); + +/*@}*/ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif /*XDG_BASEDIR_FS_H*/ |