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 *);  | 
