107fde90285efd22a35f34035b86133b0ff3cee5
[platform/upstream/dbus.git] / dbus / dbus-bus.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-bus.c  Convenience functions for communicating with the bus.
3  *
4  * Copyright (C) 2003  CodeFactory AB
5  * Copyright (C) 2003  Red Hat, Inc.
6  *
7  * Licensed under the Academic Free License version 2.1
8  * 
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  * 
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  *
23  */
24
25 #include "dbus-bus.h"
26 #include "dbus-protocol.h"
27 #include "dbus-internals.h"
28 #include "dbus-message.h"
29 #include "dbus-marshal-validate.h"
30 #include "dbus-threads-internal.h"
31 #include <string.h>
32
33 /**
34  * @defgroup DBusBus Message bus APIs
35  * @ingroup DBus
36  * @brief Functions for communicating with the message bus
37  *
38  * @todo right now the default address of the system bus is hardcoded,
39  * so if you change it in the global config file suddenly you have to
40  * set DBUS_SYSTEM_BUS_ADDRESS env variable.  Might be nice if the
41  * client lib somehow read the config file, or if the bus on startup
42  * somehow wrote out its address to a well-known spot, but might also
43  * not be worth it.
44  */
45
46 /**
47  * @defgroup DBusBusInternals Message bus APIs internals
48  * @ingroup DBusInternals
49  * @brief Internals of functions for communicating with the message bus
50  *
51  * @{
52  */
53
54 /**
55  * Block of message-bus-related data we attach to each
56  * #DBusConnection used with these convenience functions.
57  *
58  */
59 typedef struct
60 {
61   DBusConnection *connection; /**< Connection we're associated with */
62   char *unique_name; /**< Unique name of this connection */
63
64   unsigned int is_well_known : 1; /**< Is one of the well-known connections in our global array */
65 } BusData;
66
67 /** The slot we have reserved to store BusData.
68  */
69 static dbus_int32_t bus_data_slot = -1;
70
71 /** Number of bus types */
72 #define N_BUS_TYPES 3
73
74 static DBusConnection *bus_connections[N_BUS_TYPES];
75 static char *bus_connection_addresses[N_BUS_TYPES] = { NULL, NULL, NULL };
76
77 static DBusBusType activation_bus_type = DBUS_BUS_STARTER;
78
79 static dbus_bool_t initialized = FALSE;
80
81 /**
82  * Lock for globals in this file
83  */
84 _DBUS_DEFINE_GLOBAL_LOCK (bus);
85
86 static void
87 addresses_shutdown_func (void *data)
88 {
89   int i;
90
91   i = 0;
92   while (i < N_BUS_TYPES)
93     {
94       if (bus_connections[i] != NULL)
95         _dbus_warn ("dbus_shutdown() called but connections were still live!");
96       
97       dbus_free (bus_connection_addresses[i]);
98       bus_connection_addresses[i] = NULL;
99       ++i;
100     }
101
102   activation_bus_type = DBUS_BUS_STARTER;
103 }
104
105 static dbus_bool_t
106 get_from_env (char           **connection_p,
107               const char      *env_var)
108 {
109   const char *s;
110   
111   _dbus_assert (*connection_p == NULL);
112   
113   s = _dbus_getenv (env_var);
114   if (s == NULL || *s == '\0')
115     return TRUE; /* successfully didn't use the env var */
116   else
117     {
118       *connection_p = _dbus_strdup (s);
119       return *connection_p != NULL;
120     }
121 }
122
123 static dbus_bool_t
124 init_connections_unlocked (void)
125 {
126   if (!initialized)
127     {
128       const char *s;
129       int i;
130
131       i = 0;
132       while (i < N_BUS_TYPES)
133         {
134           bus_connections[i] = NULL;
135           ++i;
136         }
137
138       /* Don't init these twice, we may run this code twice if
139        * init_connections_unlocked() fails midway through.
140        * In practice, each block below should contain only one
141        * "return FALSE" or running through twice may not
142        * work right.
143        */
144       
145        if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
146          {
147            _dbus_verbose ("Filling in system bus address...\n");
148            
149            if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SYSTEM],
150                               "DBUS_SYSTEM_BUS_ADDRESS"))
151              return FALSE;
152          }
153
154                   
155        if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
156          {
157            /* Use default system bus address if none set in environment */
158            bus_connection_addresses[DBUS_BUS_SYSTEM] =
159              _dbus_strdup (DBUS_SYSTEM_BUS_DEFAULT_ADDRESS);
160            if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
161              return FALSE;
162            
163            _dbus_verbose ("  used default system bus \"%s\"\n",
164                           bus_connection_addresses[DBUS_BUS_SYSTEM]);
165          }
166        else
167          _dbus_verbose ("  used env var system bus \"%s\"\n",
168                         bus_connection_addresses[DBUS_BUS_SYSTEM]);
169           
170       if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
171         {
172           _dbus_verbose ("Filling in session bus address...\n");
173           
174           if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SESSION],
175                              "DBUS_SESSION_BUS_ADDRESS"))
176             return FALSE;
177           _dbus_verbose ("  \"%s\"\n", bus_connection_addresses[DBUS_BUS_SESSION] ?
178                          bus_connection_addresses[DBUS_BUS_SESSION] : "none set");
179         }
180
181       if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
182         {
183           _dbus_verbose ("Filling in activation bus address...\n");
184           
185           if (!get_from_env (&bus_connection_addresses[DBUS_BUS_STARTER],
186                              "DBUS_STARTER_ADDRESS"))
187             return FALSE;
188           
189           _dbus_verbose ("  \"%s\"\n", bus_connection_addresses[DBUS_BUS_STARTER] ?
190                          bus_connection_addresses[DBUS_BUS_STARTER] : "none set");
191         }
192
193
194       if (bus_connection_addresses[DBUS_BUS_STARTER] != NULL)
195         {
196           s = _dbus_getenv ("DBUS_STARTER_BUS_TYPE");
197               
198           if (s != NULL)
199             {
200               _dbus_verbose ("Bus activation type was set to \"%s\"\n", s);
201                   
202               if (strcmp (s, "system") == 0)
203                 activation_bus_type = DBUS_BUS_SYSTEM;
204               else if (strcmp (s, "session") == 0)
205                 activation_bus_type = DBUS_BUS_SESSION;
206             }
207         }
208       else
209         {
210           /* Default to the session bus instead if available */
211           if (bus_connection_addresses[DBUS_BUS_SESSION] != NULL)
212             {
213               bus_connection_addresses[DBUS_BUS_STARTER] =
214                 _dbus_strdup (bus_connection_addresses[DBUS_BUS_SESSION]);
215               if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
216                 return FALSE;
217             }
218         }
219       
220       /* If we return FALSE we have to be sure that restarting
221        * the above code will work right
222        */
223       
224       if (!_dbus_setenv ("DBUS_ACTIVATION_ADDRESS", NULL))
225         return FALSE;
226
227       if (!_dbus_setenv ("DBUS_ACTIVATION_BUS_TYPE", NULL))
228         return FALSE;
229       
230       if (!_dbus_register_shutdown_func (addresses_shutdown_func,
231                                          NULL))
232         return FALSE;
233       
234       initialized = TRUE;
235     }
236
237   return initialized;
238 }
239
240 static void
241 bus_data_free (void *data)
242 {
243   BusData *bd = data;
244   
245   if (bd->is_well_known)
246     {
247       int i;
248       _DBUS_LOCK (bus);
249       /* We may be stored in more than one slot */
250       i = 0;
251       while (i < N_BUS_TYPES)
252         {
253           if (bus_connections[i] == bd->connection)
254             bus_connections[i] = NULL;
255           
256           ++i;
257         }
258       _DBUS_UNLOCK (bus);
259     }
260   
261   dbus_free (bd->unique_name);
262   dbus_free (bd);
263
264   dbus_connection_free_data_slot (&bus_data_slot);
265 }
266
267 static BusData*
268 ensure_bus_data (DBusConnection *connection)
269 {
270   BusData *bd;
271
272   if (!dbus_connection_allocate_data_slot (&bus_data_slot))
273     return NULL;
274
275   bd = dbus_connection_get_data (connection, bus_data_slot);
276   if (bd == NULL)
277     {      
278       bd = dbus_new0 (BusData, 1);
279       if (bd == NULL)
280         {
281           dbus_connection_free_data_slot (&bus_data_slot);
282           return NULL;
283         }
284
285       bd->connection = connection;
286       
287       if (!dbus_connection_set_data (connection, bus_data_slot, bd,
288                                      bus_data_free))
289         {
290           dbus_free (bd);
291           dbus_connection_free_data_slot (&bus_data_slot);
292           return NULL;
293         }
294
295       /* Data slot refcount now held by the BusData */
296     }
297   else
298     {
299       dbus_connection_free_data_slot (&bus_data_slot);
300     }
301
302   return bd;
303 }
304
305 static DBusConnection *
306 internal_bus_get (DBusBusType  type,
307               DBusError   *error, dbus_bool_t private)
308 {
309   const char *address;
310   DBusConnection *connection;
311   BusData *bd;
312   DBusBusType address_type;
313
314   _dbus_return_val_if_fail (type >= 0 && type < N_BUS_TYPES, NULL);
315   _dbus_return_val_if_error_is_set (error, NULL);
316
317   _DBUS_LOCK (bus);
318
319   if (!init_connections_unlocked ())
320     {
321       _DBUS_UNLOCK (bus);
322       _DBUS_SET_OOM (error);
323       return NULL;
324     }
325
326   /* We want to use the activation address even if the
327    * activating bus is the session or system bus,
328    * per the spec.
329    */
330   address_type = type;
331   
332   /* Use the real type of the activation bus for getting its
333    * connection, but only if the real type's address is available. (If
334    * the activating bus isn't a well-known bus then
335    * activation_bus_type == DBUS_BUS_STARTER)
336    */
337   if (type == DBUS_BUS_STARTER &&
338       bus_connection_addresses[activation_bus_type] != NULL)
339     type = activation_bus_type;
340   
341   if (!private && bus_connections[type] != NULL)
342     {
343       connection = bus_connections[type];
344       dbus_connection_ref (connection);
345       
346       _DBUS_UNLOCK (bus);
347       return connection;
348     }
349
350   address = bus_connection_addresses[address_type];
351   if (address == NULL)
352     {
353       dbus_set_error (error, DBUS_ERROR_FAILED,
354                       "Unable to determine the address of the message bus");
355       _DBUS_UNLOCK (bus);
356       return NULL;
357     }
358
359   if (private)
360     connection = dbus_connection_open_private(address, error);
361   else
362     connection = dbus_connection_open (address, error);
363   
364   if (!connection)
365     {
366       _DBUS_ASSERT_ERROR_IS_SET (error);
367       _DBUS_UNLOCK (bus);
368       return NULL;
369     }
370
371   /* By default we're bound to the lifecycle of
372    * the message bus.
373    */
374   dbus_connection_set_exit_on_disconnect (connection,
375                                           TRUE);
376   
377   if (!dbus_bus_register (connection, error))
378     {
379       _DBUS_ASSERT_ERROR_IS_SET (error);
380       dbus_connection_close (connection);
381       dbus_connection_unref (connection);
382
383       _DBUS_UNLOCK (bus);
384       return NULL;
385     }
386
387   if (!private)
388     bus_connections[type] = connection;
389   
390   bd = ensure_bus_data (connection);
391   _dbus_assert (bd != NULL);
392
393   bd->is_well_known = TRUE;
394
395   _DBUS_UNLOCK (bus);
396   return connection;
397 }
398
399
400 /** @} */ /* end of implementation details docs */
401
402 /**
403  * @addtogroup DBusBus
404  * @{
405  */
406
407 /**
408  * Connects to a bus daemon and registers the client with it.  If a
409  * connection to the bus already exists, then that connection is
410  * returned.  Caller owns a reference to the bus.
411  *
412  * @todo alex thinks we should nullify the connection when we get a disconnect-message.
413  *
414  * @param type bus type
415  * @param error address where an error can be returned.
416  * @returns a DBusConnection with new ref
417  */
418 DBusConnection *
419 dbus_bus_get (DBusBusType  type,
420               DBusError   *error) {
421   return internal_bus_get(type, error, FALSE);
422 }
423
424 /**
425  * Connects to a bus daemon and registers the client with it.  Unlike
426  * dbus_bus_get(), always creates a new connection. This connection
427  * will not be saved or recycled by libdbus. Caller owns a reference
428  * to the bus.
429  *
430  * @param type bus type
431  * @param error address where an error can be returned.
432  * @returns a DBusConnection with new ref
433  */
434 DBusConnection *
435 dbus_bus_get_private (DBusBusType  type,
436               DBusError   *error) {
437   return internal_bus_get(type, error, TRUE);
438 }
439
440 /**
441  * Registers a connection with the bus. This must be the first
442  * thing an application does when connecting to the message bus.
443  * If registration succeeds, the unique name will be set,
444  * and can be obtained using dbus_bus_get_unique_name().
445  * 
446  * @param connection the connection
447  * @param error place to store errors
448  * @returns #TRUE on success
449  */
450 dbus_bool_t
451 dbus_bus_register (DBusConnection *connection,
452                    DBusError      *error)
453 {
454   DBusMessage *message, *reply;
455   char *name;
456   BusData *bd;
457   dbus_bool_t retval;
458
459   _dbus_return_val_if_fail (connection != NULL, FALSE);
460   _dbus_return_val_if_error_is_set (error, FALSE);
461
462   retval = FALSE;
463   
464   bd = ensure_bus_data (connection);
465   if (bd == NULL)
466     {
467       _DBUS_SET_OOM (error);
468       return FALSE;
469     }
470
471   if (bd->unique_name != NULL)
472     {
473       _dbus_warn ("Attempt to register the same DBusConnection with the message bus, but it is already registered\n");
474       /* This isn't an error, it's a programming bug. We'll be nice
475        * and not _dbus_assert_not_reached()
476        */
477       return TRUE;
478     }
479   
480   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
481                                           DBUS_PATH_DBUS,
482                                           DBUS_INTERFACE_DBUS,
483                                           "Hello"); 
484
485   if (!message)
486     {
487       _DBUS_SET_OOM (error);
488       return FALSE;
489     }
490   
491   reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
492
493   dbus_message_unref (message);
494   
495   if (reply == NULL)
496     goto out;
497   else if (dbus_set_error_from_message (error, reply))
498     goto out;
499   else if (!dbus_message_get_args (reply, error,
500                                    DBUS_TYPE_STRING, &name,
501                                    DBUS_TYPE_INVALID))
502     goto out;
503   
504   bd->unique_name = _dbus_strdup (name);
505   if (bd->unique_name == NULL)
506     {
507       _DBUS_SET_OOM (error);
508       goto out;
509     }
510   
511   retval = TRUE;
512   
513  out:
514   if (reply)
515     dbus_message_unref (reply);
516
517   if (!retval)
518     _DBUS_ASSERT_ERROR_IS_SET (error);
519   
520   return retval;
521 }
522
523
524 /**
525  * Sets the unique name of the connection.  Can only be used if you
526  * registered with the bus manually (i.e. if you did not call
527  * dbus_bus_register()). Can only be called once per connection.
528  *
529  * @param connection the connection
530  * @param unique_name the unique name
531  * @returns #FALSE if not enough memory
532  */
533 dbus_bool_t
534 dbus_bus_set_unique_name (DBusConnection *connection,
535                           const char     *unique_name)
536 {
537   BusData *bd;
538
539   _dbus_return_val_if_fail (connection != NULL, FALSE);
540   _dbus_return_val_if_fail (unique_name != NULL, FALSE);
541   
542   bd = ensure_bus_data (connection);
543   if (bd == NULL)
544     return FALSE;
545
546   _dbus_assert (bd->unique_name == NULL);
547   
548   bd->unique_name = _dbus_strdup (unique_name);
549   return bd->unique_name != NULL;
550 }
551
552 /**
553  * Gets the unique name of the connection.  Only possible after the
554  * connection has been registered with the message bus.
555  *
556  * The name remains valid for the duration of the connection and
557  * should not be freed by the caller.
558  * 
559  * @param connection the connection
560  * @returns the unique name or NULL on error
561  */
562 const char*
563 dbus_bus_get_unique_name (DBusConnection *connection)
564 {
565   BusData *bd;
566
567   _dbus_return_val_if_fail (connection != NULL, NULL);
568   
569   bd = ensure_bus_data (connection);
570   if (bd == NULL)
571     return NULL;
572   
573   return bd->unique_name;
574 }
575
576 /**
577  * Asks the bus to return the uid of the named
578  * connection.
579  *
580  * @param connection the connection
581  * @param name a name owned by the connection
582  * @param error location to store the error
583  * @returns a result code, -1 if error is set
584  */ 
585 unsigned long
586 dbus_bus_get_unix_user (DBusConnection *connection,
587                         const char     *name,
588                         DBusError      *error)
589 {
590   DBusMessage *message, *reply;
591   dbus_uint32_t uid;
592
593   _dbus_return_val_if_fail (connection != NULL, DBUS_UID_UNSET);
594   _dbus_return_val_if_fail (name != NULL, DBUS_UID_UNSET);
595   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), DBUS_UID_UNSET);
596   _dbus_return_val_if_error_is_set (error, DBUS_UID_UNSET);
597   
598   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
599                                           DBUS_PATH_DBUS,
600                                           DBUS_INTERFACE_DBUS,
601                                           "GetConnectionUnixUser");
602
603   if (message == NULL)
604     {
605       _DBUS_SET_OOM (error);
606       return DBUS_UID_UNSET;
607     }
608  
609   if (!dbus_message_append_args (message,
610                                  DBUS_TYPE_STRING, &name,
611                                  DBUS_TYPE_INVALID))
612     {
613       dbus_message_unref (message);
614       _DBUS_SET_OOM (error);
615       return DBUS_UID_UNSET;
616     }
617   
618   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
619                                                      error);
620   
621   dbus_message_unref (message);
622   
623   if (reply == NULL)
624     {
625       _DBUS_ASSERT_ERROR_IS_SET (error);
626       return DBUS_UID_UNSET;
627     }  
628
629   if (dbus_set_error_from_message (error, reply))
630     {
631       _DBUS_ASSERT_ERROR_IS_SET (error);
632       dbus_message_unref (reply);
633       return DBUS_UID_UNSET;
634     }
635   
636   if (!dbus_message_get_args (reply, error,
637                               DBUS_TYPE_UINT32, &uid,
638                               DBUS_TYPE_INVALID))
639     {
640       _DBUS_ASSERT_ERROR_IS_SET (error);
641       dbus_message_unref (reply);
642       return DBUS_UID_UNSET;
643     }
644
645   dbus_message_unref (reply);
646   
647   return (unsigned long) uid;
648 }
649
650
651 /**
652  * Asks the bus to assign the given name to this connection by invoking
653  * the RequestName method on the bus. This method is fully documented
654  * in the D-BUS specification. For quick reference, the flags and
655  * result codes are discussed here, but the specification is the
656  * canonical version of this information.
657  *
658  * The #DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT flag indicates that
659  * if the name is successfully requested, other applications
660  * will not be able to take over the name. i.e. the name's
661  * owner (the application calling this function) must let go of
662  * the name, it will not lose it involuntarily.
663  *
664  * The #DBUS_NAME_FLAG_REPLACE_EXISTING flag indicates that the caller
665  * would like to take over the name from the current owner.
666  * If the current name owner used #DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT
667  * then this flag indicates that the caller would like to be placed
668  * in the queue to own the name when the current owner lets go.
669  *
670  * If no flags are given, an application will receive the requested
671  * name only if the name is currently unowned; and it will give
672  * up the name if another application asks to take it over using
673  * #DBUS_NAME_FLAG_REPLACE_EXISTING.
674  *
675  * This function returns a result code. The possible result codes
676  * are as follows.
677  * 
678  * #DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER means that the name had no
679  * existing owner, and the caller is now the primary owner; or that
680  * the name had an owner, and the caller specified
681  * #DBUS_NAME_FLAG_REPLACE_EXISTING, and the current owner did not
682  * specify #DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT.
683  *
684  * #DBUS_REQUEST_NAME_REPLY_IN_QUEUE happens only if the current owner
685  * specified #DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT and the caller specified
686  * #DBUS_NAME_FLAG_REPLACE_EXISTING. In this case the caller ends up in
687  * a queue to own the name after the current owner gives it up.
688  *
689  * #DBUS_REQUEST_NAME_REPLY_EXISTS happens if the name has an owner
690  * #already and DBUS_NAME_FLAG_REPLACE_EXISTING was not specified.
691  *
692  * #DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER happens if an application
693  * requests a name it already owns.
694  *
695  * When a service represents an application, say "text editor," then
696  * it should specify #DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT if it wants
697  * the first editor started to be the user's editor vs. the last one
698  * started.  Then any editor that can be the user's editor should
699  * specify #DBUS_NAME_FLAG_REPLACE_EXISTING to either take over
700  * (last-started-wins) or be queued up (first-started-wins) according
701  * to whether #DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT was given.
702  * 
703  * @todo this all seems sort of broken. Shouldn't the flags be a property
704  * of the name, not the app requesting the name? What are the use-cases
705  * other than the "text editor" thing and how are we supporting them?
706  * 
707  * @param connection the connection
708  * @param name the name to request
709  * @param flags flags
710  * @param error location to store the error
711  * @returns a result code, -1 if error is set
712  */ 
713 int
714 dbus_bus_request_name (DBusConnection *connection,
715                        const char     *name,
716                        unsigned int    flags,
717                        DBusError      *error)
718 {
719   DBusMessage *message, *reply;
720   dbus_uint32_t result;
721
722   _dbus_return_val_if_fail (connection != NULL, 0);
723   _dbus_return_val_if_fail (name != NULL, 0);
724   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
725   _dbus_return_val_if_error_is_set (error, 0);
726   
727   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
728                                           DBUS_PATH_DBUS,
729                                           DBUS_INTERFACE_DBUS,
730                                           "RequestName");
731
732   if (message == NULL)
733     {
734       _DBUS_SET_OOM (error);
735       return -1;
736     }
737  
738   if (!dbus_message_append_args (message,
739                                  DBUS_TYPE_STRING, &name,
740                                  DBUS_TYPE_UINT32, &flags,
741                                  DBUS_TYPE_INVALID))
742     {
743       dbus_message_unref (message);
744       _DBUS_SET_OOM (error);
745       return -1;
746     }
747   
748   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
749                                                      error);
750   
751   dbus_message_unref (message);
752   
753   if (reply == NULL)
754     {
755       _DBUS_ASSERT_ERROR_IS_SET (error);
756       return -1;
757     }  
758
759   if (dbus_set_error_from_message (error, reply))
760     {
761       _DBUS_ASSERT_ERROR_IS_SET (error);
762       dbus_message_unref (reply);
763       return -1;
764     }
765   
766   if (!dbus_message_get_args (reply, error,
767                               DBUS_TYPE_UINT32, &result,
768                               DBUS_TYPE_INVALID))
769     {
770       _DBUS_ASSERT_ERROR_IS_SET (error);
771       dbus_message_unref (reply);
772       return -1;
773     }
774
775   dbus_message_unref (reply);
776   
777   return result;
778 }
779
780 /**
781  * Checks whether a certain name has an owner.
782  *
783  * @param connection the connection
784  * @param name the name
785  * @param error location to store any errors
786  * @returns #TRUE if the name exists, #FALSE if not or on error
787  */
788 dbus_bool_t
789 dbus_bus_name_has_owner (DBusConnection *connection,
790                          const char     *name,
791                          DBusError      *error)
792 {
793   DBusMessage *message, *reply;
794   dbus_bool_t exists;
795
796   _dbus_return_val_if_fail (connection != NULL, FALSE);
797   _dbus_return_val_if_fail (name != NULL, FALSE);
798   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
799   _dbus_return_val_if_error_is_set (error, FALSE);
800   
801   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
802                                           DBUS_PATH_DBUS,
803                                           DBUS_INTERFACE_DBUS,
804                                           "NameHasOwner");
805   if (message == NULL)
806     {
807       _DBUS_SET_OOM (error);
808       return FALSE;
809     }
810   
811   if (!dbus_message_append_args (message,
812                                  DBUS_TYPE_STRING, &name,
813                                  DBUS_TYPE_INVALID))
814     {
815       dbus_message_unref (message);
816       _DBUS_SET_OOM (error);
817       return FALSE;
818     }
819   
820   reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
821   dbus_message_unref (message);
822
823   if (reply == NULL)
824     {
825       _DBUS_ASSERT_ERROR_IS_SET (error);
826       return FALSE;
827     }
828
829   if (!dbus_message_get_args (reply, error,
830                               DBUS_TYPE_BOOLEAN, &exists,
831                               DBUS_TYPE_INVALID))
832     {
833       _DBUS_ASSERT_ERROR_IS_SET (error);
834       dbus_message_unref (reply);
835       return FALSE;
836     }
837   
838   dbus_message_unref (reply);
839   return exists;
840 }
841
842 /**
843  * Starts a service that will request ownership of the given name.
844  * The returned result will be one of be one of
845  * #DBUS_START_REPLY_SUCCESS or #DBUS_START_REPLY_ALREADY_RUNNING if
846  * successful.  Pass #NULL if you don't care about the result.
847  * 
848  * The flags parameter is for future expansion, currently you should
849  * specify 0.
850  *
851  * @param connection the connection
852  * @param name the name we want the new service to request
853  * @param flags the flags (should always be 0 for now)
854  * @param result a place to store the result or #NULL
855  * @param error location to store any errors
856  * @returns #TRUE if the activation succeeded, #FALSE if not
857  */
858 dbus_bool_t
859 dbus_bus_start_service_by_name (DBusConnection *connection,
860                                 const char     *name,
861                                 dbus_uint32_t   flags,
862                                 dbus_uint32_t  *result,
863                                 DBusError      *error)
864 {
865   DBusMessage *msg;
866   DBusMessage *reply;
867
868   _dbus_return_val_if_fail (connection != NULL, FALSE);
869   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
870   
871   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
872                                       DBUS_PATH_DBUS,
873                                       DBUS_INTERFACE_DBUS,
874                                       "StartServiceByName");
875
876   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name,
877                                  DBUS_TYPE_UINT32, &flags, DBUS_TYPE_INVALID))
878     {
879       dbus_message_unref (msg);
880       _DBUS_SET_OOM (error);
881       return FALSE;
882     }
883
884   reply = dbus_connection_send_with_reply_and_block (connection, msg,
885                                                      -1, error);
886   dbus_message_unref (msg);
887
888   if (reply == NULL)
889     {
890       _DBUS_ASSERT_ERROR_IS_SET (error);
891       return FALSE;
892     }
893
894   if (dbus_set_error_from_message (error, reply))
895     {
896       _DBUS_ASSERT_ERROR_IS_SET (error);
897       dbus_message_unref (reply);
898       return FALSE;
899     }
900
901   if (result != NULL &&
902       !dbus_message_get_args (reply, error, DBUS_TYPE_UINT32,
903                               result, DBUS_TYPE_INVALID))
904     {
905       _DBUS_ASSERT_ERROR_IS_SET (error);
906       dbus_message_unref (reply);
907       return FALSE;
908     }
909   
910   dbus_message_unref (reply);
911   return TRUE;
912 }
913
914 static void
915 send_no_return_values (DBusConnection *connection,
916                        DBusMessage    *msg,
917                        DBusError      *error)
918 {
919   if (error)
920     {
921       /* Block to check success codepath */
922       DBusMessage *reply;
923       
924       reply = dbus_connection_send_with_reply_and_block (connection, msg,
925                                                          -1, error);
926       
927       if (reply == NULL)
928         _DBUS_ASSERT_ERROR_IS_SET (error);
929       else
930         dbus_message_unref (reply);
931     }
932   else
933     {
934       /* Silently-fail nonblocking codepath */
935       dbus_message_set_no_reply (msg, TRUE);
936       dbus_connection_send (connection, msg, NULL);
937     }
938 }
939
940 /**
941  * Adds a match rule to match messages going through the message bus.
942  * The "rule" argument is the string form of a match rule.
943  *
944  * If you pass #NULL for the error, this function will not
945  * block; the match thus won't be added until you flush the
946  * connection, and if there's an error adding the match
947  * (only possible error is lack of resources in the bus),
948  * you won't find out about it.
949  *
950  * If you pass non-#NULL for the error this function will
951  * block until it gets a reply.
952  *
953  * Normal API conventions would have the function return
954  * a boolean value indicating whether the error was set,
955  * but that would require blocking always to determine
956  * the return value.
957  * 
958  * @param connection connection to the message bus
959  * @param rule textual form of match rule
960  * @param error location to store any errors
961  */
962 void
963 dbus_bus_add_match (DBusConnection *connection,
964                     const char     *rule,
965                     DBusError      *error)
966 {
967   DBusMessage *msg;
968
969   _dbus_return_if_fail (rule != NULL);
970
971   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
972                                       DBUS_PATH_DBUS,
973                                       DBUS_INTERFACE_DBUS,
974                                       "AddMatch");
975
976   if (msg == NULL)
977     {
978       _DBUS_SET_OOM (error);
979       return;
980     }
981
982   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
983                                  DBUS_TYPE_INVALID))
984     {
985       dbus_message_unref (msg);
986       _DBUS_SET_OOM (error);
987       return;
988     }
989
990   send_no_return_values (connection, msg, error);
991
992   dbus_message_unref (msg);
993 }
994
995 /**
996  * Removes a previously-added match rule "by value" (the most
997  * recently-added identical rule gets removed).  The "rule" argument
998  * is the string form of a match rule.
999  *
1000  * If you pass #NULL for the error, this function will not
1001  * block; otherwise it will. See detailed explanation in
1002  * docs for dbus_bus_add_match().
1003  * 
1004  * @param connection connection to the message bus
1005  * @param rule textual form of match rule
1006  * @param error location to store any errors
1007  */
1008 void
1009 dbus_bus_remove_match (DBusConnection *connection,
1010                        const char     *rule,
1011                        DBusError      *error)
1012 {
1013   DBusMessage *msg;
1014
1015   _dbus_return_if_fail (rule != NULL);
1016   
1017   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
1018                                       DBUS_PATH_DBUS,
1019                                       DBUS_INTERFACE_DBUS,
1020                                       "RemoveMatch");
1021
1022   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
1023                                  DBUS_TYPE_INVALID))
1024     {
1025       dbus_message_unref (msg);
1026       _DBUS_SET_OOM (error);
1027       return;
1028     }
1029
1030   send_no_return_values (connection, msg, error);
1031
1032   dbus_message_unref (msg);
1033 }
1034
1035 /** @} */