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