595697919883f676a50735524ed7e0d945eed1bd
[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,"directory_new_open",NULL);
48                 xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_directory_parent_object));
49                 xmlNewProp(xml_action,"pathname",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,"result",(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,"directory_new_make",NULL);
82                 xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_directory_parent_object));
83                 xmlNewProp(xml_action,"pathname",captive_directory_parent_object->pathname);
84                 xmlNewProp(xml_action,"perm",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,"result",(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,"directory_close",NULL);
114                 xmlNewProp(xml_action,"object",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,"result",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                 g_assert(file_info_last_l->data==NULL); /* directory EOF */
133                 captive_directory_parent_object->corba_Directory_file_info_list=g_list_delete_link(
134                                 captive_directory_parent_object->corba_Directory_file_info_list,file_info_last_l);
135                 gnome_vfs_file_info_list_free(captive_directory_parent_object->corba_Directory_file_info_list);
136                 captive_directory_parent_object->corba_Directory_file_info_list=NULL;
137                 }
138
139         return r;
140 }
141
142 static GnomeVFSResult captive_sandbox_parent_directory_read_fill1
143                 (CaptiveDirectoryParentObject *captive_directory_parent_object,GnomeVFSFileInfo *file_info_captive)
144 {
145 xmlNode *xml_action=NULL;
146 Captive_GnomeVFSFileInfo *file_info_corba;
147 GnomeVFSResult r;
148 CaptiveVfsParentObject *captive_vfs_parent_object;
149
150         g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
151         g_return_val_if_fail(file_info_captive!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
152
153         captive_vfs_parent_object=CAPTIVE_VFS_PARENT_OBJECT(CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object)->vfs);
154
155         if (captive_vfs_parent_object->corba_bug_action) {
156                 xml_action=xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,"directory_read",NULL);
157                 xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_directory_parent_object));
158                 }
159
160         Captive_Directory_read(captive_directory_parent_object->corba_Directory_object,&file_info_corba,&captive_corba_ev);
161         r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
162         if (xml_action)
163                 xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
164         if (r!=GNOME_VFS_OK)
165                 return r;
166
167         r=captive_sandbox_file_info_corba_to_captive(file_info_captive,file_info_corba);
168         if (xml_action)
169                 xmlSetProp(xml_action,"result",gnome_vfs_result_to_string(r));
170         if (r!=GNOME_VFS_OK)
171                 return r;       /* 'file_info_corba' leak */
172
173         Captive_GnomeVFSFileInfo__freekids(file_info_corba,NULL/* 'd'; meaning? */);
174         CORBA_free(file_info_corba);
175
176         return GNOME_VFS_OK;
177 }
178
179 static GnomeVFSResult captive_sandbox_parent_directory_read_filldir(CaptiveDirectoryParentObject *captive_directory_parent_object)
180 {
181 GnomeVFSFileInfo *file_info_captive;
182 GnomeVFSResult r;
183
184         g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
185         g_return_val_if_fail(captive_directory_parent_object->corba_Directory_file_info_list==NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
186
187         for (;;) {
188                 file_info_captive=gnome_vfs_file_info_new();
189                 r=captive_sandbox_parent_directory_read_fill1(captive_directory_parent_object,file_info_captive);
190                 if (r==GNOME_VFS_ERROR_EOF) {
191                         gnome_vfs_file_info_unref(file_info_captive);
192                         break;
193                         }
194                 if (r!=GNOME_VFS_OK) {
195                         gnome_vfs_file_info_unref(file_info_captive);
196                         gnome_vfs_file_info_list_free(captive_directory_parent_object->corba_Directory_file_info_list);
197                         captive_directory_parent_object->corba_Directory_file_info_list=NULL;
198                         return r;
199                         }
200                 captive_directory_parent_object->corba_Directory_file_info_list=g_list_prepend(
201                                 captive_directory_parent_object->corba_Directory_file_info_list,file_info_captive);
202                 }
203
204         captive_directory_parent_object->corba_Directory_file_info_list=g_list_prepend(
205                         captive_directory_parent_object->corba_Directory_file_info_list,NULL);  /* EOF */
206         captive_directory_parent_object->corba_Directory_file_info_list=g_list_reverse(
207                         captive_directory_parent_object->corba_Directory_file_info_list);
208
209         return GNOME_VFS_OK;
210 }
211
212 /* We have to read the whole directory atomically
213  * as during valid child restart we would loose our reading position.
214  */
215 GnomeVFSResult captive_sandbox_parent_directory_read
216                 (CaptiveDirectoryParentObject *captive_directory_parent_object,GnomeVFSFileInfo *file_info_captive)
217 {
218 GnomeVFSResult r;
219
220         g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
221         g_return_val_if_fail(file_info_captive!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
222
223         if (!captive_directory_parent_object->corba_Directory_file_info_list)
224                 if (GNOME_VFS_OK!=(r=captive_sandbox_parent_directory_read_filldir(captive_directory_parent_object)))
225                         return r;
226
227         if (!captive_directory_parent_object->corba_Directory_file_info_list->data) {
228                 g_assert(captive_directory_parent_object->corba_Directory_file_info_list->next==NULL);
229                 /* Do not clear the list to leave us stuck at EOF - GnomeVFS behaves that way. */
230                 r=GNOME_VFS_ERROR_EOF;
231                 }
232         else {
233                 /* Cut first list item. */
234                 gnome_vfs_file_info_copy(
235                                 file_info_captive,  /* dest */
236                                 captive_directory_parent_object->corba_Directory_file_info_list->data); /* src */
237                 gnome_vfs_file_info_unref(captive_directory_parent_object->corba_Directory_file_info_list->data);
238                 captive_directory_parent_object->corba_Directory_file_info_list=g_list_delete_link(
239                                 captive_directory_parent_object->corba_Directory_file_info_list,
240                                 captive_directory_parent_object->corba_Directory_file_info_list);
241                 r=GNOME_VFS_OK;
242                 }
243
244         return r;
245 }
246
247
248 GnomeVFSResult captive_sandbox_parent_directory_remove(CaptiveDirectoryParentObject *captive_directory_parent_object)
249 {
250 GnomeVFSResult r;
251 xmlNode *xml_action=NULL;
252 CaptiveVfsParentObject *captive_vfs_parent_object;
253
254         g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
255
256         captive_vfs_parent_object=CAPTIVE_VFS_PARENT_OBJECT(CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object)->vfs);
257
258         if (captive_vfs_parent_object->corba_bug_action) {
259                 xml_action=xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,"directory_remove",NULL);
260                 xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_directory_parent_object));
261                 }
262
263         Captive_Directory_remove(captive_directory_parent_object->corba_Directory_object,&captive_corba_ev);
264         r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,captive_vfs_parent_object);
265         if (xml_action)
266                 xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
267         if (r!=GNOME_VFS_OK)
268                 return r;
269
270         return GNOME_VFS_OK;
271 }