[PATCH 4/6] device-wifi: auto-mount/unmount network drives on connect/disconnect
- From: Dominik Sommer <dominik sommer name>
- To: networkmanager-list gnome org
- Subject: [PATCH 4/6] device-wifi: auto-mount/unmount network drives on connect/disconnect
- Date: Mon, 16 Apr 2012 14:32:35 +0200
---
src/applet-device-wifi.c | 189 ++++++++-
diff --git a/src/applet-device-wifi.c b/src/applet-device-wifi.c
index ff0e374..aa35839 100644
--- a/src/applet-device-wifi.c
+++ b/src/applet-device-wifi.c
@@ -31,6 +31,7 @@
#include <glib/gi18n.h>
#include <gtk/gtk.h>
+#include <gio/gio.h>
#include <nm-device.h>
#include <nm-access-point.h>
@@ -1245,6 +1246,78 @@ update_active_ap (NMDevice *device, NMDeviceState
state, NMApplet *applet)
}
static void
+mount_done_cb (GObject *object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ gboolean succeeded;
+ GError *error = NULL;
+
+ succeeded = g_file_mount_enclosing_volume_finish (G_FILE (object),
res, &error);
+ if (succeeded)
+ {
+ g_message("Auto-mounted %s", (char *) user_data);
+ } else {
+ g_warning("Error auto-mounting %s: %s", (char *) user_data,
error->message);
+ g_error_free(error);
+ }
+}
+
+typedef struct
+{
+ NMApplet *applet;
+ const char *uri;
+
+ // a pointer to the unmount counter of a network disconnect event
+ int *unmount_count;
+} UnmountInfo;
+
+static gboolean
+reset_disconnecting_flag(gpointer user_data)
+{
+ UnmountInfo *unmount_info = (UnmountInfo *) user_data;
+
+ // Clear flag & memory
+ unmount_info->applet->disconnecting = FALSE;
+ g_free(unmount_info);
+
+ return FALSE;
+}
+
+static void
+unmount_done_cb (GObject *object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ gboolean succeeded;
+ GError *error = NULL;
+ UnmountInfo *unmount_info = (UnmountInfo *) user_data;
+
+ // Finish unmount of this network drive
+ succeeded = g_mount_unmount_with_operation_finish (G_MOUNT
(object), res, &error);
+ if (succeeded)
+ {
+ g_message("Auto-unmounted %s", unmount_info->uri);
+ } else {
+ g_warning("Error auto-unmounting %s: %s", unmount_info->uri,
error->message);
+ g_error_free(error);
+ }
+
+ // Do housekeeping for outstanding unmounts
+ *unmount_info->unmount_count = *unmount_info->unmount_count - 1;
+ if (*unmount_info->unmount_count == 0)
+ {
+ g_free(unmount_info->unmount_count);
+
+ // Wait 10 seconds before reacting to unmount events - callbacks to
+ // the applet could take a while
+ g_timeout_add(
+ 10 * 1000, reset_disconnecting_flag,
+ (gpointer) unmount_info);
+ }
+}
+
+static void
wireless_device_state_changed (NMDevice *device,
NMDeviceState new_state,
NMDeviceState old_state,
@@ -1253,23 +1326,120 @@ wireless_device_state_changed (NMDevice *device,
{
NMAccessPoint *new = NULL;
char *msg;
- char *esc_ssid = NULL;
+ NMRemoteConnection *connection = NULL;
+ NMSettingResources *settings_resources = NULL;
+ const char *connection_id = NULL;
+ int i, *unmount_count = NULL;
+
+ // Get connection info before updating device, to get it also when
disconnected
+ connection = applet_get_exported_connection_for_device (NM_DEVICE
(device), applet);
new = update_active_ap (device, new_state, applet);
if (new_state == NM_DEVICE_STATE_DISCONNECTED)
queue_avail_access_point_notification (device);
- if (new_state != NM_DEVICE_STATE_ACTIVATED)
+ if (connection)
+ {
+ connection_id = nm_connection_get_id(&connection->parent);
+ msg = g_strdup_printf (_("You are now connected to %s"),
connection_id);
+
+ settings_resources =
nm_connection_get_setting_resources(&connection->parent);
+ }
+ else
+ {
+ connection_id = get_ssid_utf8 (new);
+ msg = g_strdup_printf (_("You are now connected to the wireless
network %s"), connection_id);
+ }
+
+ // Notify when connected
+ if (connection_id && (new_state == NM_DEVICE_STATE_ACTIVATED))
+ {
+ applet_do_notify_with_pref (applet, _("Connection Established"),
+ msg, "nm-device-wireless",
+ PREF_DISABLE_CONNECTED_NOTIFICATIONS);
+ g_free (msg);
+ }
+
+ // If the connection does not have resources, we're done here
+ if (!NM_IS_SETTING_RESOURCES(settings_resources))
return;
- esc_ssid = get_ssid_utf8 (new);
- msg = g_strdup_printf (_("You are now connected to the wireless
network '%s'."), esc_ssid);
- applet_do_notify_with_pref (applet, _("Connection Established"),
- msg, "nm-device-wireless",
- PREF_DISABLE_CONNECTED_NOTIFICATIONS);
- g_free (msg);
- g_free (esc_ssid);
+ switch (new_state)
+ {
+ case NM_DEVICE_STATE_ACTIVATED:
+ // If network drives are configured to be automounted, mount them
+ for (i = 0; i <
nm_setting_resources_get_num_network_drives(settings_resources); i++)
+ {
+ const char *network_drive =
nm_setting_resources_get_network_drive(settings_resources, i);
+ GFile *file = g_file_new_for_uri(network_drive);
+ GError *error = NULL;
+
+ // Check if already mounted
+ GMount *mount = g_file_find_enclosing_mount(file, NULL,
&error);
+ if (error == NULL)
+ {
+ g_debug("%s is already mounted; skipping auto-mount",
network_drive);
+ g_object_unref(mount);
+ continue;
+ }
+ g_error_free(error);
+
+ // If not, auto-mount
+ g_file_mount_enclosing_volume (file,
+ 0,
+ NULL,
+ NULL,
+ mount_done_cb,
+ (gpointer) network_drive);
+ }
+ break;
+ case NM_DEVICE_STATE_DISCONNECTED:
+ // If network drives are configured to be automounted, unmount them
+ applet->disconnecting = TRUE;
+ for (i = 0; i <
nm_setting_resources_get_num_network_drives(settings_resources); i++)
+ {
+ const char *network_drive =
nm_setting_resources_get_network_drive(settings_resources, i);
+ GFile *file = g_file_new_for_uri(network_drive);
+ GError *error = NULL;
+ GMount *mount = g_file_find_enclosing_mount(file, NULL,
&error);
+ UnmountInfo *unmount_info;
+
+ // Only unmount if the network drive is currently mounted
+ if (error != NULL)
+ {
+ g_debug("%s is not mounted; skipping auto-unmount",
network_drive);
+ g_error_free(error);
+ g_object_unref(file);
+ continue;
+ }
+
+ // Unmount the network drive and block applet's reaction to
unmount
+ // events (i.e. prevent notifications for removing auto-mounts)
+ unmount_info = g_malloc0(sizeof(UnmountInfo));
+ if (unmount_count == NULL)
+ {
+ // Allocate the unmount counter for this disconnect event
+ g_message("Network disconnected; ignoring unmount
events for the next 10 seconds");
+ unmount_count = g_malloc0(sizeof(int));
+ }
+ *unmount_count = *unmount_count + 1;
+ unmount_info->applet = applet;
+ unmount_info->uri = network_drive;
+ unmount_info->unmount_count = unmount_count;
+
+ g_mount_unmount_with_operation(
+ mount,
+ G_MOUNT_UNMOUNT_NONE,
+ NULL,
+ NULL,
+ unmount_done_cb,
+ (gpointer) unmount_info);
+ }
+ break;
+ default:
+ break;
+ }
}
static GdkPixbuf *
@@ -1386,6 +1556,7 @@ activate_existing_cb (NMClient *client,
utils_show_error_dialog (_("Connection failure"), text,
err_text, FALSE, NULL);
g_free (err_text);
}
+
applet_schedule_update_icon (NM_APPLET (user_data));
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]