Initial original import from: fuse-2.4.2-2.fc4
[captive.git] / src / libcaptive / sandbox / server-Vfs.c
index 621a5a3..28affd3 100644 (file)
 #include "config.h"
 
 #include "server-Vfs.h"        /* self */
-#include "server-GlibLogFunc.h"        /* for impl_Captive_Vfs_registerGlibLogFunc() */
 #include "sandbox.h"
 #include <glib/gmessages.h>
 #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 */
-       NULL,   /* finalize routine */
+       (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_registerGlibLogFunc,
+       (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,
@@ -51,24 +59,16 @@ static POA_Captive_Vfs__vepv impl_Captive_Vfs_vepv={
        };
 
 
-struct captive_options *captive_corba_child_options;
-
-
 Captive_Vfs impl_Captive_Vfs__create(PortableServer_POA poa,CORBA_Environment *ev)
 {
 Captive_Vfs retval;
 impl_POA_Captive_Vfs *newservant;
 PortableServer_ObjectId *objid;
-GnomeVFSResult errvfsresult;
 
        captive_new0(newservant);       /* FIXME: leak */
        newservant->servant.vepv=&impl_Captive_Vfs_vepv;
        newservant->poa=poa;
-       if (GNOME_VFS_OK!=(errvfsresult=captive_vfs_new(&newservant->captive_vfs_object,captive_corba_child_options))) {
-               g_free(newservant);
-               CORBA_exception_set(ev,CORBA_USER_EXCEPTION,ex_Captive_GnomeVFSResultException,GINT_TO_POINTER((gint)errvfsresult));
-               return NULL;
-               }
+       newservant->captive_vfs_object=NULL;
        POA_Captive_Vfs__init((PortableServer_Servant)newservant,ev);
        objid=PortableServer_POA_activate_object(poa,newservant,ev);
        CORBA_free(objid);
@@ -78,21 +78,159 @@ GnomeVFSResult errvfsresult;
 }
 
 
+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;
+       /* 'md5' is never used in sandbox client; XML is dumped by the master. */
+       dest_options_module_captive->u.pe32.md5=g_strdup("<sandbox-client:undef>");
+}
+
+
+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;moduleui<options_corba->load_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.
         */
-       g_idle_add_full(
-                       G_PRIORITY_LOW, /* priority */
-                       impl_Captive_Vfs_shutdown_idle, /* function */
-                       NULL,   /* data */
+  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;
 }