e1931ca61b2b75d16f1c8105ba9d7f021d9a8121
[captive.git] / src / libcaptive / client / parent-connector.c
1 /* $Id$
2  * fs object sandbox parents reconnections to their sandbox slave peers
3  * Copyright (C) 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 "parent-connector.h"   /* self */
23 #include <glib/gmessages.h>
24
25
26 /* g_object_get_data() 'key': */
27 #define CAPTIVE_PARENT_CONNECTOR_CORBA_OBJECTP             "captive_parent_connector-corba_objectp"     /* &CORBA_Object */
28 #define CAPTIVE_PARENT_CONNECTOR_CAPTIVE_VFS_PARENT_OBJECT "captive_parent_connector-captive_vfs_parent_object" /* &CaptiveVfsParentObject */
29 #define CAPTIVE_PARENT_CONNECTOR_DIRTY                     "captive_parent_connector-dirty"     /* GINT_TO_POINTER(0/1) */
30 #define CAPTIVE_PARENT_CONNECTOR_VFS_SIGNALS_CONNECTED     "captive_parent_connector-vfs_signals_connected"     /* GINT_TO_POINTER(0/1) */
31
32
33 /*
34  * vfs signal <detach>
35  * vfs signal <cease>
36  * vfs signal <abort>
37  * 
38  * connector state vfs          yes/no
39  * connector state corba_object yes/no
40  * connector state dirty        yes/no
41  * 
42  *                 vfs     handle  dirty   oper.   detach  cease   abort
43  * disconnected    N       N       N       opn_*   discon. discon. discon.
44  * broken          N       N       Y       broken  broken  broken  broken
45  * N/A             N       Y       N
46  * N/A             N       Y       Y
47  * closed_clean    Y       N       N       X       X       discon. discon.
48  * closed_dirty    Y       N       Y       X       X       discon. broken
49  * opened_clean    Y       Y       N       opn_*   cls_cln X       discon.
50  * opened_dirty    Y       Y       Y       opn_drt cls_drt X       broken
51  * 
52  * init->disconnected
53  * 
54  * <detach>[VFS shutdown]<cease>
55  * <detach>[failure]<abort>
56  * [failure]<abort>
57  * 
58  * 
59  * sandbox master GObject hierarchy (horizontal=dervived):
60  *         DirectoryParent----------------------------------->Directory->GObject
61  *                        \->ParentConnector->GTypeInterface   |
62  *                                  | [ref.]                   | [reference]
63  *                                 VfsParent----------------->Vfs->GObject
64  * 
65  * sandbox master GObject reconnections signalling:
66  *               VfsParent -> ParentConnector
67  *         ParentConnector -> DirectoryParent
68  * sandbox master reconnection requests:
69  *         DirectoryParent -> ParentConnector
70  *         ParentConnector -> VfsParent
71  * 
72  * CORBA/ORBit connections:
73  *         sandbox master                   |  sandbox slave (restartable)
74  *         ---------------------------------|-----------------------------------
75  *         DirectoryParent--Directory_stub <-> Directory_servant--DirectorySlave
76  *               VfsParent--------Vfs_stub <->       Vfs_servant--VfsSlave
77  * 
78  * sandbox slave GObject hierarchy (horizontal=dervived):
79  *         DirectorySlave->Directory->GObject
80  *                          | [reference]
81  *               VfsSlave->Vfs->GObject
82  */
83
84
85 static GnomeVFSResult captive_parent_connector_handler_open(CaptiveParentConnector *captive_parent_connector);
86 static GnomeVFSResult captive_parent_connector_handler_close(CaptiveParentConnector *captive_parent_connector);
87
88
89 static void captive_parent_connector_iface_init(CaptiveParentConnectorIface *captive_parent_connector_iface)
90 {
91         captive_parent_connector_iface->open=captive_parent_connector_handler_open;
92         captive_parent_connector_iface->close=captive_parent_connector_handler_close;
93 }
94
95
96 GType captive_parent_connector_get_type(void)
97 {
98 static GType captive_parent_connector_type=0;
99
100         if (!captive_parent_connector_type) {
101 static const GTypeInfo captive_parent_connector_info={
102                                 sizeof(CaptiveParentConnectorIface),
103                                 (GBaseInitFunc)captive_parent_connector_iface_init,     /* base_init */
104                                 NULL,   /* base_finalize */
105                                 NULL,   /* iface_init */
106                                 NULL,   /* iface_finalize */
107                                 NULL,   /* iface_data */
108                                 0,      /* instance_size */
109                                 0,      /* n_preallocs */
110                                 NULL,   /* instance_init */
111                                 };
112
113                 captive_parent_connector_type=g_type_register_static(G_TYPE_INTERFACE,
114                                 "CaptiveParentConnector",&captive_parent_connector_info,0);
115                 }
116
117         return captive_parent_connector_type;
118 }
119
120 static void captive_parent_connector_vfs_signals_disconnect(CaptiveParentConnector *captive_parent_connector);
121
122 static void captive_parent_connector_vfs_detach(CaptiveVfsParentObject *captive_vfs_parent_object,
123                 CaptiveParentConnector *captive_parent_connector)
124 {
125         g_return_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object));
126         g_return_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector));
127         g_return_if_fail(captive_vfs_parent_object==captive_parent_connector_get_captive_vfs_parent_object(captive_parent_connector));
128
129         /**/ if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED))
130                 /* NOP */;
131         else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_BROKEN))
132                 /* NOP */;
133         else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED))
134                 g_assert_not_reached();
135         else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED)) {
136                 (*CAPTIVE_PARENT_CONNECTOR_GET_IFACE(captive_parent_connector)->close)(captive_parent_connector);       /* errors ignored */
137                 g_assert(captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED));
138                 }
139         else g_assert_not_reached();
140 }
141
142 static void captive_parent_connector_vfs_cease(CaptiveVfsParentObject *captive_vfs_parent_object,
143                 CaptiveParentConnector *captive_parent_connector)
144 {
145         g_return_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object));
146         g_return_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector));
147         g_return_if_fail(captive_vfs_parent_object==captive_parent_connector_get_captive_vfs_parent_object(captive_parent_connector));
148
149         /**/ if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED))
150                 /* NOP */;
151         else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_BROKEN))
152                 /* NOP */;
153         else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED)) {
154                 g_object_set_data(G_OBJECT(captive_parent_connector),CAPTIVE_PARENT_CONNECTOR_DIRTY,
155                                 GINT_TO_POINTER(FALSE));
156                 }
157         else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED))
158                 g_assert_not_reached();
159         else g_assert_not_reached();
160
161         captive_parent_connector_vfs_signals_disconnect(captive_parent_connector);
162 }
163
164 static void captive_parent_connector_vfs_abort(CaptiveVfsParentObject *captive_vfs_parent_object,
165                 CaptiveParentConnector *captive_parent_connector)
166 {
167         g_return_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object));
168         g_return_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector));
169         g_return_if_fail(captive_vfs_parent_object==captive_parent_connector_get_captive_vfs_parent_object(captive_parent_connector));
170
171         /**/ if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED))
172                 /* NOP */;
173         else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_BROKEN))
174                 /* NOP */;
175         else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED))
176                 /* NOP */;      /* -> DISCONNECTED or BROKEN */
177         else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED)) {
178                 (*CAPTIVE_PARENT_CONNECTOR_GET_IFACE(captive_parent_connector)->close)(captive_parent_connector);       /* errors ignored */
179                 g_assert(captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED));
180                 }
181         else g_assert_not_reached();
182
183         captive_parent_connector_vfs_signals_disconnect(captive_parent_connector);
184 }
185
186 static void captive_parent_connector_vfs_signals_connect(CaptiveParentConnector *captive_parent_connector)
187 {
188 CaptiveVfsParentObject *captive_vfs_parent_object;
189
190         g_return_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector));
191
192         captive_vfs_parent_object=captive_parent_connector_get_captive_vfs_parent_object(captive_parent_connector);
193
194         if (g_object_get_data(G_OBJECT(captive_vfs_parent_object),CAPTIVE_PARENT_CONNECTOR_VFS_SIGNALS_CONNECTED))
195                 return;
196
197         g_object_ref(captive_vfs_parent_object);
198
199         g_signal_connect(captive_vfs_parent_object,"detach",
200                         G_CALLBACK(captive_parent_connector_vfs_detach),captive_parent_connector);      /* c_handler,data */
201         g_signal_connect(captive_vfs_parent_object,"cease",
202                         G_CALLBACK(captive_parent_connector_vfs_cease),captive_parent_connector);       /* c_handler,data */
203         g_signal_connect(captive_vfs_parent_object,"abort",
204                         G_CALLBACK(captive_parent_connector_vfs_abort),captive_parent_connector);       /* c_handler,data */
205
206         g_object_set_data(G_OBJECT(captive_vfs_parent_object),CAPTIVE_PARENT_CONNECTOR_VFS_SIGNALS_CONNECTED,
207                         GINT_TO_POINTER(TRUE));
208 }
209
210 static void captive_parent_connector_vfs_signals_disconnect(CaptiveParentConnector *captive_parent_connector)
211 {
212 CaptiveVfsParentObject *captive_vfs_parent_object;
213
214         g_return_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector));
215
216         captive_vfs_parent_object=captive_parent_connector_get_captive_vfs_parent_object(captive_parent_connector);
217
218         if (!g_object_get_data(G_OBJECT(captive_vfs_parent_object),CAPTIVE_PARENT_CONNECTOR_VFS_SIGNALS_CONNECTED))
219                 return;
220
221         g_signal_handlers_disconnect_by_func(captive_vfs_parent_object,
222                         G_CALLBACK(captive_parent_connector_vfs_detach),captive_parent_connector);      /* func,data */
223         g_signal_handlers_disconnect_by_func(captive_vfs_parent_object,
224                         G_CALLBACK(captive_parent_connector_vfs_cease),captive_parent_connector);       /* func,data */
225         g_signal_handlers_disconnect_by_func(captive_vfs_parent_object,
226                         G_CALLBACK(captive_parent_connector_vfs_abort),captive_parent_connector);       /* func,data */
227
228         g_object_unref(captive_vfs_parent_object);
229
230         g_object_set_data(G_OBJECT(captive_vfs_parent_object),CAPTIVE_PARENT_CONNECTOR_VFS_SIGNALS_CONNECTED,
231                         GINT_TO_POINTER(FALSE));
232 }
233
234 void captive_parent_connector_init(CaptiveParentConnector *captive_parent_connector,
235                 CORBA_Object *corba_objectp,CaptiveVfsParentObject *captive_vfs_parent_object)
236 {
237         g_return_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector));
238         g_return_if_fail(corba_objectp!=NULL);
239         g_return_if_fail(/* CORBA_Object_is_nil() */ *corba_objectp==CORBA_OBJECT_NIL);
240         g_return_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object));
241
242         g_object_set_data(G_OBJECT(captive_parent_connector),CAPTIVE_PARENT_CONNECTOR_CORBA_OBJECTP,
243                         corba_objectp);
244         g_object_set_data(G_OBJECT(captive_parent_connector),CAPTIVE_PARENT_CONNECTOR_CAPTIVE_VFS_PARENT_OBJECT,
245                         captive_vfs_parent_object);
246         g_object_set_data(G_OBJECT(captive_parent_connector),CAPTIVE_PARENT_CONNECTOR_DIRTY,
247                         GINT_TO_POINTER(FALSE));
248
249         g_assert(captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED_OR_CLOSED));
250 }
251
252
253 void captive_parent_connector_finalize(CaptiveParentConnector *captive_parent_connector)
254 {
255         g_return_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector));
256
257         g_assert(captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED_OR_CLOSED));
258
259         captive_parent_connector_vfs_signals_disconnect(captive_parent_connector);
260 }
261
262
263 GnomeVFSResult captive_parent_connector_connect(CaptiveParentConnector *captive_parent_connector)
264 {
265 GnomeVFSResult r;
266
267         g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),GNOME_VFS_ERROR_BAD_PARAMETERS);
268
269         if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED)) {
270                 if (GNOME_VFS_OK!=(r=captive_vfs_parent_object_connect(
271                                 captive_parent_connector_get_captive_vfs_parent_object(captive_parent_connector))))
272                         return r;
273                 g_assert(captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED_CLEAN));
274                 }
275
276         /**/ if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED))
277                 g_assert_not_reached();
278         else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_BROKEN))
279                 return GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE;
280         else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED))
281                 return GNOME_VFS_OK;
282         else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED))
283                 return GNOME_VFS_OK;
284         else g_assert_not_reached();
285
286         /* NOTREACHED */
287         return GNOME_VFS_ERROR_INTERNAL;
288 }
289
290
291 GnomeVFSResult captive_parent_connector_open(CaptiveParentConnector *captive_parent_connector)
292 {
293 GnomeVFSResult r;
294
295         g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),GNOME_VFS_ERROR_BAD_PARAMETERS);
296
297         if (GNOME_VFS_OK!=(r=captive_parent_connector_connect(captive_parent_connector)))
298                 return r;
299
300         if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED)) {
301                 if (GNOME_VFS_OK!=(r=(*CAPTIVE_PARENT_CONNECTOR_GET_IFACE(captive_parent_connector)->open)(captive_parent_connector)))
302                         return r;
303                 g_assert(captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED));
304                 }
305
306         /**/ if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED))
307                 g_assert_not_reached();
308         else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_BROKEN))
309                 g_assert_not_reached();
310         else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED))
311                 g_assert_not_reached();
312         else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED))
313                 return GNOME_VFS_OK;
314         else g_assert_not_reached();
315
316         /* NOTREACHED */
317         return GNOME_VFS_ERROR_INTERNAL;
318 }
319
320
321 GnomeVFSResult captive_parent_connector_close(CaptiveParentConnector *captive_parent_connector)
322 {
323 GnomeVFSResult r;
324
325         g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),GNOME_VFS_ERROR_BAD_PARAMETERS);
326
327         if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED)) {
328                 if (GNOME_VFS_OK!=(r=(*CAPTIVE_PARENT_CONNECTOR_GET_IFACE(captive_parent_connector)->close)(captive_parent_connector)))
329                         return r;
330                 g_assert(captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED));
331                 }
332
333         /**/ if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED))
334                 return GNOME_VFS_OK;
335         else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_BROKEN))
336                 return GNOME_VFS_OK;
337         else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED))
338                 return GNOME_VFS_OK;
339         else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED))
340                 g_assert_not_reached();
341         else g_assert_not_reached();
342
343         /* NOTREACHED */
344         return GNOME_VFS_ERROR_INTERNAL;
345 }
346
347
348 void captive_parent_connector_set_dirty(CaptiveParentConnector *captive_parent_connector)
349 {
350         g_return_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector));
351
352         g_return_if_fail(captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED));
353
354         g_object_set_data(G_OBJECT(captive_parent_connector),CAPTIVE_PARENT_CONNECTOR_DIRTY,
355                         GINT_TO_POINTER(TRUE));
356 }
357
358
359 static GnomeVFSResult captive_parent_connector_handler_open(CaptiveParentConnector *captive_parent_connector)
360 {
361         g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),GNOME_VFS_ERROR_BAD_PARAMETERS);
362
363         /* Handler should have 'opened' us. */
364
365         /**/ if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED))
366                 g_assert_not_reached();
367         else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_BROKEN))
368                 g_assert_not_reached();
369         else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED))
370                 g_assert_not_reached(); /* Parent handler failed. */
371         else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED)) {
372                 captive_parent_connector_vfs_signals_connect(captive_parent_connector);
373                 return GNOME_VFS_OK;
374                 }
375         else g_assert_not_reached();
376
377         /* NOTREACHED */
378         return GNOME_VFS_ERROR_INTERNAL;
379 }
380
381
382 static GnomeVFSResult captive_parent_connector_handler_close(CaptiveParentConnector *captive_parent_connector)
383 {
384         g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),GNOME_VFS_ERROR_BAD_PARAMETERS);
385
386         /* Handler should have 'closed' us. */
387
388         /**/ if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_DISCONNECTED)) {
389                 captive_parent_connector_vfs_signals_disconnect(captive_parent_connector);
390                 return GNOME_VFS_OK;
391                 }
392         else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_BROKEN)) {
393                 captive_parent_connector_vfs_signals_disconnect(captive_parent_connector);
394                 return GNOME_VFS_OK;
395                 }
396         else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_CLOSED))
397                 return GNOME_VFS_OK;
398         else if (captive_parent_connector_is_state(captive_parent_connector,CAPTIVE_PARENT_CONNECTOR_FLAGS_OPENED))
399                 g_assert_not_reached();
400         else g_assert_not_reached();
401
402         /* NOTREACHED */
403         return GNOME_VFS_ERROR_INTERNAL;
404 }
405
406
407 CaptiveVfsParentObject *captive_parent_connector_get_captive_vfs_parent_object
408                 (CaptiveParentConnector *captive_parent_connector)
409 {
410 CaptiveVfsParentObject *r;
411
412         g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),NULL);
413
414         r=g_object_get_data(G_OBJECT(captive_parent_connector),CAPTIVE_PARENT_CONNECTOR_CAPTIVE_VFS_PARENT_OBJECT);
415         g_assert(CAPTIVE_VFS_PARENT_IS_OBJECT(r));
416
417         return r;
418 }
419
420
421 CORBA_Object captive_parent_connector_get_corba_object(CaptiveParentConnector *captive_parent_connector)
422 {
423 CORBA_Object *rp;
424
425         g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),NULL);
426
427         rp=g_object_get_data(G_OBJECT(captive_parent_connector),CAPTIVE_PARENT_CONNECTOR_CORBA_OBJECTP);
428         g_assert(rp!=NULL);
429         /* '*rp' may be NULL */
430
431         return *rp;
432 }
433
434
435 gboolean captive_parent_connector_get_dirty(CaptiveParentConnector *captive_parent_connector)
436 {
437 gpointer r_gpointer;
438 gint r_gint;
439
440         g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),FALSE);
441
442         r_gpointer=g_object_get_data(G_OBJECT(captive_parent_connector),CAPTIVE_PARENT_CONNECTOR_DIRTY);
443         r_gint=GPOINTER_TO_INT(r_gpointer);
444         g_assert(r_gint==TRUE || r_gint==FALSE);
445
446         return r_gint;
447 }
448
449
450 gboolean captive_parent_connector_is_state(CaptiveParentConnector *captive_parent_connector,
451                 CaptiveParentConnectorFlagWant vfs_want,
452                 CaptiveParentConnectorFlagWant corba_object_want,CaptiveParentConnectorFlagWant dirty_want)
453 {
454         g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),FALSE);
455
456         if (vfs_want!=CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ANY) {
457 CaptiveVfsParentObject *captive_vfs_parent_object;
458
459                 captive_vfs_parent_object=captive_parent_connector_get_captive_vfs_parent_object(captive_parent_connector);
460                 if ((vfs_want==CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ON)!=
461                                 (/* !CORBA_Object_is_nil() */ captive_vfs_parent_object->corba_Vfs_object!=CORBA_OBJECT_NIL))
462                         return FALSE;
463                 }
464         if (corba_object_want!=CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ANY) {
465 CORBA_Object corba_object;
466
467                 corba_object=captive_parent_connector_get_corba_object(captive_parent_connector);
468                 if ((corba_object_want==CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ON)!=
469                                 (/* !CORBA_Object_is_nil() */ corba_object!=CORBA_OBJECT_NIL))
470                         return FALSE;
471                 }
472         if (dirty_want!=CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ANY) {
473 gboolean dirty;
474
475                 dirty=captive_parent_connector_get_dirty(captive_parent_connector);
476                 if ((dirty_want==CAPTIVE_PARENT_CONNECTOR_FLAG_WANT_ON)!=dirty)
477                         return FALSE;
478                 }
479
480         return TRUE;
481 }