diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2016-10-30 16:06:30 +0100 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2016-11-11 15:34:48 +0100 |
commit | 3c9933b546af87273316d57edfd8242ca9030c7f (patch) | |
tree | 74930d4169152feafc9d44a8c63590aa598a0b22 | |
parent | 23d17860776f04f179903b0434d3b17c2af2450a (diff) | |
download | network-manager-applet-3c9933b546af87273316d57edfd8242ca9030c7f.tar.gz |
editor: refactor the VPN import logic
Split the file and the actual import logic, so that it can be invoked
with a file name known in advance.
Also move it into connection-helpers -- it well might in future be extended
to handle other connection types. There's really nothing VPN-specific
about a file picker.
-rw-r--r-- | src/connection-editor/connection-helpers.c | 143 | ||||
-rw-r--r-- | src/connection-editor/connection-helpers.h | 2 | ||||
-rw-r--r-- | src/connection-editor/page-vpn.c | 174 | ||||
-rw-r--r-- | src/connection-editor/page-vpn.h | 8 | ||||
-rw-r--r-- | src/connection-editor/vpn-helpers.c | 86 | ||||
-rw-r--r-- | src/connection-editor/vpn-helpers.h | 3 |
6 files changed, 198 insertions, 218 deletions
diff --git a/src/connection-editor/connection-helpers.c b/src/connection-editor/connection-helpers.c index bff09a05..a9ab69d0 100644 --- a/src/connection-editor/connection-helpers.c +++ b/src/connection-editor/connection-helpers.c @@ -170,6 +170,149 @@ no_description: gtk_label_set_text (label, ""); } +NMConnection * +vpn_connection_from_file (const char *filename) +{ + NMConnection *connection = NULL; + GError *error = NULL; + GSList *iter; + + for (iter = vpn_get_plugin_infos (); !connection && iter; iter = iter->next) { + NMVpnEditorPlugin *plugin; + + plugin = nm_vpn_plugin_info_get_editor_plugin (iter->data); + g_clear_error (&error); + connection = nm_vpn_editor_plugin_import (plugin, filename, &error); + if (connection) + break; + } + + if (connection) { + NMSettingVpn *s_vpn; + const char *service_type; + + s_vpn = nm_connection_get_setting_vpn (connection); + service_type = s_vpn ? nm_setting_vpn_get_service_type (s_vpn) : NULL; + + /* Check connection sanity. */ + if (!service_type || !strlen (service_type)) { + g_object_unref (connection); + connection = NULL; + + error = g_error_new_literal (NMA_ERROR, NMA_ERROR_GENERIC, + _("The VPN plugin failed to import the VPN connection correctly\n\nError: no VPN service type.")); + } + } + + if (!connection) { + GtkWidget *err_dialog; + char *bname = g_path_get_basename (filename); + + err_dialog = gtk_message_dialog_new (NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("Cannot import VPN connection")); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (err_dialog), + _("The file ā%sā could not be read or does not contain recognized VPN connection information\n\nError: %s."), + bname, error ? error->message : _("unknown error")); + g_free (bname); + g_signal_connect (err_dialog, "delete-event", G_CALLBACK (gtk_widget_destroy), NULL); + g_signal_connect (err_dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL); + gtk_widget_show_all (err_dialog); + gtk_window_present (GTK_WINDOW (err_dialog)); + } + + g_clear_error (&error); + + return connection; +} + +typedef struct { + GtkWindow *parent; + NMClient *client; + PageNewConnectionResultFunc result_func; + gpointer user_data; +} ImportVpnInfo; + +static void +import_vpn_from_file_cb (GtkWidget *dialog, gint response, gpointer user_data) +{ + char *filename = NULL; + ImportVpnInfo *info = (ImportVpnInfo *) user_data; + NMConnection *connection = NULL; + + if (response != GTK_RESPONSE_ACCEPT) + goto out; + + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + if (!filename) { + g_warning ("%s: didn't get a filename back from the chooser!", __func__); + goto out; + } + + connection = vpn_connection_from_file (filename); + if (connection) { + /* Wrap around the actual new function so that the page can complete + * the missing parts, such as UUID or make up the connection name. */ + vpn_connection_new (info->parent, + NULL, + NULL, + connection, + info->client, + info->result_func, + info->user_data); + } + + g_free (filename); +out: + gtk_widget_hide (dialog); + gtk_widget_destroy (dialog); + g_object_unref (info->parent); + g_object_unref (info->client); + g_slice_free (ImportVpnInfo, info); +} + +static void +vpn_connection_import (GtkWindow *parent, + const char *detail, + gpointer detail_data, + NMConnection *connection, + NMClient *client, + PageNewConnectionResultFunc result_func, + gpointer user_data) +{ + ImportVpnInfo *info; + GtkWidget *dialog; + const char *home_folder; + + /* The import function decides about the type. */ + g_return_if_fail (!detail); + + /* We're not going to need this one. We'll create another + * when we know the file name to import from. */ + g_object_unref (connection); + + info = g_slice_new (ImportVpnInfo); + info->parent = g_object_ref (parent); + info->result_func = result_func; + info->client = g_object_ref (client); + info->user_data = user_data; + + dialog = gtk_file_chooser_dialog_new (_("Select file to import"), + NULL, + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + NULL); + home_folder = g_get_home_dir (); + gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), home_folder); + + g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (import_vpn_from_file_cb), info); + gtk_widget_show_all (dialog); + gtk_window_present (GTK_WINDOW (dialog)); +} + static void set_up_connection_type_combo (GtkComboBox *combo, GtkLabel *description_label, diff --git a/src/connection-editor/connection-helpers.h b/src/connection-editor/connection-helpers.h index 014bbb32..caf37376 100644 --- a/src/connection-editor/connection-helpers.h +++ b/src/connection-editor/connection-helpers.h @@ -73,5 +73,7 @@ void delete_connection (GtkWindow *parent_window, gboolean connection_supports_ip4 (NMConnection *connection); gboolean connection_supports_ip6 (NMConnection *connection); +NMConnection *vpn_connection_from_file (const char *filename); + #endif /* __CONNECTION_HELPERS_H__ */ diff --git a/src/connection-editor/page-vpn.c b/src/connection-editor/page-vpn.c index 5025eb91..d5923f2b 100644 --- a/src/connection-editor/page-vpn.c +++ b/src/connection-editor/page-vpn.c @@ -191,82 +191,12 @@ typedef struct { gpointer user_data; } NewVpnInfo; -static void -import_cb (NMConnection *connection, gpointer user_data) -{ - NewVpnInfo *info = (NewVpnInfo *) user_data; - NMSettingConnection *s_con; - NMSettingVpn *s_vpn; - const char *service_type; - char *s; - GError *error = NULL; - - /* Basic sanity checks of the connection */ - s_con = nm_connection_get_setting_connection (connection); - if (!s_con) { - s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - } - - s = (char *) nm_setting_connection_get_id (s_con); - if (!s) { - const GPtrArray *connections; - - connections = nm_client_get_connections (info->client); - s = ce_page_get_next_available_name (connections, _("VPN connection %d")); - g_object_set (s_con, NM_SETTING_CONNECTION_ID, s, NULL); - g_free (s); - } - - s = (char *) nm_setting_connection_get_connection_type (s_con); - if (!s || strcmp (s, NM_SETTING_VPN_SETTING_NAME)) - g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, NM_SETTING_VPN_SETTING_NAME, NULL); - - s = (char *) nm_setting_connection_get_uuid (s_con); - if (!s) { - s = nm_utils_uuid_generate (); - g_object_set (s_con, NM_SETTING_CONNECTION_UUID, s, NULL); - g_free (s); - } - - s_vpn = nm_connection_get_setting_vpn (connection); - service_type = s_vpn ? nm_setting_vpn_get_service_type (s_vpn) : NULL; - - if (!service_type || !strlen (service_type)) { - g_object_unref (connection); - connection = NULL; - - error = g_error_new_literal (NMA_ERROR, NMA_ERROR_GENERIC, - _("The VPN plugin failed to import the VPN connection correctly\n\nError: no VPN service type.")); - } - - info->result_func (connection, FALSE, error, info->user_data); - g_clear_error (&error); - g_object_unref (info->client); - g_slice_free (NewVpnInfo, info); -} - -void -vpn_connection_import (GtkWindow *parent, - const char *detail, - gpointer detail_data, - NMConnection *connection, - NMClient *client, - PageNewConnectionResultFunc result_func, - gpointer user_data) -{ - NewVpnInfo *info; +typedef void (*VpnImportSuccessCallback) (NMConnection *connection, gpointer user_data); - /* We're not going to need this one. We'll create another - * when we know the file name to import from. */ - g_object_unref (connection); - - info = g_slice_new (NewVpnInfo); - info->result_func = result_func; - info->client = g_object_ref (client); - info->user_data = user_data; - vpn_import (import_cb, info); -} +typedef struct { + VpnImportSuccessCallback callback; + gpointer user_data; +} ActionInfo; static void complete_vpn_connection (NMConnection *connection, NMClient *client) @@ -315,7 +245,7 @@ vpn_connection_new (GtkWindow *parent, const char *add_detail_key = NULL; const char *add_detail_val = NULL; - if (!detail) { + if (!detail && !connection) { NewVpnInfo *info; /* This will happen if nm-c-e is launched from the command line @@ -333,58 +263,60 @@ vpn_connection_new (GtkWindow *parent, return; } - service_type = detail; - add_detail_key = vpn_data ? vpn_data->add_detail_key : NULL; - add_detail_val = vpn_data ? vpn_data->add_detail_val : NULL; - - service_type_free = nm_vpn_plugin_info_list_find_service_type (vpn_get_plugin_infos (), detail); - if (service_type_free) - service_type = service_type_free; - else if (!vpn_data) { - /* when called without @vpn_data, it means that @detail may contain "<SERVICE_TYPE>:<ADD_DETAIL>". - * Try to parse them by spliting @detail at the colons and try to interpret the first part as - * @service_type and the remainder as add-detail. */ - l = strlen (detail); - for (split_idx = 1; split_idx < l - 1; split_idx++) { - if (detail[split_idx] == ':') { - gs_free char *detail_main = g_strndup (detail, split_idx); - NMVpnEditorPlugin *plugin; - - service_type_free = nm_vpn_plugin_info_list_find_service_type (vpn_get_plugin_infos (), detail_main); - if (!service_type_free) - continue; - plugin = vpn_get_plugin_by_service (service_type_free); - if (!plugin) { - g_clear_pointer (&service_type_free, g_free); - continue; - } - - /* we found a @service_type. Try to use the remainder as add-detail. */ - service_type = service_type_free; - if (nm_vpn_editor_plugin_get_service_add_detail (plugin, service_type, &detail[split_idx + 1], - NULL, NULL, - &add_detail_key_free, &add_detail_val_free, NULL) - && add_detail_key_free && add_detail_key_free[0] - && add_detail_val_free && add_detail_val_free[0]) { - add_detail_key = add_detail_key_free; - add_detail_val = add_detail_val_free; + if (detail) { + service_type = detail; + add_detail_key = vpn_data ? vpn_data->add_detail_key : NULL; + add_detail_val = vpn_data ? vpn_data->add_detail_val : NULL; + + service_type_free = nm_vpn_plugin_info_list_find_service_type (vpn_get_plugin_infos (), detail); + if (service_type_free) + service_type = service_type_free; + else if (!vpn_data) { + /* when called without @vpn_data, it means that @detail may contain "<SERVICE_TYPE>:<ADD_DETAIL>". + * Try to parse them by spliting @detail at the colons and try to interpret the first part as + * @service_type and the remainder as add-detail. */ + l = strlen (detail); + for (split_idx = 1; split_idx < l - 1; split_idx++) { + if (detail[split_idx] == ':') { + gs_free char *detail_main = g_strndup (detail, split_idx); + NMVpnEditorPlugin *plugin; + + service_type_free = nm_vpn_plugin_info_list_find_service_type (vpn_get_plugin_infos (), detail_main); + if (!service_type_free) + continue; + plugin = vpn_get_plugin_by_service (service_type_free); + if (!plugin) { + g_clear_pointer (&service_type_free, g_free); + continue; + } + + /* we found a @service_type. Try to use the remainder as add-detail. */ + service_type = service_type_free; + if (nm_vpn_editor_plugin_get_service_add_detail (plugin, service_type, &detail[split_idx + 1], + NULL, NULL, + &add_detail_key_free, &add_detail_val_free, NULL) + && add_detail_key_free && add_detail_key_free[0] + && add_detail_val_free && add_detail_val_free[0]) { + add_detail_key = add_detail_key_free; + add_detail_val = add_detail_val_free; + } + break; } - break; } } - } - if (!service_type) - service_type = detail; + if (!service_type) + service_type = detail; - complete_vpn_connection (connection, client); + s_vpn = nm_setting_vpn_new (); + g_object_set (s_vpn, NM_SETTING_VPN_SERVICE_TYPE, service_type, NULL); - s_vpn = nm_setting_vpn_new (); - g_object_set (s_vpn, NM_SETTING_VPN_SERVICE_TYPE, service_type, NULL); + if (add_detail_key) + nm_setting_vpn_add_data_item ((NMSettingVpn *) s_vpn, add_detail_key, add_detail_val); - if (add_detail_key) - nm_setting_vpn_add_data_item ((NMSettingVpn *) s_vpn, add_detail_key, add_detail_val); + nm_connection_add_setting (connection, s_vpn); + } - nm_connection_add_setting (connection, s_vpn); + complete_vpn_connection (connection, client); (*result_func) (connection, FALSE, NULL, user_data); } diff --git a/src/connection-editor/page-vpn.h b/src/connection-editor/page-vpn.h index 566851e9..6b52e10a 100644 --- a/src/connection-editor/page-vpn.h +++ b/src/connection-editor/page-vpn.h @@ -67,12 +67,4 @@ void vpn_connection_new (GtkWindow *parent, PageNewConnectionResultFunc result_func, gpointer user_data); -void vpn_connection_import (GtkWindow *parent, - const char *detail, - gpointer detail_data, - NMConnection *connection, - NMClient *client, - PageNewConnectionResultFunc result_func, - gpointer user_data); - #endif /* __PAGE_VPN_H__ */ diff --git a/src/connection-editor/vpn-helpers.c b/src/connection-editor/vpn-helpers.c index a444d0d5..02bb0683 100644 --- a/src/connection-editor/vpn-helpers.c +++ b/src/connection-editor/vpn-helpers.c @@ -97,92 +97,6 @@ vpn_get_plugin_infos (void) return plugins; } -typedef struct { - VpnImportSuccessCallback callback; - gpointer user_data; -} ActionInfo; - -static void -import_vpn_from_file_cb (GtkWidget *dialog, gint response, gpointer user_data) -{ - char *filename = NULL; - ActionInfo *info = (ActionInfo *) user_data; - GSList *iter; - NMConnection *connection = NULL; - GError *error = NULL; - - if (response != GTK_RESPONSE_ACCEPT) - goto out; - - filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); - if (!filename) { - g_warning ("%s: didn't get a filename back from the chooser!", __func__); - goto out; - } - - for (iter = vpn_get_plugin_infos (); !connection && iter; iter = iter->next) { - NMVpnEditorPlugin *plugin; - - plugin = nm_vpn_plugin_info_get_editor_plugin (iter->data); - g_clear_error (&error); - connection = nm_vpn_editor_plugin_import (plugin, filename, &error); - } - - if (connection) - info->callback (connection, info->user_data); - else { - GtkWidget *err_dialog; - char *bname = g_path_get_basename (filename); - - err_dialog = gtk_message_dialog_new (NULL, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - _("Cannot import VPN connection")); - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (err_dialog), - _("The file ā%sā could not be read or does not contain recognized VPN connection information\n\nError: %s."), - bname, error ? error->message : _("unknown error")); - g_free (bname); - g_signal_connect (err_dialog, "delete-event", G_CALLBACK (gtk_widget_destroy), NULL); - g_signal_connect (err_dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL); - gtk_widget_show_all (err_dialog); - gtk_window_present (GTK_WINDOW (err_dialog)); - } - - g_clear_error (&error); - g_free (filename); - -out: - gtk_widget_hide (dialog); - gtk_widget_destroy (dialog); - g_free (info); -} - -void -vpn_import (VpnImportSuccessCallback callback, gpointer user_data) -{ - GtkWidget *dialog; - ActionInfo *info; - const char *home_folder; - - dialog = gtk_file_chooser_dialog_new (_("Select file to import"), - NULL, - GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, - NULL); - home_folder = g_get_home_dir (); - gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), home_folder); - - info = g_malloc0 (sizeof (ActionInfo)); - info->callback = callback; - info->user_data = user_data; - - g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (import_vpn_from_file_cb), info); - gtk_widget_show_all (dialog); - gtk_window_present (GTK_WINDOW (dialog)); -} - static void export_vpn_to_file_cb (GtkWidget *dialog, gint response, gpointer user_data) { diff --git a/src/connection-editor/vpn-helpers.h b/src/connection-editor/vpn-helpers.h index 2c70d329..b1f39b56 100644 --- a/src/connection-editor/vpn-helpers.h +++ b/src/connection-editor/vpn-helpers.h @@ -32,9 +32,6 @@ GSList *vpn_get_plugin_infos (void); NMVpnEditorPlugin *vpn_get_plugin_by_service (const char *service); -typedef void (*VpnImportSuccessCallback) (NMConnection *connection, gpointer user_data); -void vpn_import (VpnImportSuccessCallback callback, gpointer user_data); - void vpn_export (NMConnection *connection); gboolean vpn_supports_ipv6 (NMConnection *connection); |