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