File gnome-vfs2-172870-unmount-uses-hal-udi-from-drive.diff of Package gnome-vfs2

2006-05-23  Federico Mena Quintero  <federico@novell.com>

	* libgnomevfs/gnome-vfs-volume-ops.c (mount_unmount_operation):
	See if the HAL property "volume.mount.valid_options" has "uid=".
	In this case, add an uid option to our dbus message.  This makes
	the mount be writable by the user.

2006-05-22  Federico Mena Quintero  <federico@novell.com>

	* libgnomevfs/gnome-vfs-volume-ops.c (dispatch_callback_idle_cb):
	Call force_probe() before calling the user's callback, in a
	similar fashion to report_mount_result().  We need this so that
	the volume monitor will update itself.  This way the user's
	callback will get a consistent view of the volume monitor's state.
	(force_probe): Move outside of the "#if !defined (USE_HAL)" block.

2006-05-21  Federico Mena Quintero  <federico@novell.com>

	* libgnomevfs/gnome-vfs-volume-ops.c (gnome_vfs_volume_unmount):
	If the volume doesn't have a HAL UDI, get it from the
	corresponding drive.  This is merged from CVS.  Fixes the
	gnome-vfs part of https://bugzilla.novell.com/show_bug.cgi?id=172870

--- gnome-vfs/libgnomevfs/gnome-vfs-volume-ops.c.orig	2006-05-21 20:12:34.000000000 -0500
+++ gnome-vfs/libgnomevfs/gnome-vfs-volume-ops.c	2006-05-21 20:13:49.000000000 -0500
@@ -89,6 +89,37 @@ enum {
 	UNMOUNT = 0x4,
 };
 
