Initial original import from: fuse-2.4.2-2.fc4
[captive.git] / src / libcaptive / sandbox / parent-Directory.c
1 /* $Id$
2  * CORBA/ORBit client side of Directory 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 "parent-Directory.h"   /* self */
23 #include <glib/gmessages.h>
24 #include "split.h"
25 #include "sandbox.h"
26 #include "../client/directory.h"
27 #include "../client/vfs.h"
28 #include "FileInfo.h"
29 #include "captive/macros.h"
30 #include "../client/vfs-parent.h"
31
32
33 GnomeVFSResult captive_sandbox_parent_directory_new_open
34                 (CaptiveDirectoryParentObject *captive_directory_parent_object)
35 {
36 xmlNode *xml_action=NULL;
37 CaptiveVfsParentObject *captive_vfs_parent_object;
38 GnomeVFSResult r;
39 Captive_Directory corba_Directory_object;
40
41         g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
42         g_return_val_if_fail(captive_directory_parent_object->pathname!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
43
44         captive_vfs_parent_object=CAPTIVE_VFS_PARENT_OBJECT(CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object)->vfs);
45
46         if (captive_vfs_parent_object->corba_bug_action) {
47                 xml_action=xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,BAD_CAST "directory_new_open",NULL);
48                 xmlNewProp(xml_action,BAD_CAST "object",BAD_CAST captive_printf_alloca("%p",captive_directory_parent_object));
49                 xmlNewProp(xml_action,BAD_CAST "pathname",BAD_CAST captive_directory_parent_object->pathname);
50                 }
51
52         corba_Directory_object=Captive_Vfs_directory_new_open(
53                         captive_vfs_parent_object->corba_Vfs_object,captive_directory_parent_object->pathname,&captive_corba_ev);
54         if (xml_action)
55                 xmlNewProp(xml_action,BAD_CAST "result",BAD_CAST (captive_corba_ev._major==CORBA_NO_EXCEPTION ? "1" : "0"));
56         /* If 'r' means failure 'corba_Directory_object' may not be 'CORBA_OBJECT_NIL'
57          * although it is not valid 'CORBA_Object' to be passed to CORBA_Object_release().
58          */
59         if (GNOME_VFS_OK!=(r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object)))
60                 return r;
61
62         captive_directory_parent_object->corba_Directory_object=corba_Directory_object;
63         return GNOME_VFS_OK;
64 }
65
66
67 GnomeVFSResult captive_sandbox_parent_directory_new_make
68                 (CaptiveDirectoryParentObject *captive_directory_parent_object,guint perm)
69 {
70 xmlNode *xml_action=NULL;
71 CaptiveVfsParentObject *captive_vfs_parent_object;
72 GnomeVFSResult r;
73 Captive_Directory corba_Directory_object;
74
75         g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
76         g_return_val_if_fail(captive_directory_parent_object->pathname!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
77
78         captive_vfs_parent_object=CAPTIVE_VFS_PARENT_OBJECT(CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object)->vfs);
79
80         if (captive_vfs_parent_object->corba_bug_action) {
81                 xml_action=xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,BAD_CAST "directory_new_make",NULL);
82                 xmlNewProp(xml_action,BAD_CAST "object",BAD_CAST captive_printf_alloca("%p",captive_directory_parent_object));
83                 xmlNewProp(xml_action,BAD_CAST "pathname",BAD_CAST captive_directory_parent_object->pathname);
84                 xmlNewProp(xml_action,BAD_CAST "perm",BAD_CAST captive_printf_alloca("%u",(unsigned)perm));
85                 }
86
87         corba_Directory_object=Captive_Vfs_directory_new_make(
88                         captive_vfs_parent_object->corba_Vfs_object,captive_directory_parent_object->pathname,perm,&captive_corba_ev);
89         if (xml_action)
90                 xmlNewProp(xml_action,BAD_CAST "result",BAD_CAST (captive_corba_ev._major==CORBA_NO_EXCEPTION ? "1" : "0"));
91         /* If 'r' means failure 'corba_Directory_object' may not be 'CORBA_OBJECT_NIL'
92          * although it is not valid 'CORBA_Object' to be passed to CORBA_Object_release().
93          */
94         if (GNOME_VFS_OK!=(r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object)))
95                 return r;
96
97         captive_directory_parent_object->corba_Directory_object=corba_Directory_object;
98         return GNOME_VFS_OK;
99 }
100
101
102 GnomeVFSResult captive_sandbox_parent_directory_close(CaptiveDirectoryParentObject *captive_directory_parent_object)
103 {
104 GnomeVFSResult r;
105 xmlNode *xml_action=NULL;
106 CaptiveVfsParentObject *captive_vfs_parent_object;
107
108         g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
109
110         captive_vfs_parent_object=CAPTIVE_VFS_PARENT_OBJECT(CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object)->vfs);
111
112         if (captive_vfs_parent_object->corba_bug_action) {
113                 xml_action=xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,BAD_CAST "directory_close",NULL);
114                 xmlNewProp(xml_action,BAD_CAST "object",BAD_CAST captive_printf_alloca("%p",captive_directory_parent_object));
115                 }
116
117         Captive_Directory_shutdown(captive_directory_parent_object->corba_Directory_object,&captive_corba_ev);
118         r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
119         if (xml_action)
120                 xmlNewProp(xml_action,BAD_CAST "result",BAD_CAST gnome_vfs_result_to_string(r));
121
122         /* Always clear 'corba_Directory_object' even if 'r' means failure. */
123         CORBA_Object_release((CORBA_Object)captive_directory_parent_object->corba_Directory_object,&captive_corba_ev);
124         captive_directory_parent_object->corba_Directory_object=CORBA_OBJECT_NIL;
125
126         if (captive_directory_parent_object->corba_Directory_file_info_list) {
127 GList *file_info_last_l=g_list_last(captive_directory_parent_object->corba_Directory_file_info_list);
128
129                 /* Prevent gnome_vfs_file_info_list_free() and its gnome_vfs_file_info_unref()
130                  * on the last 'file_info_list' items as it is EOF with NULL '->data'.
131                  */
132                 /* Do not: g_assert(file_info_last_l->data==NULL);      * directory EOF *
133                  * as the crashed client may not produced the trailing NULL.
134                  */
135                 if (!file_info_last_l->data)
136                         captive_directory_parent_object->corba_Directory_file_info_list=g_list_delete_link(
137                                         captive_directory_parent_object->corba_Directory_file_info_list,file_info_last_l);
138                 gnome_vfs_file_info_list_free(captive_directory_parent_object->corba_Directory_file_info_list);
139                 captive_directory_parent_object->corba_Directory_file_info_list=NULL;
140                 }
141
142         return r;
143 }
144
145 static GnomeVFSResult captive_sandbox_parent_directory_read_fill1
146                 (CaptiveDirectoryParentObject *captive_directory_parent_object,GnomeVFSFileInfo *file_info_captive)
147 {
148 xmlNode *xml_action=NULL;
149 Captive_GnomeVFSFileInfo *file_info_corba;
150 GnomeVFSResult r;
151 CaptiveVfsParentObject *captive_vfs_parent_object;
152
153         g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
154         g_return_val_if_fail(file_info_captive!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
155
156         captive_vfs_parent_object=CAPTIVE_VFS_PARENT_OBJECT(CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object)->vfs);
157
158         if (captive_vfs_parent_object->corba_bug_action) {
159                 xml_action=xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,BAD_CAST "directory_read",NULL);
160                 xmlNewProp(xml_action,BAD_CAST "object",BAD_CAST captive_printf_alloca("%p",captive_directory_parent_object));
161                 }
162
163         Captive_Directory_read(captive_directory_parent_object->corba_Directory_object,&file_info_corba,&captive_corba_ev);
164         r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
165         if (xml_action)
166                 xmlNewProp(xml_action,BAD_CAST "result",BAD_CAST gnome_vfs_result_to_string(r));
167         if (r!=GNOME_VFS_OK)
168                 return r;
169
170         r=captive_sandbox_file_info_corba_to_captive(file_info_captive,file_info_corba);
171         if (xml_action)
172                 xmlSetProp(xml_action,BAD_CAST "result",BAD_CAST gnome_vfs_result_to_string(r));
173         if (r!=GNOME_VFS_OK)
174                 return r;       /* 'file_info_corba' leak */
175
176         Captive_GnomeVFSFileInfo__freekids(file_info_corba,NULL/* 'd'; meaning? */);
177         CORBA_free(file_info_corba);
178
179         return GNOME_VFS_OK;
180 }
181
182 static GnomeVFSResult captive_sandbox_parent_directory_read_filldir(CaptiveDirectoryParentObject *captive_directory_parent_object)
183 {
184 GnomeVFSFileInfo *file_info_captive;
185 GnomeVFSResult r;
186
187         g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
188         g_return_val_if_fail(captive_directory_parent_object->corba_Directory_file_info_list==NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
189
190         for (;;) {
191                 file_info_captive=gnome_vfs_file_info_new();
192                 r=captive_sandbox_parent_directory_read_fill1(captive_directory_parent_object,file_info_captive);
193                 if (r==GNOME_VFS_ERROR_EOF) {
194                         gnome_vfs_file_info_unref(file_info_captive);
195                         break;
196                         }
197                 if (r!=GNOME_VFS_OK) {
198                         gnome_vfs_file_info_unref(file_info_captive);
199                         gnome_vfs_file_info_list_free(captive_directory_parent_object->corba_Directory_file_info_list);
200                         captive_directory_parent_object->corba_Directory_file_info_list=NULL;
201                         return r;
202                         }
203                 captive_directory_parent_object->corba_Directory_file_info_list=g_list_prepend(
204                                 captive_directory_parent_object->corba_Directory_file_info_list,file_info_captive);
205                 }
206
207         captive_directory_parent_object->corba_Directory_file_info_list=g_list_prepend(
208                         captive_directory_parent_object->corba_Directory_file_info_list,NULL);  /* EOF */
209         captive_directory_parent_object->corba_Directory_file_info_list=g_list_reverse(
210                         captive_directory_parent_object->corba_Directory_file_info_list);
211
212         return GNOME_VFS_OK;
213 }
214
215 /* We have to read the whole directory atomically
216  * as during valid child restart we would loose our reading position.
217  */
218 GnomeVFSResult captive_sandbox_parent_directory_read
219                 (CaptiveDirectoryParentObject *captive_directory_parent_object,GnomeVFSFileInfo *file_info_captive)
220 {
221 GnomeVFSResult r;
222
223         g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
224         g_return_val_if_fail(file_info_captive!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
225
226         if (!captive_directory_parent_object->corba_Directory_file_info_list)
227                 if (GNOME_VFS_OK!=(r=captive_sandbox_parent_directory_read_filldir(captive_directory_parent_object)))
228                         return r;
229
230         if (!captive_directory_parent_object->corba_Directory_file_info_list->data) {
231                 g_assert(captive_directory_parent_object->corba_Directory_file_info_list->next==NULL);
232                 /* Do not clear the list to leave us stuck at EOF - GnomeVFS behaves that way. */
233                 r=GNOME_VFS_ERROR_EOF;
234                 }
235         else {
236                 /* Cut first list item. */
237                 gnome_vfs_file_info_copy(
238                                 file_info_captive,  /* dest */
239                                 captive_directory_parent_object->corba_Directory_file_info_list->data); /* src */
240                 gnome_vfs_file_info_unref(captive_directory_parent_object->corba_Directory_file_info_list->data);
241                 captive_directory_parent_object->corba_Directory_file_info_list=g_list_delete_link(
242                                 captive_directory_parent_object->corba_Directory_file_info_list,
243                                 captive_directory_parent_object->corba_Directory_file_info_list);
244                 r=GNOME_VFS_OK;
245                 }
246
247         return r;
248 }
249
250
251 GnomeVFSResult captive_sandbox_parent_directory_remove(CaptiveDirectoryParentObject *captive_directory_parent_object)
252 {
253 GnomeVFSResult r;
254 xmlNode *xml_action=NULL;
255 CaptiveVfsParentObject *captive_vfs_parent_object;
256
257         g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
258
259         captive_vfs_parent_object=CAPTIVE_VFS_PARENT_OBJECT(CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object)->vfs);
260
261         if (captive_vfs_parent_object->corba_bug_action) {
262                 xml_action=xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,BAD_CAST "directory_remove",NULL);
263                 xmlNewProp(xml_action,BAD_CAST "object",BAD_CAST captive_printf_alloca("%p",captive_directory_parent_object));
264                 }
265
266         Captive_Directory_remove(captive_directory_parent_object->corba_Directory_object,&captive_corba_ev);
267         r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
268         if (xml_action)
269                 xmlNewProp(xml_action,BAD_CAST "result",BAD_CAST gnome_vfs_result_to_string(r));
270         if (r!=GNOME_VFS_OK)
271                 return r;
272
273         return GNOME_VFS_OK;
274 }