mirror of https://gitee.com/openkylin/gvfs.git
324 lines
10 KiB
C
324 lines
10 KiB
C
/* 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 <alexl@redhat.com>
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <gio/gio.h>
|
|
#include <glib/gi18n-lib.h>
|
|
#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);
|
|
}
|