+Generates --bug-pathname resources file for sandbox crash bugreport
authorshort <>
Fri, 4 Jul 2003 15:06:35 +0000 (15:06 +0000)
committershort <>
Fri, 4 Jul 2003 15:06:35 +0000 (15:06 +0000)
18 files changed:
NEWS
configure.in
src/libcaptive/client/Makefile.am
src/libcaptive/client/giochannel-blind.c
src/libcaptive/client/giochannel-blind.h
src/libcaptive/client/options-module.c
src/libcaptive/client/options.c
src/libcaptive/client/vfs.h
src/libcaptive/include/captive/options-module.h
src/libcaptive/include/captive/options.h
src/libcaptive/sandbox/Makefile.am
src/libcaptive/sandbox/parent-Directory.c
src/libcaptive/sandbox/parent-File.c
src/libcaptive/sandbox/parent-Vfs.c
src/libcaptive/sandbox/server-GLogFunc.c
src/libcaptive/sandbox/server-GLogFunc.h
src/libcaptive/sandbox/split.c
src/libcaptive/storage/Makefile.am

diff --git a/NEWS b/NEWS
index c6ded82..f8afc21 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,7 @@ NEWS for captive-0.9
 * Multifilesystem capability by new CaptiveVfsObject
 * Finished and deployed CORBA sandbox separation
 * Implemented filesystem unmount to successfuly remount ntfs volume
+* Generates --bug-pathname resources file for sandbox crash bugreport
 
 
 NEWS for captive-0.8 (2003-05-02)
index ba4cfbc..d6dc64f 100644 (file)
@@ -192,6 +192,14 @@ PKG_CHECK_MODULES(GNOME_VFS_MODULE,gnome-vfs-module-2.0)
 AC_SUBST(GNOME_VFS_MODULE_CFLAGS)
 AC_SUBST(GNOME_VFS_MODULE_LIBS)
 
+PKG_CHECK_MODULES(LIBXML,libxml-2.0)
+AC_SUBST(LIBXML_CFLAGS)
+AC_SUBST(LIBXML_LIBS)
+
+PKG_CHECK_MODULES(OPENSSL,openssl)
+AC_SUBST(OPENSSL_CFLAGS)
+AC_SUBST(OPENSSL_LIBS)
+
 dnl for $(top_srcdir)/src/libcaptive/sandbox/split-sandbox.c
 AM_PATH_LINC(,,[AC_MSG_ERROR([Captive requires linc library used by ORBit.])])
 
index 1471a51..026ca07 100644 (file)
@@ -40,6 +40,6 @@ libclient_la_SOURCES= \
                vfs.c \
                vfs.h
 libclient_la_CFLAGS= \
-               $(GNOME_VFS_MODULE_CFLAGS)
+               $(GNOME_VFS_MODULE_CFLAGS) $(OPENSSL_CFLAGS) $(LIBXML_CFLAGS)
 libclient_la_LIBADD= \
-               $(GNOME_VFS_MODULE_LIBS)
+               $(GNOME_VFS_MODULE_LIBS)   $(OPENSSL_LIBS)   $(LIBXML_LIBS)
index ff2518b..da09cb8 100644 (file)
@@ -25,6 +25,9 @@
 #include <glib/gmessages.h>
 #include "captive/macros.h"
 #include "captive/storage.h"
+#include <openssl/bn.h>
+#include <openssl/crypto.h>
+#include <libxml/tree.h>
 
 
 /* CONFIG: */
@@ -452,7 +455,10 @@ struct captive_giochannel_blind *giochannel_blind;
 }
 
 
-static void captive_giochannel_blind_as_sorted_array_foreach
+typedef void (*sorted_array_filter)
+               (const guint64 *keyp,const struct blind_block *blind_block,const struct blind_block ***rpp /* user_data */);
+
+static void captive_giochannel_blind_written_as_sorted_array_foreach
                (const guint64 *keyp,const struct blind_block *blind_block,const struct blind_block ***rpp /* user_data */)
 {
        g_return_if_fail(keyp!=NULL);
@@ -465,6 +471,19 @@ static void captive_giochannel_blind_as_sorted_array_foreach
        *((*rpp)++)=blind_block;
 }
 
+static void captive_giochannel_blind_read_as_sorted_array_foreach
+               (const guint64 *keyp,const struct blind_block *blind_block,const struct blind_block ***rpp /* user_data */)
+{
+       g_return_if_fail(keyp!=NULL);
+       g_return_if_fail(blind_block!=NULL);
+       g_return_if_fail(rpp!=NULL);
+
+       if (!blind_block->was_read)
+               return;
+
+       *((*rpp)++)=blind_block;
+}
+
 static int captive_giochannel_blind_as_sorted_array_compat
                (const struct blind_block *const *ap,const struct blind_block *const *bp)
 {
@@ -476,7 +495,8 @@ static int captive_giochannel_blind_as_sorted_array_compat
        return ((*ap)->offset>(*bp)->offset) - ((*bp)->offset>(*ap)->offset);
 }
 
-static struct blind_block **captive_giochannel_blind_as_sorted_array(struct captive_giochannel_blind *giochannel_blind)
+static struct blind_block **captive_giochannel_blind_as_sorted_array
+               (struct captive_giochannel_blind *giochannel_blind,sorted_array_filter filter_func)
 {
 guint hash_size;
 struct blind_block **r,**rp;
@@ -486,7 +506,7 @@ struct blind_block **r,**rp;
        hash_size=g_hash_table_size(giochannel_blind->buffer_hash);
        captive_newn(r,hash_size+1);
        rp=r;
-       g_hash_table_foreach(giochannel_blind->buffer_hash,(GHFunc)captive_giochannel_blind_as_sorted_array_foreach,&rp);
+       g_hash_table_foreach(giochannel_blind->buffer_hash,(GHFunc)filter_func,&rp);
        g_assert(rp<=r+hash_size);
        *rp=NULL;
        qsort(r,rp-r,sizeof(*r),(int (*)(const void *,const void *))captive_giochannel_blind_as_sorted_array_compat);
@@ -507,7 +527,8 @@ GIOStatus errgiostatus;
                        NULL);  /* error */
        g_assert(errgiostatus==G_IO_STATUS_NORMAL);
 
-       blind_block_array=captive_giochannel_blind_as_sorted_array(giochannel_blind);
+       blind_block_array=captive_giochannel_blind_as_sorted_array
+                       (giochannel_blind,captive_giochannel_blind_written_as_sorted_array_foreach);
 
        for (blind_blockp=blind_block_array;*blind_blockp;blind_blockp++) {
 struct blind_block *blind_block=*blind_blockp;
@@ -543,3 +564,80 @@ gsize bytes_written;
 
        return G_IO_STATUS_NORMAL;
 }
