Merge "Call g_supplicant_interface_scan with scan_params" into tizen
[platform/upstream/connman.git] / vpn / main.c
old mode 100644 (file)
new mode 100755 (executable)
index 35daca7..debb0ca
@@ -2,7 +2,7 @@
  *
  *  ConnMan VPN daemon
  *
- *  Copyright (C) 2012  Intel Corporation. All rights reserved.
+ *  Copyright (C) 2012-2013  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
 
 #include "connman/vpn-dbus.h"
 
+#define CONFIGMAINFILE CONFIGDIR "/connman-vpn.conf"
+
+#define DEFAULT_INPUT_REQUEST_TIMEOUT 300 * 1000
+#define DEFAULT_BROWSER_LAUNCH_TIMEOUT 300 * 1000
+
 static GMainLoop *main_loop = NULL;
 
 static unsigned int __terminated = 0;
 
+static struct {
+       unsigned int timeout_inputreq;
+       unsigned int timeout_browserlaunch;
+} connman_vpn_settings  = {
+       .timeout_inputreq = DEFAULT_INPUT_REQUEST_TIMEOUT,
+       .timeout_browserlaunch = DEFAULT_BROWSER_LAUNCH_TIMEOUT,
+};
+
+static GKeyFile *load_config(const char *file)
+{
+       GError *err = NULL;
+       GKeyFile *keyfile;
+
+       keyfile = g_key_file_new();
+
+       g_key_file_set_list_separator(keyfile, ',');
+
+       if (!g_key_file_load_from_file(keyfile, file, 0, &err)) {
+               if (err->code != G_FILE_ERROR_NOENT) {
+                       connman_error("Parsing %s failed: %s", file,
+                                                               err->message);
+               }
+
+               g_error_free(err);
+               g_key_file_free(keyfile);
+               return NULL;
+       }
+
+       return keyfile;
+}
+
+static void parse_config(GKeyFile *config, const char *file)
+{
+       GError *error = NULL;
+       int timeout;
+
+       if (!config)
+               return;
+
+       DBG("parsing %s", file);
+
+       timeout = g_key_file_get_integer(config, "General",
+                       "InputRequestTimeout", &error);
+       if (!error && timeout >= 0)
+               connman_vpn_settings.timeout_inputreq = timeout * 1000;
+
+       g_clear_error(&error);
+}
+
+static int config_init(const char *file)
+{
+       GKeyFile *config;
+
+       config = load_config(file);
+       parse_config(config, file);
+       if (config)
+               g_key_file_free(config);
+
+       return 0;
+}
+
 static gboolean signal_handler(GIOChannel *channel, GIOCondition cond,
                                                        gpointer user_data)
 {
@@ -121,13 +187,15 @@ static void disconnect_callback(DBusConnection *conn, void *user_data)
        g_main_loop_quit(main_loop);
 }
 
+static gchar *option_config = NULL;
 static gchar *option_debug = NULL;
 static gchar *option_plugin = NULL;
 static gchar *option_noplugin = NULL;
-static gboolean option_detach = TRUE;
-static gboolean option_version = FALSE;
+static bool option_detach = true;
+static bool option_version = false;
+static bool option_routes = false;
 
