source: trunk/third/bonobo-activation/bonobo-activation/bonobo-activation-activate.c @ 18563

Revision 18563, 22.6 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18562, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2/*
3 *  bonobo-activation: A library for accessing bonobo-activation-server.
4 *
5 *  Copyright (C) 1999, 2000 Red Hat, Inc.
6 *  Copyright (C) 2000 Eazel, Inc.
7 *
8 *  This library is free software; you can redistribute it and/or
9 *  modify it under the terms of the GNU Library General Public
10 *  License as published by the Free Software Foundation; either
11 *  version 2 of the License, or (at your option) any later version.
12 *
13 *  This library is distributed in the hope that it will be useful,
14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 *  Library General Public License for more details.
17 *
18 *  You should have received a copy of the GNU Library General Public
19 *  License along with this library; if not, write to the Free
20 *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 *  Author: Elliot Lee <sopwith@redhat.com>
23 */
24#include <config.h>
25#include <string.h>
26#include <stdlib.h>
27#include <locale.h>
28
29#include <bonobo-activation/bonobo-activation-activate.h>
30
31#include <bonobo-activation/bonobo-activation-id.h>
32#include <bonobo-activation/bonobo-activation-init.h>
33#include <bonobo-activation/bonobo-activation-server-info.h>
34#include <bonobo-activation/bonobo-activation-private.h>
35#include <bonobo-activation/bonobo-activation-shlib.h>
36#include <bonobo-activation/bonobo-activation-client.h>
37#include <bonobo-activation/bonobo-activation-async.h>
38#include <bonobo-activation/bonobo-activation-i18n.h>
39#include <bonobo-activation/Bonobo_ActivationContext.h>
40
41static Bonobo_ActivationEnvironment activation_environment;
42
43/* FIXME: deprecated internal functions. Should we just remove?
44 */
45void
46bonobo_activation_set_test_components_enabled (gboolean val)
47{
48}
49
50gboolean
51bonobo_activation_get_test_components_enabled (void)
52{
53        return FALSE;
54}
55
56static void
57copy_strv_to_sequence (char *const       *selection_order,
58                       Bonobo_StringList *str_seq)
59{
60        int len;
61
62        if (!selection_order) {
63                memset (str_seq, 0, sizeof (Bonobo_StringList));
64                return;
65        }
66
67        for (len = 0; selection_order [len]; len++);
68
69        str_seq->_length  = str_seq->_maximum = len;
70        str_seq->_buffer  = (char **) selection_order;
71        str_seq->_release = FALSE;
72}
73
74/* Limit of the number of cached queries */
75#define QUERY_CACHE_MAX 32
76#undef QUERY_CACHE_DEBUG
77
78static GHashTable *query_cache = NULL;
79
80typedef struct {
81        char  *query;
82        char **sort_criteria;
83
84        Bonobo_ServerInfoList *list;
85} QueryCacheEntry;
86
87static void
88query_cache_entry_free (gpointer data)
89{
90        QueryCacheEntry *entry = data;
91
92#ifdef QUERY_CACHE_DEBUG
93        g_warning ("Blowing item %p", entry);
94#endif /* QUERY_CACHE_DEBUG */
95
96        g_free (entry->query);
97        g_strfreev (entry->sort_criteria);
98        CORBA_free (entry->list);
99        g_free (entry);
100}
101
102static gboolean
103cache_clean_half (gpointer  key,
104                  gpointer  value,
105                  gpointer  user_data)
106{
107        int *a = user_data;
108        /* Blow half the elements */
109        return (*a)++ % 2;
110}
111
112static gboolean
113query_cache_equal (gconstpointer a, gconstpointer b)
114{
115        int i;
116        char **strsa, **strsb;
117        const QueryCacheEntry *entrya = a;
118        const QueryCacheEntry *entryb = b;
119
120        if (strcmp (entrya->query, entryb->query))
121                return FALSE;
122
123        strsa = entrya->sort_criteria;
124        strsb = entryb->sort_criteria;
125
126        if (!strsa && !strsb)
127                return TRUE;
128
129        if (!strsa || !strsb)
130                return FALSE;
131
132        for (i = 0; strsa [i] && strsb [i]; i++)
133                if (strcmp (strsa [i], strsb [i]))
134                        return FALSE;
135
136        if (strsa [i] || strsb [i])
137                return FALSE;
138
139        return TRUE;
140}
141
142static guint
143query_cache_hash (gconstpointer a)
144{
145        guint hash, i;
146        char **strs;
147        const QueryCacheEntry *entry = a;
148       
149        hash = g_str_hash (entry->query);
150        strs = entry->sort_criteria;
151
152        for (i = 0; strs && strs [i]; i++)
153                hash ^= g_str_hash (strs [i]);
154
155        return hash;
156}
157
158static void
159query_cache_reset (void)
160{
161        if (query_cache) {
162                g_hash_table_destroy (query_cache);
163                query_cache = NULL;
164        }
165}
166
167static void
168create_query_cache (void)
169{
170        query_cache = g_hash_table_new_full (
171                query_cache_hash,
172                query_cache_equal,
173                query_cache_entry_free,
174                NULL);
175        bonobo_activation_add_reset_notify (query_cache_reset);
176}
177
178static Bonobo_ServerInfoList *
179query_cache_lookup (const char   *query,
180                    char * const *sort_criteria)
181{
182        QueryCacheEntry  fake;
183        QueryCacheEntry *entry;
184
185        if (!query_cache) {
186                create_query_cache ();
187                return NULL;
188        }
189
190        fake.query = (char *) query;
191        fake.sort_criteria = (char **) sort_criteria;
192        if ((entry = g_hash_table_lookup (query_cache, &fake))) {
193#ifdef QUERY_CACHE_DEBUG
194                g_warning ("\n\n ---  Hit (%p)  ---\n\n\n", entry->list);
195#endif /* QUERY_CACHE_DEBUG */
196                return Bonobo_ServerInfoList_duplicate (entry->list);
197        } else {
198#ifdef QUERY_CACHE_DEBUG
199                g_warning ("Miss");
200#endif /* QUERY_CACHE_DEBUG */
201                return NULL;
202        }
203}
204
205static void
206query_cache_insert (const char   *query,
207                    char * const *sort_criteria,
208                    Bonobo_ServerInfoList *list)
209{
210        int idx = 0;
211        QueryCacheEntry *entry = g_new (QueryCacheEntry, 1);
212
213        if (!query_cache) {
214                create_query_cache ();
215       
216        } else if (g_hash_table_size (query_cache) > QUERY_CACHE_MAX) {
217                g_hash_table_foreach_remove (
218                        query_cache, cache_clean_half, &idx);
219        }
220
221        entry->query = g_strdup (query);
222        entry->sort_criteria = g_strdupv ((char **) sort_criteria);
223        entry->list = Bonobo_ServerInfoList_duplicate (list);
224
225        g_hash_table_replace (query_cache, entry, entry);
226
227#ifdef QUERY_CACHE_DEBUG
228        g_warning ("Query cache size now %d",
229                g_hash_table_size (query_cache));
230#endif /* QUERY_CACHE_DEBUG */
231}
232
233/**
234 * bonobo_activation_query:
235 * @requirements: query string.
236 * @selection_order: sort criterion for returned list.
237 * @ev: a %CORBA_Environment structure which will contain
238 *      the CORBA exception status of the operation, or NULL
239 *
240 * Executes the @requirements query on the bonobo-activation-server.
241 * The result is sorted according to @selection_order.
242 * @selection_order can safely be NULL as well as @ev.
243 * The returned list has to be freed with CORBA_free.
244 *
245 * Return value: the list of servers matching the requirements.
246 */
247Bonobo_ServerInfoList *
248bonobo_activation_query (const char        *requirements,
249                         char * const      *selection_order,
250                         CORBA_Environment *opt_ev)
251{
252        Bonobo_StringList         selorder;
253        Bonobo_ServerInfoList    *retval;
254        Bonobo_ActivationContext  ac;
255        CORBA_Environment         tempenv, *ev;
256
257        g_return_val_if_fail (requirements != NULL, CORBA_OBJECT_NIL);
258
259        ac = bonobo_activation_activation_context_get ();
260        g_return_val_if_fail (ac != NULL, CORBA_OBJECT_NIL);
261
262        retval = query_cache_lookup (requirements, selection_order);
263        if (retval)
264                return retval;
265
266        if (!opt_ev) {
267                CORBA_exception_init (&tempenv);
268                ev = &tempenv;
269        } else
270                ev = opt_ev;
271
272        copy_strv_to_sequence (selection_order, &selorder);
273
274        retval = Bonobo_ActivationContext_query (
275                ac, requirements, &selorder,
276                bonobo_activation_context_get (), ev);
277
278        if (ev->_major == CORBA_NO_EXCEPTION)
279                query_cache_insert (requirements, selection_order, retval);
280        else
281                retval = NULL;
282
283        if (!opt_ev)
284                CORBA_exception_free (&tempenv);
285
286        return retval;
287}
288
289static CORBA_Object
290handle_activation_result (Bonobo_ActivationResult *result,
291                          Bonobo_ActivationID     *ret_aid,
292                          CORBA_Environment       *ev)
293{
294        CORBA_Object retval = CORBA_OBJECT_NIL;
295
296        switch (result->res._d) {
297        case Bonobo_ACTIVATION_RESULT_SHLIB:
298                retval = bonobo_activation_activate_shlib_server (result, ev);
299                break;
300        case Bonobo_ACTIVATION_RESULT_OBJECT:
301                retval = CORBA_Object_duplicate (result->res._u.res_object, ev);
302                break;
303        case Bonobo_ACTIVATION_RESULT_NONE:
304        default:
305                break;
306        }
307
308        if (ret_aid) {
309                if (result->aid && result->aid [0])
310                        *ret_aid = g_strdup (result->aid);
311                else
312                        *ret_aid = NULL;
313        }
314
315        CORBA_free (result);
316
317        return retval;
318}
319
320/**
321 * bonobo_activation_activate:
322 * @requirements: query string.
323 * @selection_order: sort criterion for returned list.
324 * @flags: how to activate the object.
325 * @ret_aid: AID of the activated object.
326 * @ev: %CORBA_Environment structure which will contain
327 *      the CORBA exception status of the operation.
328 *
329 * Activates a given object. @ret_aid can be safely NULLed as well
330 * as @ev and @selection_order. @flags can be set to zero if you do
331 * not what to use.
332 *
333 * Return value: the CORBA object reference of the activated object.
334 *               This value can be CORBA_OBJECT_NIL: you are supposed
335 *               to check @ev for success.
336 */
337CORBA_Object
338bonobo_activation_activate (const char             *requirements,
339                            char *const            *selection_order,
340                            Bonobo_ActivationFlags  flags,
341                            Bonobo_ActivationID    *ret_aid,
342                            CORBA_Environment      *opt_ev)
343{
344        Bonobo_ActivationContext  ac;
345        Bonobo_ActivationResult  *result;
346        CORBA_Environment         tempenv, *ev;
347        Bonobo_StringList         selorder;
348        CORBA_Object              retval = CORBA_OBJECT_NIL;
349
350        g_return_val_if_fail (requirements != NULL, CORBA_OBJECT_NIL);
351
352        ac = bonobo_activation_activation_context_get ();
353        g_return_val_if_fail (ac != NULL, CORBA_OBJECT_NIL);
354
355        if (!opt_ev) {
356                CORBA_exception_init (&tempenv);
357                ev = &tempenv;
358        } else
359                ev = opt_ev;
360
361        copy_strv_to_sequence (selection_order, &selorder);
362
363        result = Bonobo_ActivationContext_activateMatching (
364                        ac, requirements, &selorder, &activation_environment,
365                        flags, bonobo_activation_context_get (), ev);
366
367        if (ev->_major == CORBA_NO_EXCEPTION)
368                retval = handle_activation_result (result, ret_aid, ev);
369
370        if (!opt_ev)
371                CORBA_exception_free (&tempenv);
372
373        return retval;
374}
375
376/**
377 * bonobo_activation_activate_from_id
378 * @aid: AID or IID of the object to activate.
379 * @flags: activation flag.
380 * @ret_aid: AID of the activated server.
381 * @ev: %CORBA_Environment structure which will contain
382 *      the CORBA exception status of the operation.
383 *
384 * Activates the server corresponding to @aid. @ret_aid can be safely
385 * NULLed as well as @ev. @flags can be zero if you do not know what
386 * to do.
387 *
388 * Return value: a CORBA object reference to the newly activated
389 *               server. Do not forget to check @ev for failure!!
390 */
391CORBA_Object
392bonobo_activation_activate_from_id (const Bonobo_ActivationID aid,
393                                    Bonobo_ActivationFlags    flags,
394                                    Bonobo_ActivationID      *ret_aid,
395                                    CORBA_Environment        *opt_ev)
396{
397        Bonobo_ActivationContext  ac;
398        Bonobo_ActivationResult  *result;
399        CORBA_Environment        *ev, tempenv;
400        CORBA_Object              retval = CORBA_OBJECT_NIL;
401
402        g_return_val_if_fail (aid != NULL, CORBA_OBJECT_NIL);
403
404        if (!strncmp ("OAFIID:", aid, 7)) {
405                char *requirements;
406
407                requirements = g_alloca (strlen (aid) + sizeof ("iid == ''"));
408                sprintf (requirements, "iid == '%s'", aid);
409
410                return bonobo_activation_activate (
411                                requirements, NULL, flags, ret_aid, opt_ev);
412        }
413       
414        if (!opt_ev) {
415                CORBA_exception_init (&tempenv);
416                ev = &tempenv;
417        } else
418                ev = opt_ev;
419
420        ac = bonobo_activation_internal_activation_context_get_extended (
421                                (flags & Bonobo_ACTIVATION_FLAG_EXISTING_ONLY), ev);
422        if (!ac) {
423                if (!opt_ev)
424                        CORBA_exception_free (&tempenv);
425
426                return CORBA_OBJECT_NIL;
427        }
428
429        result = Bonobo_ActivationContext_activateFromAid (
430                        ac, aid, flags, bonobo_activation_context_get (), ev);
431
432        if (ev->_major == CORBA_NO_EXCEPTION)
433                retval = handle_activation_result (result, ret_aid, ev);
434       
435        if (!opt_ev)
436                CORBA_exception_free (&tempenv);
437
438        return retval;
439}
440
441/* Async activation
442 */
443
444#define ASYNC_ERROR_NO_AID            (_("No ActivationID supplied"))
445#define ASYNC_ERROR_NO_REQUIREMENTS   (_("No requirements supplied"))
446#define ASYNC_ERROR_NO_CONTEXT        (_("Failed to initialise the AcitvationContext"))
447#define ASYNC_ERROR_INV_FAILED        (_("Failed to invoke method on the AcitvationContext"))
448#define ASYNC_ERROR_GENERAL_EXCEPTION (_("System exception: %s : %s"))
449#define ASYNC_ERROR_EXCEPTION         (_("System exception: %s"))
450
451static ORBit_IMethod *activate_matching_method = NULL;
452static ORBit_IMethod *activate_from_aid_method = NULL;
453
454typedef struct {
455        BonoboActivationCallback user_cb;
456        gpointer                 user_data;
457} AsyncActivationData;
458
459static void
460setup_methods (void)
461{
462        activate_matching_method = &Bonobo_ActivationContext__iinterface.methods._buffer [6];
463        activate_from_aid_method = &Bonobo_ActivationContext__iinterface.methods._buffer [7];
464
465        /* If these blow the IDL changed order, and the above
466           indexes need updating */
467        g_assert (!strcmp (activate_matching_method->name, "activateMatching"));
468        g_assert (!strcmp (activate_from_aid_method->name, "activateFromAid"));
469}
470
471static void
472activation_async_callback (CORBA_Object          object,
473                           ORBit_IMethod        *m_data,
474                           ORBitAsyncQueueEntry *aqe,
475                           gpointer              user_data,
476                           CORBA_Environment    *ev)
477{
478        Bonobo_ActivationResult *result = NULL;
479        AsyncActivationData     *async_data = user_data;
480        Bonobo_GeneralError     *err;
481        CORBA_Object             retval;
482        char                    *reason = NULL;
483
484        g_return_if_fail (async_data != NULL);
485        g_return_if_fail (async_data->user_cb != NULL);
486
487        if (ev->_major != CORBA_NO_EXCEPTION)
488                goto return_exception;
489
490        ORBit_small_demarshal_async (aqe, &result, NULL, ev);
491
492        if (ev->_major != CORBA_NO_EXCEPTION)
493                goto return_exception;
494
495        retval = handle_activation_result (result, NULL, ev);
496
497        if (ev->_major != CORBA_NO_EXCEPTION)
498                goto return_exception;
499
500        async_data->user_cb (retval, NULL, async_data->user_data);
501
502clean_out:
503        g_free (async_data);
504        return;
505
506return_exception:
507        if (!strcmp (ev->_id, "IDL:Bonobo/GeneralError:1.0")) {
508                err = ev->_any._value;
509
510                if (!err || !err->description)
511                        reason = g_strdup_printf (ASYNC_ERROR_GENERAL_EXCEPTION,
512                                                  ev->_id, "(no description)");
513                else
514                        reason = g_strdup_printf (ASYNC_ERROR_GENERAL_EXCEPTION,
515                                                  ev->_id, err->description);
516        } else
517                reason = g_strdup_printf (ASYNC_ERROR_EXCEPTION, ev->_id);
518
519        async_data->user_cb (CORBA_OBJECT_NIL, reason, async_data->user_data);
520        g_free (reason);
521
522        goto clean_out;
523}
524
525/**
526 * bonobo_activation_activate_async:
527 * @requirements: the bonobo-activation query string.
528 * @selection_order: preference array.
529 * @flags: activation flags.
530 * @callback: callback function.
531 * @user_data: data to be poassed to the callback function.
532 * @ev: exception structure.
533 *
534 * This function will asynchronously try to activate a component
535 * given the @requirements query string. When the component is
536 * activated or when the activation fails, it will call @callback
537 * with the given @user_data data as parameter.
538 * callback will be called with a CORBA_OBJECT_NIL object if the
539 * activation fails. If the activation fails, the callback will be
540 * given a human-readable string containing a description of the
541 * error. In case of sucess, the error string value is undefined.
542 *
543 * @selection_order can be safely NULLed as well as @ev and
544 * @user_data. @flags can be set to 0 if you do not know what to
545 * use.
546 */
547void
548bonobo_activation_activate_async (const char               *requirements,
549                                  char *const              *selection_order,
550                                  Bonobo_ActivationFlags    flags,
551                                  BonoboActivationCallback  async_cb,
552                                  gpointer                  user_data,
553                                  CORBA_Environment        *opt_ev)
554{
555        Bonobo_ActivationContext  ac;
556        AsyncActivationData      *async_data;
557        CORBA_Environment        *ev, tempenv;
558        Bonobo_StringList         selorder;
559        gpointer                  args [4];
560
561        if (!requirements) {
562                async_cb (CORBA_OBJECT_NIL, ASYNC_ERROR_NO_REQUIREMENTS, user_data);
563                return;
564        }
565
566        ac = bonobo_activation_activation_context_get ();
567        if (!ac) {
568                async_cb (CORBA_OBJECT_NIL, ASYNC_ERROR_NO_CONTEXT, user_data);
569                return;
570        }
571
572        if (!opt_ev) {
573                CORBA_exception_init (&tempenv);
574                ev = &tempenv;
575        } else
576                ev = opt_ev;
577
578        async_data = g_new (AsyncActivationData, 1);
579        async_data->user_cb   = async_cb;
580        async_data->user_data = user_data;
581
582        copy_strv_to_sequence (selection_order, &selorder);
583
584        args [0] = &requirements;
585        args [1] = &selorder;
586        args [2] = &activation_environment;
587        args [3] = &flags;
588
589        if (!activate_matching_method)
590                setup_methods ();
591
592        ORBit_small_invoke_async (ac, activate_matching_method,
593                                  activation_async_callback, async_data,
594                                  args, bonobo_activation_context_get (), ev);
595
596        if (ev->_major != CORBA_NO_EXCEPTION) {
597                async_cb (CORBA_OBJECT_NIL, ASYNC_ERROR_INV_FAILED, user_data);
598                g_free (async_data);
599        }
600
601        if (!opt_ev)
602                CORBA_exception_free (&tempenv);
603
604        return;
605}
606
607/**
608 * bonobo_activation_activate_from_id_async:
609 * @aid: the AID or IID of the component to activate.
610 * @flags: activation flags.
611 * @callback: callback function.
612 * @user_data: data to be poassed to the callback function.
613 * @ev: exception structure.
614 *
615 * This function will asynchronously try to activate a component
616 * with the given @aid. When the component is
617 * activated or when the activation fails, it will call @callback
618 * with the given @user_data data as parameter.
619 * callback will be called with a CORBA_OBJECT_NIL object if the
620 * activation fails. If the activation fails, the callback will be
621 * given a human-readable string containing a description of the
622 * error. In case of sucess, the error string value is undefined.
623 *
624 * @flags can be 0 if you do not know what to set it to and
625 * @ev can be safely set to NULL.
626 */
627void
628bonobo_activation_activate_from_id_async (const Bonobo_ActivationID  aid,
629                                          Bonobo_ActivationFlags     flags,
630                                          BonoboActivationCallback   async_cb,
631                                          gpointer                   user_data,
632                                          CORBA_Environment         *opt_ev)
633{
634        Bonobo_ActivationContext  ac;
635        AsyncActivationData      *async_data;
636        CORBA_Environment        *ev, tempenv;
637        gpointer                  args [2];
638
639        if (!aid) {
640                async_cb (CORBA_OBJECT_NIL, ASYNC_ERROR_NO_AID, user_data);
641                return;
642        }
643
644        if (!strncmp ("OAFIID:", aid, 7)) {
645                char *requirements;
646
647                requirements = g_alloca (strlen (aid) + sizeof ("iid == ''"));
648                sprintf (requirements, "iid == '%s'", aid);
649
650                bonobo_activation_activate_async (
651                        requirements, NULL, flags, async_cb, user_data, opt_ev);
652                return;
653        }
654       
655        if (!opt_ev) {
656                CORBA_exception_init (&tempenv);
657                ev = &tempenv;
658        } else
659                ev = opt_ev;
660
661        ac = bonobo_activation_internal_activation_context_get_extended (
662                                (flags & Bonobo_ACTIVATION_FLAG_EXISTING_ONLY), ev);
663        if (!ac) {
664                if (!opt_ev)
665                        CORBA_exception_free (&tempenv);
666
667                async_cb (CORBA_OBJECT_NIL, ASYNC_ERROR_NO_CONTEXT, user_data);
668                return;
669        }
670
671        async_data = g_new (AsyncActivationData, 1);
672        async_data->user_cb   = async_cb;
673        async_data->user_data = user_data;
674
675        if (!activate_from_aid_method)
676                setup_methods ();
677
678        args [0] = (gpointer) &aid;
679        args [1] = &flags;
680
681        ORBit_small_invoke_async (ac, activate_from_aid_method,
682                                  activation_async_callback, async_data,
683                                  args, bonobo_activation_context_get (), ev);
684
685        if (ev->_major != CORBA_NO_EXCEPTION) {
686                async_cb (CORBA_OBJECT_NIL, ASYNC_ERROR_INV_FAILED, user_data);
687                g_free (async_data);
688        }
689
690        if (!opt_ev)
691                CORBA_exception_free (&tempenv);
692
693        return;
694
695}
696
697void
698bonobo_activation_init_activation_env (void)
699{
700        int i, j, num_items = 0;
701
702        struct {
703                const char *name;
704                const char *value;
705        } getenv_values[] = {
706                { "DISPLAY",         NULL }, /* X display */
707                { "SESSION_MANAGER", NULL }, /* XSMP session manager */
708                { "AUDIODEV",        NULL }, /* Audio device on Sun systems */
709                { "LANG",            NULL }, /* Fallback locale name */
710                { NULL,              NULL }
711        };
712
713        struct {
714                int         category;
715                const char *name;
716                const char *value;
717        } setlocale_values[] =  { /* locale information: see setlocale(3) */
718                { LC_ALL,      "LC_ALL",          NULL },
719                { LC_COLLATE,  "LC_COLLATE",      NULL },
720                { LC_MESSAGES, "LC_MESSAGES",     NULL },
721                { LC_MONETARY, "LC_MONETARY",     NULL },
722                { LC_NUMERIC,  "LC_NUMERIC",      NULL },
723                { LC_TIME,     "LC_TIME",         NULL },
724                { 0,           NULL,              NULL }
725        };
726
727        for (i = 0; getenv_values [i].name; i++) {
728                getenv_values [i].value = getenv (getenv_values [i].name);
729
730                if (getenv_values [i].value)
731                        num_items++;
732        }
733
734        for (i = 0; setlocale_values [i].name; i++) {
735                setlocale_values [i].value = setlocale (setlocale_values [i].category, NULL);
736
737                if (!setlocale_values [i].value)
738                        setlocale_values [i].value = getenv (setlocale_values [i].name);
739
740                if (setlocale_values [i].value) {
741                        num_items++;
742                        if (setlocale_values [i].category == LC_ALL)
743                                break; /* LC_ALL overrides all others */
744                }
745        }
746
747        if (!num_items)
748                return;
749
750        activation_environment._length  = activation_environment._maximum = num_items;
751        activation_environment._buffer  = Bonobo_ActivationEnvironment_allocbuf (num_items);
752        activation_environment._release = TRUE;
753
754        j = 0;
755
756        for (i = 0; getenv_values [i].name; i++) {
757                if (!getenv_values [i].value)
758                        continue;
759
760                Bonobo_ActivationEnvValue_set (
761                        &activation_environment._buffer [j++],
762                        getenv_values [i].name,
763                        getenv_values [i].value);
764        }
765
766
767        for (i = 0; setlocale_values [i].name; i++) {
768                if (!setlocale_values [i].value)
769                        continue;
770
771                Bonobo_ActivationEnvValue_set (
772                        &activation_environment._buffer [j++],
773                        setlocale_values [i].name,
774                        setlocale_values [i].value);
775        }
776
777        g_assert (j == num_items);
778}
779
780void
781bonobo_activation_set_activation_env_value (const char *name,
782                                            const char *value)
783{
784        Bonobo_ActivationEnvValue *old_buffer;
785        int                        i;
786
787        g_return_if_fail (name != NULL);
788
789        for (i = 0; i < activation_environment._length; i++)
790                if (!strcmp (activation_environment._buffer [i].name, name)) {
791                        Bonobo_ActivationEnvValue_set (
792                                &activation_environment._buffer [i], name, value);
793                        break;
794                }
795
796        if (i > 0 && i != activation_environment._length)
797                return; /* We've overwritten a value */
798
799        old_buffer = activation_environment._buffer;
800
801        activation_environment._length++;
802        activation_environment._maximum++;
803        activation_environment._buffer  = Bonobo_ActivationEnvironment_allocbuf (
804                                                        activation_environment._length);
805        activation_environment._release = TRUE;
806
807        for (i = 0; i < activation_environment._length - 1; i++)
808                Bonobo_ActivationEnvValue_copy (
809                        &activation_environment._buffer [i], &old_buffer [i]);
810
811        Bonobo_ActivationEnvValue_set (&activation_environment._buffer [i], name, value);
812
813        if (old_buffer)
814                CORBA_free (old_buffer);
815}
816
817/**
818 * bonobo_activation_name_service_get:
819 * @ev: %CORBA_Environment structure which will contain
820 *      the CORBA exception status of the operation.
821 *
822 * Returns the name server of bonobo-activation. @ev can be NULL.
823 *
824 * Return value: the name server of bonobo-activation.
825 */
826CORBA_Object
827bonobo_activation_name_service_get (CORBA_Environment * ev)
828{
829        return bonobo_activation_activate_from_id (
830                "OAFIID:Bonobo_CosNaming_NamingContext", 0, NULL, ev);
831}
Note: See TracBrowser for help on using the repository browser.