Postpone captive_fs_new() to the process of lufsd(8)
[captive.git] / src / client / lufs / captivefs-vfs.c
index ae4b31d..dc769fa 100644 (file)
 
 #include "config.h"
 
+#include "captivefs-vfs.h"     /* self */
 #include <glib/gmessages.h>
 #include "captivefs-misc.h"
+#include <unistd.h>
 
 #include <captive/client-vfs.h>
 #include <captive/options.h>
 #include <lufs/fs.h>
 
 
+gboolean captivefs_vfs_validate(struct captivefs_vfs *captivefs_vfs)
+{
+       g_return_val_if_fail(captivefs_vfs!=NULL,FALSE);
+
+       if (!captivefs_vfs->captive_vfs_object) {
+GnomeVFSResult errvfsresult;
+
+               if (captivefs_vfs->parent_pid==getpid())
+                       return FALSE;
+
+               G_LOCK(libcaptive);
+               errvfsresult=captive_vfs_new(&captivefs_vfs->captive_vfs_object,&captivefs_vfs->options);
+               G_UNLOCK(libcaptive);
+
+               g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,FALSE);
+               }
+       g_return_val_if_fail(CAPTIVE_VFS_IS_OBJECT(captivefs_vfs->captive_vfs_object),FALSE);
+
+       return TRUE;
+}
+
+
 /* Initialization
  * Here we allocate a structure to hold all the file system local info 
  * (localfs_local). This structure will then be passed as a parameter to 
  * ! Most filesystems don't need a global context so you can safely ignore the
  *   global_ctx parameter.  
  */
