summary refs log tree commit diff
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c185
1 files changed, 42 insertions, 143 deletions
diff --git a/src/main.c b/src/main.c
index 328c253d..b7c0fd5a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -15,7 +15,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * Copyright (C) 2004 - 2010 Red Hat, Inc.
+ * Copyright (C) 2004 - 2011 Red Hat, Inc.
  * Copyright (C) 2005 - 2008 Novell, Inc.
  */
 
@@ -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,51 +309,11 @@ 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,
                   gboolean *wwan_enabled,
-				  gboolean *wimax_enabled,
+                  gboolean *wimax_enabled,
                   GError **error)
 {
 	GKeyFile *state_file;
@@ -368,13 +327,15 @@ parse_state_file (const char *filename,
 
 	state_file = g_key_file_new ();
 	if (!state_file) {
-		g_set_error (error, 0, 0,
-		             "Not enough memory to load state file.");
+		g_set_error (error, NM_CONFIG_ERROR, NM_CONFIG_ERROR_NO_MEMORY,
+		             "Not enough memory to load state file %s.", filename);
 		return FALSE;
 	}
 
 	g_key_file_set_list_separator (state_file, ',');
 	if (!g_key_file_load_from_file (state_file, filename, G_KEY_FILE_KEEP_COMMENTS, &tmp_error)) {
+		gboolean ret = FALSE;
+
 		/* This is kinda ugly; create the file and directory if it doesn't
 		 * exist yet.  We can't rely on distros necessarily creating the
 		 * /var/lib/NetworkManager for us since we have to ensure that
@@ -384,15 +345,16 @@ parse_state_file (const char *filename,
 		    && tmp_error->code == G_FILE_ERROR_NOENT) {
 			char *data, *dirname;
 			gsize len = 0;
-			gboolean ret = FALSE;
+
+			g_clear_error (&tmp_error);
 
 			/* try to create the directory if it doesn't exist */
 			dirname = g_path_get_dirname (filename);
 			errno = 0;
-			if (mkdir (dirname, 0755) != 0) {
+			if (g_mkdir_with_parents (dirname, 0755) != 0) {
 				if (errno != EEXIST) {
 					g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_ACCES,
-					             "Error creating state directory %s: %d", dirname, errno);
+					             "Error creating state directory %s: %s", dirname, strerror(errno));
 					g_free (dirname);
 					return FALSE;
 				}
@@ -409,53 +371,38 @@ parse_state_file (const char *filename,
 			if (data)
 				ret = g_file_set_contents (filename, data, len, error);
 			g_free (data);
-
-			return ret;
 		} else {
-			g_set_error_literal (error, tmp_error->domain, tmp_error->code, tmp_error->message);
-			g_clear_error (&tmp_error);
+			/* the error is not "No such file or directory" - propagate the error */
+			g_propagate_error (error, tmp_error);
 		}
 
-		/* Otherwise, file probably corrupt or inaccessible */
-		return FALSE;
+		return ret;
 	}
 
 	/* Reading state bits of NetworkManager; an error leaves the passed-in state
 	 * value unchanged.
 	 */
 	net = g_key_file_get_boolean (state_file, "main", "NetworkingEnabled", &tmp_error);
-	if (tmp_error)
-		g_set_error_literal (error, tmp_error->domain, tmp_error->code, tmp_error->message);
-	else
+	if (tmp_error == NULL)
 		*net_enabled = net;
 	g_clear_error (&tmp_error);
 
 	wifi = g_key_file_get_boolean (state_file, "main", "WirelessEnabled", &tmp_error);
-	if (tmp_error) {
-		g_clear_error (error);
-		g_set_error_literal (error, tmp_error->domain, tmp_error->code, tmp_error->message);
-	} else
+	if (tmp_error == NULL)
 		*wifi_enabled = wifi;
 	g_clear_error (&tmp_error);
 
 	wwan = g_key_file_get_boolean (state_file, "main", "WWANEnabled", &tmp_error);
-	if (tmp_error) {
-		g_clear_error (error);
-		g_set_error_literal (error, tmp_error->domain, tmp_error->code, tmp_error->message);
-	} else
+	if (tmp_error == NULL)
 		*wwan_enabled = wwan;
 	g_clear_error (&tmp_error);
 
 	wimax = g_key_file_get_boolean (state_file, "main", "WimaxEnabled", &tmp_error);
-	if (tmp_error) {
-		g_clear_error (error);
-		g_set_error_literal (error, tmp_error->domain, tmp_error->code, tmp_error->message);
-	} else
+	if (tmp_error == NULL)
 		*wimax_enabled = wimax;
 	g_clear_error (&tmp_error);
 
 	g_key_file_free (state_file);
-
 	return TRUE;
 }
 
@@ -469,10 +416,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 +428,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 +438,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 +500,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 +519,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 +585,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,22 +605,22 @@ 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)");
 		goto done;
 	}
 
-	manager = nm_manager_get (settings,
-	                          config,
-	                          plugins,
+	manager = nm_manager_new (settings,
 	                          state_file,
 	                          net_enabled,
 	                          wifi_enabled,
@@ -746,7 +647,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;
@@ -806,17 +707,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);