From 9ee502417ce58ab161b86ecca91b954663ca1b31 Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Mon, 17 Mar 2014 22:05:57 -0400 Subject: Move config loading into one function; move that function into libcommon; call it from liblightdm too --- common/Makefile.am | 4 +- common/configuration.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++++ common/configuration.h | 2 + 3 files changed, 123 insertions(+), 1 deletion(-) (limited to 'common') diff --git a/common/Makefile.am b/common/Makefile.am index f289e6ac..b501f221 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -14,7 +14,9 @@ libcommon_la_SOURCES = \ libcommon_la_CFLAGS = \ $(WARN_CFLAGS) \ - $(GLIB_CFLAGS) + $(GLIB_CFLAGS) \ + -DCONFIG_DIR=\"$(sysconfdir)/lightdm\" \ + -DSYSTEM_CONFIG_DIR=\"$(pkgdatadir)/lightdm.conf.d\" libcommon_la_LIBADD = \ $(GLIB_LDFLAGS) diff --git a/common/configuration.c b/common/configuration.c index 8ced3642..015d2fc4 100644 --- a/common/configuration.c +++ b/common/configuration.c @@ -9,6 +9,8 @@ * license. */ +#include + #include "configuration.h" struct ConfigurationPrivate @@ -70,6 +72,122 @@ config_load_from_file (Configuration *config, const gchar *path, GError **error) return TRUE; } +static gchar * +path_make_absolute (gchar *path) +{ + gchar *cwd, *abs_path; + + if (!path) + return NULL; + + if (g_path_is_absolute (path)) + return path; + + cwd = g_get_current_dir (); + abs_path = g_build_filename (cwd, path, NULL); + g_free (path); + + return abs_path; +} + +static int +compare_strings (gconstpointer a, gconstpointer b) +{ + return strcmp (a, b); +} + +static void +load_config_directory (const gchar *path, GList **messages) +{ + GDir *dir; + GList *files = NULL, *link; + GError *error = NULL; + + /* Find configuration files */ + dir = g_dir_open (path, 0, &error); + if (error && !g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) + g_printerr ("Failed to open configuration directory %s: %s\n", path, error->message); + g_clear_error (&error); + if (dir) + { + const gchar *name; + while ((name = g_dir_read_name (dir))) + files = g_list_append (files, g_strdup (name)); + g_dir_close (dir); + } + + /* Sort alphabetically and load onto existing configuration */ + files = g_list_sort (files, compare_strings); + for (link = files; link; link = link->next) + { + gchar *filename = link->data; + gchar *conf_path; + + conf_path = g_build_filename (path, filename, NULL); + if (g_str_has_suffix (filename, ".conf")) + { + if (messages) + *messages = g_list_append (*messages, g_strdup_printf ("Loading configuration from %s", conf_path)); + config_load_from_file (config_get_instance (), conf_path, &error); + if (error && !g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) + g_printerr ("Failed to load configuration from %s: %s\n", filename, error->message); + g_clear_error (&error); + } + else + g_debug ("Ignoring configuration file %s, it does not have .conf suffix", conf_path); + g_free (conf_path); + } + g_list_free_full (files, g_free); +} + +gboolean +config_load_from_standard_locations (Configuration *config, const gchar *config_path, GList **messages) +{ + gchar *config_dir, *config_d_dir = NULL; + gboolean explicit_config = FALSE; + gboolean success = TRUE; + GError *error = NULL; + + if (config_path) + { + config_dir = g_path_get_basename (config_path); + config_dir = path_make_absolute (config_dir); + explicit_config = TRUE; + } + else + { + config_dir = g_strdup (CONFIG_DIR); + config_d_dir = g_build_filename (config_dir, "lightdm.conf.d", NULL); + config_path = g_build_filename (config_dir, "lightdm.conf", NULL); + } + config_set_string (config, "LightDM", "config-directory", config_dir); + g_free (config_dir); + + load_config_directory (SYSTEM_CONFIG_DIR, messages); + if (config_d_dir) + load_config_directory (config_d_dir, messages); + g_free (config_d_dir); + + if (messages) + *messages = g_list_append (*messages, g_strdup_printf ("Loading configuration from %s", config_path)); + if (!config_load_from_file (config, config_path, &error)) + { + gboolean is_empty; + + is_empty = error && g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT); + + if (explicit_config || !is_empty) + { + if (error) + g_printerr ("Failed to load configuration from %s: %s\n", config_path, error->message); + success = FALSE; + } + } + g_clear_error (&error); + + return success; +} + gchar ** config_get_groups (Configuration *config) { diff --git a/common/configuration.h b/common/configuration.h index cae56912..b689398e 100644 --- a/common/configuration.h +++ b/common/configuration.h @@ -38,6 +38,8 @@ Configuration *config_get_instance (void); gboolean config_load_from_file (Configuration *config, const gchar *path, GError **error); +gboolean config_load_from_standard_locations (Configuration *config, const gchar *config_path, GList **messages); + gchar **config_get_groups (Configuration *config); gchar **config_get_keys (Configuration *config, const gchar *group_name); -- cgit v1.2.1 From 4a65ff1df5a1649edf8f3f4922d1319504802be7 Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Mon, 17 Mar 2014 23:06:36 -0400 Subject: Scan XDG_DATA_DIRS and XDG_CONFIG_DIRS for config values too --- common/Makefile.am | 3 +-- common/configuration.c | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) (limited to 'common') diff --git a/common/Makefile.am b/common/Makefile.am index b501f221..4c7603c5 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -15,8 +15,7 @@ libcommon_la_SOURCES = \ libcommon_la_CFLAGS = \ $(WARN_CFLAGS) \ $(GLIB_CFLAGS) \ - -DCONFIG_DIR=\"$(sysconfdir)/lightdm\" \ - -DSYSTEM_CONFIG_DIR=\"$(pkgdatadir)/lightdm.conf.d\" + -DCONFIG_DIR=\"$(sysconfdir)/lightdm\" libcommon_la_LIBADD = \ $(GLIB_LDFLAGS) diff --git a/common/configuration.c b/common/configuration.c index 015d2fc4..524b33f4 100644 --- a/common/configuration.c +++ b/common/configuration.c @@ -140,6 +140,21 @@ load_config_directory (const gchar *path, GList **messages) g_list_free_full (files, g_free); } +static void +load_config_directories (const gchar * const *dirs, GList **messages) +{ + gint i; + + for (i = 0; dirs[i]; i++) + { + gchar *full_dir = g_build_filename (dirs[i], "lightdm", "lightdm.conf.d", NULL); + if (messages) + *messages = g_list_append (*messages, g_strdup_printf ("Loading configuration dirs from %s", full_dir)); + load_config_directory (full_dir, messages); + g_free (full_dir); + } +} + gboolean config_load_from_standard_locations (Configuration *config, const gchar *config_path, GList **messages) { @@ -148,6 +163,9 @@ config_load_from_standard_locations (Configuration *config, const gchar *config_ gboolean success = TRUE; GError *error = NULL; + load_config_directories (g_get_system_data_dirs (), messages); + load_config_directories (g_get_system_config_dirs (), messages); + if (config_path) { config_dir = g_path_get_basename (config_path); @@ -163,7 +181,6 @@ config_load_from_standard_locations (Configuration *config, const gchar *config_ config_set_string (config, "LightDM", "config-directory", config_dir); g_free (config_dir); - load_config_directory (SYSTEM_CONFIG_DIR, messages); if (config_d_dir) load_config_directory (config_d_dir, messages); g_free (config_d_dir); -- cgit v1.2.1 From 34e0db531ad1f39fc99e3e3c7b86590b74460935 Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Mon, 17 Mar 2014 23:14:51 -0400 Subject: Reverse order of directory loading for a given XDG variable --- common/configuration.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'common') diff --git a/common/configuration.c b/common/configuration.c index 524b33f4..8502d6d1 100644 --- a/common/configuration.c +++ b/common/configuration.c @@ -145,7 +145,9 @@ load_config_directories (const gchar * const *dirs, GList **messages) { gint i; - for (i = 0; dirs[i]; i++) + // Load in reverse order, because XDG_* fields are preference-ordered and + // the directories in front should override directories in back. + for (i = g_strv_length ((gchar **)dirs) - 1; i >= 0; i--) { gchar *full_dir = g_build_filename (dirs[i], "lightdm", "lightdm.conf.d", NULL); if (messages) -- cgit v1.2.1