-CaptiveVfsObject *captivefs_init
+struct captivefs_vfs *captivefs_init
                (struct list_head *cfg,struct dir_cache *cache,const struct credentials *cred,void **global_ctx)
 {
-CaptiveVfsObject *captive_vfs_object;
-struct captive_options options;
-GnomeVFSResult errvfsresult;
+struct captivefs_vfs *captivefs_vfs;
 const struct poptOption *cpopt;
 GPtrArray *arg_array;
 const gchar *cgs;
@@ -83,8 +105,12 @@ const gchar *dashdashname,*value;
        /* Initialize GObject subsystem of GLib. */
        g_type_init();
 
-       captive_options_init(&options);
-       captive_options=&options;       /* for parsing by 'CAPTIVE_POPT_INCLUDE' */
+       captive_new(captivefs_vfs);
+       captivefs_vfs->captive_vfs_object=NULL;
+       captivefs_vfs->parent_pid=getpid();
+
+       captive_options_init(&captivefs_vfs->options);
+       captive_options=&captivefs_vfs->options;        /* for parsing by 'CAPTIVE_POPT_INCLUDE' */
 
        context=poptGetContext(
                        PACKAGE,        /* name */
@@ -92,6 +118,8 @@ const gchar *dashdashname,*value;
                        (const char **)arg_array->pdata,        /* argv */
                        captive_popt,   /* options */
                        POPT_CONTEXT_POSIXMEHARDER);    /* flags; && !POPT_CONTEXT_KEEP_FIRST */
+       g_ptr_array_free(arg_array,
+                       FALSE); /* free_seg */
        if (context==NULL) {
                g_warning("%s: argument recognization args_error","captivefs_init");
                goto fail_free_options;
@@ -115,45 +143,25 @@ const gchar *dashdashname,*value;
 
        captive_options=NULL;   /* already parsed by 'CAPTIVE_POPT_INCLUDE' */
 
-       if (options.debug_messages)
+       if (captivefs_vfs->options.debug_messages)
                g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_init");
 
        /* image_iochannel */
        if ((cgs=lu_opt_getchar(cfg,"MOUNT","image"))) {
-               g_assert(options.image_iochannel==NULL);
-               if (!(options.image_iochannel=g_io_channel_new_file(
+               g_assert(captivefs_vfs->options.image_iochannel==NULL);
+               if (!(captivefs_vfs->options.image_iochannel=g_io_channel_new_file(
                                cgs,    /* filename */
-                               (options.rwmode==CAPTIVE_OPTION_RWMODE_RW ? "r+" : "r"),        /* mode */
+                               (captivefs_vfs->options.rwmode==CAPTIVE_OPTION_RWMODE_RW ? "r+" : "r"), /* mode */
                                NULL))) {       /* error */
                        g_warning(_("%s: image_iochannel open failed"),"captivefs_init");
                        goto fail_free_options;
                        }
                }
 
-       G_LOCK(libcaptive);
-       errvfsresult=captive_vfs_new(&captive_vfs_object,&options);
-       G_UNLOCK(libcaptive);
-
-       if (errvfsresult!=GNOME_VFS_OK)
-               goto fail_unref_image_iochannel;
+       return captivefs_vfs;
 
-       if (options.debug_messages)
-               g_object_set_data(G_OBJECT(captive_vfs_object),"captivefs-debug_messages",captive_vfs_object /* boolean true */);
-
-       g_object_set_data(G_OBJECT(captive_vfs_object),"captivefs-vfs-image_iochannel",options.image_iochannel);
-       captive_options_free(&options);
-       g_ptr_array_free(arg_array,
-                       FALSE); /* free_seg */
-
-       return captive_vfs_object;
-
-fail_unref_image_iochannel:
-       g_io_channel_unref(options.image_iochannel);
 fail_free_options:
-       captive_options_free(&options);
-/* fail_free_arg_array: */
-       g_ptr_array_free(arg_array,
-                       FALSE); /* free_seg */
+       captive_options_free(&captivefs_vfs->options);
 /* fail: */
        return NULL;
 }
@@ -163,25 +171,22 @@ fail_free_options:
  * Check the global context count and free it if necessary.
  * Deallocate memory and free all resources.
  */
-void captivefs_free(CaptiveVfsObject *captive_vfs_object)
+void captivefs_free(struct captivefs_vfs *captivefs_vfs)
 {
-GIOChannel *image_iochannel;
-
-       g_return_if_fail(CAPTIVE_VFS_IS_OBJECT(captive_vfs_object));
+       g_return_if_fail(captivefs_vfs_validate(captivefs_vfs));
 
-       if (VFS_DEBUG_MESSAGES(captive_vfs_object))
+       if (captivefs_vfs->options.debug_messages)
                g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_free");
 
-       image_iochannel=g_object_get_data(G_OBJECT(captive_vfs_object),"captivefs-vfs-image_iochannel");
-       g_assert(image_iochannel!=NULL);
-       g_object_set_data(G_OBJECT(captive_vfs_object),"captivefs-vfs-image_iochannel",NULL);   /* just a sanity */
-       /* Keep 'image_iochannel' reffed until 'g_object_unref(captive_vfs_object)'. */
+       g_assert(G_OBJECT(captivefs_vfs->captive_vfs_object)->ref_count==1);
 
        G_LOCK(libcaptive);
-       g_object_unref(captive_vfs_object);
+       g_object_unref(captivefs_vfs->captive_vfs_object);
        G_UNLOCK(libcaptive);
 
-       g_io_channel_unref(image_iochannel);
+       g_io_channel_unref(captivefs_vfs->options.image_iochannel);
+       captive_options_free(&captivefs_vfs->options);
+       g_free(captivefs_vfs);
 }
 
 
@@ -197,11 +202,13 @@ GIOChannel *image_iochannel;
  * from a configuration file if you want to, for example, be able to set
  * default values.
  */
-int captivefs_mount(CaptiveVfsObject *captive_vfs_object)
+int captivefs_mount(struct captivefs_vfs *captivefs_vfs)
 {
-       g_return_val_if_fail(CAPTIVE_VFS_IS_OBJECT(captive_vfs_object),0);
-    
-       if (VFS_DEBUG_MESSAGES(captive_vfs_object))
+       /* We may be called from the parent. */
+       g_return_val_if_fail(captivefs_vfs!=NULL,FALSE);
+       captivefs_vfs_validate(captivefs_vfs);  /* It may return FALSE. */
+
+       if (captivefs_vfs->options.debug_messages)
                g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_mount");
 
        return 1;       /* NEVER return 0 */
@@ -211,10 +218,10 @@ int captivefs_mount(CaptiveVfsObject *captive_vfs_object)
 /* Unmount the  file system
  * Called when the file system is unmounted.
  */
-void captivefs_umount(CaptiveVfsObject *captive_vfs_object)
+void captivefs_umount(struct captivefs_vfs *captivefs_vfs)
 {
-       g_return_if_fail(CAPTIVE_VFS_IS_OBJECT(captive_vfs_object));
+       g_return_if_fail(captivefs_vfs_validate(captivefs_vfs));
 
-       if (VFS_DEBUG_MESSAGES(captive_vfs_object))
+       if (captivefs_vfs->options.debug_messages)
                g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_umount");
 }