+
+
+xmlNode *captive_giochannel_blind_readreport_to_xml(xmlNode *xml_parent,GIOChannel *giochannel)
+{
+struct captive_giochannel_blind *giochannel_blind=(struct captive_giochannel_blind *)giochannel;
+struct blind_block **blind_block_array,**blind_blockp;
+GIOStatus errgiostatus;
+guint8 data_read[1+GIOCHANNEL_BLIND_BLOCK_SIZE];       /* '1+' for leading stub to prevent shorter output of BN_bn2hex() */
+xmlNode *xml_media;
+
+       g_return_val_if_fail(validate_giochannel_blind(giochannel_blind),NULL);
+
+       errgiostatus=g_io_channel_flush(
+                       giochannel,     /* channel */
+                       NULL);  /* error */
+       g_assert(errgiostatus==G_IO_STATUS_NORMAL);
+
+       xml_media=xmlNewTextChild(xml_parent,NULL,"media",NULL);
+       xmlNewProp(xml_media,"size",captive_printf_alloca("%" G_GUINT64_FORMAT,giochannel_blind->size));
+
+       blind_block_array=captive_giochannel_blind_as_sorted_array
+                       (giochannel_blind,captive_giochannel_blind_read_as_sorted_array_foreach);
+
+       for (blind_blockp=blind_block_array;*blind_blockp;blind_blockp++) {
+struct blind_block *blind_block=*blind_blockp;
+gsize bytes_read;
+xmlNode *xml_media_read;
+gchar offset_string[64];
+BIGNUM *bignum;
+char *hex,*s;
+gchar hex_out[0
+               +1 /* leading '\n' */
+               +GIOCHANNEL_BLIND_BLOCK_SIZE*2/64*(64+1)        /* each line of 64 characters has EOL '\n' */
+               +1],*gd;        /* terminating '\0' */
+
+               errgiostatus=g_io_channel_seek_position(
+                               giochannel_blind->giochannel_orig,      /* channel */
+                               blind_block->offset,    /* offset */
+                               G_SEEK_SET,     /* type */
+                               NULL);  /* error */
+               g_return_val_if_fail(errgiostatus==G_IO_STATUS_NORMAL,NULL);
+               errgiostatus=g_io_channel_read_chars(
+                               giochannel_blind->giochannel_orig,      /* channel */
+                               data_read+1,    /* buf */
+                               GIOCHANNEL_BLIND_BLOCK_SIZE,    /* count */
+                               &bytes_read,    /* bytes_read */
+                               NULL);  /* error */
+               g_return_val_if_fail(errgiostatus==G_IO_STATUS_NORMAL,NULL);
+               g_return_val_if_fail(bytes_read==GIOCHANNEL_BLIND_BLOCK_SIZE,NULL);
+
+               /* Convert binary block to 'hex' and reformat line-wrap it to 'hex_out'. */
+               data_read[0]=0xFF;      /* stub to prevent shorter output of BN_bn2hex() */
+               bignum=BN_bin2bn(data_read,1+GIOCHANNEL_BLIND_BLOCK_SIZE,NULL);
+               hex=BN_bn2hex(bignum);
+               BN_free(bignum);
+               g_assert(strlen(hex)==2*(1+GIOCHANNEL_BLIND_BLOCK_SIZE));
+               gd=hex_out;
+               *gd++='\n';
+               for (s=hex+2;s<hex+2+2*GIOCHANNEL_BLIND_BLOCK_SIZE;s+=64,gd+=64+1) {
+                       memcpy(gd,s,64);
+                       gd[64]='\n';
+                       }
+               OPENSSL_free(hex);
+               *gd++=0;
+               g_assert(s==hex+2+2*GIOCHANNEL_BLIND_BLOCK_SIZE);
+               g_assert(gd==hex_out+sizeof(hex_out));
+               xml_media_read=xmlNewTextChild(xml_media,NULL,"block",hex_out);
+               {
+                       g_snprintf(offset_string,sizeof(offset_string),"%" G_GUINT64_FORMAT,blind_block->offset);
+                       xmlNewProp(xml_media_read,"offset",offset_string);
+                       }
+               }
+
+       g_free(blind_block_array);
+
+       return xml_media;
+}
index 6ce16f7..f6c5735 100644 (file)
@@ -22,6 +22,7 @@
 
 
 #include <glib/giochannel.h>
+#include <libxml/tree.h>
 
 
 G_BEGIN_DECLS
@@ -31,6 +32,7 @@ struct captive_giochannel_blind;
 struct captive_giochannel_blind *captive_giochannel_blind_new(GIOChannel *giochannel_ro,gboolean writeable);
 gboolean captive_giochannel_blind_get_size(GIOChannel *giochannel,guint64 *size_return);
 GIOStatus captive_giochannel_blind_commit(GIOChannel *giochannel_blind);
+xmlNode *captive_giochannel_blind_readreport_to_xml(xmlNode *xml_parent,GIOChannel *giochannel);
 
 G_END_DECLS
 
index daefd7e..4b4ba7d 100644 (file)
@@ -29,6 +29,9 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <sys/mman.h>
+#include <openssl/md5.h>
+#include <openssl/bn.h>
+#include <openssl/crypto.h>
 
 
 gboolean captive_options_module_load(struct captive_options_module *options_module,const gchar *pathname_utf8)
@@ -51,7 +54,20 @@ gboolean captive_options_module_load(struct captive_options_module *options_modu
 
        if (options_module->u.pe32.length>=2
                        && (('M'<<8U)|('Z'<<0U))==GUINT16_FROM_BE(*(const guint16 *)options_module->u.pe32.base)) {
+unsigned char md5_bin[1+128/8];        /* 128 bits==16 bytes; '1+' for leading stub to prevent shorter output of BN_bn2hex() */
+BIGNUM *bignum;
+char *hex;
+
                /* already done above */
+               /* Calculate MD5 sum and convert it to hex string: */
+               MD5(options_module->u.pe32.base,options_module->u.pe32.length,md5_bin+1);
+               md5_bin[0]=0xFF;        /* stub to prevent shorter output of BN_bn2hex() */
+               bignum=BN_bin2bn(md5_bin,1+128/8,NULL);
+               hex=BN_bn2hex(bignum);
+               g_assert(strlen(hex)==2*(1+128/8));
+               options_module->u.pe32.md5=g_strdup(hex+2);
+               OPENSSL_free(hex);
+               BN_free(bignum);
                }
        else {
                captive_rtl_file_munmap(options_module->u.pe32.base);
@@ -78,6 +94,7 @@ void captive_options_module_copy(struct captive_options_module *dest,const struc
                        dest->u.pe32.base=g_memdup(src->u.pe32.base,src->u.pe32.length);
                        dest->u.pe32.length=src->u.pe32.length;
                        dest->u.pe32.mapped=FALSE;
+                       dest->u.pe32.md5=g_strdup(src->u.pe32.md5);
                        break;
 
                case CAPTIVE_OPTIONS_MODULE_TYPE_GMODULE:
@@ -104,6 +121,7 @@ void captive_options_module_free(struct captive_options_module *options_module)
                                captive_rtl_file_munmap(options_module->u.pe32.base);
                        else
                                g_free(options_module->u.pe32.base);
+                       g_free(options_module->u.pe32.md5);
                        break;
 
                case CAPTIVE_OPTIONS_MODULE_TYPE_GMODULE:
index e124b8d..da06bb0 100644 (file)
@@ -82,6 +82,9 @@ char **sp;
 
        if (src->sandbox_server_ior)
                dest->sandbox_server_ior=g_strdup(src->sandbox_server_ior);
+
+       if (src->bug_pathname)
+               dest->bug_pathname=g_strdup(src->bug_pathname);
 }
 
 
@@ -100,6 +103,7 @@ void captive_options_free(struct captive_options *options)
 
        g_free(options->sandbox_server_argv);
        g_free(options->sandbox_server_ior);
+       g_free(options->bug_pathname);
 }
 
 
@@ -193,6 +197,12 @@ static void arg_no_sandbox(void)
        sandbox_args_clear();
 }
 
