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

Revision 18563, 14.9 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.
RevLine 
[18310]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 */
25
26#include <config.h>
27#include <bonobo-activation/bonobo-activation-register.h>
28#include <bonobo-activation/bonobo-activation-private.h>
29#include <bonobo-activation/bonobo-activation-init.h>
30#include <bonobo-activation/Bonobo_ObjectDirectory.h>
31
32#include <stdio.h>
33#include <unistd.h>
34
[18562]35typedef struct {
36        char *name;
37        char *value;
38} RegistrationEnvValue;
39
[18310]40static gboolean check_registration = TRUE;
41static gboolean need_ior_printout  = TRUE;
42
[18562]43static Bonobo_ActivationEnvironment global_reg_env;
44
[18310]45void
46bonobo_activation_timeout_reg_check_set (gboolean on)
47{
48        check_registration = on;
49}
50
51gboolean
52bonobo_activation_timeout_reg_check (gpointer data)
53{
54        if (!check_registration)
55                return FALSE;
56
57        if (need_ior_printout) {
58                g_error ("This process has not registered the required OAFIID "
59                         "your source code should register '%s'. If your code is "
60                         "performing delayed registration and this message is trapped "
61                         "in error, see bonobo_activation_idle_reg_check_set.",
62                         bonobo_activation_iid_get ());
63        }
64
65        return FALSE;
66}
67
[18562]68gboolean
69Bonobo_ActivationEnvironment_match (const Bonobo_ActivationEnvironment *a,
70                                    const Bonobo_ActivationEnvironment *b)
71{
72        int i, start = 0;
[18310]73
[18562]74        for (i = 0; i < a->_length; i++) {
75                int j;
76
77                for (j = start; j < b->_length; j++)
78                        if (!strcmp (a->_buffer [i].name, b->_buffer [j].name))
79                                break;
80
81                if (j >= b->_length)
82                        continue;
83
84                if (strcmp (a->_buffer [i].value, b->_buffer [j].value) != 0)
85                        return FALSE;
86
87                if (j == start)
88                        start++;
89        }
90
91        return TRUE;
92}
93
94void
95Bonobo_ActivationEnvValue_copy (Bonobo_ActivationEnvValue *dest,
96                                Bonobo_ActivationEnvValue *src)
97{
98        g_return_if_fail (dest != NULL);
99        g_return_if_fail (src != NULL);
100
101        dest->name  = CORBA_string_dup (src->name);
102        dest->value = CORBA_string_dup (src->value);
103        dest->unset = src->unset;
104}
105
106void
107Bonobo_ActivationEnvValue_set (Bonobo_ActivationEnvValue *env,
108                               const char                *name,
109                               const char                *value)
110{
111        g_return_if_fail (env != NULL);
112        g_return_if_fail (name != NULL);
113
114        if (env->name)
115                CORBA_free (env->name);
116
117        if (env->value)
118                CORBA_free (env->value);
119
120        env->name  = CORBA_string_dup (name);
121        env->value = value ?
122                        CORBA_string_dup (value) :
123                        CORBA_string_dup ("");
124        env->unset = !value;
125}
126
127static void
128copy_env_list_to_sequence (Bonobo_ActivationEnvironment *environment,
129                           GSList                       *reg_env)
130{
131        GSList *l;
132        int     i;
133
134        g_assert (reg_env != NULL);
135
136        environment->_length  = environment->_maximum = g_slist_length (reg_env);
137        environment->_buffer  = Bonobo_ActivationEnvironment_allocbuf (environment->_length);
138        environment->_release = TRUE;
139
140        for (l = reg_env, i = 0; l; l = l->next, i++) {
141                RegistrationEnvValue *val = l->data;
142
143                Bonobo_ActivationEnvValue_set (
144                        &environment->_buffer [i], val->name, val->value);
145
146#ifdef BONOBO_ACTIVATION_DEBUG
147                g_warning ("Registration environment for '%s' = '%s'%s",
148                           environment->_buffer [i].name,
149                           environment->_buffer [i].value,
150                           environment->_buffer [i].unset ? "(unset)" : "");
151#endif
152        }
153}
154
155#ifdef BONOBO_ACTIVATION_DEBUG
156static char *
157registration_result_to_string (Bonobo_RegistrationResult result)
158{
159        switch (result) {
160        case Bonobo_ACTIVATION_REG_SUCCESS:
161                return "(success)";
162                break;
163        case Bonobo_ACTIVATION_REG_NOT_LISTED:
164                return "(not listed)";
165                break;
166        case Bonobo_ACTIVATION_REG_ALREADY_ACTIVE:
167                return "(already active)";
168                break;
169        case Bonobo_ACTIVATION_REG_ERROR:
170                return "(error)";
171                break;
172        default:
173                g_assert_not_reached ();
174                break;
175        }
176
177        return "(invalid)";
178}
179#endif /* BONOBO_ACTIVATION_DEBUG */
180
[18310]181/**
[18562]182 * bonobo_activation_register_active_server:
[18310]183 * @iid: IID of the server to register.
184 * @obj: CORBA::Object to register.
[18562]185 * @reg_env: the registration environment.
[18310]186 *
[18562]187 * Registers @obj with @iid with the local bonobo-activation-server
188 * daemon.
[18310]189 *
[18562]190 * If @reg_env is not %NULL, @obj will be registered in such a
191 * way that if a client who's environment differs from the
192 * environment specified in @reg_env, then another attempt
193 * to activate @iid will not result in a reference to @obj
194 * being returned, but rather another instance of @iid being
195 * activated.
196 *
197 * So, for example, you can ensure that a seperate instance
198 * of the component is activated for each distinct X display
199 * (and screen) by:
200 *
201 * <informalexample><programlisting>
202 *   display_name = gdk_display_get_name (gdk_display_get_default());
203 *   reg_env = bonobo_activation_registration_env_set (
204 *                              reg_env, "DISPLAY", display_name);
205 *   bonobo_activation_register_active_server (iid, active_server, reg_env);
206 *   bonobo_activation_registration_env_free (reg_env);
207 * </programlisting></informalexample>
208 *
209 * If @reg_env is %NULL, the global registration environment
210 * list will be used if it is set. See
211 * bonobo_activation_registration_env_set_global().
212 *
[18310]213 * Return value: status of the registration.
214 */
215Bonobo_RegistrationResult
[18562]216bonobo_activation_register_active_server (const char   *iid,
217                                          CORBA_Object  obj,
218                                          GSList       *reg_env)
[18310]219{
[18562]220        Bonobo_ObjectDirectory     od;
221        CORBA_Environment          ev;
222        Bonobo_RegistrationResult  retval;
223        const char                *actid;
[18310]224
225        CORBA_exception_init (&ev);
226
227#ifdef BONOBO_ACTIVATION_DEBUG
[18562]228        g_warning ("About to register '%s': %p%s",
229                   iid, obj,
[18310]230                   CORBA_Object_non_existent (obj, &ev) ? " (nonexistent)" : "");
231#endif
232
233        actid = bonobo_activation_iid_get ();
234
235        if (actid && strcmp (actid, iid) == 0 && bonobo_activation_private) {
236                retval = Bonobo_ACTIVATION_REG_SUCCESS;
237        } else {
[18562]238                Bonobo_ActivationEnvironment environment;
239
[18310]240                od = bonobo_activation_object_directory_get (
241                        bonobo_activation_username_get (),
[18562]242                        bonobo_activation_hostname_get ());
[18310]243               
244                if (CORBA_Object_is_nil (od, &ev)) {
245                        return Bonobo_ACTIVATION_REG_ERROR;
246                }
[18562]247
248                if (reg_env)
249                        copy_env_list_to_sequence (&environment, reg_env);
250
[18310]251                retval = Bonobo_ObjectDirectory_register_new (
[18562]252                                        od, iid,
253                                        reg_env ? &environment : &global_reg_env,
254                                        obj, &ev);
255
256                if (reg_env)
257                        CORBA_free (environment._buffer);
[18310]258        }
259
260#ifdef BONOBO_ACTIVATION_DEBUG
[18562]261        g_warning ("registration of '%s' returns %s", iid,
262                   registration_result_to_string (retval));
[18310]263#endif
264        if (actid && strcmp (actid, iid) == 0 && need_ior_printout) {
265                char *iorstr;
266                FILE *fh;
267                int iorfd = bonobo_activation_ior_fd_get ();
268
269                need_ior_printout = FALSE;
270
271                if (iorfd == 1)
272                        fh = stdout;
273                else {
274                        fh = fdopen (iorfd, "w");
275                        if (!fh)
276                                fh = stdout;
277                }
278
279                iorstr = CORBA_ORB_object_to_string (
280                        bonobo_activation_orb_get (), obj, &ev);
281
282                if (ev._major == CORBA_NO_EXCEPTION) {
283                        fprintf (fh, "%s\n", iorstr);
284                        CORBA_free (iorstr);
285                }
286
287                if (fh != stdout) {
288                        fclose (fh);
289                } else if (iorfd > 2) {
290                        close (iorfd);
291                }
292        }
293#ifdef BONOBO_ACTIVATION_DEBUG
294        else if (actid && need_ior_printout) {
[18562]295                g_warning ("Unusual '%s' was activated, but "
[18310]296                           "'%s' is needed", iid, actid);
297        }
298#endif
299
300        CORBA_exception_free (&ev);
301
302#ifdef BONOBO_ACTIVATION_DEBUG
[18562]303        g_warning ("Successfully registered `%s'", iid);
[18310]304#endif
305
306        return retval;
307}
308
[18562]309/**
310 * bonobo_activation_active_server_register:
311 * @registration_id: IID of the server to register.
312 * @obj: CORBA::Object to register.
313 *
314 * Registers @obj with @iid with the local bonobo-activation-server
315 * daemon.
316 *
317 * This function is now deprecated and should no longer be
318 * used. bonobo_activation_register_active_server() should now
319 * be used.
320 *
321 * Return value: status of the registration.
322 */
323Bonobo_RegistrationResult
324bonobo_activation_active_server_register (const char   *registration_id,
325                                          CORBA_Object  obj)
326{
327        Bonobo_RegistrationResult  retval;
328        char                      *iid;
[18310]329
[18562]330        iid = strrchr (registration_id, ',');
331        if (!iid) {
332                retval = bonobo_activation_register_active_server (
333                                                registration_id, obj, NULL);
334        } else {
335                GSList *reg_env = NULL;
336                char   *display_name;
337                int     len;
338
339                len = iid - registration_id;
340                display_name = g_alloca (len + 1);
341                strncpy (display_name, registration_id, len);
342                display_name [len] = '\0';
343
344                iid++;
345
346                reg_env = bonobo_activation_registration_env_set (
347                                        reg_env, "DISPLAY", display_name);
348
349#ifdef BONOBO_ACTIVATION_DEBUG
350                g_warning ("Registering iid '%s' with display '%s'", iid, display_name);
351#endif
352
353                retval = bonobo_activation_register_active_server (iid, obj, reg_env);
354
355                bonobo_activation_registration_env_free (reg_env);
356        }
357
358        return retval;
359}
360
[18310]361/**
[18562]362 * bonobo_activation_unregister_active_server:
[18310]363 * @iid: IID of the server to unregister.
364 * @obj: CORBA::Object to unregister.
365 *
[18562]366 * Unregisters @obj with @iid with the local bonobo-activation-server
367 * daemon.
[18310]368 */
369void
[18562]370bonobo_activation_unregister_active_server (const char   *iid,
371                                            CORBA_Object  obj)
[18310]372{
[18562]373        Bonobo_ObjectDirectory        od;
374        CORBA_Environment             ev;
375        const char                   *actid;
[18310]376
377        actid = bonobo_activation_iid_get ();
378        if(actid && strcmp (actid, iid) == 0 && bonobo_activation_private) {
379                return;
380        }
381
382        od = bonobo_activation_object_directory_get (
383                bonobo_activation_username_get (),
[18562]384                bonobo_activation_hostname_get ());
[18310]385
386        CORBA_exception_init (&ev);
387        if (CORBA_Object_is_nil (od, &ev))
388                return;
389
390        Bonobo_ObjectDirectory_unregister (od, (char *) iid, obj, &ev);
391
392        CORBA_exception_free (&ev);
393}
394
[18562]395void
396bonobo_activation_active_server_unregister (const char   *iid, 
397                                            CORBA_Object  obj)
398{
399        bonobo_activation_unregister_active_server (iid, obj);
400}
[18310]401
[18562]402/**
403 * bonobo_activation_registration_env_set:
404 * @reg_env: a GSList pointer.
405 * @name: the name of the env variable (must not be %NULL).
406 * @value: the value of the env variable (may be %NULL).
407 *
408 * Sets the environment variable @name to @value in the
409 * registration environment list @reg_env.
410 *
411 * Return value: the new start of @reg_env.
412 */
413GSList *
414bonobo_activation_registration_env_set (GSList     *reg_env,
415                                        const char *name,
416                                        const char *value)
417{
418        RegistrationEnvValue *env_value;
419
420        g_return_val_if_fail (name != NULL, reg_env);
421
422#ifdef BONOBO_ACTIVATION_DEBUG
423        {
424                GSList *l;
425
426                for (l = reg_env; l; l = l->next) {
427                        RegistrationEnvValue *v = l->data;
428
429                        g_assert (v != NULL);
430                        g_assert (v->name != NULL);
431
432                        if (!strcmp (v->name, name))
433                                g_warning ("Duplicate env values set - %s=%s and %s=%s",
434                                           v->name, v->value ? v->value : "(null)",
435                                           name, value ? value : "(null)");
436                }
437        }
438#endif
439
440        env_value = g_new (RegistrationEnvValue, 1);
441
442        env_value->name  = g_strdup (name);
443        env_value->value = value ? g_strdup (value) : NULL;
444
445        reg_env = g_slist_prepend (reg_env, env_value);
446
447        return reg_env;
448}
449
450/**
451 * bonobo_activation_registration_env_free:
452 * @reg_env: a GSList pointer.
453 *
454 * Frees the registration environment list, @reg_env.
455 */
456void
457bonobo_activation_registration_env_free (GSList *reg_env)
458{
459        GSList *l;
460
461        for (l = reg_env; l; l = l->next) {
462                RegistrationEnvValue *env_value = l->data;
463
464                g_free (env_value->name);
465                g_free (env_value->value);
466                g_free (env_value);
467        }
468
469        g_slist_free (reg_env);
470}
471
472/**
473 * bonobo_activation_registration_env_set_global:
474 * @reg_env: a GSList pointer.
475 * @append_if_existing: whether or not to append to the global list.
476 *
477 * Sets the global registration environment list with the
478 * contents of @reg_env. If @append_if_existing is set to
479 * %FALSE, the an existing global list will be overwritten.
480 */
481void
482bonobo_activation_registration_env_set_global (GSList   *reg_env,
483                                               gboolean  append_if_existing)
484{
485        Bonobo_ActivationEnvValue *old_buffer;
486        int                        old_length = 0;
487
488        if (append_if_existing)
489                old_length = global_reg_env._length;
490
491        old_buffer = global_reg_env._buffer;
492
493        if (!reg_env) {
494                GSList *l;
495                int     i;
496
497                global_reg_env._length  = global_reg_env._maximum = old_length + g_slist_length (reg_env);
498                global_reg_env._buffer  = Bonobo_ActivationEnvironment_allocbuf (global_reg_env._length);
499                global_reg_env._release = TRUE;
500
501                for (i = 0; i < old_length; i++)
502                        Bonobo_ActivationEnvValue_copy (
503                                &global_reg_env._buffer [i], &old_buffer [i]);
504
505                for (l = reg_env; l; l = l->next) {
506                        RegistrationEnvValue *val = l->data;
507
508                        Bonobo_ActivationEnvValue_set (
509                                &global_reg_env._buffer [++i], val->name, val->value);
510                }
511
512                g_assert (i == global_reg_env._length - 1);
513        } else
514                memset (&global_reg_env, 0, sizeof (Bonobo_ActivationEnvironment));
515
516        if (old_buffer)
517                CORBA_free (old_buffer);
518}
519
520/**
521 * bonobo_activation_make_registration_id:
522 * @iid: IID of the server to unregister.
523 * @display: the X display name with which you wish to register.
524 *
525 * Creates bonobo-activation registration ID suitable for use
526 * with bonobo_activation_active_server_register(). If @display
527 * is the name of an X display, then using this registration
528 * ID will ensure that the server will only be used by clients
529 * using the same X display.
530 *
531 * This method is now deprecated. Instead you can achieve the
532 * same effect by:
533 *
534 * <informalexample><programlisting>
535 *   display_name = gdk_display_get_name (gdk_display_get_default());
536 *   reg_env = bonobo_activation_registration_env_set (
537 *                              reg_env, "DISPLAY", display_name);
538 *   bonobo_activation_register_active_server (iid, active_server, reg_env);
539 *   bonobo_activation_registration_env_free (reg_env);
540 * </programlisting></informalexample>
541 *
542 * Return value: newly allocated registration id.
543 */
[18310]544char *
545bonobo_activation_make_registration_id (const char *iid, const char *display)
546{
547#ifdef BONOBO_ACTIVATION_DEBUG
548        g_warning ("Make registration id from '%s' '%s'", iid, display);
549#endif
550        if (display == NULL) {
551                return g_strdup (iid);
552        } else {
553                return g_strconcat (display, ",", iid, NULL);
554        }
555}
Note: See TracBrowser for help on using the repository browser.