/*
* orbit-name-server : a CORBA CosNaming server
*
* Copyright (C) 1998 Elliot Lee, Sebastian Wilhelmi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "CosNaming.h"
#include "CosNaming_impl.h"
#include "name-support.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
/*** App-specific servant structures ***/
typedef struct
{
CosNaming_NameComponent nc;
CORBA_Object obj;
gint refcount;
CORBA_boolean is_subctx;
} RegisteredName;
typedef struct
{
POA_CosNaming_NamingContextExt servant;
PortableServer_POA poa;
GHashTable *names;
CORBA_Object objref;
} impl_POA_CosNaming_NamingContextExt;
typedef struct
{
POA_CosNaming_BindingIterator servant;
PortableServer_POA poa;
GList *items;
} impl_POA_CosNaming_BindingIterator;
/*** Stub implementations ***/
static void
NameComponent__copy (CosNaming_NameComponent * dest,
CosNaming_NameComponent * src)
{
dest->id = CORBA_string_dup (src->id);
dest->kind = CORBA_string_dup (src->kind);
}
static void
Name__copy (CosNaming_Name * dest, CosNaming_Name * src, int from_pos)
{
int i;
dest->_length = MAX (src->_length - from_pos, 0);
dest->_buffer = dest->_length ?
CORBA_sequence_CosNaming_NameComponent_allocbuf (dest->_length) : NULL;
for (i = 0; i < dest->_length; i++)
NameComponent__copy (dest->_buffer + i, src->_buffer + i + from_pos);
}
static guint
nc_hash (const CosNaming_NameComponent * nom)
{
return g_str_hash (nom->id) ^ g_str_hash (nom->kind);
}
static gint
nc_compare (const CosNaming_NameComponent * n1,
const CosNaming_NameComponent * n2)
{
return !strcmp (n1->id, n2->id) && !strcmp (n1->kind, n2->kind);
}
static RegisteredName *
rn_new (CosNaming_NameComponent * nc,
CORBA_Object obj, CORBA_boolean is_subctx)
{
RegisteredName *retval;
retval = g_new0 (RegisteredName, 1);
NameComponent__copy (&retval->nc, nc);
retval->obj = CORBA_Object_duplicate (obj, /* cheat */ NULL);
retval->is_subctx = is_subctx;
return retval;
}
#if 0
static void
rn_print (CosNaming_NameComponent * nc, RegisteredName * nom)
{
g_print ("id %s kind %s ptr %p [%p]\n", nc->id, nc->kind,
nom->obj, nom->obj ? nom->obj->pobj : NULL);
}
#endif
static RegisteredName *
rn_ref (RegisteredName * nom)
{
nom->refcount++;
return nom;
}
static void
rn_unref (RegisteredName * nom)
{
nom->refcount--;
if (nom->refcount <= 0)
{
CORBA_free (nom->nc.id);
CORBA_free (nom->nc.kind);
CORBA_Object_release (nom->obj, /* cheat */ NULL);
g_free (nom);
}
}
static void
l_rn_unref(gpointer data, gpointer user_data)
{
rn_unref((RegisteredName *)data);
}
static void
impl_NamingContext_unbind (impl_POA_CosNaming_NamingContextExt *
servant, CosNaming_Name * n,
CORBA_Environment * ev)
{
RegisteredName *nom = NULL;
if (n->_length < 1)
goto raise_exc;
nom = g_hash_table_lookup (servant->names, n->_buffer);
if (n->_length == 1 && nom)
{
g_hash_table_remove (servant->names, &nom->nc);
rn_unref (nom);
}
else if (nom && nom->is_subctx)
{
CosNaming_Name n2 = *n;
n2._length--;
n2._buffer++;
CosNaming_NamingContext_unbind (nom->obj, &n2, ev);
}
else
{
CosNaming_NamingContext_NotFound *exdata;
raise_exc:
exdata = CosNaming_NamingContext_NotFound__alloc ();
exdata->why =
nom ? CosNaming_NamingContext_not_context :
CosNaming_NamingContext_missing_node;
Name__copy (&exdata->rest_of_name, n, 0);
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
ex_CosNaming_NamingContext_NotFound, exdata);
}
}
static void
impl_NamingContext_bind (impl_POA_CosNaming_NamingContextExt *
servant, CosNaming_Name * n,
CORBA_Object obj, CORBA_Environment * ev)
{
RegisteredName *nom = NULL;
if (n->_length < 1)
goto raise_exc;
nom = g_hash_table_lookup (servant->names, n->_buffer);
if (n->_length == 1)
{
if (nom)
{
if (!CORBA_Object_non_existent (nom->obj, ev))
{
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
ex_CosNaming_NamingContext_AlreadyBound,
NULL);
return;
}
else
impl_NamingContext_unbind (servant, n, ev);
}
nom = rn_new (&n->_buffer[0], obj, CORBA_FALSE);
g_hash_table_insert (servant->names, &nom->nc, rn_ref (nom));
}
else if (nom && nom->is_subctx)
{
CosNaming_Name n2 = *n;
n2._length--;
n2._buffer++;
CosNaming_NamingContext_bind (nom->obj, &n2, obj, ev);
return;
}
else
{
CosNaming_NamingContext_NotFound *exdata;
raise_exc:
exdata = CosNaming_NamingContext_NotFound__alloc ();
exdata->why =
nom ? CosNaming_NamingContext_not_context :
CosNaming_NamingContext_missing_node;
Name__copy (&exdata->rest_of_name, n, 0);
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
ex_CosNaming_NamingContext_NotFound, exdata);
}
}
static void
impl_NamingContext_rebind (impl_POA_CosNaming_NamingContextExt *
servant, CosNaming_Name * n,
CORBA_Object obj, CORBA_Environment * ev)
{
RegisteredName *nom = NULL;
if (n->_length < 1)
goto raise_exc;
nom = g_hash_table_lookup (servant->names, n->_buffer);
if (n->_length == 1)
{
if (nom)
{
g_hash_table_remove (servant->names, &nom->nc);
rn_unref (nom);
}
nom = rn_new (&n->_buffer[0], obj, CORBA_FALSE);
g_hash_table_insert (servant->names, &nom->nc, rn_ref (nom));
}
else if (nom && nom->is_subctx)
{
CosNaming_Name n2 = *n;
n2._length--;
n2._buffer++;
CosNaming_NamingContext_rebind (nom->obj, &n2, obj, ev);
}
else
{
CosNaming_NamingContext_NotFound *exdata;
raise_exc:
exdata = CosNaming_NamingContext_NotFound__alloc ();
exdata->why =
nom ? CosNaming_NamingContext_not_context :
CosNaming_NamingContext_missing_node;
Name__copy (&exdata->rest_of_name, n, 0);
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
ex_CosNaming_NamingContext_NotFound, exdata);
}
}
static void
impl_NamingContext_bind_context (impl_POA_CosNaming_NamingContextExt
* servant, CosNaming_Name * n,
CosNaming_NamingContext nc,
CORBA_Environment * ev)
{
RegisteredName *nom = NULL;
if (n->_length < 1)
goto raise_exc;
nom = g_hash_table_lookup (servant->names, n->_buffer);
if (n->_length == 1)
{
if (nom)
{
if (!CORBA_Object_non_existent (nom->obj, ev))
{
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
ex_CosNaming_NamingContext_AlreadyBound,
NULL);
return;
}
else
impl_NamingContext_unbind (servant, n, ev);
}
nom = rn_new (&n->_buffer[0], nc, CORBA_TRUE);
g_hash_table_insert (servant->names, &nom->nc, rn_ref (nom));
}
else if (nom && nom->is_subctx)
{
CosNaming_Name n2 = *n;
n2._length--;
n2._buffer++;
CosNaming_NamingContext_bind (nom->obj, &n2, nc, ev);
return;
}
else
{
CosNaming_NamingContext_NotFound *exdata;
raise_exc:
exdata = CosNaming_NamingContext_NotFound__alloc ();
exdata->why =
nom ? CosNaming_NamingContext_not_context :
CosNaming_NamingContext_missing_node;
Name__copy (&exdata->rest_of_name, n, 0);
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
ex_CosNaming_NamingContext_NotFound, exdata);
}
}
static void
impl_NamingContext_rebind_context (impl_POA_CosNaming_NamingContextExt *
servant, CosNaming_Name * n,
CosNaming_NamingContext nc,
CORBA_Environment * ev)
{
RegisteredName *nom = NULL;
if (n->_length < 1)
goto raise_exc;
nom = g_hash_table_lookup (servant->names, n->_buffer);
if (n->_length == 1)
{
if (nom)
{
g_hash_table_remove (servant->names, &nom->nc);
rn_unref (nom);
}
nom = rn_new (&n->_buffer[0], nc, CORBA_TRUE);
g_hash_table_insert (servant->names, &nom->nc, rn_ref (nom));
}
else if (nom && nom->is_subctx)
{
CosNaming_Name n2 = *n;
n2._length--;
n2._buffer++;
CosNaming_NamingContext_rebind_context (nom->obj, &n2, nc, ev);
}
else
{
CosNaming_NamingContext_NotFound *exdata;
raise_exc:
exdata = CosNaming_NamingContext_NotFound__alloc ();
exdata->why =
nom ? CosNaming_NamingContext_not_context :
CosNaming_NamingContext_missing_node;
Name__copy (&exdata->rest_of_name, n, 0);
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
ex_CosNaming_NamingContext_NotFound, exdata);
}
}
static CORBA_Object
impl_NamingContext_resolve (impl_POA_CosNaming_NamingContextExt *
servant, CosNaming_Name * n,
CORBA_Environment * ev)
{
RegisteredName *nom = NULL;
if (n->_length < 1)
goto raise_exc;
nom = g_hash_table_lookup (servant->names, n->_buffer);
if (!nom)
{
CosNaming_NamingContext_NotFound *exdata;
exdata = CosNaming_NamingContext_NotFound__alloc ();
exdata->why = CosNaming_NamingContext_missing_node;
Name__copy (&exdata->rest_of_name, n, 0);
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
ex_CosNaming_NamingContext_NotFound, exdata);
}
else if (n->_length == 1)
{
if (!CORBA_Object_non_existent (nom->obj, ev))
return CORBA_Object_duplicate (nom->obj, ev);
else
{
CosNaming_NamingContext_NotFound *exdata;
impl_NamingContext_unbind (servant, n, ev);
raise_exc:
exdata = CosNaming_NamingContext_NotFound__alloc ();
exdata->why = CosNaming_NamingContext_missing_node;
Name__copy (&exdata->rest_of_name, n, 0);
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
ex_CosNaming_NamingContext_NotFound, exdata);
}
}
else
{
CosNaming_Name n2 = *n;
n2._length--;
n2._buffer++;
return CosNaming_NamingContext_resolve (nom->obj, &n2, ev);
}
return CORBA_OBJECT_NIL;
}
static CosNaming_NamingContext
impl_NamingContext_new_context (impl_POA_CosNaming_NamingContextExt
* servant, CORBA_Environment * ev)
{
return ORBit_CosNaming_NamingContextExt_create (servant->poa, ev);
}
static CosNaming_NamingContext
impl_NamingContext_bind_new_context (impl_POA_CosNaming_NamingContextExt *
servant, CosNaming_Name * n,
CORBA_Environment * ev)
{
RegisteredName *nom = NULL;
CosNaming_NamingContext retval;
if (n->_length < 1)
goto raise_exc;
nom = g_hash_table_lookup (servant->names, n->_buffer);
if (n->_length == 1)
{
if (nom)
{
if (!CORBA_Object_non_existent (nom->obj, ev))
{
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
ex_CosNaming_NamingContext_AlreadyBound,
NULL);
return CORBA_OBJECT_NIL;
}
else
impl_NamingContext_unbind (servant, n, ev);
}
retval = impl_NamingContext_new_context (servant, ev);
impl_NamingContext_bind_context (servant, n, retval, ev);
return retval;
}
else if (nom && nom->is_subctx)
{
CosNaming_Name n2 = *n;
n2._length--;
n2._buffer++;
return CosNaming_NamingContext_bind_new_context (nom->obj, &n2, ev);
}
else
{
CosNaming_NamingContext_NotFound *exdata;
raise_exc:
exdata = CosNaming_NamingContext_NotFound__alloc ();
exdata->why =
nom ? CosNaming_NamingContext_not_context :
CosNaming_NamingContext_missing_node;
Name__copy (&exdata->rest_of_name, n, 0);
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
ex_CosNaming_NamingContext_NotFound, exdata);
}
return CORBA_OBJECT_NIL;
}
static void
h_rn_unref (gpointer key, gpointer val, gpointer user_data)
{
rn_unref (val);
}
static void
impl_NamingContextExt__destroy (impl_POA_CosNaming_NamingContextExt *servant,
CORBA_Environment *ev)
{
CORBA_Object_release ((CORBA_Object) servant->poa, ev);
g_hash_table_foreach_remove (servant->names, (GHRFunc) h_rn_unref,
servant);
g_hash_table_destroy (servant->names);
CORBA_Object_release (servant->objref, ev);
POA_CosNaming_NamingContextExt__fini ((PortableServer_Servant) servant, ev);
g_free (servant);
}
static void
impl_NamingContext_destroy (impl_POA_CosNaming_NamingContextExt *
servant, CORBA_Environment * ev)
{
impl_NamingContextExt__destroy (servant, ev);
}
static CosNaming_BindingList *
n_names_into_bindinglist (GList ** itemlist, int n)
{
CosNaming_BindingList *bl = CosNaming_BindingList__alloc ();
int i;
RegisteredName *curnom;
bl->_length = n;
bl->_buffer =
n ? CORBA_sequence_CosNaming_Binding_allocbuf (bl->_length) : NULL;
for (i = 0; i < n; i++)
{
curnom = (*itemlist)->data;
*itemlist = g_list_remove_link (*itemlist, *itemlist);
bl->_buffer[i].binding_name._length = 1;
bl->_buffer[i].binding_name._buffer =
CORBA_sequence_CosNaming_NameComponent_allocbuf (1);
NameComponent__copy (&bl->_buffer[i].binding_name._buffer[0],
&curnom->nc);
bl->_buffer[i].binding_type =
curnom->is_subctx ? CosNaming_ncontext : CosNaming_nobject;
rn_unref (curnom);
}
return bl;
}
static void
list_ptr_append (gpointer key, gpointer val, GList ** listptr)
{
*listptr = g_list_append (*listptr, rn_ref (val));
}
static GList *
nc_names_into_itemlist (impl_POA_CosNaming_NamingContextExt * servant)
{
GList *retval = NULL;
g_hash_table_foreach (servant->names, (GHFunc) list_ptr_append, &retval);
return retval;
}
static void
impl_BindingIterator__destroy (impl_POA_CosNaming_BindingIterator *
servant, CORBA_Environment * ev)
{
CORBA_Object_release ((CORBA_Object) servant->poa, ev);
g_list_foreach (servant->items, (GFunc) l_rn_unref, NULL);
g_list_free (servant->items);
POA_CosNaming_BindingIterator__fini ((PortableServer_Servant) servant, ev);
g_free (servant);
}
static CORBA_boolean
impl_BindingIterator_next_one (impl_POA_CosNaming_BindingIterator *
servant, CosNaming_Binding ** b,
CORBA_Environment * ev)
{
RegisteredName *curnom;
if (servant->items)
{
*b = CosNaming_Binding__alloc ();
curnom = servant->items->data;
servant->items = g_list_remove_link (servant->items, servant->items);
(*b)->binding_name._length = 1;
(*b)->binding_name._buffer =
CORBA_sequence_CosNaming_NameComponent_allocbuf (1);
NameComponent__copy (&(*b)->binding_name._buffer[0], &curnom->nc);
(*b)->binding_type =
curnom->is_subctx ? CosNaming_ncontext : CosNaming_nobject;
rn_unref (curnom);
}
else
*b = NULL;
return servant->items ? CORBA_TRUE : CORBA_FALSE;
}
static CORBA_boolean
impl_BindingIterator_next_n (impl_POA_CosNaming_BindingIterator *
servant, CORBA_unsigned_long how_many,
CosNaming_BindingList ** bl,
CORBA_Environment * ev)
{
*bl =
n_names_into_bindinglist (&servant->items,
MIN (g_list_length (servant->items), how_many));
return ((*bl)->_length > 0);
}
static void
impl_BindingIterator_destroy (impl_POA_CosNaming_BindingIterator *
servant, CORBA_Environment * ev)
{
impl_BindingIterator__destroy (servant, ev);
}
static CosNaming_NamingContextExt_StringName
impl_NamingContextExt_to_string (impl_POA_CosNaming_NamingContextExt
* servant, CosNaming_Name * n,
CORBA_Environment * ev)
{
return ORBit_CosNaming_Name_to_string (n);
}
static CosNaming_Name *
impl_NamingContextExt_to_name (impl_POA_CosNaming_NamingContextExt *
servant,
CosNaming_NamingContextExt_StringName
sn, CORBA_Environment * ev)
{
return ORBit_string_to_CosNaming_Name (sn, ev);
}
static CosNaming_NamingContextExt_URLString
impl_NamingContextExt_to_url (impl_POA_CosNaming_NamingContextExt *
servant,
CosNaming_NamingContextExt_Address
addr,
CosNaming_NamingContextExt_StringName
sn, CORBA_Environment * ev)
{
return CORBA_string_dup ("FIXME: Not implemented yet, what should that "
"do BTW? Just a concatanation?");
}
static CORBA_Object
impl_NamingContextExt_resolve_str (impl_POA_CosNaming_NamingContextExt *
servant,
CosNaming_NamingContextExt_StringName n,
CORBA_Environment * ev)
{
CosNaming_Name *name = ORBit_string_to_CosNaming_Name (n, ev);
if (ev->_major != CORBA_NO_EXCEPTION)
return CORBA_OBJECT_NIL;
if (name->_length == 0)
return CORBA_Object_duplicate (servant->objref, ev);
else
return impl_NamingContext_resolve (servant, name, ev);
}
/*** epv structures ***/
static PortableServer_ServantBase__epv impl_BindingIterator_base_epv = {
NULL, /* _private data */
(gpointer) & impl_BindingIterator__destroy, /* finalize routine */
NULL, /* default_POA routine */
};
static POA_CosNaming_BindingIterator__epv impl_BindingIterator_epv = {
NULL, /* _private */
(gpointer) & impl_BindingIterator_next_one,
(gpointer) & impl_BindingIterator_next_n,
(gpointer) & impl_BindingIterator_destroy
};
static POA_CosNaming_NamingContextExt__epv impl_NamingContextExt_epv = {
NULL, /* _private */
(gpointer) & impl_NamingContextExt_to_string,
(gpointer) & impl_NamingContextExt_to_name,
(gpointer) & impl_NamingContextExt_to_url,
(gpointer) & impl_NamingContextExt_resolve_str
};
/*** vepv structures ***/
static POA_CosNaming_BindingIterator__vepv impl_BindingIterator_vepv = {
&impl_BindingIterator_base_epv,
&impl_BindingIterator_epv
};
static CosNaming_BindingIterator
impl_BindingIterator__create (PortableServer_POA poa,
impl_POA_CosNaming_BindingIterator **ns,
CORBA_Environment *ev)
{
CosNaming_BindingIterator retval;
impl_POA_CosNaming_BindingIterator *newservant;
PortableServer_ObjectId *objid;
newservant = *ns = g_new0 (impl_POA_CosNaming_BindingIterator, 1);
newservant->servant.vepv = &impl_BindingIterator_vepv;
newservant->poa = (PortableServer_POA) CORBA_Object_duplicate ((CORBA_Object) poa, ev);
newservant->items = NULL;
POA_CosNaming_BindingIterator__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_NamingContext_list (impl_POA_CosNaming_NamingContextExt *servant,
CORBA_unsigned_long how_many,
CosNaming_BindingList **bl,
CosNaming_BindingIterator *bi,
CORBA_Environment *ev)
{
GList *itemlist;
itemlist = nc_names_into_itemlist (servant);
if (how_many > 0)
{
*bl =
n_names_into_bindinglist (&itemlist,
MIN (how_many,
g_hash_table_size (servant->names)));
}
else
{
*bl = CosNaming_BindingList__alloc ();
(*bl)->_length = 0;
}
if (itemlist)
{
impl_POA_CosNaming_BindingIterator *newservant;
*bi = impl_BindingIterator__create (servant->poa, &newservant, ev);
newservant->items = itemlist;
}
else
*bi = CORBA_OBJECT_NIL;
}
static PortableServer_ServantBase__epv impl_NamingContextExt_base_epv = {
NULL, /* _private data */
(gpointer) & impl_NamingContextExt__destroy, /* finalize routine */
NULL, /* default_POA routine */
};
static POA_CosNaming_NamingContext__epv impl_NamingContext_epv = {
NULL, /* _private */
(gpointer) & impl_NamingContext_bind,
(gpointer) & impl_NamingContext_rebind,
(gpointer) & impl_NamingContext_bind_context,
(gpointer) & impl_NamingContext_rebind_context,
(gpointer) & impl_NamingContext_resolve,
(gpointer) & impl_NamingContext_unbind,
(gpointer) & impl_NamingContext_new_context,
(gpointer) & impl_NamingContext_bind_new_context,
(gpointer) & impl_NamingContext_destroy,
(gpointer) & impl_NamingContext_list
};
static POA_CosNaming_NamingContextExt__vepv impl_NamingContextExt_vepv = {
&impl_NamingContextExt_base_epv,
&impl_NamingContext_epv,
&impl_NamingContextExt_epv
};
CosNaming_NamingContextExt
ORBit_CosNaming_NamingContextExt_create (PortableServer_POA poa,
CORBA_Environment *ev)
{
CosNaming_NamingContext retval;
impl_POA_CosNaming_NamingContextExt *newservant;
PortableServer_ObjectId *objid;
newservant = g_new0 (impl_POA_CosNaming_NamingContextExt, 1);
newservant->servant.vepv = &impl_NamingContextExt_vepv;
newservant->poa = (PortableServer_POA) CORBA_Object_duplicate ((CORBA_Object) poa, ev);
newservant->names =
g_hash_table_new ((GHashFunc) nc_hash, (GCompareFunc) nc_compare);
POA_CosNaming_NamingContextExt__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);
newservant->objref = CORBA_Object_duplicate (retval, ev);
return retval;
}
syntax highlighted by Code2HTML, v. 0.9.1