-static gboolean parse_debug(const char *key, const char *value,
+static bool parse_debug(const char *key, const char *value,
                                        gpointer user_data, GError **error)
 {
        if (value)
@@ -135,10 +203,13 @@ static gboolean parse_debug(const char *key, const char *value,
        else
                option_debug = g_strdup("*");
 
-       return TRUE;
+       return true;
 }
 
 static GOptionEntry options[] = {
+       { "config", 'c', 0, G_OPTION_ARG_STRING, &option_config,
+                               "Load the specified configuration file "
+                               "instead of " CONFIGMAINFILE, "FILE" },
        { "debug", 'd', G_OPTION_FLAG_OPTIONAL_ARG,
                                G_OPTION_ARG_CALLBACK, parse_debug,
                                "Specify debug options to enable", "DEBUG" },
@@ -149,11 +220,42 @@ static GOptionEntry options[] = {
        { "nodaemon", 'n', G_OPTION_FLAG_REVERSE,
                                G_OPTION_ARG_NONE, &option_detach,
                                "Don't fork daemon to background" },
+       { "routes", 'r', 0, G_OPTION_ARG_NONE, &option_routes,
+                               "Create/delete VPN routes" },
        { "version", 'v', 0, G_OPTION_ARG_NONE, &option_version,
                                "Show version information and exit" },
        { NULL },
 };
 
+bool connman_setting_get_bool(const char *key)
+{
+       return false;
+}
+
+char **connman_setting_get_string_list(const char *key)
+{
+       return NULL;
+}
+
+unsigned int *connman_setting_get_uint_list(const char *key)
+{
+       return NULL;
+}
+
+/*
+ * This function will be called from generic src/agent.c code so we have
+ * to use connman_ prefix instead of vpn_ one.
+ */
+unsigned int connman_timeout_input_request(void)
+{
+       return connman_vpn_settings.timeout_inputreq;
+}
+
+unsigned int connman_timeout_browser_launch(void)
+{
+       return connman_vpn_settings.timeout_browserlaunch;
+}
+
 int main(int argc, char *argv[])
 {
        GOptionContext *context;
@@ -165,8 +267,8 @@ int main(int argc, char *argv[])
        context = g_option_context_new(NULL);
        g_option_context_add_main_entries(context, options, NULL);
 
-       if (g_option_context_parse(context, &argc, &argv, &error) == FALSE) {
-               if (error != NULL) {
+       if (!g_option_context_parse(context, &argc, &argv, &error)) {
+               if (error) {
                        g_printerr("%s\n", error->message);
                        g_error_free(error);
                } else
@@ -176,30 +278,40 @@ int main(int argc, char *argv[])
 
        g_option_context_free(context);
 
-       if (option_version == TRUE) {
+       if (option_version) {
                printf("%s\n", VERSION);
                exit(0);
        }
 
-       if (option_detach == TRUE) {
+       if (option_detach) {
                if (daemon(0, 0)) {
                        perror("Can't start daemon");
                        exit(1);
                }
        }
 
-       if (mkdir(STATEDIR, S_IRUSR | S_IWUSR | S_IXUSR |
+       if (mkdir(VPN_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");
        }
 
+       /*
+        * At some point the VPN stuff is migrated into VPN_STORAGEDIR
+        * and this mkdir() call can be removed.
+        */
        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");
        }
 
+       if (mkdir(VPN_STORAGEDIR, S_IRUSR | S_IWUSR | S_IXUSR |
+                               S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) {
+               if (errno != EEXIST)
+                       perror("Failed to create VPN storage directory");
+       }
+
        umask(0077);
 
        main_loop = g_main_loop_new(NULL, FALSE);
@@ -209,8 +321,8 @@ int main(int argc, char *argv[])
        dbus_error_init(&err);
 
        conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, VPN_SERVICE, &err);
-       if (conn == NULL) {
-               if (dbus_error_is_set(&err) == TRUE) {
+       if (!conn) {
+               if (dbus_error_is_set(&err)) {
                        fprintf(stderr, "%s\n", err.message);
                        dbus_error_free(&err);
                } else
@@ -220,15 +332,24 @@ int main(int argc, char *argv[])
 
        g_dbus_set_disconnect_function(conn, disconnect_callback, NULL, NULL);
 
-       __connman_log_init(argv[0], option_debug, option_detach, FALSE,
+       __connman_log_init(argv[0], option_debug, option_detach, false,
                        "Connection Manager VPN daemon", VERSION);
        __connman_dbus_init(conn);
-       __vpn_provider_init();
+
+       if (!option_config)
+               config_init(CONFIGMAINFILE);
+       else
+               config_init(option_config);
+
+       __connman_inotify_init();
+       __connman_agent_init();
+       __vpn_provider_init(option_routes);
        __vpn_manager_init();
        __vpn_ipconfig_init();
        __vpn_rtnl_init();
        __connman_task_init();
        __connman_plugin_init(option_plugin, option_noplugin);
+       __vpn_config_init();
 
        __vpn_rtnl_start();
 
@@ -239,13 +360,17 @@ int main(int argc, char *argv[])
 
        g_source_remove(signal);
 
+       __vpn_config_cleanup();
+       __connman_plugin_cleanup();
        __connman_task_cleanup();
        __vpn_rtnl_cleanup();
        __vpn_ipconfig_cleanup();
        __vpn_manager_cleanup();
        __vpn_provider_cleanup();
+       __connman_agent_cleanup();
+       __connman_inotify_cleanup();
        __connman_dbus_cleanup();
-       __connman_log_cleanup(FALSE);
+       __connman_log_cleanup(false);
 
        dbus_connection_unref(conn);