static int run_bridge (const gchar *interactive) { CockpitTransport *transport; CockpitBridge *bridge; gboolean terminated = FALSE; gboolean interupted = FALSE; gboolean closed = FALSE; gboolean init_received = FALSE; guint sig_term; guint sig_int; int outfd; cockpit_set_journal_logging (G_LOG_DOMAIN, !isatty (2)); /* * This process talks on stdin/stdout. However lots of stuff wants to write * to stdout, such as g_debug, and uses fd 1 to do that. Reroute fd 1 so that * it goes to stderr, and use another fd for stdout. */ outfd = dup (1); if (outfd < 0 || dup2 (2, 1) < 1) { g_warning ("bridge couldn't redirect stdout to stderr"); outfd = 1; } sig_term = g_unix_signal_add (SIGTERM, on_signal_done, &terminated); sig_int = g_unix_signal_add (SIGINT, on_signal_done, &interupted); g_type_init (); cockpit_dbus_json_allow_external = FALSE; packages = cockpit_packages_new (); cockpit_dbus_internal_startup (interactive != NULL); if (interactive) { /* Allow skipping the init message when interactive */ init_received = TRUE; transport = cockpit_interact_transport_new (0, outfd, interactive); } else { transport = cockpit_pipe_transport_new_fds ("stdio", 0, outfd); } g_resources_register (cockpitassets_get_resource ()); cockpit_web_failure_resource = "/org/cockpit-project/Cockpit/fail.html"; bridge = cockpit_bridge_new (transport, payload_types, init_received); cockpit_dbus_environment_startup (); g_signal_connect (transport, "closed", G_CALLBACK (on_closed_set_flag), &closed); send_init_command (transport); while (!terminated && !closed && !interupted) g_main_context_iteration (NULL, TRUE); g_object_unref (bridge); g_object_unref (transport); cockpit_packages_free (packages); packages = NULL; g_source_remove (sig_term); g_source_remove (sig_int); /* So the caller gets the right signal */ if (terminated) raise (SIGTERM); return 0; }
static int run_bridge (const gchar *interactive, gboolean privileged_slave) { CockpitTransport *transport; gboolean terminated = FALSE; gboolean interupted = FALSE; gboolean closed = FALSE; CockpitPortal *super = NULL; CockpitPortal *pcp = NULL; gpointer polkit_agent = NULL; const gchar *directory; struct passwd *pwd; GPid daemon_pid = 0; GPid agent_pid = 0; guint sig_term; guint sig_int; int outfd; uid_t uid; cockpit_set_journal_logging (G_LOG_DOMAIN, !isatty (2)); /* * The bridge always runs from within $XDG_RUNTIME_DIR * This makes it easy to create user sockets and/or files. */ if (!privileged_slave) { directory = g_get_user_runtime_dir (); if (g_mkdir_with_parents (directory, 0700) < 0) g_warning ("couldn't create runtime dir: %s: %s", directory, g_strerror (errno)); else if (g_chdir (directory) < 0) g_warning ("couldn't change to runtime dir: %s: %s", directory, g_strerror (errno)); } /* Always set environment variables early */ uid = geteuid(); pwd = getpwuid_a (uid); if (pwd == NULL) { g_message ("couldn't get user info: %s", g_strerror (errno)); } else { g_setenv ("USER", pwd->pw_name, TRUE); g_setenv ("HOME", pwd->pw_dir, TRUE); g_setenv ("SHELL", pwd->pw_shell, TRUE); } /* Reset the umask, typically this is done in .bashrc for a login shell */ umask (022); /* * This process talks on stdin/stdout. However lots of stuff wants to write * to stdout, such as g_debug, and uses fd 1 to do that. Reroute fd 1 so that * it goes to stderr, and use another fd for stdout. */ outfd = dup (1); if (outfd < 0 || dup2 (2, 1) < 1) { g_warning ("bridge couldn't redirect stdout to stderr"); outfd = 1; } sig_term = g_unix_signal_add (SIGTERM, on_signal_done, &terminated); sig_int = g_unix_signal_add (SIGINT, on_signal_done, &interupted); g_type_init (); /* Start daemons if necessary */ if (!interactive && !privileged_slave) { if (!have_env ("DBUS_SESSION_BUS_ADDRESS")) daemon_pid = start_dbus_daemon (); if (!have_env ("SSH_AUTH_SOCK")) agent_pid = start_ssh_agent (); } packages = cockpit_packages_new (); cockpit_dbus_internal_startup (interactive != NULL); if (interactive) { /* Allow skipping the init message when interactive */ init_received = TRUE; transport = cockpit_interact_transport_new (0, outfd, interactive); } else { transport = cockpit_pipe_transport_new_fds ("stdio", 0, outfd); } if (uid != 0) { if (!interactive) polkit_agent = cockpit_polkit_agent_register (transport, NULL); super = cockpit_portal_new_superuser (transport); } g_resources_register (cockpitassets_get_resource ()); cockpit_web_failure_resource = "/org/cockpit-project/Cockpit/fail.html"; pcp = cockpit_portal_new_pcp (transport); cockpit_dbus_time_startup (); cockpit_dbus_user_startup (pwd); cockpit_dbus_setup_startup (); g_free (pwd); pwd = NULL; g_signal_connect (transport, "control", G_CALLBACK (on_transport_control), NULL); g_signal_connect (transport, "closed", G_CALLBACK (on_closed_set_flag), &closed); send_init_command (transport); /* Owns the channels */ channels = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); while (!terminated && !closed && !interupted) g_main_context_iteration (NULL, TRUE); if (polkit_agent) cockpit_polkit_agent_unregister (polkit_agent); if (super) g_object_unref (super); g_object_unref (pcp); g_object_unref (transport); g_hash_table_destroy (channels); cockpit_dbus_internal_cleanup (); cockpit_packages_free (packages); packages = NULL; if (daemon_pid) kill (daemon_pid, SIGTERM); if (agent_pid) kill (agent_pid, SIGTERM); g_source_remove (sig_term); g_source_remove (sig_int); /* So the caller gets the right signal */ if (terminated) raise (SIGTERM); return 0; }
int main (int argc, char **argv) { GError *error; GOptionContext *opt_context; gint ret; guint name_owner_id; guint sigint_id; ret = 1; loop = NULL; opt_context = NULL; name_owner_id = 0; sigint_id = 0; /* Ignore SIGPIPE, it's not useful in daemons */ signal (SIGPIPE, SIG_IGN); g_type_init (); g_setenv ("GIO_USE_PROXY_RESOLVER", "dummy", TRUE); /* avoid gvfs (http://bugzilla.gnome.org/show_bug.cgi?id=526454) */ if (!g_setenv ("GIO_USE_VFS", "local", TRUE)) { g_printerr ("Error setting GIO_USE_GVFS\n"); goto out; } opt_context = g_option_context_new ("cockpit storage daemon"); g_option_context_add_main_entries (opt_context, opt_entries, NULL); error = NULL; if (!g_option_context_parse (opt_context, &argc, &argv, &error)) { g_printerr ("Error parsing options: %s\n", error->message); g_error_free (error); goto out; } if (g_getenv ("PATH") == NULL) g_setenv ("PATH", "/usr/bin:/bin:/usr/sbin:/sbin", TRUE); if (!opt_debug) cockpit_set_journal_logging (); g_info ("cockpit daemon version %s starting", PACKAGE_VERSION); loop = g_main_loop_new (NULL, FALSE); sigint_id = 0; if (!opt_no_sigint) { sigint_id = g_unix_signal_add_full (G_PRIORITY_DEFAULT, SIGINT, on_sigint, NULL, /* user_data */ NULL); /* GDestroyNotify */ } name_owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, "com.redhat.Cockpit", G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | (opt_replace ? G_BUS_NAME_OWNER_FLAGS_REPLACE : 0), on_bus_acquired, on_name_acquired, on_name_lost, NULL, NULL); g_main_loop_run (loop); ret = 0; out: if (sigint_id > 0) g_source_remove (sigint_id); if (the_daemon != NULL) g_object_unref (the_daemon); if (name_owner_id != 0) g_bus_unown_name (name_owner_id); if (loop != NULL) g_main_loop_unref (loop); if (opt_context != NULL) g_option_context_free (opt_context); g_info ("cockpit daemon version %s exiting", PACKAGE_VERSION); return ret; }
int main (int argc, char *argv[]) { gint ret = 1; CockpitWebServer *server = NULL; GOptionContext *context; CockpitHandlerData data; GTlsCertificate *certificate = NULL; GError *local_error = NULL; GError **error = &local_error; gchar **roots = NULL; gchar *cert_path = NULL; GMainLoop *loop = NULL; gchar *login_html = NULL; gchar *login_po_html = NULL; CockpitPipe *pipe = NULL; int outfd = -1; signal (SIGPIPE, SIG_IGN); g_setenv ("GSETTINGS_BACKEND", "memory", TRUE); g_setenv ("GIO_USE_PROXY_RESOLVER", "dummy", TRUE); g_setenv ("GIO_USE_VFS", "local", TRUE); /* Any interaction with a krb5 ccache should be explicit */ g_setenv ("KRB5CCNAME", "FILE:/dev/null", TRUE); g_setenv ("G_TLS_GNUTLS_PRIORITY", "SECURE128:%LATEST_RECORD_VERSION:-VERS-SSL3.0:-VERS-TLS1.0", FALSE); memset (&data, 0, sizeof (data)); context = g_option_context_new (NULL); g_option_context_add_main_entries (context, cmd_entries, NULL); if (!g_option_context_parse (context, &argc, &argv, error)) { goto out; } if (opt_version) { print_version (); ret = 0; goto out; } /* * This process talks on stdin/stdout. However lots of stuff wants to write * to stdout, such as g_debug, and uses fd 1 to do that. Reroute fd 1 so that * it goes to stderr, and use another fd for stdout. */ outfd = dup (1); if (outfd < 0 || dup2 (2, 1) < 1) { g_printerr ("ws couldn't redirect stdout to stderr"); if (outfd > -1) close (outfd); goto out; } cockpit_set_journal_logging (NULL, !isatty (2)); if (opt_local_session || opt_no_tls) { /* no certificate */ } else { cert_path = cockpit_certificate_locate (FALSE, error); if (cert_path != NULL) certificate = cockpit_certificate_load (cert_path, error); if (certificate == NULL) goto out; g_info ("Using certificate: %s", cert_path); } loop = g_main_loop_new (NULL, FALSE); data.os_release = cockpit_system_load_os_release (); data.auth = cockpit_auth_new (opt_local_ssh); roots = setup_static_roots (data.os_release); data.branding_roots = (const gchar **)roots; login_html = g_strdup (DATADIR "/cockpit/static/login.html"); data.login_html = (const gchar *)login_html; login_po_html = g_strdup (DATADIR "/cockpit/static/login.po.html"); data.login_po_html = (const gchar *)login_po_html; server = cockpit_web_server_new (opt_address, opt_port, certificate, NULL, error); if (server == NULL) { g_prefix_error (error, "Error starting web server: "); goto out; } cockpit_web_server_set_redirect_tls (server, !cockpit_conf_bool ("WebService", "AllowUnencrypted", FALSE)); if (cockpit_conf_string ("WebService", "UrlRoot")) { g_object_set (server, "url-root", cockpit_conf_string ("WebService", "UrlRoot"), NULL); } if (cockpit_web_server_get_socket_activated (server)) g_signal_connect_swapped (data.auth, "idling", G_CALLBACK (g_main_loop_quit), loop); /* Ignores stuff it shouldn't handle */ g_signal_connect (server, "handle-stream", G_CALLBACK (cockpit_handler_socket), &data); /* External channels, ignore stuff they shouldn't handle */ g_signal_connect (server, "handle-stream", G_CALLBACK (cockpit_handler_external), &data); /* Don't redirect to TLS for /ping */ g_object_set (server, "ssl-exception-prefix", "/ping", NULL); g_signal_connect (server, "handle-resource::/ping", G_CALLBACK (cockpit_handler_ping), &data); /* Files that cannot be cache-forever, because of well known names */ g_signal_connect (server, "handle-resource::/favicon.ico", G_CALLBACK (cockpit_handler_root), &data); g_signal_connect (server, "handle-resource::/apple-touch-icon.png", G_CALLBACK (cockpit_handler_root), &data); /* The fallback handler for everything else */ g_signal_connect (server, "handle-resource", G_CALLBACK (cockpit_handler_default), &data); if (opt_local_session) { struct passwd *pwd; if (g_str_equal (opt_local_session, "-")) { pipe = cockpit_pipe_new (opt_local_session, 0, outfd); outfd = -1; } else { const gchar *args[] = { opt_local_session, NULL }; pipe = cockpit_pipe_spawn (args, NULL, NULL, COCKPIT_PIPE_FLAGS_NONE); } /* Spawn a local session as a bridge */ pwd = getpwuid (geteuid ()); if (!pwd) { g_printerr ("Failed to resolve current user id %u\n", geteuid ()); goto out; } cockpit_auth_local_async (data.auth, pwd->pw_name, pipe, on_local_ready, g_object_ref (server)); g_object_unref (pipe); } else { /* When no local bridge, start serving immediately */ cockpit_web_server_start (server); } /* Debugging issues during testing */ #if WITH_DEBUG signal (SIGABRT, cockpit_test_signal_backtrace); signal (SIGSEGV, cockpit_test_signal_backtrace); #endif g_main_loop_run (loop); ret = 0; out: if (outfd >= 0) close (outfd); if (loop) g_main_loop_unref (loop); if (local_error) { g_printerr ("cockpit-ws: %s\n", local_error->message); g_error_free (local_error); } g_clear_object (&server); g_clear_object (&data.auth); if (data.os_release) g_hash_table_unref (data.os_release); g_clear_object (&certificate); g_free (cert_path); g_strfreev (roots); g_free (login_po_html); g_free (login_html); g_free (opt_address); g_free (opt_local_session); cockpit_conf_cleanup (); return ret; }
int main (int argc, char *argv[]) { gint ret = 1; CockpitWebServer *server = NULL; GOptionContext *context; CockpitHandlerData data; GError *local_error = NULL; GError **error = &local_error; GMainLoop *loop; g_type_init (); memset (&data, 0, sizeof (data)); context = g_option_context_new (NULL); g_option_context_add_main_entries (context, cmd_entries, NULL); if (!g_option_context_parse (context, &argc, &argv, error)) { goto out; } if (!opt_debug) cockpit_set_journal_logging (); if (opt_http_root == NULL) opt_http_root = g_strdup (PACKAGE_DATA_DIR "/cockpit/content"); if (opt_no_tls) { /* no certificate */ } else { if (!load_cert (&data.certificate, error)) goto out; } if (!opt_disable_auth) data.auth = cockpit_auth_new (); data.system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error); if (data.system_bus == NULL) { g_prefix_error (error, "Error getting system bus: "); goto out; } server = cockpit_web_server_new (opt_port, data.certificate, opt_http_root, NULL, error); if (server == NULL) { g_prefix_error (error, "Error starting web server: "); goto out; } /* Ignores stuff it shouldn't handle */ g_signal_connect (server, "handle-resource", G_CALLBACK (cockpit_handler_socket), &data); g_signal_connect (server, "handle-resource::/login", G_CALLBACK (cockpit_handler_login), &data); g_signal_connect (server, "handle-resource::/logout", G_CALLBACK (cockpit_handler_logout), &data); g_signal_connect (server, "handle-resource::/cockpitdyn.js", G_CALLBACK (cockpit_handler_cockpitdyn), &data); g_info ("HTTP Server listening on port %d", opt_port); loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (loop); g_main_loop_unref (loop); ret = 0; out: g_free (opt_http_root); if (local_error) { g_printerr ("%s (%s, %d)\n", local_error->message, g_quark_to_string (local_error->domain), local_error->code); g_error_free (local_error); } g_clear_object (&server); g_clear_object (&data.auth); g_clear_object (&data.system_bus); g_clear_object (&data.certificate); return ret; }
int main (int argc, char *argv[]) { gint ret = 1; CockpitWebServer *server = NULL; GOptionContext *context; CockpitHandlerData data; GTlsCertificate *certificate = NULL; GError *local_error = NULL; GError **error = &local_error; gchar **roots = NULL; gchar *cert_path = NULL; GMainLoop *loop; signal (SIGPIPE, SIG_IGN); g_setenv ("GSETTINGS_BACKEND", "memory", TRUE); g_setenv ("GIO_USE_PROXY_RESOLVER", "dummy", TRUE); g_setenv ("GIO_USE_VFS", "local", TRUE); /* Any interaction with a krb5 ccache should be explicit */ g_setenv ("KRB5CCNAME", "FILE:/dev/null", TRUE); g_type_init (); ssh_init (); memset (&data, 0, sizeof (data)); context = g_option_context_new (NULL); g_option_context_add_main_entries (context, cmd_entries, NULL); if (!g_option_context_parse (context, &argc, &argv, error)) { goto out; } cockpit_set_journal_logging (!isatty (2)); if (opt_no_tls) { /* no certificate */ } else { cert_path = cockpit_certificate_locate (FALSE, error); if (cert_path != NULL) certificate = cockpit_certificate_load (cert_path, error); if (certificate == NULL) goto out; g_info ("Using certificate: %s", cert_path); } if (opt_uninstalled) { roots = cockpit_web_server_resolve_roots (SRCDIR "/src/static", SRCDIR "/lib", NULL); cockpit_ws_bridge_program = BUILDDIR "/cockpit-bridge"; cockpit_ws_session_program = BUILDDIR "/cockpit-session"; } else { roots = cockpit_web_server_resolve_roots (DATADIR "/cockpit/static", NULL); } data.auth = cockpit_auth_new (); data.static_roots = (const gchar **)roots; server = cockpit_web_server_new (opt_port, certificate, NULL, NULL, error); if (server == NULL) { g_prefix_error (error, "Error starting web server: "); goto out; } /* Ignores stuff it shouldn't handle */ g_signal_connect (server, "handle-stream", G_CALLBACK (cockpit_handler_socket), &data); g_signal_connect (server, "handle-resource::/login", G_CALLBACK (cockpit_handler_login), &data); /* Don't redirect to TLS for /ping */ g_object_set (server, "ssl-exception-prefix", "/ping", NULL); g_signal_connect (server, "handle-resource::/ping", G_CALLBACK (cockpit_handler_ping), &data); g_signal_connect (server, "handle-resource::/", G_CALLBACK (cockpit_handler_index), &data); g_signal_connect (server, "handle-resource::/static/", G_CALLBACK (cockpit_handler_static), &data); g_signal_connect (server, "handle-resource::/cockpit/", G_CALLBACK (cockpit_handler_resource), &data); /* Files that cannot be cache-forever, because of well known names */ g_signal_connect (server, "handle-resource::/favicon.ico", G_CALLBACK (cockpit_handler_root), &data); g_signal_connect (server, "handle-resource::/apple-touch-icon.png", G_CALLBACK (cockpit_handler_root), &data); g_info ("HTTP Server listening on port %d", opt_port); loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (loop); g_main_loop_unref (loop); ret = 0; out: if (local_error) { g_printerr ("cockpit-ws: %s\n", local_error->message); g_error_free (local_error); } g_clear_object (&server); g_clear_object (&data.auth); g_clear_object (&certificate); g_free (cert_path); g_strfreev (roots); return ret; }
int main (int argc, char *argv[]) { gint ret = 1; CockpitWebServer *server = NULL; GOptionContext *context; CockpitHandlerData data; GTlsCertificate *certificate = NULL; GError *local_error = NULL; GError **error = &local_error; gchar **roots = NULL; gchar *cert_path = NULL; GMainLoop *loop = NULL; signal (SIGPIPE, SIG_IGN); g_setenv ("GSETTINGS_BACKEND", "memory", TRUE); g_setenv ("GIO_USE_PROXY_RESOLVER", "dummy", TRUE); g_setenv ("GIO_USE_VFS", "local", TRUE); /* Any interaction with a krb5 ccache should be explicit */ g_setenv ("KRB5CCNAME", "FILE:/dev/null", TRUE); g_setenv ("G_TLS_GNUTLS_PRIORITY", "SECURE128:%LATEST_RECORD_VERSION:-VERS-SSL3.0:-VERS-TLS1.0", FALSE); g_type_init (); ssh_threads_set_callbacks (ssh_threads_get_pthread()); ssh_init (); memset (&data, 0, sizeof (data)); context = g_option_context_new (NULL); g_option_context_add_main_entries (context, cmd_entries, NULL); if (!g_option_context_parse (context, &argc, &argv, error)) { goto out; } if (opt_version) { print_version (); ret = 0; goto out; } cockpit_set_journal_logging (NULL, !isatty (2)); if (opt_no_tls) { /* no certificate */ } else { cert_path = cockpit_certificate_locate (FALSE, error); if (cert_path != NULL) certificate = cockpit_certificate_load (cert_path, error); if (certificate == NULL) goto out; g_info ("Using certificate: %s", cert_path); } loop = g_main_loop_new (NULL, FALSE); data.os_release = cockpit_system_load_os_release (); data.auth = cockpit_auth_new (opt_local_ssh); roots = calculate_static_roots (data.os_release); data.static_roots = (const gchar **)roots; server = cockpit_web_server_new (opt_port, certificate, NULL, NULL, error); if (server == NULL) { g_prefix_error (error, "Error starting web server: "); goto out; } if (cockpit_web_server_get_socket_activated (server)) g_signal_connect_swapped (data.auth, "idling", G_CALLBACK (g_main_loop_quit), loop); /* Ignores stuff it shouldn't handle */ g_signal_connect (server, "handle-stream", G_CALLBACK (cockpit_handler_socket), &data); g_signal_connect (server, "handle-resource::/login", G_CALLBACK (cockpit_handler_login), &data); /* Don't redirect to TLS for /ping */ g_object_set (server, "ssl-exception-prefix", "/ping", NULL); g_signal_connect (server, "handle-resource::/ping", G_CALLBACK (cockpit_handler_ping), &data); g_signal_connect (server, "handle-resource::/", G_CALLBACK (cockpit_handler_resource), &data); g_signal_connect (server, "handle-resource::/cockpit/", G_CALLBACK (cockpit_handler_resource), &data); /* Files that cannot be cache-forever, because of well known names */ g_signal_connect (server, "handle-resource::/favicon.ico", G_CALLBACK (cockpit_handler_root), &data); g_signal_connect (server, "handle-resource::/apple-touch-icon.png", G_CALLBACK (cockpit_handler_root), &data); g_main_loop_run (loop); ret = 0; out: if (loop) g_main_loop_unref (loop); if (local_error) { g_printerr ("cockpit-ws: %s\n", local_error->message); g_error_free (local_error); } g_clear_object (&server); g_clear_object (&data.auth); if (data.os_release) g_hash_table_unref (data.os_release); g_clear_object (&certificate); g_free (cert_path); g_strfreev (roots); cockpit_conf_cleanup (); return ret; }
static int run_bridge (const gchar *interactive) { CockpitTransport *transport; CockpitRouter *router; gboolean terminated = FALSE; gboolean interupted = FALSE; gboolean closed = FALSE; guint sig_term; guint sig_int; int outfd; cockpit_set_journal_logging (G_LOG_DOMAIN, !isatty (2)); /* * This process talks on stdin/stdout. However lots of stuff wants to write * to stdout, such as g_debug, and uses fd 1 to do that. Reroute fd 1 so that * it goes to stderr, and use another fd for stdout. */ outfd = dup (1); if (outfd < 0 || dup2 (2, 1) < 1) { g_warning ("bridge couldn't redirect stdout to stderr"); if (outfd > -1) close (outfd); outfd = 1; } sig_term = g_unix_signal_add (SIGTERM, on_signal_done, &terminated); sig_int = g_unix_signal_add (SIGINT, on_signal_done, &interupted); g_type_init (); cockpit_dbus_json_allow_external = FALSE; cockpit_dbus_internal_startup (interactive != NULL); if (interactive) { transport = cockpit_interact_transport_new (0, outfd, interactive); } else { transport = cockpit_pipe_transport_new_fds ("stdio", 0, outfd); } g_resources_register (cockpitassets_get_resource ()); cockpit_web_failure_resource = "/org/cockpit-project/Cockpit/fail.html"; /* Set a path if nothing is set */ g_setenv ("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 0); router = setup_router (transport); cockpit_dbus_process_startup (); g_signal_connect (transport, "closed", G_CALLBACK (on_closed_set_flag), &closed); send_init_command (transport, interactive ? TRUE : FALSE); while (!terminated && !closed && !interupted) g_main_context_iteration (NULL, TRUE); g_object_unref (router); g_object_unref (transport); g_source_remove (sig_term); g_source_remove (sig_int); /* So the caller gets the right signal */ if (terminated) raise (SIGTERM); return 0; }