Implemented CaptiveParentConnector sandbox restarts handling GInterface.
[captive.git] / src / libcaptive / client / directory-parent.c
index 6a473cf..be8970e 100644 (file)
@@ -23,6 +23,7 @@
 #include <glib/gmessages.h>
 #include "../sandbox/parent-Directory.h"
 #include "vfs-parent.h"
+#include "parent-connector.h"
 
 
 static gpointer captive_directory_parent_object_parent_class=NULL;
@@ -57,8 +58,31 @@ CaptiveDirectoryObjectClass *captive_directory_object_class=CAPTIVE_DIRECTORY_OB
 }
 
 
+static GnomeVFSResult (*captive_directory_parent_object_captive_parent_connector_open_orig)
+               (CaptiveParentConnector *captive_parent_connector);
+static GnomeVFSResult captive_directory_parent_object_captive_parent_connector_open
+               (CaptiveParentConnector *captive_parent_connector);
+
+static GnomeVFSResult captive_directory_parent_object_captive_parent_connector_close
+               (CaptiveParentConnector *captive_parent_connector);
+static GnomeVFSResult (*captive_directory_parent_object_captive_parent_connector_close_orig)
+               (CaptiveParentConnector *captive_parent_connector);
+
+static void captive_directory_parent_object_captive_parent_connector_init(CaptiveParentConnectorIface *captive_parent_connector_iface)
+{
+       g_return_if_fail(CAPTIVE_IS_PARENT_CONNECTOR_CLASS(captive_parent_connector_iface));
+
+       captive_directory_parent_object_captive_parent_connector_open_orig=captive_parent_connector_iface->open;
+       captive_parent_connector_iface->open=captive_directory_parent_object_captive_parent_connector_open;
+
+       captive_directory_parent_object_captive_parent_connector_close_orig=captive_parent_connector_iface->close;
+       captive_parent_connector_iface->close=captive_directory_parent_object_captive_parent_connector_close;
+}
+
+
 static void captive_directory_parent_object_init(CaptiveDirectoryParentObject *captive_directory_parent_object)
 {
+       g_return_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_parent_object));
 }
 
 
@@ -78,19 +102,44 @@ static const GTypeInfo captive_directory_parent_object_info={
                                5,      /* n_preallocs */
                                (GInstanceInitFunc)captive_directory_parent_object_init,
                                };
+static const GInterfaceInfo captive_parent_connector_info={
+                               (GInterfaceInitFunc)captive_directory_parent_object_captive_parent_connector_init,      /* interface_init */
+                               NULL,   /* interface_finalize */
+                               NULL,   /* interface_data */
+                               };
 
                captive_directory_parent_object_type=g_type_register_static(CAPTIVE_DIRECTORY_TYPE_OBJECT,
                                "CaptiveDirectoryParentObject",&captive_directory_parent_object_info,0);
+               g_type_add_interface_static(captive_directory_parent_object_type,
+                               CAPTIVE_TYPE_PARENT_CONNECTOR,&captive_parent_connector_info);
                }
 
        return captive_directory_parent_object_type;
 }
 
 
