[PATCH 2/3] core: split out config file handling
- From: Dan Williams <dcbw redhat com>
- To: "networkmanager-list gnome org" <networkmanager-list gnome org>
- Subject: [PATCH 2/3] core: split out config file handling
- Date: Tue, 27 Sep 2011 10:45:19 -0500
Make config file stuff somewhat clearer and easier to understand,
and possibly easier to extend later.
---
src/Makefile.am | 2 +
src/main.c | 135 +++++--------------------
src/nm-config.c | 243 ++++++++++++++++++++++++++++++++++++++++++++
src/nm-config.h | 55 ++++++++++
src/settings/nm-settings.c | 22 ++--
src/settings/nm-settings.h | 2 +-
6 files changed, 335 insertions(+), 124 deletions(-)
create mode 100644 src/nm-config.c
create mode 100644 src/nm-config.h
diff --git a/src/Makefile.am b/src/Makefile.am
index c8caefb..cbcfdc6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -142,6 +142,8 @@ NetworkManager_SOURCES = \
nm-ip6-config.h \
nm-active-connection.h \
nm-active-connection.c \
+ nm-config.h \
+ nm-config.c \
main.c \
nm-policy.c \
nm-policy.h \
diff --git a/src/main.c b/src/main.c
index a9ffd38..8d37bc9 100644
--- a/src/main.c
+++ b/src/main.c
@@ -50,14 +50,13 @@
#include "nm-vpn-manager.h"
#include "nm-logging.h"
#include "nm-policy-hosts.h"
+#include "nm-config.h"
#if !defined(NM_DIST_VERSION)
# define NM_DIST_VERSION VERSION
#endif
#define NM_DEFAULT_PID_FILE LOCALSTATEDIR"/run/NetworkManager.pid"
-#define NM_DEFAULT_SYSTEM_CONF_FILE SYSCONFDIR"/NetworkManager/NetworkManager.conf"
-#define NM_OLD_SYSTEM_CONF_FILE SYSCONFDIR"/NetworkManager/nm-system-settings.conf"
#define NM_DEFAULT_SYSTEM_STATE_FILE LOCALSTATEDIR"/lib/NetworkManager/NetworkManager.state"
/*
@@ -310,46 +309,6 @@ done:
}
static gboolean
-parse_config_file (const char *filename,
- char **plugins,
- char **dhcp_client,
- char ***dns_plugins,
- char **log_level,
- char **log_domains,
- GError **error)
-{
- GKeyFile *config;
- gboolean success = FALSE;
-
- config = g_key_file_new ();
- if (!config) {
- g_set_error (error, 0, 0,
- "Not enough memory to load config file.");
- return FALSE;
- }
-
- g_key_file_set_list_separator (config, ',');
- if (!g_key_file_load_from_file (config, filename, G_KEY_FILE_NONE, error))
- goto out;
-
- *plugins = g_key_file_get_value (config, "main", "plugins", error);
- if (*error)
- goto out;
-
- *dhcp_client = g_key_file_get_value (config, "main", "dhcp", NULL);
- *dns_plugins = g_key_file_get_string_list (config, "main", "dns", NULL, NULL);
-
- *log_level = g_key_file_get_value (config, "logging", "level", NULL);
- *log_domains = g_key_file_get_value (config, "logging", "domains", NULL);
-
- success = TRUE;
-
-out:
- g_key_file_free (config);
- return success;
-}
-
-static gboolean
parse_state_file (const char *filename,
gboolean *net_enabled,
gboolean *wifi_enabled,
@@ -469,10 +428,9 @@ main (int argc, char *argv[])
GOptionContext *opt_ctx = NULL;
gboolean become_daemon = FALSE;
gboolean g_fatal_warnings = FALSE;
- char *pidfile = NULL, *state_file = NULL, *dhcp = NULL;
- char *config = NULL, *plugins = NULL, *conf_plugins = NULL;
+ char *pidfile = NULL, *state_file = NULL;
+ char *config_path = NULL, *plugins = NULL;
char *log_level = NULL, *log_domains = NULL;
- char **dns = NULL;
gboolean wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE, wimax_enabled = TRUE;
gboolean success, show_version = FALSE;
NMPolicy *policy = NULL;
@@ -482,9 +440,9 @@ main (int argc, char *argv[])
NMSupplicantManager *sup_mgr = NULL;
NMDHCPManager *dhcp_mgr = NULL;
NMSettings *settings = NULL;
+ NMConfig *config;
GError *error = NULL;
gboolean wrote_pidfile = FALSE;
- char *cfg_log_level = NULL, *cfg_log_domains = NULL;
GOptionEntry options[] = {
{ "version", 0, 0, G_OPTION_ARG_NONE, &show_version, "Print NetworkManager version and exit", NULL },
@@ -492,7 +450,7 @@ main (int argc, char *argv[])
{ "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &g_fatal_warnings, "Make all warnings fatal", NULL },
{ "pid-file", 0, 0, G_OPTION_ARG_FILENAME, &pidfile, "Specify the location of a PID file", "filename" },
{ "state-file", 0, 0, G_OPTION_ARG_FILENAME, &state_file, "State file location", "/path/to/state.file" },
- { "config", 0, 0, G_OPTION_ARG_FILENAME, &config, "Config file location", "/path/to/config.file" },
+ { "config", 0, 0, G_OPTION_ARG_FILENAME, &config_path, "Config file location", "/path/to/config.file" },
{ "plugins", 0, 0, G_OPTION_ARG_STRING, &plugins, "List of plugins separated by ','", "plugin1,plugin2" },
{ "log-level", 0, 0, G_OPTION_ARG_STRING, &log_level, "Log level: one of [ERR, WARN, INFO, DEBUG]", "INFO" },
{ "log-domains", 0, 0, G_OPTION_ARG_STRING, &log_domains,
@@ -554,58 +512,18 @@ main (int argc, char *argv[])
if (check_pidfile (pidfile))
exit (1);
- /* Parse the config file */
- if (config) {
- if (!parse_config_file (config, &conf_plugins, &dhcp, &dns, &cfg_log_level, &cfg_log_domains, &error)) {
- fprintf (stderr, "Config file %s invalid: (%d) %s\n",
- config,
- error ? error->code : -1,
- (error && error->message) ? error->message : "unknown");
- exit (1);
- }
- } else {
- gboolean parsed = FALSE;
-
- /* 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 (g_file_test (NM_OLD_SYSTEM_CONF_FILE, G_FILE_TEST_EXISTS)) {
- config = g_strdup (NM_OLD_SYSTEM_CONF_FILE);
- parsed = parse_config_file (config, &conf_plugins, &dhcp, &dns, &cfg_log_level, &cfg_log_domains, &error);
- if (!parsed) {
- fprintf (stderr, "Default config file %s invalid: (%d) %s\n",
- config,
- error ? error->code : -1,
- (error && error->message) ? error->message : "unknown");
- g_free (config);
- config = NULL;
- g_clear_error (&error);
- }
- }
-
- /* Try the preferred NetworkManager.conf last */
- if (!parsed && g_file_test (NM_DEFAULT_SYSTEM_CONF_FILE, G_FILE_TEST_EXISTS)) {
- config = g_strdup (NM_DEFAULT_SYSTEM_CONF_FILE);
- parsed = parse_config_file (config, &conf_plugins, &dhcp, &dns, &cfg_log_level, &cfg_log_domains, &error);
- if (!parsed) {
- fprintf (stderr, "Default config file %s invalid: (%d) %s\n",
- config,
- error ? error->code : -1,
- (error && error->message) ? error->message : "unknown");
- g_free (config);
- config = NULL;
- g_clear_error (&error);
- }
- }
+ /* Read the config file and CLI overrides */
+ config = nm_config_new (config_path, plugins, log_level, log_domains, &error);
+ if (config == NULL) {
+ fprintf (stderr, "Failed to read configuration: (%d) %s\n",
+ error ? error->code : -1,
+ (error && error->message) ? error->message : "unknown");
+ exit (1);
}
+
/* Logging setup */
- if (!nm_logging_setup (log_level ? log_level : cfg_log_level,
- log_domains ? log_domains : cfg_log_domains,
+ if (!nm_logging_setup (nm_config_get_log_level (config),
+ nm_config_get_log_domains (config),
&error)) {
fprintf (stderr,
_("%s. Please use --help to see a list of valid options.\n"),
@@ -613,10 +531,6 @@ main (int argc, char *argv[])
exit (1);
}
- /* Plugins specified with '--plugins' override those of config file */
- plugins = plugins ? plugins : g_strdup (conf_plugins);
- g_free (conf_plugins);
-
/* Parse the state file */
if (!parse_state_file (state_file, &net_enabled, &wifi_enabled, &wwan_enabled, &wimax_enabled, &error)) {
fprintf (stderr, "State file %s parsing failed: (%d) %s\n",
@@ -683,8 +597,7 @@ main (int argc, char *argv[])
nm_log_info (LOGD_CORE, "NetworkManager (version " NM_DIST_VERSION ") is starting...");
success = FALSE;
- if (config)
- nm_log_info (LOGD_CORE, "Read config file %s", config);
+ nm_log_info (LOGD_CORE, "Read config file %s", nm_config_get_path (config));
main_loop = g_main_loop_new (NULL, FALSE);
@@ -704,13 +617,15 @@ main (int argc, char *argv[])
goto done;
}
- dns_mgr = nm_dns_manager_get ((const char **) dns);
+ dns_mgr = nm_dns_manager_get (nm_config_get_dns_plugins (config));
if (!dns_mgr) {
nm_log_err (LOGD_CORE, "failed to start the DNS manager.");
goto done;
}
- settings = nm_settings_new (config, plugins, &error);
+ settings = nm_settings_new (nm_config_get_path (config),
+ nm_config_get_plugins (config),
+ &error);
if (!settings) {
nm_log_err (LOGD_CORE, "failed to initialize settings storage: %s",
error && error->message ? error->message : "(unknown)");
@@ -744,7 +659,7 @@ main (int argc, char *argv[])
}
/* Initialize DHCP manager */
- dhcp_mgr = nm_dhcp_manager_new (dhcp, &error);
+ dhcp_mgr = nm_dhcp_manager_new (nm_config_get_dhcp_client (config), &error);
if (!dhcp_mgr) {
nm_log_err (LOGD_CORE, "failed to start the DHCP manager: %s.", error->message);
goto done;
@@ -804,17 +719,15 @@ done:
if (pidfile && wrote_pidfile)
unlink (pidfile);
+ nm_config_free (config);
+
/* Free options */
g_free (pidfile);
g_free (state_file);
- g_free (config);
+ g_free (config_path);
g_free (plugins);
- g_free (dhcp);
- g_strfreev (dns);
g_free (log_level);
g_free (log_domains);
- g_free (cfg_log_level);
- g_free (cfg_log_domains);
nm_log_info (LOGD_CORE, "exiting (%s)", success ? "success" : "error");
exit (success ? 0 : 1);
diff --git a/src/nm-config.c b/src/nm-config.c
new file mode 100644
index 0000000..f52f06f
--- /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);
+}
+
diff --git a/src/nm-config.h b/src/nm-config.h
new file mode 100644
index 0000000..fae344f
--- /dev/null
+++ b/src/nm-config.h
@@ -0,0 +1,55 @@
+/* -*- 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.
+ */
+
+#ifndef NM_CONFIG_H
+#define NM_CONFIG_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+typedef struct NMConfig NMConfig;
+
+typedef enum {
+ NM_CONFIG_ERROR_NO_MEMORY = 0,
+} NMConfigError;
+
+#define NM_CONFIG_ERROR (nm_config_error_quark ())
+GQuark nm_config_error_quark (void);
+#define NM_TYPE_CONFIG_ERROR (nm_config_error_get_type ())
+GType nm_config_error_get_type (void);
+
+
+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);
+
+const char *nm_config_get_path (NMConfig *config);
+const char **nm_config_get_plugins (NMConfig *config);
+const char *nm_config_get_dhcp_client (NMConfig *config);
+const char **nm_config_get_dns_plugins (NMConfig *config);
+const char *nm_config_get_log_level (NMConfig *config);
+const char *nm_config_get_log_domains (NMConfig *config);
+
+void nm_config_free (NMConfig *config);
+
+#endif /* NM_CONFIG_H */
+
diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c
index cb094e9..f0bfc16 100644
--- a/src/settings/nm-settings.c
+++ b/src/settings/nm-settings.c
@@ -27,6 +27,7 @@
#include <unistd.h>
#include <string.h>
+#include <ctype.h>
#include <gmodule.h>
#include <net/ethernet.h>
#include <netinet/ether.h>
@@ -546,24 +547,23 @@ find_plugin (GSList *list, const char *pname)
}
static gboolean
-load_plugins (NMSettings *self, const char *plugins, GError **error)
+load_plugins (NMSettings *self, const char **plugins, GError **error)
{
GSList *list = NULL;
- char **plist;
- char **iter;
+ const char **iter;
gboolean success = TRUE;
- plist = g_strsplit (plugins, ",", 0);
- if (!plist)
- return FALSE;
-
- for (iter = plist; *iter; iter++) {
+ for (iter = plugins; *iter; iter++) {
GModule *plugin;
char *full_name, *path;
- const char *pname = g_strstrip (*iter);
+ const char *pname = *iter;
GObject *obj;
GObject * (*factory_func) (void);
+ /* strip leading spaces */
+ while (isblank (*pname))
+ pname++;
+
/* keyfile plugin built in now */
if (!strcmp (pname, "keyfile"))
continue;
@@ -616,8 +616,6 @@ load_plugins (NMSettings *self, const char *plugins, GError **error)
list = g_slist_append (list, obj);
}
- g_strfreev (plist);
-
g_slist_foreach (list, (GFunc) g_object_unref, NULL);
g_slist_free (list);
@@ -1494,7 +1492,7 @@ nm_settings_device_removed (NMSettings *self, NMDevice *device)
NMSettings *
nm_settings_new (const char *config_file,
- const char *plugins,
+ const char **plugins,
GError **error)
{
NMSettings *self;
diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h
index 66d41cc..77485e1 100644
--- a/src/settings/nm-settings.h
+++ b/src/settings/nm-settings.h
@@ -77,7 +77,7 @@ typedef struct {
GType nm_settings_get_type (void);
NMSettings *nm_settings_new (const char *config_file,
- const char *plugins,
+ const char **plugins,
GError **error);
typedef void (*NMSettingsForEachFunc) (NMSettings *settings,
--
1.7.6.2
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]