From: short <> Date: Sat, 7 Jun 2003 07:20:01 +0000 (+0000) Subject: +backward image iochannel over CORBA transport to be sandboxable X-Git-Tag: bp_captive~210 X-Git-Url: http://git.jankratochvil.net/?a=commitdiff_plain;h=1163731f59ddd68d1911caaf2c135f23ca11de2f;p=captive.git +backward image iochannel over CORBA transport to be sandboxable --- diff --git a/src/libcaptive/sandbox/client-CaptiveIOChannel.c b/src/libcaptive/sandbox/client-CaptiveIOChannel.c new file mode 100644 index 0000000..0b72f4f --- /dev/null +++ b/src/libcaptive/sandbox/client-CaptiveIOChannel.c @@ -0,0 +1,227 @@ +/* $Id$ + * CORBA/ORBit client side of image GIOChannel object of sandbox_child() + * Copyright (C) 2003 Jan Kratochvil + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; exactly version 2 of June 1991 is required + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "config.h" + +#include "client-CaptiveIOChannel.h" /* self */ +#include +#include "split.h" +#include +#include "captive/macros.h" + + +struct captive_io_channel { + GIOChannel iochannel; + Captive_CaptiveIOChannel corba_captive_io_channel; + }; + + +G_LOCK_DEFINE_STATIC(captive_io_channel_funcs); +static GIOFuncs captive_io_channel_funcs; + + +static gboolean validate_captive_io_channel(struct captive_io_channel *captive_io_channel) +{ + g_return_val_if_fail(captive_io_channel!=NULL,FALSE); + g_return_val_if_fail(captive_io_channel->corba_captive_io_channel!=NULL,FALSE); + + return TRUE; +} + + +static GIOStatus captive_io_channel_io_read + (GIOChannel *channel,gchar *buffer_captive,gsize count,gsize *bytes_read_return,GError **err) +{ +struct captive_io_channel *captive_io_channel=(struct captive_io_channel *)channel; +Captive_Bytes *buffer_corba; + + g_return_val_if_fail(validate_captive_io_channel(captive_io_channel),G_IO_STATUS_ERROR); + g_return_val_if_fail(buffer_captive!=NULL,G_IO_STATUS_ERROR); + g_return_val_if_fail(bytes_read_return!=NULL,G_IO_STATUS_ERROR); + + *bytes_read_return=0; + + Captive_CaptiveIOChannel_read(captive_io_channel->corba_captive_io_channel,&buffer_corba,count,&captive_corba_ev); + if (GNOME_VFS_OK!=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev)) + return G_IO_STATUS_ERROR; + + g_return_val_if_fail(buffer_corba->_length<=count,G_IO_STATUS_ERROR); + memcpy(buffer_captive,buffer_corba->_buffer,buffer_corba->_length); + *bytes_read_return=buffer_corba->_length; + + Captive_Bytes__freekids(buffer_corba,NULL/* 'd'; meaning? */); + CORBA_free(buffer_corba); + + return (*bytes_read_return == 0 ? G_IO_STATUS_EOF : G_IO_STATUS_NORMAL); +} + + +static GIOStatus captive_io_channel_io_write + (GIOChannel *channel,const gchar *buffer_captive,gsize count,gsize *bytes_written_return,GError **err) +{ +struct captive_io_channel *captive_io_channel=(struct captive_io_channel *)channel; +Captive_Bytes buffer_corba_local; +Captive_GSize bytes_written_corba; + + g_return_val_if_fail(validate_captive_io_channel(captive_io_channel),G_IO_STATUS_ERROR); + g_return_val_if_fail(buffer_captive!=NULL,G_IO_STATUS_ERROR); + g_return_val_if_fail(bytes_written_return!=NULL,G_IO_STATUS_ERROR); + + *bytes_written_return=0; + + buffer_corba_local._maximum=count; + buffer_corba_local._length=count; + buffer_corba_local._buffer=(/* de-const */gpointer)buffer_captive; + buffer_corba_local._release=FALSE; + + Captive_CaptiveIOChannel_write(captive_io_channel->corba_captive_io_channel, + &buffer_corba_local,&bytes_written_corba,&captive_corba_ev); + if (GNOME_VFS_OK!=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev)) + return G_IO_STATUS_ERROR; + + *bytes_written_return=bytes_written_corba; + + return G_IO_STATUS_NORMAL; +} + + +static GIOStatus captive_io_channel_io_seek(GIOChannel *channel,gint64 offset,GSeekType type,GError **err) +{ +struct captive_io_channel *captive_io_channel=(struct captive_io_channel *)channel; + + g_return_val_if_fail(validate_captive_io_channel(captive_io_channel),G_IO_STATUS_ERROR); + + Captive_CaptiveIOChannel_seek(captive_io_channel->corba_captive_io_channel,offset,type,&captive_corba_ev); + if (GNOME_VFS_OK!=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev)) + return G_IO_STATUS_ERROR; + + return G_IO_STATUS_NORMAL; +} + + +static GIOStatus captive_io_channel_io_close(GIOChannel *channel,GError **err) +{ +struct captive_io_channel *captive_io_channel=(struct captive_io_channel *)channel; + + g_return_val_if_fail(validate_captive_io_channel(captive_io_channel),G_IO_STATUS_ERROR); + + /* We are not authorized to destroy 'captive_io_channel->corba_captive_io_channel'. */ + /* flush()? */ + captive_io_channel->corba_captive_io_channel=NULL; + + return G_IO_STATUS_NORMAL; +} + + +static GSource* captive_io_channel_io_create_watch(GIOChannel *channel,GIOCondition condition) +{ +struct captive_io_channel *captive_io_channel=(struct captive_io_channel *)channel; + + g_return_val_if_fail(validate_captive_io_channel(captive_io_channel),NULL); + + g_return_val_if_reached(NULL); /* FIXME: NOT IMPLEMENTED YET */ +} + + +static void captive_io_channel_io_free(GIOChannel *channel) +{ +struct captive_io_channel *captive_io_channel=(struct captive_io_channel *)channel; + + /* After captive_io_channel_io_close() 'captive_io_channel' + * may be no longer valid for validate_captive_io_channel(captive_io_channel). + */ + g_return_if_fail(captive_io_channel!=NULL); + + g_assert(captive_io_channel->corba_captive_io_channel==NULL); + + g_free(captive_io_channel); +} + + +static GIOStatus captive_io_channel_io_set_flags(GIOChannel *channel,GIOFlags flags,GError **err) +{ +struct captive_io_channel *captive_io_channel=(struct captive_io_channel *)channel; + + g_return_val_if_fail(validate_captive_io_channel(captive_io_channel),G_IO_STATUS_ERROR); + + /* no G_IO_FLAG_APPEND and no G_IO_FLAG_NONBLOCK */ + g_return_val_if_fail((flags&G_IO_FLAG_SET_MASK)==0,G_IO_STATUS_ERROR); + + return G_IO_STATUS_NORMAL; +} + + +static GIOFlags captive_io_channel_io_get_flags(GIOChannel *channel) +{ +struct captive_io_channel *captive_io_channel=(struct captive_io_channel *)channel; + + g_return_val_if_fail(validate_captive_io_channel(captive_io_channel),0); + + return 0; /* | !G_IO_FLAG_APPEND | !G_IO_FLAG_NONBLOCK */ +} + + +struct captive_io_channel *captive_io_channel_new(Captive_CaptiveIOChannel corba_captive_io_channel,gboolean writeable) +{ +struct captive_io_channel *captive_io_channel; + + g_return_val_if_fail(corba_captive_io_channel!=NULL,NULL); + + G_LOCK(captive_io_channel_funcs); + captive_io_channel_funcs.io_read =captive_io_channel_io_read; + captive_io_channel_funcs.io_write =captive_io_channel_io_write; + captive_io_channel_funcs.io_seek =captive_io_channel_io_seek; + captive_io_channel_funcs.io_close =captive_io_channel_io_close; + captive_io_channel_funcs.io_create_watch=captive_io_channel_io_create_watch; + captive_io_channel_funcs.io_free =captive_io_channel_io_free; + captive_io_channel_funcs.io_set_flags =captive_io_channel_io_set_flags; + captive_io_channel_funcs.io_get_flags =captive_io_channel_io_get_flags; + G_UNLOCK(captive_io_channel_funcs); + + captive_new(captive_io_channel); + g_assert(G_STRUCT_OFFSET(struct captive_io_channel,iochannel)==0); /* safely re-type-able */ + g_io_channel_init(&captive_io_channel->iochannel); + captive_io_channel->iochannel.funcs=&captive_io_channel_funcs; + captive_io_channel->iochannel.is_seekable=TRUE; + captive_io_channel->iochannel.is_readable=TRUE; + captive_io_channel->iochannel.is_writeable=writeable; + captive_io_channel->iochannel.close_on_unref=TRUE; /* run g_io_channel_shutdown() flush on last unref */ + captive_io_channel->corba_captive_io_channel=corba_captive_io_channel; + + return captive_io_channel; +} + + +gboolean captive_io_channel_get_size(GIOChannel *giochannel,guint64 *size_return) +{ +struct captive_io_channel *captive_io_channel; + + g_return_val_if_fail(giochannel!=NULL,FALSE); + g_return_val_if_fail(size_return!=NULL,FALSE); + + if (giochannel->funcs!=&captive_io_channel_funcs) + return FALSE; + captive_io_channel=(struct captive_io_channel *)giochannel; + + *size_return=Captive_CaptiveIOChannel_size(captive_io_channel->corba_captive_io_channel,&captive_corba_ev); + if (GNOME_VFS_OK!=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev)) + return FALSE; + + return TRUE; +} diff --git a/src/libcaptive/sandbox/client-CaptiveIOChannel.h b/src/libcaptive/sandbox/client-CaptiveIOChannel.h new file mode 100644 index 0000000..63bb026 --- /dev/null +++ b/src/libcaptive/sandbox/client-CaptiveIOChannel.h @@ -0,0 +1,40 @@ +/* $Id$ + * Include file for CORBA/ORBit client side of image GIOChannel object of sandbox_child() + * Copyright (C) 2003 Jan Kratochvil + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; exactly version 2 of June 1991 is required + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _CLIENT_CAPTIVEIOCHANNEL_H +#define _CLIENT_CAPTIVEIOCHANNEL_H 1 + + +#include +#ifdef ORBIT2 /* Prevent missing $(ORBIT_CFLAGS) outside of libcaptive/sandbox/ */ +#include "sandbox.h" +#endif + + +G_BEGIN_DECLS + +#ifdef ORBIT2 /* Prevent missing $(ORBIT_CFLAGS) outside of libcaptive/sandbox/ */ +struct captive_io_channel *captive_io_channel_new(Captive_CaptiveIOChannel corba_captive_io_channel,gboolean writeable); +#endif +gboolean captive_io_channel_get_size(GIOChannel *giochannel,guint64 *size_return); + +G_END_DECLS + + +#endif /* _CLIENT_CAPTIVEIOCHANNEL_H */ diff --git a/src/libcaptive/sandbox/server-CaptiveIOChannel.c b/src/libcaptive/sandbox/server-CaptiveIOChannel.c new file mode 100644 index 0000000..db71790 --- /dev/null +++ b/src/libcaptive/sandbox/server-CaptiveIOChannel.c @@ -0,0 +1,178 @@ +/* $Id$ + * CORBA/ORBit client side of image GIOChannel object of sandbox_child() + * Copyright (C) 2003 Jan Kratochvil + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; exactly version 2 of June 1991 is required + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "config.h" + +#include "server-CaptiveIOChannel.h" /* self */ +#include "sandbox.h" +#include +#include "captive/macros.h" +#include "split.h" +#include +#include "captive/storage.h" + + +static void impl_Captive_CaptiveIOChannel_fini(impl_POA_Captive_CaptiveIOChannel *servant,CORBA_Environment *ev); +static void impl_Captive_CaptiveIOChannel_read(impl_POA_Captive_CaptiveIOChannel *servant, + Captive_Bytes **buffer_corba_return,const Captive_GSize count,CORBA_Environment *ev); +static void impl_Captive_CaptiveIOChannel_write(impl_POA_Captive_CaptiveIOChannel *servant, + const Captive_Bytes *buffer,Captive_GSize *bytes_written_return,CORBA_Environment *ev); +static void impl_Captive_CaptiveIOChannel_seek + (impl_POA_Captive_CaptiveIOChannel *servant,const Captive_GInt64 offset,const Captive_GSeekType type,CORBA_Environment *ev); +static Captive_GUInt64 impl_Captive_CaptiveIOChannel_size(impl_POA_Captive_CaptiveIOChannel *servant,CORBA_Environment *ev); + + +static PortableServer_ServantBase__epv impl_Captive_CaptiveIOChannel_base_epv={ + NULL, /* _private data */ + (gpointer)&impl_Captive_CaptiveIOChannel_fini, /* finalize routine */ + NULL, /* default_POA routine */ + }; +static POA_Captive_CaptiveIOChannel__epv impl_Captive_CaptiveIOChannel_epv={ + NULL, /* _private */ + (gpointer)&impl_Captive_CaptiveIOChannel_read, + (gpointer)&impl_Captive_CaptiveIOChannel_write, + (gpointer)&impl_Captive_CaptiveIOChannel_seek, + (gpointer)&impl_Captive_CaptiveIOChannel_size, + }; +static POA_Captive_CaptiveIOChannel__vepv impl_Captive_CaptiveIOChannel_vepv={ + &impl_Captive_CaptiveIOChannel_base_epv, + &impl_Captive_CaptiveIOChannel_epv, + }; + + +Captive_CaptiveIOChannel impl_Captive_CaptiveIOChannel__create + (PortableServer_POA poa,GIOChannel *image_iochannel,CORBA_Environment *ev) +{ +Captive_CaptiveIOChannel retval; +impl_POA_Captive_CaptiveIOChannel *newservant; +PortableServer_ObjectId *objid; +GIOStatus erriostatus; + + captive_new0(newservant); /* FIXME: leak */ + newservant->servant.vepv=&impl_Captive_CaptiveIOChannel_vepv; + newservant->poa=poa; + + newservant->image_iochannel=image_iochannel; + erriostatus=g_io_channel_set_encoding(newservant->image_iochannel, + NULL, /* encoding; force binary data */ + NULL); /* error */ + g_assert(erriostatus==G_IO_STATUS_NORMAL); + + /* captive_giochannel_size() only _after_ g_io_channel_set_encoding() ! */ + newservant->image_size=captive_giochannel_size(newservant->image_iochannel); + g_return_val_if_fail(newservant->image_size>0,NULL); + + POA_Captive_CaptiveIOChannel__init((PortableServer_Servant)newservant,ev); + objid=PortableServer_POA_activate_object(poa,newservant,ev); + CORBA_free(objid); + retval=PortableServer_POA_servant_to_reference(poa,newservant,ev); + + return retval; +} + + +static void impl_Captive_CaptiveIOChannel_fini(impl_POA_Captive_CaptiveIOChannel *servant,CORBA_Environment *ev) +{ + /* FIXME: Any flushes? */ +} + + +void impl_Captive_CaptiveIOChannel__destroy(impl_POA_Captive_CaptiveIOChannel *servant,CORBA_Environment *ev) +{ +PortableServer_ObjectId *objid; + + objid=PortableServer_POA_servant_to_id(servant->poa,servant,ev); + PortableServer_POA_deactivate_object(servant->poa,objid,ev); + CORBA_free(objid); + impl_Captive_CaptiveIOChannel_fini(servant,ev); + g_free(servant); +} + + +static void impl_Captive_CaptiveIOChannel_read(impl_POA_Captive_CaptiveIOChannel *servant, + Captive_Bytes **buffer_corba_return,const Captive_GSize count,CORBA_Environment *ev) +{ +Captive_Bytes *buffer_corba; +gsize bytes_read; +GIOStatus erriostatus; + + buffer_corba=Captive_Bytes__alloc(); + buffer_corba->_maximum=count; + buffer_corba->_length=0; + buffer_corba->_buffer=Captive_Bytes_allocbuf(buffer_corba->_maximum); + buffer_corba->_release=TRUE; + + erriostatus=g_io_channel_read_chars(servant->image_iochannel, + buffer_corba->_buffer, /* buf */ + count, /* count */ + &bytes_read, /* bytes_read */ + NULL); /* error */ + if (erriostatus==G_IO_STATUS_EOF) { + g_assert(bytes_read==0); + bytes_read=0; + erriostatus=G_IO_STATUS_NORMAL; + } + if (erriostatus!=G_IO_STATUS_NORMAL) { + captive_sandbox_child_GnomeVFSResultException_throw(ev,GNOME_VFS_ERROR_IO); + Captive_Bytes__freekids(buffer_corba,NULL/* 'd'; meaning? */); + CORBA_free(buffer_corba); + return; + } + + buffer_corba->_length=bytes_read; + *buffer_corba_return=buffer_corba; +} + + +static void impl_Captive_CaptiveIOChannel_write(impl_POA_Captive_CaptiveIOChannel *servant, + const Captive_Bytes *buffer_corba,Captive_GSize *bytes_written_return,CORBA_Environment *ev) +{ +gsize bytes_written; + + if (G_IO_STATUS_NORMAL!=g_io_channel_write_chars(servant->image_iochannel, + buffer_corba->_buffer, /* buf */ + buffer_corba->_length, /* count */ + &bytes_written, /* bytes_written */ + NULL) /* error */ + || bytes_written!=buffer_corba->_length) { + captive_sandbox_child_GnomeVFSResultException_throw(ev,GNOME_VFS_ERROR_IO); + return; + } + + *bytes_written_return=bytes_written; +} + + +static void impl_Captive_CaptiveIOChannel_seek + (impl_POA_Captive_CaptiveIOChannel *servant,const Captive_GInt64 offset,const Captive_GSeekType type,CORBA_Environment *ev) +{ + if (G_IO_STATUS_NORMAL!=g_io_channel_seek_position(servant->image_iochannel, + offset, /* offset */ + type, /* type */ + NULL)) { /* error */ + captive_sandbox_child_GnomeVFSResultException_throw(ev,GNOME_VFS_ERROR_IO); + return; + } +} + + +static Captive_GUInt64 impl_Captive_CaptiveIOChannel_size(impl_POA_Captive_CaptiveIOChannel *servant,CORBA_Environment *ev) +{ + return servant->image_size; +} diff --git a/src/libcaptive/sandbox/server-CaptiveIOChannel.h b/src/libcaptive/sandbox/server-CaptiveIOChannel.h new file mode 100644 index 0000000..8efbc0a --- /dev/null +++ b/src/libcaptive/sandbox/server-CaptiveIOChannel.h @@ -0,0 +1,45 @@ +/* $Id$ + * Include file for CORBA/ORBit client side of image GIOChannel object of sandbox_child() + * Copyright (C) 2003 Jan Kratochvil + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; exactly version 2 of June 1991 is required + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _SERVER_CAPTIVEIOCHANNEL_H +#define _SERVER_CAPTIVEIOCHANNEL_H 1 + + +#include +#include "sandbox.h" + + +G_BEGIN_DECLS + +typedef struct { + POA_Captive_CaptiveIOChannel servant; + PortableServer_POA poa; + GIOChannel *image_iochannel; + guint64 image_size; + } impl_POA_Captive_CaptiveIOChannel; + + +Captive_CaptiveIOChannel impl_Captive_CaptiveIOChannel__create + (PortableServer_POA poa,GIOChannel *image_iochannel,CORBA_Environment *ev); +void impl_Captive_CaptiveIOChannel__destroy(impl_POA_Captive_CaptiveIOChannel *servant,CORBA_Environment *ev); + +G_END_DECLS + + +#endif /* _SERVER_CAPTIVEIOCHANNEL_H */ diff --git a/src/libcaptive/storage/size.c b/src/libcaptive/storage/size.c index f1a80c2..7dfbbe7 100644 --- a/src/libcaptive/storage/size.c +++ b/src/libcaptive/storage/size.c @@ -23,6 +23,7 @@ #include "captive/storage.h" /* self */ #include "../client/giochannel-blind.h" /* for captive_giochannel_blind_get_size() */ +#include "../sandbox/client-CaptiveIOChannel.h" /* for captive_io_channel_get_size() */ #include #include #include @@ -46,6 +47,19 @@ guint64 r; } +static guint64 size_sandbox(GIOChannel *iochannel) +{ +guint64 r; + + g_return_val_if_fail(iochannel!=NULL,0); + + if (!captive_io_channel_get_size(iochannel,&r)) + return 0; + + return r; +} + + static GIOChannel *iochannel_null; static int iounixchannel_get_fd(GIOChannel *iochannel) @@ -197,6 +211,8 @@ guint64 r; if ((r=size_blind(iochannel))) return r; + if ((r=size_sandbox(iochannel))) + return r; if ((r=size_ioctl(iochannel))) return r; if ((r=size_seek(iochannel)))