f31ad2430ae982165a0b293a4ac5c7451de6949d
[captive.git] / src / libcaptive / sandbox / server-Directory.c
1 /* $Id$
2  * CORBA/ORBit server side of Directory object, ran by sandbox_child()
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 "server-Directory.h"   /* self */
23 #include "sandbox.h"
24 #include <glib/gmessages.h>
25 #include "captive/macros.h"
26 #include "../client/directory.h"
27 #include "FileInfo.h"
28 #include "split.h"
29 #include "../client/vfs-slave.h"
30
31
32 static void impl_Captive_Directory_fini(impl_POA_Captive_Directory *servant,CORBA_Environment *ev);
33 static void impl_Captive_Directory_read
34                 (impl_POA_Captive_Directory *servant,Captive_GnomeVFSFileInfo **file_info,CORBA_Environment *ev);
35 static void impl_Captive_Directory_remove(impl_POA_Captive_Directory *servant,CORBA_Environment *ev);
36 static void impl_Captive_Directory_shutdown(impl_POA_Captive_Directory *servant,CORBA_Environment *ev);
37
38
39 static PortableServer_ServantBase__epv impl_Captive_Directory_base_epv={
40         NULL,   /* _private data */
41         (gpointer)&impl_Captive_Directory_fini, /* finalize routine */
42         NULL,   /* default_POA routine */
43         };
44 static POA_Captive_Directory__epv impl_Captive_Directory_epv={
45         NULL,   /* _private */
46         (gpointer)&impl_Captive_Directory_read,
47         (gpointer)&impl_Captive_Directory_remove,
48         (gpointer)&impl_Captive_Directory_shutdown,
49         };
50 static POA_Captive_Directory__vepv impl_Captive_Directory_vepv={
51         &impl_Captive_Directory_base_epv,
52         &impl_Captive_Directory_epv,
53         };
54
55
56 Captive_Directory impl_Captive_Directory__create(PortableServer_POA poa,CORBA_Environment *ev)
57 {
58 Captive_Directory retval;
59 impl_POA_Captive_Directory *newservant;
60 PortableServer_ObjectId *objid;
61
62         captive_new0(newservant);       /* FIXME: leak */
63         newservant->servant.vepv=&impl_Captive_Directory_vepv;
64         newservant->poa=poa;
65         newservant->captive_directory_object=NULL;
66         POA_Captive_Directory__init((PortableServer_Servant)newservant,ev);
67         objid=PortableServer_POA_activate_object(poa,newservant,ev);
68         CORBA_free(objid);
69         retval=PortableServer_POA_servant_to_reference(poa,newservant,ev);
70
71         return retval;
72 }
73
74
75 static void impl_Captive_Directory_fini(impl_POA_Captive_Directory *servant,CORBA_Environment *ev)
76 {
77         if (servant->captive_directory_object) {
78                 g_object_unref(servant->captive_directory_object);
79                 servant->captive_directory_object=NULL;
80                 }
81 }
82
83
84 static void impl_Captive_Directory__destroy(impl_POA_Captive_Directory *servant,CORBA_Environment *ev)
85 {
86 PortableServer_ObjectId *objid;
87
88         objid=PortableServer_POA_servant_to_id(servant->poa,servant,ev);
89         PortableServer_POA_deactivate_object(servant->poa,objid,ev);
90         CORBA_free(objid);
91         impl_Captive_Directory_fini(servant,ev);
92         g_free(servant);
93 }
94
95
96 Captive_Directory impl_Captive_Vfs_directory_new_open
97                 (impl_POA_Captive_Vfs *servant,const CORBA_char *pathname,CORBA_Environment *ev)
98 {
99 Captive_Directory retval;
100 impl_POA_Captive_Directory *retval_servant;
101 GnomeVFSResult errvfsresult;
102
103         g_return_val_if_fail(CAPTIVE_VFS_SLAVE_IS_OBJECT(servant->captive_vfs_object),NULL);    /* not yet initialized? */
104
105         retval=impl_Captive_Directory__create(servant->poa,ev);
106         if (ev->_major!=CORBA_NO_EXCEPTION)
107                 return NULL;
108
109         retval_servant=PortableServer_POA_reference_to_servant(servant->poa,retval,ev);
110         if (ev->_major!=CORBA_NO_EXCEPTION)
111                 return NULL;    /* 'retval' leak */
112
113         if (GNOME_VFS_OK!=(errvfsresult=captive_directory_new_open(&retval_servant->captive_directory_object,
114                         servant->captive_vfs_object,pathname))) {
115                 impl_Captive_Directory__destroy(retval_servant,ev);
116                 captive_sandbox_child_GnomeVFSResultException_throw(ev,errvfsresult);
117                 return NULL;
118                 }
119
120         return retval;
121 }
122
123
124 Captive_Directory impl_Captive_Vfs_directory_new_make(impl_POA_Captive_Vfs *servant,
125                 const CORBA_char *pathname,const Captive_GnomeVFSFilePermissions perm,CORBA_Environment *ev)
126 {
127 Captive_Directory retval;
128 impl_POA_Captive_Directory *retval_servant;
129 GnomeVFSResult errvfsresult;
130
131         g_return_val_if_fail(CAPTIVE_VFS_SLAVE_IS_OBJECT(servant->captive_vfs_object),NULL);    /* not yet initialized? */
132
133         retval=impl_Captive_Directory__create(servant->poa,ev);
134         if (ev->_major!=CORBA_NO_EXCEPTION)
135                 return NULL;
136
137         retval_servant=PortableServer_POA_reference_to_servant(servant->poa,retval,ev);
138         if (ev->_major!=CORBA_NO_EXCEPTION)
139                 return NULL;    /* 'retval' leak */
140
141         if (GNOME_VFS_OK!=(errvfsresult=captive_directory_new_make(&retval_servant->captive_directory_object,
142                         servant->captive_vfs_object,pathname,perm))) {
143                 impl_Captive_Directory__destroy(retval_servant,ev);
144                 captive_sandbox_child_GnomeVFSResultException_throw(ev,errvfsresult);
145                 return NULL;
146                 }
147
148         return retval;
149 }
150
151
152 static void impl_Captive_Directory_read
153                 (impl_POA_Captive_Directory *servant,Captive_GnomeVFSFileInfo **file_info_corba_return,CORBA_Environment *ev)
154 {
155 GnomeVFSFileInfo file_info_captive;
156 Captive_GnomeVFSFileInfo *file_info_corba;
157 GnomeVFSResult errvfsresult;
158
159         if (GNOME_VFS_OK!=(errvfsresult=captive_directory_read(servant->captive_directory_object,&file_info_captive))) {
160                 captive_sandbox_child_GnomeVFSResultException_throw(ev,errvfsresult);
161                 return;
162                 }
163
164         file_info_corba=Captive_GnomeVFSFileInfo__alloc();
165
166         if (GNOME_VFS_OK!=(errvfsresult=captive_sandbox_file_info_captive_to_corba(
167                         file_info_corba,&file_info_captive))) {
168                 captive_sandbox_child_GnomeVFSResultException_throw(ev,errvfsresult);
169                 Captive_GnomeVFSFileInfo__freekids(file_info_corba,NULL/* 'd'; meaning? */);
170                 CORBA_free(file_info_corba);
171                 return;
172                 }
173
174         *file_info_corba_return=file_info_corba;
175 }
176
177
178 static void impl_Captive_Directory_remove(impl_POA_Captive_Directory *servant,CORBA_Environment *ev)
179 {
180 GnomeVFSResult errvfsresult;
181
182         if (GNOME_VFS_OK!=(errvfsresult=captive_directory_remove(servant->captive_directory_object))) {
183                 captive_sandbox_child_GnomeVFSResultException_throw(ev,errvfsresult);
184                 return;
185                 }
186 }
187
188
189 static gboolean impl_Captive_Directory_shutdown_idle(impl_POA_Captive_Directory *servant /* data */)
190 {
191         impl_Captive_Directory__destroy(servant,&captive_corba_ev);
192         g_assert(validate_CORBA_Environment(&captive_corba_ev));
193
194         return FALSE;   /* remove me */
195 }
196
197 static void impl_Captive_Directory_shutdown(impl_POA_Captive_Directory *servant,CORBA_Environment *ev)
198 {
199 GSource *source;
200
201         /* Shutdown 'servant->captive_directory_object' synchronously as it may
202          * flush its buffers needed to be transferred to our parent.
203          */
204         impl_Captive_Directory_fini(servant,&captive_corba_ev);
205         g_assert(validate_CORBA_Environment(&captive_corba_ev));
206
207         /* Do not call impl_Captive_Directory__destroy() directly as we would fail
208          * to finish this CORBA method call properly.
209          * Do not call g_idle_add_full() as it would miss linc main loop.
210          * FIXME: STATUS_SHARING_VIOLATION error during batch processing.
211          *  - probably exclusive access to be changed to shareable one
212          */
213   source=g_idle_source_new ();
214         g_source_set_priority(source,G_PRIORITY_LOW);
215   g_source_set_callback(
216                         source, /* source */
217                         (GSourceFunc)impl_Captive_Directory_shutdown_idle,      /* func */
218                         servant,        /* data */
219                         NULL);  /* notify */
220   g_source_attach(source,
221                         g_main_loop_get_context(linc_main_get_loop())); /* context; NULL means 'default context' */
222   g_source_unref(source);
223 }