+static void arg_bug_pathname(void)
+{
+       g_free(captive_options->bug_pathname);
+       captive_options->bug_pathname=g_strdup(captive_popt_optarg);
+}
+
 
 static void captive_popt_callback
                (poptContext con,enum poptCallbackReason reason,const struct poptOption *opt,const char *arg,const void *data);
@@ -227,6 +237,7 @@ const struct poptOption captive_popt[]={
                CAPTIVE_POPT_STRING("sandbox-server"    ,N_("Pathname to 'captive-sandbox-server', turns on sandboxing"),N_("pathname")),
                CAPTIVE_POPT_STRING("sandbox-server-ior",N_("CORBA IOR of 'captive-sandbox-server', turns on sandboxing"),N_("IOR")),
                CAPTIVE_POPT_NONE(  "no-sandbox"        ,N_("Turn off sandboxing feature")),
+               CAPTIVE_POPT_STRING("bug-pathname"      ,N_("Pathname to strftime(3) for .captivebug.xml.gz bugreports"),N_("pathname")),
 
 #undef CAPTIVE_POPT_NONE
 #undef CAPTIVE_POPT_STRING
@@ -253,6 +264,7 @@ static void (*const popt_func_table[])(void)={
                arg_sandbox_server,
                arg_sandbox_server_ior,
                arg_no_sandbox,
+               arg_bug_pathname,
                };
 
 
index 0e1b2be..5a4a2e7 100644 (file)
@@ -25,6 +25,7 @@
 #include <glib/gtypes.h>
 #include <glib-object.h>
 #include "../sandbox/sandbox.h"
+#include <libxml/tree.h>
 
 
 G_BEGIN_DECLS
@@ -48,6 +49,8 @@ struct _CaptiveVfsObject {
                GIOChannel *corba_parent_giochanel_blind_source;
                int corba_parentheart_fds_1;
                pid_t corba_child_pid;
+               xmlDoc *corba_bug_doc;
+               xmlNode *corba_bug,*corba_bug_action,*corba_bug_log;
        };
 struct _CaptiveVfsObjectClass {
        GObjectClass parent_class;
index dcffdca..aee9eeb 100644 (file)
@@ -43,6 +43,7 @@ struct captive_options_module {
                        guint8 *base;
                        size_t length;
                        gboolean mapped;        /* otherwise g_malloc()ed */
+                       gchar *md5;
                        } pe32;
                struct {
                        gchar *pathname;
index e18578e..7651e57 100644 (file)
@@ -56,6 +56,7 @@ struct captive_options {
        gboolean sandbox;
        char **sandbox_server_argv;
        gchar *sandbox_server_ior;
+       gchar *bug_pathname;
        };
 
 /**
index 53a774a..b61da48 100644 (file)
@@ -48,7 +48,7 @@ libsandbox_la_SOURCES= \
                split.c \
                split.h
 
-libsandbox_la_CFLAGS=$(ORBIT_CFLAGS) $(LINC_CFLAGS) $(GNOME_VFS_MODULE_CFLAGS)
+libsandbox_la_CFLAGS=$(ORBIT_CFLAGS) $(LINC_CFLAGS) $(GNOME_VFS_MODULE_CFLAGS) $(LIBXML_CFLAGS)
 
 # $(LINC_LIBS) should be included by $(ORBIT_LIBS)
 # As we have no direct dependency on 'linc' it would be fatal if unexpectedly
index bbc6fff..fba5438 100644 (file)
 #include "../client/directory.h"
 #include "../client/vfs.h"
 #include "FileInfo.h"
+#include "captive/macros.h"
 
 
 GnomeVFSResult captive_sandbox_parent_directory_new_open
                (CaptiveDirectoryObject *captive_directory_object,const gchar *pathname)
 {
 gboolean retried=FALSE;
+xmlNode *xml_action;
 
        g_return_val_if_fail(captive_directory_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(pathname!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(captive_directory_object->dir_Handle==NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
 retry:
+       xml_action=NULL;
+       if (captive_directory_object->vfs->corba_bug_action) {
+               xml_action=xmlNewTextChild(captive_directory_object->vfs->corba_bug_action,NULL,"directory_new_open",NULL);
+               xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_directory_object));
+               xmlNewProp(xml_action,"pathname",pathname);
+               }
+
        captive_directory_object->corba_Directory_object=Captive_Vfs_directory_new_open(
                        captive_directory_object->vfs->corba_Vfs_object,pathname,&captive_corba_ev);
+       if (xml_action)
+               xmlNewProp(xml_action,"result",(captive_corba_ev._major==CORBA_NO_EXCEPTION ? "1" : "0"));
 
        if (!retried && captive_sandbox_parent_query_vfs_retry(&captive_corba_ev,captive_directory_object->vfs)) {
                retried=TRUE;
@@ -54,14 +65,25 @@ GnomeVFSResult captive_sandbox_parent_directory_new_make
                (CaptiveDirectoryObject *captive_directory_object,const gchar *pathname,guint perm)
 {
 gboolean retried=FALSE;
+xmlNode *xml_action;
 
        g_return_val_if_fail(captive_directory_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(pathname!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(captive_directory_object->dir_Handle==NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
 retry:
+       xml_action=NULL;
+       if (captive_directory_object->vfs->corba_bug_action) {
+               xml_action=xmlNewTextChild(captive_directory_object->vfs->corba_bug_action,NULL,"directory_new_make",NULL);
+               xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_directory_object));
+               xmlNewProp(xml_action,"pathname",pathname);
+               xmlNewProp(xml_action,"perm",captive_printf_alloca("%u",(unsigned)perm));
+               }
+
        captive_directory_object->corba_Directory_object=Captive_Vfs_directory_new_make(
                        captive_directory_object->vfs->corba_Vfs_object,pathname,perm,&captive_corba_ev);
+       if (xml_action)
+               xmlNewProp(xml_action,"result",(captive_corba_ev._major==CORBA_NO_EXCEPTION ? "1" : "0"));
 
        if (!retried && captive_sandbox_parent_query_vfs_retry(&captive_corba_ev,captive_directory_object->vfs)) {
                retried=TRUE;
@@ -75,12 +97,21 @@ retry:
 GnomeVFSResult captive_sandbox_parent_directory_close(CaptiveDirectoryObject *captive_directory_object)
 {
 GnomeVFSResult r;
+xmlNode *xml_action=NULL;
 
        g_return_val_if_fail(captive_directory_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(captive_directory_object->dir_Handle==NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
+       if (captive_directory_object->vfs->corba_bug_action) {
+               xml_action=xmlNewTextChild(captive_directory_object->vfs->corba_bug_action,NULL,"directory_close",NULL);
+               xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_directory_object));
+               }
+
        Captive_Directory_shutdown(captive_directory_object->corba_Directory_object,&captive_corba_ev);
-       if (GNOME_VFS_OK!=(r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev)))
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       if (xml_action)
+               xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
+       if (r!=GNOME_VFS_OK)
                return r;
 
        CORBA_Object_release((CORBA_Object)captive_directory_object->corba_Directory_object,&captive_corba_ev);
@@ -95,16 +126,28 @@ GnomeVFSResult captive_sandbox_parent_directory_read
 {
 Captive_GnomeVFSFileInfo *file_info_corba;
 GnomeVFSResult r;
+xmlNode *xml_action=NULL;
 
        g_return_val_if_fail(captive_directory_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(file_info_captive!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(captive_directory_object->dir_Handle==NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
+       if (captive_directory_object->vfs->corba_bug_action) {
+               xml_action=xmlNewTextChild(captive_directory_object->vfs->corba_bug_action,NULL,"directory_read",NULL);
+               xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_directory_object));
+               }
+
        Captive_Directory_read(captive_directory_object->corba_Directory_object,&file_info_corba,&captive_corba_ev);
-       if (GNOME_VFS_OK!=(r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev)))
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       if (xml_action)
+               xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
+       if (r!=GNOME_VFS_OK)
                return r;
 
-       if (GNOME_VFS_OK!=(r=captive_sandbox_file_info_corba_to_captive(file_info_captive,file_info_corba)))
+       r=captive_sandbox_file_info_corba_to_captive(file_info_captive,file_info_corba);
+       if (xml_action)
+               xmlSetProp(xml_action,"result",gnome_vfs_result_to_string(r));
+       if (r!=GNOME_VFS_OK)
                return r;       /* 'file_info_corba' leak */
 
        Captive_GnomeVFSFileInfo__freekids(file_info_corba,NULL/* 'd'; meaning? */);
@@ -117,12 +160,21 @@ GnomeVFSResult r;
 GnomeVFSResult captive_sandbox_parent_directory_remove(CaptiveDirectoryObject *captive_directory_object)
 {
 GnomeVFSResult r;
+xmlNode *xml_action=NULL;
 
        g_return_val_if_fail(captive_directory_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(captive_directory_object->dir_Handle==NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
+       if (captive_directory_object->vfs->corba_bug_action) {
+               xml_action=xmlNewTextChild(captive_directory_object->vfs->corba_bug_action,NULL,"directory_remove",NULL);
+               xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_directory_object));
+               }
+
        Captive_Directory_remove(captive_directory_object->corba_Directory_object,&captive_corba_ev);
-       if (GNOME_VFS_OK!=(r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev)))
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       if (xml_action)
+               xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
+       if (r!=GNOME_VFS_OK)
                return r;
 
        return GNOME_VFS_OK;
index 288fd6d..4de1da8 100644 (file)
 #include "../client/file.h"
 #include "../client/vfs.h"
 #include "FileInfo.h"
+#include "captive/macros.h"
 
 
 GnomeVFSResult captive_sandbox_parent_file_new_open(CaptiveFileObject *captive_file_object,
                const gchar *pathname,GnomeVFSOpenMode mode)
 {
+xmlNode *xml_action=NULL;
+
        g_return_val_if_fail(captive_file_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(pathname!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
+       if (captive_file_object->vfs->corba_bug_action) {
+               xml_action=xmlNewTextChild(captive_file_object->vfs->corba_bug_action,NULL,"file_new_open",NULL);
+               xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_file_object));
+               xmlNewProp(xml_action,"pathname",pathname);
+               xmlNewProp(xml_action,"mode",captive_printf_alloca("%u",(unsigned)mode));
+               }
+
        captive_file_object->corba_File_object=Captive_Vfs_file_new_open(
                        captive_file_object->vfs->corba_Vfs_object,pathname,mode,&captive_corba_ev);
+       if (xml_action)
+               xmlNewProp(xml_action,"result",(captive_corba_ev._major==CORBA_NO_EXCEPTION ? "1" : "0"));
 
        return captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
 }
@@ -44,11 +56,24 @@ GnomeVFSResult captive_sandbox_parent_file_new_open(CaptiveFileObject *captive_f
 GnomeVFSResult captive_sandbox_parent_file_new_create(CaptiveFileObject *captive_file_object,
                const gchar *pathname,GnomeVFSOpenMode mode,gboolean exclusive,guint perm)
 {
+xmlNode *xml_action=NULL;
+
        g_return_val_if_fail(captive_file_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(pathname!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
+       if (captive_file_object->vfs->corba_bug_action) {
+               xml_action=xmlNewTextChild(captive_file_object->vfs->corba_bug_action,NULL,"file_new_create",NULL);
+               xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_file_object));
+               xmlNewProp(xml_action,"pathname",pathname);
+               xmlNewProp(xml_action,"mode",captive_printf_alloca("%u",(unsigned)mode));
+               xmlNewProp(xml_action,"exclusive",captive_printf_alloca("%u",(unsigned)exclusive));
+               xmlNewProp(xml_action,"perm",captive_printf_alloca("%u",(unsigned)perm));
+               }
+
        captive_file_object->corba_File_object=Captive_Vfs_file_new_create(
                        captive_file_object->vfs->corba_Vfs_object,pathname,mode,exclusive,perm,&captive_corba_ev);
+       if (xml_action)
+               xmlNewProp(xml_action,"result",(captive_corba_ev._major==CORBA_NO_EXCEPTION ? "1" : "0"));
 
        return captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
 }
@@ -57,12 +82,21 @@ GnomeVFSResult captive_sandbox_parent_file_new_create(CaptiveFileObject *captive
 GnomeVFSResult captive_sandbox_parent_file_close(CaptiveFileObject *captive_file_object)
 {
 GnomeVFSResult r;
+xmlNode *xml_action=NULL;
 
        g_return_val_if_fail(captive_file_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(captive_file_object->file_Handle==NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
+       if (captive_file_object->vfs->corba_bug_action) {
+               xml_action=xmlNewTextChild(captive_file_object->vfs->corba_bug_action,NULL,"file_close",NULL);
+               xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_file_object));
+               }
+
        Captive_File_shutdown(captive_file_object->corba_File_object,&captive_corba_ev);
-       if (GNOME_VFS_OK!=(r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev)))
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       if (xml_action)
+               xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
+       if (r!=GNOME_VFS_OK)
                return r;
 
        CORBA_Object_release((CORBA_Object)captive_file_object->corba_File_object,&captive_corba_ev);
@@ -77,6 +111,7 @@ GnomeVFSResult captive_sandbox_parent_file_read(CaptiveFileObject *captive_file_
 {
 GnomeVFSResult r;
 Captive_Bytes *buffer_corba;
+xmlNode *xml_action=NULL;
 
        g_return_val_if_fail(captive_file_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(buffer_captive!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
@@ -86,8 +121,18 @@ Captive_Bytes *buffer_corba;
 
        *bytes_read_return=0;
 
+       if (captive_file_object->vfs->corba_bug_action) {
+               xml_action=xmlNewTextChild(captive_file_object->vfs->corba_bug_action,NULL,"file_read",NULL);
+               xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_file_object));
+               xmlNewProp(xml_action,"num_bytes",captive_printf_alloca("%lu",(unsigned long)num_bytes));
+               }
+
        Captive_File_read(captive_file_object->corba_File_object,&buffer_corba,num_bytes,&captive_corba_ev);
-       if (GNOME_VFS_OK!=(r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev)))
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+               return r;
+       if (xml_action)
+               xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
+       if (r!=GNOME_VFS_OK)
                return r;
 
        g_return_val_if_fail(buffer_corba->_length<=num_bytes,GNOME_VFS_ERROR_GENERIC);
@@ -97,6 +142,9 @@ Captive_Bytes *buffer_corba;
        Captive_Bytes__freekids(buffer_corba,NULL/* 'd'; meaning? */);
        CORBA_free(buffer_corba);
 
+       if (xml_action)
+               xmlNewProp(xml_action,"bytes_read_return",captive_printf_alloca("%lu",(unsigned long)*bytes_read_return));
+
        return GNOME_VFS_OK;
 }
 
@@ -107,6 +155,7 @@ GnomeVFSResult captive_sandbox_parent_file_write(CaptiveFileObject *captive_file
 GnomeVFSResult r;
 Captive_Bytes buffer_corba_local;
 Captive_GnomeVFSFileSize bytes_written_corba;
+xmlNode *xml_action=NULL;
 
        g_return_val_if_fail(captive_file_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(buffer_captive!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
@@ -116,17 +165,29 @@ Captive_GnomeVFSFileSize bytes_written_corba;
 
        *bytes_written_return=0;
 
+       if (captive_file_object->vfs->corba_bug_action) {
+               xml_action=xmlNewTextChild(captive_file_object->vfs->corba_bug_action,NULL,"file_write",NULL);
+               xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_file_object));
+               xmlNewProp(xml_action,"num_bytes",captive_printf_alloca("%lu",(unsigned long)num_bytes));
+               }
+
        buffer_corba_local._maximum=num_bytes;
        buffer_corba_local._length=num_bytes;
        buffer_corba_local._buffer=(/* de-const */gpointer)buffer_captive;
        buffer_corba_local._release=FALSE;
 
        Captive_File_write(captive_file_object->corba_File_object,&buffer_corba_local,&bytes_written_corba,&captive_corba_ev);
-       if (GNOME_VFS_OK!=(r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev)))
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       if (xml_action)
+               xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
+       if (r!=GNOME_VFS_OK)
                return r;
 
        *bytes_written_return=bytes_written_corba;
 
+       if (xml_action)
+               xmlNewProp(xml_action,"bytes_written_return",captive_printf_alloca("%lu",(unsigned long)*bytes_written_return));
+
        return GNOME_VFS_OK;
 }
 
@@ -135,12 +196,26 @@ GnomeVFSResult captive_sandbox_parent_file_seek
                (CaptiveFileObject *captive_file_object,GnomeVFSSeekPosition whence,GnomeVFSFileOffset offset)
 {
 GnomeVFSResult r;
+xmlNode *xml_action=NULL;
 
        g_return_val_if_fail(captive_file_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(captive_file_object->file_Handle==NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
+       if (captive_file_object->vfs->corba_bug_action) {
+               xml_action=xmlNewTextChild(captive_file_object->vfs->corba_bug_action,NULL,"file_seek",NULL);
+               xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_file_object));
+               xmlNewProp(xml_action,"whence",
+                               (whence==GNOME_VFS_SEEK_START ? "start" :
+                                       (whence==GNOME_VFS_SEEK_CURRENT ? "current" :
+                                               (whence==GNOME_VFS_SEEK_END ? "end" : captive_printf_alloca("%lu",(unsigned long)whence)))));
+               xmlNewProp(xml_action,"offset",captive_printf_alloca("%" G_GINT64_FORMAT,(gint64)offset));
+               }
+
        Captive_File_seek(captive_file_object->corba_File_object,whence,offset,&captive_corba_ev);
-       if (GNOME_VFS_OK!=(r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev)))
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       if (xml_action)
+               xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
+       if (r!=GNOME_VFS_OK)
                return r;
 
        return GNOME_VFS_OK;
@@ -151,17 +226,29 @@ GnomeVFSResult captive_sandbox_parent_file_tell(CaptiveFileObject *captive_file_
 {
 Captive_GnomeVFSFileOffset offset_corba;
 GnomeVFSResult r;
+xmlNode *xml_action=NULL;
 
        g_return_val_if_fail(captive_file_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(offset_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(captive_file_object->file_Handle==NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
+       if (captive_file_object->vfs->corba_bug_action) {
+               xml_action=xmlNewTextChild(captive_file_object->vfs->corba_bug_action,NULL,"file_tell",NULL);
+               xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_file_object));
+               }
+
        Captive_File_tell(captive_file_object->corba_File_object,&offset_corba,&captive_corba_ev);
-       if (GNOME_VFS_OK!=(r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev)))
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       if (xml_action)
+               xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
+       if (r!=GNOME_VFS_OK)
                return r;
 
        *offset_return=offset_corba;
 
+       if (xml_action)
+               xmlNewProp(xml_action,"offset_return",captive_printf_alloca("%" G_GINT64_FORMAT,(gint64)*offset_return));
+
        return GNOME_VFS_OK;
 }
 
@@ -169,12 +256,21 @@ GnomeVFSResult r;
 GnomeVFSResult captive_sandbox_parent_file_remove(CaptiveFileObject *captive_file_object)
 {
 GnomeVFSResult r;
+xmlNode *xml_action=NULL;
 
        g_return_val_if_fail(captive_file_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(captive_file_object->file_Handle==NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
+       if (captive_file_object->vfs->corba_bug_action) {
+               xml_action=xmlNewTextChild(captive_file_object->vfs->corba_bug_action,NULL,"file_remove",NULL);
+               xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_file_object));
+               }
+
        Captive_File_remove(captive_file_object->corba_File_object,&captive_corba_ev);
-       if (GNOME_VFS_OK!=(r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev)))
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       if (xml_action)
+               xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
+       if (r!=GNOME_VFS_OK)
                return r;
 
        return GNOME_VFS_OK;
@@ -186,18 +282,29 @@ GnomeVFSResult captive_sandbox_parent_file_file_info_get(CaptiveFileObject *capt
 {
 Captive_GnomeVFSFileInfo *file_info_corba;
 GnomeVFSResult r;
+xmlNode *xml_action=NULL;
 
        g_return_val_if_fail(captive_file_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(file_info_captive!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(captive_file_object->file_Handle==NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
+       if (captive_file_object->vfs->corba_bug_action) {
+               xml_action=xmlNewTextChild(captive_file_object->vfs->corba_bug_action,NULL,"file_file_info_get",NULL);
+               xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_file_object));
+               }
+
        Captive_File_file_info_get(captive_file_object->corba_File_object,&file_info_corba,&captive_corba_ev);
-       if (GNOME_VFS_OK!=(r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev)))
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       if (xml_action)
+               xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
+       if (r!=GNOME_VFS_OK)
                return r;
 
        r=captive_sandbox_file_info_corba_to_captive(file_info_captive,file_info_corba);
        Captive_GnomeVFSFileInfo__freekids(file_info_corba,NULL/* 'd'; meaning? */);
        CORBA_free(file_info_corba);
+       if (xml_action)
+               xmlSetProp(xml_action,"result",gnome_vfs_result_to_string(r));
        if (r!=GNOME_VFS_OK)
                return r;
 
@@ -210,16 +317,26 @@ GnomeVFSResult captive_sandbox_parent_file_file_info_set(CaptiveFileObject *capt
 {
 Captive_GnomeVFSFileInfo file_info_corba;
 GnomeVFSResult r;
+xmlNode *xml_action=NULL;
 
        g_return_val_if_fail(captive_file_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(file_info_captive!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(captive_file_object->file_Handle==NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
+       if (captive_file_object->vfs->corba_bug_action) {
+               xml_action=xmlNewTextChild(captive_file_object->vfs->corba_bug_action,NULL,"file_file_info_set",NULL);
+               xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_file_object));
+               xmlNewProp(xml_action,"mask",captive_printf_alloca("%u",(unsigned)mask));
+               }
+
        if (GNOME_VFS_OK!=(r=captive_sandbox_file_info_captive_to_corba(&file_info_corba,file_info_captive)))
                return r;
 
        Captive_File_file_info_set(captive_file_object->corba_File_object,&file_info_corba,mask,&captive_corba_ev);
-       if (GNOME_VFS_OK!=(r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev)))
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       if (xml_action)
+               xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
+       if (r!=GNOME_VFS_OK)
                return r;
 
        Captive_GnomeVFSFileInfo__freekids(&file_info_corba,NULL/* 'd'; meaning? */);
@@ -231,12 +348,22 @@ GnomeVFSResult r;
 GnomeVFSResult captive_sandbox_parent_file_truncate(CaptiveFileObject *captive_file_object,GnomeVFSFileSize file_size)
 {
 GnomeVFSResult r;
+xmlNode *xml_action=NULL;
 
        g_return_val_if_fail(captive_file_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(captive_file_object->file_Handle==NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
+       if (captive_file_object->vfs->corba_bug_action) {
+               xml_action=xmlNewTextChild(captive_file_object->vfs->corba_bug_action,NULL,"file_truncate",NULL);
+               xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_file_object));
+               xmlNewProp(xml_action,"file_size",captive_printf_alloca("%" G_GUINT64_FORMAT,(guint64)file_size));
+               }
+
        Captive_File_truncate(captive_file_object->corba_File_object,file_size,&captive_corba_ev);
-       if (GNOME_VFS_OK!=(r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev)))
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       if (xml_action)
+               xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
+       if (r!=GNOME_VFS_OK)
                return r;
 
        return GNOME_VFS_OK;
@@ -247,13 +374,24 @@ GnomeVFSResult captive_sandbox_parent_file_move
                (CaptiveFileObject *captive_file_object_old,const gchar *pathname_new,gboolean force_replace)
 {
 GnomeVFSResult r;
+xmlNode *xml_action=NULL;
 
        g_return_val_if_fail(captive_file_object_old!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(pathname_new!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(captive_file_object_old->file_Handle==NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
+       if (captive_file_object_old->vfs->corba_bug_action) {
+               xml_action=xmlNewTextChild(captive_file_object_old->vfs->corba_bug_action,NULL,"file_truncate",NULL);
+               xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_file_object_old));
+               xmlNewProp(xml_action,"pathname_new",pathname_new);
+               xmlNewProp(xml_action,"force_replace",captive_printf_alloca("%u",(unsigned)force_replace));
+               }
+
        Captive_File_move(captive_file_object_old->corba_File_object,pathname_new,force_replace,&captive_corba_ev);
-       if (GNOME_VFS_OK!=(r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev)))
+       r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
+       if (xml_action)
+               xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
+       if (r!=GNOME_VFS_OK)
                return r;
 
        return GNOME_VFS_OK;
index 862f27b..a080794 100644 (file)
@@ -30,6 +30,9 @@
 #include <signal.h>    /* for kill(2) */
 #include <wait.h>
 #include "../client/giochannel-blind.h"        /* for captive_giochannel_blind_commit() */
+#include <time.h>
+#include <errno.h>
+#include <fcntl.h>
 
 
 GnomeVFSResult captive_sandbox_parent_vfs_new(CaptiveVfsObject *captive_vfs_object)
@@ -47,6 +50,34 @@ gboolean errbool;
 }
 
 
+static void bug_doc_generate(CaptiveVfsObject *captive_vfs_object)
+{
+size_t out_fname_size;
+time_t time_t_local;
+gchar out_fname[PATH_MAX];
+int errint;
+
+       g_return_if_fail(captive_vfs_object!=NULL);
+
+       captive_giochannel_blind_readreport_to_xml(captive_vfs_object->corba_bug,captive_vfs_object->corba_parent_giochanel_blind);
+       xmlSetDocCompressMode(captive_vfs_object->corba_bug_doc,9);
+
+       time(&time_t_local);
+       if (!(out_fname_size=strftime(out_fname,sizeof(out_fname),captive_vfs_object->options.bug_pathname,
+                       localtime(&time_t_local)))) {
+               g_assert_not_reached();
+               return;
+               }
+
+       /* xmlSaveFormatFileEnc() would be better to prevent rewriting
+        * of target 'out_fname' but it does not support compression.
+        */
+       errint=xmlSaveFormatFileEnc(out_fname,captive_vfs_object->corba_bug_doc,"UTF-8",
+                       1);     /* format; ==output indenting; FIXME: Is it really indented? */
+       g_assert(errint!=-1);
+}
+
+
 GnomeVFSResult captive_sandbox_parent_vfs_close(CaptiveVfsObject *captive_vfs_object)
 {
 GnomeVFSResult r;
@@ -115,11 +146,21 @@ GIOStatus erriostatus;
                                NULL);  /* error */
                g_assert(erriostatus==G_IO_STATUS_NORMAL);
 
-               /* TODO: Summarize the bugreport. */
+               /* Summarize the bugreport. */
+               if (captive_vfs_object->corba_bug_doc)
+                       bug_doc_generate(captive_vfs_object);
                }
        g_io_channel_unref(captive_vfs_object->corba_parent_giochanel_blind);
        captive_vfs_object->corba_parent_giochanel_blind=NULL;
 
+       if (captive_vfs_object->corba_bug_doc) {
+               xmlFreeDoc(captive_vfs_object->corba_bug_doc);
+               captive_vfs_object->corba_bug_doc=NULL;
+               captive_vfs_object->corba_bug=NULL;
+               captive_vfs_object->corba_bug_action=NULL;
+               captive_vfs_object->corba_bug_log=NULL;
+               }
+
        return r;
 }
 
index de5153a..b650a68 100644 (file)
@@ -24,6 +24,8 @@
 #include "split.h"
 #include <glib/gmessages.h>
 #include "captive/macros.h"
+#include <libxml/tree.h>
+#include "../client/vfs.h"
 
 
 static void impl_Captive_GLogFunc_g_log_func
@@ -44,7 +46,8 @@ static POA_Captive_GLogFunc__vepv impl_Captive_GLogFunc_vepv={
        };
 
 
-Captive_GLogFunc impl_Captive_GLogFunc__create(PortableServer_POA poa,CORBA_Environment *ev)
+Captive_GLogFunc impl_Captive_GLogFunc__create
+               (PortableServer_POA poa,CaptiveVfsObject *captive_vfs_object,CORBA_Environment *ev)
 {
 Captive_GLogFunc retval;
 impl_POA_Captive_GLogFunc *newservant;
@@ -53,6 +56,7 @@ PortableServer_ObjectId *objid;
        captive_new0(newservant);       /* FIXME: leak */
        newservant->servant.vepv=&impl_Captive_GLogFunc_vepv;
        newservant->poa=poa;
+       newservant->captive_vfs_object=captive_vfs_object;
        POA_Captive_GLogFunc__init((PortableServer_Servant)newservant,ev);
        objid=PortableServer_POA_activate_object(poa,newservant,ev);
        CORBA_free(objid);
@@ -78,20 +82,55 @@ static void impl_Captive_GLogFunc_g_log_func
                (impl_POA_Captive_GLogFunc *servant,const Captive_GLogMessage *g_log_message,CORBA_Environment *ev)
 {
 GLogLevelFlags log_level_use;
-gboolean fatal=FALSE;
-
-       log_level_use=g_log_message->log_level;
-       /* Downgrade always-fatal 'ERROR' to 'CRITICAL' level */
-       if (log_level_use&G_LOG_LEVEL_ERROR) {
-               log_level_use=(log_level_use|G_LOG_LEVEL_CRITICAL)&~G_LOG_LEVEL_ERROR;
-               fatal=TRUE;
-               }
-       if (log_level_use&G_LOG_FLAG_FATAL) {
-               log_level_use&=~G_LOG_FLAG_FATAL;
-               fatal=TRUE;
+static const struct level_map {
+       GLogLevelFlags from,to;
+       const gchar *name;
+       } level_map[]={
+               /* Downgrade always-fatal 'ERROR' to 'CRITICAL' level */
+               { G_LOG_LEVEL_ERROR   ,G_LOG_LEVEL_CRITICAL,"error"    },
+               { G_LOG_LEVEL_CRITICAL,G_LOG_LEVEL_CRITICAL,"critical" },
+               { G_LOG_LEVEL_WARNING ,G_LOG_LEVEL_WARNING ,"warning"  },
+               { G_LOG_LEVEL_MESSAGE ,G_LOG_LEVEL_MESSAGE ,"message"  },
+               { G_LOG_LEVEL_INFO    ,G_LOG_LEVEL_INFO    ,"info"     },
+               { G_LOG_LEVEL_DEBUG   ,G_LOG_LEVEL_DEBUG   ,"debug"    },
+               };
+static const struct flag_map {
+       GLogLevelFlags from,to;
+       const gchar *name;
+       } flag_map[]={
+               { G_LOG_FLAG_RECURSION,G_LOG_FLAG_RECURSION,"recursion" },
+               { G_LOG_FLAG_FATAL    ,0                   ,"fatal"     },
+               };
+const struct level_map *levelp;
+const struct flag_map *flagp;
+
+       for (levelp=level_map;levelp<level_map+G_N_ELEMENTS(level_map);levelp++) {
+               log_level_use=g_log_message->log_level;
+               if (!(g_log_message->log_level & levelp->from))
+                       continue;
+               {
+               xmlNode *xml_message=NULL;
+
+                       if (servant->captive_vfs_object->corba_bug_log) {
+                               xml_message=xmlNewTextChild(servant->captive_vfs_object->corba_bug_log,NULL,"message",g_log_message->message);
+                                       xmlNewProp(xml_message,"level",levelp->name);
+                               }
+
+                       log_level_use&=~levelp->from;
+                       log_level_use|= levelp->to;
+                       for (flagp=flag_map;flagp<flag_map+G_N_ELEMENTS(flag_map);flagp++) {
+                               if (!(g_log_message->log_level & flagp->from))
+                                       continue;
+                               log_level_use&=~flagp->from;
+                               log_level_use|= flagp->to;
+                               if (xml_message)
+                                       xmlNewProp(xml_message,flagp->name,flagp->name);
+                               }
+                       }
+               g_log(G_LOG_DOMAIN,log_level_use,"sandbox: %s%s",
+                               (!(g_log_message->log_level & G_LOG_FLAG_FATAL) ? "" : "FATAL: "),
+                               g_log_message->message);
                }
-
-       g_log(G_LOG_DOMAIN,log_level_use,"sandbox: %s%s",(!fatal ? "" : "FATAL: "),g_log_message->message);
 }
 
 
index ffef985..be913d6 100644 (file)
@@ -31,11 +31,13 @@ G_BEGIN_DECLS
 typedef struct {
        POA_Captive_GLogFunc servant;
        PortableServer_POA poa;
+       CaptiveVfsObject *captive_vfs_object;
        } impl_POA_Captive_GLogFunc;
 
 
 void impl_Captive_Vfs_init_g_log_func(const Captive_GLogFunc g_log_func,gboolean debug_messages,CORBA_Environment *ev);
-Captive_GLogFunc impl_Captive_GLogFunc__create(PortableServer_POA poa,CORBA_Environment *ev);
+Captive_GLogFunc impl_Captive_GLogFunc__create
+               (PortableServer_POA poa,CaptiveVfsObject *captive_vfs_object,CORBA_Environment *ev);
 void impl_Captive_GLogFunc__destroy(impl_POA_Captive_GLogFunc *servant,CORBA_Environment *ev);
 void impl_Captive_Vfs_init_g_log_func_disable(void);
 
index 30ddca8..15ce117 100644 (file)
@@ -431,6 +431,72 @@ const gchar *chrooted_orbit_dir;
 }
 
 
+static xmlNode *options_module_captive_to_xml
+               (xmlNode *dest_xml_parent,const struct captive_options_module *src_options_module_captive)
+{
+       g_return_val_if_fail(dest_xml_parent!=NULL,NULL);
+       g_return_val_if_fail(src_options_module_captive!=NULL,NULL);
+
+       { xmlNode *module=xmlNewTextChild(dest_xml_parent,NULL,"module",NULL);
+       const gchar *type_string,*basename,*cgs;
+
+               basename=src_options_module_captive->pathname_utf8;
+               if ((cgs=strrchr(basename,'/')))
+                       basename=cgs+1;
+               xmlNewProp(module,"basename",basename);
+               switch (src_options_module_captive->type) {
+                       case CAPTIVE_OPTIONS_MODULE_TYPE_PE32:
+                               type_string="PE32";
+                               xmlNewProp(module,"length",captive_printf_alloca("%lu",(unsigned long)src_options_module_captive->u.pe32.length));
+                               xmlNewProp(module,"md5"   ,src_options_module_captive->u.pe32.md5);
+                               break;
+                       case CAPTIVE_OPTIONS_MODULE_TYPE_GMODULE:
+                               type_string="gmodule";
+                               break;
+                       default: g_assert_not_reached();
+                       }
+               xmlNewProp(module,"type",type_string);  /* AFTER the 'switch' to set 'type_string'! */
+               return module;
+               }
+}
+
+
+static void sandbox_parent_bug_doc_make(CaptiveVfsObject *captive_vfs_object)
+{
+       { xmlDoc *doc=xmlNewDoc("1.0");
+               captive_vfs_object->corba_bug_doc=doc;
+               { xmlNode *bug=xmlNewDocNode(captive_vfs_object->corba_bug_doc,NULL,"bug",NULL);
+                       xmlDocSetRootElement(captive_vfs_object->corba_bug_doc,bug);
+                       captive_vfs_object->corba_bug=bug;
+                       { xmlNode *bug_captive=xmlNewTextChild(bug,NULL,"captive",NULL);
+                               xmlNewProp(bug_captive,"version",VERSION);
+                               }
+                       { xmlNode *bug_filesystem=xmlNewTextChild(bug,NULL,"filesystem",NULL);
+                               options_module_captive_to_xml(bug_filesystem,&captive_vfs_object->options.filesystem);
+                               }
+                       { xmlNode *bug_load_module=xmlNewTextChild(bug,NULL,"load_module",NULL);
+                       guint load_moduleui;
+                       struct captive_options_module *options_module;
+                       GList *load_module_node;
+
+                               for (load_moduleui=0,load_module_node=captive_vfs_object->options.load_module;
+                                               load_module_node;
+                                               load_moduleui++,load_module_node=load_module_node->next) {
+                                       options_module=load_module_node->data;
+                                       options_module_captive_to_xml(bug_load_module,options_module);
+                                       }
+                               }
+                       { xmlNode *bug_action=xmlNewTextChild(bug,NULL,"action",NULL);
+                               captive_vfs_object->corba_bug_action=bug_action;
+                               }
+                       { xmlNode *bug_log=xmlNewTextChild(bug,NULL,"log",NULL);
+                               captive_vfs_object->corba_bug_log=bug_log;
+                               }
+                       }
+               }
+}
+
+
 static void sandbox_parent(const gchar *Vfs_IOR,const gchar *child_chroot_pid_hashkey_dir,CaptiveVfsObject *captive_vfs_object)
 {
 Captive_Vfs Vfs_object;
@@ -451,7 +517,7 @@ int errint;
        g_assert(validate_CORBA_Environment(&captive_corba_ev));
 
        /* Init 'GLogFunc_object' */
-       GLogFunc_object=impl_Captive_GLogFunc__create(captive_corba_poa,&captive_corba_ev);
+       GLogFunc_object=impl_Captive_GLogFunc__create(captive_corba_poa,captive_vfs_object,&captive_corba_ev);
        g_assert(validate_CORBA_Environment(&captive_corba_ev));
 
        /* Init 'CaptiveIOChannel_object' */
@@ -550,6 +616,9 @@ struct dirent *dirent;
        captive_vfs_object->corba_Vfs_object=Vfs_object;
        captive_vfs_object->corba_GLogFunc_object=GLogFunc_object;
        captive_vfs_object->corba_CaptiveIOChannel_object=CaptiveIOChannel_object;
+
+       if (captive_vfs_object->options.bug_pathname)
+               sandbox_parent_bug_doc_make(captive_vfs_object);
 }
 
 static void fd_shiftup(int *fdp)
index 5cb0b0a..2205af3 100644 (file)
@@ -1,6 +1,6 @@
 # $Id$
 # automake source for the storage drivers for reactos of libcaptive Makefile 
-# Copyright (C) 2002 Jan Kratochvil <project-captive@jankratochvil.net>
+# Copyright (C) 2002-2003 Jan Kratochvil <project-captive@jankratochvil.net>
 # 
 # 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
@@ -26,3 +26,5 @@ libstorage_la_SOURCES= \
                media.c \
                media.h \
                size.c
+libstorage_la_CFLAGS= \
+               $(LIBXML_CFLAGS)