diff options
author | Dan Williams <dcbw@redhat.com> | 2011-09-22 10:16:07 -0500 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2011-09-27 09:40:50 -0500 |
commit | 52e96be3c4c493760d9d4da31265c92d2a842655 (patch) | |
tree | 1172a81824640f02b23bc3f0eaaa64042c8d510e /src/nm-config.c | |
parent | 1f835b0adbd015c5221ab26aff79836bd0cd0271 (diff) | |
download | NetworkManager-52e96be3c4c493760d9d4da31265c92d2a842655.tar.gz |
core: split out config file handling
Make config file stuff somewhat clearer and easier to understand,
and possibly easier to extend later.
Diffstat (limited to 'src/nm-config.c')
-rw-r--r-- | src/nm-config.c | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/src/nm-config.c b/src/nm-config.c new file mode 100644 index 0000000000..f52f06fd0c --- /dev/null +++ b/src/nm-config.c @@ -0,0 +1,243 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2011 Red Hat, Inc. + */ + +#include <config.h> +#include <string.h> +#include <stdio.h> + +#include "nm-config.h" + +#define NM_DEFAULT_SYSTEM_CONF_FILE SYSCONFDIR"/NetworkManager/NetworkManager.conf" +#define NM_OLD_SYSTEM_CONF_FILE SYSCONFDIR"/NetworkManager/nm-system-settings.conf" + +struct NMConfig { + char *path; + char **plugins; + char *dhcp_client; + char **dns_plugins; + char *log_level; + char *log_domains; +}; + +/************************************************************************/ + +GQuark +nm_config_error_quark (void) +{ + static GQuark quark = 0; + if (!quark) + quark = g_quark_from_static_string ("nm-config-error"); + return quark; +} + +/* This should really be standard. */ +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +nm_config_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + /* Not enough memory to parse the config file. */ + ENUM_ENTRY (NM_CONFIG_ERROR_NO_MEMORY, "NoMemory"), + { 0, 0, 0 } + }; + etype = g_enum_register_static ("NMConfigError", values); + } + return etype; +} + +/************************************************************************/ + +const char * +nm_config_get_path (NMConfig *config) +{ + g_return_val_if_fail (config != NULL, NULL); + + return config->path; +} + +const char ** +nm_config_get_plugins (NMConfig *config) +{ + g_return_val_if_fail (config != NULL, NULL); + + return (const char **) config->plugins; +} + +const char * +nm_config_get_dhcp_client (NMConfig *config) +{ + g_return_val_if_fail (config != NULL, NULL); + + return config->dhcp_client; +} + +const char ** +nm_config_get_dns_plugins (NMConfig *config) +{ + g_return_val_if_fail (config != NULL, NULL); + + return (const char **) config->dns_plugins; +} + +const char * +nm_config_get_log_level (NMConfig *config) +{ + g_return_val_if_fail (config != NULL, NULL); + + return config->log_level; +} + +const char * +nm_config_get_log_domains (NMConfig *config) +{ + g_return_val_if_fail (config != NULL, NULL); + + return config->log_domains; +} + +/************************************************************************/ + +static gboolean +fill_from_file (NMConfig *config, + const char *path, + const char *cli_plugins, + const char *cli_log_level, + const char *cli_log_domains, + GError **error) +{ + GKeyFile *kf; + gboolean success = FALSE; + + if (g_file_test (path, G_FILE_TEST_EXISTS) == FALSE) { + g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND, "file not found"); + return FALSE; + } + + kf = g_key_file_new (); + if (!kf) { + g_set_error (error, NM_CONFIG_ERROR, NM_CONFIG_ERROR_NO_MEMORY, + "Not enough memory to load config file"); + return FALSE; + } + + g_key_file_set_list_separator (kf, ','); + if (g_key_file_load_from_file (kf, path, G_KEY_FILE_NONE, error)) { + config->path = g_strdup (path); + + /* CLI provided options override config file options */ + if (cli_plugins && strlen (cli_plugins)) + config->plugins = g_strsplit_set (cli_plugins, ",", 0); + else + config->plugins = g_key_file_get_string_list (kf, "main", "plugins", NULL, NULL); + + config->dhcp_client = g_key_file_get_value (kf, "main", "dhcp", NULL); + config->dns_plugins = g_key_file_get_string_list (kf, "main", "dns", NULL, NULL); + + if (cli_log_level && strlen (cli_log_level)) + config->log_level = g_strdup (cli_log_level); + else + config->log_level = g_key_file_get_value (kf, "logging", "level", NULL); + + if (cli_log_domains && strlen (cli_log_domains)) + config->log_domains = g_strdup (cli_log_domains); + else + config->log_domains = g_key_file_get_value (kf, "logging", "domains", NULL); + success = TRUE; + } + + g_key_file_free (kf); + return success; +} + +NMConfig * +nm_config_new (const char *cli_config_path, + const char *cli_plugins, + const char *cli_log_level, + const char *cli_log_domains, + GError **error) +{ + NMConfig *config; + GError *local = NULL; + + config = g_malloc0 (sizeof (*config)); + + if (cli_config_path) { + /* Bad user-specific config file path is a hard error */ + if (!fill_from_file (config, cli_config_path, cli_plugins, cli_log_level, cli_log_domains, error)) { + nm_config_free (config); + return NULL; + } + return config; + } + + /* Even though we prefer NetworkManager.conf, we need to check the + * old nm-system-settings.conf first to preserve compat with older + * setups. In package managed systems dropping a NetworkManager.conf + * onto the system would make NM use it instead of nm-system-settings.conf, + * changing behavior during an upgrade. We don't want that. + */ + + /* Try deprecated nm-system-settings.conf first */ + if (fill_from_file (config, NM_OLD_SYSTEM_CONF_FILE, cli_plugins, cli_log_level, cli_log_domains, &local)) + return config; + + if (g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND) == FALSE) { + fprintf (stderr, "Default config file %s invalid: (%d) %s\n", + NM_OLD_SYSTEM_CONF_FILE, + local ? local->code : -1, + (local && local->message) ? local->message : "unknown"); + } + g_clear_error (&local); + + /* Try the standard config file location next */ + if (fill_from_file (config, NM_DEFAULT_SYSTEM_CONF_FILE, cli_plugins, cli_log_level, cli_log_domains, &local)) + return config; + + if (g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND) == FALSE) { + fprintf (stderr, "Default config file %s invalid: (%d) %s\n", + NM_DEFAULT_SYSTEM_CONF_FILE, + local ? local->code : -1, + (local && local->message) ? local->message : "unknown"); + } + + g_propagate_error (error, local); + return config; +} + +void +nm_config_free (NMConfig *config) +{ + g_return_if_fail (config != NULL); + + g_free (config->path); + g_strfreev (config->plugins); + g_free (config->dhcp_client); + g_strfreev (config->dns_plugins); + g_free (config->log_level); + g_free (config->log_domains); + + memset (config, 0, sizeof (*config)); + g_free (config); +} + |