| /* |
| * |
| * Connection Manager |
| * |
| * Copyright (C) 2007-2009 Intel Corporation. All rights reserved. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 as |
| * published by the Free Software Foundation. |
| * |
| * 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 St, Fifth Floor, Boston, MA 02110-1301 USA |
| * |
| */ |
| |
| #ifdef HAVE_CONFIG_H |
| #include <config.h> |
| #endif |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <unistd.h> |
| #include <string.h> |
| #include <signal.h> |
| #include <getopt.h> |
| #include <sys/stat.h> |
| #include <net/if.h> |
| |
| #include <gdbus.h> |
| |
| #include "connman.h" |
| |
| static GMainLoop *main_loop = NULL; |
| |
| static void sig_term(int sig) |
| { |
| connman_info("Terminating"); |
| |
| g_main_loop_quit(main_loop); |
| } |
| |
| static void disconnect_callback(DBusConnection *conn, void *user_data) |
| { |
| connman_error("D-Bus disconnect"); |
| |
| g_main_loop_quit(main_loop); |
| } |
| |
| static gchar **option_devices = NULL; |
| static gchar **option_plugins = NULL; |
| static gchar **option_nodevices = NULL; |
| static gchar **option_noplugins = NULL; |
| static gchar **option_profiles = NULL; |
| static gchar *option_wifi = NULL; |
| static gchar *option_keymatter = NULL; |
| static gchar *option_modemmanagers = NULL; |
| static gchar *option_order = NULL; |
| static gchar *option_portal_list = NULL; |
| static gboolean option_detach = TRUE; |
| static gboolean option_compat = FALSE; |
| static gboolean option_version = FALSE; |
| |
| static gboolean option_debug_callback(const gchar *option, |
| const gchar *value, |
| gpointer data, |
| GError **error) |
| { |
| unsigned int *debugmask = (unsigned int *)data; |
| if (value != NULL) |
| *debugmask = __connman_debug_tags_to_mask(value, error); |
| else |
| *debugmask = DBG_ANY; |
| return *error == NULL; |
| } |
| |
| static GOptionEntry options[] = { |
| { "device", 'i', 0, G_OPTION_ARG_STRING_ARRAY, &option_devices, |
| "Specify networking device or interfaces" |
| " (can be repeated)", |
| "DEV" }, |
| { "nodevice", 'I', 0, G_OPTION_ARG_STRING_ARRAY, &option_nodevices, |
| "Specify networking interfaces to ignore" |
| " (can be repeated)", |
| "DEV" }, |
| { "plugin", 'p', 0, G_OPTION_ARG_STRING_ARRAY, &option_plugins, |
| "Specify plugins to load" |
| " (can be repeated)", |
| "NAME" }, |
| { "noplugin", 'P', 0, G_OPTION_ARG_STRING_ARRAY, &option_noplugins, |
| "Specify plugins not to load" |
| " (can be repeated)", |
| "NAME" }, |
| { "push", 'u', 0, G_OPTION_ARG_STRING_ARRAY, &option_profiles, |
| "Specify profiles to push" |
| " (can be repeated)", |
| "NAME" }, |
| { "keymatter", 'k', 0, G_OPTION_ARG_STRING, &option_keymatter, |
| "Specify file containing data to use when " |
| "generating cryptographic keys.", "FILENAME" }, |
| { "wifi", 'W', 0, G_OPTION_ARG_STRING, &option_wifi, |
| "Specify driver for WiFi/Supplicant", "NAME" }, |
| { "modemmanagers", 'm', 0, G_OPTION_ARG_STRING, &option_modemmanagers, |
| "Comma separated list of DBUS modem manager " |
| "services", |
| "SERVICE_NAME:PATH,..." }, |
| { "order", 'o', 0, G_OPTION_ARG_STRING, &option_order, |
| "Specify service priority ordering", |
| "SERVICE,SERVICE,..." }, |
| { "nodaemon", 'n', G_OPTION_FLAG_REVERSE, |
| G_OPTION_ARG_NONE, &option_detach, |
| "Don't fork daemon to background" }, |
| { "compat", 'c', 0, G_OPTION_ARG_NONE, &option_compat, |
| "Enable Network Manager compatibility" }, |
| { "version", 'v', 0, G_OPTION_ARG_NONE, &option_version, |
| "Show version information and exit" }, |
| { "portal-list", 'l', 0, G_OPTION_ARG_STRING, &option_portal_list, |
| "Comma separated list of services to check" }, |
| { NULL }, |
| }; |
| |
| static GOptionEntry debug_options[] = { |
| { "debug", 'd', G_OPTION_FLAG_OPTIONAL_ARG, |
| G_OPTION_ARG_CALLBACK, &option_debug_callback, |
| "Optional list of debug tags, or all tags if omitted", |
| "tag1+tag2+..."}, |
| { NULL } |
| }; |
| |
| const char *connman_option_get_string(const char *key) |
| { |
| if (g_strcmp0(key, "wifi") == 0) { |
| if (option_wifi == NULL) |
| return "nl80211"; |
| else |
| return option_wifi; |
| } |
| if (g_strcmp0(key, "modemmanagers") == 0) { |
| return option_modemmanagers; |
| } |
| if (g_strcmp0(key, "keymatter") == 0) { |
| return option_keymatter; |
| } |
| if (g_strcmp0(key, "portal-list") == 0) { |
| return option_portal_list; |
| } |
| |
| return NULL; |
| } |
| |
| int main(int argc, char *argv[]) |
| { |
| GOptionContext *context; |
| GOptionGroup *dbg_group; |
| GError *error = NULL; |
| DBusConnection *conn; |
| DBusError err; |
| struct sigaction sa; |
| unsigned int debugmask = 0; |
| |
| #ifdef NEED_THREADS |
| if (g_thread_supported() == FALSE) |
| g_thread_init(NULL); |
| #endif |
| |
| context = g_option_context_new(NULL); |
| g_option_context_add_main_entries(context, options, NULL); |
| dbg_group = g_option_group_new( |
| "debug", |
| "Enable debug information output", |
| "Show help for debug options", |
| &debugmask, |
| NULL); |
| g_option_group_add_entries(dbg_group, debug_options); |
| g_option_context_add_group(context, dbg_group); |
| |
| if (g_option_context_parse(context, &argc, &argv, &error) == FALSE) { |
| if (error != NULL) { |
| g_printerr("%s\n", error->message); |
| g_error_free(error); |
| } else |
| g_printerr("An unknown error occurred\n"); |
| exit(1); |
| } |
| |
| g_option_context_free(context); |
| |
| if (option_version == TRUE) { |
| printf("%s\n", VERSION); |
| exit(0); |
| } |
| |
| if (option_detach == TRUE) { |
| if (daemon(0, 0)) { |
| perror("Can't start daemon"); |
| exit(1); |
| } |
| } |
| |
| if (mkdir(STATEDIR, S_IRUSR | S_IWUSR | S_IXUSR | |
| S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) { |
| if (errno != EEXIST) |
| perror("Failed to create state directory"); |
| } |
| |
| if (mkdir(STORAGEDIR, S_IRUSR | S_IWUSR | S_IXUSR | |
| S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) { |
| if (errno != EEXIST) |
| perror("Failed to create storage directory"); |
| } |
| |
| (void) umask(077); |
| |
| main_loop = g_main_loop_new(NULL, FALSE); |
| |
| #ifdef NEED_THREADS |
| if (dbus_threads_init_default() == FALSE) { |
| fprintf(stderr, "Can't init usage of threads\n"); |
| exit(1); |
| } |
| #endif |
| |
| dbus_error_init(&err); |
| |
| conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, CONNMAN_SERVICE, &err); |
| if (conn == NULL) { |
| if (dbus_error_is_set(&err) == TRUE) { |
| fprintf(stderr, "%s\n", err.message); |
| dbus_error_free(&err); |
| } else |
| fprintf(stderr, "Can't register with system bus\n"); |
| exit(1); |
| } |
| |
| g_dbus_set_disconnect_function(conn, disconnect_callback, NULL, NULL); |
| |
| if (option_compat == TRUE) { |
| if (g_dbus_request_name(conn, NM_SERVICE, NULL) == FALSE) { |
| fprintf(stderr, "Can't register compat service\n"); |
| option_compat = FALSE; |
| } |
| } |
| |
| __connman_log_init(option_detach, debugmask); |
| |
| __connman_dbus_init(conn); |
| |
| /* |
| * Crypto has to be initialized before any tries to write or read |
| * an encrypted value. |
| */ |
| __connman_crypto_init(); |
| __connman_storage_init(); |
| __connman_element_init(option_devices, option_nodevices, option_order); |
| |
| __connman_agent_init(); |
| __connman_manager_init(option_compat); |
| __connman_profile_init(); |
| |
| __connman_resolver_init(); |
| __connman_ipconfig_init(); |
| __connman_ipv4_init(); |
| __connman_ipv6_init(); |
| __connman_portal_init(); |
| __connman_dns_client_init(); |
| __connman_rtnl_init(); |
| __connman_security_init(); |
| __connman_udev_init(); |
| __connman_task_init(); |
| |
| __connman_plugin_init(option_plugins, option_noplugins); |
| |
| __connman_element_start(); |
| |
| __connman_profile_push_batch(option_profiles); |
| |
| g_strfreev(option_devices); |
| g_strfreev(option_plugins); |
| g_strfreev(option_nodevices); |
| g_strfreev(option_noplugins); |
| g_strfreev(option_profiles); |
| |
| memset(&sa, 0, sizeof(sa)); |
| sa.sa_handler = sig_term; |
| sigaction(SIGINT, &sa, NULL); |
| sigaction(SIGTERM, &sa, NULL); |
| |
| g_main_loop_run(main_loop); |
| |
| __connman_element_stop(); |
| |
| __connman_plugin_cleanup(); |
| |
| __connman_task_cleanup(); |
| __connman_udev_cleanup(); |
| __connman_rtnl_cleanup(); |
| __connman_dns_client_cleanup(); |
| __connman_portal_cleanup(); |
| __connman_ipv6_cleanup(); |
| __connman_ipv4_cleanup(); |
| __connman_ipconfig_cleanup(); |
| __connman_resolver_cleanup(); |
| |
| __connman_profile_cleanup(); |
| __connman_manager_cleanup(); |
| __connman_agent_cleanup(); |
| |
| __connman_element_cleanup(); |
| __connman_storage_cleanup(); |
| __connman_crypto_cleanup(); |
| |
| __connman_dbus_cleanup(); |
| |
| __connman_log_cleanup(); |
| |
| dbus_connection_unref(conn); |
| |
| g_main_loop_unref(main_loop); |
| |
| return 0; |
| } |