+vfs_commit() logging to --bug-pathname file
[captive.git] / src / libcaptive / sandbox / parent-Vfs.c
1 /* $Id$
2  * CORBA/ORBit client side of Vfs object of sandbox_parent()
3  * Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
4  * 
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
8  * 
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.
13  * 
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
17  */
18
19
20 #include "config.h"
21
22 #include "captive/parent-Vfs.h" /* self */
23 #include <glib/gmessages.h>
24 #include "split.h"
25 #include "../client/vfs.h"
26 #include "sandbox.h"
27 #include <unistd.h>
28 #include "server-GLogFunc.h"
29 #include "server-CaptiveIOChannel.h"
30 #include <signal.h>     /* for kill(2) */
31 #include <wait.h>
32 #include "../client/giochannel-blind.h" /* for captive_giochannel_blind_commit() */
33 #include <time.h>
34 #include <errno.h>
35 #include <fcntl.h>
36 #include "captive/macros.h"
37
38
39 static GnomeVFSResult captive_sandbox_parent_vfs_new_silent(CaptiveVfsObject *captive_vfs_object)
40 {
41 gboolean errbool;
42
43         g_return_val_if_fail(captive_vfs_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
44
45         captive_vfs_object->is_sandbox_parent=TRUE;
46
47         errbool=captive_sandbox_spawn(captive_vfs_object);
48         g_return_val_if_fail(errbool==TRUE,GNOME_VFS_ERROR_GENERIC);
49
50         return GNOME_VFS_OK;
51 }
52
53
54 GnomeVFSResult captive_sandbox_parent_vfs_new(CaptiveVfsObject *captive_vfs_object)
55 {
56 GnomeVFSResult r;
57
58         g_return_val_if_fail(captive_vfs_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
59
60         r=captive_sandbox_parent_vfs_new_silent(captive_vfs_object);
61
62         if (captive_vfs_object->corba_bug_action) {
63 xmlNode *xml_action;
64
65                 xml_action=xmlNewTextChild(captive_vfs_object->corba_bug_action,NULL,"vfs_new",NULL);
66                 xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_vfs_object));
67                 }
68
69         return r;
70 }
71
72
73 static void bug_doc_generate(CaptiveVfsObject *captive_vfs_object)
74 {
75 size_t out_fname_size;
76 time_t time_t_local;
77 gchar out_fname[PATH_MAX];
78 int errint;
79
80         g_return_if_fail(captive_vfs_object!=NULL);
81
82         captive_giochannel_blind_readreport_to_xml(captive_vfs_object->corba_bug,captive_vfs_object->corba_parent_giochanel_blind);
83         xmlSetDocCompressMode(captive_vfs_object->corba_bug_doc,9);
84
85         time(&time_t_local);
86         if (!(out_fname_size=strftime(out_fname,sizeof(out_fname),captive_vfs_object->options.bug_pathname,
87                         localtime(&time_t_local)))) {
88                 g_assert_not_reached();
89                 return;
90                 }
91
92         /* xmlSaveFormatFileEnc() would be better to prevent rewriting
93          * of target 'out_fname' but it does not support compression.
94          */
95         errint=xmlSaveFormatFileEnc(out_fname,captive_vfs_object->corba_bug_doc,"UTF-8",
96                         1);     /* format; ==output indenting; FIXME: Is it really indented? */
97         g_assert(errint!=-1);
98 }
99
100
101 static GnomeVFSResult captive_sandbox_parent_vfs_close_silent(CaptiveVfsObject *captive_vfs_object)
102 {
103 GnomeVFSResult r;
104 int errint;
105 impl_POA_Captive_GLogFunc *GLogFunc_servant;
106 impl_POA_Captive_CaptiveIOChannel *CaptiveIOChannel_servant;
107 GIOStatus erriostatus;
108
109         g_return_val_if_fail(captive_vfs_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
110
111         Captive_Vfs_shutdown(captive_vfs_object->corba_Vfs_object,&captive_corba_ev);
112         r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
113
114         CORBA_Object_release(captive_vfs_object->corba_Vfs_object,&captive_corba_ev);
115         g_assert(validate_CORBA_Environment(&captive_corba_ev));
116
117         /* Shutdown 'GLogFunc' servant. */
118         GLogFunc_servant=PortableServer_POA_reference_to_servant(captive_corba_poa,
119                         captive_vfs_object->corba_GLogFunc_object,&captive_corba_ev);
120         g_assert(validate_CORBA_Environment(&captive_corba_ev));
121         CORBA_Object_release(captive_vfs_object->corba_GLogFunc_object,&captive_corba_ev);
122         g_assert(validate_CORBA_Environment(&captive_corba_ev));
123         impl_Captive_GLogFunc__destroy(GLogFunc_servant,&captive_corba_ev);
124         g_assert(validate_CORBA_Environment(&captive_corba_ev));
125
126         /* Shutdown 'CaptiveIOChannel' servant. */
127         CaptiveIOChannel_servant=PortableServer_POA_reference_to_servant(captive_corba_poa,
128                         captive_vfs_object->corba_CaptiveIOChannel_object,&captive_corba_ev);
129         g_assert(validate_CORBA_Environment(&captive_corba_ev));
130         CORBA_Object_release(captive_vfs_object->corba_CaptiveIOChannel_object,&captive_corba_ev);
131         g_assert(validate_CORBA_Environment(&captive_corba_ev));
132         impl_Captive_CaptiveIOChannel__destroy(CaptiveIOChannel_servant,&captive_corba_ev);
133         g_assert(validate_CORBA_Environment(&captive_corba_ev));
134
135         /* Close parentheart_fd_write. */
136         if (captive_vfs_object->corba_parentheart_fds_1!=-1) {
137                 errint=close(captive_vfs_object->corba_parentheart_fds_1);
138                 g_return_val_if_fail(errint==0,FALSE);
139                 }
140
141         /* Cleanup the child process. */
142         if (captive_vfs_object->corba_child_pid!=(pid_t)-1) {
143                 /*
144                  *
145                  *
146                  *
147                  *
148                  */
149                 kill(captive_vfs_object->corba_child_pid,SIGKILL);      /* errors ignored */
150                 /*
151                  *
152                  */
153                 waitpid(captive_vfs_object->corba_child_pid,
154                                 NULL,   /* status */
155                                 WNOHANG);       /* options */
156                 }
157
158         if (r==GNOME_VFS_OK) {
159                 erriostatus=captive_giochannel_blind_commit(captive_vfs_object->corba_parent_giochanel_blind);
160                 g_assert(erriostatus==G_IO_STATUS_NORMAL);
161                 }
162         else {  /* sandbox child failure */
163                 /* Flush the channel to catch all the disk accesses to the bugreport. */
164                 erriostatus=g_io_channel_flush(
165                                 captive_vfs_object->corba_parent_giochanel_blind,       /* channel */
166                                 NULL);  /* error */
167                 g_assert(erriostatus==G_IO_STATUS_NORMAL);
168
169                 /* Summarize the bugreport. */
170                 if (captive_vfs_object->corba_bug_doc)
171                         bug_doc_generate(captive_vfs_object);
172                 }
173         g_io_channel_unref(captive_vfs_object->corba_parent_giochanel_blind);
174         captive_vfs_object->corba_parent_giochanel_blind=NULL;
175
176         if (captive_vfs_object->corba_bug_doc) {
177                 xmlFreeDoc(captive_vfs_object->corba_bug_doc);
178                 captive_vfs_object->corba_bug_doc=NULL;
179                 captive_vfs_object->corba_bug=NULL;
180                 captive_vfs_object->corba_bug_action=NULL;
181                 captive_vfs_object->corba_bug_log=NULL;
182                 }
183
184         return r;
185 }
186
187
188 GnomeVFSResult captive_sandbox_parent_vfs_close(CaptiveVfsObject *captive_vfs_object)
189 {
190         g_return_val_if_fail(captive_vfs_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
191
192         if (captive_vfs_object->corba_bug_action) {
193 xmlNode *xml_action;
194
195                 xml_action=xmlNewTextChild(captive_vfs_object->corba_bug_action,NULL,"vfs_close",NULL);
196                 xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_vfs_object));
197                 }
198
199         return captive_sandbox_parent_vfs_close_silent(captive_vfs_object);
200 }
201
202
203 GnomeVFSResult captive_sandbox_parent_vfs_commit(CaptiveVfsObject *captive_vfs_object)
204 {
205 GnomeVFSResult r_close,r_new;
206 xmlNode *xml_action=NULL;
207
208         g_return_val_if_fail(captive_vfs_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
209
210         if (captive_vfs_object->corba_bug_action) {
211                 xmlNewTextChild(captive_vfs_object->corba_bug_action,NULL,"vfs_commit",NULL);
212                 xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_vfs_object));
213                 }
214
215         r_close=captive_sandbox_parent_vfs_close_silent(captive_vfs_object);    /* errors ignored */
216         r_new=captive_sandbox_parent_vfs_new_silent(captive_vfs_object);
217
218         if (captive_vfs_object->corba_bug_action) {
219                 xml_action=xmlNewTextChild(captive_vfs_object->corba_bug_action,NULL,"vfs_commit",NULL);
220                 xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_vfs_object));
221                 xmlNewProp(xml_action,"result_prev_close",gnome_vfs_result_to_string(r_close));
222                 xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r_new));
223                 }
224
225         return (r_new!=GNOME_VFS_OK ? r_new : r_close);
226 }