some docs cleanups
[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 /** @} */ /* end of implementation details docs */
306
307 /**
308  * @addtogroup DBusBus
309  * @{
310  */
311
312 /**
313  * Connects to a bus daemon and registers the client with it.  If a
314  * connection to the bus already exists, then that connection is
315  * returned.  Caller owns a reference to the bus.
316  *
317  * @todo alex thinks we should nullify the connection when we get a disconnect-message.
318  *
319  * @param type bus type
320  * @param error address where an error can be returned.
321  * @returns a DBusConnection with new ref
322  */
323 DBusConnection *
324 dbus_bus_get (DBusBusType  type,
325               DBusError   *error)
326 {
327   const char *address;
328   DBusConnection *connection;
329   BusData *bd;
330   DBusBusType address_type;
331
332   _dbus_return_val_if_fail (type >= 0 && type < N_BUS_TYPES, NULL);
333   _dbus_return_val_if_error_is_set (error, NULL);
334
335   _DBUS_LOCK (bus);
336
337   if (!init_connections_unlocked ())
338     {
339       _DBUS_UNLOCK (bus);
340       _DBUS_SET_OOM (error);
341       return NULL;
342     }
343
344   /* We want to use the activation address even if the
345    * activating bus is the session or system bus,
346    * per the spec.
347    */
348   address_type = type;
349   
350   /* Use the real type of the activation bus for getting its
351    * connection, but only if the real type's address is available. (If
352    * the activating bus isn't a well-known bus then
353    * activation_bus_type == DBUS_BUS_STARTER)
354    */
355   if (type == DBUS_BUS_STARTER &&
356       bus_connection_addresses[activation_bus_type] != NULL)
357     type = activation_bus_type;
358   
359   if (bus_connections[type] != NULL)
360     {
361       connection = bus_connections[type];
362       dbus_connection_ref (connection);
363       
364       _DBUS_UNLOCK (bus);
365       return connection;
366     }
367
368   address = bus_connection_addresses[address_type];
369   if (address == NULL)
370     {
371       dbus_set_error (error, DBUS_ERROR_FAILED,
372                       "Unable to determine the address of the message bus");
373       _DBUS_UNLOCK (bus);
374       return NULL;
375     }
376
377   connection = dbus_connection_open (address, error);
378   
379   if (!connection)
380     {
381       _DBUS_ASSERT_ERROR_IS_SET (error);
382       _DBUS_UNLOCK (bus);
383       return NULL;
384     }
385
386   /* By default we're bound to the lifecycle of
387    * the message bus.
388    */
389   dbus_connection_set_exit_on_disconnect (connection,
390                                           TRUE);
391   
392   if (!dbus_bus_register (connection, error))
393     {
394       _DBUS_ASSERT_ERROR_IS_SET (error);
395       dbus_connection_close (connection);
396       dbus_connection_unref (connection);
397
398       _DBUS_UNLOCK (bus);
399       return NULL;
400     }
401
402   bus_connections[type] = connection;
403   bd = ensure_bus_data (connection);
404   _dbus_assert (bd != NULL);
405
406   bd->is_well_known = TRUE;
407
408   _DBUS_UNLOCK (bus);
409   return connection;
410 }
411
412
413 /**
414  * Registers a connection with the bus. This must be the first
415  * thing an application does when connecting to the message bus.
416  * If registration succeeds, the unique name will be set,
417  * and can be obtained using dbus_bus_get_unique_name().
418  * 
419  * @param connection the connection
420  * @param error place to store errors
421  * @returns #TRUE on success
422  */
423 dbus_bool_t
424 dbus_bus_register (DBusConnection *connection,
425                    DBusError      *error)
426 {
427   DBusMessage *message, *reply;
428   char *name;
429   BusData *bd;
430   dbus_bool_t retval;
431
432   _dbus_return_val_if_fail (connection != NULL, FALSE);
433   _dbus_return_val_if_error_is_set (error, FALSE);
434
435   retval = FALSE;
436   
437   bd = ensure_bus_data (connection);
438   if (bd == NULL)
439     {
440       _DBUS_SET_OOM (error);
441       return FALSE;
442     }
443
444   if (bd->unique_name != NULL)
445     {
446       _dbus_warn ("Attempt to register the same DBusConnection with the message bus, but it is already registered\n");
447       /* This isn't an error, it's a programming bug. We'll be nice
448        * and not _dbus_assert_not_reached()
449        */
450       return TRUE;
451     }
452   
453   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
454                                           DBUS_PATH_DBUS,
455                                           DBUS_INTERFACE_DBUS,
456                                           "Hello"); 
457
458   if (!message)
459     {
460       _DBUS_SET_OOM (error);
461       return FALSE;
462     }
463   
464   reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
465
466   dbus_message_unref (message);
467   
468   if (reply == NULL)
469     goto out;
470   else if (dbus_set_error_from_message (error, reply))
471     goto out;
472   else if (!dbus_message_get_args (reply, error,
473                                    DBUS_TYPE_STRING, &name,
474                                    DBUS_TYPE_INVALID))
475     goto out;
476   
477   bd->unique_name = _dbus_strdup (name);
478   if (bd->unique_name == NULL)
479     {
480       _DBUS_SET_OOM (error);
481       goto out;
482     }
483   
484   retval = TRUE;
485   
486  out:
487   if (reply)
488     dbus_message_unref (reply);
489
490   if (!retval)
491     _DBUS_ASSERT_ERROR_IS_SET (error);
492   
493   return retval;
494 }
495
496
497 /**
498  * Sets the unique name of the connection.  Can only be used if you
499  * registered with the bus manually (i.e. if you did not call
500  * dbus_bus_register()). Can only be called once per connection.
501  *
502  * @param connection the connection
503  * @param unique_name the unique name
504  * @returns #FALSE if not enough memory
505  */
506 dbus_bool_t
507 dbus_bus_set_unique_name (DBusConnection *connection,
508                           const char     *unique_name)
509 {
510   BusData *bd;
511
512   _dbus_return_val_if_fail (connection != NULL, FALSE);
513   _dbus_return_val_if_fail (unique_name != NULL, FALSE);
514   
515   bd = ensure_bus_data (connection);
516   if (bd == NULL)
517     return FALSE;
518
519   _dbus_assert (bd->unique_name == NULL);
520   
521   bd->unique_name = _dbus_strdup (unique_name);
522   return bd->unique_name != NULL;
523 }
524
525 /**
526  * Gets the unique name of the connection.  Only possible after the
527  * connection has been registered with the message bus.
528  *
529  * @param connection the connection
530  * @returns the unique name
531  */
532 const char*
533 dbus_bus_get_unique_name (DBusConnection *connection)
534 {
535   BusData *bd;
536
537   _dbus_return_val_if_fail (connection != NULL, NULL);
538   
539   bd = ensure_bus_data (connection);
540   if (bd == NULL)
541     return NULL;
542   
543   return bd->unique_name;
544 }
545
546 /**
547  * Asks the bus to return the uid of the named
548  * connection.
549  *
550  * @param connection the connection
551  * @param name a name owned by the connection
552  * @param error location to store the error
553  * @returns a result code, -1 if error is set
554  */ 
555 unsigned long
556 dbus_bus_get_unix_user (DBusConnection *connection,
557                         const char     *name,
558                         DBusError      *error)
559 {
560   DBusMessage *message, *reply;
561   dbus_uint32_t uid;
562
563   _dbus_return_val_if_fail (connection != NULL, DBUS_UID_UNSET);
564   _dbus_return_val_if_fail (name != NULL, DBUS_UID_UNSET);
565   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), DBUS_UID_UNSET);
566   _dbus_return_val_if_error_is_set (error, DBUS_UID_UNSET);
567   
568   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
569                                           DBUS_PATH_DBUS,
570                                           DBUS_INTERFACE_DBUS,
571                                           "GetConnectionUnixUser");
572
573   if (message == NULL)
574     {
575       _DBUS_SET_OOM (error);
576       return DBUS_UID_UNSET;
577     }
578  
579   if (!dbus_message_append_args (message,
580                                  DBUS_TYPE_STRING, &name,
581                                  DBUS_TYPE_INVALID))
582     {
583       dbus_message_unref (message);
584       _DBUS_SET_OOM (error);
585       return DBUS_UID_UNSET;
586     }
587   
588   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
589                                                      error);
590   
591   dbus_message_unref (message);
592   
593   if (reply == NULL)
594     {
595       _DBUS_ASSERT_ERROR_IS_SET (error);
596       return DBUS_UID_UNSET;
597     }  
598
599   if (dbus_set_error_from_message (error, reply))
600     {
601       _DBUS_ASSERT_ERROR_IS_SET (error);
602       dbus_message_unref (reply);
603       return DBUS_UID_UNSET;
604     }
605   
606   if (!dbus_message_get_args (reply, error,
607                               DBUS_TYPE_UINT32, &uid,
608                               DBUS_TYPE_INVALID))
609     {
610       _DBUS_ASSERT_ERROR_IS_SET (error);
611       dbus_message_unref (reply);
612       return DBUS_UID_UNSET;
613     }
614
615   dbus_message_unref (reply);
616   
617   return (unsigned long) uid;
618 }
619
620
621 /**
622  * Asks the bus to assign the given name to this connection by invoking
623  * the RequestName method on the bus. This method is fully documented
624  * in the D-BUS specification. For quick reference, the flags and
625  * result codes are discussed here, but the specification is the
626  * canonical version of this information.
627  *
628  * The #DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT flag indicates that
629  * if the name is successfully requested, other applications
630  * will not be able to take over the name. i.e. the name's
631  * owner (the application calling this function) must let go of
632  * the name, it will not lose it involuntarily.
633  *
634  * The #DBUS_NAME_FLAG_REPLACE_EXISTING flag indicates that the caller
635  * would like to take over the name from the current owner.
636  * If the current name owner used #DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT
637  * then this flag indicates that the caller would like to be placed
638  * in the queue to own the name when the current owner lets go.
639  *
640  * If no flags are given, an application will receive the requested
641  * name only if the name is currently unowned; and it will give
642  * up the name if another application asks to take it over using
643  * #DBUS_NAME_FLAG_REPLACE_EXISTING.
644  *
645  * This function returns a result code. The possible result codes
646  * are as follows.
647  * 
648  * #DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER means that the name had no
649  * existing owner, and the caller is now the primary owner; or that
650  * the name had an owner, and the caller specified
651  * #DBUS_NAME_FLAG_REPLACE_EXISTING, and the current owner did not
652  * specify #DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT.
653  *
654  * #DBUS_REQUEST_NAME_REPLY_IN_QUEUE happens only if the current owner
655  * specified #DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT and the caller specified
656  * #DBUS_NAME_FLAG_REPLACE_EXISTING. In this case the caller ends up in
657  * a queue to own the name after the current owner gives it up.
658  *
659  * #DBUS_REQUEST_NAME_REPLY_EXISTS happens if the name has an owner
660  * #already and DBUS_NAME_FLAG_REPLACE_EXISTING was not specified.
661  *
662  * #DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER happens if an application
663  * requests a name it already owns.
664  *
665  * When a service represents an application, say "text editor," then
666  * it should specify #DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT if it wants
667  * the first editor started to be the user's editor vs. the last one
668  * started.  Then any editor that can be the user's editor should
669  * specify #DBUS_NAME_FLAG_REPLACE_EXISTING to either take over
670  * (last-started-wins) or be queued up (first-started-wins) according
671  * to whether #DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT was given.
672  * 
673  * @todo this all seems sort of broken. Shouldn't the flags be a property
674  * of the name, not the app requesting the name? What are the use-cases
675  * other than the "text editor" thing and how are we supporting them?
676  * 
677  * @param connection the connection
678  * @param name the name to request
679  * @param flags flags
680  * @param error location to store the error
681  * @returns a result code, -1 if error is set
682  */ 
683 int
684 dbus_bus_request_name (DBusConnection *connection,
685                        const char     *name,
686                        unsigned int    flags,
687                        DBusError      *error)
688 {
689   DBusMessage *message, *reply;
690   dbus_uint32_t result;
691
692   _dbus_return_val_if_fail (connection != NULL, 0);
693   _dbus_return_val_if_fail (name != NULL, 0);
694   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
695   _dbus_return_val_if_error_is_set (error, 0);
696   
697   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
698                                           DBUS_PATH_DBUS,
699                                           DBUS_INTERFACE_DBUS,
700                                           "RequestName");
701
702   if (message == NULL)
703     {
704       _DBUS_SET_OOM (error);
705       return -1;
706     }
707  
708   if (!dbus_message_append_args (message,
709                                  DBUS_TYPE_STRING, &name,
710                                  DBUS_TYPE_UINT32, &flags,
711                                  DBUS_TYPE_INVALID))
712     {
713       dbus_message_unref (message);
714       _DBUS_SET_OOM (error);
715       return -1;
716     }
717   
718   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
719                                                      error);
720   
721   dbus_message_unref (message);
722   
723   if (reply == NULL)
724     {
725       _DBUS_ASSERT_ERROR_IS_SET (error);
726       return -1;
727     }  
728
729   if (dbus_set_error_from_message (error, reply))
730     {
731       _DBUS_ASSERT_ERROR_IS_SET (error);
732       dbus_message_unref (reply);
733       return -1;
734     }
735   
736   if (!dbus_message_get_args (reply, error,
737                               DBUS_TYPE_UINT32, &result,
738                               DBUS_TYPE_INVALID))
739     {
740       _DBUS_ASSERT_ERROR_IS_SET (error);
741       dbus_message_unref (reply);
742       return -1;
743     }
744
745   dbus_message_unref (reply);
746   
747   return result;
748 }
749
750 /**
751  * Checks whether a certain name has an owner.
752  *
753  * @param connection the connection
754  * @param name the name
755  * @param error location to store any errors
756  * @returns #TRUE if the name exists, #FALSE if not or on error
757  */
758 dbus_bool_t
759 dbus_bus_name_has_owner (DBusConnection *connection,
760                          const char     *name,
761                          DBusError      *error)
762 {
763   DBusMessage *message, *reply;
764   dbus_bool_t exists;
765
766   _dbus_return_val_if_fail (connection != NULL, FALSE);
767   _dbus_return_val_if_fail (name != NULL, FALSE);
768   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
769   _dbus_return_val_if_error_is_set (error, FALSE);
770   
771   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
772                                           DBUS_PATH_DBUS,
773                                           DBUS_INTERFACE_DBUS,
774                                           "NameHasOwner");
775   if (message == NULL)
776     {
777       _DBUS_SET_OOM (error);
778       return FALSE;
779     }
780   
781   if (!dbus_message_append_args (message,
782                                  DBUS_TYPE_STRING, &name,
783                                  DBUS_TYPE_INVALID))
784     {
785       dbus_message_unref (message);
786       _DBUS_SET_OOM (error);
787       return FALSE;
788     }
789   
790   reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
791   dbus_message_unref (message);
792
793   if (reply == NULL)
794     {
795       _DBUS_ASSERT_ERROR_IS_SET (error);
796       return FALSE;
797     }
798
799   if (!dbus_message_get_args (reply, error,
800                               DBUS_TYPE_BOOLEAN, &exists,
801                               DBUS_TYPE_INVALID))
802     {
803       _DBUS_ASSERT_ERROR_IS_SET (error);
804       dbus_message_unref (reply);
805       return FALSE;
806     }
807   
808   dbus_message_unref (reply);
809   return exists;
810 }
811
812 /**
813  * Starts a service that will request ownership of the given name.
814  * The returned result will be one of be one of
815  * #DBUS_START_REPLY_SUCCESS or #DBUS_START_REPLY_ALREADY_RUNNING if
816  * successful.  Pass #NULL if you don't care about the result.
817  * 
818  * The flags parameter is for future expansion, currently you should
819  * specify 0.
820  *
821  * @param connection the connection
822  * @param name the name we want the new service to request
823  * @param flags the flags (should always be 0 for now)
824  * @param result a place to store the result or #NULL
825  * @param error location to store any errors
826  * @returns #TRUE if the activation succeeded, #FALSE if not
827  */
828 dbus_bool_t
829 dbus_bus_start_service_by_name (DBusConnection *connection,
830                                 const char     *name,
831                                 dbus_uint32_t   flags,
832                                 dbus_uint32_t  *result,
833                                 DBusError      *error)
834 {
835   DBusMessage *msg;
836   DBusMessage *reply;
837
838   _dbus_return_val_if_fail (connection != NULL, FALSE);
839   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
840   
841   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
842                                       DBUS_PATH_DBUS,
843                                       DBUS_INTERFACE_DBUS,
844                                       "StartServiceByName");
845
846   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name,
847                                  DBUS_TYPE_UINT32, &flags, DBUS_TYPE_INVALID))
848     {
849       dbus_message_unref (msg);
850       _DBUS_SET_OOM (error);
851       return FALSE;
852     }
853
854   reply = dbus_connection_send_with_reply_and_block (connection, msg,
855                                                      -1, error);
856   dbus_message_unref (msg);
857
858   if (reply == NULL)
859     {
860       _DBUS_ASSERT_ERROR_IS_SET (error);
861       return FALSE;
862     }
863
864   if (dbus_set_error_from_message (error, reply))
865     {
866       _DBUS_ASSERT_ERROR_IS_SET (error);
867       dbus_message_unref (reply);
868       return FALSE;
869     }
870
871   if (result != NULL &&
872       !dbus_message_get_args (reply, error, DBUS_TYPE_UINT32,
873                               result, DBUS_TYPE_INVALID))
874     {
875       _DBUS_ASSERT_ERROR_IS_SET (error);
876       dbus_message_unref (reply);
877       return FALSE;
878     }
879   
880   dbus_message_unref (reply);
881   return TRUE;
882 }
883
884 static void
885 send_no_return_values (DBusConnection *connection,
886                        DBusMessage    *msg,
887                        DBusError      *error)
888 {
889   if (error)
890     {
891       /* Block to check success codepath */
892       DBusMessage *reply;
893       
894       reply = dbus_connection_send_with_reply_and_block (connection, msg,
895                                                          -1, error);
896       
897       if (reply == NULL)
898         _DBUS_ASSERT_ERROR_IS_SET (error);
899       else
900         dbus_message_unref (reply);
901     }
902   else
903     {
904       /* Silently-fail nonblocking codepath */
905       dbus_message_set_no_reply (msg, TRUE);
906       dbus_connection_send (connection, msg, NULL);
907     }
908 }
909
910 /**
911  * Adds a match rule to match messages going through the message bus.
912  * The "rule" argument is the string form of a match rule.
913  *
914  * If you pass #NULL for the error, this function will not
915  * block; the match thus won't be added until you flush the
916  * connection, and if there's an error adding the match
917  * (only possible error is lack of resources in the bus),
918  * you won't find out about it.
919  *
920  * If you pass non-#NULL for the error this function will
921  * block until it gets a reply.
922  *
923  * Normal API conventions would have the function return
924  * a boolean value indicating whether the error was set,
925  * but that would require blocking always to determine
926  * the return value.
927  * 
928  * @param connection connection to the message bus
929  * @param rule textual form of match rule
930  * @param error location to store any errors
931  */
932 void
933 dbus_bus_add_match (DBusConnection *connection,
934                     const char     *rule,
935                     DBusError      *error)
936 {
937   DBusMessage *msg;
938
939   _dbus_return_if_fail (rule != NULL);
940
941   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
942                                       DBUS_PATH_DBUS,
943                                       DBUS_INTERFACE_DBUS,
944                                       "AddMatch");
945
946   if (msg == NULL)
947     {
948       _DBUS_SET_OOM (error);
949       return;
950     }
951
952   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
953                                  DBUS_TYPE_INVALID))
954     {
955       dbus_message_unref (msg);
956       _DBUS_SET_OOM (error);
957       return;
958     }
959
960   send_no_return_values (connection, msg, error);
961
962   dbus_message_unref (msg);
963 }
964
965 /**
966  * Removes a previously-added match rule "by value" (the most
967  * recently-added identical rule gets removed).  The "rule" argument
968  * is the string form of a match rule.
969  *
970  * If you pass #NULL for the error, this function will not
971  * block; otherwise it will. See detailed explanation in
972  * docs for dbus_bus_add_match().
973  * 
974  * @param connection connection to the message bus
975  * @param rule textual form of match rule
976  * @param error location to store any errors
977  */
978 void
979 dbus_bus_remove_match (DBusConnection *connection,
980                        const char     *rule,
981                        DBusError      *error)
982 {
983   DBusMessage *msg;
984
985   _dbus_return_if_fail (rule != NULL);
986   
987   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
988                                       DBUS_PATH_DBUS,
989                                       DBUS_INTERFACE_DBUS,
990                                       "RemoveMatch");
991
992   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
993                                  DBUS_TYPE_INVALID))
994     {
995       dbus_message_unref (msg);
996       _DBUS_SET_OOM (error);
997       return;
998     }
999
1000   send_no_return_values (connection, msg, error);
1001
1002   dbus_message_unref (msg);
1003 }
1004
1005 /** @} */