2 * CORBA/ORBit client side of Vfs object of sandbox_parent()
3 * Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; exactly version 2 of June 1991 is required
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "parent-Vfs.h" /* self */
23 #include <glib/gmessages.h>
25 #include "../client/vfs.h"
28 #include "server-GLogFunc.h"
29 #include "server-CaptiveIOChannel.h"
30 #include <signal.h> /* for kill(2) */
32 #include "../client/giochannel-blind.h" /* for captive_giochannel_blind_commit() */
36 #include "captive/macros.h"
39 GnomeVFSResult captive_sandbox_parent_vfs_new_silent(CaptiveVfsParentObject *captive_vfs_parent_object)
43 g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
45 g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS);
47 errbool=captive_sandbox_spawn(captive_vfs_parent_object);
48 g_return_val_if_fail(errbool==TRUE,GNOME_VFS_ERROR_GENERIC);
54 GnomeVFSResult captive_sandbox_parent_vfs_new(CaptiveVfsParentObject *captive_vfs_parent_object)
58 g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
60 g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS);
62 r=captive_sandbox_parent_vfs_new_silent(captive_vfs_parent_object);
64 if (captive_vfs_parent_object->corba_bug_action) {
67 xml_action=xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,BAD_CAST "vfs_new",NULL);
68 xmlNewProp(xml_action,BAD_CAST "object",BAD_CAST captive_printf_alloca("%p",captive_vfs_parent_object));
75 static void bug_doc_generate(CaptiveVfsParentObject *captive_vfs_parent_object)
77 size_t out_fname_size;
79 gchar out_fname[PATH_MAX];
82 const gchar *xml_media_type="???"; /* Prevent: ... might be used uninitialized in this function */
84 g_return_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object));
86 xml_media=captive_giochannel_blind_readreport_to_xml(captive_vfs_parent_object->corba_bug,captive_vfs_parent_object->corba_parent_giochanel_blind);
87 switch (CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.media) {
88 case CAPTIVE_OPTION_MEDIA_CDROM: xml_media_type="cdrom"; break;
89 case CAPTIVE_OPTION_MEDIA_DISK: xml_media_type="disk"; break;
90 default: g_assert_not_reached();
92 xmlNewProp(xml_media,BAD_CAST "type",BAD_CAST xml_media_type);
94 xmlSetDocCompressMode(captive_vfs_parent_object->corba_bug_doc,9);
97 if (!(out_fname_size=strftime(out_fname,sizeof(out_fname),
98 CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.bug_pathname,localtime(&time_t_local)))) {
99 g_assert_not_reached();
103 /* xmlSaveFormatFileEnc() would be better to prevent rewriting
104 * of target 'out_fname' but it does not support compression.
106 errint=xmlSaveFormatFileEnc(out_fname,captive_vfs_parent_object->corba_bug_doc,"UTF-8",
107 1); /* format; ==output indenting; FIXME: Is it really indented? */
108 g_assert(errint!=-1);
112 static GnomeVFSResult captive_sandbox_parent_vfs_close_silent(CaptiveVfsParentObject *captive_vfs_parent_object)
116 impl_POA_Captive_GLogFunc *GLogFunc_servant;
117 impl_POA_Captive_CaptiveIOChannel *CaptiveIOChannel_servant;
118 GIOStatus erriostatus;
120 g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
122 g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object!=CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS);
124 Captive_Vfs_shutdown(captive_vfs_parent_object->corba_Vfs_object,&captive_corba_ev);
125 r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
127 /* We may get called by recursion from captive_sandbox_parent_return_from_CORBA_Environment(): */
128 if (captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL)
131 /* Always clear 'corba_Vfs_object' even if 'r' means failure. */
132 CORBA_Object_release(captive_vfs_parent_object->corba_Vfs_object,&captive_corba_ev);
133 g_assert(validate_CORBA_Environment(&captive_corba_ev));
134 captive_vfs_parent_object->corba_Vfs_object=CORBA_OBJECT_NIL;
136 /* Shutdown 'GLogFunc' servant. */
137 GLogFunc_servant=PortableServer_POA_reference_to_servant(captive_corba_poa,
138 captive_vfs_parent_object->corba_GLogFunc_object,&captive_corba_ev);
139 g_assert(validate_CORBA_Environment(&captive_corba_ev));
140 CORBA_Object_release(captive_vfs_parent_object->corba_GLogFunc_object,&captive_corba_ev);
141 g_assert(validate_CORBA_Environment(&captive_corba_ev));
142 impl_Captive_GLogFunc__destroy(GLogFunc_servant,&captive_corba_ev);
143 g_assert(validate_CORBA_Environment(&captive_corba_ev));
145 /* Shutdown 'CaptiveIOChannel' servant. */
146 CaptiveIOChannel_servant=PortableServer_POA_reference_to_servant(captive_corba_poa,
147 captive_vfs_parent_object->corba_CaptiveIOChannel_object,&captive_corba_ev);
148 g_assert(validate_CORBA_Environment(&captive_corba_ev));
149 CORBA_Object_release(captive_vfs_parent_object->corba_CaptiveIOChannel_object,&captive_corba_ev);
150 g_assert(validate_CORBA_Environment(&captive_corba_ev));
151 impl_Captive_CaptiveIOChannel__destroy(CaptiveIOChannel_servant,&captive_corba_ev);
152 g_assert(validate_CORBA_Environment(&captive_corba_ev));
154 /* Close parentheart_fd_write. */
155 if (captive_vfs_parent_object->corba_parentheart_fds_1!=-1) {
156 errint=close(captive_vfs_parent_object->corba_parentheart_fds_1);
157 g_return_val_if_fail(errint==0,FALSE);
160 /* Cleanup linked child socket to our parent '/tmp'. */
161 if (captive_vfs_parent_object->corba_chrooted_orbit_dir) {
162 if (captive_vfs_parent_object->corba_socketname) {
163 const gchar *socketpathname;
165 socketpathname=captive_printf_alloca("%s/%s",
166 captive_vfs_parent_object->corba_chrooted_orbit_dir,captive_vfs_parent_object->corba_socketname);
167 unlink(socketpathname); /* errors ignored */
168 g_free(captive_vfs_parent_object->corba_socketname);
169 captive_vfs_parent_object->corba_socketname=NULL;
171 rmdir(captive_vfs_parent_object->corba_chrooted_orbit_dir); /* errors ignored */
172 g_free(captive_vfs_parent_object->corba_chrooted_orbit_dir);
173 captive_vfs_parent_object->corba_chrooted_orbit_dir=NULL;
176 /* Cleanup the child process. */
177 if (captive_vfs_parent_object->corba_child_pid!=(pid_t)-1) {
178 kill(captive_vfs_parent_object->corba_child_pid,SIGKILL); /* errors ignored */
179 /* waitpid(2) errors are ignored as we should be immune against failures as the parent. */
180 waitpid(captive_vfs_parent_object->corba_child_pid,
182 /* options: !WNOHANG as the child will not be ready yet for waitpid()
183 * right after its SIGKILL. As we did SIGKILL I hope it has no chance
189 if (r==GNOME_VFS_OK) {
190 erriostatus=captive_giochannel_blind_commit(captive_vfs_parent_object->corba_parent_giochanel_blind);
191 g_assert(erriostatus==G_IO_STATUS_NORMAL);
193 else { /* sandbox child failure */
194 /* Flush the channel to catch all the disk accesses to the bugreport. */
195 erriostatus=g_io_channel_flush(
196 captive_vfs_parent_object->corba_parent_giochanel_blind, /* channel */
198 g_assert(erriostatus==G_IO_STATUS_NORMAL);
200 /* Summarize the bugreport. */
201 if (captive_vfs_parent_object->corba_bug_doc)
202 bug_doc_generate(captive_vfs_parent_object);
204 g_io_channel_unref(captive_vfs_parent_object->corba_parent_giochanel_blind);
205 captive_vfs_parent_object->corba_parent_giochanel_blind=NULL;
207 if (captive_vfs_parent_object->corba_bug_doc) {
208 xmlFreeDoc(captive_vfs_parent_object->corba_bug_doc);
209 captive_vfs_parent_object->corba_bug_doc=NULL;
210 captive_vfs_parent_object->corba_bug=NULL;
211 captive_vfs_parent_object->corba_bug_action=NULL;
212 captive_vfs_parent_object->corba_bug_log=NULL;
219 GnomeVFSResult captive_sandbox_parent_vfs_close(CaptiveVfsParentObject *captive_vfs_parent_object)
221 g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
223 g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object!=CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS);
225 if (captive_vfs_parent_object->corba_bug_action) {
228 xml_action=xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,BAD_CAST "vfs_close",NULL);
229 xmlNewProp(xml_action,BAD_CAST "object",BAD_CAST captive_printf_alloca("%p",captive_vfs_parent_object));
232 return captive_sandbox_parent_vfs_close_silent(captive_vfs_parent_object);
236 GnomeVFSResult captive_sandbox_parent_vfs_commit(CaptiveVfsParentObject *captive_vfs_parent_object)
238 GnomeVFSResult r_close,r_new;
239 xmlNode *xml_action=NULL;
241 g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
243 g_return_val_if_fail(captive_vfs_parent_object->corba_Vfs_object!=CORBA_OBJECT_NIL,GNOME_VFS_ERROR_BAD_PARAMETERS);
245 if (captive_vfs_parent_object->corba_bug_action) {
246 xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,BAD_CAST "vfs_commit",NULL);
247 xmlNewProp(xml_action,BAD_CAST "object",BAD_CAST captive_printf_alloca("%p",captive_vfs_parent_object));
250 r_close=captive_vfs_parent_object_disconnect(captive_vfs_parent_object);
251 if (captive_vfs_parent_object->corba_Vfs_object==CORBA_OBJECT_NIL)
252 r_new=captive_vfs_parent_object_connect(captive_vfs_parent_object);
254 r_new=GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE;
256 if (captive_vfs_parent_object->corba_bug_action) {
257 xml_action=xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,BAD_CAST "vfs_commit",NULL);
258 xmlNewProp(xml_action,BAD_CAST "object",BAD_CAST captive_printf_alloca("%p",captive_vfs_parent_object));
259 xmlNewProp(xml_action,BAD_CAST "result_prev_close",BAD_CAST gnome_vfs_result_to_string(r_close));
260 xmlNewProp(xml_action,BAD_CAST "result",BAD_CAST gnome_vfs_result_to_string(r_new));
263 return (r_new!=GNOME_VFS_OK ? r_new : r_close);
267 GnomeVFSResult captive_sandbox_parent_vfs_volume_info_get
268 (CaptiveVfsParentObject *captive_vfs_parent_object,CaptiveVfsVolumeInfo *volume_info_captive)
270 xmlNode *xml_action=NULL;
271 Captive_CaptiveVfsVolumeInfo volume_info_corba;
274 g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
275 g_return_val_if_fail(volume_info_captive!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
277 if (captive_vfs_parent_object->corba_bug_action) {
278 xml_action=xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,BAD_CAST "vfs_volume_info_get",NULL);
279 xmlNewProp(xml_action,BAD_CAST "object",BAD_CAST captive_printf_alloca("%p",captive_vfs_parent_object));
282 Captive_Vfs_volume_info_get(captive_vfs_parent_object->corba_Vfs_object,&volume_info_corba,&captive_corba_ev);
284 xmlNewProp(xml_action,BAD_CAST "result",BAD_CAST (captive_corba_ev._major==CORBA_NO_EXCEPTION ? "1" : "0"));
286 r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
288 xmlSetProp(xml_action,BAD_CAST "result",BAD_CAST gnome_vfs_result_to_string(r));
292 volume_info_captive->block_size=volume_info_corba.block_size;
293 volume_info_captive->bytes=volume_info_corba.bytes;
294 volume_info_captive->bytes_free=volume_info_corba.bytes_free;
295 volume_info_captive->bytes_available=volume_info_corba.bytes_available;