diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2024-06-28 16:42:56 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2024-06-28 16:42:56 (GMT) |
commit | 21788df2799eb8976c1c68cd84abf0ffe92a7a45 (patch) | |
tree | 328acd460424011b3def91cd2d5425a5156caa53 /src/common | |
parent | 00452431d4fb061f20a4eaa4c93b61014f7651ef (diff) |
Handle the XDG directories.
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/xdg.c | 338 | ||||
-rw-r--r-- | src/common/xdg.h | 19 |
2 files changed, 322 insertions, 35 deletions
diff --git a/src/common/xdg.c b/src/common/xdg.c index cabff75..891b6ae 100644 --- a/src/common/xdg.c +++ b/src/common/xdg.c @@ -24,20 +24,41 @@ #include "xdg.h" -#include <dirent.h> -#include <errno.h> +#include <assert.h> #include <glib.h> #include <malloc.h> -#include <stdlib.h> #include <string.h> +#include <unistd.h> + + +#include "pathname.h" + + + +/** + * Cf. https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html + */ + +/* $HOME/.cache */ +#define CACHE_HOME_SUFFIX ".cache" G_DIR_SEPARATOR_S + +/* $HOME/.config */ +#define CONFIG_HOME_SUFFIX ".config" G_DIR_SEPARATOR_S + +/* $HOME/.local/share */ +#define DATA_HOME_SUFFIX ".local" G_DIR_SEPARATOR_S "share" G_DIR_SEPARATOR_S + +/* $HOME/.local/state */ +#define STATE_HOME_SUFFIX ".local" G_DIR_SEPARATOR_S "state" G_DIR_SEPARATOR_S /****************************************************************************** * * * Paramètres : suffix = élément visé dans le répertoire de configuration. * +* create = assure la mise en place du répertoire final. * * * -* Description : Détermine le chemin d'un répertoire selon les specs. XDG. * +* Description : Détermine le chemin d'un répertoire de données XDG. * * * * Retour : Chemin d'accès aux configurations personnelles ou NULL. * * * @@ -45,70 +66,321 @@ * * ******************************************************************************/ -char *get_xdg_config_dir(const char *suffix) +char *get_xdg_cache_dir(const char *suffix, bool create) { char *result; /* Chemin d'accès à renvoyer */ const char *env; /* Valeur de l'environnement */ - DIR *directory; /* Répertoire avec contenu ? */ - struct dirent *entry; /* Elément de répertoire */ + int ret; /* Bilan d'une assurance */ + + assert(suffix[0] != G_DIR_SEPARATOR); result = NULL; - env = getenv("XDG_CONFIG_HOME"); + env = getenv("XDG_CACHE_HOME"); if (env != NULL && env[0] != '\0') { - directory = opendir(env); - if (directory == NULL) goto default_cfg_dir; + result = calloc(strlen(env) + 1 + strlen(suffix) + 1, sizeof(char)); + + strcpy(result, env); + + if (env[strlen(env) - 1] != G_DIR_SEPARATOR) + strcat(result, G_DIR_SEPARATOR_S); + + strcat(result, suffix); + + } + + else + { + env = getenv("HOME"); + if (env == NULL || env[0] == '\0') goto no_env; + + result = calloc(strlen(env) + 1 + strlen(CACHE_HOME_SUFFIX) + strlen(suffix) + 1, sizeof(char)); + + strcpy(result, env); + + if (env[strlen(env) - 1] != G_DIR_SEPARATOR) + strcat(result, G_DIR_SEPARATOR_S); + + strcat(result, CACHE_HOME_SUFFIX); + strcat(result, suffix); + + } + + if (create) + { + ret = ensure_path_exists(result); - while (1) + if (ret != 0) { - errno = 0; + free(result); + result = NULL; + } + + } + + no_env: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : suffix = élément visé dans le répertoire de configuration. * +* create = assure la mise en place du répertoire final. * +* * +* Description : Détermine le chemin d'un répertoire de données XDG. * +* * +* Retour : Chemin d'accès aux configurations personnelles ou NULL. * +* * +* Remarques : cf. http://standards.freedesktop.org/basedir-spec/. * +* * +******************************************************************************/ - entry = readdir(directory); +char *get_xdg_config_dir(const char *suffix, bool create) +{ + char *result; /* Chemin d'accès à renvoyer */ + const char *env; /* Valeur de l'environnement */ + int ret; /* Bilan d'une assurance */ + + assert(suffix[0] != G_DIR_SEPARATOR); - if (entry == NULL) - { - if (errno != 0) - perror("readdir"); + result = NULL; + + env = getenv("XDG_CONFIG_HOME"); - break; + if (env != NULL && env[0] != '\0') + { + result = calloc(strlen(env) + 1 + strlen(suffix) + 1, sizeof(char)); - } + strcpy(result, env); - if (strcmp(entry->d_name, ".") == 0) continue; - if (strcmp(entry->d_name, "..") == 0) continue; + if (env[strlen(env) - 1] != G_DIR_SEPARATOR) + strcat(result, G_DIR_SEPARATOR_S); - result = calloc(strlen(env) + 2 + strlen(suffix) + 1, sizeof(char)); - strcpy(result, env); + strcat(result, suffix); - if (env[strlen(env) - 1] != G_DIR_SEPARATOR) - strcat(result, G_DIR_SEPARATOR_S); + } + + else + { + env = getenv("HOME"); + if (env == NULL || env[0] == '\0') goto no_env; + + result = calloc(strlen(env) + 1 + strlen(CONFIG_HOME_SUFFIX) + strlen(suffix) + 1, sizeof(char)); + + strcpy(result, env); + + if (env[strlen(env) - 1] != G_DIR_SEPARATOR) + strcat(result, G_DIR_SEPARATOR_S); + + strcat(result, CONFIG_HOME_SUFFIX); + strcat(result, suffix); + + } - strcat(result, "."); - strcat(result, suffix); + if (create) + { + ret = ensure_path_exists(result); + if (ret != 0) + { + free(result); + result = NULL; } - closedir(directory); + } + + no_env: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : suffix = élément visé dans le répertoire de configuration. * +* create = assure la mise en place du répertoire final. * +* * +* Description : Détermine le chemin d'un répertoire de données XDG. * +* * +* Retour : Chemin d'accès aux configurations personnelles ou NULL. * +* * +* Remarques : cf. http://standards.freedesktop.org/basedir-spec/. * +* * +******************************************************************************/ + +char *get_xdg_data_dir(const char *suffix, bool create) +{ + char *result; /* Chemin d'accès à renvoyer */ + const char *env; /* Valeur de l'environnement */ + int ret; /* Bilan d'une assurance */ + + assert(suffix[0] != G_DIR_SEPARATOR); + + result = NULL; + + env = getenv("XDG_DATA_HOME"); + + if (env != NULL && env[0] != '\0') + { + result = calloc(strlen(env) + 1 + strlen(suffix) + 1, sizeof(char)); + + strcpy(result, env); + + if (env[strlen(env) - 1] != G_DIR_SEPARATOR) + strcat(result, G_DIR_SEPARATOR_S); + + strcat(result, suffix); + + } + + else + { + env = getenv("HOME"); + if (env == NULL || env[0] == '\0') goto no_env; + + result = calloc(strlen(env) + 1 + strlen(DATA_HOME_SUFFIX) + strlen(suffix) + 1, sizeof(char)); + + strcpy(result, env); + + if (env[strlen(env) - 1] != G_DIR_SEPARATOR) + strcat(result, G_DIR_SEPARATOR_S); + + strcat(result, DATA_HOME_SUFFIX); + strcat(result, suffix); + + } + + if (create) + { + ret = ensure_path_exists(result); + + if (ret != 0) + { + free(result); + result = NULL; + } } - default_cfg_dir: + no_env: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : suffix = élément visé dans le répertoire de configuration. * +* create = assure la mise en place du répertoire final. * +* * +* Description : Détermine le chemin d'un répertoire de données XDG. * +* * +* Retour : Chemin d'accès aux configurations personnelles ou NULL. * +* * +* Remarques : cf. http://standards.freedesktop.org/basedir-spec/. * +* * +******************************************************************************/ + +char *get_xdg_state_dir(const char *suffix, bool create) +{ + char *result; /* Chemin d'accès à renvoyer */ + const char *env; /* Valeur de l'environnement */ + int ret; /* Bilan d'une assurance */ + + assert(suffix[0] != G_DIR_SEPARATOR); + + result = NULL; + + env = getenv("XDG_STATE_HOME"); + + if (env != NULL && env[0] != '\0') + { + result = calloc(strlen(env) + 1 + strlen(suffix) + 1, sizeof(char)); + + strcpy(result, env); + + if (env[strlen(env) - 1] != G_DIR_SEPARATOR) + strcat(result, G_DIR_SEPARATOR_S); - if (result == NULL) + strcat(result, suffix); + + } + + else { env = getenv("HOME"); - if (env == NULL || env[0] == '\0') return NULL; + if (env == NULL || env[0] == '\0') goto no_env; + + result = calloc(strlen(env) + 1 + strlen(STATE_HOME_SUFFIX) + strlen(suffix) + 1, sizeof(char)); + + strcpy(result, env); + + if (env[strlen(env) - 1] != G_DIR_SEPARATOR) + strcat(result, G_DIR_SEPARATOR_S); + + strcat(result, STATE_HOME_SUFFIX); + strcat(result, suffix); + + } + + if (create) + { + ret = ensure_path_exists(result); + + if (ret != 0) + { + free(result); + result = NULL; + } + + } + + no_env: + + return result; + +} + - result = calloc(strlen(env) + 1 + strlen(".config" G_DIR_SEPARATOR_S) + strlen(suffix) + 1, sizeof(char)); +/****************************************************************************** +* * +* Paramètres : suffix = élément visé dans le répertoire de configuration. * +* * +* Description : Détermine le chemin d'un répertoire éphémère XDG. * +* * +* Retour : Chemin d'accès aux configurations personnelles ou NULL. * +* * +* Remarques : cf. http://standards.freedesktop.org/basedir-spec/. * +* * +******************************************************************************/ + +char *get_xdg_runtime_dir(const char *suffix) +{ + char *result; /* Chemin d'accès à renvoyer */ + const char *env; /* Valeur de l'environnement */ + + assert(suffix[0] != G_DIR_SEPARATOR); + + result = NULL; + + env = getenv("XDG_RUNTIME_DIR"); + + if (env != NULL && env[0] != '\0') + { + result = calloc(strlen(env) + 1 + strlen(suffix) + 1, sizeof(char)); strcpy(result, env); if (env[strlen(env) - 1] != G_DIR_SEPARATOR) strcat(result, G_DIR_SEPARATOR_S); - strcat(result, ".config" G_DIR_SEPARATOR_S); strcat(result, suffix); } diff --git a/src/common/xdg.h b/src/common/xdg.h index c9c2327..a6cd91d 100644 --- a/src/common/xdg.h +++ b/src/common/xdg.h @@ -25,9 +25,24 @@ #define _COMMON_XDG_H +#include <stdbool.h> -/* Détermine le chemin d'un répertoire selon les specs. XDG. */ -char *get_xdg_config_dir(const char *); + + +/* Détermine le chemin d'un répertoire de données XDG. */ +char *get_xdg_cache_dir(const char *, bool); + +/* Détermine le chemin d'un répertoire de données XDG. */ +char *get_xdg_config_dir(const char *, bool); + +/* Détermine le chemin d'un répertoire de données XDG. */ +char *get_xdg_data_dir(const char *, bool); + +/* Détermine le chemin d'un répertoire de données XDG. */ +char *get_xdg_state_dir(const char *, bool); + +/* Détermine le chemin d'un répertoire éphémère XDG. */ +char *get_xdg_runtime_dir(const char *); |