/* $Id$ * captive vfs 'vfs' interface to reactos of sandbox parent * Copyright (C) 2002-2003 Jan Kratochvil * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; exactly version 2 of June 1991 is required * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "vfs-parent.h" /* self */ #include #include "captive/macros.h" #include "../sandbox/parent-Vfs.h" #include "directory-parent.h" #include "file-parent.h" #include "marshallers.h" static gpointer captive_vfs_parent_object_parent_class=NULL; static GnomeVFSResult captive_vfs_parent_init(CaptiveVfsObject *captive_vfs_object); static void captive_vfs_parent_object_dispose(CaptiveVfsParentObject *captive_vfs_parent_object); static void captive_vfs_parent_object_handler_detach(CaptiveVfsParentObject *captive_vfs_parent_object); static void captive_vfs_parent_object_handler_cease(CaptiveVfsParentObject *captive_vfs_parent_object); static void captive_vfs_parent_object_handler_abort(CaptiveVfsParentObject *captive_vfs_parent_object); static GnomeVFSResult captive_vfs_parent_close(CaptiveVfsObject *captive_vfs_object); static GnomeVFSResult captive_vfs_parent_commit(CaptiveVfsObject *captive_vfs_object); static GnomeVFSResult captive_vfs_parent_volume_info_get (CaptiveVfsObject *captive_vfs_object,CaptiveVfsVolumeInfo *volume_info); static GnomeVFSResult captive_vfs_parent_object_connect_silent(CaptiveVfsParentObject *captive_vfs_parent_object); /* We need to close the filesystem during custom 'dispose' * as the default GObject g_object_real_dispose() destroys all the signals * first and we would not notify our Connectors during captive_vfs_parent_object_finalize(). */ static void captive_vfs_parent_object_dispose(CaptiveVfsParentObject *captive_vfs_parent_object) { g_return_if_fail(captive_vfs_parent_object!=NULL); captive_vfs_parent_close(CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)); /* errors ignored */ G_OBJECT_CLASS(captive_vfs_parent_object_parent_class)->dispose((GObject *)captive_vfs_parent_object); } static void captive_vfs_parent_object_finalize(CaptiveVfsParentObject *captive_vfs_parent_object) { g_return_if_fail(captive_vfs_parent_object!=NULL); G_OBJECT_CLASS(captive_vfs_parent_object_parent_class)->finalize((GObject *)captive_vfs_parent_object); } static void captive_vfs_parent_object_class_init(CaptiveVfsParentObjectClass *class) { GObjectClass *gobject_class=G_OBJECT_CLASS(class); CaptiveVfsObjectClass *captive_vfs_object_class=CAPTIVE_VFS_OBJECT_CLASS(class); captive_vfs_parent_object_parent_class=g_type_class_ref(g_type_parent(G_TYPE_FROM_CLASS(class))); gobject_class->dispose=(void (*)(GObject *object))captive_vfs_parent_object_dispose; gobject_class->finalize=(void (*)(GObject *object))captive_vfs_parent_object_finalize; captive_vfs_object_class->init=captive_vfs_parent_init; captive_vfs_object_class->commit=captive_vfs_parent_commit; captive_vfs_object_class->volume_info_get=captive_vfs_parent_volume_info_get; captive_vfs_object_class->directory_new_open=captive_directory_parent_new_open; captive_vfs_object_class->directory_new_make=captive_directory_parent_new_make; captive_vfs_object_class->file_new_open=captive_file_parent_new_open; captive_vfs_object_class->file_new_create=captive_file_parent_new_create; class->detach=captive_vfs_parent_object_handler_detach; g_signal_new( "detach", /* signal_name */ G_TYPE_FROM_CLASS(class), /* itype */ G_SIGNAL_RUN_LAST, /* signal_flags */ G_STRUCT_OFFSET(CaptiveVfsParentObjectClass,detach), /* class_offset */ NULL,NULL, /* accumulator,accu_data */ captive_client_VOID__VOID, /* c_marshaller */ G_TYPE_NONE,0); /* return_type,n_params */ class->cease=captive_vfs_parent_object_handler_cease; g_signal_new( "cease", /* signal_name */ G_TYPE_FROM_CLASS(class), /* itype */ G_SIGNAL_RUN_LAST, /* signal_flags */ G_STRUCT_OFFSET(CaptiveVfsParentObjectClass,cease), /* class_offset */ NULL,NULL, /* accumulator,accu_data */ captive_client_VOID__VOID, /* c_marshaller */ G_TYPE_NONE,0); /* return_type,n_params */ class->abort=captive_vfs_parent_object_handler_abort; g_signal_new( "abort", /* signal_name */ G_TYPE_FROM_CLASS(class), /* itype */ G_SIGNAL_RUN_LAST, /* signal_flags */ G_STRUCT_OFFSET(CaptiveVfsParentObjectClass,abort), /* class_offset */ NULL,NULL, /* accumulator,accu_data */ captive_client_VOID__VOID, /* c_marshaller */ G_TYPE_NONE,0); /* return_type,n_params */ } static void captive_vfs_parent_object_init(CaptiveVfsParentObject *captive_vfs_parent_object) { captive_vfs_parent_object->corba_parent_giochanel_blind=NULL; } static void captive_vfs_parent_object_handler_detach(CaptiveVfsParentObject *captive_vfs_parent_object) { g_return_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object)); } static void captive_vfs_parent_object_handler_cease(CaptiveVfsParentObject *captive_vfs_parent_object) { g_return_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object)); } static void captive_vfs_parent_object_handler_abort(CaptiveVfsParentObject *captive_vfs_parent_object) { g_return_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object)); } GType captive_vfs_parent_object_get_type(void) { static GType captive_vfs_parent_object_type=0; if (!captive_vfs_parent_object_type) { static const GTypeInfo captive_vfs_parent_object_info={ sizeof(CaptiveVfsParentObjectClass), NULL, /* base_init */ NULL, /* base_finalize */ (GClassInitFunc)captive_vfs_parent_object_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof(CaptiveVfsParentObject), 5, /* n_preallocs */ (GInstanceInitFunc)captive_vfs_parent_object_init, }; captive_vfs_parent_object_type=g_type_register_static(CAPTIVE_VFS_TYPE_OBJECT, "CaptiveVfsParentObject",&captive_vfs_parent_object_info,0); } return captive_vfs_parent_object_type; } static GnomeVFSResult captive_vfs_parent_init(CaptiveVfsObject *captive_vfs_object) { CaptiveVfsParentObject *captive_vfs_parent_object; g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_object),GNOME_VFS_ERROR_BAD_PARAMETERS); captive_vfs_parent_object=CAPTIVE_VFS_PARENT_OBJECT(captive_vfs_object); return captive_sandbox_parent_vfs_new(captive_vfs_parent_object); } static GnomeVFSResult captive_vfs_parent_close(CaptiveVfsObject *captive_vfs_object) { CaptiveVfsParentObject *captive_vfs_parent_object; GnomeVFSResult r; g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_object),GNOME_VFS_ERROR_BAD_PARAMETERS); captive_vfs_parent_object=CAPTIVE_VFS_PARENT_OBJECT(captive_vfs_object); if (captive_vfs_parent_object->corba_Vfs_object!=CORBA_OBJECT_NIL) { r=captive_vfs_parent_object_disconnect(captive_vfs_parent_object); g_assert(captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL); } else r=GNOME_VFS_OK; if (captive_vfs_parent_object->corba_parent_giochanel_blind_source) { g_io_channel_unref(captive_vfs_parent_object->corba_parent_giochanel_blind_source); captive_vfs_parent_object->corba_parent_giochanel_blind_source=NULL; } return r; } static GnomeVFSResult captive_vfs_parent_commit(CaptiveVfsObject *captive_vfs_object) { CaptiveVfsParentObject *captive_vfs_parent_object; GnomeVFSResult r; gint retried=0; g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_object),GNOME_VFS_ERROR_BAD_PARAMETERS); captive_vfs_parent_object=CAPTIVE_VFS_PARENT_OBJECT(captive_vfs_object); do { if (captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL && GNOME_VFS_OK!=(r=captive_vfs_parent_object_connect_silent(captive_vfs_parent_object))) return r; if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE !=(r=captive_sandbox_parent_vfs_commit(captive_vfs_parent_object))) return r; } while (!retried++); return r; } static GnomeVFSResult captive_vfs_parent_volume_info_get (CaptiveVfsObject *captive_vfs_object,CaptiveVfsVolumeInfo *volume_info) { CaptiveVfsParentObject *captive_vfs_parent_object; GnomeVFSResult r; gint retried=0; g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_object),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(volume_info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); captive_vfs_parent_object=CAPTIVE_VFS_PARENT_OBJECT(captive_vfs_object); do { if (captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL && GNOME_VFS_OK!=(r=captive_vfs_parent_object_connect(captive_vfs_parent_object))) return r; if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE !=(r=captive_sandbox_parent_vfs_volume_info_get(captive_vfs_parent_object,volume_info))) return r; } while (!retried++); return r; } GnomeVFSResult captive_vfs_parent_object_connect(CaptiveVfsParentObject *captive_vfs_parent_object) { g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS); return captive_sandbox_parent_vfs_new(captive_vfs_parent_object); } static GnomeVFSResult captive_vfs_parent_object_connect_silent(CaptiveVfsParentObject *captive_vfs_parent_object) { g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS); return captive_sandbox_parent_vfs_new_silent(captive_vfs_parent_object); } GnomeVFSResult captive_vfs_parent_object_disconnect(CaptiveVfsParentObject *captive_vfs_parent_object) { GnomeVFSResult r; g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object!=CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS); /* Detach all connectors: */ g_signal_emit_by_name(captive_vfs_parent_object,"detach"); /* Some connector detaching broke the connection? */ if (captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL) { /* "abort" should have been emitted by captive_vfs_parent_object_aborted() */ return GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE; } if (GNOME_VFS_OK!=(r=captive_sandbox_parent_vfs_close(captive_vfs_parent_object))) { /* Some non-ORBit shutdown error may have occured: */ g_signal_emit_by_name(captive_vfs_parent_object,"abort"); return r; } /* success: */ g_signal_emit_by_name(captive_vfs_parent_object,"cease"); return GNOME_VFS_OK; } GnomeVFSResult captive_vfs_parent_object_aborted(CaptiveVfsParentObject *captive_vfs_parent_object) { static gint inside=0; GnomeVFSResult r; g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object!=CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS); /* Prevent looping by COMM_FAILURE of 'unmount' operation * by captive_sandbox_parent_vfs_close(). */ g_assert(inside>=0); if (inside) return GNOME_VFS_OK; inside++; g_signal_emit_by_name(captive_vfs_parent_object,"abort"); r=captive_sandbox_parent_vfs_close(captive_vfs_parent_object); g_assert(inside==1); inside--; return r; }