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