summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2024-06-28 16:42:56 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2024-06-28 16:42:56 (GMT)
commit21788df2799eb8976c1c68cd84abf0ffe92a7a45 (patch)
tree328acd460424011b3def91cd2d5425a5156caa53 /src
parent00452431d4fb061f20a4eaa4c93b61014f7651ef (diff)
Handle the XDG directories.
Diffstat (limited to 'src')
-rw-r--r--src/common/xdg.c338
-rw-r--r--src/common/xdg.h19
-rw-r--r--src/plugins/plugin.c2
3 files changed, 323 insertions, 36 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 *);
diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c
index 1dc20e8..75cf4e0 100644
--- a/src/plugins/plugin.c
+++ b/src/plugins/plugin.c
@@ -1203,7 +1203,7 @@ char *g_plugin_module_build_config_filename(const GPluginModule *plugin, const c
suffix = stradd(suffix, G_DIR_SEPARATOR_S);
suffix = stradd(suffix, final);
- result = get_xdg_config_dir(suffix);
+ result = get_xdg_config_dir(suffix, true);
free(suffix);
free(modname);