00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <config.h>
00025 #include "dbus-server.h"
00026 #include "dbus-server-unix.h"
00027 #include "dbus-server-socket.h"
00028 #include "dbus-string.h"
00029 #ifdef DBUS_BUILD_TESTS
00030 #include "dbus-server-debug-pipe.h"
00031 #endif
00032 #include "dbus-address.h"
00033 #include "dbus-protocol.h"
00034
00056
00057
00058
00059 static char*
00060 copy_address_with_guid_appended (const DBusString *address,
00061 const DBusString *guid_hex)
00062 {
00063 DBusString with_guid;
00064 char *retval;
00065
00066 if (!_dbus_string_init (&with_guid))
00067 return NULL;
00068
00069 if (!_dbus_string_copy (address, 0, &with_guid,
00070 _dbus_string_get_length (&with_guid)) ||
00071 !_dbus_string_append (&with_guid, ",guid=") ||
00072 !_dbus_string_copy (guid_hex, 0,
00073 &with_guid, _dbus_string_get_length (&with_guid)))
00074 {
00075 _dbus_string_free (&with_guid);
00076 return NULL;
00077 }
00078
00079 retval = NULL;
00080 _dbus_string_steal_data (&with_guid, &retval);
00081
00082 _dbus_string_free (&with_guid);
00083
00084 return retval;
00085 }
00086
00096 dbus_bool_t
00097 _dbus_server_init_base (DBusServer *server,
00098 const DBusServerVTable *vtable,
00099 const DBusString *address)
00100 {
00101 server->vtable = vtable;
00102 server->refcount.value = 1;
00103
00104 server->address = NULL;
00105 server->watches = NULL;
00106 server->timeouts = NULL;
00107 server->published_address = FALSE;
00108
00109 if (!_dbus_string_init (&server->guid_hex))
00110 return FALSE;
00111
00112 _dbus_generate_uuid (&server->guid);
00113
00114 if (!_dbus_uuid_encode (&server->guid, &server->guid_hex))
00115 goto failed;
00116
00117 server->address = copy_address_with_guid_appended (address,
00118 &server->guid_hex);
00119 if (server->address == NULL)
00120 goto failed;
00121
00122 _dbus_mutex_new_at_location (&server->mutex);
00123 if (server->mutex == NULL)
00124 goto failed;
00125
00126 server->watches = _dbus_watch_list_new ();
00127 if (server->watches == NULL)
00128 goto failed;
00129
00130 server->timeouts = _dbus_timeout_list_new ();
00131 if (server->timeouts == NULL)
00132 goto failed;
00133
00134 _dbus_data_slot_list_init (&server->slot_list);
00135
00136 _dbus_verbose ("Initialized server on address %s\n", server->address);
00137
00138 return TRUE;
00139
00140 failed:
00141 _dbus_mutex_free_at_location (&server->mutex);
00142 server->mutex = NULL;
00143 if (server->watches)
00144 {
00145 _dbus_watch_list_free (server->watches);
00146 server->watches = NULL;
00147 }
00148 if (server->timeouts)
00149 {
00150 _dbus_timeout_list_free (server->timeouts);
00151 server->timeouts = NULL;
00152 }
00153 if (server->address)
00154 {
00155 dbus_free (server->address);
00156 server->address = NULL;
00157 }
00158 _dbus_string_free (&server->guid_hex);
00159
00160 return FALSE;
00161 }
00162
00169 void
00170 _dbus_server_finalize_base (DBusServer *server)
00171 {
00172
00173
00174
00175 #ifndef DBUS_DISABLE_CHECKS
00176 _dbus_assert (!server->have_server_lock);
00177 #endif
00178 _dbus_assert (server->disconnected);
00179
00180
00181 _dbus_data_slot_list_free (&server->slot_list);
00182
00183 dbus_server_set_new_connection_function (server, NULL, NULL, NULL);
00184
00185 _dbus_watch_list_free (server->watches);
00186 _dbus_timeout_list_free (server->timeouts);
00187
00188 _dbus_mutex_free_at_location (&server->mutex);
00189
00190 dbus_free (server->address);
00191
00192 dbus_free_string_array (server->auth_mechanisms);
00193
00194 _dbus_string_free (&server->guid_hex);
00195 }
00196
00197
00199 typedef dbus_bool_t (* DBusWatchAddFunction) (DBusWatchList *list,
00200 DBusWatch *watch);
00202 typedef void (* DBusWatchRemoveFunction) (DBusWatchList *list,
00203 DBusWatch *watch);
00205 typedef void (* DBusWatchToggleFunction) (DBusWatchList *list,
00206 DBusWatch *watch,
00207 dbus_bool_t enabled);
00208
00209 static dbus_bool_t
00210 protected_change_watch (DBusServer *server,
00211 DBusWatch *watch,
00212 DBusWatchAddFunction add_function,
00213 DBusWatchRemoveFunction remove_function,
00214 DBusWatchToggleFunction toggle_function,
00215 dbus_bool_t enabled)
00216 {
00217 DBusWatchList *watches;
00218 dbus_bool_t retval;
00219
00220 HAVE_LOCK_CHECK (server);
00221
00222
00223
00224
00225
00226
00227 watches = server->watches;
00228 if (watches)
00229 {
00230 server->watches = NULL;
00231 _dbus_server_ref_unlocked (server);
00232 SERVER_UNLOCK (server);
00233
00234 if (add_function)
00235 retval = (* add_function) (watches, watch);
00236 else if (remove_function)
00237 {
00238 retval = TRUE;
00239 (* remove_function) (watches, watch);
00240 }
00241 else
00242 {
00243 retval = TRUE;
00244 (* toggle_function) (watches, watch, enabled);
00245 }
00246
00247 SERVER_LOCK (server);
00248 server->watches = watches;
00249 _dbus_server_unref_unlocked (server);
00250
00251 return retval;
00252 }
00253 else
00254 return FALSE;
00255 }
00256
00264 dbus_bool_t
00265 _dbus_server_add_watch (DBusServer *server,
00266 DBusWatch *watch)
00267 {
00268 HAVE_LOCK_CHECK (server);
00269 return protected_change_watch (server, watch,
00270 _dbus_watch_list_add_watch,
00271 NULL, NULL, FALSE);
00272 }
00273
00280 void
00281 _dbus_server_remove_watch (DBusServer *server,
00282 DBusWatch *watch)
00283 {
00284 HAVE_LOCK_CHECK (server);
00285 protected_change_watch (server, watch,
00286 NULL,
00287 _dbus_watch_list_remove_watch,
00288 NULL, FALSE);
00289 }
00290
00300 void
00301 _dbus_server_toggle_watch (DBusServer *server,
00302 DBusWatch *watch,
00303 dbus_bool_t enabled)
00304 {
00305 _dbus_assert (watch != NULL);
00306
00307 HAVE_LOCK_CHECK (server);
00308 protected_change_watch (server, watch,
00309 NULL, NULL,
00310 _dbus_watch_list_toggle_watch,
00311 enabled);
00312 }
00313
00315 typedef dbus_bool_t (* DBusTimeoutAddFunction) (DBusTimeoutList *list,
00316 DBusTimeout *timeout);
00318 typedef void (* DBusTimeoutRemoveFunction) (DBusTimeoutList *list,
00319 DBusTimeout *timeout);
00321 typedef void (* DBusTimeoutToggleFunction) (DBusTimeoutList *list,
00322 DBusTimeout *timeout,
00323 dbus_bool_t enabled);
00324
00325
00326 static dbus_bool_t
00327 protected_change_timeout (DBusServer *server,
00328 DBusTimeout *timeout,
00329 DBusTimeoutAddFunction add_function,
00330 DBusTimeoutRemoveFunction remove_function,
00331 DBusTimeoutToggleFunction toggle_function,
00332 dbus_bool_t enabled)
00333 {
00334 DBusTimeoutList *timeouts;
00335 dbus_bool_t retval;
00336
00337 HAVE_LOCK_CHECK (server);
00338
00339
00340
00341
00342
00343 timeouts = server->timeouts;
00344 if (timeouts)
00345 {
00346 server->timeouts = NULL;
00347 _dbus_server_ref_unlocked (server);
00348 SERVER_UNLOCK (server);
00349
00350 if (add_function)
00351 retval = (* add_function) (timeouts, timeout);
00352 else if (remove_function)
00353 {
00354 retval = TRUE;
00355 (* remove_function) (timeouts, timeout);
00356 }
00357 else
00358 {
00359 retval = TRUE;
00360 (* toggle_function) (timeouts, timeout, enabled);
00361 }
00362
00363 SERVER_LOCK (server);
00364 server->timeouts = timeouts;
00365 _dbus_server_unref_unlocked (server);
00366
00367 return retval;
00368 }
00369 else
00370 return FALSE;
00371 }
00372
00382 dbus_bool_t
00383 _dbus_server_add_timeout (DBusServer *server,
00384 DBusTimeout *timeout)
00385 {
00386 return protected_change_timeout (server, timeout,
00387 _dbus_timeout_list_add_timeout,
00388 NULL, NULL, FALSE);
00389 }
00390
00397 void
00398 _dbus_server_remove_timeout (DBusServer *server,
00399 DBusTimeout *timeout)
00400 {
00401 protected_change_timeout (server, timeout,
00402 NULL,
00403 _dbus_timeout_list_remove_timeout,
00404 NULL, FALSE);
00405 }
00406
00416 void
00417 _dbus_server_toggle_timeout (DBusServer *server,
00418 DBusTimeout *timeout,
00419 dbus_bool_t enabled)
00420 {
00421 protected_change_timeout (server, timeout,
00422 NULL, NULL,
00423 _dbus_timeout_list_toggle_timeout,
00424 enabled);
00425 }
00426
00427
00433 void
00434 _dbus_server_ref_unlocked (DBusServer *server)
00435 {
00436 _dbus_assert (server != NULL);
00437 _dbus_assert (server->refcount.value > 0);
00438
00439 HAVE_LOCK_CHECK (server);
00440
00441 #ifdef DBUS_HAVE_ATOMIC_INT
00442 _dbus_atomic_inc (&server->refcount);
00443 #else
00444 _dbus_assert (server->refcount.value > 0);
00445
00446 server->refcount.value += 1;
00447 #endif
00448 }
00449
00455 void
00456 _dbus_server_unref_unlocked (DBusServer *server)
00457 {
00458 dbus_bool_t last_unref;
00459
00460
00461
00462 _dbus_assert (server != NULL);
00463 _dbus_assert (server->refcount.value > 0);
00464
00465 HAVE_LOCK_CHECK (server);
00466
00467 #ifdef DBUS_HAVE_ATOMIC_INT
00468 last_unref = (_dbus_atomic_dec (&server->refcount) == 1);
00469 #else
00470 _dbus_assert (server->refcount.value > 0);
00471
00472 server->refcount.value -= 1;
00473 last_unref = (server->refcount.value == 0);
00474 #endif
00475
00476 if (last_unref)
00477 {
00478 _dbus_assert (server->disconnected);
00479
00480 SERVER_UNLOCK (server);
00481
00482 _dbus_assert (server->vtable->finalize != NULL);
00483
00484 (* server->vtable->finalize) (server);
00485 }
00486 }
00487
00509 static const struct {
00510 DBusServerListenResult (* func) (DBusAddressEntry *entry,
00511 DBusServer **server_p,
00512 DBusError *error);
00513 } listen_funcs[] = {
00514 { _dbus_server_listen_socket }
00515 , { _dbus_server_listen_platform_specific }
00516 #ifdef DBUS_BUILD_TESTS
00517 , { _dbus_server_listen_debug_pipe }
00518 #endif
00519 };
00520
00541 DBusServer*
00542 dbus_server_listen (const char *address,
00543 DBusError *error)
00544 {
00545 DBusServer *server;
00546 DBusAddressEntry **entries;
00547 int len, i;
00548 DBusError first_connect_error = DBUS_ERROR_INIT;
00549 dbus_bool_t handled_once;
00550
00551 _dbus_return_val_if_fail (address != NULL, NULL);
00552 _dbus_return_val_if_error_is_set (error, NULL);
00553
00554 if (!dbus_parse_address (address, &entries, &len, error))
00555 return NULL;
00556
00557 server = NULL;
00558 handled_once = FALSE;
00559
00560 for (i = 0; i < len; i++)
00561 {
00562 int j;
00563
00564 for (j = 0; j < (int) _DBUS_N_ELEMENTS (listen_funcs); ++j)
00565 {
00566 DBusServerListenResult result;
00567 DBusError tmp_error = DBUS_ERROR_INIT;
00568
00569 result = (* listen_funcs[j].func) (entries[i],
00570 &server,
00571 &tmp_error);
00572
00573 if (result == DBUS_SERVER_LISTEN_OK)
00574 {
00575 _dbus_assert (server != NULL);
00576 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00577 handled_once = TRUE;
00578 goto out;
00579 }
00580 else if (result == DBUS_SERVER_LISTEN_ADDRESS_ALREADY_USED)
00581 {
00582 _dbus_assert (server == NULL);
00583 dbus_set_error (error,
00584 DBUS_ERROR_ADDRESS_IN_USE,
00585 "Address '%s' already used",
00586 dbus_address_entry_get_method (entries[0]));
00587 handled_once = TRUE;
00588 goto out;
00589 }
00590 else if (result == DBUS_SERVER_LISTEN_BAD_ADDRESS)
00591 {
00592 _dbus_assert (server == NULL);
00593 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
00594 dbus_move_error (&tmp_error, error);
00595 handled_once = TRUE;
00596 goto out;
00597 }
00598 else if (result == DBUS_SERVER_LISTEN_NOT_HANDLED)
00599 {
00600 _dbus_assert (server == NULL);
00601 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00602
00603
00604 }
00605 else if (result == DBUS_SERVER_LISTEN_DID_NOT_CONNECT)
00606 {
00607 _dbus_assert (server == NULL);
00608 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
00609 if (!dbus_error_is_set (&first_connect_error))
00610 dbus_move_error (&tmp_error, &first_connect_error);
00611 else
00612 dbus_error_free (&tmp_error);
00613
00614 handled_once = TRUE;
00615
00616
00617 }
00618 }
00619
00620 _dbus_assert (server == NULL);
00621 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00622 }
00623
00624 out:
00625
00626 if (!handled_once)
00627 {
00628 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00629 if (len > 0)
00630 dbus_set_error (error,
00631 DBUS_ERROR_BAD_ADDRESS,
00632 "Unknown address type '%s'",
00633 dbus_address_entry_get_method (entries[0]));
00634 else
00635 dbus_set_error (error,
00636 DBUS_ERROR_BAD_ADDRESS,
00637 "Empty address '%s'",
00638 address);
00639 }
00640
00641 dbus_address_entries_free (entries);
00642
00643 if (server == NULL)
00644 {
00645 _dbus_assert (error == NULL || dbus_error_is_set (&first_connect_error) ||
00646 dbus_error_is_set (error));
00647
00648 if (error && dbus_error_is_set (error))
00649 {
00650
00651 }
00652 else
00653 {
00654
00655
00656
00657 _dbus_assert (error == NULL || dbus_error_is_set (&first_connect_error));
00658 dbus_move_error (&first_connect_error, error);
00659 }
00660
00661 _DBUS_ASSERT_ERROR_IS_CLEAR (&first_connect_error);
00662 _DBUS_ASSERT_ERROR_IS_SET (error);
00663
00664 return NULL;
00665 }
00666 else
00667 {
00668 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00669 return server;
00670 }
00671 }
00672
00679 DBusServer *
00680 dbus_server_ref (DBusServer *server)
00681 {
00682 _dbus_return_val_if_fail (server != NULL, NULL);
00683 _dbus_return_val_if_fail (server->refcount.value > 0, NULL);
00684
00685 #ifdef DBUS_HAVE_ATOMIC_INT
00686 _dbus_atomic_inc (&server->refcount);
00687 #else
00688 SERVER_LOCK (server);
00689 _dbus_assert (server->refcount.value > 0);
00690
00691 server->refcount.value += 1;
00692 SERVER_UNLOCK (server);
00693 #endif
00694
00695 return server;
00696 }
00697
00706 void
00707 dbus_server_unref (DBusServer *server)
00708 {
00709 dbus_bool_t last_unref;
00710
00711
00712
00713 _dbus_return_if_fail (server != NULL);
00714 _dbus_return_if_fail (server->refcount.value > 0);
00715
00716 #ifdef DBUS_HAVE_ATOMIC_INT
00717 last_unref = (_dbus_atomic_dec (&server->refcount) == 1);
00718 #else
00719 SERVER_LOCK (server);
00720
00721 _dbus_assert (server->refcount.value > 0);
00722
00723 server->refcount.value -= 1;
00724 last_unref = (server->refcount.value == 0);
00725
00726 SERVER_UNLOCK (server);
00727 #endif
00728
00729 if (last_unref)
00730 {
00731
00732 _dbus_assert (server->disconnected);
00733
00734 _dbus_assert (server->vtable->finalize != NULL);
00735
00736 (* server->vtable->finalize) (server);
00737 }
00738 }
00739
00748 void
00749 dbus_server_disconnect (DBusServer *server)
00750 {
00751 _dbus_return_if_fail (server != NULL);
00752 _dbus_return_if_fail (server->refcount.value > 0);
00753
00754 SERVER_LOCK (server);
00755 _dbus_server_ref_unlocked (server);
00756
00757 _dbus_assert (server->vtable->disconnect != NULL);
00758
00759 if (!server->disconnected)
00760 {
00761
00762 server->disconnected = TRUE;
00763
00764 (* server->vtable->disconnect) (server);
00765 }
00766
00767 SERVER_UNLOCK (server);
00768 dbus_server_unref (server);
00769 }
00770
00776 dbus_bool_t
00777 dbus_server_get_is_connected (DBusServer *server)
00778 {
00779 dbus_bool_t retval;
00780
00781 _dbus_return_val_if_fail (server != NULL, FALSE);
00782
00783 SERVER_LOCK (server);
00784 retval = !server->disconnected;
00785 SERVER_UNLOCK (server);
00786
00787 return retval;
00788 }
00789
00797 char*
00798 dbus_server_get_address (DBusServer *server)
00799 {
00800 char *retval;
00801
00802 _dbus_return_val_if_fail (server != NULL, NULL);
00803
00804 SERVER_LOCK (server);
00805 retval = _dbus_strdup (server->address);
00806 SERVER_UNLOCK (server);
00807
00808 return retval;
00809 }
00810
00833 char*
00834 dbus_server_get_id (DBusServer *server)
00835 {
00836 char *retval;
00837
00838 _dbus_return_val_if_fail (server != NULL, NULL);
00839
00840 SERVER_LOCK (server);
00841 retval = NULL;
00842 _dbus_string_copy_data (&server->guid_hex, &retval);
00843 SERVER_UNLOCK (server);
00844
00845 return retval;
00846 }
00847
00868 void
00869 dbus_server_set_new_connection_function (DBusServer *server,
00870 DBusNewConnectionFunction function,
00871 void *data,
00872 DBusFreeFunction free_data_function)
00873 {
00874 DBusFreeFunction old_free_function;
00875 void *old_data;
00876
00877 _dbus_return_if_fail (server != NULL);
00878
00879 SERVER_LOCK (server);
00880 old_free_function = server->new_connection_free_data_function;
00881 old_data = server->new_connection_data;
00882
00883 server->new_connection_function = function;
00884 server->new_connection_data = data;
00885 server->new_connection_free_data_function = free_data_function;
00886 SERVER_UNLOCK (server);
00887
00888 if (old_free_function != NULL)
00889 (* old_free_function) (old_data);
00890 }
00891
00908 dbus_bool_t
00909 dbus_server_set_watch_functions (DBusServer *server,
00910 DBusAddWatchFunction add_function,
00911 DBusRemoveWatchFunction remove_function,
00912 DBusWatchToggledFunction toggled_function,
00913 void *data,
00914 DBusFreeFunction free_data_function)
00915 {
00916 dbus_bool_t result;
00917 DBusWatchList *watches;
00918
00919 _dbus_return_val_if_fail (server != NULL, FALSE);
00920
00921 SERVER_LOCK (server);
00922 watches = server->watches;
00923 server->watches = NULL;
00924 if (watches)
00925 {
00926 SERVER_UNLOCK (server);
00927 result = _dbus_watch_list_set_functions (watches,
00928 add_function,
00929 remove_function,
00930 toggled_function,
00931 data,
00932 free_data_function);
00933 SERVER_LOCK (server);
00934 }
00935 else
00936 {
00937 _dbus_warn_check_failed ("Re-entrant call to %s\n", _DBUS_FUNCTION_NAME);
00938 result = FALSE;
00939 }
00940 server->watches = watches;
00941 SERVER_UNLOCK (server);
00942
00943 return result;
00944 }
00945
00961 dbus_bool_t
00962 dbus_server_set_timeout_functions (DBusServer *server,
00963 DBusAddTimeoutFunction add_function,
00964 DBusRemoveTimeoutFunction remove_function,
00965 DBusTimeoutToggledFunction toggled_function,
00966 void *data,
00967 DBusFreeFunction free_data_function)
00968 {
00969 dbus_bool_t result;
00970 DBusTimeoutList *timeouts;
00971
00972 _dbus_return_val_if_fail (server != NULL, FALSE);
00973
00974 SERVER_LOCK (server);
00975 timeouts = server->timeouts;
00976 server->timeouts = NULL;
00977 if (timeouts)
00978 {
00979 SERVER_UNLOCK (server);
00980 result = _dbus_timeout_list_set_functions (timeouts,
00981 add_function,
00982 remove_function,
00983 toggled_function,
00984 data,
00985 free_data_function);
00986 SERVER_LOCK (server);
00987 }
00988 else
00989 {
00990 _dbus_warn_check_failed ("Re-entrant call to %s\n", _DBUS_FUNCTION_NAME);
00991 result = FALSE;
00992 }
00993 server->timeouts = timeouts;
00994 SERVER_UNLOCK (server);
00995
00996 return result;
00997 }
00998
01012 dbus_bool_t
01013 dbus_server_set_auth_mechanisms (DBusServer *server,
01014 const char **mechanisms)
01015 {
01016 char **copy;
01017
01018 _dbus_return_val_if_fail (server != NULL, FALSE);
01019
01020 SERVER_LOCK (server);
01021
01022 if (mechanisms != NULL)
01023 {
01024 copy = _dbus_dup_string_array (mechanisms);
01025 if (copy == NULL)
01026 return FALSE;
01027 }
01028 else
01029 copy = NULL;
01030
01031 dbus_free_string_array (server->auth_mechanisms);
01032 server->auth_mechanisms = copy;
01033
01034 SERVER_UNLOCK (server);
01035
01036 return TRUE;
01037 }
01038
01039
01040 static DBusDataSlotAllocator slot_allocator;
01041 _DBUS_DEFINE_GLOBAL_LOCK (server_slots);
01042
01057 dbus_bool_t
01058 dbus_server_allocate_data_slot (dbus_int32_t *slot_p)
01059 {
01060 return _dbus_data_slot_allocator_alloc (&slot_allocator,
01061 (DBusMutex **)&_DBUS_LOCK_NAME (server_slots),
01062 slot_p);
01063 }
01064
01076 void
01077 dbus_server_free_data_slot (dbus_int32_t *slot_p)
01078 {
01079 _dbus_return_if_fail (*slot_p >= 0);
01080
01081 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
01082 }
01083
01097 dbus_bool_t
01098 dbus_server_set_data (DBusServer *server,
01099 int slot,
01100 void *data,
01101 DBusFreeFunction free_data_func)
01102 {
01103 DBusFreeFunction old_free_func;
01104 void *old_data;
01105 dbus_bool_t retval;
01106
01107 _dbus_return_val_if_fail (server != NULL, FALSE);
01108
01109 SERVER_LOCK (server);
01110
01111 retval = _dbus_data_slot_list_set (&slot_allocator,
01112 &server->slot_list,
01113 slot, data, free_data_func,
01114 &old_free_func, &old_data);
01115
01116
01117 SERVER_UNLOCK (server);
01118
01119 if (retval)
01120 {
01121
01122 if (old_free_func)
01123 (* old_free_func) (old_data);
01124 }
01125
01126 return retval;
01127 }
01128
01137 void*
01138 dbus_server_get_data (DBusServer *server,
01139 int slot)
01140 {
01141 void *res;
01142
01143 _dbus_return_val_if_fail (server != NULL, NULL);
01144
01145 SERVER_LOCK (server);
01146
01147 res = _dbus_data_slot_list_get (&slot_allocator,
01148 &server->slot_list,
01149 slot);
01150
01151 SERVER_UNLOCK (server);
01152
01153 return res;
01154 }
01155
01158 #ifdef DBUS_BUILD_TESTS
01159 #include "dbus-test.h"
01160 #include <string.h>
01161
01162 dbus_bool_t
01163 _dbus_server_test (void)
01164 {
01165 const char *valid_addresses[] = {
01166 "tcp:port=1234",
01167 "tcp:host=localhost,port=1234",
01168 "tcp:host=localhost,port=1234;tcp:port=5678",
01169 #ifdef DBUS_UNIX
01170 "unix:path=./boogie",
01171 "tcp:port=1234;unix:path=./boogie",
01172 #endif
01173 };
01174
01175 DBusServer *server;
01176 int i;
01177
01178 for (i = 0; i < _DBUS_N_ELEMENTS (valid_addresses); i++)
01179 {
01180 DBusError error = DBUS_ERROR_INIT;
01181 char *address;
01182 char *id;
01183
01184 server = dbus_server_listen (valid_addresses[i], &error);
01185 if (server == NULL)
01186 {
01187 _dbus_warn ("server listen error: %s: %s\n", error.name, error.message);
01188 dbus_error_free (&error);
01189 _dbus_assert_not_reached ("Failed to listen for valid address.");
01190 }
01191
01192 id = dbus_server_get_id (server);
01193 _dbus_assert (id != NULL);
01194 address = dbus_server_get_address (server);
01195 _dbus_assert (address != NULL);
01196
01197 if (strstr (address, id) == NULL)
01198 {
01199 _dbus_warn ("server id '%s' is not in the server address '%s'\n",
01200 id, address);
01201 _dbus_assert_not_reached ("bad server id or address");
01202 }
01203
01204 dbus_free (id);
01205 dbus_free (address);
01206
01207 dbus_server_disconnect (server);
01208 dbus_server_unref (server);
01209 }
01210
01211 return TRUE;
01212 }
01213
01214 #endif