/* GIO - GLib Input, Output and Streaming Library * * Copyright (C) 2006-2007 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * Author: Alexander Larsson */ #include #include #include #include #include "gmountoperationdbus.h" #include "gvfsdbus.h" typedef struct { GMountOperation *op; char *obj_path; char *dbus_id; GDBusConnection *connection; GVfsDBusMountOperation *mount_op_skeleton; GVfsDBusMountOperation *object; GDBusMethodInvocation *invocation; } GMountOperationDBus; static void mount_op_got_reply (GMountOperationDBus *op_dbus) { g_signal_handlers_disconnect_matched (op_dbus->op, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA, g_signal_lookup ("reply", G_TYPE_MOUNT_OPERATION), 0, NULL, NULL, op_dbus); } static void ask_password_reply (GMountOperation *op, GMountOperationResult result, gpointer data) { GMountOperationDBus *op_dbus = data; const char *username, *password, *domain; gboolean anonymous; guint32 password_save; gboolean handled, abort_dbus; handled = (result != G_MOUNT_OPERATION_UNHANDLED); abort_dbus = (result == G_MOUNT_OPERATION_ABORTED); password = g_mount_operation_get_password (op); if (password == NULL) password = ""; username = g_mount_operation_get_username (op); if (username == NULL) username = ""; domain = g_mount_operation_get_domain (op); if (domain == NULL) domain = ""; anonymous = g_mount_operation_get_anonymous (op); password_save = g_mount_operation_get_password_save (op); gvfs_dbus_mount_operation_complete_ask_password (op_dbus->object, op_dbus->invocation, handled, abort_dbus, password, username, domain, anonymous, password_save); mount_op_got_reply (op_dbus); } static gboolean handle_ask_password (GVfsDBusMountOperation *object, GDBusMethodInvocation *invocation, const gchar *arg_message_string, const gchar *arg_default_user, const gchar *arg_default_domain, guint arg_flags_as_int, gpointer data) { GMountOperationDBus *op_dbus = data; op_dbus->object = object; op_dbus->invocation = invocation; g_signal_connect (op_dbus->op, "reply", G_CALLBACK (ask_password_reply), op_dbus); g_signal_emit_by_name (op_dbus->op, "ask_password", arg_message_string, arg_default_user, arg_default_domain, arg_flags_as_int); return TRUE; } static void ask_question_reply (GMountOperation *op, GMountOperationResult result, gpointer data) { GMountOperationDBus *op_dbus = data; guint32 choice; gboolean handled, abort_dbus; op_dbus = g_object_get_data (G_OBJECT (op), "dbus-op"); handled = (result != G_MOUNT_OPERATION_UNHANDLED); abort_dbus = (result == G_MOUNT_OPERATION_ABORTED); choice = g_mount_operation_get_choice (op); gvfs_dbus_mount_operation_complete_ask_question (op_dbus->object, op_dbus->invocation, handled, abort_dbus, choice); mount_op_got_reply (op_dbus); } static gboolean handle_ask_question (GVfsDBusMountOperation *object, GDBusMethodInvocation *invocation, const gchar *arg_message_string, const gchar *const *arg_choices, gpointer data) { GMountOperationDBus *op_dbus = data; op_dbus->object = object; op_dbus->invocation = invocation; g_signal_connect (op_dbus->op, "reply", G_CALLBACK (ask_question_reply), op_dbus); g_signal_emit_by_name (op_dbus->op, "ask_question", arg_message_string, arg_choices); return TRUE; } static void show_processes_reply (GMountOperation *op, GMountOperationResult result, gpointer data) { GMountOperationDBus *op_dbus = data; guint32 choice; gboolean handled, abort_dbus; op_dbus = g_object_get_data (G_OBJECT (op), "dbus-op"); handled = (result != G_MOUNT_OPERATION_UNHANDLED); abort_dbus = (result == G_MOUNT_OPERATION_ABORTED); choice = g_mount_operation_get_choice (op); gvfs_dbus_mount_operation_complete_show_processes (op_dbus->object, op_dbus->invocation, handled, abort_dbus, choice); mount_op_got_reply (op_dbus); } static gboolean handle_show_processes (GVfsDBusMountOperation *object, GDBusMethodInvocation *invocation, const gchar *arg_message_string, const gchar *const *arg_choices, GVariant *arg_processes, gpointer data) { GMountOperationDBus *op_dbus = data; GArray *processes; GPid pid; GVariantIter iter; processes = g_array_new (FALSE, FALSE, sizeof (GPid)); g_variant_iter_init (&iter, arg_processes); while (g_variant_iter_loop (&iter, "i", &pid)) g_array_append_val (processes, pid); op_dbus->object = object; op_dbus->invocation = invocation; g_signal_connect (op_dbus->op, "reply", G_CALLBACK (show_processes_reply), op_dbus); g_signal_emit_by_name (op_dbus->op, "show_processes", arg_message_string, processes, arg_choices); g_array_unref (processes); return TRUE; } static gboolean handle_show_unmount_progress (GVfsDBusMountOperation *object, GDBusMethodInvocation *invocation, const gchar *arg_message_string, gint64 arg_time_left, gint64 arg_bytes_left, gpointer data) { GMountOperationDBus *op_dbus = data; g_signal_emit_by_name (op_dbus->op, "show-unmount-progress", arg_message_string, arg_time_left, arg_bytes_left); gvfs_dbus_mount_operation_complete_show_unmount_progress (object, invocation); return TRUE; } static gboolean handle_aborted (GVfsDBusMountOperation *object, GDBusMethodInvocation *invocation, gpointer data) { GMountOperationDBus *op_dbus = data; /* also emit reply to make the all DBus ops return */ g_mount_operation_reply (op_dbus->op, G_MOUNT_OPERATION_UNHANDLED); g_signal_emit_by_name (op_dbus->op, "aborted"); gvfs_dbus_mount_operation_complete_aborted (object, invocation); return TRUE; } static void g_mount_operation_dbus_free (GMountOperationDBus *op_dbus) { if (op_dbus->connection) { if (op_dbus->mount_op_skeleton != NULL) { g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (op_dbus->mount_op_skeleton)); g_object_unref (op_dbus->mount_op_skeleton); } g_object_unref (op_dbus->connection); } g_free (op_dbus->dbus_id); g_free (op_dbus->obj_path); g_free (op_dbus); } GMountSource * g_mount_operation_dbus_wrap (GMountOperation *op, GDBusConnection *connection) { GMountOperationDBus *op_dbus; static int mount_id = 0; GError *error; if (op == NULL) return g_mount_source_new_dummy (); op_dbus = g_new0 (GMountOperationDBus, 1); op_dbus->op = op; op_dbus->connection = g_object_ref (connection); op_dbus->obj_path = g_strdup_printf ("/org/gtk/gvfs/mountop/%d", mount_id++); if (op_dbus->connection) { op_dbus->dbus_id = g_strdup (g_dbus_connection_get_unique_name (op_dbus->connection)); op_dbus->mount_op_skeleton = gvfs_dbus_mount_operation_skeleton_new (); g_signal_connect (op_dbus->mount_op_skeleton, "handle-ask-password", G_CALLBACK (handle_ask_password), op_dbus); g_signal_connect (op_dbus->mount_op_skeleton, "handle-ask-question", G_CALLBACK (handle_ask_question), op_dbus); g_signal_connect (op_dbus->mount_op_skeleton, "handle-show-processes", G_CALLBACK (handle_show_processes), op_dbus); g_signal_connect (op_dbus->mount_op_skeleton, "handle-show-unmount-progress", G_CALLBACK (handle_show_unmount_progress), op_dbus); g_signal_connect (op_dbus->mount_op_skeleton, "handle-aborted", G_CALLBACK (handle_aborted), op_dbus); error = NULL; if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (op_dbus->mount_op_skeleton), op_dbus->connection, op_dbus->obj_path, &error)) { g_warning ("Error exporting GMountOperationDBus: %s (%s, %d)\n", error->message, g_quark_to_string (error->domain), error->code); g_error_free (error); } } g_object_set_data_full (G_OBJECT (op), "dbus-op", op_dbus, (GDestroyNotify)g_mount_operation_dbus_free); return g_mount_source_new (op_dbus->dbus_id, op_dbus->obj_path); }