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);
111 gchar **groups = NULL;
114 GKeyFile *settings = g_key_file_new ();
117 const gchar * const *sysconfdirs;
119 if (!self->priv->config_file_path) {
120 def_config = g_strdup (g_getenv ("TLM_CONF_FILE"));
122 def_config = g_build_filename (g_get_user_config_dir(),
125 if (g_access (def_config, R_OK) == 0) {
126 self->priv->config_file_path = def_config;
129 sysconfdirs = g_get_system_config_dirs ();
130 while (*sysconfdirs != NULL) {
131 def_config = g_build_filename (*sysconfdirs,
134 if (g_access (def_config, R_OK) == 0) {
135 self->priv->config_file_path = def_config;
143 # else /* ENABLE_DEBUG */
144 # ifndef TLM_SYSCONF_DIR
145 # error "System configuration directory not defined!"
147 def_config = g_build_filename (TLM_SYSCONF_DIR,
150 if (g_access (def_config, R_OK) == 0) {
151 self->priv->config_file_path = def_config;
155 # endif /* ENABLE_DEBUG */
157 if (self->priv->config_file_path) {
158 DBG ("Loading TLM config from %s", self->priv->config_file_path);
159 if (!g_key_file_load_from_file (settings,
160 self->priv->config_file_path,
161 G_KEY_FILE_NONE, &err)) {
162 WARN ("error reading config file at '%s': %s",
163 self->priv->config_file_path, err->message);
165 g_key_file_free (settings);
170 WARN ("No valid configuration file found");
174 groups = g_key_file_get_groups (settings, &n_groups);
176 for (i = 0; i < n_groups; i++) {
179 GHashTable *group_table = NULL;
180 gchar **keys = g_key_file_get_keys (settings,
185 WARN ("fail to read group '%s': %s", groups[i], err->message);
190 group_table = (GHashTable *) g_hash_table_lookup (
191 self->priv->config_table, groups[i]);
193 group_table = g_hash_table_new_full (
197 (GDestroyNotify)g_free);
199 for (j = 0; j < n_keys; j++) {
200 gchar *value = g_key_file_get_value (settings,
205 WARN ("fail to read key '%s/%s': %s", groups[i], keys[j],
211 DBG ("found config : '%s/%s' - '%s'", groups[i], keys[j], value);
213 g_hash_table_insert (group_table,
214 (gpointer)g_strdup (keys[j]),
219 g_hash_table_insert (self->priv->config_table,
220 g_strdup (groups[i]),
228 g_key_file_free (settings);
238 const gchar *e_val = 0;
240 e_val = g_getenv("TLM_ACCOUNT_PLUGIN");
242 tlm_config_set_string (self,
244 TLM_CONFIG_GENERAL_ACCOUNTS_PLUGIN, e_val);
246 #endif /* ENABLE_DEBUG */
253 /* accounts plugin => default */
254 if (!tlm_config_has_key (self,
256 TLM_CONFIG_GENERAL_ACCOUNTS_PLUGIN)) {
257 tlm_config_set_string (self,
259 TLM_CONFIG_GENERAL_ACCOUNTS_PLUGIN,
263 /* default PAM service => tlm-login */
264 if (!tlm_config_has_key (self,
266 TLM_CONFIG_GENERAL_PAM_SERVICE)) {
267 tlm_config_set_string (self,
269 TLM_CONFIG_GENERAL_PAM_SERVICE,
273 /* default user => guest */
274 if (!tlm_config_has_key (self,
276 TLM_CONFIG_GENERAL_DEFAULT_USER)) {
277 tlm_config_set_string (self,
279 TLM_CONFIG_GENERAL_DEFAULT_USER,
285 * tlm_config_get_group:
286 * @self: (transfer none): an instance of #TlmConfig
287 * @group: the group name
289 * Retrives the configuration in given #group as #GHashTable
291 * Returns: (transfer none): the key, value paired dictionary if found,
295 tlm_config_get_group (
299 g_return_val_if_fail (self && TLM_IS_CONFIG(self), NULL);
300 g_return_val_if_fail (group && group[0], NULL);
302 return (GHashTable *) g_hash_table_lookup (self->priv->config_table,
307 * tlm_config_get_string:
308 * @self: (transfer none): an instance of #TlmConfig
309 * @group: (transfer none): the group name, NULL refers to General
310 * @key: (transfer none): the key name
312 * Get a string configuration value.
314 * Returns: the value corresponding to the key as an string. If the
315 * key does not exist or cannot be converted to the integer, NULL is returned.
318 tlm_config_get_string (
323 g_return_val_if_fail (self && TLM_IS_CONFIG (self), NULL);
324 g_return_val_if_fail (key && key[0], NULL);
326 GHashTable *group_table = tlm_config_get_group (self, group);
327 if (!group_table) return NULL;
329 return (const gchar *) g_hash_table_lookup (group_table, key);
333 * tlm_config_set_string:
334 * @self: (transfer none): an instance of #TlmConfig
335 * @group: (transfer none): the group name
336 * @key: (transfer none): the key name
337 * @value: (transfer none): the value
339 * Sets the configuration value to the provided string.
342 tlm_config_set_string (
348 g_return_if_fail (self && TLM_IS_CONFIG (self));
349 g_return_if_fail (key && key[0]);
351 if (!group) group = TLM_CONFIG_GENERAL;
353 GHashTable *group_table = tlm_config_get_group (self, group);
355 group_table = g_hash_table_new_full (g_str_hash,
359 g_hash_table_insert (self->priv->config_table,
360 (gpointer)g_strdup (group),
361 (gpointer)group_table);
364 g_hash_table_insert (group_table,
365 (gpointer) g_strdup (key),
366 (gpointer) g_strdup (value));
370 * tlm_config_get_int:
371 * @self: (transfer none): an instance of #TlmConfig
372 * @group: the group name
374 * @retval: value to be returned in case key is not found
376 * Get an integer configuration value.
378 * Returns: the value corresponding to the key as an integer. If the key does
379 * not exist or cannot be converted to the integer, retval is returned.
388 const gchar *str_value = tlm_config_get_string (self, group, key);
389 return (gint) (str_value ? atoi (str_value) : retval);
393 * tlm_config_set_int:
394 * @self: (transfer none): an instance of #TlmConfig
395 * @group: the group name
399 * Sets the configuration value to the provided integer.
409 g_return_if_fail (self && TLM_IS_CONFIG (self));
411 s_value = g_strdup_printf ("%d", value);
412 if (!s_value) return;
414 tlm_config_set_string (self, group, key, s_value);
420 * tlm_config_get_uint:
421 * @self: (transfer none): an instance of #TlmConfig
422 * @group: (transfer none): the group name
423 * @key: (transfer none): the key name
424 * @retval: value to be returned in case key is not found
426 * Get an unsigned integer configuration value.
428 * Returns: the value corresponding to the key as an unsigned integer. If the
429 * key does not exist or cannot be converted to the integer, retval is returned.
432 tlm_config_get_uint (
439 const gchar *str_value = tlm_config_get_string (self, group, key);
440 if (!str_value || sscanf (str_value, "%u", &value) <= 0) value = retval;
446 * tlm_config_set_uint:
447 * @self: (transfer none): an instance of #TlmConfig
448 * @group: (transfer none): the group name
452 * Sets the configuration value to the provided unsigned integer.
455 tlm_config_set_uint (
462 g_return_if_fail (self && TLM_IS_CONFIG (self));
464 s_value = g_strdup_printf ("%u", value);
465 if (!s_value) return;
467 tlm_config_set_string (self, group, key, s_value);
472 * tlm_config_get_boolean:
473 * @self: (transfer none): an instance of #TlmConfig
474 * @group: (transfer none): the group name
475 * @key: (transfer none): the key name
476 * @retval: value to be returned in case key is not found
478 * Get a boolean configuration value.
480 * Returns: the value corresponding to the key as boolean. If the
481 * key does not exist or cannot be converted to boolean, retval is returned.
484 tlm_config_get_boolean (
490 const gchar *str_value = NULL;
492 g_return_val_if_fail (self && TLM_IS_CONFIG (self), retval);
494 str_value = tlm_config_get_string (self, group, key);
498 if (g_ascii_strncasecmp (str_value, "false", 5) == 0 ||
499 g_ascii_strncasecmp (str_value, "no", 2) == 0)
502 if (g_ascii_strncasecmp (str_value, "true", 4) == 0 ||
503 g_ascii_strncasecmp (str_value, "yes", 3) == 0)
506 if (sscanf (str_value, "%d", &value) <= 0)
509 return (gboolean) value;
513 * tlm_config_set_boolean:
514 * @self: (transfer none): an instance of #TlmConfig
515 * @group: the group name
519 * Sets the configuration value to the provided #value.
522 tlm_config_set_boolean (
528 g_return_if_fail (self && TLM_IS_CONFIG (self));
530 tlm_config_set_int (self, group, key, (gint)value);
533 * tlm_config_has_group:
534 * @self: (transfer none): an instance of #TlmConfig
535 * @group: the group name
537 * Checks if any configuration available for #group.
539 * Returns: TRUE if found, FALSE otherwise.
542 tlm_config_has_group (
546 g_return_val_if_fail (self && TLM_IS_CONFIG (self), FALSE);
547 g_return_val_if_fail (group, FALSE);
549 return g_hash_table_contains (self->priv->config_table,
550 (gconstpointer)group);
554 * tlm_config_has_key:
555 * @self: (transfer none): an instance of #TlmConfig
556 * @group: the group name
559 * Checks if #key is in given #group.
561 * Returns: TRUE, if found, FALSE otherwise.
570 GHashTable *group_table = NULL;
571 g_return_val_if_fail (self && TLM_IS_CONFIG (self), FALSE);
572 g_return_val_if_fail (key, FALSE);
574 if (!group) group = TLM_CONFIG_GENERAL;
576 group_table = tlm_config_get_group (self, group);
577 if (!group_table) return FALSE;
579 return g_hash_table_contains (group_table, (gconstpointer)key);
583 _cleanup (TlmConfig *self)
585 if (self->priv->config_table) {
586 g_hash_table_unref (self->priv->config_table);
587 self->priv->config_table = NULL;
590 if (self->priv->config_file_path) {
591 g_free (self->priv->config_file_path);
592 self->priv->config_file_path = NULL;
601 g_return_if_fail (object && TLM_IS_CONFIG (object));
603 self = TLM_CONFIG (object);
607 G_OBJECT_CLASS (tlm_config_parent_class)->dispose (object);
611 tlm_config_finalize (
614 g_return_if_fail (object && TLM_IS_CONFIG (object));
616 G_OBJECT_CLASS (tlm_config_parent_class)->finalize (object);
620 tlm_config_class_init (
621 TlmConfigClass *klass)
623 GObjectClass *object_class = G_OBJECT_CLASS (klass);
625 g_type_class_add_private (object_class, sizeof (TlmConfigPrivate));
627 object_class->dispose = tlm_config_dispose;
628 object_class->finalize = tlm_config_finalize;
632 _initialize (TlmConfig *self)
634 self->priv->config_file_path = NULL;
635 self->priv->config_table = g_hash_table_new_full (
639 (GDestroyNotify)g_hash_table_unref);
642 if (!_load_config (self))
643 WARN ("load configuration failed, using default settings");
646 _load_environment (self);
648 _set_defaults (self);
655 self->priv = TLM_CONFIG_PRIV (self);
661 * @self: (transfer none): an instance of #TlmConfig
663 * Reloads the configuration.
670 g_return_if_fail (self && TLM_IS_CONFIG (self));
672 DBG ("reload configuration");
680 * Create a #TlmConfig object.
682 * Returns: an instance of #TlmConfig.
687 return TLM_CONFIG (g_object_new (TLM_TYPE_CONFIG, NULL));