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 tlm
6 * Copyright (C) 2013-2014 Intel Corporation.
8 * Contact: Imran Zaman <imran.zaman@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>
32 #include "tlm-config.h"
33 #include "tlm-config-general.h"
38 * @short_description: tlm configuration information
39 * @include: tlm-config.h
41 * #TlmConfig holds configuration information as a set of keys and values
42 * (integer or strings). The key names are defined in
43 * <link linkend="tlm-General-configuration">General config keys</link>.
44 * Note that authentication and account plugins may use plugin-specific
45 * configuration keys; see plugins' documentation for specifics.
47 * The configuration is retrieved from the tlm configuration file. See below
48 * for where the file is searched for.
50 * <refsect1><title>Usage</title></refsect1>
51 * Following code snippet demonstrates how to create and use config object:
54 * TlmConfig* config = tlm_config_new ();
55 * const gchar *str = tlm_config_get_string (config,
56 * TLM_CONFIG_GENERAL, TLM_CONFIG_GENERAL_PAM_SERVICE, 0);
57 * g_object_unref(config);
61 * <refsect1><title>Where the configuration file is searched for</title>
64 * If tlm has been compiled with --enable-debug, then these locations are used,
65 * in decreasing order of priority:
66 * - TLM_CONF_FILE environment variable
67 * - g_get_user_config_dir() + "tlm.conf"
68 * - each of g_get_system_config_dirs() + "tlm.conf"
70 * Otherwise, the config file location is determined at compilation time as
71 * $(sysconfdir) + "tlm.conf"
73 * <refsect1><title>Example configuration file</title></refsect1>
75 * See example configuration file here:
76 * <ulink url="https://github.com/01org/tlm/blob/master/data/tlm.conf.in">
77 * tlm configuration file</ulink>
84 * Opaque structure for the object.
89 * @parent_class: parent class object
91 * Opaque structure for the class.
94 struct _TlmConfigPrivate
96 gchar *config_file_path;
97 GHashTable *config_table;
100 #define TLM_CONFIG_PRIV(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
101 TLM_TYPE_CONFIG, TlmConfigPrivate)
103 G_DEFINE_TYPE (TlmConfig, tlm_config, G_TYPE_OBJECT);
106 _check_config_file (const gchar *path)
108 gchar *fn = g_build_filename (path, "tlm.conf", NULL);
109 DBG ("check config at %s", fn);
110 if (g_access (fn, R_OK) == 0)
117 _load_config (TlmConfig *self)
119 TlmConfigPrivate *priv = self->priv;
121 gchar **groups = NULL;
124 GKeyFile *settings = g_key_file_new ();
126 const gchar * const *sysconfdirs;
128 if (!priv->config_file_path) {
129 const gchar *cfg_env = g_getenv ("TLM_CONF_FILE");
131 if (g_access (cfg_env, R_OK) == 0)
132 priv->config_file_path = g_strdup (cfg_env);
135 if (!priv->config_file_path) {
136 priv->config_file_path = _check_config_file (TLM_SYSCONF_DIR);
138 if (!priv->config_file_path) {
139 sysconfdirs = g_get_system_config_dirs ();
140 while (*sysconfdirs != NULL) {
141 gchar *sys_cfg = _check_config_file (*sysconfdirs);
143 priv->config_file_path = sys_cfg;
150 if (priv->config_file_path) {
151 DBG ("loading TLM config from %s", priv->config_file_path);
152 if (!g_key_file_load_from_file (settings,
153 priv->config_file_path,
154 G_KEY_FILE_NONE, &err)) {
155 WARN ("error reading config file at '%s': %s",
156 priv->config_file_path, err->message);
158 g_key_file_free (settings);
163 WARN ("No valid configuration file found");
167 groups = g_key_file_get_groups (settings, &n_groups);
169 for (i = 0; i < n_groups; i++) {
172 GHashTable *group_table = NULL;
173 gchar **keys = g_key_file_get_keys (settings,
178 WARN ("fail to read group '%s': %s", groups[i], err->message);
183 group_table = (GHashTable *) g_hash_table_lookup (
184 priv->config_table, groups[i]);
186 group_table = g_hash_table_new_full (
190 (GDestroyNotify)g_free);
192 for (j = 0; j < n_keys; j++) {
193 gchar *value = g_key_file_get_value (settings,
198 WARN ("fail to read key '%s/%s': %s", groups[i], keys[j],
204 DBG ("found config : '%s/%s' - '%s'", groups[i], keys[j], value);
206 g_hash_table_insert (group_table,
207 (gpointer)g_strdup (keys[j]),
212 g_hash_table_insert (priv->config_table,
213 g_strdup (groups[i]),
221 g_key_file_free (settings);
231 const gchar *e_val = 0;
233 e_val = g_getenv("TLM_ACCOUNT_PLUGIN");
235 tlm_config_set_string (self,
237 TLM_CONFIG_GENERAL_ACCOUNTS_PLUGIN, e_val);
239 #endif /* ENABLE_DEBUG */
246 /* accounts plugin => default */
247 if (!tlm_config_has_key (self,
249 TLM_CONFIG_GENERAL_ACCOUNTS_PLUGIN)) {
250 tlm_config_set_string (self,
252 TLM_CONFIG_GENERAL_ACCOUNTS_PLUGIN,
256 /* default PAM service => tlm-login */
257 if (!tlm_config_has_key (self,
259 TLM_CONFIG_GENERAL_PAM_SERVICE)) {
260 tlm_config_set_string (self,
262 TLM_CONFIG_GENERAL_PAM_SERVICE,
266 /* default user => guest */
267 if (!tlm_config_has_key (self,
269 TLM_CONFIG_GENERAL_DEFAULT_USER)) {
270 tlm_config_set_string (self,
272 TLM_CONFIG_GENERAL_DEFAULT_USER,
278 * tlm_config_get_group:
279 * @self: (transfer none): an instance of #TlmConfig
280 * @group: the group name
282 * Retrives the configuration in given #group as #GHashTable
284 * Returns: (transfer none): the key, value paired dictionary if found,
288 tlm_config_get_group (
292 g_return_val_if_fail (self && TLM_IS_CONFIG(self), NULL);
293 g_return_val_if_fail (group && group[0], NULL);
295 return (GHashTable *) g_hash_table_lookup (self->priv->config_table,
300 * tlm_config_get_string:
301 * @self: (transfer none): an instance of #TlmConfig
302 * @group: (transfer none): the group name, NULL refers to General
303 * @key: (transfer none): the key name
305 * Get a string configuration value.
307 * Returns: the value corresponding to the key as an string. If the
308 * key does not exist or cannot be converted to the integer, NULL is returned.
311 tlm_config_get_string (
316 g_return_val_if_fail (self && TLM_IS_CONFIG (self), NULL);
317 g_return_val_if_fail (key && key[0], NULL);
319 GHashTable *group_table = tlm_config_get_group (self, group);
320 if (!group_table) return NULL;
322 return (const gchar *) g_hash_table_lookup (group_table, key);
326 * tlm_config_set_string:
327 * @self: (transfer none): an instance of #TlmConfig
328 * @group: (transfer none): the group name
329 * @key: (transfer none): the key name
330 * @value: (transfer none): the value
332 * Sets the configuration value to the provided string.
335 tlm_config_set_string (
341 g_return_if_fail (self && TLM_IS_CONFIG (self));
342 g_return_if_fail (key && key[0]);
344 if (!group) group = TLM_CONFIG_GENERAL;
346 GHashTable *group_table = tlm_config_get_group (self, group);
348 group_table = g_hash_table_new_full (g_str_hash,
352 g_hash_table_insert (self->priv->config_table,
353 (gpointer)g_strdup (group),
354 (gpointer)group_table);
357 g_hash_table_insert (group_table,
358 (gpointer) g_strdup (key),
359 (gpointer) g_strdup (value));
363 * tlm_config_get_int:
364 * @self: (transfer none): an instance of #TlmConfig
365 * @group: the group name
367 * @retval: value to be returned in case key is not found
369 * Get an integer configuration value.
371 * Returns: the value corresponding to the key as an integer. If the key does
372 * not exist or cannot be converted to the integer, retval is returned.
381 const gchar *str_value = tlm_config_get_string (self, group, key);
382 return (gint) (str_value ? atoi (str_value) : retval);
386 * tlm_config_set_int:
387 * @self: (transfer none): an instance of #TlmConfig
388 * @group: the group name
392 * Sets the configuration value to the provided integer.
402 g_return_if_fail (self && TLM_IS_CONFIG (self));
404 s_value = g_strdup_printf ("%d", value);
405 if (!s_value) return;
407 tlm_config_set_string (self, group, key, s_value);
413 * tlm_config_get_uint:
414 * @self: (transfer none): an instance of #TlmConfig
415 * @group: (transfer none): the group name
416 * @key: (transfer none): the key name
417 * @retval: value to be returned in case key is not found
419 * Get an unsigned integer configuration value.
421 * Returns: the value corresponding to the key as an unsigned integer. If the
422 * key does not exist or cannot be converted to the integer, retval is returned.
425 tlm_config_get_uint (
432 const gchar *str_value = tlm_config_get_string (self, group, key);
433 if (!str_value || sscanf (str_value, "%u", &value) <= 0) value = retval;
439 * tlm_config_set_uint:
440 * @self: (transfer none): an instance of #TlmConfig
441 * @group: (transfer none): the group name
445 * Sets the configuration value to the provided unsigned integer.
448 tlm_config_set_uint (
455 g_return_if_fail (self && TLM_IS_CONFIG (self));
457 s_value = g_strdup_printf ("%u", value);
458 if (!s_value) return;
460 tlm_config_set_string (self, group, key, s_value);
465 * tlm_config_get_boolean:
466 * @self: (transfer none): an instance of #TlmConfig
467 * @group: (transfer none): the group name
468 * @key: (transfer none): the key name
469 * @retval: value to be returned in case key is not found
471 * Get a boolean configuration value.
473 * Returns: the value corresponding to the key as boolean. If the
474 * key does not exist or cannot be converted to boolean, retval is returned.
477 tlm_config_get_boolean (
483 const gchar *str_value = NULL;
485 g_return_val_if_fail (self && TLM_IS_CONFIG (self), retval);
487 str_value = tlm_config_get_string (self, group, key);
491 if (g_ascii_strncasecmp (str_value, "false", 5) == 0 ||
492 g_ascii_strncasecmp (str_value, "no", 2) == 0)
495 if (g_ascii_strncasecmp (str_value, "true", 4) == 0 ||
496 g_ascii_strncasecmp (str_value, "yes", 3) == 0)
499 if (sscanf (str_value, "%d", &value) <= 0)
502 return (gboolean) value;
506 * tlm_config_set_boolean:
507 * @self: (transfer none): an instance of #TlmConfig
508 * @group: the group name
512 * Sets the configuration value to the provided #value.
515 tlm_config_set_boolean (
521 g_return_if_fail (self && TLM_IS_CONFIG (self));
523 tlm_config_set_int (self, group, key, (gint)value);
526 * tlm_config_has_group:
527 * @self: (transfer none): an instance of #TlmConfig
528 * @group: the group name
530 * Checks if any configuration available for #group.
532 * Returns: TRUE if found, FALSE otherwise.
535 tlm_config_has_group (
539 g_return_val_if_fail (self && TLM_IS_CONFIG (self), FALSE);
540 g_return_val_if_fail (group, FALSE);
542 return g_hash_table_contains (self->priv->config_table,
543 (gconstpointer)group);
547 * tlm_config_has_key:
548 * @self: (transfer none): an instance of #TlmConfig
549 * @group: the group name
552 * Checks if #key is in given #group.
554 * Returns: TRUE, if found, FALSE otherwise.
563 GHashTable *group_table = NULL;
564 g_return_val_if_fail (self && TLM_IS_CONFIG (self), FALSE);
565 g_return_val_if_fail (key, FALSE);
567 if (!group) group = TLM_CONFIG_GENERAL;
569 group_table = tlm_config_get_group (self, group);
570 if (!group_table) return FALSE;
572 return g_hash_table_contains (group_table, (gconstpointer)key);
576 _cleanup (TlmConfig *self)
578 if (self->priv->config_table) {
579 g_hash_table_unref (self->priv->config_table);
580 self->priv->config_table = NULL;
583 if (self->priv->config_file_path) {
584 g_free (self->priv->config_file_path);
585 self->priv->config_file_path = NULL;
594 g_return_if_fail (object && TLM_IS_CONFIG (object));
596 self = TLM_CONFIG (object);
600 G_OBJECT_CLASS (tlm_config_parent_class)->dispose (object);
604 tlm_config_finalize (
607 g_return_if_fail (object && TLM_IS_CONFIG (object));
609 G_OBJECT_CLASS (tlm_config_parent_class)->finalize (object);
613 tlm_config_class_init (
614 TlmConfigClass *klass)
616 GObjectClass *object_class = G_OBJECT_CLASS (klass);
618 g_type_class_add_private (object_class, sizeof (TlmConfigPrivate));
620 object_class->dispose = tlm_config_dispose;
621 object_class->finalize = tlm_config_finalize;
625 _initialize (TlmConfig *self)
627 self->priv->config_file_path = NULL;
628 self->priv->config_table = g_hash_table_new_full (
632 (GDestroyNotify)g_hash_table_unref);
635 if (!_load_config (self))
636 WARN ("load configuration failed, using default settings");
639 _load_environment (self);
641 _set_defaults (self);
648 self->priv = TLM_CONFIG_PRIV (self);
654 * @self: (transfer none): an instance of #TlmConfig
656 * Reloads the configuration.
663 g_return_if_fail (self && TLM_IS_CONFIG (self));
665 DBG ("reload configuration");
673 * Create a #TlmConfig object.
675 * Returns: an instance of #TlmConfig.
680 return TLM_CONFIG (g_object_new (TLM_TYPE_CONFIG, NULL));