+backward image iochannel over CORBA transport to be sandboxable
[captive.git] / src / libcaptive / sandbox / server-CaptiveIOChannel.c
1 /* $Id$
2  * CORBA/ORBit client side of image GIOChannel object of 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-CaptiveIOChannel.h"    /* self */
23 #include "sandbox.h"
24 #include <glib/gmessages.h>
25 #include "captive/macros.h"
26 #include "split.h"
27 #include <libgnomevfs/gnome-vfs-file-size.h>
28 #include "captive/storage.h"
29
30
31 static void impl_Captive_CaptiveIOChannel_fini(impl_POA_Captive_CaptiveIOChannel *servant,CORBA_Environment *ev);
32 static void impl_Captive_CaptiveIOChannel_read(impl_POA_Captive_CaptiveIOChannel *servant,
33                 Captive_Bytes **buffer_corba_return,const Captive_GSize count,CORBA_Environment *ev);
34 static void impl_Captive_CaptiveIOChannel_write(impl_POA_Captive_CaptiveIOChannel *servant,
35                 const Captive_Bytes *buffer,Captive_GSize *bytes_written_return,CORBA_Environment *ev);
36 static void impl_Captive_CaptiveIOChannel_seek
37                 (impl_POA_Captive_CaptiveIOChannel *servant,const Captive_GInt64 offset,const Captive_GSeekType type,CORBA_Environment *ev);
38 static Captive_GUInt64 impl_Captive_CaptiveIOChannel_size(impl_POA_Captive_CaptiveIOChannel *servant,CORBA_Environment *ev);
39
40
41 static PortableServer_ServantBase__epv impl_Captive_CaptiveIOChannel_base_epv={
42         NULL,   /* _private data */
43         (gpointer)&impl_Captive_CaptiveIOChannel_fini,  /* finalize routine */
44         NULL,   /* default_POA routine */
45         };
46 static POA_Captive_CaptiveIOChannel__epv impl_Captive_CaptiveIOChannel_epv={
47         NULL,   /* _private */
48         (gpointer)&impl_Captive_CaptiveIOChannel_read,
49         (gpointer)&impl_Captive_CaptiveIOChannel_write,
50         (gpointer)&impl_Captive_CaptiveIOChannel_seek,
51         (gpointer)&impl_Captive_CaptiveIOChannel_size,
52         };
53 static POA_Captive_CaptiveIOChannel__vepv impl_Captive_CaptiveIOChannel_vepv={
54         &impl_Captive_CaptiveIOChannel_base_epv,
55         &impl_Captive_CaptiveIOChannel_epv,
56         };
57
58
59 Captive_CaptiveIOChannel impl_Captive_CaptiveIOChannel__create
60                 (PortableServer_POA poa,GIOChannel *image_iochannel,CORBA_Environment *ev)
61 {
62 Captive_CaptiveIOChannel retval;
63 impl_POA_Captive_CaptiveIOChannel *newservant;
64 PortableServer_ObjectId *objid;
65 GIOStatus erriostatus;
66
67         captive_new0(newservant);       /* FIXME: leak */
68         newservant->servant.vepv=&impl_Captive_CaptiveIOChannel_vepv;
69         newservant->poa=poa;
70
71         newservant->image_iochannel=image_iochannel;
72         erriostatus=g_io_channel_set_encoding(newservant->image_iochannel,
73                         NULL, /* encoding; force binary data */
74                         NULL);  /* error */
75         g_assert(erriostatus==G_IO_STATUS_NORMAL);
76
77         /* captive_giochannel_size() only _after_ g_io_channel_set_encoding() ! */
78         newservant->image_size=captive_giochannel_size(newservant->image_iochannel);
79         g_return_val_if_fail(newservant->image_size>0,NULL);
80
81         POA_Captive_CaptiveIOChannel__init((PortableServer_Servant)newservant,ev);
82         objid=PortableServer_POA_activate_object(poa,newservant,ev);
83         CORBA_free(objid);
84         retval=PortableServer_POA_servant_to_reference(poa,newservant,ev);
85
86         return retval;
87 }
88
89
90 static void impl_Captive_CaptiveIOChannel_fini(impl_POA_Captive_CaptiveIOChannel *servant,CORBA_Environment *ev)
91 {
92         /* FIXME: Any flushes? */
93 }
94
95
96 void impl_Captive_CaptiveIOChannel__destroy(impl_POA_Captive_CaptiveIOChannel *servant,CORBA_Environment *ev)
97 {
98 PortableServer_ObjectId *objid;
99
100         objid=PortableServer_POA_servant_to_id(servant->poa,servant,ev);
101         PortableServer_POA_deactivate_object(servant->poa,objid,ev);
102         CORBA_free(objid);
103         impl_Captive_CaptiveIOChannel_fini(servant,ev);
104         g_free(servant);
105 }
106
107
108 static void impl_Captive_CaptiveIOChannel_read(impl_POA_Captive_CaptiveIOChannel *servant,
109                 Captive_Bytes **buffer_corba_return,const Captive_GSize count,CORBA_Environment *ev)
110 {
111 Captive_Bytes *buffer_corba;
112 gsize bytes_read;
113 GIOStatus erriostatus;
114
115         buffer_corba=Captive_Bytes__alloc();
116         buffer_corba->_maximum=count;
117         buffer_corba->_length=0;
118         buffer_corba->_buffer=Captive_Bytes_allocbuf(buffer_corba->_maximum);
119         buffer_corba->_release=TRUE;
120
121         erriostatus=g_io_channel_read_chars(servant->image_iochannel,
122                         buffer_corba->_buffer,  /* buf */
123                         count,  /* count */
124                         &bytes_read,    /* bytes_read */
125                         NULL);  /* error */
126         if (erriostatus==G_IO_STATUS_EOF) {
127                 g_assert(bytes_read==0);
128                 bytes_read=0;
129                 erriostatus=G_IO_STATUS_NORMAL;
130                 }
131         if (erriostatus!=G_IO_STATUS_NORMAL) {
132                 captive_sandbox_child_GnomeVFSResultException_throw(ev,GNOME_VFS_ERROR_IO);
133                 Captive_Bytes__freekids(buffer_corba,NULL/* 'd'; meaning? */);
134                 CORBA_free(buffer_corba);
135                 return;
136                 }
137
138         buffer_corba->_length=bytes_read;
139         *buffer_corba_return=buffer_corba;
140 }
141
142
143 static void impl_Captive_CaptiveIOChannel_write(impl_POA_Captive_CaptiveIOChannel *servant,
144                 const Captive_Bytes *buffer_corba,Captive_GSize *bytes_written_return,CORBA_Environment *ev)
145 {
146 gsize bytes_written;
147
148         if (G_IO_STATUS_NORMAL!=g_io_channel_write_chars(servant->image_iochannel,
149                         buffer_corba->_buffer,  /* buf */
150                         buffer_corba->_length,  /* count */
151                         &bytes_written, /* bytes_written */
152                         NULL)   /* error */
153                                         || bytes_written!=buffer_corba->_length) {
154                 captive_sandbox_child_GnomeVFSResultException_throw(ev,GNOME_VFS_ERROR_IO);
155                 return;
156                 }
157
158         *bytes_written_return=bytes_written;
159 }
160
161
162 static void impl_Captive_CaptiveIOChannel_seek
163                 (impl_POA_Captive_CaptiveIOChannel *servant,const Captive_GInt64 offset,const Captive_GSeekType type,CORBA_Environment *ev)
164 {
165         if (G_IO_STATUS_NORMAL!=g_io_channel_seek_position(servant->image_iochannel,
166                         offset, /* offset */
167                         type,   /* type */
168                         NULL)) {        /* error */
169                 captive_sandbox_child_GnomeVFSResultException_throw(ev,GNOME_VFS_ERROR_IO);
170                 return;
171                 }
172 }
173
174
175 static Captive_GUInt64 impl_Captive_CaptiveIOChannel_size(impl_POA_Captive_CaptiveIOChannel *servant,CORBA_Environment *ev)
176 {
177         return servant->image_size;
178 }