/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
/*
* bonobo-activation: A library for accessing bonobo-activation-server.
*
* Copyright (C) 1999, 2000 Red Hat, Inc.
* Copyright (C) 2000 Eazel, Inc.
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Author: Elliot Lee <sopwith@redhat.com>
*/
#include <config.h>
#include <string.h>
#include <stdlib.h>
#include <locale.h>
#include <bonobo-activation/bonobo-activation-activate.h>
#include <bonobo-activation/bonobo-activation-init.h>
#include <bonobo-activation/bonobo-activation-server-info.h>
#include <bonobo-activation/bonobo-activation-private.h>
#include <bonobo-activation/bonobo-activation-shlib.h>
#include <bonobo-activation/bonobo-activation-client.h>
#include <bonobo-activation/bonobo-activation-async.h>
#include <glib/gi18n-lib.h>
#include <bonobo-activation/Bonobo_ActivationContext.h>
static Bonobo_ActivationEnvironment *activation_environment = NULL;
/* FIXME: deprecated internal functions. Should we just remove?
*/
void
bonobo_activation_set_test_components_enabled (gboolean val)
{
}
gboolean
bonobo_activation_get_test_components_enabled (void)
{
return FALSE;
}
static void
copy_strv_to_sequence (char *const *selection_order,
Bonobo_StringList *str_seq)
{
int len;
if (!selection_order) {
memset (str_seq, 0, sizeof (Bonobo_StringList));
return;
}
for (len = 0; selection_order [len]; len++);
str_seq->_length = str_seq->_maximum = len;
str_seq->_buffer = (char **) selection_order;
str_seq->_release = FALSE;
}
/* Limit of the number of cached queries */
#define QUERY_CACHE_MAX 32
#undef QUERY_CACHE_DEBUG
static GHashTable *query_cache = NULL;
typedef struct {
char *query;
char **sort_criteria;
Bonobo_ServerInfoList *list;
} QueryCacheEntry;
static void
query_cache_entry_free (gpointer data)
{
QueryCacheEntry *entry = data;
#ifdef QUERY_CACHE_DEBUG
g_message ("Blowing item %p", entry);
#endif /* QUERY_CACHE_DEBUG */
g_free (entry->query);
g_strfreev (entry->sort_criteria);
CORBA_free (entry->list);
g_free (entry);
}
static gboolean
cache_clean_half (gpointer key,
gpointer value,
gpointer user_data)
{
int *a = user_data;
/* Blow half the elements */
return (*a)++ % 2;
}
static gboolean
query_cache_equal (gconstpointer a, gconstpointer b)
{
int i;
char **strsa, **strsb;
const QueryCacheEntry *entrya = a;
const QueryCacheEntry *entryb = b;
if (strcmp (entrya->query, entryb->query))
return FALSE;
strsa = entrya->sort_criteria;
strsb = entryb->sort_criteria;
if (!strsa && !strsb)
return TRUE;
if (!strsa || !strsb)
return FALSE;
for (i = 0; strsa [i] && strsb [i]; i++)
if (strcmp (strsa [i], strsb [i]))
return FALSE;
if (strsa [i] || strsb [i])
return FALSE;
return TRUE;
}
static guint
query_cache_hash (gconstpointer a)
{
guint hash, i;
char **strs;
const QueryCacheEntry *entry = a;
hash = g_str_hash (entry->query);
strs = entry->sort_criteria;
for (i = 0; strs && strs [i]; i++)
hash ^= g_str_hash (strs [i]);
return hash;
}
static void
query_cache_reset (void)
{
if (query_cache) {
g_hash_table_destroy (query_cache);
query_cache = NULL;
}
}
static void
create_query_cache (void)
{
query_cache = g_hash_table_new_full (
query_cache_hash,
query_cache_equal,
query_cache_entry_free,
NULL);
bonobo_activation_add_reset_notify (query_cache_reset);
}
static Bonobo_ServerInfoList *
query_cache_lookup (const char *query,
char * const *sort_criteria,
gboolean *active)
{
QueryCacheEntry fake;
QueryCacheEntry *entry;
Bonobo_ServerInfoList *result;
BONOBO_ACTIVATION_LOCK ();
*active = FALSE;
if (!query_cache) {
create_query_cache ();
BONOBO_ACTIVATION_UNLOCK ();
return NULL;
}
if (strstr (query, "_active")) {
*active = TRUE;
return NULL;
}
fake.query = (char *) query;
fake.sort_criteria = (char **) sort_criteria;
if ((entry = g_hash_table_lookup (query_cache, &fake))) {
#ifdef QUERY_CACHE_DEBUG
g_message ("\n\n --- Hit (%p) ---\n\n\n", entry->list);
#endif /* QUERY_CACHE_DEBUG */
result = Bonobo_ServerInfoList_duplicate (entry->list);
} else {
#ifdef QUERY_CACHE_DEBUG
g_message ("Miss");
#endif /* QUERY_CACHE_DEBUG */
result = NULL;
}
BONOBO_ACTIVATION_UNLOCK ();
return result;
}
static void
query_cache_insert (const char *query,
char * const *sort_criteria,
Bonobo_ServerInfoList *list)
{
int idx = 0;
QueryCacheEntry *entry = g_new (QueryCacheEntry, 1);
if (!query_cache) {
create_query_cache ();
} else if (g_hash_table_size (query_cache) > QUERY_CACHE_MAX) {
g_hash_table_foreach_remove (
query_cache, cache_clean_half, &idx);
}
entry->query = g_strdup (query);
entry->sort_criteria = g_strdupv ((char **) sort_criteria);
entry->list = Bonobo_ServerInfoList_duplicate (list);
g_hash_table_replace (query_cache, entry, entry);
#ifdef QUERY_CACHE_DEBUG
g_message ("Query cache size now %d",
g_hash_table_size (query_cache));
#endif /* QUERY_CACHE_DEBUG */
}
/**
* bonobo_activation_query:
* @requirements: query string.
* @selection_order: sort criterion for returned list.
* @ev: a %CORBA_Environment structure which will contain
* the CORBA exception status of the operation, or NULL
*
* Executes the @requirements query on the bonobo-activation-server.
* The result is sorted according to @selection_order.
* @selection_order can safely be NULL as well as @ev.
* The returned list has to be freed with CORBA_free.
*
* Return value: the list of servers matching the requirements.
*/
Bonobo_ServerInfoList *
bonobo_activation_query (const char *requirements,
char * const *selection_order,
CORBA_Environment *opt_ev)
{
gboolean active;
Bonobo_StringList selorder;
Bonobo_ServerInfoList *retval;
Bonobo_ActivationContext ac;
CORBA_Environment tempenv, *ev;
g_return_val_if_fail (requirements != NULL, CORBA_OBJECT_NIL);
ac = bonobo_activation_activation_context_get ();
g_return_val_if_fail (ac != NULL, CORBA_OBJECT_NIL);
retval = query_cache_lookup (requirements, selection_order, &active);
if (retval)
return retval;
if (!opt_ev) {
CORBA_exception_init (&tempenv);
ev = &tempenv;
} else
ev = opt_ev;
copy_strv_to_sequence (selection_order, &selorder);
retval = Bonobo_ActivationContext_query (
ac, requirements, &selorder,
bonobo_activation_context_get (), ev);
if (ev->_major == CORBA_NO_EXCEPTION) {
if (!active)
query_cache_insert (requirements, selection_order, retval);
} else
retval = NULL;
if (!opt_ev)
CORBA_exception_free (&tempenv);
return retval;
}
static CORBA_Object
handle_activation_result (Bonobo_ActivationResult *result,
Bonobo_ActivationID *ret_aid,
CORBA_Environment *ev)
{
CORBA_Object retval = CORBA_OBJECT_NIL;
switch (result->res._d) {
case Bonobo_ACTIVATION_RESULT_SHLIB:
retval = bonobo_activation_activate_shlib_server (result, ev);
break;
case Bonobo_ACTIVATION_RESULT_OBJECT:
retval = CORBA_Object_duplicate (result->res._u.res_object, ev);
break;
case Bonobo_ACTIVATION_RESULT_NONE:
default:
break;
}
if (ret_aid) {
if (result->aid && result->aid [0])
*ret_aid = g_strdup (result->aid);
else
*ret_aid = NULL;
}
CORBA_free (result);
return retval;
}
/**
* bonobo_activation_activate:
* @requirements: query string.
* @selection_order: sort criterion for returned list.
* @flags: how to activate the object.
* @ret_aid: AID of the activated object.
* @ev: %CORBA_Environment structure which will contain
* the CORBA exception status of the operation.
*
* Activates a given object. @ret_aid can be safely NULLed as well
* as @ev and @selection_order. @flags can be set to zero if you do
* not what to use.
*
* Return value: the CORBA object reference of the activated object.
* This value can be CORBA_OBJECT_NIL: you are supposed
* to check @ev for success.
*/
CORBA_Object
bonobo_activation_activate (const char *requirements,
char *const *selection_order,
Bonobo_ActivationFlags flags,
Bonobo_ActivationID *ret_aid,
CORBA_Environment *opt_ev)
{
Bonobo_ActivationContext ac;
Bonobo_ActivationResult *result;
CORBA_Environment tempenv, *ev;
Bonobo_StringList selorder;
CORBA_Object retval = CORBA_OBJECT_NIL;
g_return_val_if_fail (requirements != NULL, CORBA_OBJECT_NIL);
ac = bonobo_activation_activation_context_get ();
g_return_val_if_fail (ac != NULL, CORBA_OBJECT_NIL);
if (!opt_ev) {
CORBA_exception_init (&tempenv);
ev = &tempenv;
} else
ev = opt_ev;
copy_strv_to_sequence (selection_order, &selorder);
result = Bonobo_ActivationContext_activateMatchingFull
(ac, requirements, &selorder, activation_environment,
flags, bonobo_activation_client_get (),
bonobo_activation_context_get (), ev);
if (ev->_major == CORBA_SYSTEM_EXCEPTION &&
!strcmp (ev->_id, ex_CORBA_BAD_OPERATION)) /* fall-back */
{
g_message ("TESTME: Fall-back activate");
result = Bonobo_ActivationContext_activateMatching
(ac, requirements, &selorder, activation_environment,
flags, bonobo_activation_context_get (), ev);
}
if (ev->_major == CORBA_NO_EXCEPTION)
retval = handle_activation_result (result, ret_aid, ev);
if (!opt_ev)
CORBA_exception_free (&tempenv);
return retval;
}
/**
* bonobo_activation_activate_from_id
* @aid: AID or IID of the object to activate.
* @flags: activation flag.
* @ret_aid: AID of the activated server.
* @ev: %CORBA_Environment structure which will contain
* the CORBA exception status of the operation.
*
* Activates the server corresponding to @aid. @ret_aid can be safely
* NULLed as well as @ev. @flags can be zero if you do not know what
* to do.
*
* Return value: a CORBA object reference to the newly activated
* server. Do not forget to check @ev for failure!!
*/
CORBA_Object
bonobo_activation_activate_from_id (const Bonobo_ActivationID aid,
Bonobo_ActivationFlags flags,
Bonobo_ActivationID *ret_aid,
CORBA_Environment *opt_ev)
{
Bonobo_ActivationContext ac;
Bonobo_ActivationResult *result;
CORBA_Environment *ev, tempenv;
CORBA_Object retval = CORBA_OBJECT_NIL;
g_return_val_if_fail (aid != NULL, CORBA_OBJECT_NIL);
if (!strncmp ("OAFIID:", aid, 7)) {
char *requirements;
requirements = g_alloca (strlen (aid) + sizeof ("iid == ''"));
sprintf (requirements, "iid == '%s'", aid);
return bonobo_activation_activate (
requirements, NULL, flags, ret_aid, opt_ev);
}
if (!opt_ev) {
CORBA_exception_init (&tempenv);
ev = &tempenv;
} else
ev = opt_ev;
ac = bonobo_activation_internal_activation_context_get_extended (
(flags & Bonobo_ACTIVATION_FLAG_EXISTING_ONLY), ev);
if (!ac) {
if (!opt_ev)
CORBA_exception_free (&tempenv);
return CORBA_OBJECT_NIL;
}
result = Bonobo_ActivationContext_activateFromAidFull
(ac, aid, flags, bonobo_activation_client_get (),
bonobo_activation_context_get (), ev);
if (ev->_major == CORBA_SYSTEM_EXCEPTION &&
!strcmp (ev->_id, ex_CORBA_BAD_OPERATION)) /* fall-back */
result = Bonobo_ActivationContext_activateFromAid
(ac, aid, flags, bonobo_activation_context_get (), ev);
if (ev->_major == CORBA_NO_EXCEPTION)
retval = handle_activation_result (result, ret_aid, ev);
if (!opt_ev)
CORBA_exception_free (&tempenv);
return retval;
}
/* Async activation
*/
#define ASYNC_ERROR_NO_AID (_("No ActivationID supplied"))
#define ASYNC_ERROR_NO_REQUIREMENTS (_("No requirements supplied"))
#define ASYNC_ERROR_NO_CONTEXT (_("Failed to initialise the ActivationContext"))
#define ASYNC_ERROR_INV_FAILED (_("Failed to invoke method on the ActivationContext"))
#define ASYNC_ERROR_GENERAL_EXCEPTION (_("System exception: %s : %s"))
#define ASYNC_ERROR_EXCEPTION (_("System exception: %s"))
static ORBit_IMethod *activate_matching_full_method = NULL;
static ORBit_IMethod *activate_from_aid_full_method = NULL;
typedef struct {
BonoboActivationCallback user_cb;
gpointer user_data;
} AsyncActivationData;
static void
setup_methods (void)
{
activate_matching_full_method = &Bonobo_ActivationContext__iinterface.methods._buffer [7];
activate_from_aid_full_method = &Bonobo_ActivationContext__iinterface.methods._buffer [9];
/* If these blow the IDL changed order, and the above
indexes need updating */
g_assert (!strcmp (activate_matching_full_method->name, "activateMatchingFull"));
g_assert (!strcmp (activate_from_aid_full_method->name, "activateFromAidFull"));
}
static void
activation_async_callback (CORBA_Object object,
ORBit_IMethod *m_data,
ORBitAsyncQueueEntry *aqe,
gpointer user_data,
CORBA_Environment *ev)
{
Bonobo_ActivationResult *result = NULL;
AsyncActivationData *async_data = user_data;
Bonobo_GeneralError *err;
CORBA_Object retval;
char *reason = NULL;
g_return_if_fail (async_data != NULL);
g_return_if_fail (async_data->user_cb != NULL);
if (ev->_major != CORBA_NO_EXCEPTION)
goto return_exception;
ORBit_small_demarshal_async (aqe, &result, NULL, ev);
if (ev->_major != CORBA_NO_EXCEPTION)
goto return_exception;
retval = handle_activation_result (result, NULL, ev);
if (ev->_major != CORBA_NO_EXCEPTION)
goto return_exception;
async_data->user_cb (retval, NULL, async_data->user_data);
clean_out:
g_free (async_data);
return;
return_exception:
if (!strcmp (ev->_id, "IDL:Bonobo/GeneralError:1.0")) {
err = ev->_any._value;
if (!err || !err->description)
reason = g_strdup_printf (ASYNC_ERROR_GENERAL_EXCEPTION,
ev->_id, "(no description)");
else
reason = g_strdup_printf (ASYNC_ERROR_GENERAL_EXCEPTION,
ev->_id, err->description);
} else
reason = g_strdup_printf (ASYNC_ERROR_EXCEPTION, ev->_id);
async_data->user_cb (CORBA_OBJECT_NIL, reason, async_data->user_data);
g_free (reason);
goto clean_out;
}
/**
* bonobo_activation_activate_async:
* @requirements: the bonobo-activation query string.
* @selection_order: preference array.
* @flags: activation flags.
* @callback: callback function.
* @user_data: data to be poassed to the callback function.
* @ev: exception structure.
*
* This function will asynchronously try to activate a component
* given the @requirements query string. When the component is
* activated or when the activation fails, it will call @callback
* with the given @user_data data as parameter.
* callback will be called with a CORBA_OBJECT_NIL object if the
* activation fails. If the activation fails, the callback will be
* given a human-readable string containing a description of the
* error. In case of sucess, the error string value is undefined.
*
* @selection_order can be safely NULLed as well as @ev and
* @user_data. @flags can be set to 0 if you do not know what to
* use.
*/
void
bonobo_activation_activate_async (const char *requirements,
char *const *selection_order,
Bonobo_ActivationFlags flags,
BonoboActivationCallback async_cb,
gpointer user_data,
CORBA_Environment *opt_ev)
{
Bonobo_ActivationContext ac;
AsyncActivationData *async_data;
CORBA_Environment *ev, tempenv;
Bonobo_StringList selorder;
Bonobo_ActivationClient client;
gpointer args [5];
if (!requirements) {
async_cb (CORBA_OBJECT_NIL, ASYNC_ERROR_NO_REQUIREMENTS, user_data);
return;
}
ac = bonobo_activation_activation_context_get ();
if (!ac) {
async_cb (CORBA_OBJECT_NIL, ASYNC_ERROR_NO_CONTEXT, user_data);
return;
}
if (!opt_ev) {
CORBA_exception_init (&tempenv);
ev = &tempenv;
} else
ev = opt_ev;
async_data = g_new (AsyncActivationData, 1);
async_data->user_cb = async_cb;
async_data->user_data = user_data;
copy_strv_to_sequence (selection_order, &selorder);
client = bonobo_activation_client_get ();
args [0] = &requirements;
args [1] = &selorder;
args [2] = activation_environment;
args [3] = &flags;
args [4] = &client;
if (!activate_matching_full_method)
setup_methods ();
ORBit_small_invoke_async (ac, activate_matching_full_method,
activation_async_callback, async_data,
args, bonobo_activation_context_get (), ev);
if (ev->_major != CORBA_NO_EXCEPTION) {
async_cb (CORBA_OBJECT_NIL, ASYNC_ERROR_INV_FAILED, user_data);
g_free (async_data);
}
if (!opt_ev)
CORBA_exception_free (&tempenv);
return;
}
/**
* bonobo_activation_activate_from_id_async:
* @aid: the AID or IID of the component to activate.
* @flags: activation flags.
* @callback: callback function.
* @user_data: data to be poassed to the callback function.
* @ev: exception structure.
*
* This function will asynchronously try to activate a component
* with the given @aid. When the component is
* activated or when the activation fails, it will call @callback
* with the given @user_data data as parameter.
* callback will be called with a CORBA_OBJECT_NIL object if the
* activation fails. If the activation fails, the callback will be
* given a human-readable string containing a description of the
* error. In case of sucess, the error string value is undefined.
*
* @flags can be 0 if you do not know what to set it to and
* @ev can be safely set to NULL.
*/
void
bonobo_activation_activate_from_id_async (const Bonobo_ActivationID aid,
Bonobo_ActivationFlags flags,
BonoboActivationCallback async_cb,
gpointer user_data,
CORBA_Environment *opt_ev)
{
Bonobo_ActivationContext ac;
AsyncActivationData *async_data;
CORBA_Environment *ev, tempenv;
Bonobo_ActivationClient client;
gpointer args [3];
if (!aid) {
async_cb (CORBA_OBJECT_NIL, ASYNC_ERROR_NO_AID, user_data);
return;
}
if (!strncmp ("OAFIID:", aid, 7)) {
char *requirements;
requirements = g_alloca (strlen (aid) + sizeof ("iid == ''"));
sprintf (requirements, "iid == '%s'", aid);
bonobo_activation_activate_async (
requirements, NULL, flags, async_cb, user_data, opt_ev);
return;
}
if (!opt_ev) {
CORBA_exception_init (&tempenv);
ev = &tempenv;
} else
ev = opt_ev;
ac = bonobo_activation_internal_activation_context_get_extended (
(flags & Bonobo_ACTIVATION_FLAG_EXISTING_ONLY), ev);
if (!ac) {
if (!opt_ev)
CORBA_exception_free (&tempenv);
async_cb (CORBA_OBJECT_NIL, ASYNC_ERROR_NO_CONTEXT, user_data);
return;
}
async_data = g_new (AsyncActivationData, 1);
async_data->user_cb = async_cb;
async_data->user_data = user_data;
if (!activate_from_aid_full_method)
setup_methods ();
client = bonobo_activation_client_get ();
args [0] = (gpointer) &aid;
args [1] = &flags;
args [2] = &client;
ORBit_small_invoke_async (ac, activate_from_aid_full_method,
activation_async_callback, async_data,
args, bonobo_activation_context_get (), ev);
if (ev->_major != CORBA_NO_EXCEPTION) {
async_cb (CORBA_OBJECT_NIL, ASYNC_ERROR_INV_FAILED, user_data);
g_free (async_data);
}
if (!opt_ev)
CORBA_exception_free (&tempenv);
return;
}
void
bonobo_activation_init_activation_env (void)
{
int i;
struct {
const char *name;
const char *value;
} getenv_values[] = {
#ifndef G_OS_WIN32
{ "DISPLAY", NULL }, /* X display */
{ "SESSION_MANAGER", NULL }, /* XSMP session manager */
{ "AUDIODEV", NULL }, /* Audio device on Sun systems */
{ "XAUTHORITY", NULL },
{ "LC_ALL", NULL }, /* locale information: see setlocale(3) */
{ "LC_COLLATE", NULL },
{ "LC_MESSAGES", NULL },
{ "LC_MONETARY", NULL },
{ "LC_NUMERIC", NULL },
{ "LC_TIME", NULL },
#endif
{ "LANG", NULL }, /* Fallback locale name */
{ NULL, NULL }
};
g_assert (activation_environment == NULL);
activation_environment = Bonobo_ActivationEnvironment__alloc ();
for (i = 0; getenv_values [i].name; i++) {
getenv_values [i].value = getenv (getenv_values [i].name);
if (!getenv_values [i].value)
continue;
Bonobo_ActivationEnvValue value = {
(CORBA_char *) getenv_values [i].name,
(CORBA_char *) getenv_values [i].value,
0 /* flags */ };
ORBit_sequence_append (activation_environment, &value);
}
}
void
bonobo_activation_set_activation_env_value (const char *name,
const char *value)
{
int i;
Bonobo_ActivationEnvValue env_value = { (CORBA_char *) name, (CORBA_char *) value, 0 };
g_return_if_fail (name != NULL);
for (i = 0; i < activation_environment->_length; i++) {
if (!strcmp (activation_environment->_buffer [i].name, name)) {
ORBit_sequence_remove (activation_environment, i);
break;
}
}
ORBit_sequence_append (activation_environment, &env_value);
}
CORBA_char *
_bonobo_activation_get_activation_env_value (const char *name)
{
int i;
g_return_val_if_fail (name != NULL, NULL);
for (i = 0; i < activation_environment->_length; i++) {
if (strcmp (activation_environment->_buffer [i].name, name) == 0) {
return activation_environment->_buffer [i].value;
}
}
return NULL;
}
/**
* bonobo_activation_name_service_get:
* @ev: %CORBA_Environment structure which will contain
* the CORBA exception status of the operation.
*
* Returns the name server of bonobo-activation. @ev can be NULL.
*
* Return value: the name server of bonobo-activation.
*/
CORBA_Object
bonobo_activation_name_service_get (CORBA_Environment * ev)
{
return bonobo_activation_activate_from_id (
"OAFIID:Bonobo_CosNaming_NamingContext", 0, NULL, ev);
}
/**
* bonobo_activation_dynamic_add_path:
* @add_path: The path would be loaded in runtime.
* @ev: %CORBA_Environment structure which will contain
* the CORBA exception status of the operation.
* This function could make BAS server load the specific
* search path in runtime.
*
* Return value: a result of dynamic path load
*/
Bonobo_DynamicPathLoadResult
bonobo_activation_dynamic_add_path (const char *add_path,
CORBA_Environment * ev)
{
Bonobo_ObjectDirectory od;
Bonobo_DynamicPathLoadResult res;
g_return_val_if_fail (add_path != NULL, Bonobo_DYNAMIC_LOAD_ERROR);
od = bonobo_activation_object_directory_get (
bonobo_activation_username_get (),
bonobo_activation_hostname_get ());
if (CORBA_Object_is_nil (od, ev))
return Bonobo_DYNAMIC_LOAD_ERROR;
res = Bonobo_ObjectDirectory_dynamic_add_path(od, add_path, ev);
if (ev->_major != CORBA_NO_EXCEPTION)
return Bonobo_DYNAMIC_LOAD_ERROR;
return res;
}
/**
* bonobo_activation_dynamic_remove_path:
* @remove_path: The path would be unloaded in runtime.
* @ev: %CORBA_Environment structure which will contain
* the CORBA exception status of the operation.
* This function could make BAS server unload the specific
* search path in runtime.
*
* Return value: a result of dynamic path load
*/
Bonobo_DynamicPathLoadResult
bonobo_activation_dynamic_remove_path (const char *remove_path,
CORBA_Environment * ev)
{
Bonobo_ObjectDirectory od;
Bonobo_DynamicPathLoadResult res;
g_return_val_if_fail (remove_path != NULL, Bonobo_DYNAMIC_LOAD_ERROR);
od = bonobo_activation_object_directory_get (
bonobo_activation_username_get (),
bonobo_activation_hostname_get ());
if (CORBA_Object_is_nil (od, ev))
return Bonobo_DYNAMIC_LOAD_ERROR;
res = Bonobo_ObjectDirectory_dynamic_remove_path(od, remove_path, ev);
if (ev->_major != CORBA_NO_EXCEPTION)
return Bonobo_DYNAMIC_LOAD_ERROR;
return res;
}
syntax highlighted by Code2HTML, v. 0.9.1