+static void captive_directory_parent_init
+               (CaptiveDirectoryParentObject *captive_directory_parent_object,CaptiveVfsObject *captive_vfs_object)
+{
+       g_return_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_parent_object));
+       g_return_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_object));
+
+       /* Order of captive_directory_init() and captive_parent_connector_init()
+        * should not matter as 'vfs' is passed by value to captive_parent_connector_init().
+        */
+       captive_directory_init(CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object),captive_vfs_object);
+
+       captive_parent_connector_init(
+                       CAPTIVE_PARENT_CONNECTOR(captive_directory_parent_object),      /* captive_parent_connector */
+                       &captive_directory_parent_object->corba_Directory_object,       /* corba_objectp */
+                       CAPTIVE_VFS_PARENT_OBJECT(CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object)->vfs));     /* captive_vfs_parent_object */
+}
+
 GnomeVFSResult captive_directory_parent_new_open(CaptiveDirectoryObject **captive_directory_object_return,
                CaptiveVfsObject *captive_vfs_object,const gchar *pathname)
 {
 CaptiveDirectoryParentObject *captive_directory_parent_object;
+GnomeVFSResult r;
 
        g_return_val_if_fail(captive_directory_object_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
@@ -99,12 +148,22 @@ CaptiveDirectoryParentObject *captive_directory_parent_object;
        captive_directory_parent_object=g_object_new(
                        CAPTIVE_DIRECTORY_PARENT_TYPE_OBJECT,   /* object_type */
                        NULL);  /* first_property_name; FIXME: support properties */
+       captive_directory_parent_object->pathname=g_strdup(pathname);
 
-       captive_directory_init(CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object),captive_vfs_object);
+       captive_directory_parent_init(captive_directory_parent_object,captive_vfs_object);
 
-       *captive_directory_object_return=CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object);
+       if (GNOME_VFS_OK!=(r=captive_parent_connector_connect(CAPTIVE_PARENT_CONNECTOR(captive_directory_parent_object))))
+               return r;
+
+       if (GNOME_VFS_OK!=(r=captive_sandbox_parent_directory_new_open(captive_directory_parent_object))) {
+               g_object_unref(captive_directory_parent_object);
+               *captive_directory_object_return=NULL;
+               return r;
+               }
 
-       return captive_sandbox_parent_directory_new_open(captive_directory_parent_object,pathname);
+       *captive_directory_object_return=CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object);
+       return (*captive_directory_parent_object_captive_parent_connector_open_orig)
+                       (CAPTIVE_PARENT_CONNECTOR(captive_directory_parent_object));
 }
 
 
@@ -112,6 +171,7 @@ GnomeVFSResult captive_directory_parent_new_make(CaptiveDirectoryObject **captiv
                CaptiveVfsObject *captive_vfs_object,const gchar *pathname,guint perm)
 {
 CaptiveDirectoryParentObject *captive_directory_parent_object;
+GnomeVFSResult r;
 
        g_return_val_if_fail(captive_directory_object_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
@@ -120,24 +180,72 @@ CaptiveDirectoryParentObject *captive_directory_parent_object;
        captive_directory_parent_object=g_object_new(
                        CAPTIVE_DIRECTORY_PARENT_TYPE_OBJECT,   /* object_type */
                        NULL);  /* first_property_name; FIXME: support properties */
+       captive_directory_parent_object->pathname=g_strdup(pathname);
 
-       captive_directory_init(CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object),captive_vfs_object);
+       captive_directory_parent_init(captive_directory_parent_object,captive_vfs_object);
 
-       *captive_directory_object_return=CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object);
+       if (GNOME_VFS_OK!=(r=captive_parent_connector_connect(CAPTIVE_PARENT_CONNECTOR(captive_directory_parent_object))))
+               return r;
+
+       if (GNOME_VFS_OK!=(r=captive_sandbox_parent_directory_new_make(captive_directory_parent_object,perm))) {
+               g_object_unref(captive_directory_parent_object);
+               *captive_directory_object_return=NULL;
+               return r;
+               }
 
