diff options
author | Alexander Larsson <alexl@src.gnome.org> | 2007-09-13 13:30:56 +0000 |
---|---|---|
committer | Alexander Larsson <alexl@src.gnome.org> | 2007-09-13 13:30:56 +0000 |
commit | 5b4105130d30cc15a9684282d86327eb33338bf5 (patch) | |
tree | 3b250064784a2ee9cf4ed13f43e3b6fe020b1ef4 /common | |
parent | 5f50676f601fd06e58606b32ddd341de37d35dd4 (diff) | |
download | gvfs-5b4105130d30cc15a9684282d86327eb33338bf5.tar.gz |
Add GMountTracker to track gvfs mounts.
Removed _g_daemon_vfs_get_mount_list_sync.
Original git commit by Alexander Larsson <alexl@redhat.com> at 1178716509 +0200
svn path=/trunk/; revision=537
Diffstat (limited to 'common')
-rw-r--r-- | common/Makefile.am | 1 | ||||
-rw-r--r-- | common/gmounttracker.c | 384 | ||||
-rw-r--r-- | common/gmounttracker.h | 51 |
3 files changed, 436 insertions, 0 deletions
diff --git a/common/Makefile.am b/common/Makefile.am index dc7f695b..522bebea 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -14,6 +14,7 @@ libcommon_la_SOURCES = \ gmountspec.c gmountspec.h \ gmountoperationdbus.c gmountoperation.h \ gmountsource.c gmountsource.h \ + gmounttracker.c gmounttracker.h \ gvfsdaemonprotocol.h \ $(NULL) diff --git a/common/gmounttracker.c b/common/gmounttracker.c new file mode 100644 index 00000000..145e56c2 --- /dev/null +++ b/common/gmounttracker.c @@ -0,0 +1,384 @@ +#include <config.h> + +#include <string.h> + +#include <gmounttracker.h> +#include <gdbusutils.h> +#include <gvfsdaemonprotocol.h> + +enum { + MOUNTED, + UNMOUNTED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +struct _GMountTracker +{ + GObject parent_instance; + + GList *mounts; +}; + +G_DEFINE_TYPE (GMountTracker, g_mount_tracker, G_TYPE_OBJECT); + +static DBusHandlerResult g_mount_tracker_filter_func (DBusConnection *conn, + DBusMessage *message, + gpointer data); + + + +gboolean +g_mount_info_equal (GMountInfo *info1, + GMountInfo *info2) +{ + return + strcmp (info1->dbus_id, info2->dbus_id) == 0 && + strcmp (info1->object_path, info2->object_path) == 0; +} + +GMountInfo * +g_mount_info_dup (GMountInfo *info) +{ + GMountInfo *copy; + + copy = g_new (GMountInfo, 1); + copy->display_name = g_strdup (info->display_name); + copy->icon = g_strdup (info->icon); + copy->dbus_id = g_strdup (info->dbus_id); + copy->object_path = g_strdup (info->object_path); + copy->mount_spec = g_mount_spec_copy (info->mount_spec); + + return copy; +} + +void +g_mount_info_free (GMountInfo *info) +{ + g_free (info->display_name); + g_free (info->icon); + g_free (info->dbus_id); + g_free (info->object_path); + g_mount_spec_unref (info->mount_spec); + g_free (info); +} + +static GMountInfo * +g_mount_info_from_dbus (DBusMessageIter *iter) +{ + DBusMessageIter struct_iter; + GMountInfo *info; + GMountSpec *mount_spec; + gchar *display_name; + gchar *icon; + gchar *dbus_id; + gchar *obj_path; + + if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_STRUCT) + return NULL; + + dbus_message_iter_recurse (iter, &struct_iter); + + if (!_g_dbus_message_iter_get_args (&struct_iter, NULL, + DBUS_TYPE_STRING, &display_name, + DBUS_TYPE_STRING, &icon, + DBUS_TYPE_STRING, &dbus_id, + DBUS_TYPE_OBJECT_PATH, &obj_path, + 0)) + return NULL; + + mount_spec = g_mount_spec_from_dbus (&struct_iter); + if (mount_spec == NULL) + return NULL; + + info = g_new0 (GMountInfo, 1); + info->display_name = g_strdup (display_name); + info->icon = g_strdup (icon); + info->dbus_id = g_strdup (dbus_id); + info->object_path = g_strdup (obj_path); + info->mount_spec = mount_spec; + + return info; +} + + +static void +g_mount_tracker_finalize (GObject *object) +{ + GMountTracker *tracker; + DBusConnection *conn; + + tracker = G_MOUNT_TRACKER (object); + + g_list_foreach (tracker->mounts, + (GFunc)g_mount_info_free, NULL); + g_list_free (tracker->mounts); + + conn = dbus_bus_get (DBUS_BUS_SESSION, NULL); + if (conn) + { + dbus_connection_remove_filter (conn, g_mount_tracker_filter_func, tracker); + + + dbus_bus_remove_match (conn, + "sender='"G_VFS_DBUS_DAEMON_NAME"'," + "interface='"G_VFS_DBUS_MOUNTTRACKER_INTERFACE"'," + "member='"G_VFS_DBUS_MOUNTTRACKER_SIGNAL_MOUNTED"'", + NULL); + dbus_bus_remove_match (conn, + "sender='"G_VFS_DBUS_DAEMON_NAME"'," + "interface='"G_VFS_DBUS_MOUNTTRACKER_INTERFACE"'," + "member='"G_VFS_DBUS_MOUNTTRACKER_SIGNAL_UNMOUNTED"'", + NULL); + + dbus_connection_unref (conn); + } + + + if (G_OBJECT_CLASS (g_mount_tracker_parent_class)->finalize) + (*G_OBJECT_CLASS (g_mount_tracker_parent_class)->finalize) (object); +} + +static void +g_mount_tracker_class_init (GMountTrackerClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_mount_tracker_finalize; + + signals[MOUNTED] = g_signal_new (I_("mounted"), + G_TYPE_MOUNT_TRACKER, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GMountTrackerClass, mounted), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); + + signals[UNMOUNTED] = g_signal_new (I_("unmounted"), + G_TYPE_MOUNT_TRACKER, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GMountTrackerClass, unmounted), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); + +} + +static GList * +g_mount_tracker_find (GMountTracker *tracker, + GMountInfo *info) +{ + GList *l; + + for (l = tracker->mounts; l != NULL; l = l->next) + { + if (g_mount_info_equal (info, (GMountInfo *)l->data)) + return l; + } + + return NULL; +} + +static void +g_mount_tracker_add_mount (GMountTracker *tracker, + GMountInfo *info) +{ + /* Don't add multiple times */ + if (g_mount_tracker_find (tracker, info)) + return; + + tracker->mounts = g_list_prepend (tracker->mounts, g_mount_info_dup (info)); + + g_signal_emit (tracker, signals[MOUNTED], 0, info); +} + +static void +g_mount_tracker_remove_mount (GMountTracker *tracker, + GMountInfo *info) +{ + GList *l; + GMountInfo *old_info; + + + l = g_mount_tracker_find (tracker, info); + + /* Don't remove multiple times */ + if (l == NULL) + return; + + old_info = l->data; + + tracker->mounts = g_list_delete_link (tracker->mounts, l); + + g_signal_emit (tracker, signals[UNMOUNTED], 0, old_info); + g_mount_info_free (old_info); +} + +static void +list_mounts_reply (DBusPendingCall *pending, + void *_data) +{ + GMountTracker *tracker = _data; + DBusMessageIter iter, array_iter; + GMountInfo *info; + DBusMessage *reply; + gboolean b; + + reply = dbus_pending_call_steal_reply (pending); + dbus_pending_call_unref (pending); + + b = dbus_message_iter_init (reply, &iter); + dbus_message_iter_recurse (&iter, &array_iter); + + do + { + info = g_mount_info_from_dbus (&array_iter); + if (info) + { + g_mount_tracker_add_mount (tracker, info); + g_mount_info_free (info); + } + } + while (dbus_message_iter_next (&array_iter)); + + dbus_message_unref (reply); +} + +static DBusHandlerResult +g_mount_tracker_filter_func (DBusConnection *conn, + DBusMessage *message, + gpointer data) +{ + GMountTracker *tracker = data; + GMountInfo *info; + DBusMessageIter iter; + + if (dbus_message_is_signal (message, + G_VFS_DBUS_MOUNTTRACKER_INTERFACE, + G_VFS_DBUS_MOUNTTRACKER_SIGNAL_MOUNTED)) + { + dbus_message_iter_init (message, &iter); + info = g_mount_info_from_dbus (&iter); + + if (info) + { + g_mount_tracker_add_mount (tracker, info); + g_mount_info_free (info); + } + } + else if (dbus_message_is_signal (message, + G_VFS_DBUS_MOUNTTRACKER_INTERFACE, + G_VFS_DBUS_MOUNTTRACKER_SIGNAL_UNMOUNTED)) + { + dbus_message_iter_init (message, &iter); + info = g_mount_info_from_dbus (&iter); + + if (info) + { + g_mount_tracker_remove_mount (tracker, info); + g_mount_info_free (info); + } + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + + +static void +g_mount_tracker_init (GMountTracker *tracker) +{ + DBusConnection *conn; + DBusMessage *message; + DBusPendingCall *pending; + + conn = dbus_bus_get (DBUS_BUS_SESSION, NULL); + if (conn) + { + message = + dbus_message_new_method_call (G_VFS_DBUS_DAEMON_NAME, + G_VFS_DBUS_MOUNTTRACKER_PATH, + G_VFS_DBUS_MOUNTTRACKER_INTERFACE, + G_VFS_DBUS_MOUNTTRACKER_OP_LIST_MOUNTS); + if (message == NULL) + _g_dbus_oom (); + + dbus_message_set_auto_start (message, TRUE); + + if (!dbus_connection_send_with_reply (conn, message, + &pending, + G_VFS_DBUS_TIMEOUT_MSECS)) + _g_dbus_oom (); + + dbus_message_unref (message); + + if (pending != NULL) + { + if (!dbus_pending_call_set_notify (pending, + list_mounts_reply, + g_object_ref (tracker), g_object_unref)) + _g_dbus_oom (); + } + + dbus_connection_add_filter (conn, g_mount_tracker_filter_func, tracker, NULL); + + dbus_bus_add_match (conn, + "sender='"G_VFS_DBUS_DAEMON_NAME"'," + "interface='"G_VFS_DBUS_MOUNTTRACKER_INTERFACE"'," + "member='"G_VFS_DBUS_MOUNTTRACKER_SIGNAL_MOUNTED"'", + NULL); + dbus_bus_add_match (conn, + "sender='"G_VFS_DBUS_DAEMON_NAME"'," + "interface='"G_VFS_DBUS_MOUNTTRACKER_INTERFACE"'," + "member='"G_VFS_DBUS_MOUNTTRACKER_SIGNAL_UNMOUNTED"'", + NULL); + + dbus_connection_unref (conn); + } +} + +GMountTracker * +g_mount_tracker_new (void) +{ + GMountTracker *tracker; + + tracker = g_object_new (G_TYPE_MOUNT_TRACKER, NULL); + + return tracker; +} + +GList * +g_mount_tracker_list_mounts (GMountTracker *tracker) +{ + GList *res, *l; + GMountInfo *copy; + + res = NULL; + for (l = tracker->mounts; l != NULL; l = l->next) + { + copy = g_mount_info_dup (l->data); + res = g_list_prepend (res, copy); + } + + return g_list_reverse (res); +} + +GMountInfo * +g_mount_tracker_find_by_mount_spec (GMountTracker *tracker, + GMountSpec *mount_spec) +{ + GList *l; + GMountInfo *info; + + for (l = tracker->mounts; l != NULL; l = l->next) + { + info = l->data; + + if (g_mount_spec_equal (info->mount_spec, mount_spec)) + return g_mount_info_dup (info); + } + + return NULL; +} + + diff --git a/common/gmounttracker.h b/common/gmounttracker.h new file mode 100644 index 00000000..2a717a1f --- /dev/null +++ b/common/gmounttracker.h @@ -0,0 +1,51 @@ +#ifndef __G_MOUNT_TRACKER_H__ +#define __G_MOUNT_TRACKER_H__ + +#include <glib-object.h> +#include <gmountspec.h> + +G_BEGIN_DECLS + +#define G_TYPE_MOUNT_TRACKER (g_mount_tracker_get_type ()) +#define G_MOUNT_TRACKER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_MOUNT_TRACKER, GMountTracker)) +#define G_MOUNT_TRACKER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_MOUNT_TRACKER, GMountTrackerClass)) +#define G_IS_MOUNT_TRACKER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_MOUNT_TRACKER)) +#define G_IS_MOUNT_TRACKER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_MOUNT_TRACKER)) +#define G_MOUNT_TRACKER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_MOUNT_TRACKER, GMountTrackerClass)) + +typedef struct _GMountTracker GMountTracker; +typedef struct _GMountTrackerClass GMountTrackerClass; + +typedef struct { + char *display_name; + char *icon; + char *dbus_id; + char *object_path; + GMountSpec *mount_spec; +} GMountInfo; + +struct _GMountTrackerClass +{ + GObjectClass parent_class; + + void (*mounted) (GMountTracker *tracker, + GMountInfo *info); + void (*unmounted) (GMountTracker *tracker, + GMountInfo *info); +}; + +GType g_mount_tracker_get_type (void) G_GNUC_CONST; + +gboolean g_mount_info_equal (GMountInfo *info1, + GMountInfo *info2); +GMountInfo *g_mount_info_dup (GMountInfo *info); +void g_mount_info_free (GMountInfo *info); + +GMountTracker *g_mount_tracker_new (void); +GList * g_mount_tracker_list_mounts (GMountTracker *tracker); +GMountInfo * g_mount_tracker_find_by_mount_spec (GMountTracker *tracker, + GMountSpec *mount_spec); + +G_END_DECLS + +#endif /* __G_MOUNT_TRACKER_H__ */ |