/* Chrysalide - Outil d'analyse de fichiers binaires * xdg.c - compléments mineurs au support Freedesktop * * Copyright (C) 2014-2018 Cyrille Bagard * * This file is part of Chrysalide. * * Chrysalide is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Chrysalide 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Chrysalide. If not, see . */ #include "xdg.h" #include #include #include #include #include #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 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_cache_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_CACHE_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(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); if (ret != 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/. * * * ******************************************************************************/ 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); result = NULL; env = getenv("XDG_CONFIG_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(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); } if (create) { ret = ensure_path_exists(result); if (ret != 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/. * * * ******************************************************************************/ 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; } } 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); strcat(result, suffix); } else { env = getenv("HOME"); 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; } /****************************************************************************** * * * 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, suffix); } return result; }