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 "gvfsjobunmountmountable.h"
33
34 G_DEFINE_TYPE (GVfsJobUnmountMountable, g_vfs_job_unmount_mountable, G_VFS_TYPE_JOB_DBUS)
35
36 static void run (GVfsJob *job);
37 static gboolean try (GVfsJob *job);
38 static void create_reply (GVfsJob *job,
39 GVfsDBusMount *object,
40 GDBusMethodInvocation *invocation);
41
42 static void
g_vfs_job_unmount_mountable_finalize(GObject * object)43 g_vfs_job_unmount_mountable_finalize (GObject *object)
44 {
45 GVfsJobUnmountMountable *job;
46
47 job = G_VFS_JOB_UNMOUNT_MOUNTABLE (object);
48
49 if (job->mount_source)
50 g_object_unref (job->mount_source);
51
52 g_free (job->filename);
53
54 if (G_OBJECT_CLASS (g_vfs_job_unmount_mountable_parent_class)->finalize)
55 (*G_OBJECT_CLASS (g_vfs_job_unmount_mountable_parent_class)->finalize) (object);
56 }
57
58 static void
g_vfs_job_unmount_mountable_class_init(GVfsJobUnmountMountableClass * klass)59 g_vfs_job_unmount_mountable_class_init (GVfsJobUnmountMountableClass *klass)
60 {
61 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
62 GVfsJobClass *job_class = G_VFS_JOB_CLASS (klass);
63 GVfsJobDBusClass *job_dbus_class = G_VFS_JOB_DBUS_CLASS (klass);
64
65 gobject_class->finalize = g_vfs_job_unmount_mountable_finalize;
66 job_class->run = run;
67 job_class->try = try;
68 job_dbus_class->create_reply = create_reply;
69 }
70
71 static void
g_vfs_job_unmount_mountable_init(GVfsJobUnmountMountable * job)72 g_vfs_job_unmount_mountable_init (GVfsJobUnmountMountable *job)
73 {
74 }
75
76 static gboolean
do_g_vfs_job_unmount_mountable_new_handle(GVfsDBusMount * object,GDBusMethodInvocation * invocation,const gchar * arg_path_data,guint arg_flags,const gchar * arg_dbus_id,const gchar * arg_obj_path,GVfsBackend * backend,gboolean eject)77 do_g_vfs_job_unmount_mountable_new_handle (GVfsDBusMount *object,
78 GDBusMethodInvocation *invocation,
79 const gchar *arg_path_data,
80 guint arg_flags,
81 const gchar *arg_dbus_id,
82 const gchar *arg_obj_path,
83 GVfsBackend *backend,
84 gboolean eject)
85 {
86 GVfsJobUnmountMountable *job;
87
88 if (g_vfs_backend_invocation_first_handler (object, invocation, backend))
89 return TRUE;
90
91 job = g_object_new (G_VFS_TYPE_JOB_UNMOUNT_MOUNTABLE,
92 "object", object,
93 "invocation", invocation,
94 NULL);
95
96 job->filename = g_strdup (arg_path_data);
97 job->backend = backend;
98 job->eject = eject;
99 job->flags = arg_flags;
100 job->mount_source = g_mount_source_new (arg_dbus_id, arg_obj_path);
101
102 g_vfs_job_source_new_job (G_VFS_JOB_SOURCE (backend), G_VFS_JOB (job));
103 g_object_unref (job);
104
105 return TRUE;
106 }
107
108 gboolean
g_vfs_job_unmount_mountable_new_handle(GVfsDBusMount * object,GDBusMethodInvocation * invocation,const gchar * arg_path_data,guint arg_flags,const gchar * arg_dbus_id,const gchar * arg_obj_path,GVfsBackend * backend)109 g_vfs_job_unmount_mountable_new_handle (GVfsDBusMount *object,
110 GDBusMethodInvocation *invocation,
111 const gchar *arg_path_data,
112 guint arg_flags,
113 const gchar *arg_dbus_id,
114 const gchar *arg_obj_path,
115 GVfsBackend *backend)
116 {
117 return do_g_vfs_job_unmount_mountable_new_handle (object,
118 invocation,
119 arg_path_data,
120 arg_flags,
121 arg_dbus_id,
122 arg_obj_path,
123 backend,
124 FALSE);
125 }
126
127 gboolean
g_vfs_job_eject_mountable_new_handle(GVfsDBusMount * object,GDBusMethodInvocation * invocation,const gchar * arg_path_data,guint arg_flags,const gchar * arg_dbus_id,const gchar * arg_obj_path,GVfsBackend * backend)128 g_vfs_job_eject_mountable_new_handle (GVfsDBusMount *object,
129 GDBusMethodInvocation *invocation,
130 const gchar *arg_path_data,
131 guint arg_flags,
132 const gchar *arg_dbus_id,
133 const gchar *arg_obj_path,
134 GVfsBackend *backend)
135 {
136 return do_g_vfs_job_unmount_mountable_new_handle (object,
137 invocation,
138 arg_path_data,
139 arg_flags,
140 arg_dbus_id,
141 arg_obj_path,
142 backend,
143 TRUE);
144 }
145
146 static void
run(GVfsJob * job)147 run (GVfsJob *job)
148 {
149 GVfsJobUnmountMountable *op_job = G_VFS_JOB_UNMOUNT_MOUNTABLE (job);
150 GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
151
152 if (op_job->eject)
153 {
154 if (class->eject_mountable == NULL)
155 {
156 g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
157 _("Operation not supported"));
158 return;
159 }
160
161 class->eject_mountable (op_job->backend,
162 op_job,
163 op_job->filename,
164 op_job->flags,
165 op_job->mount_source);
166 }
167 else
168 {
169 if (class->unmount_mountable == NULL)
170 {
171 g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
172 _("Operation not supported"));
173 return;
174 }
175
176 class->unmount_mountable (op_job->backend,
177 op_job,
178 op_job->filename,
179 op_job->flags,
180 op_job->mount_source);
181 }
182 }
183
184 static gboolean
try(GVfsJob * job)185 try (GVfsJob *job)
186 {
187 GVfsJobUnmountMountable *op_job = G_VFS_JOB_UNMOUNT_MOUNTABLE (job);
188 GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
189
190 if (op_job->eject)
191 {
192 if (class->try_eject_mountable == NULL)
193 return FALSE;
194
195 return class->try_eject_mountable (op_job->backend,
196 op_job,
197 op_job->filename,
198 op_job->flags,
199 op_job->mount_source);
200 }
201 else
202 {
203 if (class->try_unmount_mountable == NULL)
204 return FALSE;
205
206 return class->try_unmount_mountable (op_job->backend,
207 op_job,
208 op_job->filename,
209 op_job->flags,
210 op_job->mount_source);
211 }
212 }
213
214 /* Might be called on an i/o thread */
215 static void
create_reply(GVfsJob * job,GVfsDBusMount * object,GDBusMethodInvocation * invocation)216 create_reply (GVfsJob *job,
217 GVfsDBusMount *object,
218 GDBusMethodInvocation *invocation)
219 {
220 gvfs_dbus_mount_complete_enumerate (object, invocation);
221 }
222