diff options
Diffstat (limited to 'common/gdm-config.c')
-rw-r--r-- | common/gdm-config.c | 1487 |
1 files changed, 0 insertions, 1487 deletions
diff --git a/common/gdm-config.c b/common/gdm-config.c deleted file mode 100644 index b21ab7ff..00000000 --- a/common/gdm-config.c +++ /dev/null @@ -1,1487 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" - -#include <string.h> -#include <unistd.h> -#include <stdlib.h> -#include <locale.h> -#include <syslog.h> -#include <errno.h> -#include <sys/stat.h> - -#include <glib.h> -#include <glib/gstdio.h> -#include <glib/gi18n.h> - -#include "gdm-config.h" - -struct _GdmConfig -{ - char *mandatory_filename; - char *default_filename; - char *custom_filename; - - gboolean mandatory_loaded; - gboolean default_loaded; - gboolean custom_loaded; - - GKeyFile *mandatory_key_file; - GKeyFile *default_key_file; - GKeyFile *custom_key_file; - - time_t mandatory_mtime; - time_t default_mtime; - time_t custom_mtime; - - GPtrArray *entries; - - GHashTable *value_hash; - - GdmConfigFunc validate_func; - gpointer validate_func_data; - GdmConfigFunc notify_func; - gpointer notify_func_data; -}; - - -typedef struct _GdmConfigRealValue -{ - GdmConfigValueType type; - union { - gboolean bool; - int integer; - char *str; - char **array; - } val; -} GdmConfigRealValue; - -#define REAL_VALUE(x) ((GdmConfigRealValue *)(x)) - -GQuark -gdm_config_error_quark (void) -{ - return g_quark_from_static_string ("gdm-config-error-quark"); -} - -GdmConfigEntry * -gdm_config_entry_copy (const GdmConfigEntry *src) -{ - GdmConfigEntry *dest; - - dest = g_new0 (GdmConfigEntry, 1); - dest->group = g_strdup (src->group); - dest->key = g_strdup (src->key); - dest->default_value = g_strdup (src->default_value); - dest->type = src->type; - dest->id = src->id; - - return dest; -} - -void -gdm_config_entry_free (GdmConfigEntry *entry) -{ - g_free (entry->group); - g_free (entry->key); - g_free (entry->default_value); - - g_free (entry); -} - -GdmConfigValue * -gdm_config_value_new (GdmConfigValueType type) -{ - GdmConfigValue *value; - - g_return_val_if_fail (type != GDM_CONFIG_VALUE_INVALID, NULL); - - value = (GdmConfigValue *) g_slice_new0 (GdmConfigRealValue); - value->type = type; - - return value; -} - -void -gdm_config_value_free (GdmConfigValue *value) -{ - GdmConfigRealValue *real; - - real = REAL_VALUE (value); - - switch (real->type) { - case GDM_CONFIG_VALUE_INVALID: - case GDM_CONFIG_VALUE_BOOL: - case GDM_CONFIG_VALUE_INT: - break; - case GDM_CONFIG_VALUE_STRING: - case GDM_CONFIG_VALUE_LOCALE_STRING: - g_free (real->val.str); - break; - case GDM_CONFIG_VALUE_STRING_ARRAY: - case GDM_CONFIG_VALUE_LOCALE_STRING_ARRAY: - g_strfreev (real->val.array); - break; - default: - g_assert_not_reached (); - break; - } - - g_slice_free (GdmConfigRealValue, real); -} - -static void -set_string (char **dest, - const char *src) -{ - if (*dest != NULL) { - g_free (*dest); - } - - *dest = src ? g_strdup (src) : NULL; -} - -static void -set_string_array (char ***dest, - const char **src) -{ - if (*dest != NULL) { - g_strfreev (*dest); - } - - *dest = src ? g_strdupv ((char **)src) : NULL; -} - -GdmConfigValue * -gdm_config_value_copy (const GdmConfigValue *src) -{ - GdmConfigRealValue *dest; - GdmConfigRealValue *real; - - g_return_val_if_fail (src != NULL, NULL); - - real = REAL_VALUE (src); - dest = REAL_VALUE (gdm_config_value_new (src->type)); - - switch (real->type) { - case GDM_CONFIG_VALUE_INT: - case GDM_CONFIG_VALUE_BOOL: - case GDM_CONFIG_VALUE_INVALID: - dest->val = real->val; - break; - case GDM_CONFIG_VALUE_STRING: - case GDM_CONFIG_VALUE_LOCALE_STRING: - set_string (&dest->val.str, real->val.str); - break; - case GDM_CONFIG_VALUE_STRING_ARRAY: - case GDM_CONFIG_VALUE_LOCALE_STRING_ARRAY: - set_string_array (&dest->val.array, (const char **)real->val.array); - break; - default: - g_assert_not_reached(); - } - - return (GdmConfigValue *) dest; -} - -const char * -gdm_config_value_get_string (const GdmConfigValue *value) -{ - g_return_val_if_fail (value != NULL, NULL); - g_return_val_if_fail (value->type == GDM_CONFIG_VALUE_STRING, NULL); - return REAL_VALUE (value)->val.str; -} - -const char * -gdm_config_value_get_locale_string (const GdmConfigValue *value) -{ - g_return_val_if_fail (value != NULL, NULL); - g_return_val_if_fail (value->type == GDM_CONFIG_VALUE_LOCALE_STRING, NULL); - return REAL_VALUE (value)->val.str; -} - -const char ** -gdm_config_value_get_string_array (const GdmConfigValue *value) -{ - g_return_val_if_fail (value != NULL, NULL); - g_return_val_if_fail (value->type == GDM_CONFIG_VALUE_STRING_ARRAY, NULL); - return (const char **)REAL_VALUE (value)->val.array; -} - -gboolean -gdm_config_value_get_bool (const GdmConfigValue *value) -{ - g_return_val_if_fail (value != NULL, FALSE); - g_return_val_if_fail (value->type == GDM_CONFIG_VALUE_BOOL, FALSE); - return REAL_VALUE (value)->val.bool; -} - -int -gdm_config_value_get_int (const GdmConfigValue *value) -{ - g_return_val_if_fail (value != NULL, 0); - g_return_val_if_fail (value->type == GDM_CONFIG_VALUE_INT, 0); - return REAL_VALUE (value)->val.integer; -} - -static gint -safe_strcmp (const char *a, - const char *b) -{ - return strcmp (a ? a : "", b ? b : ""); -} - -/* based on code from gconf */ -int -gdm_config_value_compare (const GdmConfigValue *value_a, - const GdmConfigValue *value_b) -{ - g_return_val_if_fail (value_a != NULL, 0); - g_return_val_if_fail (value_b != NULL, 0); - - if (value_a->type < value_b->type) { - return -1; - } else if (value_a->type > value_b->type) { - return 1; - } - - switch (value_a->type) { - case GDM_CONFIG_VALUE_INT: - if (gdm_config_value_get_int (value_a) < gdm_config_value_get_int (value_b)) { - return -1; - } else if (gdm_config_value_get_int (value_a) > gdm_config_value_get_int (value_b)) { - return 1; - } else { - return 0; - } - case GDM_CONFIG_VALUE_STRING: - return safe_strcmp (gdm_config_value_get_string (value_a), - gdm_config_value_get_string (value_b)); - case GDM_CONFIG_VALUE_LOCALE_STRING: - return safe_strcmp (gdm_config_value_get_locale_string (value_a), - gdm_config_value_get_locale_string (value_b)); - case GDM_CONFIG_VALUE_STRING_ARRAY: - case GDM_CONFIG_VALUE_LOCALE_STRING_ARRAY: - { - char *str_a; - char *str_b; - int res; - - str_a = gdm_config_value_to_string (value_a); - str_b = gdm_config_value_to_string (value_a); - res = safe_strcmp (str_a, str_b); - g_free (str_a); - g_free (str_b); - - return res; - } - case GDM_CONFIG_VALUE_BOOL: - if (gdm_config_value_get_bool (value_a) == gdm_config_value_get_bool (value_b)) { - return 0; - } else if (gdm_config_value_get_bool (value_a)) { - return 1; - } else { - return -1; - } - case GDM_CONFIG_VALUE_INVALID: - default: - g_assert_not_reached (); - break; - } - - return 0; -} - -/* based on code from gconf */ -GdmConfigValue * -gdm_config_value_new_from_string (GdmConfigValueType type, - const char *value_str, - GError **error) -{ - GdmConfigValue *value; - - g_return_val_if_fail (type != GDM_CONFIG_VALUE_INVALID, NULL); - g_return_val_if_fail (value_str != NULL, NULL); - - value = gdm_config_value_new (type); - - switch (value->type) { - case GDM_CONFIG_VALUE_INT: - { - char* endptr = NULL; - glong result; - - errno = 0; - result = strtol (value_str, &endptr, 10); - if (endptr == value_str) { - g_set_error (error, - GDM_CONFIG_ERROR, - GDM_CONFIG_ERROR_PARSE_ERROR, - _("Didn't understand `%s' (expected integer)"), - value_str); - gdm_config_value_free (value); - value = NULL; - } else if (errno == ERANGE) { - g_set_error (error, - GDM_CONFIG_ERROR, - GDM_CONFIG_ERROR_PARSE_ERROR, - _("Integer `%s' is too large or small"), - value_str); - gdm_config_value_free (value); - value = NULL; - } else { - gdm_config_value_set_int (value, result); - } - } - break; - case GDM_CONFIG_VALUE_BOOL: - switch (*value_str) { - case 't': - case 'T': - case '1': - case 'y': - case 'Y': - gdm_config_value_set_bool (value, TRUE); - break; - - case 'f': - case 'F': - case '0': - case 'n': - case 'N': - gdm_config_value_set_bool (value, FALSE); - break; - default: - g_set_error (error, - GDM_CONFIG_ERROR, - GDM_CONFIG_ERROR_PARSE_ERROR, - _("Didn't understand `%s' (expected true or false)"), - value_str); - gdm_config_value_free (value); - value = NULL; - break; - } - break; - case GDM_CONFIG_VALUE_STRING: - if (! g_utf8_validate (value_str, -1, NULL)) { - g_set_error (error, - GDM_CONFIG_ERROR, - GDM_CONFIG_ERROR_PARSE_ERROR, - _("Text contains invalid UTF-8")); - gdm_config_value_free (value); - value = NULL; - } else { - gdm_config_value_set_string (value, value_str); - } - break; - case GDM_CONFIG_VALUE_LOCALE_STRING: - if (! g_utf8_validate (value_str, -1, NULL)) { - g_set_error (error, - GDM_CONFIG_ERROR, - GDM_CONFIG_ERROR_PARSE_ERROR, - _("Text contains invalid UTF-8")); - gdm_config_value_free (value); - value = NULL; - } else { - gdm_config_value_set_locale_string (value, value_str); - } - break; - case GDM_CONFIG_VALUE_STRING_ARRAY: - if (! g_utf8_validate (value_str, -1, NULL)) { - g_set_error (error, - GDM_CONFIG_ERROR, - GDM_CONFIG_ERROR_PARSE_ERROR, - _("Text contains invalid UTF-8")); - gdm_config_value_free (value); - value = NULL; - } else { - char **split; - split = g_strsplit (value_str, ";", -1); - gdm_config_value_set_string_array (value, (const char **)split); - g_strfreev (split); - } - break; - case GDM_CONFIG_VALUE_LOCALE_STRING_ARRAY: - if (! g_utf8_validate (value_str, -1, NULL)) { - g_set_error (error, - GDM_CONFIG_ERROR, - GDM_CONFIG_ERROR_PARSE_ERROR, - _("Text contains invalid UTF-8")); - gdm_config_value_free (value); - value = NULL; - } else { - char **split; - split = g_strsplit (value_str, ";", -1); - gdm_config_value_set_locale_string_array (value, (const char **)split); - g_strfreev (split); - } - break; - case GDM_CONFIG_VALUE_INVALID: - default: - g_assert_not_reached (); - break; - } - - return value; -} - -void -gdm_config_value_set_string_array (GdmConfigValue *value, - const char **array) -{ - GdmConfigRealValue *real; - - g_return_if_fail (value != NULL); - g_return_if_fail (value->type == GDM_CONFIG_VALUE_STRING_ARRAY); - - real = REAL_VALUE (value); - - g_strfreev (real->val.array); - real->val.array = g_strdupv ((char **)array); -} - -void -gdm_config_value_set_locale_string_array (GdmConfigValue *value, - const char **array) -{ - GdmConfigRealValue *real; - - g_return_if_fail (value != NULL); - g_return_if_fail (value->type == GDM_CONFIG_VALUE_LOCALE_STRING_ARRAY); - - real = REAL_VALUE (value); - - g_strfreev (real->val.array); - real->val.array = g_strdupv ((char **)array); -} - -void -gdm_config_value_set_int (GdmConfigValue *value, - int integer) -{ - GdmConfigRealValue *real; - - g_return_if_fail (value != NULL); - g_return_if_fail (value->type == GDM_CONFIG_VALUE_INT); - - real = REAL_VALUE (value); - - real->val.integer = integer; -} - -void -gdm_config_value_set_bool (GdmConfigValue *value, - gboolean bool) -{ - GdmConfigRealValue *real; - - g_return_if_fail (value != NULL); - g_return_if_fail (value->type == GDM_CONFIG_VALUE_BOOL); - - real = REAL_VALUE (value); - - real->val.bool = bool; -} - -void -gdm_config_value_set_string (GdmConfigValue *value, - const char *str) -{ - GdmConfigRealValue *real; - - g_return_if_fail (value != NULL); - g_return_if_fail (value->type == GDM_CONFIG_VALUE_STRING); - - real = REAL_VALUE (value); - - g_free (real->val.str); - real->val.str = g_strdup (str); -} - -void -gdm_config_value_set_locale_string (GdmConfigValue *value, - const char *str) -{ - GdmConfigRealValue *real; - - g_return_if_fail (value != NULL); - g_return_if_fail (value->type == GDM_CONFIG_VALUE_LOCALE_STRING); - - real = REAL_VALUE (value); - - g_free (real->val.str); - real->val.str = g_strdup (str); -} - -char * -gdm_config_value_to_string (const GdmConfigValue *value) -{ - GdmConfigRealValue *real; - char *ret; - - g_return_val_if_fail (value != NULL, NULL); - - ret = NULL; - real = REAL_VALUE (value); - - switch (real->type) { - case GDM_CONFIG_VALUE_INVALID: - break; - case GDM_CONFIG_VALUE_BOOL: - ret = real->val.bool ? g_strdup ("true") : g_strdup ("false"); - break; - case GDM_CONFIG_VALUE_INT: - ret = g_strdup_printf ("%d", real->val.integer); - break; - case GDM_CONFIG_VALUE_STRING: - case GDM_CONFIG_VALUE_LOCALE_STRING: - ret = g_strdup (real->val.str); - break; - case GDM_CONFIG_VALUE_STRING_ARRAY: - case GDM_CONFIG_VALUE_LOCALE_STRING_ARRAY: - ret = g_strjoinv (";", real->val.array); - break; - default: - g_assert_not_reached (); - break; - } - return ret; -} - -static void -gdm_config_init (GdmConfig *config) -{ - config->entries = g_ptr_array_new (); - config->value_hash = g_hash_table_new_full (g_str_hash, - g_str_equal, - (GDestroyNotify)g_free, - (GDestroyNotify)gdm_config_value_free); -} - -GdmConfig * -gdm_config_new (void) -{ - GdmConfig *config; - - config = g_slice_new0 (GdmConfig); - gdm_config_init (config); - - return config; -} - -void -gdm_config_free (GdmConfig *config) -{ - g_return_if_fail (config != NULL); - - g_ptr_array_foreach (config->entries, (GFunc)gdm_config_entry_free, NULL); - g_ptr_array_free (config->entries, TRUE); - - g_free (config->mandatory_filename); - g_free (config->default_filename); - g_free (config->custom_filename); - - if (config->mandatory_key_file != NULL) { - g_key_file_free (config->mandatory_key_file); - } - if (config->default_key_file != NULL) { - g_key_file_free (config->default_key_file); - } - if (config->custom_key_file != NULL) { - g_key_file_free (config->custom_key_file); - } - if (config->value_hash != NULL) { - g_hash_table_destroy (config->value_hash); - } - - g_slice_free (GdmConfig, config); -} - -const GdmConfigEntry * -gdm_config_lookup_entry (GdmConfig *config, - const char *group, - const char *key) -{ - int i; - const GdmConfigEntry *entry; - - g_return_val_if_fail (config != NULL, NULL); - g_return_val_if_fail (group != NULL, NULL); - g_return_val_if_fail (key != NULL, NULL); - - entry = NULL; - - for (i = 0; i < config->entries->len; i++) { - GdmConfigEntry *this; - this = g_ptr_array_index (config->entries, i); - if (strcmp (this->group, group) == 0 - && strcmp (this->key, key) == 0) { - entry = (const GdmConfigEntry *)this; - break; - } - } - - return entry; -} - -const GdmConfigEntry * -gdm_config_lookup_entry_for_id (GdmConfig *config, - int id) -{ - int i; - const GdmConfigEntry *entry; - - g_return_val_if_fail (config != NULL, NULL); - - entry = NULL; - - for (i = 0; i < config->entries->len; i++) { - GdmConfigEntry *this; - this = g_ptr_array_index (config->entries, i); - if (this->id == id) { - entry = (const GdmConfigEntry *)this; - break; - } - } - - return entry; -} - -void -gdm_config_add_entry (GdmConfig *config, - const GdmConfigEntry *entry) -{ - GdmConfigEntry *new_entry; - - g_return_if_fail (config != NULL); - g_return_if_fail (entry != NULL); - - new_entry = gdm_config_entry_copy (entry); - g_ptr_array_add (config->entries, new_entry); -} - -void -gdm_config_add_static_entries (GdmConfig *config, - const GdmConfigEntry *entries) -{ - int i; - - g_return_if_fail (config != NULL); - g_return_if_fail (entries != NULL); - - for (i = 0; entries[i].group != NULL; i++) { - gdm_config_add_entry (config, &entries[i]); - } -} - -void -gdm_config_set_validate_func (GdmConfig *config, - GdmConfigFunc func, - gpointer data) -{ - g_return_if_fail (config != NULL); - - config->validate_func = func; - config->validate_func_data = data; -} - -void -gdm_config_set_mandatory_file (GdmConfig *config, - const char *name) -{ - g_return_if_fail (config != NULL); - - g_free (config->mandatory_filename); - config->mandatory_filename = g_strdup (name); -} - -void -gdm_config_set_default_file (GdmConfig *config, - const char *name) -{ - g_return_if_fail (config != NULL); - - g_free (config->default_filename); - config->default_filename = g_strdup (name); -} - -void -gdm_config_set_custom_file (GdmConfig *config, - const char *name) -{ - g_return_if_fail (config != NULL); - - g_free (config->custom_filename); - config->custom_filename = g_strdup (name); -} - -void -gdm_config_set_notify_func (GdmConfig *config, - GdmConfigFunc func, - gpointer data) -{ - g_return_if_fail (config != NULL); - - config->notify_func = func; - config->notify_func_data = data; -} - -static gboolean -key_file_get_value (GdmConfig *config, - GKeyFile *key_file, - const char *group, - const char *key, - GdmConfigValueType type, - GdmConfigValue **valuep) -{ - char *val; - GError *error; - GdmConfigValue *value; - gboolean ret; - - ret = FALSE; - value = NULL; - - error = NULL; - if (type == GDM_CONFIG_VALUE_LOCALE_STRING || - type == GDM_CONFIG_VALUE_LOCALE_STRING_ARRAY) { - /* Use NULL locale to detect current locale */ - val = g_key_file_get_locale_string (key_file, - group, - key, - NULL, - &error); - g_debug ("Loading locale string: %s %s", key, val ? val : "(null)"); - - if (error != NULL) { - g_debug ("%s", error->message); - g_error_free (error); - } - if (val == NULL) { - error = NULL; - val = g_key_file_get_value (key_file, - group, - key, - &error); - g_debug ("Loading non-locale string: %s %s", key, val ? val : "(null)"); - } - } else { - val = g_key_file_get_value (key_file, - group, - key, - &error); - } - - if (error != NULL) { - g_error_free (error); - goto out; - } - - if (val == NULL) { - goto out; - } - - error = NULL; - value = gdm_config_value_new_from_string (type, val, &error); - if (error != NULL) { - g_warning ("%s", error->message); - g_error_free (error); - goto out; - } - - ret = TRUE; - - out: - *valuep = value; - - return ret; -} - -static void -entry_get_default_value (GdmConfig *config, - const GdmConfigEntry *entry, - GdmConfigValue **valuep) -{ - GdmConfigValue *value; - GError *error; - - error = NULL; - value = gdm_config_value_new_from_string (entry->type, - entry->default_value ? entry->default_value : "", - &error); - if (error != NULL) { - g_warning ("%s", error->message); - g_error_free (error); - } - - *valuep = value; -} - -static gboolean -load_value_entry (GdmConfig *config, - const GdmConfigEntry *entry, - GdmConfigValue **valuep, - GdmConfigSourceType *sourcep) -{ - GdmConfigValue *value; - GdmConfigSourceType source; - gboolean ret; - gboolean res; - - value = NULL; - - /* Look for the first occurence of the key in: - mandatory file, custom file, default file, or built-in-default - */ - - if (config->mandatory_filename != NULL) { - source = GDM_CONFIG_SOURCE_MANDATORY; - res = key_file_get_value (config, - config->mandatory_key_file, - entry->group, - entry->key, - entry->type, - &value); - if (res) { - goto done; - } - } - if (config->custom_filename != NULL) { - source = GDM_CONFIG_SOURCE_CUSTOM; - res = key_file_get_value (config, - config->custom_key_file, - entry->group, - entry->key, - entry->type, - &value); - if (res) { - goto done; - } - } - if (config->default_filename != NULL) { - source = GDM_CONFIG_SOURCE_DEFAULT; - res = key_file_get_value (config, - config->default_key_file, - entry->group, - entry->key, - entry->type, - &value); - if (res) { - goto done; - } - } - - - source = GDM_CONFIG_SOURCE_BUILT_IN; - entry_get_default_value (config, entry, &value); - - done: - - if (value != NULL) { - ret = TRUE; - } else { - ret = FALSE; - } - - *valuep = value; - *sourcep = source; - - return ret; -} - -static int -lookup_id_for_key (GdmConfig *config, - const char *group, - const char *key) -{ - int id; - const GdmConfigEntry *entry; - - id = GDM_CONFIG_INVALID_ID; - entry = gdm_config_lookup_entry (config, group, key); - if (entry != NULL) { - id = entry->id; - } - - return id; -} - -static void -internal_set_value (GdmConfig *config, - GdmConfigSourceType source, - const char *group, - const char *key, - GdmConfigValue *value) -{ - char *key_path; - int id; - GdmConfigValue *v; - gboolean res; - - g_return_if_fail (config != NULL); - - key_path = g_strdup_printf ("%s/%s", group, key); - - v = NULL; - res = g_hash_table_lookup_extended (config->value_hash, - key_path, - NULL, - (gpointer *)&v); - - if (res) { - if (v != NULL && gdm_config_value_compare (v, value) == 0) { - /* value is the same - don't update */ - goto out; - } - } - - g_hash_table_insert (config->value_hash, - g_strdup (key_path), - gdm_config_value_copy (value)); - - id = lookup_id_for_key (config, group, key); - - if (config->notify_func) { - (* config->notify_func) (config, source, group, key, value, id, config->notify_func_data); - } - out: - g_free (key_path); -} - -static void -store_entry_value (GdmConfig *config, - const GdmConfigEntry *entry, - GdmConfigSourceType source, - GdmConfigValue *value) -{ - internal_set_value (config, source, entry->group, entry->key, value); -} - -static gboolean -load_entry (GdmConfig *config, - const GdmConfigEntry *entry) -{ - GdmConfigValue *value; - GdmConfigSourceType source; - gboolean res; - - value = NULL; - source = GDM_CONFIG_SOURCE_INVALID; - - res = load_value_entry (config, entry, &value, &source); - if (!res) { - return FALSE; - } - - res = TRUE; - if (config->validate_func) { - res = (* config->validate_func) (config, source, entry->group, entry->key, value, entry->id, config->validate_func_data); - } - - if (res) { - /* store runs notify */ - store_entry_value (config, entry, source, value); - } - - return TRUE; -} - -static void -add_keys_to_hash (GKeyFile *key_file, - const char *group_name, - GHashTable *hash) -{ - GError *local_error; - char **keys; - gsize len; - int i; - - local_error = NULL; - len = 0; - keys = g_key_file_get_keys (key_file, - group_name, - &len, - &local_error); - if (local_error != NULL) { - g_error_free (local_error); - return; - } - - for (i = 0; i < len; i++) { - g_hash_table_insert (hash, keys[i], GINT_TO_POINTER (1)); - } -} - -static void -collect_hash_keys (const char *key, - gpointer value, - GPtrArray **array) -{ - g_message ("Adding %s", key); - g_ptr_array_add (*array, g_strdup (key)); -} - -char ** -gdm_config_get_keys_for_group (GdmConfig *config, - const char *group, - gsize *length, - GError **error) -{ - GHashTable *hash; - gsize len; - GPtrArray *array; - - hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - - if (config->mandatory_filename != NULL) { - add_keys_to_hash (config->mandatory_key_file, group, hash); - } - - if (config->default_filename != NULL) { - add_keys_to_hash (config->default_key_file, group, hash); - } - - if (config->custom_filename != NULL) { - add_keys_to_hash (config->custom_key_file, group, hash); - } - - len = g_hash_table_size (hash); - array = g_ptr_array_sized_new (len); - - g_hash_table_foreach (hash, (GHFunc)collect_hash_keys, &array); - g_ptr_array_add (array, NULL); - - g_hash_table_destroy (hash); - - if (length != NULL) { - *length = array->len - 1; - } - - return (char **)g_ptr_array_free (array, FALSE); -} - -static gboolean -load_backend (GdmConfig *config, - const char *filename, - GKeyFile **key_file, - time_t *mtime) -{ - GError *local_error; - gboolean res; - gboolean ret; - struct stat statbuf; - GKeyFile *kf; - time_t lmtime; - - if (filename == NULL) { - return FALSE; - } - - if (g_stat (filename, &statbuf) != 0) { - return FALSE; - } - lmtime = statbuf.st_mtime; - - /* if already loaded check whether reload is necessary */ - if (*key_file != NULL) { - if (lmtime > *mtime) { - /* needs an update */ - g_key_file_free (*key_file); - } else { - /* no reload necessary so we're done */ - return TRUE; - } - } - - kf = g_key_file_new (); - - local_error = NULL; - res = g_key_file_load_from_file (kf, - filename, - G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, - &local_error); - if (! res) { - g_error_free (local_error); - g_key_file_free (kf); - kf = NULL; - lmtime = 0; - ret = FALSE; - } else { - ret = TRUE; - } - - *key_file = kf; - *mtime = lmtime; - - return ret; -} - -gboolean -gdm_config_load (GdmConfig *config, - GError **error) -{ - g_return_val_if_fail (config != NULL, FALSE); - - config->mandatory_loaded = load_backend (config, - config->mandatory_filename, - &config->mandatory_key_file, - &config->mandatory_mtime); - config->default_loaded = load_backend (config, - config->default_filename, - &config->default_key_file, - &config->default_mtime); - config->custom_loaded = load_backend (config, - config->custom_filename, - &config->custom_key_file, - &config->custom_mtime); - - return TRUE; -} - -static gboolean -process_entries (GdmConfig *config, - const GdmConfigEntry **entries, - gsize n_entries, - GError **error) -{ - gboolean ret; - int i; - - ret = TRUE; - - for (i = 0; i < n_entries; i++) { - load_entry (config, entries[i]); - } - - return ret; -} - -gboolean -gdm_config_process_entry (GdmConfig *config, - const GdmConfigEntry *entry, - GError **error) -{ - gboolean ret; - - g_return_val_if_fail (config != NULL, FALSE); - g_return_val_if_fail (entry != NULL, FALSE); - - ret = load_entry (config, entry); - - return ret; -} - -gboolean -gdm_config_process_entries (GdmConfig *config, - const GdmConfigEntry **entries, - gsize n_entries, - GError **error) -{ - gboolean ret; - - g_return_val_if_fail (config != NULL, FALSE); - g_return_val_if_fail (entries != NULL, FALSE); - g_return_val_if_fail (n_entries > 0, FALSE); - - ret = process_entries (config, entries, n_entries, error); - - return ret; -} - -gboolean -gdm_config_process_all (GdmConfig *config, - GError **error) -{ - gboolean ret; - - g_return_val_if_fail (config != NULL, FALSE); - - ret = process_entries (config, - (const GdmConfigEntry **)config->entries->pdata, - config->entries->len, - error); - - return ret; -} - -gboolean -gdm_config_peek_value (GdmConfig *config, - const char *group, - const char *key, - const GdmConfigValue **valuep) -{ - gboolean ret; - char *key_path; - const GdmConfigValue *value; - - g_return_val_if_fail (config != NULL, FALSE); - - key_path = g_strdup_printf ("%s/%s", group, key); - value = NULL; - ret = g_hash_table_lookup_extended (config->value_hash, - key_path, - NULL, - (gpointer *)&value); - g_free (key_path); - - if (valuep != NULL) { - if (ret) { - *valuep = value; - } else { - *valuep = NULL; - } - } - - return ret; -} - -gboolean -gdm_config_get_value (GdmConfig *config, - const char *group, - const char *key, - GdmConfigValue **valuep) -{ - gboolean res; - const GdmConfigValue *value; - - res = gdm_config_peek_value (config, group, key, &value); - if (valuep != NULL) { - *valuep = (value == NULL) ? NULL : gdm_config_value_copy (value); - } - - return res; -} - -gboolean -gdm_config_set_value (GdmConfig *config, - const char *group, - const char *key, - GdmConfigValue *value) -{ - g_return_val_if_fail (config != NULL, FALSE); - g_return_val_if_fail (group != NULL, FALSE); - g_return_val_if_fail (key != NULL, FALSE); - g_return_val_if_fail (value != NULL, FALSE); - - internal_set_value (config, GDM_CONFIG_SOURCE_RUNTIME_USER, group, key, value); - - return TRUE; -} - -static gboolean -gdm_config_peek_value_for_id (GdmConfig *config, - int id, - const GdmConfigValue **valuep) -{ - const GdmConfigEntry *entry; - - g_return_val_if_fail (config != NULL, FALSE); - - entry = gdm_config_lookup_entry_for_id (config, id); - if (entry == NULL) { - return FALSE; - } - - return gdm_config_peek_value (config, entry->group, entry->key, valuep); -} - -gboolean -gdm_config_get_value_for_id (GdmConfig *config, - int id, - GdmConfigValue **valuep) -{ - const GdmConfigEntry *entry; - - g_return_val_if_fail (config != NULL, FALSE); - - entry = gdm_config_lookup_entry_for_id (config, id); - if (entry == NULL) { - return FALSE; - } - - return gdm_config_get_value (config, entry->group, entry->key, valuep); -} - -gboolean -gdm_config_set_value_for_id (GdmConfig *config, - int id, - GdmConfigValue *valuep) -{ - const GdmConfigEntry *entry; - - g_return_val_if_fail (config != NULL, FALSE); - - entry = gdm_config_lookup_entry_for_id (config, id); - if (entry == NULL) { - return FALSE; - } - - return gdm_config_set_value (config, entry->group, entry->key, valuep); -} - -gboolean -gdm_config_peek_string_for_id (GdmConfig *config, - int id, - const char **strp) -{ - const GdmConfigValue *value; - const char *str; - gboolean res; - - g_return_val_if_fail (config != NULL, FALSE); - - res = gdm_config_peek_value_for_id (config, id, &value); - if (! res) { - return FALSE; - } - - str = gdm_config_value_get_string (value); - if (strp != NULL) { - *strp = str; - } - - return res; -} - -gboolean -gdm_config_get_string_for_id (GdmConfig *config, - int id, - char **strp) -{ - gboolean res; - const char *str; - - res = gdm_config_peek_string_for_id (config, id, &str); - if (strp != NULL) { - *strp = g_strdup (str); - } - - return res; -} - -gboolean -gdm_config_get_bool_for_id (GdmConfig *config, - int id, - gboolean *boolp) -{ - GdmConfigValue *value; - gboolean bool; - gboolean res; - - g_return_val_if_fail (config != NULL, FALSE); - - res = gdm_config_get_value_for_id (config, id, &value); - if (! res) { - return FALSE; - } - - bool = gdm_config_value_get_bool (value); - if (boolp != NULL) { - *boolp = bool; - } - - gdm_config_value_free (value); - - return res; -} - -gboolean -gdm_config_get_int_for_id (GdmConfig *config, - int id, - int *integerp) -{ - GdmConfigValue *value; - gboolean integer; - gboolean res; - - g_return_val_if_fail (config != NULL, FALSE); - - res = gdm_config_get_value_for_id (config, id, &value); - if (! res) { - return FALSE; - } - - integer = gdm_config_value_get_int (value); - if (integerp != NULL) { - *integerp = integer; - } - - gdm_config_value_free (value); - - return res; -} - -gboolean -gdm_config_set_string_for_id (GdmConfig *config, - int id, - char *str) -{ - GdmConfigValue *value; - gboolean res; - - g_return_val_if_fail (config != NULL, FALSE); - - value = gdm_config_value_new (GDM_CONFIG_VALUE_STRING); - gdm_config_value_set_string (value, str); - - res = gdm_config_set_value_for_id (config, id, value); - gdm_config_value_free (value); - - return res; -} - -gboolean -gdm_config_set_bool_for_id (GdmConfig *config, - int id, - gboolean bool) -{ - GdmConfigValue *value; - gboolean res; - - g_return_val_if_fail (config != NULL, FALSE); - - value = gdm_config_value_new (GDM_CONFIG_VALUE_BOOL); - gdm_config_value_set_bool (value, bool); - - res = gdm_config_set_value_for_id (config, id, value); - gdm_config_value_free (value); - - return res; -} - -gboolean -gdm_config_set_int_for_id (GdmConfig *config, - int id, - int integer) -{ - GdmConfigValue *value; - gboolean res; - - g_return_val_if_fail (config != NULL, FALSE); - - value = gdm_config_value_new (GDM_CONFIG_VALUE_INT); - gdm_config_value_set_int (value, integer); - - res = gdm_config_set_value_for_id (config, id, value); - gdm_config_value_free (value); - - return res; -} |