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