+static void
+force_probe (void)
+{
+	GnomeVFSVolumeMonitor *volume_monitor;
+	GnomeVFSClient *client;
+	GNOME_VFS_Daemon daemon;
+	CORBA_Environment  ev;
+	GnomeVFSDaemonForceProbeCallback callback;
+	
+	volume_monitor = gnome_vfs_get_volume_monitor ();
+
+	if (gnome_vfs_get_is_daemon ()) {
+		callback = _gnome_vfs_get_daemon_force_probe_callback();
+		(*callback) (GNOME_VFS_VOLUME_MONITOR (volume_monitor));
+	} else {
+		client = _gnome_vfs_get_client ();
+		daemon = _gnome_vfs_client_get_daemon (client);
+
+		if (daemon != CORBA_OBJECT_NIL) {
+			CORBA_exception_init (&ev);
+			GNOME_VFS_Daemon_forceProbe (daemon,
+						     BONOBO_OBJREF (client),
+						     &ev);
+			if (BONOBO_EX (&ev)) {
+				CORBA_exception_free (&ev);
+			}
+			CORBA_Object_release (daemon, NULL);
+		}
+	}
+}
+
 #if !defined (USE_HAL) && !defined (G_OS_WIN32)
 
 typedef struct {
@@ -155,37 +186,6 @@ generate_unmount_error_message (char *st
 	return message;
 }
 
-static void
-force_probe (void)
-{
-	GnomeVFSVolumeMonitor *volume_monitor;
-	GnomeVFSClient *client;
-	GNOME_VFS_Daemon daemon;
-	CORBA_Environment  ev;
-	GnomeVFSDaemonForceProbeCallback callback;
-	
-	volume_monitor = gnome_vfs_get_volume_monitor ();
-
-	if (gnome_vfs_get_is_daemon ()) {
-		callback = _gnome_vfs_get_daemon_force_probe_callback();
-		(*callback) (GNOME_VFS_VOLUME_MONITOR (volume_monitor));
-	} else {
-		client = _gnome_vfs_get_client ();
-		daemon = _gnome_vfs_client_get_daemon (client);
-
-		if (daemon != CORBA_OBJECT_NIL) {
-			CORBA_exception_init (&ev);
-			GNOME_VFS_Daemon_forceProbe (daemon,
-						     BONOBO_OBJREF (client),
-						     &ev);
-			if (BONOBO_EX (&ev)) {
-				CORBA_exception_free (&ev);
-			}
-			CORBA_Object_release (daemon, NULL);
-		}
-	}
-}
-
 static gboolean
 report_mount_result (gpointer callback_data)
 {
@@ -359,6 +359,14 @@ dispatch_callback_idle_cb (gpointer data
 
 	closure = data;
 
+	/* fprintf (stderr, "LOG: gnome-vfs dispatch_callback_idle_cb(): d-bus call %s.  Calling force_probe().\n",
+		 closure->succeeded ? "SUCCEDED" : "FAILED"); */
+
+	/* We want to force probing here so that the daemon
+	   can refresh and tell us (and everyone else) of the new
+	   volume before we call the callback */
+	force_probe ();
+
 	(* closure->callback) (closure->succeeded,
 			       closure->error_message,
 			       closure->detailed_error_message,
@@ -388,6 +396,46 @@ queue_dispatch_callback (gboolean succee
 	g_idle_add (dispatch_callback_idle_cb, closure);
 }
 
+#ifdef USE_HAL
+static gboolean
+uid_is_valid_option (DBusConnection *dbus_ctx, const char *hal_udi)
+{
+	LibHalContext *hal_ctx;
+	DBusError error;
+	char **options;
+	char **p;
+	gboolean retval;
+
+	hal_ctx = libhal_ctx_new ();
+	if (!hal_ctx)
+		return FALSE;
+
+	libhal_ctx_set_dbus_connection (hal_ctx, dbus_ctx);
+
+	dbus_error_init (&error);
+
+	if (!libhal_ctx_init (hal_ctx, &error)) {
+		dbus_error_free (&error);
+		libhal_ctx_free (hal_ctx);
+		return FALSE;
+	}
+
+	retval = FALSE;
+
+	options = libhal_device_get_property_strlist (hal_ctx, hal_udi, "volume.mount.valid_options", NULL);
+	for (p = options; *p; p++) {
+		if (strcmp (*p, "uid=") == 0)
+			retval = TRUE;
+	}
+	libhal_free_string_array (options);
+
+	libhal_ctx_shutdown (hal_ctx, NULL);
+	libhal_ctx_free (hal_ctx);
+
+	return retval;
+}
+#endif
+
 static void
 mount_unmount_operation (const char *mount_point,
 			 const char *device_path,
@@ -427,17 +475,28 @@ mount_unmount_operation (const char *mou
 	}
 	
 	if ((flags & MOUNT)) {
-		char *options[] = { NULL };
+		GPtrArray *options;
 		char *mount_point = "";
 		char *fstype = "";
-		
+		char uid[32];
+
+		options = g_ptr_array_new ();
+
+		if (uid_is_valid_option (dbus_ctx, hal_udi)) {
+			g_snprintf (uid, sizeof (uid), "uid=%d", getuid ());
+			g_ptr_array_add (options, uid);
+		}
+
 		if (!dbus_message_append_args (dmesg, DBUS_TYPE_STRING, &mount_point, DBUS_TYPE_STRING, &fstype,
-					       DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &options, 0, DBUS_TYPE_INVALID)) {
+					       DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &options->pdata, options->len, DBUS_TYPE_INVALID)) {
 			queue_dispatch_callback (FALSE, _("Could not append args to dbus message"), method, callback, user_data);
 			g_warning ("Mount failed for %s: could not append args to dbus message", hal_udi);
 			dbus_message_unref (dmesg);
+			g_ptr_array_free (options, TRUE);
 			goto exception;
 		}
+
+		g_ptr_array_free (options, TRUE);
 	}
 
 	if ((flags & UNMOUNT)) {
@@ -666,14 +725,27 @@ gnome_vfs_volume_unmount (GnomeVFSVolume
 
 	type = gnome_vfs_volume_get_volume_type (volume);
 	if (type == GNOME_VFS_VOLUME_TYPE_MOUNTPOINT) {
+		char *hal_udi;
+
 		uri = gnome_vfs_volume_get_activation_uri (volume);
 		mount_path = gnome_vfs_get_local_path_from_uri (uri);
 		g_free (uri);
 		device_path = gnome_vfs_volume_get_device_path (volume);
 		filesystem_type = gnome_vfs_volume_get_filesystem_type (volume);
+
+		hal_udi = gnome_vfs_volume_get_hal_udi (volume);
+		if (hal_udi == NULL) {
+			GnomeVFSDrive *drive;
+			drive = gnome_vfs_volume_get_drive (volume);
+			if (drive != NULL) {
+				hal_udi = gnome_vfs_drive_get_hal_udi (drive);
+				gnome_vfs_drive_unref (drive);
+			}
+		}
+
 		mount_unmount_operation (mount_path,
 					 device_path,
-					 gnome_vfs_volume_get_hal_udi (volume),
+					 hal_udi,
 					 filesystem_type,
 					 gnome_vfs_volume_get_device_type (volume),
 					 UNMOUNT,
@@ -681,6 +753,7 @@ gnome_vfs_volume_unmount (GnomeVFSVolume
 		g_free (mount_path);
 		g_free (device_path);
 		g_free (filesystem_type);
+		g_free (hal_udi);
 	} else {
 		unmount_connected_server (volume, callback, user_data);
 	}