-       return captive_sandbox_parent_directory_new_make(captive_directory_parent_object,pathname,perm);
+       *captive_directory_object_return=CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object);
+       return (*captive_directory_parent_object_captive_parent_connector_open_orig)
+                       (CAPTIVE_PARENT_CONNECTOR(captive_directory_parent_object));
 }
 
 
 static GnomeVFSResult captive_directory_parent_close(CaptiveDirectoryObject *captive_directory_object)
 {
 CaptiveDirectoryParentObject *captive_directory_parent_object;
+GnomeVFSResult r;
 
        g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
 
        captive_directory_parent_object=CAPTIVE_DIRECTORY_PARENT_OBJECT(captive_directory_object);
 
-       return captive_sandbox_parent_directory_close(captive_directory_parent_object);
+       r=captive_parent_connector_close(CAPTIVE_PARENT_CONNECTOR(captive_directory_parent_object));
+
+       captive_parent_connector_finalize(CAPTIVE_PARENT_CONNECTOR(captive_directory_parent_object));
+
+       g_free(captive_directory_parent_object->pathname);
+       captive_directory_parent_object->pathname=NULL;
+
+       return r;
+}
+
+
+static GnomeVFSResult captive_directory_parent_object_captive_parent_connector_open
+               (CaptiveParentConnector *captive_parent_connector)
+{
+GnomeVFSResult r;
+
+       g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),GNOME_VFS_ERROR_BAD_PARAMETERS);
+       g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_parent_connector),GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+       if (GNOME_VFS_OK!=(r=captive_sandbox_parent_directory_new_open(CAPTIVE_DIRECTORY_PARENT_OBJECT(captive_parent_connector))))
+               return r;
+
+       return (*captive_directory_parent_object_captive_parent_connector_open_orig)(captive_parent_connector);
+}
+
+
+static GnomeVFSResult captive_directory_parent_object_captive_parent_connector_close
+               (CaptiveParentConnector *captive_parent_connector)
+{
+GnomeVFSResult r;
+
+       g_return_val_if_fail(CAPTIVE_IS_PARENT_CONNECTOR(captive_parent_connector),GNOME_VFS_ERROR_BAD_PARAMETERS);
+       g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_parent_connector),GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+       if (GNOME_VFS_OK!=(r=captive_sandbox_parent_directory_close(CAPTIVE_DIRECTORY_PARENT_OBJECT(captive_parent_connector))))
+               return r;
+
+       return (*captive_directory_parent_object_captive_parent_connector_close_orig)(captive_parent_connector);
 }
 
 
@@ -145,23 +253,43 @@ static GnomeVFSResult captive_directory_parent_read
                (CaptiveDirectoryObject *captive_directory_object,GnomeVFSFileInfo *file_info)
 {
 CaptiveDirectoryParentObject *captive_directory_parent_object;
+GnomeVFSResult r;
+gint retried=0;
 
        g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(file_info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
        captive_directory_parent_object=CAPTIVE_DIRECTORY_PARENT_OBJECT(captive_directory_object);
 
-       return captive_sandbox_parent_directory_read(captive_directory_parent_object,file_info);
+       do {
+               if (GNOME_VFS_OK!=(r=captive_parent_connector_open(CAPTIVE_PARENT_CONNECTOR(captive_directory_parent_object))))
+                       return r;
+               if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE
+                               !=(r=captive_sandbox_parent_directory_read(captive_directory_parent_object,file_info)))
+                       return r;
+               } while (!retried++);
+       return r;
 }
 
 
 static GnomeVFSResult captive_directory_parent_remove(CaptiveDirectoryObject *captive_directory_object)
 {
 CaptiveDirectoryParentObject *captive_directory_parent_object;
+GnomeVFSResult r;
+gint retried=0;
 
        g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
 
        captive_directory_parent_object=CAPTIVE_DIRECTORY_PARENT_OBJECT(captive_directory_object);
 
-       return captive_sandbox_parent_directory_remove(captive_directory_parent_object);
+       do {
+               if (GNOME_VFS_OK!=(r=captive_parent_connector_open(CAPTIVE_PARENT_CONNECTOR(captive_directory_parent_object))))
+                       return r;
+               if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE!=(r=captive_sandbox_parent_directory_remove(captive_directory_parent_object))) {
+                       if (GNOME_VFS_OK==r)
+                               captive_parent_connector_set_dirty(CAPTIVE_PARENT_CONNECTOR(captive_directory_parent_object));
+                       return r;
+                       }
+               } while (!retried++);
+       return r;
 }