Merge branch 'socket-set-33337'
[platform/upstream/dbus.git] / dbus / 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
35 /**
36  * @defgroup DBusServer DBusServer
37  * @ingroup  DBus
38  * @brief Server that listens for new connections.
39  *
40  * A DBusServer represents a server that other applications
41  * can connect to. Each connection from another application
42  * is represented by a #DBusConnection.
43  *
44  * @todo Thread safety hasn't been tested much for #DBusServer
45  * @todo Need notification to apps of disconnection, may matter for some transports
46  */
47
48 /**
49  * @defgroup DBusServerInternals DBusServer implementation details
50  * @ingroup  DBusInternals
51  * @brief Implementation details of DBusServer
52  *
53  * @{
54  */
55
56 /* this is a little fragile since it assumes the address doesn't
57  * already have a guid, but it shouldn't
58  */
59 static char*
60 copy_address_with_guid_appended (const DBusString *address,
61                                  const DBusString *guid_hex)
62 {
63   DBusString with_guid;
64   char *retval;
65   
66   if (!_dbus_string_init (&with_guid))
67     return NULL;
68
69   if (!_dbus_string_copy (address, 0, &with_guid,
70                           _dbus_string_get_length (&with_guid)) ||
71       !_dbus_string_append (&with_guid, ",guid=") ||
72       !_dbus_string_copy (guid_hex, 0,
73                           &with_guid, _dbus_string_get_length (&with_guid)))
74     {
75       _dbus_string_free (&with_guid);
76       return NULL;
77     }
78
79   retval = NULL;
80   _dbus_string_steal_data (&with_guid, &retval);
81
82   _dbus_string_free (&with_guid);
83       
84   return retval; /* may be NULL if steal_data failed */
85 }
86
87 /**
88  * Initializes the members of the DBusServer base class.
89  * Chained up to by subclass constructors.
90  *
91  * @param server the server.
92  * @param vtable the vtable for the subclass.
93  * @param address the server's address
94  * @returns #TRUE on success.
95  */
96 dbus_bool_t
97 _dbus_server_init_base (DBusServer             *server,
98                         const DBusServerVTable *vtable,
99                         const DBusString       *address)
100 {
101   server->vtable = vtable;
102
103 #ifdef DBUS_DISABLE_ASSERT
104   _dbus_atomic_inc (&server->refcount);
105 #else
106     {
107       dbus_int32_t old_refcount = _dbus_atomic_inc (&server->refcount);
108
109       _dbus_assert (old_refcount == 0);
110     }
111 #endif
112
113   server->address = NULL;
114   server->watches = NULL;
115   server->timeouts = NULL;
116   server->published_address = FALSE;
117
118   if (!_dbus_string_init (&server->guid_hex))
119     return FALSE;
120
121   _dbus_generate_uuid (&server->guid);
122
123   if (!_dbus_uuid_encode (&server->guid, &server->guid_hex))
124     goto failed;
125   
126   server->address = copy_address_with_guid_appended (address,
127                                                      &server->guid_hex);
128   if (server->address == NULL)
129     goto failed;
130   
131   _dbus_mutex_new_at_location (&server->mutex);
132   if (server->mutex == NULL)
133     goto failed;
134   
135   server->watches = _dbus_watch_list_new ();
136   if (server->watches == NULL)
137     goto failed;
138
139   server->timeouts = _dbus_timeout_list_new ();
140   if (server->timeouts == NULL)
141     goto failed;
142
143   _dbus_data_slot_list_init (&server->slot_list);
144
145   _dbus_verbose ("Initialized server on address %s\n", server->address);
146   
147   return TRUE;
148
149  failed:
150   _dbus_mutex_free_at_location (&server->mutex);
151   server->mutex = NULL;
152   if (server->watches)
153     {
154       _dbus_watch_list_free (server->watches);
155       server->watches = NULL;
156     }
157   if (server->timeouts)
158     {
159       _dbus_timeout_list_free (server->timeouts);
160       server->timeouts = NULL;
161     }
162   if (server->address)
163     {
164       dbus_free (server->address);
165       server->address = NULL;
166     }
167   _dbus_string_free (&server->guid_hex);
168   
169   return FALSE;
170 }
171
172 /**
173  * Finalizes the members of the DBusServer base class.
174  * Chained up to by subclass finalizers.
175  *
176  * @param server the server.
177  */
178 void
179 _dbus_server_finalize_base (DBusServer *server)
180 {
181   /* We don't have the lock, but nobody should be accessing
182    * concurrently since they don't have a ref
183    */
184 #ifndef DBUS_DISABLE_CHECKS
185   _dbus_assert (!server->have_server_lock);
186 #endif
187   _dbus_assert (server->disconnected);
188   
189   /* calls out to application code... */
190   _dbus_data_slot_list_free (&server->slot_list);
191
192   dbus_server_set_new_connection_function (server, NULL, NULL, NULL);
193
194   _dbus_watch_list_free (server->watches);
195   _dbus_timeout_list_free (server->timeouts);
196
197   _dbus_mutex_free_at_location (&server->mutex);
198   
199   dbus_free (server->address);
200
201   dbus_free_string_array (server->auth_mechanisms);
202
203   _dbus_string_free (&server->guid_hex);
204 }
205
206
207 /** Function to be called in protected_change_watch() with refcount held */
208 typedef dbus_bool_t (* DBusWatchAddFunction)     (DBusWatchList *list,
209                                                   DBusWatch     *watch);
210 /** Function to be called in protected_change_watch() with refcount held */
211 typedef void        (* DBusWatchRemoveFunction)  (DBusWatchList *list,
212                                                   DBusWatch     *watch);
213 /** Function to be called in protected_change_watch() with refcount held */
214 typedef void        (* DBusWatchToggleFunction)  (DBusWatchList *list,
215                                                   DBusWatch     *watch,
216                                                   dbus_bool_t    enabled);
217
218 static dbus_bool_t
219 protected_change_watch (DBusServer             *server,
220                         DBusWatch              *watch,
221                         DBusWatchAddFunction    add_function,
222                         DBusWatchRemoveFunction remove_function,
223                         DBusWatchToggleFunction toggle_function,
224                         dbus_bool_t             enabled)
225 {
226   DBusWatchList *watches;
227   dbus_bool_t retval;
228   
229   HAVE_LOCK_CHECK (server);
230
231   /* This isn't really safe or reasonable; a better pattern is the "do
232    * everything, then drop lock and call out" one; but it has to be
233    * propagated up through all callers
234    */
235   
236   watches = server->watches;
237   if (watches)
238     {
239       server->watches = NULL;
240       _dbus_server_ref_unlocked (server);
241       SERVER_UNLOCK (server);
242
243       if (add_function)
244         retval = (* add_function) (watches, watch);
245       else if (remove_function)
246         {
247           retval = TRUE;
248           (* remove_function) (watches, watch);
249         }
250       else
251         {
252           retval = TRUE;
253           (* toggle_function) (watches, watch, enabled);
254         }
255       
256       SERVER_LOCK (server);
257       server->watches = watches;
258       _dbus_server_unref_unlocked (server);
259
260       return retval;
261     }
262   else
263     return FALSE;
264 }
265
266 /**
267  * Adds a watch for this server, chaining out to application-provided
268  * watch handlers.
269  *
270  * @param server the server.
271  * @param watch the watch to add.
272  */
273 dbus_bool_t
274 _dbus_server_add_watch (DBusServer *server,
275                         DBusWatch  *watch)
276 {
277   HAVE_LOCK_CHECK (server);
278   return protected_change_watch (server, watch,
279                                  _dbus_watch_list_add_watch,
280                                  NULL, NULL, FALSE);
281 }
282
283 /**
284  * Removes a watch previously added with _dbus_server_remove_watch().
285  *
286  * @param server the server.
287  * @param watch the watch to remove.
288  */
289 void
290 _dbus_server_remove_watch  (DBusServer *server,
291                             DBusWatch  *watch)
292 {
293   HAVE_LOCK_CHECK (server);
294   protected_change_watch (server, watch,
295                           NULL,
296                           _dbus_watch_list_remove_watch,
297                           NULL, FALSE);
298 }
299
300 /**
301  * Toggles a watch and notifies app via server's
302  * DBusWatchToggledFunction if available. It's an error to call this
303  * function on a watch that was not previously added.
304  *
305  * @param server the server.
306  * @param watch the watch to toggle.
307  * @param enabled whether to enable or disable
308  */
309 void
310 _dbus_server_toggle_watch (DBusServer  *server,
311                            DBusWatch   *watch,
312                            dbus_bool_t  enabled)
313 {
314   _dbus_assert (watch != NULL);
315
316   HAVE_LOCK_CHECK (server);
317   protected_change_watch (server, watch,
318                           NULL, NULL,
319                           _dbus_watch_list_toggle_watch,
320                           enabled);
321 }
322
323 /** Function to be called in protected_change_timeout() with refcount held */
324 typedef dbus_bool_t (* DBusTimeoutAddFunction)    (DBusTimeoutList *list,
325                                                    DBusTimeout     *timeout);
326 /** Function to be called in protected_change_timeout() with refcount held */
327 typedef void        (* DBusTimeoutRemoveFunction) (DBusTimeoutList *list,
328                                                    DBusTimeout     *timeout);
329 /** Function to be called in protected_change_timeout() with refcount held */
330 typedef void        (* DBusTimeoutToggleFunction) (DBusTimeoutList *list,
331                                                    DBusTimeout     *timeout,
332                                                    dbus_bool_t      enabled);
333
334
335 static dbus_bool_t
336 protected_change_timeout (DBusServer               *server,
337                           DBusTimeout              *timeout,
338                           DBusTimeoutAddFunction    add_function,
339                           DBusTimeoutRemoveFunction remove_function,
340                           DBusTimeoutToggleFunction toggle_function,
341                           dbus_bool_t               enabled)
342 {
343   DBusTimeoutList *timeouts;
344   dbus_bool_t retval;
345   
346   HAVE_LOCK_CHECK (server);
347
348   /* This isn't really safe or reasonable; a better pattern is the "do everything, then
349    * drop lock and call out" one; but it has to be propagated up through all callers
350    */
351   
352   timeouts = server->timeouts;
353   if (timeouts)
354     {
355       server->timeouts = NULL;
356       _dbus_server_ref_unlocked (server);
357       SERVER_UNLOCK (server);
358
359       if (add_function)
360         retval = (* add_function) (timeouts, timeout);
361       else if (remove_function)
362         {
363           retval = TRUE;
364           (* remove_function) (timeouts, timeout);
365         }
366       else
367         {
368           retval = TRUE;
369           (* toggle_function) (timeouts, timeout, enabled);
370         }
371       
372       SERVER_LOCK (server);
373       server->timeouts = timeouts;
374       _dbus_server_unref_unlocked (server);
375
376       return retval;
377     }
378   else
379     return FALSE;
380 }
381
382 /**
383  * Adds a timeout for this server, chaining out to
384  * application-provided timeout handlers. The timeout should be
385  * repeatedly handled with dbus_timeout_handle() at its given interval
386  * until it is removed.
387  *
388  * @param server the server.
389  * @param timeout the timeout to add.
390  */
391 dbus_bool_t
392 _dbus_server_add_timeout (DBusServer  *server,
393                           DBusTimeout *timeout)
394 {
395   return protected_change_timeout (server, timeout,
396                                    _dbus_timeout_list_add_timeout,
397                                    NULL, NULL, FALSE);
398 }
399
400 /**
401  * Removes a timeout previously added with _dbus_server_add_timeout().
402  *
403  * @param server the server.
404  * @param timeout the timeout to remove.
405  */
406 void
407 _dbus_server_remove_timeout (DBusServer  *server,
408                              DBusTimeout *timeout)
409 {
410   protected_change_timeout (server, timeout,
411                             NULL,
412                             _dbus_timeout_list_remove_timeout,
413                             NULL, FALSE);
414 }
415
416 /**
417  * Toggles a timeout and notifies app via server's
418  * DBusTimeoutToggledFunction if available. It's an error to call this
419  * function on a timeout that was not previously added.
420  *
421  * @param server the server.
422  * @param timeout the timeout to toggle.
423  * @param enabled whether to enable or disable
424  */
425 void
426 _dbus_server_toggle_timeout (DBusServer  *server,
427                              DBusTimeout *timeout,
428                              dbus_bool_t  enabled)
429 {
430   protected_change_timeout (server, timeout,
431                             NULL, NULL,
432                             _dbus_timeout_list_toggle_timeout,
433                             enabled);
434 }
435
436
437 /**
438  * Like dbus_server_ref() but does not acquire the lock (must already be held)
439  *
440  * @param server the server.
441  */
442 void
443 _dbus_server_ref_unlocked (DBusServer *server)
444 {
445   _dbus_assert (server != NULL);
446   HAVE_LOCK_CHECK (server);
447
448 #ifdef DBUS_DISABLE_ASSERT
449   _dbus_atomic_inc (&server->refcount);
450 #else
451     {
452       dbus_int32_t old_refcount = _dbus_atomic_inc (&server->refcount);
453
454       _dbus_assert (old_refcount > 0);
455     }
456 #endif
457 }
458
459 /**
460  * Like dbus_server_unref() but does not acquire the lock (must already be held)
461  *
462  * @param server the server.
463  */
464 void
465 _dbus_server_unref_unlocked (DBusServer *server)
466 {
467   dbus_int32_t old_refcount;
468
469   /* Keep this in sync with dbus_server_unref */
470
471   _dbus_assert (server != NULL);
472
473   HAVE_LOCK_CHECK (server);
474
475   old_refcount = _dbus_atomic_dec (&server->refcount);
476   _dbus_assert (old_refcount > 0);
477
478   if (old_refcount == 1)
479     {
480       _dbus_assert (server->disconnected);
481       
482       SERVER_UNLOCK (server);
483       
484       _dbus_assert (server->vtable->finalize != NULL);
485       
486       (* server->vtable->finalize) (server);
487     }
488 }
489
490 /** @} */
491
492 /**
493  * @addtogroup DBusServer
494  *
495  * @{
496  */
497
498
499 /**
500  * @typedef DBusServer
501  *
502  * An opaque object representing a server that listens for
503  * connections from other applications. Each time a connection
504  * is made, a new DBusConnection is created and made available
505  * via an application-provided DBusNewConnectionFunction.
506  * The DBusNewConnectionFunction is provided with
507  * dbus_server_set_new_connection_function().
508  * 
509  */
510
511 static const struct {
512   DBusServerListenResult (* func) (DBusAddressEntry *entry,
513                                    DBusServer      **server_p,
514                                    DBusError        *error);
515 } listen_funcs[] = {
516   { _dbus_server_listen_socket }
517   , { _dbus_server_listen_platform_specific }
518 #ifdef DBUS_BUILD_TESTS
519   , { _dbus_server_listen_debug_pipe }
520 #endif
521 };
522
523 /**
524  * Listens for new connections on the given address.  If there are
525  * multiple semicolon-separated address entries in the address, tries
526  * each one and listens on the first one that works.
527  * 
528  * Returns #NULL and sets error if listening fails for any reason.
529  * Otherwise returns a new #DBusServer.
530  * dbus_server_set_new_connection_function(),
531  * dbus_server_set_watch_functions(), and
532  * dbus_server_set_timeout_functions() should be called immediately to
533  * render the server fully functional.
534  *
535  * To free the server, applications must call first
536  * dbus_server_disconnect() and then dbus_server_unref().
537  * 
538  * @param address the address of this server.
539  * @param error location to store reason for failure.
540  * @returns a new #DBusServer, or #NULL on failure.
541  * 
542  */
543 DBusServer*
544 dbus_server_listen (const char     *address,
545                     DBusError      *error)
546 {
547   DBusServer *server;
548   DBusAddressEntry **entries;
549   int len, i;
550   DBusError first_connect_error = DBUS_ERROR_INIT;
551   dbus_bool_t handled_once;
552   
553   _dbus_return_val_if_fail (address != NULL, NULL);
554   _dbus_return_val_if_error_is_set (error, NULL);
555   
556   if (!dbus_parse_address (address, &entries, &len, error))
557     return NULL;
558
559   server = NULL;
560   handled_once = FALSE;
561
562   for (i = 0; i < len; i++)
563     {
564       int j;
565
566       for (j = 0; j < (int) _DBUS_N_ELEMENTS (listen_funcs); ++j)
567         {
568           DBusServerListenResult result;
569           DBusError tmp_error = DBUS_ERROR_INIT;
570
571           result = (* listen_funcs[j].func) (entries[i],
572                                              &server,
573                                              &tmp_error);
574
575           if (result == DBUS_SERVER_LISTEN_OK)
576             {
577               _dbus_assert (server != NULL);
578               _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
579               handled_once = TRUE;
580               goto out;
581             }
582           else if (result == DBUS_SERVER_LISTEN_ADDRESS_ALREADY_USED)
583             {
584               _dbus_assert (server == NULL);
585               dbus_set_error (error,
586                        DBUS_ERROR_ADDRESS_IN_USE,
587                        "Address '%s' already used",
588                        dbus_address_entry_get_method (entries[0]));
589               handled_once = TRUE;
590               goto out;
591             }
592           else if (result == DBUS_SERVER_LISTEN_BAD_ADDRESS)
593             {
594               _dbus_assert (server == NULL);
595               _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
596               dbus_move_error (&tmp_error, error);
597               handled_once = TRUE;
598               goto out;
599             }
600           else if (result == DBUS_SERVER_LISTEN_NOT_HANDLED)
601             {
602               _dbus_assert (server == NULL);
603               _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
604
605               /* keep trying addresses */
606             }
607           else if (result == DBUS_SERVER_LISTEN_DID_NOT_CONNECT)
608             {
609               _dbus_assert (server == NULL);
610               _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
611               if (!dbus_error_is_set (&first_connect_error))
612                 dbus_move_error (&tmp_error, &first_connect_error);
613               else
614                 dbus_error_free (&tmp_error);
615
616               handled_once = TRUE;
617               
618               /* keep trying addresses */
619             }
620         }
621
622       _dbus_assert (server == NULL);
623       _DBUS_ASSERT_ERROR_IS_CLEAR (error);
624     }
625
626  out:
627
628   if (!handled_once)
629     {
630       _DBUS_ASSERT_ERROR_IS_CLEAR (error);
631       if (len > 0)
632         dbus_set_error (error,
633                        DBUS_ERROR_BAD_ADDRESS,
634                        "Unknown address type '%s'",
635                        dbus_address_entry_get_method (entries[0]));
636       else
637         dbus_set_error (error,
638                         DBUS_ERROR_BAD_ADDRESS,
639                         "Empty address '%s'",
640                         address);
641     }
642   
643   dbus_address_entries_free (entries);
644
645   if (server == NULL)
646     {
647       _dbus_assert (error == NULL || dbus_error_is_set (&first_connect_error) ||
648                    dbus_error_is_set (error));
649       
650       if (error && dbus_error_is_set (error))
651         {
652           /* already set the error */
653         }
654       else
655         {
656           /* didn't set the error but either error should be
657            * NULL or first_connect_error should be set.
658            */
659           _dbus_assert (error == NULL || dbus_error_is_set (&first_connect_error));
660           dbus_move_error (&first_connect_error, error);
661         }
662
663       _DBUS_ASSERT_ERROR_IS_CLEAR (&first_connect_error); /* be sure we freed it */
664       _DBUS_ASSERT_ERROR_IS_SET (error);
665
666       return NULL;
667     }
668   else
669     {
670       _DBUS_ASSERT_ERROR_IS_CLEAR (error);
671       return server;
672     }
673 }
674
675 /**
676  * Increments the reference count of a DBusServer.
677  *
678  * @param server the server.
679  * @returns the server
680  */
681 DBusServer *
682 dbus_server_ref (DBusServer *server)
683 {
684   _dbus_return_val_if_fail (server != NULL, NULL);
685
686 #ifdef DBUS_DISABLE_CHECKS
687   _dbus_atomic_inc (&server->refcount);
688 #else
689     {
690       dbus_int32_t old_refcount;
691
692       /* can't get the refcount without a side-effect */
693       old_refcount = _dbus_atomic_inc (&server->refcount);
694
695       if (_DBUS_UNLIKELY (old_refcount <= 0))
696         {
697           /* undo side-effect first */
698           _dbus_atomic_dec (&server->refcount);
699           _dbus_warn_check_failed (_dbus_return_if_fail_warning_format,
700                                    _DBUS_FUNCTION_NAME, "old_refcount > 0",
701                                    __FILE__, __LINE__);
702           return NULL;
703         }
704     }
705 #endif
706
707   return server;
708 }
709
710 /**
711  * Decrements the reference count of a DBusServer.  Finalizes the
712  * server if the reference count reaches zero.
713  *
714  * The server must be disconnected before the refcount reaches zero.
715  *
716  * @param server the server.
717  */
718 void
719 dbus_server_unref (DBusServer *server)
720 {
721   dbus_int32_t old_refcount;
722
723   /* keep this in sync with unref_unlocked */
724
725   _dbus_return_if_fail (server != NULL);
726
727   /* can't get the refcount without a side-effect */
728   old_refcount = _dbus_atomic_dec (&server->refcount);
729
730 #ifndef DBUS_DISABLE_CHECKS
731   if (_DBUS_UNLIKELY (old_refcount <= 0))
732     {
733       /* undo side-effect first */
734       _dbus_atomic_inc (&server->refcount);
735       _dbus_warn_check_failed (_dbus_return_if_fail_warning_format,
736                                _DBUS_FUNCTION_NAME, "old_refcount > 0",
737                                __FILE__, __LINE__);
738       return;
739     }
740 #endif
741
742   if (old_refcount == 1)
743     {
744       /* lock not held! */
745       _dbus_assert (server->disconnected);
746       
747       _dbus_assert (server->vtable->finalize != NULL);
748       
749       (* server->vtable->finalize) (server);
750     }
751 }
752
753 /**
754  * Releases the server's address and stops listening for
755  * new clients. If called more than once, only the first
756  * call has an effect. Does not modify the server's
757  * reference count.
758  * 
759  * @param server the server.
760  */
761 void
762 dbus_server_disconnect (DBusServer *server)
763 {
764   _dbus_return_if_fail (server != NULL);
765
766 #ifdef DBUS_DISABLE_CHECKS
767   _dbus_atomic_inc (&server->refcount);
768 #else
769     {
770       dbus_int32_t old_refcount = _dbus_atomic_inc (&server->refcount);
771
772       _dbus_return_if_fail (old_refcount > 0);
773     }
774 #endif
775
776   SERVER_LOCK (server);
777
778   _dbus_assert (server->vtable->disconnect != NULL);
779
780   if (!server->disconnected)
781     {
782       /* this has to be first so recursive calls to disconnect don't happen */
783       server->disconnected = TRUE;
784       
785       (* server->vtable->disconnect) (server);
786     }
787
788   SERVER_UNLOCK (server);
789   dbus_server_unref (server);
790 }
791
792 /**
793  * Returns #TRUE if the server is still listening for new connections.
794  *
795  * @param server the server.
796  */
797 dbus_bool_t
798 dbus_server_get_is_connected (DBusServer *server)
799 {
800   dbus_bool_t retval;
801   
802   _dbus_return_val_if_fail (server != NULL, FALSE);
803
804   SERVER_LOCK (server);
805   retval = !server->disconnected;
806   SERVER_UNLOCK (server);
807
808   return retval;
809 }
810
811 /**
812  * Returns the address of the server, as a newly-allocated
813  * string which must be freed by the caller.
814  *
815  * @param server the server
816  * @returns the address or #NULL if no memory
817  */
818 char*
819 dbus_server_get_address (DBusServer *server)
820 {
821   char *retval;
822   
823   _dbus_return_val_if_fail (server != NULL, NULL);
824
825   SERVER_LOCK (server);
826   retval = _dbus_strdup (server->address);
827   SERVER_UNLOCK (server);
828
829   return retval;
830 }
831
832 /**
833  * Returns the unique ID of the server, as a newly-allocated
834  * string which must be freed by the caller. This ID is
835  * normally used by clients to tell when two #DBusConnection
836  * would be equivalent (because the server address passed
837  * to dbus_connection_open() will have the same guid in the
838  * two cases). dbus_connection_open() can re-use an existing
839  * connection with the same ID instead of opening a new
840  * connection.
841  *
842  * This is an ID unique to each #DBusServer. Remember that
843  * a #DBusServer represents only one mode of connecting,
844  * so e.g. a bus daemon can listen on multiple addresses
845  * which will mean it has multiple #DBusServer each with
846  * their own ID.
847  *
848  * The ID is not a UUID in the sense of RFC4122; the details
849  * are explained in the D-Bus specification.
850  *
851  * @param server the server
852  * @returns the id of the server or #NULL if no memory
853  */
854 char*
855 dbus_server_get_id (DBusServer *server)
856 {
857   char *retval;
858   
859   _dbus_return_val_if_fail (server != NULL, NULL);
860
861   SERVER_LOCK (server);
862   retval = NULL;
863   _dbus_string_copy_data (&server->guid_hex, &retval);
864   SERVER_UNLOCK (server);
865
866   return retval;
867 }
868
869 /**
870  * Sets a function to be used for handling new connections.  The given
871  * function is passed each new connection as the connection is
872  * created. If the new connection function increments the connection's
873  * reference count, the connection will stay alive. Otherwise, the
874  * connection will be unreferenced and closed. The new connection
875  * function may also close the connection itself, which is considered
876  * good form if the connection is not wanted.
877  *
878  * The connection here is private in the sense of
879  * dbus_connection_open_private(), so if the new connection function
880  * keeps a reference it must arrange for the connection to be closed.
881  * i.e. libdbus does not own this connection once the new connection
882  * function takes a reference.
883  *
884  * @param server the server.
885  * @param function a function to handle new connections.
886  * @param data data to pass to the new connection handler.
887  * @param free_data_function function to free the data.
888  */
889 void
890 dbus_server_set_new_connection_function (DBusServer                *server,
891                                          DBusNewConnectionFunction  function,
892                                          void                      *data,
893                                          DBusFreeFunction           free_data_function)
894 {
895   DBusFreeFunction old_free_function;
896   void *old_data;
897   
898   _dbus_return_if_fail (server != NULL);
899
900   SERVER_LOCK (server);
901   old_free_function = server->new_connection_free_data_function;
902   old_data = server->new_connection_data;
903   
904   server->new_connection_function = function;
905   server->new_connection_data = data;
906   server->new_connection_free_data_function = free_data_function;
907   SERVER_UNLOCK (server);
908     
909   if (old_free_function != NULL)
910     (* old_free_function) (old_data);
911 }
912
913 /**
914  * Sets the watch functions for the server. These functions are
915  * responsible for making the application's main loop aware of file
916  * descriptors that need to be monitored for events.
917  *
918  * This function behaves exactly like dbus_connection_set_watch_functions();
919  * see the documentation for that routine.
920  *
921  * @param server the server.
922  * @param add_function function to begin monitoring a new descriptor.
923  * @param remove_function function to stop monitoring a descriptor.
924  * @param toggled_function function to notify when the watch is enabled/disabled
925  * @param data data to pass to add_function and remove_function.
926  * @param free_data_function function to be called to free the data.
927  * @returns #FALSE on failure (no memory)
928  */
929 dbus_bool_t
930 dbus_server_set_watch_functions (DBusServer              *server,
931                                  DBusAddWatchFunction     add_function,
932                                  DBusRemoveWatchFunction  remove_function,
933                                  DBusWatchToggledFunction toggled_function,
934                                  void                    *data,
935                                  DBusFreeFunction         free_data_function)
936 {
937   dbus_bool_t result;
938   DBusWatchList *watches;
939   
940   _dbus_return_val_if_fail (server != NULL, FALSE);
941
942   SERVER_LOCK (server);
943   watches = server->watches;
944   server->watches = NULL;
945   if (watches)
946     {
947       SERVER_UNLOCK (server);
948       result = _dbus_watch_list_set_functions (watches,
949                                                add_function,
950                                                remove_function,
951                                                toggled_function,
952                                                data,
953                                                free_data_function);
954       SERVER_LOCK (server);
955     }
956   else
957     {
958       _dbus_warn_check_failed ("Re-entrant call to %s\n", _DBUS_FUNCTION_NAME);
959       result = FALSE;
960     }
961   server->watches = watches;
962   SERVER_UNLOCK (server);
963   
964   return result;
965 }
966
967 /**
968  * Sets the timeout functions for the server. These functions are
969  * responsible for making the application's main loop aware of timeouts.
970  *
971  * This function behaves exactly like dbus_connection_set_timeout_functions();
972  * see the documentation for that routine.
973  *
974  * @param server the server.
975  * @param add_function function to add a timeout.
976  * @param remove_function function to remove a timeout.
977  * @param toggled_function function to notify when the timeout is enabled/disabled
978  * @param data data to pass to add_function and remove_function.
979  * @param free_data_function function to be called to free the data.
980  * @returns #FALSE on failure (no memory)
981  */
982 dbus_bool_t
983 dbus_server_set_timeout_functions (DBusServer                *server,
984                                    DBusAddTimeoutFunction     add_function,
985                                    DBusRemoveTimeoutFunction  remove_function,
986                                    DBusTimeoutToggledFunction toggled_function,
987                                    void                      *data,
988                                    DBusFreeFunction           free_data_function)
989 {
990   dbus_bool_t result;
991   DBusTimeoutList *timeouts;
992   
993   _dbus_return_val_if_fail (server != NULL, FALSE);
994
995   SERVER_LOCK (server);
996   timeouts = server->timeouts;
997   server->timeouts = NULL;
998   if (timeouts)
999     {
1000       SERVER_UNLOCK (server);
1001       result = _dbus_timeout_list_set_functions (timeouts,
1002                                                  add_function,
1003                                                  remove_function,
1004                                                  toggled_function,
1005                                                  data,
1006                                                  free_data_function);
1007       SERVER_LOCK (server);
1008     }
1009   else
1010     {
1011       _dbus_warn_check_failed ("Re-entrant call to %s\n", _DBUS_FUNCTION_NAME);
1012       result = FALSE;
1013     }
1014   server->timeouts = timeouts;
1015   SERVER_UNLOCK (server);
1016   
1017   return result;
1018 }
1019
1020 /**
1021  * Sets the authentication mechanisms that this server offers to
1022  * clients, as a #NULL-terminated array of mechanism names. This
1023  * function only affects connections created <em>after</em> it is
1024  * called.  Pass #NULL instead of an array to use all available
1025  * mechanisms (this is the default behavior).
1026  *
1027  * The D-Bus specification describes some of the supported mechanisms.
1028  *
1029  * @param server the server
1030  * @param mechanisms #NULL-terminated array of mechanisms
1031  * @returns #FALSE if no memory
1032  */
1033 dbus_bool_t
1034 dbus_server_set_auth_mechanisms (DBusServer  *server,
1035                                  const char **mechanisms)
1036 {
1037   char **copy;
1038
1039   _dbus_return_val_if_fail (server != NULL, FALSE);
1040
1041   SERVER_LOCK (server);
1042   
1043   if (mechanisms != NULL)
1044     {
1045       copy = _dbus_dup_string_array (mechanisms);
1046       if (copy == NULL)
1047         return FALSE;
1048     }
1049   else
1050     copy = NULL;
1051
1052   dbus_free_string_array (server->auth_mechanisms);
1053   server->auth_mechanisms = copy;
1054
1055   SERVER_UNLOCK (server);
1056   
1057   return TRUE;
1058 }
1059
1060
1061 static DBusDataSlotAllocator slot_allocator;
1062 _DBUS_DEFINE_GLOBAL_LOCK (server_slots);
1063
1064 /**
1065  * Allocates an integer ID to be used for storing application-specific
1066  * data on any DBusServer. The allocated ID may then be used
1067  * with dbus_server_set_data() and dbus_server_get_data().
1068  * The slot must be initialized with -1. If a nonnegative
1069  * slot is passed in, the refcount is incremented on that
1070  * slot, rather than creating a new slot.
1071  *  
1072  * The allocated slot is global, i.e. all DBusServer objects will have
1073  * a slot with the given integer ID reserved.
1074  *
1075  * @param slot_p address of global variable storing the slot ID
1076  * @returns #FALSE on no memory
1077  */
1078 dbus_bool_t
1079 dbus_server_allocate_data_slot (dbus_int32_t *slot_p)
1080 {
1081   return _dbus_data_slot_allocator_alloc (&slot_allocator,
1082                                           (DBusMutex **)&_DBUS_LOCK_NAME (server_slots),
1083                                           slot_p);
1084 }
1085
1086 /**
1087  * Deallocates a global ID for server data slots.
1088  * dbus_server_get_data() and dbus_server_set_data()
1089  * may no longer be used with this slot.
1090  * Existing data stored on existing DBusServer objects
1091  * will be freed when the server is finalized,
1092  * but may not be retrieved (and may only be replaced
1093  * if someone else reallocates the slot).
1094  *
1095  * @param slot_p address of the slot to deallocate
1096  */
1097 void
1098 dbus_server_free_data_slot (dbus_int32_t *slot_p)
1099 {
1100   _dbus_return_if_fail (*slot_p >= 0);
1101   
1102   _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
1103 }
1104
1105 /**
1106  * Stores a pointer on a DBusServer, along
1107  * with an optional function to be used for freeing
1108  * the data when the data is set again, or when
1109  * the server is finalized. The slot number
1110  * must have been allocated with dbus_server_allocate_data_slot().
1111  *
1112  * @param server the server
1113  * @param slot the slot number
1114  * @param data the data to store
1115  * @param free_data_func finalizer function for the data
1116  * @returns #TRUE if there was enough memory to store the data
1117  */
1118 dbus_bool_t
1119 dbus_server_set_data (DBusServer       *server,
1120                       int               slot,
1121                       void             *data,
1122                       DBusFreeFunction  free_data_func)
1123 {
1124   DBusFreeFunction old_free_func;
1125   void *old_data;
1126   dbus_bool_t retval;
1127
1128   _dbus_return_val_if_fail (server != NULL, FALSE);
1129
1130   SERVER_LOCK (server);
1131   
1132   retval = _dbus_data_slot_list_set (&slot_allocator,
1133                                      &server->slot_list,
1134                                      slot, data, free_data_func,
1135                                      &old_free_func, &old_data);
1136
1137
1138   SERVER_UNLOCK (server);
1139   
1140   if (retval)
1141     {
1142       /* Do the actual free outside the server lock */
1143       if (old_free_func)
1144         (* old_free_func) (old_data);
1145     }
1146
1147   return retval;
1148 }
1149
1150 /**
1151  * Retrieves data previously set with dbus_server_set_data().
1152  * The slot must still be allocated (must not have been freed).
1153  *
1154  * @param server the server
1155  * @param slot the slot to get data from
1156  * @returns the data, or #NULL if not found
1157  */
1158 void*
1159 dbus_server_get_data (DBusServer   *server,
1160                       int           slot)
1161 {
1162   void *res;
1163
1164   _dbus_return_val_if_fail (server != NULL, NULL);
1165   
1166   SERVER_LOCK (server);
1167   
1168   res = _dbus_data_slot_list_get (&slot_allocator,
1169                                   &server->slot_list,
1170                                   slot);
1171
1172   SERVER_UNLOCK (server);
1173   
1174   return res;
1175 }
1176
1177 /** @} */
1178
1179 #ifdef DBUS_BUILD_TESTS
1180 #include "dbus-test.h"
1181 #include <string.h>
1182
1183 dbus_bool_t
1184 _dbus_server_test (void)
1185 {
1186   const char *valid_addresses[] = {
1187     "tcp:port=1234",
1188     "tcp:host=localhost,port=1234",
1189     "tcp:host=localhost,port=1234;tcp:port=5678",
1190 #ifdef DBUS_UNIX
1191     "unix:path=./boogie",
1192     "tcp:port=1234;unix:path=./boogie",
1193 #endif
1194   };
1195
1196   DBusServer *server;
1197   int i;
1198   
1199   for (i = 0; i < _DBUS_N_ELEMENTS (valid_addresses); i++)
1200     {
1201       DBusError error = DBUS_ERROR_INIT;
1202       char *address;
1203       char *id;
1204
1205       server = dbus_server_listen (valid_addresses[i], &error);
1206       if (server == NULL)
1207         {
1208           _dbus_warn ("server listen error: %s: %s\n", error.name, error.message);
1209           dbus_error_free (&error);
1210           _dbus_assert_not_reached ("Failed to listen for valid address.");
1211         }
1212
1213       id = dbus_server_get_id (server);
1214       _dbus_assert (id != NULL);
1215       address = dbus_server_get_address (server);
1216       _dbus_assert (address != NULL);
1217
1218       if (strstr (address, id) == NULL)
1219         {
1220           _dbus_warn ("server id '%s' is not in the server address '%s'\n",
1221                       id, address);
1222           _dbus_assert_not_reached ("bad server id or address");
1223         }
1224
1225       dbus_free (id);
1226       dbus_free (address);
1227       
1228       dbus_server_disconnect (server);
1229       dbus_server_unref (server);
1230     }
1231
1232   return TRUE;
1233 }
1234
1235 #endif /* DBUS_BUILD_TESTS */