1 /* GIO - GLib Input, Output and Streaming Library
2 *
3 * Copyright (C) 2006-2007 Red Hat, Inc.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 * Author: Alexander Larsson <alexl@redhat.com>
21 */
22
23 #include <config.h>
24
25 #include <unistd.h>
26 #include <sys/types.h>
27 #include <sys/socket.h>
28 #include <sys/un.h>
29
30 #include <glib.h>
31 #include <glib/gi18n.h>
32 #include "gvfsjobmountmountable.h"
33 #include "gvfsdaemonutils.h"
34
35 G_DEFINE_TYPE (GVfsJobMountMountable, g_vfs_job_mount_mountable, G_VFS_TYPE_JOB_DBUS)
36
37 static void run (GVfsJob *job);
38 static gboolean try (GVfsJob *job);
39 static void create_reply (GVfsJob *job,
40 GVfsDBusMount *object,
41 GDBusMethodInvocation *invocation);
42
43 static void
g_vfs_job_mount_mountable_finalize(GObject * object)44 g_vfs_job_mount_mountable_finalize (GObject *object)
45 {
46 GVfsJobMountMountable *job;
47
48 job = G_VFS_JOB_MOUNT_MOUNTABLE (object);
49
50 if (job->mount_source)
51 g_object_unref (job->mount_source);
52
53 if (job->mount_spec)
54 g_mount_spec_unref (job->mount_spec);
55
56 g_free (job->filename);
57 g_free (job->target_filename);
58
59 if (G_OBJECT_CLASS (g_vfs_job_mount_mountable_parent_class)->finalize)
60 (*G_OBJECT_CLASS (g_vfs_job_mount_mountable_parent_class)->finalize) (object);
61 }
62
63 static void
g_vfs_job_mount_mountable_class_init(GVfsJobMountMountableClass * klass)64 g_vfs_job_mount_mountable_class_init (GVfsJobMountMountableClass *klass)
65 {
66 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
67 GVfsJobClass *job_class = G_VFS_JOB_CLASS (klass);
68 GVfsJobDBusClass *job_dbus_class = G_VFS_JOB_DBUS_CLASS (klass);
69
70 gobject_class->finalize = g_vfs_job_mount_mountable_finalize;
71 job_class->run = run;
72 job_class->try = try;
73 job_dbus_class->create_reply = create_reply;
74 }
75
76 static void
g_vfs_job_mount_mountable_init(GVfsJobMountMountable * job)77 g_vfs_job_mount_mountable_init (GVfsJobMountMountable *job)
78 {
79 }
80
81 gboolean
g_vfs_job_mount_mountable_new_handle(GVfsDBusMount * object,GDBusMethodInvocation * invocation,const gchar * arg_path_data,const gchar * arg_dbus_id,const gchar * arg_obj_path,GVfsBackend * backend)82 g_vfs_job_mount_mountable_new_handle (GVfsDBusMount *object,
83 GDBusMethodInvocation *invocation,
84 const gchar *arg_path_data,
85 const gchar *arg_dbus_id,
86 const gchar *arg_obj_path,
87 GVfsBackend *backend)
88 {
89 GVfsJobMountMountable *job;
90
91 if (g_vfs_backend_invocation_first_handler (object, invocation, backend))
92 return TRUE;
93
94 job = g_object_new (G_VFS_TYPE_JOB_MOUNT_MOUNTABLE,
95 "object", object,
96 "invocation", invocation,
97 NULL);
98
99 job->filename = g_strdup (arg_path_data);
100 job->backend = backend;
101 job->mount_source = g_mount_source_new (arg_dbus_id, arg_obj_path);
102
103 g_vfs_job_source_new_job (G_VFS_JOB_SOURCE (backend), G_VFS_JOB (job));
104 g_object_unref (job);
105
106 return TRUE;
107 }
108
109 void
g_vfs_job_mount_mountable_set_target(GVfsJobMountMountable * job,GMountSpec * mount_spec,const char * filename,gboolean must_mount_location)110 g_vfs_job_mount_mountable_set_target (GVfsJobMountMountable *job,
111 GMountSpec *mount_spec,
112 const char *filename,
113 gboolean must_mount_location)
114 {
115 job->mount_spec = g_mount_spec_ref (mount_spec);
116 job->target_filename = g_strdup (filename);
117 job->must_mount_location = must_mount_location;
118 }
119
120 void
g_vfs_job_mount_mountable_set_target_uri(GVfsJobMountMountable * job,const char * uri,gboolean must_mount_location)121 g_vfs_job_mount_mountable_set_target_uri (GVfsJobMountMountable *job,
122 const char *uri,
123 gboolean must_mount_location)
124 {
125 job->target_uri = g_strdup (uri);
126 job->must_mount_location = must_mount_location;
127 }
128
129 static void
run(GVfsJob * job)130 run (GVfsJob *job)
131 {
132 GVfsJobMountMountable *op_job = G_VFS_JOB_MOUNT_MOUNTABLE (job);
133 GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
134
135 if (class->mount_mountable == NULL)
136 {
137 g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
138 _("Operation not supported"));
139 return;
140 }
141
142 class->mount_mountable (op_job->backend,
143 op_job,
144 op_job->filename,
145 op_job->mount_source);
146 }
147
148 static gboolean
try(GVfsJob * job)149 try (GVfsJob *job)
150 {
151 GVfsJobMountMountable *op_job = G_VFS_JOB_MOUNT_MOUNTABLE (job);
152 GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
153
154 if (class->try_mount_mountable == NULL)
155 return FALSE;
156
157 return class->try_mount_mountable (op_job->backend,
158 op_job,
159 op_job->filename,
160 op_job->mount_source);
161 }
162
163 /* Might be called on an i/o thread */
164 static void
create_reply(GVfsJob * job,GVfsDBusMount * object,GDBusMethodInvocation * invocation)165 create_reply (GVfsJob *job,
166 GVfsDBusMount *object,
167 GDBusMethodInvocation *invocation)
168 {
169 GVfsJobMountMountable *op_job = G_VFS_JOB_MOUNT_MOUNTABLE (job);
170 gboolean is_uri, must_mount;
171 GMountSpec *fake_mountspec = NULL;
172
173 must_mount = op_job->must_mount_location;
174 is_uri = op_job->target_uri != NULL;
175
176 if (is_uri)
177 fake_mountspec = g_mount_spec_new (NULL);
178
179 gvfs_dbus_mount_complete_mount_mountable (object,
180 invocation,
181 is_uri,
182 is_uri ? op_job->target_uri : op_job->target_filename,
183 must_mount,
184 g_mount_spec_to_dbus (is_uri ? fake_mountspec : op_job->mount_spec));
185
186 if (fake_mountspec)
187 g_mount_spec_unref (fake_mountspec);
188 }
189