summaryrefslogtreecommitdiff
path: root/common/gdm-config.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/gdm-config.c')
-rw-r--r--common/gdm-config.c1487
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;
-}