/* $Id$ * CORBA/ORBit server side of Vfs object, ran by sandbox_child() * Copyright (C) 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 "server-Vfs.h" /* self */ #include "sandbox.h" #include #include "captive/macros.h" #include "server-Directory.h" #include "server-File.h" #include "split.h" #include "server-GLogFunc.h" #include "client-CaptiveIOChannel.h" #include "../client/vfs-slave.h" static void impl_Captive_Vfs_fini(impl_POA_Captive_Vfs *servant,CORBA_Environment *ev); static void impl_Captive_Vfs_init (impl_POA_Captive_Vfs *servant,const Captive_CaptiveOptions *options_corba,CORBA_Environment *ev); static void impl_Captive_Vfs_shutdown(impl_POA_Captive_Vfs *servant,CORBA_Environment *ev); static void impl_Captive_Vfs_volume_info_get (impl_POA_Captive_Vfs *servant,Captive_CaptiveVfsVolumeInfo *volume_info_corba,CORBA_Environment *ev); static PortableServer_ServantBase__epv impl_Captive_Vfs_base_epv={ NULL, /* _private data */ (gpointer)&impl_Captive_Vfs_fini, /* finalize routine */ NULL, /* default_POA routine */ }; static POA_Captive_Vfs__epv impl_Captive_Vfs_epv={ NULL, /* _private */ (gpointer)&impl_Captive_Vfs_init, (gpointer)&impl_Captive_Vfs_shutdown, (gpointer)&impl_Captive_Vfs_directory_new_open, (gpointer)&impl_Captive_Vfs_directory_new_make, (gpointer)&impl_Captive_Vfs_file_new_open, (gpointer)&impl_Captive_Vfs_file_new_create, (gpointer)&impl_Captive_Vfs_volume_info_get, }; static POA_Captive_Vfs__vepv impl_Captive_Vfs_vepv={ &impl_Captive_Vfs_base_epv, &impl_Captive_Vfs_epv, }; Captive_Vfs impl_Captive_Vfs__create(PortableServer_POA poa,CORBA_Environment *ev) { Captive_Vfs retval; impl_POA_Captive_Vfs *newservant; PortableServer_ObjectId *objid; captive_new0(newservant); /* FIXME: leak */ newservant->servant.vepv=&impl_Captive_Vfs_vepv; newservant->poa=poa; newservant->captive_vfs_object=NULL; POA_Captive_Vfs__init((PortableServer_Servant)newservant,ev); objid=PortableServer_POA_activate_object(poa,newservant,ev); CORBA_free(objid); retval=PortableServer_POA_servant_to_reference(poa,newservant,ev); return retval; } static void impl_Captive_Vfs_fini(impl_POA_Captive_Vfs *servant,CORBA_Environment *ev) { if (servant->captive_vfs_object) { g_object_unref(servant->captive_vfs_object); servant->captive_vfs_object=NULL; } } static Captive_CaptiveIOChannel options_corba_image_iochannel_copy; void impl_Captive_Vfs__destroy(impl_POA_Captive_Vfs *servant,CORBA_Environment *ev) { PortableServer_ObjectId *objid; objid=PortableServer_POA_servant_to_id(servant->poa,servant,ev); PortableServer_POA_deactivate_object(servant->poa,objid,ev); CORBA_free(objid); impl_Captive_Vfs_fini(servant,ev); CORBA_Object_release(options_corba_image_iochannel_copy,ev); g_free(servant); } static void options_module_corba_to_options_module_captive (struct captive_options_module *dest_options_module_captive,const Captive_CaptiveOptionsModule *src_options_module_corba) { g_return_if_fail(dest_options_module_captive!=NULL); g_return_if_fail(src_options_module_corba!=NULL); dest_options_module_captive->pathname_utf8=g_strdup(src_options_module_corba->pathname_utf8); dest_options_module_captive->type=CAPTIVE_OPTIONS_MODULE_TYPE_PE32; dest_options_module_captive->u.pe32.base=g_memdup(src_options_module_corba->data._buffer, src_options_module_corba->data._length); dest_options_module_captive->u.pe32.length=src_options_module_corba->data._length; dest_options_module_captive->u.pe32.mapped=FALSE; } static void impl_Captive_Vfs_init (impl_POA_Captive_Vfs *servant,const Captive_CaptiveOptions *options_corba,CORBA_Environment *ev) { struct captive_options options_captive; GnomeVFSResult errvfsresult; guint moduleui; g_return_if_fail(servant->captive_vfs_object==NULL); options_corba_image_iochannel_copy=CORBA_Object_duplicate(options_corba->image_iochannel,ev); if (ev->_major!=CORBA_NO_EXCEPTION) return; /* impl_Captive_Vfs_init_g_log_func() does its own copy of 'options_corba->g_log_func'. */ impl_Captive_Vfs_init_g_log_func(options_corba->g_log_func,options_corba->debug_messages,ev); captive_options_init(&options_captive); options_module_corba_to_options_module_captive(&options_captive.filesystem,&options_corba->filesystem); options_captive.debug_messages=options_corba->debug_messages; options_captive.rwmode =options_corba->rwmode; options_captive.media =options_corba->media; options_captive.image_iochannel=(GIOChannel *)captive_io_channel_new( options_corba_image_iochannel_copy, /* corba_captive_io_channel */ (options_captive.rwmode!=CAPTIVE_OPTION_RWMODE_RO)); /* writeable */ for (moduleui=0;moduleuiload_module._length;moduleui++) { struct captive_options_module *options_module; captive_new(options_module); options_module_corba_to_options_module_captive(options_module,options_corba->load_module._buffer+moduleui); options_captive.load_module=g_list_append(options_captive.load_module,options_module); } options_captive.sandbox=TRUE; g_assert(options_captive.sandbox_server_argv==NULL); g_assert(options_captive.sandbox_server_ior==NULL); if (GNOME_VFS_OK!=(errvfsresult=captive_vfs_new(&servant->captive_vfs_object,&options_captive))) { CORBA_exception_set(ev,CORBA_USER_EXCEPTION,ex_Captive_GnomeVFSResultException,GINT_TO_POINTER((gint)errvfsresult)); captive_options_free(&options_captive); return; } captive_options_free(&options_captive); g_assert(CAPTIVE_VFS_SLAVE_IS_OBJECT(servant->captive_vfs_object)); } #if 0 /* Currently unused - see impl_Captive_Vfs_shutdown() */ static gboolean impl_Captive_Vfs_shutdown_idle(gpointer data /* unused */) { sandbox_child_shutdown(); return FALSE; /* remove me */ } #endif static void impl_Captive_Vfs_shutdown(impl_POA_Captive_Vfs *servant,CORBA_Environment *ev) { #if 0 /* Currently unused - see impl_Captive_Vfs_shutdown() */ GSource *source; #endif /* Shutdown 'servant->captive_vfs_object' synchronously as it may * flush its buffers needed to be transferred to our parent. */ impl_Captive_Vfs_fini(servant,&captive_corba_ev); g_assert(validate_CORBA_Environment(&captive_corba_ev)); /* Currently we do not do any sandbox child shutdown here as it sometimes * crashes the parent with COMM_FAILURE without proper finish of this * shutdown() CORBA method call. Parent will kill(2) us soon * from its parent-Vfs.c:captive_sandbox_parent_vfs_close() anyway. */ #if 0 sandbox_child_prepare_shutdown(); /* Do not call sandbox_child_shutdown() directly as we would fail * to finish this CORBA method call properly. * Do not call g_idle_add_full() as it would miss linc main loop. */ source=g_idle_source_new (); g_source_set_priority(source,G_PRIORITY_LOW); g_source_set_callback( source, /* source */ (GSourceFunc)impl_Captive_Vfs_shutdown_idle, /* func */ servant, /* data */ NULL); /* notify */ g_source_attach(source, captive_corba_get_context()); /* context; NULL means 'default context' */ g_source_unref(source); #endif } static void impl_Captive_Vfs_volume_info_get (impl_POA_Captive_Vfs *servant,Captive_CaptiveVfsVolumeInfo *volume_info_corba,CORBA_Environment *ev) { CaptiveVfsVolumeInfo volume_info_captive; GnomeVFSResult errvfsresult; if (GNOME_VFS_OK!=(errvfsresult=captive_vfs_volume_info_get(servant->captive_vfs_object,&volume_info_captive))) { captive_sandbox_child_GnomeVFSResultException_throw(ev,errvfsresult); return; } volume_info_corba->block_size =volume_info_captive.block_size; volume_info_corba->bytes =volume_info_captive.bytes; volume_info_corba->bytes_free =volume_info_captive.bytes_free; volume_info_corba->bytes_available=volume_info_captive.bytes_available; }