Split (vfs|directory|file) to &, &_parent and &_slave by inheritance.
[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,const gchar *pathname)
35 {
36 gboolean retried=FALSE;
37 xmlNode *xml_action;
38 CaptiveVfsParentObject *captive_vfs_parent_object;
39
40         g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
41         g_return_val_if_fail(pathname!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
42
43         captive_vfs_parent_object=CAPTIVE_VFS_PARENT_OBJECT(CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object)->vfs);
44
45 retry:
46         xml_action=NULL;
47         if (captive_vfs_parent_object->corba_bug_action) {
48                 xml_action=xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,"directory_new_open",NULL);
49                 xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_directory_parent_object));
50                 xmlNewProp(xml_action,"pathname",pathname);
51                 }
52
53         captive_directory_parent_object->corba_Directory_object=Captive_Vfs_directory_new_open(
54                         captive_vfs_parent_object->corba_Vfs_object,pathname,&captive_corba_ev);
55         if (xml_action)
56                 xmlNewProp(xml_action,"result",(captive_corba_ev._major==CORBA_NO_EXCEPTION ? "1" : "0"));
57
58         if (!retried && captive_sandbox_parent_query_vfs_retry(&captive_corba_ev,captive_vfs_parent_object)) {
59                 retried=TRUE;
60                 goto retry;
61                 }
62
63         return captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
64 }
65
66
67 GnomeVFSResult captive_sandbox_parent_directory_new_make
68                 (CaptiveDirectoryParentObject *captive_directory_parent_object,const gchar *pathname,guint perm)
69 {
70 gboolean retried=FALSE;
71 xmlNode *xml_action;
72 CaptiveVfsParentObject *captive_vfs_parent_object;
73
74         g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
75         g_return_val_if_fail(pathname!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
76
77         captive_vfs_parent_object=CAPTIVE_VFS_PARENT_OBJECT(CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object)->vfs);
78
79 retry:
80         xml_action=NULL;
81         if (captive_vfs_parent_object->corba_bug_action) {
82                 xml_action=xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,"directory_new_make",NULL);
83                 xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_directory_parent_object));
84                 xmlNewProp(xml_action,"pathname",pathname);
85                 xmlNewProp(xml_action,"perm",captive_printf_alloca("%u",(unsigned)perm));
86                 }
87
88         captive_directory_parent_object->corba_Directory_object=Captive_Vfs_directory_new_make(
89                         captive_vfs_parent_object->corba_Vfs_object,pathname,perm,&captive_corba_ev);
90         if (xml_action)
91                 xmlNewProp(xml_action,"result",(captive_corba_ev._major==CORBA_NO_EXCEPTION ? "1" : "0"));
92
93         if (!retried && captive_sandbox_parent_query_vfs_retry(&captive_corba_ev,captive_vfs_parent_object)) {
94                 retried=TRUE;
95                 goto retry;
96                 }
97
98         return captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
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);
119         if (xml_action)
120                 xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
121         if (r!=GNOME_VFS_OK)
122                 return r;
123
124         CORBA_Object_release((CORBA_Object)captive_directory_parent_object->corba_Directory_object,&captive_corba_ev);
125         captive_directory_parent_object->corba_Directory_object=CORBA_OBJECT_NIL;
126
127         if (captive_directory_parent_object->corba_Directory_file_info_list) {
128 GList *file_info_last_l=g_list_last(captive_directory_parent_object->corba_Directory_file_info_list);
129
130                 /* Prevent gnome_vfs_file_info_list_free() and its gnome_vfs_file_info_unref()
131                  * on the last 'file_info_list' items as it is EOF with NULL '->data'.
132                  */
133                 g_assert(file_info_last_l->data==NULL); /* directory EOF */
134                 captive_directory_parent_object->corba_Directory_file_info_list=g_list_delete_link(
135                                 captive_directory_parent_object->corba_Directory_file_info_list,file_info_last_l);
136                 gnome_vfs_file_info_list_free(captive_directory_parent_object->corba_Directory_file_info_list);
137                 captive_directory_parent_object->corba_Directory_file_info_list=NULL;
138                 }
139
140         return captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
141 }
142
143 static GnomeVFSResult captive_sandbox_parent_directory_read_fill1
144                 (CaptiveDirectoryParentObject *captive_directory_parent_object,GnomeVFSFileInfo *file_info_captive)
145 {
146 xmlNode *xml_action=NULL;
147 Captive_GnomeVFSFileInfo *file_info_corba;
148 GnomeVFSResult r;
149 CaptiveVfsParentObject *captive_vfs_parent_object;
150
151         g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
152         g_return_val_if_fail(file_info_captive!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
153
154         captive_vfs_parent_object=CAPTIVE_VFS_PARENT_OBJECT(CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object)->vfs);
155
156         if (captive_vfs_parent_object->corba_bug_action) {
157                 xml_action=xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,"directory_read",NULL);
158                 xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_directory_parent_object));
159                 }
160
161         Captive_Directory_read(captive_directory_parent_object->corba_Directory_object,&file_info_corba,&captive_corba_ev);
162         r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
163         if (xml_action)
164                 xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
165         if (r!=GNOME_VFS_OK)
166                 return r;
167
168         r=captive_sandbox_file_info_corba_to_captive(file_info_captive,file_info_corba);
169         if (xml_action)
170                 xmlSetProp(xml_action,"result",gnome_vfs_result_to_string(r));
171         if (r!=GNOME_VFS_OK)
172                 return r;       /* 'file_info_corba' leak */
173
174         Captive_GnomeVFSFileInfo__freekids(file_info_corba,NULL/* 'd'; meaning? */);
175         CORBA_free(file_info_corba);
176
177         return GNOME_VFS_OK;
178 }
179
180 static GnomeVFSResult captive_sandbox_parent_directory_read_filldir(CaptiveDirectoryParentObject *captive_directory_parent_object)
181 {
182 GnomeVFSFileInfo *file_info_captive;
183 GnomeVFSResult r;
184
185         g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
186         g_return_val_if_fail(captive_directory_parent_object->corba_Directory_file_info_list==NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
187
188         for (;;) {
189                 file_info_captive=gnome_vfs_file_info_new();
190                 r=captive_sandbox_parent_directory_read_fill1(captive_directory_parent_object,file_info_captive);
191                 if (r==GNOME_VFS_ERROR_EOF) {
192                         gnome_vfs_file_info_unref(file_info_captive);
193                         break;
194                         }
195                 if (r!=GNOME_VFS_OK) {
196                         gnome_vfs_file_info_unref(file_info_captive);
197                         gnome_vfs_file_info_list_free(captive_directory_parent_object->corba_Directory_file_info_list);
198                         captive_directory_parent_object->corba_Directory_file_info_list=NULL;
199                         return r;
200                         }
201                 captive_directory_parent_object->corba_Directory_file_info_list=g_list_prepend(
202                                 captive_directory_parent_object->corba_Directory_file_info_list,file_info_captive);
203                 }
204
205         captive_directory_parent_object->corba_Directory_file_info_list=g_list_prepend(
206                         captive_directory_parent_object->corba_Directory_file_info_list,NULL);  /* EOF */
207         captive_directory_parent_object->corba_Directory_file_info_list=g_list_reverse(
208                         captive_directory_parent_object->corba_Directory_file_info_list);
209
210         return GNOME_VFS_OK;
211 }
212
213 /* We have to read the whole directory atomically
214  * as during valid child restart we would loose our reading position.
215  */
216 GnomeVFSResult captive_sandbox_parent_directory_read
217                 (CaptiveDirectoryParentObject *captive_directory_parent_object,GnomeVFSFileInfo *file_info_captive)
218 {
219 GnomeVFSResult r;
220
221         g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
222         g_return_val_if_fail(file_info_captive!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
223
224         if (!captive_directory_parent_object->corba_Directory_file_info_list)
225                 if (GNOME_VFS_OK!=(r=captive_sandbox_parent_directory_read_filldir(captive_directory_parent_object)))
226                         return r;
227
228         if (!captive_directory_parent_object->corba_Directory_file_info_list->data) {
229                 g_assert(captive_directory_parent_object->corba_Directory_file_info_list->next==NULL);
230                 /* Do not clear the list to leave us stuck at EOF - GnomeVFS behaves that way. */
231                 r=GNOME_VFS_ERROR_EOF;
232                 }
233         else {
234                 /* Cut first list item. */
235                 gnome_vfs_file_info_copy(
236                                 file_info_captive,  /* dest */
237                                 captive_directory_parent_object->corba_Directory_file_info_list->data); /* src */
238                 gnome_vfs_file_info_unref(captive_directory_parent_object->corba_Directory_file_info_list->data);
239                 captive_directory_parent_object->corba_Directory_file_info_list=g_list_delete_link(
240                                 captive_directory_parent_object->corba_Directory_file_info_list,
241                                 captive_directory_parent_object->corba_Directory_file_info_list);
242                 r=GNOME_VFS_OK;
243                 }
244
245         return r;
246 }
247
248
249 GnomeVFSResult captive_sandbox_parent_directory_remove(CaptiveDirectoryParentObject *captive_directory_parent_object)
250 {
251 GnomeVFSResult r;
252 xmlNode *xml_action=NULL;
253 CaptiveVfsParentObject *captive_vfs_parent_object;
254
255         g_return_val_if_fail(CAPTIVE_DIRECTORY_PARENT_IS_OBJECT(captive_directory_parent_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
256
257         captive_vfs_parent_object=CAPTIVE_VFS_PARENT_OBJECT(CAPTIVE_DIRECTORY_OBJECT(captive_directory_parent_object)->vfs);
258
259         if (captive_vfs_parent_object->corba_bug_action) {
260                 xml_action=xmlNewTextChild(captive_vfs_parent_object->corba_bug_action,NULL,"directory_remove",NULL);
261                 xmlNewProp(xml_action,"object",captive_printf_alloca("%p",captive_directory_parent_object));
262                 }
263
264         Captive_Directory_remove(captive_directory_parent_object->corba_Directory_object,&captive_corba_ev);
265         r=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev);
266         if (xml_action)
267                 xmlNewProp(xml_action,"result",gnome_vfs_result_to_string(r));
268         if (r!=GNOME_VFS_OK)
269                 return r;
270
271         return GNOME_VFS_OK;
272 }