Implemented CaptiveParentConnector sandbox restarts handling GInterface.
[captive.git] / src / libcaptive / client / vfs-parent.c
1 /* $Id$
2  * captive vfs 'vfs' interface to reactos of sandbox parent
3  * Copyright (C) 2002-2003 Jan Kratochvil <project-captive@jankratochvil.net>
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; exactly version 2 of June 1991 is required
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19
20 #include "config.h"
21
22 #include "vfs-parent.h" /* self */
23 #include <glib/gmessages.h>
24 #include "captive/macros.h"
25 #include "../sandbox/parent-Vfs.h"
26 #include "directory-parent.h"
27 #include "file-parent.h"
28 #include "marshallers.h"
29
30
31 static gpointer captive_vfs_parent_object_parent_class=NULL;
32
33
34 static GnomeVFSResult captive_vfs_parent_init(CaptiveVfsObject *captive_vfs_object);
35 static void captive_vfs_parent_object_handler_detach(CaptiveVfsParentObject *captive_vfs_parent_object);
36 static void captive_vfs_parent_object_handler_cease(CaptiveVfsParentObject *captive_vfs_parent_object);
37 static void captive_vfs_parent_object_handler_abort(CaptiveVfsParentObject *captive_vfs_parent_object);
38 static GnomeVFSResult captive_vfs_parent_close(CaptiveVfsObject *captive_vfs_object);
39 static GnomeVFSResult captive_vfs_parent_commit(CaptiveVfsObject *captive_vfs_object);
40 static GnomeVFSResult captive_vfs_parent_volume_info_get
41                 (CaptiveVfsObject *captive_vfs_object,CaptiveVfsVolumeInfo *volume_info);
42
43
44 static void captive_vfs_parent_object_finalize(CaptiveVfsParentObject *captive_vfs_parent_object)
45 {
46         g_return_if_fail(captive_vfs_parent_object!=NULL);
47
48         captive_vfs_parent_close(CAPTIVE_VFS_OBJECT(captive_vfs_parent_object));        /* errors ignored */
49
50         G_OBJECT_CLASS(captive_vfs_parent_object_parent_class)->finalize((GObject *)captive_vfs_parent_object);
51 }
52
53
54 static void captive_vfs_parent_object_class_init(CaptiveVfsParentObjectClass *class)
55 {
56 GObjectClass *gobject_class=G_OBJECT_CLASS(class);
57 CaptiveVfsObjectClass *captive_vfs_object_class=CAPTIVE_VFS_OBJECT_CLASS(class);
58
59         captive_vfs_parent_object_parent_class=g_type_class_ref(g_type_parent(G_TYPE_FROM_CLASS(class)));
60         gobject_class->finalize=(void (*)(GObject *object))captive_vfs_parent_object_finalize;
61
62         captive_vfs_object_class->init=captive_vfs_parent_init;
63         captive_vfs_object_class->commit=captive_vfs_parent_commit;
64         captive_vfs_object_class->volume_info_get=captive_vfs_parent_volume_info_get;
65
66         captive_vfs_object_class->directory_new_open=captive_directory_parent_new_open;
67         captive_vfs_object_class->directory_new_make=captive_directory_parent_new_make;
68
69         captive_vfs_object_class->file_new_open=captive_file_parent_new_open;
70         captive_vfs_object_class->file_new_create=captive_file_parent_new_create;
71
72         class->detach=captive_vfs_parent_object_handler_detach;
73         g_signal_new(
74                         "detach",       /* signal_name */
75                         G_TYPE_FROM_CLASS(class),       /* itype */
76                         G_SIGNAL_RUN_LAST,      /* signal_flags */
77                         G_STRUCT_OFFSET(CaptiveVfsParentObjectClass,detach),    /* class_offset */
78                         NULL,NULL,      /* accumulator,accu_data */
79                         captive_client_VOID__VOID,      /* c_marshaller */
80                         G_TYPE_NONE,0); /* return_type,n_params */
81         class->cease=captive_vfs_parent_object_handler_cease;
82         g_signal_new(
83                         "cease",        /* signal_name */
84                         G_TYPE_FROM_CLASS(class),       /* itype */
85                         G_SIGNAL_RUN_LAST,      /* signal_flags */
86                         G_STRUCT_OFFSET(CaptiveVfsParentObjectClass,cease),     /* class_offset */
87                         NULL,NULL,      /* accumulator,accu_data */
88                         captive_client_VOID__VOID,      /* c_marshaller */
89                         G_TYPE_NONE,0); /* return_type,n_params */
90         class->abort=captive_vfs_parent_object_handler_abort;
91         g_signal_new(
92                         "abort",        /* signal_name */
93                         G_TYPE_FROM_CLASS(class),       /* itype */
94                         G_SIGNAL_RUN_LAST,      /* signal_flags */
95                         G_STRUCT_OFFSET(CaptiveVfsParentObjectClass,abort),     /* class_offset */
96                         NULL,NULL,      /* accumulator,accu_data */
97                         captive_client_VOID__VOID,      /* c_marshaller */
98                         G_TYPE_NONE,0); /* return_type,n_params */
99 }
100
101
102 static void captive_vfs_parent_object_init(CaptiveVfsParentObject *captive_vfs_parent_object)
103 {
104         captive_vfs_parent_object->corba_parent_giochanel_blind=NULL;
105 }
106
107         
108 static void captive_vfs_parent_object_handler_detach(CaptiveVfsParentObject *captive_vfs_parent_object)
109 {
110         g_return_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object));
111 }
112
113 static void captive_vfs_parent_object_handler_cease(CaptiveVfsParentObject *captive_vfs_parent_object)
114 {
115         g_return_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object));
116 }
117
118 static void captive_vfs_parent_object_handler_abort(CaptiveVfsParentObject *captive_vfs_parent_object)
119 {
120         g_return_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object));
121 }
122
123
124 GType captive_vfs_parent_object_get_type(void)
125 {
126 static GType captive_vfs_parent_object_type=0;
127
128         if (!captive_vfs_parent_object_type) {
129 static const GTypeInfo captive_vfs_parent_object_info={
130                                 sizeof(CaptiveVfsParentObjectClass),
131                                 NULL,   /* base_init */
132                                 NULL,   /* base_finalize */
133                                 (GClassInitFunc)captive_vfs_parent_object_class_init,
134                                 NULL,   /* class_finalize */
135                                 NULL,   /* class_data */
136                                 sizeof(CaptiveVfsParentObject),
137                                 5,      /* n_preallocs */
138                                 (GInstanceInitFunc)captive_vfs_parent_object_init,
139                                 };
140
141                 captive_vfs_parent_object_type=g_type_register_static(CAPTIVE_VFS_TYPE_OBJECT,
142                                 "CaptiveVfsParentObject",&captive_vfs_parent_object_info,0);
143                 }
144
145         return captive_vfs_parent_object_type;
146 }
147
148
149 static GnomeVFSResult captive_vfs_parent_init(CaptiveVfsObject *captive_vfs_object)
150 {
151 CaptiveVfsParentObject *captive_vfs_parent_object;
152
153         g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
154
155         captive_vfs_parent_object=CAPTIVE_VFS_PARENT_OBJECT(captive_vfs_object);
156
157         return captive_sandbox_parent_vfs_new(captive_vfs_parent_object);
158 }
159
160
161 static GnomeVFSResult captive_vfs_parent_close(CaptiveVfsObject *captive_vfs_object)
162 {
163 CaptiveVfsParentObject *captive_vfs_parent_object;
164 GnomeVFSResult r;
165
166         g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
167
168         captive_vfs_parent_object=CAPTIVE_VFS_PARENT_OBJECT(captive_vfs_object);
169
170         if (captive_vfs_parent_object->corba_Vfs_object!=CORBA_OBJECT_NIL) {
171                 r=captive_sandbox_parent_vfs_close(captive_vfs_parent_object);
172                 g_assert(captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL);
173                 }
174         else
175                 r=GNOME_VFS_OK;
176
177         return r;
178 }
179
180
181 static GnomeVFSResult captive_vfs_parent_commit(CaptiveVfsObject *captive_vfs_object)
182 {
183 CaptiveVfsParentObject *captive_vfs_parent_object;
184 GnomeVFSResult r;
185 gint retried=0;
186
187         g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
188
189         captive_vfs_parent_object=CAPTIVE_VFS_PARENT_OBJECT(captive_vfs_object);
190
191         do {
192                 if (captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL
193                                 && GNOME_VFS_OK!=(r=captive_vfs_parent_object_connect(captive_vfs_parent_object)))
194                         return r;
195                 if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE
196                                 !=(r=captive_sandbox_parent_vfs_commit(captive_vfs_parent_object)))
197                         return r;
198                 } while (!retried++);
199         return r;
200 }
201
202
203 static GnomeVFSResult captive_vfs_parent_volume_info_get
204                 (CaptiveVfsObject *captive_vfs_object,CaptiveVfsVolumeInfo *volume_info)
205 {
206 CaptiveVfsParentObject *captive_vfs_parent_object;
207 GnomeVFSResult r;
208 gint retried=0;
209
210         g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
211         g_return_val_if_fail(volume_info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
212
213         captive_vfs_parent_object=CAPTIVE_VFS_PARENT_OBJECT(captive_vfs_object);
214
215         do {
216                 if (captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL
217                                 && GNOME_VFS_OK!=(r=captive_vfs_parent_object_connect(captive_vfs_parent_object)))
218                         return r;
219                 if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE
220                                 !=(r=captive_sandbox_parent_vfs_volume_info_get(captive_vfs_parent_object,volume_info)))
221                         return r;
222                 } while (!retried++);
223         return r;
224 }
225
226
227 GnomeVFSResult captive_vfs_parent_object_connect(CaptiveVfsParentObject *captive_vfs_parent_object)
228 {
229         g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
230
231         g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS);
232
233         return captive_sandbox_parent_vfs_new(captive_vfs_parent_object);
234 }
235
236
237 GnomeVFSResult captive_vfs_parent_object_disconnect(CaptiveVfsParentObject *captive_vfs_parent_object)
238 {
239 GnomeVFSResult r;
240
241         g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
242
243         g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object!=CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS);
244
245         /* Detach all connectors: */
246         g_signal_emit_by_name(captive_vfs_parent_object,"detach");
247
248         /* Some connector detaching broke the connection? */
249         if (captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL) {
250                 /* "abort" should have been emitted by captive_vfs_parent_object_aborted() */
251                 return GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE;
252                 }
253
254         if (GNOME_VFS_OK!=(r=captive_sandbox_parent_vfs_close(captive_vfs_parent_object))) {
255                 /* Some non-ORBit shutdown error may have occured: */
256                 g_signal_emit_by_name(captive_vfs_parent_object,"abort");
257                 return r;
258                 }
259
260         /* success: */
261         g_signal_emit_by_name(captive_vfs_parent_object,"cease");
262
263         return GNOME_VFS_OK;
264 }
265
266
267 GnomeVFSResult captive_vfs_parent_object_aborted(CaptiveVfsParentObject *captive_vfs_parent_object)
268 {
269 static gint inside=0;
270 GnomeVFSResult r;
271
272         g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
273
274         g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object!=CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS);
275
276         /* Prevent looping by COMM_FAILURE of 'unmount' operation
277          * by captive_sandbox_parent_vfs_close().
278          */
279         g_assert(inside>=0);
280         if (inside)
281                 return GNOME_VFS_OK;
282         inside++;
283
284         g_signal_emit_by_name(captive_vfs_parent_object,"abort");
285
286         r=captive_sandbox_parent_vfs_close(captive_vfs_parent_object);
287
288         g_assert(inside==1);
289         inside--;
290
291         return r;
292 }