/* $Id$ * CORBA/ORBit client side of Vfs object of sandbox_parent() * 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 "parent-Vfs.h" /* self */ #include #include "split.h" #include "../client/vfs.h" #include "sandbox.h" #include #include "server-GLogFunc.h" #include "server-CaptiveIOChannel.h" #include /* for kill(2) */ #include #include "../client/giochannel-blind.h" /* for captive_giochannel_blind_commit() */ #include #include #include #include "captive/macros.h" GnomeVFSResult captive_sandbox_parent_vfs_new_silent(CaptiveVfsParentObject *captive_vfs_parent_object) { gboolean errbool; g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS); errbool=captive_sandbox_spawn(captive_vfs_parent_object); g_return_val_if_fail(errbool==TRUE,GNOME_VFS_ERROR_GENERIC); return GNOME_VFS_OK; } GnomeVFSResult captive_sandbox_parent_vfs_new(CaptiveVfsParentObject *captive_vfs_parent_object) { GnomeVFSResult r; g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS); r=captive_sandbox_parent_vfs_new_silent(captive_vfs_parent_object); if (captive_vfs_parent_object->corba_bug_action) { xmlNode *xml_action; xml_action=xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,BAD_CAST "vfs_new",NULL); xmlNewProp(xml_action,BAD_CAST "object",BAD_CAST captive_printf_alloca("%p",captive_vfs_parent_object)); } return r; } static void bug_doc_generate(CaptiveVfsParentObject *captive_vfs_parent_object) { size_t out_fname_size; time_t time_t_local; gchar out_fname[PATH_MAX]; int errint; xmlNode *xml_media; const gchar *xml_media_type="???"; /* Prevent: ... might be used uninitialized in this function */ g_return_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object)); xml_media=captive_giochannel_blind_readreport_to_xml(captive_vfs_parent_object->corba_bug,captive_vfs_parent_object->corba_parent_giochanel_blind); switch (CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.media) { case CAPTIVE_OPTION_MEDIA_CDROM: xml_media_type="cdrom"; break; case CAPTIVE_OPTION_MEDIA_DISK: xml_media_type="disk"; break; default: g_assert_not_reached(); } xmlNewProp(xml_media,BAD_CAST "type",BAD_CAST xml_media_type); xmlSetDocCompressMode(captive_vfs_parent_object->corba_bug_doc,9); time(&time_t_local); if (!(out_fname_size=strftime(out_fname,sizeof(out_fname), CAPTIVE_VFS_OBJECT(captive_vfs_parent_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_parent_object->corba_bug_doc,"UTF-8", 1); /* format; ==output indenting; FIXME: Is it really indented? */ g_assert(errint!=-1); } static GnomeVFSResult captive_sandbox_parent_vfs_close_silent(CaptiveVfsParentObject *captive_vfs_parent_object) { GnomeVFSResult r; int errint; impl_POA_Captive_GLogFunc *GLogFunc_servant; impl_POA_Captive_CaptiveIOChannel *CaptiveIOChannel_servant; GIOStatus erriostatus; g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object!=CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS); Captive_Vfs_shutdown(captive_vfs_parent_object->corba_Vfs_object,&captive_corba_ev); r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object); /* We may get called by recursion from captive_sandbox_parent_return_from_CORBA_Environment(): */ if (captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL) return r; /* Always clear 'corba_Vfs_object' even if 'r' means failure. */ CORBA_Object_release(captive_vfs_parent_object->corba_Vfs_object,&captive_corba_ev); g_assert(validate_CORBA_Environment(&captive_corba_ev)); captive_vfs_parent_object->corba_Vfs_object=CORBA_OBJECT_NIL; /* Shutdown 'GLogFunc' servant. */ GLogFunc_servant=PortableServer_POA_reference_to_servant(captive_corba_poa, captive_vfs_parent_object->corba_GLogFunc_object,&captive_corba_ev); g_assert(validate_CORBA_Environment(&captive_corba_ev)); CORBA_Object_release(captive_vfs_parent_object->corba_GLogFunc_object,&captive_corba_ev); g_assert(validate_CORBA_Environment(&captive_corba_ev)); impl_Captive_GLogFunc__destroy(GLogFunc_servant,&captive_corba_ev); g_assert(validate_CORBA_Environment(&captive_corba_ev)); /* Shutdown 'CaptiveIOChannel' servant. */ CaptiveIOChannel_servant=PortableServer_POA_reference_to_servant(captive_corba_poa, captive_vfs_parent_object->corba_CaptiveIOChannel_object,&captive_corba_ev); g_assert(validate_CORBA_Environment(&captive_corba_ev)); CORBA_Object_release(captive_vfs_parent_object->corba_CaptiveIOChannel_object,&captive_corba_ev); g_assert(validate_CORBA_Environment(&captive_corba_ev)); impl_Captive_CaptiveIOChannel__destroy(CaptiveIOChannel_servant,&captive_corba_ev); g_assert(validate_CORBA_Environment(&captive_corba_ev)); /* Close parentheart_fd_write. */ if (captive_vfs_parent_object->corba_parentheart_fds_1!=-1) { errint=close(captive_vfs_parent_object->corba_parentheart_fds_1); g_return_val_if_fail(errint==0,FALSE); } /* Cleanup linked child socket to our parent '/tmp'. */ if (captive_vfs_parent_object->corba_chrooted_orbit_dir) { if (captive_vfs_parent_object->corba_socketname) { const gchar *socketpathname; socketpathname=captive_printf_alloca("%s/%s", captive_vfs_parent_object->corba_chrooted_orbit_dir,captive_vfs_parent_object->corba_socketname); unlink(socketpathname); /* errors ignored */ g_free(captive_vfs_parent_object->corba_socketname); captive_vfs_parent_object->corba_socketname=NULL; } rmdir(captive_vfs_parent_object->corba_chrooted_orbit_dir); /* errors ignored */ g_free(captive_vfs_parent_object->corba_chrooted_orbit_dir); captive_vfs_parent_object->corba_chrooted_orbit_dir=NULL; } /* Cleanup the child process. */ if (captive_vfs_parent_object->corba_child_pid!=(pid_t)-1) { kill(captive_vfs_parent_object->corba_child_pid,SIGKILL); /* errors ignored */ /* waitpid(2) errors are ignored as we should be immune against failures as the parent. */ waitpid(captive_vfs_parent_object->corba_child_pid, NULL, /* status */ /* options: !WNOHANG as the child will not be ready yet for waitpid() * right after its SIGKILL. As we did SIGKILL I hope it has no chance * to block us. */ 0); /* options */ } if (r==GNOME_VFS_OK) { erriostatus=captive_giochannel_blind_commit(captive_vfs_parent_object->corba_parent_giochanel_blind); g_assert(erriostatus==G_IO_STATUS_NORMAL); } else { /* sandbox child failure */ /* Flush the channel to catch all the disk accesses to the bugreport. */ erriostatus=g_io_channel_flush( captive_vfs_parent_object->corba_parent_giochanel_blind, /* channel */ NULL); /* error */ g_assert(erriostatus==G_IO_STATUS_NORMAL); /* Summarize the bugreport. */ if (captive_vfs_parent_object->corba_bug_doc) bug_doc_generate(captive_vfs_parent_object); } g_io_channel_unref(captive_vfs_parent_object->corba_parent_giochanel_blind); captive_vfs_parent_object->corba_parent_giochanel_blind=NULL; if (captive_vfs_parent_object->corba_bug_doc) { xmlFreeDoc(captive_vfs_parent_object->corba_bug_doc); captive_vfs_parent_object->corba_bug_doc=NULL; captive_vfs_parent_object->corba_bug=NULL; captive_vfs_parent_object->corba_bug_action=NULL; captive_vfs_parent_object->corba_bug_log=NULL; } return r; } GnomeVFSResult captive_sandbox_parent_vfs_close(CaptiveVfsParentObject *captive_vfs_parent_object) { g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object!=CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS); if (captive_vfs_parent_object->corba_bug_action) { xmlNode *xml_action; xml_action=xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,BAD_CAST "vfs_close",NULL); xmlNewProp(xml_action,BAD_CAST "object",BAD_CAST captive_printf_alloca("%p",captive_vfs_parent_object)); } return captive_sandbox_parent_vfs_close_silent(captive_vfs_parent_object); } GnomeVFSResult captive_sandbox_parent_vfs_commit(CaptiveVfsParentObject *captive_vfs_parent_object) { GnomeVFSResult r_close,r_new; xmlNode *xml_action=NULL; g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object!=CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS); if (captive_vfs_parent_object->corba_bug_action) { xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,BAD_CAST "vfs_commit",NULL); xmlNewProp(xml_action,BAD_CAST "object",BAD_CAST captive_printf_alloca("%p",captive_vfs_parent_object)); } r_close=captive_vfs_parent_object_disconnect(captive_vfs_parent_object); if (captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL) r_new=captive_vfs_parent_object_connect(captive_vfs_parent_object); else r_new=GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE; if (captive_vfs_parent_object->corba_bug_action) { xml_action=xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,BAD_CAST "vfs_commit",NULL); xmlNewProp(xml_action,BAD_CAST "object",BAD_CAST captive_printf_alloca("%p",captive_vfs_parent_object)); xmlNewProp(xml_action,BAD_CAST "result_prev_close",BAD_CAST gnome_vfs_result_to_string(r_close)); xmlNewProp(xml_action,BAD_CAST "result",BAD_CAST gnome_vfs_result_to_string(r_new)); } return (r_new!=GNOME_VFS_OK ? r_new : r_close); } GnomeVFSResult captive_sandbox_parent_vfs_volume_info_get (CaptiveVfsParentObject *captive_vfs_parent_object,CaptiveVfsVolumeInfo *volume_info_captive) { xmlNode *xml_action=NULL; Captive_CaptiveVfsVolumeInfo volume_info_corba; GnomeVFSResult r; g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(volume_info_captive!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); if (captive_vfs_parent_object->corba_bug_action) { xml_action=xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,BAD_CAST "vfs_volume_info_get",NULL); xmlNewProp(xml_action,BAD_CAST "object",BAD_CAST captive_printf_alloca("%p",captive_vfs_parent_object)); } Captive_Vfs_volume_info_get(captive_vfs_parent_object->corba_Vfs_object,&volume_info_corba,&captive_corba_ev); if (xml_action) xmlNewProp(xml_action,BAD_CAST "result",BAD_CAST (captive_corba_ev._major==CORBA_NO_EXCEPTION ? "1" : "0")); r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object); if (xml_action) xmlSetProp(xml_action,BAD_CAST "result",BAD_CAST gnome_vfs_result_to_string(r)); if (r!=GNOME_VFS_OK) return r; volume_info_captive->block_size=volume_info_corba.block_size; volume_info_captive->bytes=volume_info_corba.bytes; volume_info_captive->bytes_free=volume_info_corba.bytes_free; volume_info_captive->bytes_available=volume_info_corba.bytes_available; return GNOME_VFS_OK; }