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 | |
---|
35 | typedef struct { |
---|
36 | char *name; |
---|
37 | char *value; |
---|
38 | } RegistrationEnvValue; |
---|
39 | |
---|
40 | static gboolean check_registration = TRUE; |
---|
41 | static gboolean need_ior_printout = TRUE; |
---|
42 | |
---|
43 | static Bonobo_ActivationEnvironment global_reg_env; |
---|
44 | |
---|
45 | void |
---|
46 | bonobo_activation_timeout_reg_check_set (gboolean on) |
---|
47 | { |
---|
48 | check_registration = on; |
---|
49 | } |
---|
50 | |
---|
51 | gboolean |
---|
52 | bonobo_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 | |
---|
68 | gboolean |
---|
69 | Bonobo_ActivationEnvironment_match (const Bonobo_ActivationEnvironment *a, |
---|
70 | const Bonobo_ActivationEnvironment *b) |
---|
71 | { |
---|
72 | int i, start = 0; |
---|
73 | |
---|
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 | |
---|
94 | void |
---|
95 | Bonobo_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 | |
---|
106 | void |
---|
107 | Bonobo_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 | |
---|
127 | static void |
---|
128 | copy_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 |
---|
156 | static char * |
---|
157 | registration_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 | |
---|
181 | /** |
---|
182 | * bonobo_activation_register_active_server: |
---|
183 | * @iid: IID of the server to register. |
---|
184 | * @obj: CORBA::Object to register. |
---|
185 | * @reg_env: the registration environment. |
---|
186 | * |
---|
187 | * Registers @obj with @iid with the local bonobo-activation-server |
---|
188 | * daemon. |
---|
189 | * |
---|
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 | * |
---|
213 | * Return value: status of the registration. |
---|
214 | */ |
---|
215 | Bonobo_RegistrationResult |
---|
216 | bonobo_activation_register_active_server (const char *iid, |
---|
217 | CORBA_Object obj, |
---|
218 | GSList *reg_env) |
---|
219 | { |
---|
220 | Bonobo_ObjectDirectory od; |
---|
221 | CORBA_Environment ev; |
---|
222 | Bonobo_RegistrationResult retval; |
---|
223 | const char *actid; |
---|
224 | |
---|
225 | CORBA_exception_init (&ev); |
---|
226 | |
---|
227 | #ifdef BONOBO_ACTIVATION_DEBUG |
---|
228 | g_warning ("About to register '%s': %p%s", |
---|
229 | iid, obj, |
---|
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 { |
---|
238 | Bonobo_ActivationEnvironment environment; |
---|
239 | |
---|
240 | od = bonobo_activation_object_directory_get ( |
---|
241 | bonobo_activation_username_get (), |
---|
242 | bonobo_activation_hostname_get ()); |
---|
243 | |
---|
244 | if (CORBA_Object_is_nil (od, &ev)) { |
---|
245 | return Bonobo_ACTIVATION_REG_ERROR; |
---|
246 | } |
---|
247 | |
---|
248 | if (reg_env) |
---|
249 | copy_env_list_to_sequence (&environment, reg_env); |
---|
250 | |
---|
251 | retval = Bonobo_ObjectDirectory_register_new ( |
---|
252 | od, iid, |
---|
253 | reg_env ? &environment : &global_reg_env, |
---|
254 | obj, &ev); |
---|
255 | |
---|
256 | if (reg_env) |
---|
257 | CORBA_free (environment._buffer); |
---|
258 | } |
---|
259 | |
---|
260 | #ifdef BONOBO_ACTIVATION_DEBUG |
---|
261 | g_warning ("registration of '%s' returns %s", iid, |
---|
262 | registration_result_to_string (retval)); |
---|
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) { |
---|
295 | g_warning ("Unusual '%s' was activated, but " |
---|
296 | "'%s' is needed", iid, actid); |
---|
297 | } |
---|
298 | #endif |
---|
299 | |
---|
300 | CORBA_exception_free (&ev); |
---|
301 | |
---|
302 | #ifdef BONOBO_ACTIVATION_DEBUG |
---|
303 | g_warning ("Successfully registered `%s'", iid); |
---|
304 | #endif |
---|
305 | |
---|
306 | return retval; |
---|
307 | } |
---|
308 | |
---|
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 | */ |
---|
323 | Bonobo_RegistrationResult |
---|
324 | bonobo_activation_active_server_register (const char *registration_id, |
---|
325 | CORBA_Object obj) |
---|
326 | { |
---|
327 | Bonobo_RegistrationResult retval; |
---|
328 | char *iid; |
---|
329 | |
---|
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 | |
---|
361 | /** |
---|
362 | * bonobo_activation_unregister_active_server: |
---|
363 | * @iid: IID of the server to unregister. |
---|
364 | * @obj: CORBA::Object to unregister. |
---|
365 | * |
---|
366 | * Unregisters @obj with @iid with the local bonobo-activation-server |
---|
367 | * daemon. |
---|
368 | */ |
---|
369 | void |
---|
370 | bonobo_activation_unregister_active_server (const char *iid, |
---|
371 | CORBA_Object obj) |
---|
372 | { |
---|
373 | Bonobo_ObjectDirectory od; |
---|
374 | CORBA_Environment ev; |
---|
375 | const char *actid; |
---|
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 (), |
---|
384 | bonobo_activation_hostname_get ()); |
---|
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 | |
---|
395 | void |
---|
396 | bonobo_activation_active_server_unregister (const char *iid, |
---|
397 | CORBA_Object obj) |
---|
398 | { |
---|
399 | bonobo_activation_unregister_active_server (iid, obj); |
---|
400 | } |
---|
401 | |
---|
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 | */ |
---|
413 | GSList * |
---|
414 | bonobo_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 | */ |
---|
456 | void |
---|
457 | bonobo_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 | */ |
---|
481 | void |
---|
482 | bonobo_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 | */ |
---|
544 | char * |
---|
545 | bonobo_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 | } |
---|