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
00103 #ifdef DBUS_DISABLE_ASSERT
00104 _dbus_atomic_inc (&server->refcount);
00105 #else
00106 {
00107 dbus_int32_t old_refcount = _dbus_atomic_inc (&server->refcount);
00108
00109 _dbus_assert (old_refcount == 0);
00110 }
00111 #endif
00112
00113 server->address = NULL;
00114 server->watches = NULL;
00115 server->timeouts = NULL;
00116 server->published_address = FALSE;
00117
00118 if (!_dbus_string_init (&server->guid_hex))
00119 return FALSE;
00120
00121 _dbus_generate_uuid (&server->guid);
00122
00123 if (!_dbus_uuid_encode (&server->guid, &server->guid_hex))
00124 goto failed;
00125
00126 server->address = copy_address_with_guid_appended (address,
00127 &server->guid_hex);
00128 if (server->address == NULL)
00129 goto failed;
00130
00131 _dbus_mutex_new_at_location (&server->mutex);
00132 if (server->mutex == NULL)
00133 goto failed;
00134
00135 server->watches = _dbus_watch_list_new ();
00136 if (server->watches == NULL)
00137 goto failed;
00138
00139 server->timeouts = _dbus_timeout_list_new ();
00140 if (server->timeouts == NULL)
00141 goto failed;
00142
00143 _dbus_data_slot_list_init (&server->slot_list);
00144
00145 _dbus_verbose ("Initialized server on address %s\n", server->address);
00146
00147 return TRUE;
00148
00149 failed:
00150 _dbus_mutex_free_at_location (&server->mutex);
00151 server->mutex = NULL;
00152 if (server->watches)
00153 {
00154 _dbus_watch_list_free (server->watches);
00155 server->watches = NULL;
00156 }
00157 if (server->timeouts)
00158 {
00159 _dbus_timeout_list_free (server->timeouts);
00160 server->timeouts = NULL;
00161 }
00162 if (server->address)
00163 {
00164 dbus_free (server->address);
00165 server->address = NULL;
00166 }
00167 _dbus_string_free (&server->guid_hex);
00168
00169 return FALSE;
00170 }
00171
00178 void
00179 _dbus_server_finalize_base (DBusServer *server)
00180 {
00181
00182
00183
00184 #ifndef DBUS_DISABLE_CHECKS
00185 _dbus_assert (!server->have_server_lock);
00186 #endif
00187 _dbus_assert (server->disconnected);
00188
00189
00190 _dbus_data_slot_list_free (&server->slot_list);
00191
00192 dbus_server_set_new_connection_function (server, NULL, NULL, NULL);
00193
00194 _dbus_watch_list_free (server->watches);
00195 _dbus_timeout_list_free (server->timeouts);
00196
00197 _dbus_mutex_free_at_location (&server->mutex);
00198
00199 dbus_free (server->address);
00200
00201 dbus_free_string_array (server->auth_mechanisms);
00202
00203 _dbus_string_free (&server->guid_hex);
00204 }
00205
00206
00208 typedef dbus_bool_t (* DBusWatchAddFunction) (DBusWatchList *list,
00209 DBusWatch *watch);
00211 typedef void (* DBusWatchRemoveFunction) (DBusWatchList *list,
00212 DBusWatch *watch);
00214 typedef void (* DBusWatchToggleFunction) (DBusWatchList *list,
00215 DBusWatch *watch,
00216 dbus_bool_t enabled);
00217
00218 static dbus_bool_t
00219 protected_change_watch (DBusServer *server,
00220 DBusWatch *watch,
00221 DBusWatchAddFunction add_function,
00222 DBusWatchRemoveFunction remove_function,
00223 DBusWatchToggleFunction toggle_function,
00224 dbus_bool_t enabled)
00225 {
00226 DBusWatchList *watches;
00227 dbus_bool_t retval;
00228
00229 HAVE_LOCK_CHECK (server);
00230
00231
00232
00233
00234
00235
00236 watches = server->watches;
00237 if (watches)
00238 {
00239 server->watches = NULL;
00240 _dbus_server_ref_unlocked (server);
00241 SERVER_UNLOCK (server);
00242
00243 if (add_function)
00244 retval = (* add_function) (watches, watch);
00245 else if (remove_function)
00246 {
00247 retval = TRUE;
00248 (* remove_function) (watches, watch);
00249 }
00250 else
00251 {
00252 retval = TRUE;
00253 (* toggle_function) (watches, watch, enabled);
00254 }
00255
00256 SERVER_LOCK (server);
00257 server->watches = watches;
00258 _dbus_server_unref_unlocked (server);
00259
00260 return retval;
00261 }
00262 else
00263 return FALSE;
00264 }
00265
00273 dbus_bool_t
00274 _dbus_server_add_watch (DBusServer *server,
00275 DBusWatch *watch)
00276 {
00277 HAVE_LOCK_CHECK (server);
00278 return protected_change_watch (server, watch,
00279 _dbus_watch_list_add_watch,
00280 NULL, NULL, FALSE);
00281 }
00282
00289 void
00290 _dbus_server_remove_watch (DBusServer *server,
00291 DBusWatch *watch)
00292 {
00293 HAVE_LOCK_CHECK (server);
00294 protected_change_watch (server, watch,
00295 NULL,
00296 _dbus_watch_list_remove_watch,
00297 NULL, FALSE);
00298 }
00299
00309 void
00310 _dbus_server_toggle_watch (DBusServer *server,
00311 DBusWatch *watch,
00312 dbus_bool_t enabled)
00313 {
00314 _dbus_assert (watch != NULL);
00315
00316 HAVE_LOCK_CHECK (server);
00317 protected_change_watch (server, watch,
00318 NULL, NULL,
00319 _dbus_watch_list_toggle_watch,
00320 enabled);
00321 }
00322
00324 typedef dbus_bool_t (* DBusTimeoutAddFunction) (DBusTimeoutList *list,
00325 DBusTimeout *timeout);
00327 typedef void (* DBusTimeoutRemoveFunction) (DBusTimeoutList *list,
00328 DBusTimeout *timeout);
00330 typedef void (* DBusTimeoutToggleFunction) (DBusTimeoutList *list,
00331 DBusTimeout *timeout,
00332 dbus_bool_t enabled);
00333
00334
00335 static dbus_bool_t
00336 protected_change_timeout (DBusServer *server,
00337 DBusTimeout *timeout,
00338 DBusTimeoutAddFunction add_function,
00339 DBusTimeoutRemoveFunction remove_function,
00340 DBusTimeoutToggleFunction toggle_function,
00341 dbus_bool_t enabled)
00342 {
00343 DBusTimeoutList *timeouts;
00344 dbus_bool_t retval;
00345
00346 HAVE_LOCK_CHECK (server);
00347
00348
00349
00350
00351
00352 timeouts = server->timeouts;
00353 if (timeouts)
00354 {
00355 server->timeouts = NULL;
00356 _dbus_server_ref_unlocked (server);
00357 SERVER_UNLOCK (server);
00358
00359 if (add_function)
00360 retval = (* add_function) (timeouts, timeout);
00361 else if (remove_function)
00362 {
00363 retval = TRUE;
00364 (* remove_function) (timeouts, timeout);
00365 }
00366 else
00367 {
00368 retval = TRUE;
00369 (* toggle_function) (timeouts, timeout, enabled);
00370 }
00371
00372 SERVER_LOCK (server);
00373 server->timeouts = timeouts;
00374 _dbus_server_unref_unlocked (server);
00375
00376 return retval;
00377 }
00378 else
00379 return FALSE;
00380 }
00381
00391 dbus_bool_t
00392 _dbus_server_add_timeout (DBusServer *server,
00393 DBusTimeout *timeout)
00394 {
00395 return protected_change_timeout (server, timeout,
00396 _dbus_timeout_list_add_timeout,
00397 NULL, NULL, FALSE);
00398 }
00399
00406 void
00407 _dbus_server_remove_timeout (DBusServer *server,
00408 DBusTimeout *timeout)
00409 {
00410 protected_change_timeout (server, timeout,
00411 NULL,
00412 _dbus_timeout_list_remove_timeout,
00413 NULL, FALSE);
00414 }
00415
00425 void
00426 _dbus_server_toggle_timeout (DBusServer *server,
00427 DBusTimeout *timeout,
00428 dbus_bool_t enabled)
00429 {
00430 protected_change_timeout (server, timeout,
00431 NULL, NULL,
00432 _dbus_timeout_list_toggle_timeout,
00433 enabled);
00434 }
00435
00436
00442 void
00443 _dbus_server_ref_unlocked (DBusServer *server)
00444 {
00445 _dbus_assert (server != NULL);
00446 HAVE_LOCK_CHECK (server);
00447
00448 #ifdef DBUS_DISABLE_ASSERT
00449 _dbus_atomic_inc (&server->refcount);
00450 #else
00451 {
00452 dbus_int32_t old_refcount = _dbus_atomic_inc (&server->refcount);
00453
00454 _dbus_assert (old_refcount > 0);
00455 }
00456 #endif
00457 }
00458
00464 void
00465 _dbus_server_unref_unlocked (DBusServer *server)
00466 {
00467 dbus_int32_t old_refcount;
00468
00469
00470
00471 _dbus_assert (server != NULL);
00472
00473 HAVE_LOCK_CHECK (server);
00474
00475 old_refcount = _dbus_atomic_dec (&server->refcount);
00476 _dbus_assert (old_refcount > 0);
00477
00478 if (old_refcount == 1)
00479 {
00480 _dbus_assert (server->disconnected);
00481
00482 SERVER_UNLOCK (server);
00483
00484 _dbus_assert (server->vtable->finalize != NULL);
00485
00486 (* server->vtable->finalize) (server);
00487 }
00488 }
00489
00511 static const struct {
00512 DBusServerListenResult (* func) (DBusAddressEntry *entry,
00513 DBusServer **server_p,
00514 DBusError *error);
00515 } listen_funcs[] = {
00516 { _dbus_server_listen_socket }
00517 , { _dbus_server_listen_platform_specific }
00518 #ifdef DBUS_BUILD_TESTS
00519 , { _dbus_server_listen_debug_pipe }
00520 #endif
00521 };
00522
00543 DBusServer*
00544 dbus_server_listen (const char *address,
00545 DBusError *error)
00546 {
00547 DBusServer *server;
00548 DBusAddressEntry **entries;
00549 int len, i;
00550 DBusError first_connect_error = DBUS_ERROR_INIT;
00551 dbus_bool_t handled_once;
00552
00553 _dbus_return_val_if_fail (address != NULL, NULL);
00554 _dbus_return_val_if_error_is_set (error, NULL);
00555
00556 if (!dbus_parse_address (address, &entries, &len, error))
00557 return NULL;
00558
00559 server = NULL;
00560 handled_once = FALSE;
00561
00562 for (i = 0; i < len; i++)
00563 {
00564 int j;
00565
00566 for (j = 0; j < (int) _DBUS_N_ELEMENTS (listen_funcs); ++j)
00567 {
00568 DBusServerListenResult result;
00569 DBusError tmp_error = DBUS_ERROR_INIT;
00570
00571 result = (* listen_funcs[j].func) (entries[i],
00572 &server,
00573 &tmp_error);
00574
00575 if (result == DBUS_SERVER_LISTEN_OK)
00576 {
00577 _dbus_assert (server != NULL);
00578 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00579 handled_once = TRUE;
00580 goto out;
00581 }
00582 else if (result == DBUS_SERVER_LISTEN_ADDRESS_ALREADY_USED)
00583 {
00584 _dbus_assert (server == NULL);
00585 dbus_set_error (error,
00586 DBUS_ERROR_ADDRESS_IN_USE,
00587 "Address '%s' already used",
00588 dbus_address_entry_get_method (entries[0]));
00589 handled_once = TRUE;
00590 goto out;
00591 }
00592 else if (result == DBUS_SERVER_LISTEN_BAD_ADDRESS)
00593 {
00594 _dbus_assert (server == NULL);
00595 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
00596 dbus_move_error (&tmp_error, error);
00597 handled_once = TRUE;
00598 goto out;
00599 }
00600 else if (result == DBUS_SERVER_LISTEN_NOT_HANDLED)
00601 {
00602 _dbus_assert (server == NULL);
00603 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00604
00605
00606 }
00607 else if (result == DBUS_SERVER_LISTEN_DID_NOT_CONNECT)
00608 {
00609 _dbus_assert (server == NULL);
00610 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
00611 if (!dbus_error_is_set (&first_connect_error))
00612 dbus_move_error (&tmp_error, &first_connect_error);
00613 else
00614 dbus_error_free (&tmp_error);
00615
00616 handled_once = TRUE;
00617
00618
00619 }
00620 }
00621
00622 _dbus_assert (server == NULL);
00623 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00624 }
00625
00626 out:
00627
00628 if (!handled_once)
00629 {
00630 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00631 if (len > 0)
00632 dbus_set_error (error,
00633 DBUS_ERROR_BAD_ADDRESS,
00634 "Unknown address type '%s'",
00635 dbus_address_entry_get_method (entries[0]));
00636 else
00637 dbus_set_error (error,
00638 DBUS_ERROR_BAD_ADDRESS,
00639 "Empty address '%s'",
00640 address);
00641 }
00642
00643 dbus_address_entries_free (entries);
00644
00645 if (server == NULL)
00646 {
00647 _dbus_assert (error == NULL || dbus_error_is_set (&first_connect_error) ||
00648 dbus_error_is_set (error));
00649
00650 if (error && dbus_error_is_set (error))
00651 {
00652
00653 }
00654 else
00655 {
00656
00657
00658
00659 _dbus_assert (error == NULL || dbus_error_is_set (&first_connect_error));
00660 dbus_move_error (&first_connect_error, error);
00661 }
00662
00663 _DBUS_ASSERT_ERROR_IS_CLEAR (&first_connect_error);
00664 _DBUS_ASSERT_ERROR_IS_SET (error);
00665
00666 return NULL;
00667 }
00668 else
00669 {
00670 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00671 return server;
00672 }
00673 }
00674
00681 DBusServer *
00682 dbus_server_ref (DBusServer *server)
00683 {
00684 _dbus_return_val_if_fail (server != NULL, NULL);
00685
00686 #ifdef DBUS_DISABLE_CHECKS
00687 _dbus_atomic_inc (&server->refcount);
00688 #else
00689 {
00690 dbus_int32_t old_refcount;
00691
00692
00693 old_refcount = _dbus_atomic_inc (&server->refcount);
00694
00695 if (_DBUS_UNLIKELY (old_refcount <= 0))
00696 {
00697
00698 _dbus_atomic_dec (&server->refcount);
00699 _dbus_warn_check_failed (_dbus_return_if_fail_warning_format,
00700 _DBUS_FUNCTION_NAME, "old_refcount > 0",
00701 __FILE__, __LINE__);
00702 return NULL;
00703 }
00704 }
00705 #endif
00706
00707 return server;
00708 }
00709
00718 void
00719 dbus_server_unref (DBusServer *server)
00720 {
00721 dbus_int32_t old_refcount;
00722
00723
00724
00725 _dbus_return_if_fail (server != NULL);
00726
00727
00728 old_refcount = _dbus_atomic_dec (&server->refcount);
00729
00730 #ifndef DBUS_DISABLE_CHECKS
00731 if (_DBUS_UNLIKELY (old_refcount <= 0))
00732 {
00733
00734 _dbus_atomic_inc (&server->refcount);
00735 _dbus_warn_check_failed (_dbus_return_if_fail_warning_format,
00736 _DBUS_FUNCTION_NAME, "old_refcount > 0",
00737 __FILE__, __LINE__);
00738 return;
00739 }
00740 #endif
00741
00742 if (old_refcount == 1)
00743 {
00744
00745 _dbus_assert (server->disconnected);
00746
00747 _dbus_assert (server->vtable->finalize != NULL);
00748
00749 (* server->vtable->finalize) (server);
00750 }
00751 }
00752
00761 void
00762 dbus_server_disconnect (DBusServer *server)
00763 {
00764 _dbus_return_if_fail (server != NULL);
00765
00766 #ifdef DBUS_DISABLE_CHECKS
00767 _dbus_atomic_inc (&server->refcount);
00768 #else
00769 {
00770 dbus_int32_t old_refcount = _dbus_atomic_inc (&server->refcount);
00771
00772 _dbus_return_if_fail (old_refcount > 0);
00773 }
00774 #endif
00775
00776 SERVER_LOCK (server);
00777
00778 _dbus_assert (server->vtable->disconnect != NULL);
00779
00780 if (!server->disconnected)
00781 {
00782
00783 server->disconnected = TRUE;
00784
00785 (* server->vtable->disconnect) (server);
00786 }
00787
00788 SERVER_UNLOCK (server);
00789 dbus_server_unref (server);
00790 }
00791
00797 dbus_bool_t
00798 dbus_server_get_is_connected (DBusServer *server)
00799 {
00800 dbus_bool_t retval;
00801
00802 _dbus_return_val_if_fail (server != NULL, FALSE);
00803
00804 SERVER_LOCK (server);
00805 retval = !server->disconnected;
00806 SERVER_UNLOCK (server);
00807
00808 return retval;
00809 }
00810
00818 char*
00819 dbus_server_get_address (DBusServer *server)
00820 {
00821 char *retval;
00822
00823 _dbus_return_val_if_fail (server != NULL, NULL);
00824
00825 SERVER_LOCK (server);
00826 retval = _dbus_strdup (server->address);
00827 SERVER_UNLOCK (server);
00828
00829 return retval;
00830 }
00831
00854 char*
00855 dbus_server_get_id (DBusServer *server)
00856 {
00857 char *retval;
00858
00859 _dbus_return_val_if_fail (server != NULL, NULL);
00860
00861 SERVER_LOCK (server);
00862 retval = NULL;
00863 _dbus_string_copy_data (&server->guid_hex, &retval);
00864 SERVER_UNLOCK (server);
00865
00866 return retval;
00867 }
00868
00889 void
00890 dbus_server_set_new_connection_function (DBusServer *server,
00891 DBusNewConnectionFunction function,
00892 void *data,
00893 DBusFreeFunction free_data_function)
00894 {
00895 DBusFreeFunction old_free_function;
00896 void *old_data;
00897
00898 _dbus_return_if_fail (server != NULL);
00899
00900 SERVER_LOCK (server);
00901 old_free_function = server->new_connection_free_data_function;
00902 old_data = server->new_connection_data;
00903
00904 server->new_connection_function = function;
00905 server->new_connection_data = data;
00906 server->new_connection_free_data_function = free_data_function;
00907 SERVER_UNLOCK (server);
00908
00909 if (old_free_function != NULL)
00910 (* old_free_function) (old_data);
00911 }
00912
00929 dbus_bool_t
00930 dbus_server_set_watch_functions (DBusServer *server,
00931 DBusAddWatchFunction add_function,
00932 DBusRemoveWatchFunction remove_function,
00933 DBusWatchToggledFunction toggled_function,
00934 void *data,
00935 DBusFreeFunction free_data_function)
00936 {
00937 dbus_bool_t result;
00938 DBusWatchList *watches;
00939
00940 _dbus_return_val_if_fail (server != NULL, FALSE);
00941
00942 SERVER_LOCK (server);
00943 watches = server->watches;
00944 server->watches = NULL;
00945 if (watches)
00946 {
00947 SERVER_UNLOCK (server);
00948 result = _dbus_watch_list_set_functions (watches,
00949 add_function,
00950 remove_function,
00951 toggled_function,
00952 data,
00953 free_data_function);
00954 SERVER_LOCK (server);
00955 }
00956 else
00957 {
00958 _dbus_warn_check_failed ("Re-entrant call to %s\n", _DBUS_FUNCTION_NAME);
00959 result = FALSE;
00960 }
00961 server->watches = watches;
00962 SERVER_UNLOCK (server);
00963
00964 return result;
00965 }
00966
00982 dbus_bool_t
00983 dbus_server_set_timeout_functions (DBusServer *server,
00984 DBusAddTimeoutFunction add_function,
00985 DBusRemoveTimeoutFunction remove_function,
00986 DBusTimeoutToggledFunction toggled_function,
00987 void *data,
00988 DBusFreeFunction free_data_function)
00989 {
00990 dbus_bool_t result;
00991 DBusTimeoutList *timeouts;
00992
00993 _dbus_return_val_if_fail (server != NULL, FALSE);
00994
00995 SERVER_LOCK (server);
00996 timeouts = server->timeouts;
00997 server->timeouts = NULL;
00998 if (timeouts)
00999 {
01000 SERVER_UNLOCK (server);
01001 result = _dbus_timeout_list_set_functions (timeouts,
01002 add_function,
01003 remove_function,
01004 toggled_function,
01005 data,
01006 free_data_function);
01007 SERVER_LOCK (server);
01008 }
01009 else
01010 {
01011 _dbus_warn_check_failed ("Re-entrant call to %s\n", _DBUS_FUNCTION_NAME);
01012 result = FALSE;
01013 }
01014 server->timeouts = timeouts;
01015 SERVER_UNLOCK (server);
01016
01017 return result;
01018 }
01019
01033 dbus_bool_t
01034 dbus_server_set_auth_mechanisms (DBusServer *server,
01035 const char **mechanisms)
01036 {
01037 char **copy;
01038
01039 _dbus_return_val_if_fail (server != NULL, FALSE);
01040
01041 SERVER_LOCK (server);
01042
01043 if (mechanisms != NULL)
01044 {
01045 copy = _dbus_dup_string_array (mechanisms);
01046 if (copy == NULL)
01047 return FALSE;
01048 }
01049 else
01050 copy = NULL;
01051
01052 dbus_free_string_array (server->auth_mechanisms);
01053 server->auth_mechanisms = copy;
01054
01055 SERVER_UNLOCK (server);
01056
01057 return TRUE;
01058 }
01059
01060
01061 static DBusDataSlotAllocator slot_allocator;
01062 _DBUS_DEFINE_GLOBAL_LOCK (server_slots);
01063
01078 dbus_bool_t
01079 dbus_server_allocate_data_slot (dbus_int32_t *slot_p)
01080 {
01081 return _dbus_data_slot_allocator_alloc (&slot_allocator,
01082 (DBusMutex **)&_DBUS_LOCK_NAME (server_slots),
01083 slot_p);
01084 }
01085
01097 void
01098 dbus_server_free_data_slot (dbus_int32_t *slot_p)
01099 {
01100 _dbus_return_if_fail (*slot_p >= 0);
01101
01102 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
01103 }
01104
01118 dbus_bool_t
01119 dbus_server_set_data (DBusServer *server,
01120 int slot,
01121 void *data,
01122 DBusFreeFunction free_data_func)
01123 {
01124 DBusFreeFunction old_free_func;
01125 void *old_data;
01126 dbus_bool_t retval;
01127
01128 _dbus_return_val_if_fail (server != NULL, FALSE);
01129
01130 SERVER_LOCK (server);
01131
01132 retval = _dbus_data_slot_list_set (&slot_allocator,
01133 &server->slot_list,
01134 slot, data, free_data_func,
01135 &old_free_func, &old_data);
01136
01137
01138 SERVER_UNLOCK (server);
01139
01140 if (retval)
01141 {
01142
01143 if (old_free_func)
01144 (* old_free_func) (old_data);
01145 }
01146
01147 return retval;
01148 }
01149
01158 void*
01159 dbus_server_get_data (DBusServer *server,
01160 int slot)
01161 {
01162 void *res;
01163
01164 _dbus_return_val_if_fail (server != NULL, NULL);
01165
01166 SERVER_LOCK (server);
01167
01168 res = _dbus_data_slot_list_get (&slot_allocator,
01169 &server->slot_list,
01170 slot);
01171
01172 SERVER_UNLOCK (server);
01173
01174 return res;
01175 }
01176
01179 #ifdef DBUS_BUILD_TESTS
01180 #include "dbus-test.h"
01181 #include <string.h>
01182
01183 dbus_bool_t
01184 _dbus_server_test (void)
01185 {
01186 const char *valid_addresses[] = {
01187 "tcp:port=1234",
01188 "tcp:host=localhost,port=1234",
01189 "tcp:host=localhost,port=1234;tcp:port=5678",
01190 #ifdef DBUS_UNIX
01191 "unix:path=./boogie",
01192 "tcp:port=1234;unix:path=./boogie",
01193 #endif
01194 };
01195
01196 DBusServer *server;
01197 int i;
01198
01199 for (i = 0; i < _DBUS_N_ELEMENTS (valid_addresses); i++)
01200 {
01201 DBusError error = DBUS_ERROR_INIT;
01202 char *address;
01203 char *id;
01204
01205 server = dbus_server_listen (valid_addresses[i], &error);
01206 if (server == NULL)
01207 {
01208 _dbus_warn ("server listen error: %s: %s\n", error.name, error.message);
01209 dbus_error_free (&error);
01210 _dbus_assert_not_reached ("Failed to listen for valid address.");
01211 }
01212
01213 id = dbus_server_get_id (server);
01214 _dbus_assert (id != NULL);
01215 address = dbus_server_get_address (server);
01216 _dbus_assert (address != NULL);
01217
01218 if (strstr (address, id) == NULL)
01219 {
01220 _dbus_warn ("server id '%s' is not in the server address '%s'\n",
01221 id, address);
01222 _dbus_assert_not_reached ("bad server id or address");
01223 }
01224
01225 dbus_free (id);
01226 dbus_free (address);
01227
01228 dbus_server_disconnect (server);
01229 dbus_server_unref (server);
01230 }
01231
01232 return TRUE;
01233 }
01234
01235 #endif