1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
4 * This file is part of gsignond
6 * Copyright (C) 2012-2013 Intel Corporation.
8 * Contact: Jussi Laako <jussi.laako@linux.intel.com>
9 * Amarnath Valluri <amarnath.valluri@linux.intel.com>
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
29 #include <glib/gstdio.h>
33 #include "gsignond/gsignond-config.h"
34 #include "gsignond/gsignond-config-general.h"
35 #include "gsignond/gsignond-config-dbus.h"
36 #include "gsignond/gsignond-log.h"
37 #include "gsignond/gsignond-dictionary.h"
40 * SECTION:gsignond-config
41 * @short_description: gSSO configuration information
42 * @include: gsignond/gsignond-config.h
44 * #GSignondConfig holds configuration information as a set of keys and values
45 * (integer or strings). The key names are defined in
46 * <link linkend="gsignond-General-configuration">general config keys</link>,
47 * and <link linkend="gsignond-DBus-configuration">DBus config keys</link>.
49 * The configuration is retrieved from the gSSO configuration file. See below
50 * for where the file is searched for.
52 * <refsect1><title>Where the configuration file is searched for</title></refsect1>
54 * If gSSO has been compiled with --enable-debug, then these locations are used,
55 * in decreasing order of priority:
56 * - GSIGNOND_CONFIG environment variable
57 * - g_get_user_config_dir() + "gsignond.conf"
58 * - path specified in --sysconfdir configure option ($(sysconfdir))
59 * - each of g_get_system_config_dirs() + "gsignond.conf"
61 * Otherwise, the config file location is determined at compilation time as
62 * $(sysconfdir) + "gsignond.conf"
64 * <refsect1><title>Example configuration file</title></refsect1>
66 * See example configuration file here:
67 * <ulink url="http://code.google.com/p/accounts-sso/source/browse/gsignond.conf.in?repo=gsignond">
68 * http://code.google.com/p/accounts-sso/source/browse/gsignond.conf.in?repo=gsignond</ulink>
74 * Opaque structure for the object.
77 * GSignondConfigClass:
79 * Opaque structure for the class.
83 struct _GSignondConfigPrivate
85 gchar *config_file_path;
86 GSignondDictionary *config_table;
89 #define GSIGNOND_CONFIG_PRIV(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), GSIGNOND_TYPE_CONFIG, GSignondConfigPrivate)
91 G_DEFINE_TYPE (GSignondConfig, gsignond_config, G_TYPE_OBJECT);
94 _check_config_file (const gchar *path)
98 fn = g_build_filename (path,
101 DBG ("check config at %s", fn);
102 if (g_access (fn, R_OK) == 0)
109 _load_config (GSignondConfig *self)
112 gchar **groups = NULL;
115 GKeyFile *settings = g_key_file_new ();
118 const gchar * const *sysconfdirs;
120 if (!self->priv->config_file_path) {
121 const gchar *cfg_env = g_getenv ("GSIGNOND_CONFIG");
123 self->priv->config_file_path = _check_config_file (cfg_env);
125 if (!self->priv->config_file_path) {
126 gchar *user_cfg = g_strdup_printf ("%s/%s",
127 g_get_user_config_dir (),
129 self->priv->config_file_path = _check_config_file (user_cfg);
132 if (!self->priv->config_file_path) {
133 self->priv->config_file_path =
134 _check_config_file (GSIGNOND_SYSCONF_DIR);
136 if (!self->priv->config_file_path) {
137 sysconfdirs = g_get_system_config_dirs ();
138 while (*sysconfdirs != NULL) {
139 gchar *sys_cfg = _check_config_file (*sysconfdirs);
141 self->priv->config_file_path = sys_cfg;
147 # else /* ENABLE_DEBUG */
148 # ifndef GSIGNOND_SYSCONF_DIR
149 # error "System configuration directory not defined!"
151 self->priv->config_file_path = _check_config_file (GSIGNOND_SYSCONF_DIR);
152 # endif /* ENABLE_DEBUG */
154 if (self->priv->config_file_path) {
155 DBG ("Loading SSO config from %s", self->priv->config_file_path);
156 if (!g_key_file_load_from_file (settings,
157 self->priv->config_file_path,
158 G_KEY_FILE_NONE, &err)) {
159 WARN ("error reading config file at '%s': %s",
160 self->priv->config_file_path, err->message);
162 g_key_file_free (settings);
167 groups = g_key_file_get_groups (settings, &n_groups);
169 for (i = 0; i < n_groups; i++) {
172 gchar **keys = g_key_file_get_keys (settings,
177 WARN ("fail to read group '%s': %s", groups[i], err->message);
182 for (j = 0; j < n_keys; j++) {
183 gchar *key = g_strdup_printf ("%s/%s", groups[i], keys[j]);
184 gchar *value = g_key_file_get_value (settings,
189 WARN ("fail to read key '%s/%s': %s", groups[i], keys[j], err->message);
194 INFO ("found config : '%s/%s' - '%s'", groups[i], keys[j], value);
195 gsignond_config_set_string (self, key, value);
206 g_key_file_free (settings);
212 * gsignond_config_get_integer:
213 * @self: an instance of #GSignondConfig
216 * Get an integer configuration value.
218 * Returns: the value corresponding to the key as an integer. If the key does not
219 * exist or cannot be converted to the integer, 0 is returned.
222 gsignond_config_get_integer (GSignondConfig *self, const gchar *key)
224 const gchar *str_value = gsignond_config_get_string (self, key);
225 return (gint) (str_value ? atoi (str_value) : 0);
229 * gsignond_config_set_integer:
230 * @self: an instance of #GSignondConfig
234 * Sets the configuration value to the provided integer.
237 gsignond_config_set_integer (GSignondConfig *self, const gchar *key,
241 g_return_if_fail (self && GSIGNOND_IS_CONFIG (self));
243 s_value = g_strdup_printf ("%d", value);
244 if (!s_value) return;
246 gsignond_config_set_string (self, (gpointer) key, s_value);
253 * gsignond_config_get_string:
254 * @self: an instance of #GSignondConfig
257 * Get a string configuration value.
259 * Returns: (transfer none): the value corresponding to the key as string. If the key does not
260 * exist, NULL is returned.
263 gsignond_config_get_string (GSignondConfig *self, const gchar *key)
265 g_return_val_if_fail (self && GSIGNOND_IS_CONFIG (self), NULL);
267 GVariant* value = gsignond_dictionary_get (self->priv->config_table,
269 if (!value) return NULL;
271 return g_variant_get_string (value, NULL);
275 * gsignond_config_set_string:
276 * @self: an instance of #GSignondConfig
278 * @value: (transfer none): the value
280 * Sets the configuration value to the provided string.
283 gsignond_config_set_string (GSignondConfig *self, const gchar *key,
286 g_return_if_fail (self && GSIGNOND_IS_CONFIG (self));
288 gsignond_dictionary_set (self->priv->config_table,
290 g_variant_new_string (value));
295 gsignond_config_dispose (GObject *object)
297 GSignondConfig *self = 0;
298 g_return_if_fail (object && GSIGNOND_IS_CONFIG (object));
300 self = GSIGNOND_CONFIG (object);
302 if (self->priv->config_table) {
303 gsignond_dictionary_unref (self->priv->config_table);
304 self->priv->config_table = NULL;
307 G_OBJECT_CLASS (gsignond_config_parent_class)->dispose (object);
311 gsignond_config_finalize (GObject *object)
313 GSignondConfig *self = 0;
314 g_return_if_fail (object && GSIGNOND_IS_CONFIG (object));
316 self = GSIGNOND_CONFIG (object);
318 if (self->priv->config_file_path) {
319 g_free (self->priv->config_file_path);
320 self->priv->config_file_path = NULL;
323 G_OBJECT_CLASS (gsignond_config_parent_class)->finalize (object);
327 gsignond_config_init (GSignondConfig *self)
329 self->priv = GSIGNOND_CONFIG_PRIV (self);
331 self->priv->config_file_path = NULL;
332 self->priv->config_table = gsignond_dictionary_new();
334 if (!_load_config (self))
335 WARN ("load configuration failed, using default settings");
339 gsignond_config_class_init (GSignondConfigClass *klass)
341 GObjectClass *object_class = G_OBJECT_CLASS (klass);
343 g_type_class_add_private (object_class, sizeof (GSignondConfigPrivate));
345 object_class->dispose = gsignond_config_dispose;
346 object_class->finalize = gsignond_config_finalize;
351 * gsignond_config_new:
353 * Create a #GSignondConfig object.
355 * Returns: an instance of #GSignondConfig. gSSO extensions should not use this
356 * as they're already provided with a config object when they're created.
359 gsignond_config_new ()
361 return GSIGNOND_CONFIG (g_object_new (GSIGNOND_TYPE_CONFIG, NULL));