summary refs log tree commit diff
path: root/src/main.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2015-05-05 17:48:57 +0200
committerMichael Biebl <biebl@debian.org>2015-05-05 17:48:57 +0200
commitf408e27bccfacf347605a8d98649975a68f38a17 (patch)
tree654fd6695c31511baf919b1c0870d119a352ed75 /src/main.c
parent2c032d8f1c6292c1338a615e6ec40252889ba85c (diff)
Imported Upstream version 1.0.2 upstream/1.0.2
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c233
1 files changed, 126 insertions, 107 deletions
diff --git a/src/main.c b/src/main.c
index b3206fb4..53e829cd 100644
--- a/src/main.c
+++ b/src/main.c
@@ -69,6 +69,21 @@
 #define NM_DEFAULT_SYSTEM_STATE_FILE NMSTATEDIR "/NetworkManager.state"
 
 static GMainLoop *main_loop = NULL;
+static gboolean quit_early = FALSE;
+
+static struct {
+	gboolean show_version;
+	gboolean become_daemon;
+	gboolean debug;
+	gboolean g_fatal_warnings;
+	gboolean run_from_build_dir;
+	char *opt_log_level;
+	char *opt_log_domains;
+	char *pidfile;
+	char *state_file;
+} global_opt = {
+	.become_daemon = TRUE,
+};
 
 static gboolean
 parse_state_file (const char *filename,
@@ -149,11 +164,23 @@ parse_state_file (const char *filename,
 }
 
 static void
+_set_g_fatal_warnings ()
+{
+	GLogLevelFlags fatal_mask;
+
+	fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
+	fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
+	g_log_set_always_fatal (fatal_mask);
+}
+
+static void
 _init_nm_debug (const char *debug)
 {
 	const guint D_RLIMIT_CORE = 1;
+	const guint D_FATAL_WARNINGS = 2;
 	GDebugKey keys[] = {
 		{ "RLIMIT_CORE", D_RLIMIT_CORE },
+		{ "fatal-warnings", D_FATAL_WARNINGS },
 	};
 	guint flags = 0;
 	const char *env = getenv ("NM_DEBUG");
@@ -167,7 +194,7 @@ _init_nm_debug (const char *debug)
 	if (debug && strcasecmp (debug, "help") != 0)
 		flags |= g_parse_debug_string (debug,  keys, G_N_ELEMENTS (keys));
 
-	if (flags & D_RLIMIT_CORE) {
+	if (NM_FLAGS_HAS (flags, D_RLIMIT_CORE)) {
 		/* only enable this, if explicitly requested, because it might
 		 * expose sensitive data. */
 
@@ -177,6 +204,8 @@ _init_nm_debug (const char *debug)
 		};
 		setrlimit (RLIMIT_CORE, &limit);
 	}
+	if (NM_FLAGS_HAS (flags, D_FATAL_WARNINGS))
+		_set_g_fatal_warnings ();
 }
 
 static void
@@ -184,6 +213,37 @@ manager_configure_quit (NMManager *manager, gpointer user_data)
 {
 	nm_log_info (LOGD_CORE, "quitting now that startup is complete");
 	g_main_loop_quit (main_loop);
+	quit_early = TRUE;
+}
+
+static void
+do_early_setup (int *argc, char **argv[])
+{
+	GOptionEntry options[] = {
+		{ "version", 'V', 0, G_OPTION_ARG_NONE, &global_opt.show_version, N_("Print NetworkManager version and exit"), NULL },
+		{ "no-daemon", 'n', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &global_opt.become_daemon, N_("Don't become a daemon"), NULL },
+		{ "debug", 'd', 0, G_OPTION_ARG_NONE, &global_opt.debug, N_("Don't become a daemon, and log to stderr"), NULL },
+		{ "log-level", 0, 0, G_OPTION_ARG_STRING, &global_opt.opt_log_level, N_("Log level: one of [%s]"), "INFO" },
+		{ "log-domains", 0, 0, G_OPTION_ARG_STRING, &global_opt.opt_log_domains,
+		  N_("Log domains separated by ',': any combination of [%s]"),
+		  "PLATFORM,RFKILL,WIFI" },
+		{ "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &global_opt.g_fatal_warnings, N_("Make all warnings fatal"), NULL },
+		{ "pid-file", 'p', 0, G_OPTION_ARG_FILENAME, &global_opt.pidfile, N_("Specify the location of a PID file"), N_("filename") },
+		{ "state-file", 0, 0, G_OPTION_ARG_FILENAME, &global_opt.state_file, N_("State file location"), N_("/path/to/state.file") },
+		{ "run-from-build-dir", 0, 0, G_OPTION_ARG_NONE, &global_opt.run_from_build_dir, "Run from build directory", NULL },
+		{NULL}
+	};
+
+	if (!nm_main_utils_early_setup ("NetworkManager",
+	                                argc,
+	                                argv,
+	                                options,
+	                                nm_config_get_options (),
+	                                _("NetworkManager monitors all network connections and automatically\nchooses the best connection to use.  It also allows the user to\nspecify wireless access points which wireless cards in the computer\nshould associate with.")))
+		exit (1);
+
+	global_opt.pidfile = global_opt.pidfile ? global_opt.pidfile : g_strdup (NM_DEFAULT_PID_FILE);
+	global_opt.state_file = global_opt.state_file ? global_opt.state_file : g_strdup (NM_DEFAULT_SYSTEM_STATE_FILE);
 }
 
 /*
@@ -193,19 +253,11 @@ manager_configure_quit (NMManager *manager, gpointer user_data)
 int
 main (int argc, char *argv[])
 {
-	char *opt_log_level = NULL;
-	char *opt_log_domains = NULL;
-	gboolean become_daemon = TRUE, run_from_build_dir = FALSE;
-	gboolean debug = FALSE;
-	gboolean g_fatal_warnings = FALSE;
-	gs_free char *pidfile = NULL;
-	gs_free char *state_file = NULL;
 	gboolean wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE, wimax_enabled = TRUE;
-	gboolean success, show_version = FALSE;
+	gboolean success = FALSE;
 	NMManager *manager = NULL;
 	gs_unref_object NMVpnManager *vpn_manager = NULL;
 	gs_unref_object NMDnsManager *dns_mgr = NULL;
-	gs_unref_object NMDBusManager *dbus_mgr = NULL;
 	gs_unref_object NMSupplicantManager *sup_mgr = NULL;
 	gs_unref_object NMDhcpManager *dhcp_mgr = NULL;
 	gs_unref_object NMFirewallManager *fw_mgr = NULL;
@@ -215,58 +267,40 @@ main (int argc, char *argv[])
 	GError *error = NULL;
 	gboolean wrote_pidfile = FALSE;
 	char *bad_domains = NULL;
-	gboolean quit_early = FALSE;
 
-	GOptionEntry options[] = {
-		{ "version", 'V', 0, G_OPTION_ARG_NONE, &show_version, N_("Print NetworkManager version and exit"), NULL },
-		{ "no-daemon", 'n', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &become_daemon, N_("Don't become a daemon"), NULL },
-		{ "debug", 'd', 0, G_OPTION_ARG_NONE, &debug, N_("Don't become a daemon, and log to stderr"), NULL },
-		{ "log-level", 0, 0, G_OPTION_ARG_STRING, &opt_log_level, N_("Log level: one of [%s]"), "INFO" },
-		{ "log-domains", 0, 0, G_OPTION_ARG_STRING, &opt_log_domains,
-		  N_("Log domains separated by ',': any combination of [%s]"),
-		  "PLATFORM,RFKILL,WIFI" },
-		{ "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &g_fatal_warnings, N_("Make all warnings fatal"), NULL },
-		{ "pid-file", 'p', 0, G_OPTION_ARG_FILENAME, &pidfile, N_("Specify the location of a PID file"), N_("filename") },
-		{ "state-file", 0, 0, G_OPTION_ARG_FILENAME, &state_file, N_("State file location"), N_("/path/to/state.file") },
-		{ "run-from-build-dir", 0, 0, G_OPTION_ARG_NONE, &run_from_build_dir, "Run from build directory", NULL },
-		{NULL}
-	};
+#if !GLIB_CHECK_VERSION (2, 35, 0)
+	g_type_init ();
+#endif
 
 	_nm_utils_is_manager_process = TRUE;
 
 	main_loop = g_main_loop_new (NULL, FALSE);
 
-	if (!nm_main_utils_early_setup ("NetworkManager",
-	                                &argv,
-	                                &argc,
-	                                options,
-	                                nm_config_get_options (),
-	                                _("NetworkManager monitors all network connections and automatically\nchooses the best connection to use.  It also allows the user to\nspecify wireless access points which wireless cards in the computer\nshould associate with.")))
-		exit (1);
+	do_early_setup (&argc, &argv);
+
+	if (global_opt.g_fatal_warnings)
+		_set_g_fatal_warnings ();
 
-	if (show_version) {
+	if (global_opt.show_version) {
 		fprintf (stdout, NM_DIST_VERSION "\n");
 		exit (0);
 	}
 
-	if (!nm_logging_setup (opt_log_level,
-	                       opt_log_domains,
-	                       &bad_domains,
-	                       &error)) {
-		fprintf (stderr,
-		         _("%s.  Please use --help to see a list of valid options.\n"),
-		         error->message);
+	nm_main_utils_ensure_root ();
+
+	nm_main_utils_ensure_not_running_pidfile (global_opt.pidfile);
+
+	/* Ensure state directory exists */
+	if (g_mkdir_with_parents (NMSTATEDIR, 0755) != 0) {
+		fprintf (stderr, "Cannot create '%s': %s", NMSTATEDIR, strerror (errno));
 		exit (1);
-	} else if (bad_domains) {
-		fprintf (stderr,
-		         _("Ignoring unrecognized log domain(s) '%s' passed on command line.\n"),
-		         bad_domains);
-		g_clear_pointer (&bad_domains, g_free);
 	}
 
+	nm_main_utils_ensure_rundir ();
+
 	/* When running from the build directory, determine our build directory
 	 * base and set helper paths in the build tree */
-	if (run_from_build_dir) {
+	if (global_opt.run_from_build_dir) {
 		char *path, *slash;
 		int g;
 
@@ -288,19 +322,21 @@ main (int argc, char *argv[])
 		g_free (path);
 	}
 
-	/* Ensure state directory exists */
-	if (g_mkdir_with_parents (NMSTATEDIR, 0755) != 0) {
-		nm_log_err (LOGD_CORE, "Cannot create '%s': %s", NMSTATEDIR, strerror (errno));
+	if (!nm_logging_setup (global_opt.opt_log_level,
+	                       global_opt.opt_log_domains,
+	                       &bad_domains,
+	                       &error)) {
+		fprintf (stderr,
+		         _("%s.  Please use --help to see a list of valid options.\n"),
+		         error->message);
 		exit (1);
+	} else if (bad_domains) {
+		fprintf (stderr,
+		         _("Ignoring unrecognized log domain(s) '%s' passed on command line.\n"),
+		         bad_domains);
+		g_clear_pointer (&bad_domains, g_free);
 	}
 
-	pidfile = pidfile ? pidfile : g_strdup (NM_DEFAULT_PID_FILE);
-	state_file = state_file ? state_file : g_strdup (NM_DEFAULT_SYSTEM_STATE_FILE);
-
-	/* check pid file */
-	if (nm_main_utils_check_pidfile (pidfile, "NetworkManager"))
-		exit (1);
-
 	/* Read the config file and CLI overrides */
 	config = nm_config_new (&error);
 	if (config == NULL) {
@@ -310,10 +346,12 @@ main (int argc, char *argv[])
 		exit (1);
 	}
 
+	_init_nm_debug (nm_config_get_debug (config));
+
 	/* Initialize logging from config file *only* if not explicitly
 	 * specified by commandline.
 	 */
-	if (opt_log_level == NULL && opt_log_domains == NULL) {
+	if (global_opt.opt_log_level == NULL && global_opt.opt_log_domains == NULL) {
 		if (!nm_logging_setup (nm_config_get_log_level (config),
 		                       nm_config_get_log_domains (config),
 		                       &bad_domains,
@@ -329,17 +367,7 @@ main (int argc, char *argv[])
 		}
 	}
 
-	/* 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"),
-		         state_file,
-		         error ? error->code : -1,
-		         (error && error->message) ? error->message : _("unknown"));
-		/* Not a hard failure */
-	}
-	g_clear_error (&error);
-
-	if (become_daemon && !debug) {
+	if (global_opt.become_daemon && !global_opt.debug) {
 		if (daemon (0, 0) < 0) {
 			int saved_errno;
 
@@ -349,28 +377,26 @@ main (int argc, char *argv[])
 			         saved_errno);
 			exit (1);
 		}
-		wrote_pidfile = nm_main_utils_write_pidfile (pidfile);
+		wrote_pidfile = nm_main_utils_write_pidfile (global_opt.pidfile);
 	}
 
-	_init_nm_debug (nm_config_get_debug (config));
-
 	/* Set up unix signal handling - before creating threads, but after daemonizing! */
 	if (!nm_main_utils_setup_signals (main_loop, &quit_early))
 		exit (1);
 
-	if (g_fatal_warnings) {
-		GLogLevelFlags fatal_mask;
+	nm_logging_syslog_openlog (global_opt.debug);
 
-		fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
-		fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
-		g_log_set_always_fatal (fatal_mask);
-	}
-
-	nm_logging_syslog_openlog (debug);
+	nm_log_info (LOGD_CORE, "NetworkManager (version " NM_DIST_VERSION ") is starting...");
 
-#if !GLIB_CHECK_VERSION (2, 35, 0)
-	g_type_init ();
-#endif
+	/* Parse the state file */
+	if (!parse_state_file (global_opt.state_file, &net_enabled, &wifi_enabled, &wwan_enabled, &wimax_enabled, &error)) {
+		nm_log_err (LOGD_CORE, "State file %s parsing failed: (%d) %s",
+		            global_opt.state_file,
+		            error ? error->code : -1,
+		            (error && error->message) ? error->message : _("unknown"));
+		/* Not a hard failure */
+	}
+	g_clear_error (&error);
 
 	dbus_threads_init_default ();
 
@@ -379,9 +405,6 @@ main (int argc, char *argv[])
 	 */
 	dbus_glib_global_set_disable_legacy_property_access ();
 
-	nm_log_info (LOGD_CORE, "NetworkManager (version " NM_DIST_VERSION ") is starting...");
-	success = FALSE;
-
 	nm_log_info (LOGD_CORE, "Read config: %s", nm_config_get_description (config));
 	nm_log_info (LOGD_CORE, "WEXT support is %s",
 #if HAVE_WEXT
@@ -391,15 +414,26 @@ main (int argc, char *argv[])
 #endif
 	             );
 
+	if (!nm_dbus_manager_get_connection (nm_dbus_manager_get ())) {
+#if HAVE_DBUS_GLIB_100
+		nm_log_warn (LOGD_CORE, "Failed to connect to D-Bus; only private bus is available");
+#else
+		nm_log_err (LOGD_CORE, "Failed to connect to D-Bus, exiting...");
+		goto done;
+#endif
+	} else {
+		/* Start our DBus service */
+		if (!nm_dbus_manager_start_service (nm_dbus_manager_get ())) {
+			nm_log_err (LOGD_CORE, "failed to start the dbus service.");
+			goto done;
+		}
+	}
+
 	/* Set up platform interaction layer */
 	nm_linux_platform_setup ();
 
 	nm_auth_manager_setup (nm_config_get_auth_polkit (config));
 
-	/* Initialize our DBus service & connection */
-	dbus_mgr = nm_dbus_manager_get ();
-	g_assert (dbus_mgr != NULL);
-
 	vpn_manager = nm_vpn_manager_get ();
 	g_assert (vpn_manager != NULL);
 
@@ -420,7 +454,7 @@ main (int argc, char *argv[])
 	}
 
 	manager = nm_manager_new (settings,
-	                          state_file,
+	                          global_opt.state_file,
 	                          net_enabled,
 	                          wifi_enabled,
 	                          wwan_enabled,
@@ -444,21 +478,6 @@ main (int argc, char *argv[])
 	session_monitor = nm_session_monitor_get ();
 	g_assert (session_monitor != NULL);
 
-	if (!nm_dbus_manager_get_connection (dbus_mgr)) {
-#if HAVE_DBUS_GLIB_100
-		nm_log_warn (LOGD_CORE, "Failed to connect to D-Bus; only private bus is available");
-#else
-		nm_log_err (LOGD_CORE, "Failed to connect to D-Bus, exiting...");
-		goto done;
-#endif
-	} else {
-		/* Start our DBus service */
-		if (!nm_dbus_manager_start_service (dbus_mgr)) {
-			nm_log_err (LOGD_CORE, "failed to start the dbus service.");
-			goto done;
-		}
-	}
-
 	g_signal_connect (manager, NM_MANAGER_CONFIGURE_QUIT, G_CALLBACK (manager_configure_quit), config);
 
 	nm_manager_start (manager);
@@ -489,8 +508,8 @@ done:
 
 	nm_logging_syslog_closelog ();
 
-	if (pidfile && wrote_pidfile)
-		unlink (pidfile);
+	if (global_opt.pidfile && wrote_pidfile)
+		unlink (global_opt.pidfile);
 
 	nm_log_info (LOGD_CORE, "exiting (%s)", success ? "success" : "error");
 	exit (success ? 0 : 1);