[evolution-data-server] Bug 775640 - Autoconfig: Use GSettings keys for folders and variables
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Bug 775640 - Autoconfig: Use GSettings keys for folders and variables
- Date: Thu, 15 Dec 2016 17:40:11 +0000 (UTC)
commit 7dc99c749faf25c3debf9e44a9aa1f079e5f3154
Author: Milan Crha <mcrha redhat com>
Date: Thu Dec 15 18:39:54 2016 +0100
Bug 775640 - Autoconfig: Use GSettings keys for folders and variables
.../org.gnome.evolution-data-server.gschema.xml.in | 10 +
.../evolution-source-registry/CMakeLists.txt | 1 +
.../evolution-source-registry-autoconfig.c | 176 +++++++++++++++-----
3 files changed, 147 insertions(+), 40 deletions(-)
---
diff --git a/data/org.gnome.evolution-data-server.gschema.xml.in
b/data/org.gnome.evolution-data-server.gschema.xml.in
index 696b9aa..52d3f66 100644
--- a/data/org.gnome.evolution-data-server.gschema.xml.in
+++ b/data/org.gnome.evolution-data-server.gschema.xml.in
@@ -19,5 +19,15 @@
<_summary>GIO name of the GNetworkMonitor to use for an ENetworkMonitor instance</_summary>
<_description>When set to an unknown value, then the default GNetworkMonitor is used in the
background. A special value “always-online” is used for no network monitoring.</_description>
</key>
+ <key name="autoconfig-directory" type="s">
+ <default>''</default>
+ <_summary>A full path to a directory where .source files with preconfigured options can be
stored</_summary>
+ <_description>This directory, if filled with an existing path, is checked additionally to XDG
configure directories.</_description>
+ </key>
+ <key name="autoconfig-variables" type="as">
+ <default>['']</default>
+ <_summary>A list of variables which can be part of the autoconfig .source files</_summary>
+ <_description>Each item of the array is expected to be of the form: name=value. These variables are
checked before environment variables, but after the predefined USER, REALNAME and HOST
variables.</_description>
+ </key>
</schema>
</schemalist>
diff --git a/src/services/evolution-source-registry/CMakeLists.txt
b/src/services/evolution-source-registry/CMakeLists.txt
index b5bffc1..0a4ef55 100644
--- a/src/services/evolution-source-registry/CMakeLists.txt
+++ b/src/services/evolution-source-registry/CMakeLists.txt
@@ -54,6 +54,7 @@ endforeach(_file)
glib_compile_resources(${CMAKE_CURRENT_BINARY_DIR}/builtin evolution-source-registry-resource
evolution_source_registry evolution-source-registry-resource.xml ${builtin_sources})
set(DEPENDENCIES
+ camel
ebackend
edataserver
)
diff --git a/src/services/evolution-source-registry/evolution-source-registry-autoconfig.c
b/src/services/evolution-source-registry/evolution-source-registry-autoconfig.c
index de9461b..a6eb1bf 100644
--- a/src/services/evolution-source-registry/evolution-source-registry-autoconfig.c
+++ b/src/services/evolution-source-registry/evolution-source-registry-autoconfig.c
@@ -22,17 +22,13 @@
#include <glib/gstdio.h>
#include <libebackend/libebackend.h>
+#include <camel/camel.h>
typedef struct _MergeSourceData {
gchar *path;
GKeyFile *key_file;
} MergeSourceData;
-typedef struct _EnvVarMap {
- const gchar *from;
- const gchar *to;
-} EnvVarMap;
-
typedef void (*MergeSourcePopulateHashtableFunc)(GHashTable *source,
GKeyFile *key_file,
const gchar *basename,
@@ -194,31 +190,30 @@ evolution_source_registry_clean_orphans (GHashTable *autoconfig_sources,
g_list_free (keys);
}
+typedef struct _ReplaceVariablesData {
+ const gchar *source_path;
+ GHashTable *user_variables;
+} ReplaceVariablesData;
+
static gboolean
-evolution_source_registry_replace_env_vars_eval_cb (const GMatchInfo *match_info,
- GString *result,
- gpointer user_data)
+evolution_source_registry_replace_vars_eval_cb (const GMatchInfo *match_info,
+ GString *result,
+ gpointer user_data)
{
- gchar *var_name, *source_path;
- const gchar *val;
- gint ii;
- EnvVarMap map[] = {
- { "USER", g_get_user_name () },
- { "REALNAME", g_get_real_name () },
- { "HOST", g_get_host_name () }
- };
+ gchar *var_name;
+ const gchar *val = NULL;
+ ReplaceVariablesData *rvd = user_data;
+
+ g_return_val_if_fail (rvd != NULL, FALSE);
var_name = g_match_info_fetch (match_info, 1);
- source_path = user_data;
- for (ii = 0; ii < G_N_ELEMENTS (map); ++ii) {
- if (g_strcmp0 (var_name, map[ii].from) == 0) {
- g_string_append (result, map[ii].to);
- goto exit;
- }
- }
+ if (var_name) {
+ val = g_hash_table_lookup (rvd->user_variables, var_name);
- val = g_getenv (var_name);
+ if (!val)
+ val = g_getenv (var_name);
+ }
if (val != NULL) {
g_string_append (result, val);
@@ -227,20 +222,22 @@ evolution_source_registry_replace_env_vars_eval_cb (const GMatchInfo *match_info
e_source_registry_debug_print (
"Autoconfig: Variable '${%s}' not found, used in '%s'.\n",
var_name,
- source_path);
+ rvd->source_path);
}
- exit:
g_free (var_name);
return FALSE;
}
static gchar *
-evolution_source_registry_replace_env_vars (const gchar *old, MergeSourceData *source)
+evolution_source_registry_replace_vars (const gchar *old,
+ MergeSourceData *source,
+ GHashTable *user_variables)
{
GRegex *regex;
gchar *new;
+ ReplaceVariablesData rvd;
GError *local_error = NULL;
g_return_val_if_fail (old != NULL, NULL);
@@ -249,14 +246,17 @@ evolution_source_registry_replace_env_vars (const gchar *old, MergeSourceData *s
g_return_val_if_fail (regex != NULL, g_strdup (old));
+ rvd.source_path = source->path;
+ rvd.user_variables = user_variables;
+
new = g_regex_replace_eval (
regex,
old,
-1,
0,
0,
- evolution_source_registry_replace_env_vars_eval_cb,
- source->path,
+ evolution_source_registry_replace_vars_eval_cb,
+ &rvd,
&local_error);
g_regex_unref (regex);
@@ -274,7 +274,8 @@ evolution_source_registry_replace_env_vars (const gchar *old, MergeSourceData *s
static void
evolution_source_registry_copy_source (MergeSourceData *target,
- MergeSourceData *source)
+ MergeSourceData *source,
+ GHashTable *user_variables)
{
gchar **groups = NULL;
gsize ngroups;
@@ -301,7 +302,7 @@ evolution_source_registry_copy_source (MergeSourceData *target,
keys[jj],
NULL);
- new_val = evolution_source_registry_replace_env_vars (val, source);
+ new_val = evolution_source_registry_replace_vars (val, source, user_variables);
g_free (val);
g_key_file_set_value (
@@ -322,6 +323,7 @@ evolution_source_registry_merge_source (GHashTable *home_sources,
const gchar *key,
MergeSourceData *autoconfig_key_file,
GList **key_files_to_copy,
+ GHashTable *user_variables,
GError **error)
{
GKeyFile *new_keyfile;
@@ -403,7 +405,7 @@ evolution_source_registry_merge_source (GHashTable *home_sources,
new_data->path = g_strdup (home_key_file->path);
new_data->key_file = new_keyfile;
- evolution_source_registry_copy_source (new_data, autoconfig_key_file);
+ evolution_source_registry_copy_source (new_data, autoconfig_key_file, user_variables);
*key_files_to_copy = g_list_prepend (*key_files_to_copy, new_data);
@@ -412,8 +414,9 @@ evolution_source_registry_merge_source (GHashTable *home_sources,
static void
evolution_source_registry_generate_source_from_autoconfig (const gchar *key,
- MergeSourceData *autoconfig_key_file,
- GList **key_files_to_copy)
+ MergeSourceData *autoconfig_key_file,
+ GList **key_files_to_copy,
+ GHashTable *user_variables)
{
GKeyFile *new_keyfile;
MergeSourceData *new_data;
@@ -448,7 +451,7 @@ evolution_source_registry_generate_source_from_autoconfig (const gchar *key,
new_data->path = dest_source_path;
new_data->key_file = new_keyfile;
- evolution_source_registry_copy_source (new_data, autoconfig_key_file);
+ evolution_source_registry_copy_source (new_data, autoconfig_key_file, user_variables);
*key_files_to_copy = g_list_prepend (*key_files_to_copy, new_data);
@@ -460,7 +463,8 @@ evolution_source_registry_generate_source_from_autoconfig (const gchar *key,
static GList *
evolution_source_registry_merge_sources (GHashTable *autoconfig_sources,
- GHashTable *home_sources)
+ GHashTable *home_sources,
+ GHashTable *user_variables)
{
GHashTableIter iter;
GList *key_files_to_copy = NULL;
@@ -481,6 +485,7 @@ evolution_source_registry_merge_sources (GHashTable *autoconfig_sources,
key,
autoconfig_key_file,
&key_files_to_copy,
+ user_variables,
&local_error)) {
e_source_registry_debug_print (
"Autoconfig: evolution_source_registry_merge_source() failed:
%s.\n",
@@ -492,7 +497,8 @@ evolution_source_registry_merge_sources (GHashTable *autoconfig_sources,
evolution_source_registry_generate_source_from_autoconfig (
key,
autoconfig_key_file,
- &key_files_to_copy);
+ &key_files_to_copy,
+ user_variables);
}
}
@@ -527,17 +533,71 @@ evolution_source_registry_write_key_files (GList *list,
return TRUE;
}
+static GHashTable *
+read_user_variables (GSettings *settings)
+{
+ GHashTable *variables;
+ gchar **strv;
+ gint ii;
+
+ g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
+
+ variables = g_hash_table_new_full (camel_strcase_hash, camel_strcase_equal, g_free, g_free);
+
+ strv = g_settings_get_strv (settings, "autoconfig-variables");
+ if (!strv || !strv[0]) {
+ g_strfreev (strv);
+
+ return variables;
+ }
+
+ for (ii = 0; strv[ii]; ii++) {
+ const gchar *line = strv[ii];
+ gchar *name, *value, *sep;
+
+ sep = strchr (line, '=');
+ if (!sep || sep == line) {
+ e_source_registry_debug_print ("Autoconfig: GSettings' autoconf-variables line '%s'
doesn't conform format 'name=value'.\n", line);
+ continue;
+ }
+
+ name = g_strdup (line);
+ sep = strchr (name, '=');
+ if (!sep || sep == name) {
+ g_free (name);
+ g_warn_if_reached ();
+ continue;
+ }
+
+ *sep = '\0';
+ value = sep + 1;
+
+ if (g_hash_table_contains (variables, name))
+ e_source_registry_debug_print ("Autoconfig: GSettings' autoconf-variables key
contains multiple '%s' variables.\n", name);
+
+ g_hash_table_insert (variables, name, g_strdup (value));
+ }
+
+ g_strfreev (strv);
+
+ return variables;
+}
+
gboolean
evolution_source_registry_merge_autoconfig_sources (ESourceRegistryServer *server,
GError **error)
{
- GHashTable *home_sources = NULL, *autoconfig_sources = NULL;
+ GHashTable *home_sources = NULL, *autoconfig_sources = NULL, *user_variables = NULL;
GList *key_files_to_copy = NULL;
+ GSettings *settings;
GError *local_error = NULL;
gboolean success = FALSE;
const gchar * const *config_dirs;
+ gchar *autoconfig_directory;
gint ii;
+ settings = g_settings_new ("org.gnome.evolution-data-server");
+
autoconfig_sources = g_hash_table_new_full (
g_str_hash,
g_str_equal,
@@ -561,7 +621,7 @@ evolution_source_registry_merge_autoconfig_sources (ESourceRegistryServer *serve
if (!success) {
if (local_error != NULL &&
- g_error_matches (local_error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) {
+ g_error_matches (local_error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) {
g_clear_error (&local_error);
continue;
}
@@ -570,6 +630,31 @@ evolution_source_registry_merge_autoconfig_sources (ESourceRegistryServer *serve
}
}
+ autoconfig_directory = g_settings_get_string (settings, "autoconfig-directory");
+ if (autoconfig_directory && *autoconfig_directory) {
+ if (g_file_test (autoconfig_directory, G_FILE_TEST_IS_DIR)) {
+ success = evolution_source_registry_read_directory (
+ autoconfig_directory,
+ autoconfig_sources,
+ populate_hashtable_autoconfig,
+ &local_error);
+
+ if (!success) {
+ if (local_error != NULL &&
+ g_error_matches (local_error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) {
+ g_clear_error (&local_error);
+ } else {
+ g_free (autoconfig_directory);
+ goto exit;
+ }
+ }
+ } else {
+ e_source_registry_debug_print ("Autoconfig: GSettings' directory '%s' doesn't exist,
or it's currently unavailable. Skipping it.\n", autoconfig_directory);
+ }
+ }
+
+ g_free (autoconfig_directory);
+
home_sources = g_hash_table_new_full (
g_str_hash,
g_str_equal,
@@ -585,7 +670,15 @@ evolution_source_registry_merge_autoconfig_sources (ESourceRegistryServer *serve
if (!success)
goto exit;
- key_files_to_copy = evolution_source_registry_merge_sources (autoconfig_sources, home_sources);
+ user_variables = read_user_variables (settings);
+ g_warn_if_fail (user_variables != NULL);
+
+ /* Add these last, to override any user-specified */
+ g_hash_table_insert (user_variables, g_strdup ("USER"), g_strdup (g_get_user_name ()));
+ g_hash_table_insert (user_variables, g_strdup ("REALNAME"), g_strdup (g_get_real_name ()));
+ g_hash_table_insert (user_variables, g_strdup ("HOST"), g_strdup (g_get_host_name ()));
+
+ key_files_to_copy = evolution_source_registry_merge_sources (autoconfig_sources, home_sources,
user_variables);
success = evolution_source_registry_write_key_files (key_files_to_copy, error);
@@ -594,8 +687,11 @@ evolution_source_registry_merge_autoconfig_sources (ESourceRegistryServer *serve
g_hash_table_unref (autoconfig_sources);
if (home_sources != NULL)
g_hash_table_unref (home_sources);
+ if (user_variables)
+ g_hash_table_unref (user_variables);
if (key_files_to_copy != NULL)
g_list_free_full (key_files_to_copy, evolution_source_registry_free_merge_source_data);
+ g_clear_object (&settings);
if (local_error != NULL)
g_propagate_error (error, local_error);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]