D-Bus  1.6.8
dbus-server.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-server.c DBusServer object
3  *
4  * Copyright (C) 2002, 2003, 2004, 2005 Red Hat Inc.
5  *
6  * Licensed under the Academic Free License version 2.1
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program 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
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  *
22  */
23 
24 #include <config.h>
25 #include "dbus-server.h"
26 #include "dbus-server-unix.h"
27 #include "dbus-server-socket.h"
28 #include "dbus-string.h"
29 #ifdef DBUS_BUILD_TESTS
30 #include "dbus-server-debug-pipe.h"
31 #endif
32 #include "dbus-address.h"
33 #include "dbus-protocol.h"
34 
56 #ifndef _dbus_server_trace_ref
57 void
58 _dbus_server_trace_ref (DBusServer *server,
59  int old_refcount,
60  int new_refcount,
61  const char *why)
62 {
63  static int enabled = -1;
64 
65  _dbus_trace_ref ("DBusServer", server, old_refcount, new_refcount, why,
66  "DBUS_SERVER_TRACE", &enabled);
67 }
68 #endif
69 
70 /* this is a little fragile since it assumes the address doesn't
71  * already have a guid, but it shouldn't
72  */
73 static char*
74 copy_address_with_guid_appended (const DBusString *address,
75  const DBusString *guid_hex)
76 {
77  DBusString with_guid;
78  char *retval;
79 
80  if (!_dbus_string_init (&with_guid))
81  return NULL;
82 
83  if (!_dbus_string_copy (address, 0, &with_guid,
84  _dbus_string_get_length (&with_guid)) ||
85  !_dbus_string_append (&with_guid, ",guid=") ||
86  !_dbus_string_copy (guid_hex, 0,
87  &with_guid, _dbus_string_get_length (&with_guid)))
88  {
89  _dbus_string_free (&with_guid);
90  return NULL;
91  }
92 
93  retval = NULL;
94  _dbus_string_steal_data (&with_guid, &retval);
95 
96  _dbus_string_free (&with_guid);
97 
98  return retval; /* may be NULL if steal_data failed */
99 }
100 
112  const DBusServerVTable *vtable,
113  const DBusString *address)
114 {
115  server->vtable = vtable;
116 
117 #ifdef DBUS_DISABLE_ASSERT
118  _dbus_atomic_inc (&server->refcount);
119 #else
120  {
121  dbus_int32_t old_refcount = _dbus_atomic_inc (&server->refcount);
122 
123  _dbus_assert (old_refcount == 0);
124  }
125 #endif
126 
127  server->address = NULL;
128  server->watches = NULL;
129  server->timeouts = NULL;
130  server->published_address = FALSE;
131 
132  if (!_dbus_string_init (&server->guid_hex))
133  return FALSE;
134 
135  _dbus_generate_uuid (&server->guid);
136 
137  if (!_dbus_uuid_encode (&server->guid, &server->guid_hex))
138  goto failed;
139 
140  server->address = copy_address_with_guid_appended (address,
141  &server->guid_hex);
142  if (server->address == NULL)
143  goto failed;
144 
146  if (server->mutex == NULL)
147  goto failed;
148 
149  server->watches = _dbus_watch_list_new ();
150  if (server->watches == NULL)
151  goto failed;
152 
153  server->timeouts = _dbus_timeout_list_new ();
154  if (server->timeouts == NULL)
155  goto failed;
156 
158 
159  _dbus_verbose ("Initialized server on address %s\n", server->address);
160 
161  return TRUE;
162 
163  failed:
165  server->mutex = NULL;
166  if (server->watches)
167  {
168  _dbus_watch_list_free (server->watches);
169  server->watches = NULL;
170  }
171  if (server->timeouts)
172  {
174  server->timeouts = NULL;
175  }
176  if (server->address)
177  {
178  dbus_free (server->address);
179  server->address = NULL;
180  }
181  _dbus_string_free (&server->guid_hex);
182 
183  return FALSE;
184 }
185 
192 void
194 {
195  /* We don't have the lock, but nobody should be accessing
196  * concurrently since they don't have a ref
197  */
198 #ifndef DBUS_DISABLE_CHECKS
199  _dbus_assert (!server->have_server_lock);
200 #endif
201  _dbus_assert (server->disconnected);
202 
203  /* calls out to application code... */
205 
207 
208  _dbus_watch_list_free (server->watches);
210 
212 
213  dbus_free (server->address);
214 
216 
217  _dbus_string_free (&server->guid_hex);
218 }
219 
220 
223  DBusWatch *watch);
225 typedef void (* DBusWatchRemoveFunction) (DBusWatchList *list,
226  DBusWatch *watch);
228 typedef void (* DBusWatchToggleFunction) (DBusWatchList *list,
229  DBusWatch *watch,
230  dbus_bool_t enabled);
231 
232 static dbus_bool_t
233 protected_change_watch (DBusServer *server,
234  DBusWatch *watch,
235  DBusWatchAddFunction add_function,
236  DBusWatchRemoveFunction remove_function,
237  DBusWatchToggleFunction toggle_function,
238  dbus_bool_t enabled)
239 {
240  DBusWatchList *watches;
241  dbus_bool_t retval;
242 
243  HAVE_LOCK_CHECK (server);
244 
245  /* This isn't really safe or reasonable; a better pattern is the "do
246  * everything, then drop lock and call out" one; but it has to be
247  * propagated up through all callers
248  */
249 
250  watches = server->watches;
251  if (watches)
252  {
253  server->watches = NULL;
254  _dbus_server_ref_unlocked (server);
255  SERVER_UNLOCK (server);
256 
257  if (add_function)
258  retval = (* add_function) (watches, watch);
259  else if (remove_function)
260  {
261  retval = TRUE;
262  (* remove_function) (watches, watch);
263  }
264  else
265  {
266  retval = TRUE;
267  (* toggle_function) (watches, watch, enabled);
268  }
269 
270  SERVER_LOCK (server);
271  server->watches = watches;
273 
274  return retval;
275  }
276  else
277  return FALSE;
278 }
279 
289  DBusWatch *watch)
290 {
291  HAVE_LOCK_CHECK (server);
292  return protected_change_watch (server, watch,
294  NULL, NULL, FALSE);
295 }
296 
303 void
305  DBusWatch *watch)
306 {
307  HAVE_LOCK_CHECK (server);
308  protected_change_watch (server, watch,
309  NULL,
311  NULL, FALSE);
312 }
313 
321 void
323  dbus_bool_t enabled)
324 {
325  _dbus_watch_list_toggle_all_watches (server->watches, enabled);
326 }
327 
330  DBusTimeout *timeout);
333  DBusTimeout *timeout);
336  DBusTimeout *timeout,
337  dbus_bool_t enabled);
338 
339 
340 static dbus_bool_t
341 protected_change_timeout (DBusServer *server,
342  DBusTimeout *timeout,
343  DBusTimeoutAddFunction add_function,
344  DBusTimeoutRemoveFunction remove_function,
345  DBusTimeoutToggleFunction toggle_function,
346  dbus_bool_t enabled)
347 {
348  DBusTimeoutList *timeouts;
349  dbus_bool_t retval;
350 
351  HAVE_LOCK_CHECK (server);
352 
353  /* This isn't really safe or reasonable; a better pattern is the "do everything, then
354  * drop lock and call out" one; but it has to be propagated up through all callers
355  */
356 
357  timeouts = server->timeouts;
358  if (timeouts)
359  {
360  server->timeouts = NULL;
361  _dbus_server_ref_unlocked (server);
362  SERVER_UNLOCK (server);
363 
364  if (add_function)
365  retval = (* add_function) (timeouts, timeout);
366  else if (remove_function)
367  {
368  retval = TRUE;
369  (* remove_function) (timeouts, timeout);
370  }
371  else
372  {
373  retval = TRUE;
374  (* toggle_function) (timeouts, timeout, enabled);
375  }
376 
377  SERVER_LOCK (server);
378  server->timeouts = timeouts;
380 
381  return retval;
382  }
383  else
384  return FALSE;
385 }
386 
398  DBusTimeout *timeout)
399 {
400  return protected_change_timeout (server, timeout,
402  NULL, NULL, FALSE);
403 }
404 
411 void
413  DBusTimeout *timeout)
414 {
415  protected_change_timeout (server, timeout,
416  NULL,
418  NULL, FALSE);
419 }
420 
430 void
432  DBusTimeout *timeout,
433  dbus_bool_t enabled)
434 {
435  protected_change_timeout (server, timeout,
436  NULL, NULL,
438  enabled);
439 }
440 
441 
447 void
449 {
450  dbus_int32_t old_refcount;
451 
452  _dbus_assert (server != NULL);
453  HAVE_LOCK_CHECK (server);
454 
455  old_refcount = _dbus_atomic_inc (&server->refcount);
456  _dbus_assert (old_refcount > 0);
457  _dbus_server_trace_ref (server, old_refcount, old_refcount + 1,
458  "ref_unlocked");
459 }
460 
466 void
468 {
469  dbus_int32_t old_refcount;
470 
471  /* Keep this in sync with dbus_server_unref */
472 
473  _dbus_assert (server != NULL);
474 
475  HAVE_LOCK_CHECK (server);
476 
477  old_refcount = _dbus_atomic_dec (&server->refcount);
478  _dbus_assert (old_refcount > 0);
479 
480  _dbus_server_trace_ref (server, old_refcount, old_refcount - 1,
481  "unref_unlocked");
482 
483  if (old_refcount == 1)
484  {
485  _dbus_assert (server->disconnected);
486 
487  SERVER_UNLOCK (server);
488 
489  _dbus_assert (server->vtable->finalize != NULL);
490 
491  (* server->vtable->finalize) (server);
492  }
493 }
494 
516 static const struct {
517  DBusServerListenResult (* func) (DBusAddressEntry *entry,
518  DBusServer **server_p,
519  DBusError *error);
520 } listen_funcs[] = {
523 #ifdef DBUS_BUILD_TESTS
524  , { _dbus_server_listen_debug_pipe }
525 #endif
526 };
527 
548 DBusServer*
549 dbus_server_listen (const char *address,
550  DBusError *error)
551 {
552  DBusServer *server;
553  DBusAddressEntry **entries;
554  int len, i;
555  DBusError first_connect_error = DBUS_ERROR_INIT;
556  dbus_bool_t handled_once;
557 
558  _dbus_return_val_if_fail (address != NULL, NULL);
559  _dbus_return_val_if_error_is_set (error, NULL);
560 
561  if (!dbus_parse_address (address, &entries, &len, error))
562  return NULL;
563 
564  server = NULL;
565  handled_once = FALSE;
566 
567  for (i = 0; i < len; i++)
568  {
569  int j;
570 
571  for (j = 0; j < (int) _DBUS_N_ELEMENTS (listen_funcs); ++j)
572  {
573  DBusServerListenResult result;
574  DBusError tmp_error = DBUS_ERROR_INIT;
575 
576  result = (* listen_funcs[j].func) (entries[i],
577  &server,
578  &tmp_error);
579 
580  if (result == DBUS_SERVER_LISTEN_OK)
581  {
582  _dbus_assert (server != NULL);
583  _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
584  handled_once = TRUE;
585  goto out;
586  }
587  else if (result == DBUS_SERVER_LISTEN_ADDRESS_ALREADY_USED)
588  {
589  _dbus_assert (server == NULL);
590  dbus_set_error (error,
592  "Address '%s' already used",
593  dbus_address_entry_get_method (entries[0]));
594  handled_once = TRUE;
595  goto out;
596  }
597  else if (result == DBUS_SERVER_LISTEN_BAD_ADDRESS)
598  {
599  _dbus_assert (server == NULL);
600  _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
601  dbus_move_error (&tmp_error, error);
602  handled_once = TRUE;
603  goto out;
604  }
605  else if (result == DBUS_SERVER_LISTEN_NOT_HANDLED)
606  {
607  _dbus_assert (server == NULL);
608  _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
609 
610  /* keep trying addresses */
611  }
612  else if (result == DBUS_SERVER_LISTEN_DID_NOT_CONNECT)
613  {
614  _dbus_assert (server == NULL);
615  _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
616  if (!dbus_error_is_set (&first_connect_error))
617  dbus_move_error (&tmp_error, &first_connect_error);
618  else
619  dbus_error_free (&tmp_error);
620 
621  handled_once = TRUE;
622 
623  /* keep trying addresses */
624  }
625  }
626 
627  _dbus_assert (server == NULL);
628  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
629  }
630 
631  out:
632 
633  if (!handled_once)
634  {
635  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
636  if (len > 0)
637  dbus_set_error (error,
639  "Unknown address type '%s'",
640  dbus_address_entry_get_method (entries[0]));
641  else
642  dbus_set_error (error,
644  "Empty address '%s'",
645  address);
646  }
647 
648  dbus_address_entries_free (entries);
649 
650  if (server == NULL)
651  {
652  _dbus_assert (error == NULL || dbus_error_is_set (&first_connect_error) ||
653  dbus_error_is_set (error));
654 
655  if (error && dbus_error_is_set (error))
656  {
657  /* already set the error */
658  }
659  else
660  {
661  /* didn't set the error but either error should be
662  * NULL or first_connect_error should be set.
663  */
664  _dbus_assert (error == NULL || dbus_error_is_set (&first_connect_error));
665  dbus_move_error (&first_connect_error, error);
666  }
667 
668  _DBUS_ASSERT_ERROR_IS_CLEAR (&first_connect_error); /* be sure we freed it */
669  _DBUS_ASSERT_ERROR_IS_SET (error);
670 
671  return NULL;
672  }
673  else
674  {
675  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
676  return server;
677  }
678 }
679 
686 DBusServer *
688 {
689  dbus_int32_t old_refcount;
690 
691  _dbus_return_val_if_fail (server != NULL, NULL);
692 
693  /* can't get the refcount without a side-effect */
694  old_refcount = _dbus_atomic_inc (&server->refcount);
695 
696 #ifndef DBUS_DISABLE_CHECKS
697  if (_DBUS_UNLIKELY (old_refcount <= 0))
698  {
699  /* undo side-effect first */
700  _dbus_atomic_dec (&server->refcount);
702  _DBUS_FUNCTION_NAME, "old_refcount > 0",
703  __FILE__, __LINE__);
704  return NULL;
705  }
706 #endif
707 
708  _dbus_server_trace_ref (server, old_refcount, old_refcount + 1, "ref");
709 
710  return server;
711 }
712 
721 void
723 {
724  dbus_int32_t old_refcount;
725 
726  /* keep this in sync with unref_unlocked */
727 
728  _dbus_return_if_fail (server != NULL);
729 
730  /* can't get the refcount without a side-effect */
731  old_refcount = _dbus_atomic_dec (&server->refcount);
732 
733 #ifndef DBUS_DISABLE_CHECKS
734  if (_DBUS_UNLIKELY (old_refcount <= 0))
735  {
736  /* undo side-effect first */
737  _dbus_atomic_inc (&server->refcount);
739  _DBUS_FUNCTION_NAME, "old_refcount > 0",
740  __FILE__, __LINE__);
741  return;
742  }
743 #endif
744 
745  _dbus_server_trace_ref (server, old_refcount, old_refcount - 1, "unref");
746 
747  if (old_refcount == 1)
748  {
749  /* lock not held! */
750  _dbus_assert (server->disconnected);
751 
752  _dbus_assert (server->vtable->finalize != NULL);
753 
754  (* server->vtable->finalize) (server);
755  }
756 }
757 
766 void
768 {
769  _dbus_return_if_fail (server != NULL);
770 
771 #ifdef DBUS_DISABLE_CHECKS
772  _dbus_atomic_inc (&server->refcount);
773 #else
774  {
775  dbus_int32_t old_refcount = _dbus_atomic_inc (&server->refcount);
776 
777  _dbus_return_if_fail (old_refcount > 0);
778  }
779 #endif
780 
781  SERVER_LOCK (server);
782 
783  _dbus_assert (server->vtable->disconnect != NULL);
784 
785  if (!server->disconnected)
786  {
787  /* this has to be first so recursive calls to disconnect don't happen */
788  server->disconnected = TRUE;
789 
790  (* server->vtable->disconnect) (server);
791  }
792 
793  SERVER_UNLOCK (server);
794  dbus_server_unref (server);
795 }
796 
804 {
805  dbus_bool_t retval;
806 
807  _dbus_return_val_if_fail (server != NULL, FALSE);
808 
809  SERVER_LOCK (server);
810  retval = !server->disconnected;
811  SERVER_UNLOCK (server);
812 
813  return retval;
814 }
815 
823 char*
825 {
826  char *retval;
827 
828  _dbus_return_val_if_fail (server != NULL, NULL);
829 
830  SERVER_LOCK (server);
831  retval = _dbus_strdup (server->address);
832  SERVER_UNLOCK (server);
833 
834  return retval;
835 }
836 
859 char*
861 {
862  char *retval;
863 
864  _dbus_return_val_if_fail (server != NULL, NULL);
865 
866  SERVER_LOCK (server);
867  retval = NULL;
868  _dbus_string_copy_data (&server->guid_hex, &retval);
869  SERVER_UNLOCK (server);
870 
871  return retval;
872 }
873 
894 void
896  DBusNewConnectionFunction function,
897  void *data,
898  DBusFreeFunction free_data_function)
899 {
900  DBusFreeFunction old_free_function;
901  void *old_data;
902 
903  _dbus_return_if_fail (server != NULL);
904 
905  SERVER_LOCK (server);
906  old_free_function = server->new_connection_free_data_function;
907  old_data = server->new_connection_data;
908 
909  server->new_connection_function = function;
910  server->new_connection_data = data;
911  server->new_connection_free_data_function = free_data_function;
912  SERVER_UNLOCK (server);
913 
914  if (old_free_function != NULL)
915  (* old_free_function) (old_data);
916 }
917 
936  DBusAddWatchFunction add_function,
937  DBusRemoveWatchFunction remove_function,
938  DBusWatchToggledFunction toggled_function,
939  void *data,
940  DBusFreeFunction free_data_function)
941 {
942  dbus_bool_t result;
943  DBusWatchList *watches;
944 
945  _dbus_return_val_if_fail (server != NULL, FALSE);
946 
947  SERVER_LOCK (server);
948  watches = server->watches;
949  server->watches = NULL;
950  if (watches)
951  {
952  SERVER_UNLOCK (server);
953  result = _dbus_watch_list_set_functions (watches,
954  add_function,
955  remove_function,
956  toggled_function,
957  data,
958  free_data_function);
959  SERVER_LOCK (server);
960  }
961  else
962  {
963  _dbus_warn_check_failed ("Re-entrant call to %s\n", _DBUS_FUNCTION_NAME);
964  result = FALSE;
965  }
966  server->watches = watches;
967  SERVER_UNLOCK (server);
968 
969  return result;
970 }
971 
989  DBusAddTimeoutFunction add_function,
990  DBusRemoveTimeoutFunction remove_function,
991  DBusTimeoutToggledFunction toggled_function,
992  void *data,
993  DBusFreeFunction free_data_function)
994 {
995  dbus_bool_t result;
996  DBusTimeoutList *timeouts;
997 
998  _dbus_return_val_if_fail (server != NULL, FALSE);
999 
1000  SERVER_LOCK (server);
1001  timeouts = server->timeouts;
1002  server->timeouts = NULL;
1003  if (timeouts)
1004  {
1005  SERVER_UNLOCK (server);
1006  result = _dbus_timeout_list_set_functions (timeouts,
1007  add_function,
1008  remove_function,
1009  toggled_function,
1010  data,
1011  free_data_function);
1012  SERVER_LOCK (server);
1013  }
1014  else
1015  {
1016  _dbus_warn_check_failed ("Re-entrant call to %s\n", _DBUS_FUNCTION_NAME);
1017  result = FALSE;
1018  }
1019  server->timeouts = timeouts;
1020  SERVER_UNLOCK (server);
1021 
1022  return result;
1023 }
1024 
1040  const char **mechanisms)
1041 {
1042  char **copy;
1043 
1044  _dbus_return_val_if_fail (server != NULL, FALSE);
1045 
1046  SERVER_LOCK (server);
1047 
1048  if (mechanisms != NULL)
1049  {
1050  copy = _dbus_dup_string_array (mechanisms);
1051  if (copy == NULL)
1052  return FALSE;
1053  }
1054  else
1055  copy = NULL;
1056 
1058  server->auth_mechanisms = copy;
1059 
1060  SERVER_UNLOCK (server);
1061 
1062  return TRUE;
1063 }
1064 
1065 
1066 static DBusDataSlotAllocator slot_allocator;
1067 _DBUS_DEFINE_GLOBAL_LOCK (server_slots);
1068 
1085 {
1086  return _dbus_data_slot_allocator_alloc (&slot_allocator,
1087  (DBusRMutex **)&_DBUS_LOCK_NAME (server_slots),
1088  slot_p);
1089 }
1090 
1102 void
1104 {
1105  _dbus_return_if_fail (*slot_p >= 0);
1106 
1107  _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
1108 }
1109 
1125  int slot,
1126  void *data,
1127  DBusFreeFunction free_data_func)
1128 {
1129  DBusFreeFunction old_free_func;
1130  void *old_data;
1131  dbus_bool_t retval;
1132 
1133  _dbus_return_val_if_fail (server != NULL, FALSE);
1134 
1135  SERVER_LOCK (server);
1136 
1137  retval = _dbus_data_slot_list_set (&slot_allocator,
1138  &server->slot_list,
1139  slot, data, free_data_func,
1140  &old_free_func, &old_data);
1141 
1142 
1143  SERVER_UNLOCK (server);
1144 
1145  if (retval)
1146  {
1147  /* Do the actual free outside the server lock */
1148  if (old_free_func)
1149  (* old_free_func) (old_data);
1150  }
1151 
1152  return retval;
1153 }
1154 
1163 void*
1165  int slot)
1166 {
1167  void *res;
1168 
1169  _dbus_return_val_if_fail (server != NULL, NULL);
1170 
1171  SERVER_LOCK (server);
1172 
1173  res = _dbus_data_slot_list_get (&slot_allocator,
1174  &server->slot_list,
1175  slot);
1176 
1177  SERVER_UNLOCK (server);
1178 
1179  return res;
1180 }
1181 
1184 #ifdef DBUS_BUILD_TESTS
1185 #include "dbus-test.h"
1186 #include <string.h>
1187 
1189 _dbus_server_test (void)
1190 {
1191  const char *valid_addresses[] = {
1192  "tcp:port=1234",
1193  "tcp:host=localhost,port=1234",
1194  "tcp:host=localhost,port=1234;tcp:port=5678",
1195 #ifdef DBUS_UNIX
1196  "unix:path=./boogie",
1197  "tcp:port=1234;unix:path=./boogie",
1198 #endif
1199  };
1200 
1201  DBusServer *server;
1202  int i;
1203 
1204  for (i = 0; i < _DBUS_N_ELEMENTS (valid_addresses); i++)
1205  {
1206  DBusError error = DBUS_ERROR_INIT;
1207  char *address;
1208  char *id;
1209 
1210  server = dbus_server_listen (valid_addresses[i], &error);
1211  if (server == NULL)
1212  {
1213  _dbus_warn ("server listen error: %s: %s\n", error.name, error.message);
1214  dbus_error_free (&error);
1215  _dbus_assert_not_reached ("Failed to listen for valid address.");
1216  }
1217 
1218  id = dbus_server_get_id (server);
1219  _dbus_assert (id != NULL);
1220  address = dbus_server_get_address (server);
1221  _dbus_assert (address != NULL);
1222 
1223  if (strstr (address, id) == NULL)
1224  {
1225  _dbus_warn ("server id '%s' is not in the server address '%s'\n",
1226  id, address);
1227  _dbus_assert_not_reached ("bad server id or address");
1228  }
1229 
1230  dbus_free (id);
1231  dbus_free (address);
1232 
1233  dbus_server_disconnect (server);
1234  dbus_server_unref (server);
1235  }
1236 
1237  return TRUE;
1238 }
1239 
1240 #endif /* DBUS_BUILD_TESTS */