[dconf/wip/varlib: 9/12] profiles: allow profiles in XDG_DATA_DIRS
- From: Ryan Lortie <desrt src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dconf/wip/varlib: 9/12] profiles: allow profiles in XDG_DATA_DIRS
- Date: Fri, 6 Dec 2013 20:34:36 +0000 (UTC)
commit eef709c154cc907761756ec0d3def06bdff0e692
Author: Ryan Lortie <desrt desrt ca>
Date: Sun Dec 1 23:25:33 2013 -0500
profiles: allow profiles in XDG_DATA_DIRS
If we can't find a given profile in /etc then look for it in the
XDG_DATA_DIRS.
engine/dconf-engine-profile.c | 66 ++++++++++++++++++++++++++++++++++-------
1 files changed, 55 insertions(+), 11 deletions(-)
---
diff --git a/engine/dconf-engine-profile.c b/engine/dconf-engine-profile.c
index 5dc73eb..1fbafc3 100644
--- a/engine/dconf-engine-profile.c
+++ b/engine/dconf-engine-profile.c
@@ -26,6 +26,7 @@
#include <string.h>
#include <stdio.h>
+#include <errno.h>
#include "dconf-engine-source.h"
@@ -44,8 +45,12 @@
* In both of those cases, if the named profile starts with a slash
* character then it is taken to be an absolute pathname. If it does
* not start with a slash then it is assumed to specify a profile file
- * relative to /etc/dconf/profile/ (ie: DCONF_PROFILE=test for profile
- * file /etc/dconf/profile/test).
+ * relative to /etc/dconf/profile/ or
+ * <ulink
url='http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html'>XDG_DATA_DIRS</ulink>/dconf/profile/,
+ * taking the file in /etc in preference (ie: DCONF_PROFILE=test looks
+ * first for profile file /etc/dconf/profile/test, falling back to
+ * /usr/local/share/dconf/profile/test, then to
+ * /usr/share/dconf/profile/test).
*
* If opening the profile file fails then the null profile is used.
* This is a profile that contains zero sources. All keys will be
@@ -53,9 +58,9 @@
*
* In the case that no explicit profile was given and DCONF_PROFILE is
* unset, dconf attempts to open and use a profile called "user" (ie:
- * profile file /etc/dconf/profile/user). If that fails then the
- * fallback is to act as if the profile file existed and contained a
- * single line: "user-db:user".
+ * /etc/dconf/profile/user or XDG_DATA_DIRS/dconf/profile/user). If
+ * that fails then the fallback is to act as if the profile file existed
+ * and contained a single line: "user-db:user".
*
* Note that the fallback case for a missing profile file is different
* in the case where a profile was explicitly specified (either by the
@@ -178,6 +183,49 @@ dconf_engine_read_profile_file (FILE *file,
return g_realloc_n (sources, n, sizeof (DConfEngineSource *));
}
+/* Find a profile file with the name given in 'profile' and open it. */
+static FILE *
+dconf_engine_open_profile_file (const gchar *profile)
+{
+ const gchar * const *xdg_data_dirs;
+ const gchar *prefix = "/etc";
+ FILE *fp;
+
+ xdg_data_dirs = g_get_system_data_dirs ();
+
+ /* First time through, we check "/etc", then we check XDG_DATA_DIRS,
+ * in order. We stop looking as soon as we successfully open a file
+ * or in the case that we run out of XDG_DATA_DIRS.
+ *
+ * If we hit an error other than ENOENT then we warn about that and
+ * exit immediately. We should only attempt fallback in the case that
+ * the file in the higher-precedence directory is non-existent.
+ */
+ do
+ {
+ gchar *filename;
+
+ filename = g_build_filename (prefix, "dconf/profile", profile, NULL);
+ fp = fopen (filename, "r");
+
+ /* If it wasn't ENOENT then we don't want to continue on to check
+ * other paths. Fail immediately.
+ */
+ if (fp == NULL && errno != ENOENT)
+ {
+ g_warning ("Unable to open %s: %s", filename, g_strerror (errno));
+ g_free (filename);
+ return NULL;
+ }
+
+ g_free (filename);
+ }
+ while (fp == NULL && (prefix = *xdg_data_dirs++));
+
+ /* If we didn't find it, this could be NULL. That's OK. */
+ return fp;
+}
+
DConfEngineSource **
dconf_engine_profile_open (const gchar *profile,
gint *n_sources)
@@ -190,7 +238,7 @@ dconf_engine_profile_open (const gchar *profile,
if (profile == NULL)
{
- file = fopen ("/etc/dconf/profile/user", "r");
+ file = dconf_engine_open_profile_file ("user");
/* Only in the case that no profile was specified do we use this
* fallback.
@@ -199,11 +247,7 @@ dconf_engine_profile_open (const gchar *profile,
return dconf_engine_default_profile (n_sources);
}
else if (profile[0] != '/')
- {
- gchar *filename = g_build_filename ("/etc/dconf/profile", profile, NULL);
- file = fopen (filename, "r");
- g_free (filename);
- }
+ file = dconf_engine_open_profile_file (profile);
else
file = fopen (profile, "r");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]