Small docu update
[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  * The name remains valid for the duration of the connection and
530  * should not be freed by the caller.
531  * 
532  * @param connection the connection
533  * @returns the unique name or NULL on error
534  */
535 const char*
536 dbus_bus_get_unique_name (DBusConnection *connection)
537 {
538   BusData *bd;
539
540   _dbus_return_val_if_fail (connection != NULL, NULL);
541   
542   bd = ensure_bus_data (connection);
543   if (bd == NULL)
544     return NULL;
545   
546   return bd->unique_name;
547 }
548
549 /**
550  * Asks the bus to return the uid of the named
551  * connection.
552  *
553  * @param connection the connection
554  * @param name a name owned by the connection
555  * @param error location to store the error
556  * @returns a result code, -1 if error is set
557  */ 
558 unsigned long
559 dbus_bus_get_unix_user (DBusConnection *connection,
560                         const char     *name,
561                         DBusError      *error)
562 {
563   DBusMessage *message, *reply;
564   dbus_uint32_t uid;
565
566   _dbus_return_val_if_fail (connection != NULL, DBUS_UID_UNSET);
567   _dbus_return_val_if_fail (name != NULL, DBUS_UID_UNSET);
568   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), DBUS_UID_UNSET);
569   _dbus_return_val_if_error_is_set (error, DBUS_UID_UNSET);
570   
571   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
572                                           DBUS_PATH_DBUS,
573                                           DBUS_INTERFACE_DBUS,
574                                           "GetConnectionUnixUser");
575
576   if (message == NULL)
577     {
578       _DBUS_SET_OOM (error);
579       return DBUS_UID_UNSET;
580     }
581  
582   if (!dbus_message_append_args (message,
583                                  DBUS_TYPE_STRING, &name,
584                                  DBUS_TYPE_INVALID))
585     {
586       dbus_message_unref (message);
587       _DBUS_SET_OOM (error);
588       return DBUS_UID_UNSET;
589     }
590   
591   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
592                                                      error);
593   
594   dbus_message_unref (message);
595   
596   if (reply == NULL)
597     {
598       _DBUS_ASSERT_ERROR_IS_SET (error);
599       return DBUS_UID_UNSET;
600     }  
601
602   if (dbus_set_error_from_message (error, reply))
603     {
604       _DBUS_ASSERT_ERROR_IS_SET (error);
605       dbus_message_unref (reply);
606       return DBUS_UID_UNSET;
607     }
608   
609   if (!dbus_message_get_args (reply, error,
610                               DBUS_TYPE_UINT32, &uid,
611                               DBUS_TYPE_INVALID))
612     {
613       _DBUS_ASSERT_ERROR_IS_SET (error);
614       dbus_message_unref (reply);
615       return DBUS_UID_UNSET;
616     }
617
618   dbus_message_unref (reply);
619   
620   return (unsigned long) uid;
621 }
622
623
624 /**
625  * Asks the bus to assign the given name to this connection by invoking
626  * the RequestName method on the bus. This method is fully documented
627  * in the D-BUS specification. For quick reference, the flags and
628  * result codes are discussed here, but the specification is the
629  * canonical version of this information.
630  *
631  * The #DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT flag indicates that
632  * if the name is successfully requested, other applications
633  * will not be able to take over the name. i.e. the name's
634  * owner (the application calling this function) must let go of
635  * the name, it will not lose it involuntarily.
636  *
637  * The #DBUS_NAME_FLAG_REPLACE_EXISTING flag indicates that the caller
638  * would like to take over the name from the current owner.
639  * If the current name owner used #DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT
640  * then this flag indicates that the caller would like to be placed
641  * in the queue to own the name when the current owner lets go.
642  *
643  * If no flags are given, an application will receive the requested
644  * name only if the name is currently unowned; and it will give
645  * up the name if another application asks to take it over using
646  * #DBUS_NAME_FLAG_REPLACE_EXISTING.
647  *
648  * This function returns a result code. The possible result codes
649  * are as follows.
650  * 
651  * #DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER means that the name had no
652  * existing owner, and the caller is now the primary owner; or that
653  * the name had an owner, and the caller specified
654  * #DBUS_NAME_FLAG_REPLACE_EXISTING, and the current owner did not
655  * specify #DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT.
656  *
657  * #DBUS_REQUEST_NAME_REPLY_IN_QUEUE happens only if the current owner
658  * specified #DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT and the caller specified
659  * #DBUS_NAME_FLAG_REPLACE_EXISTING. In this case the caller ends up in
660  * a queue to own the name after the current owner gives it up.
661  *
662  * #DBUS_REQUEST_NAME_REPLY_EXISTS happens if the name has an owner
663  * #already and DBUS_NAME_FLAG_REPLACE_EXISTING was not specified.
664  *
665  * #DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER happens if an application
666  * requests a name it already owns.
667  *
668  * When a service represents an application, say "text editor," then
669  * it should specify #DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT if it wants
670  * the first editor started to be the user's editor vs. the last one
671  * started.  Then any editor that can be the user's editor should
672  * specify #DBUS_NAME_FLAG_REPLACE_EXISTING to either take over
673  * (last-started-wins) or be queued up (first-started-wins) according
674  * to whether #DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT was given.
675  * 
676  * @todo this all seems sort of broken. Shouldn't the flags be a property
677  * of the name, not the app requesting the name? What are the use-cases
678  * other than the "text editor" thing and how are we supporting them?
679  * 
680  * @param connection the connection
681  * @param name the name to request
682  * @param flags flags
683  * @param error location to store the error
684  * @returns a result code, -1 if error is set
685  */ 
686 int
687 dbus_bus_request_name (DBusConnection *connection,
688                        const char     *name,
689                        unsigned int    flags,
690                        DBusError      *error)
691 {
692   DBusMessage *message, *reply;
693   dbus_uint32_t result;
694
695   _dbus_return_val_if_fail (connection != NULL, 0);
696   _dbus_return_val_if_fail (name != NULL, 0);
697   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
698   _dbus_return_val_if_error_is_set (error, 0);
699   
700   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
701                                           DBUS_PATH_DBUS,
702                                           DBUS_INTERFACE_DBUS,
703                                           "RequestName");
704
705   if (message == NULL)
706     {
707       _DBUS_SET_OOM (error);
708       return -1;
709     }
710  
711   if (!dbus_message_append_args (message,
712                                  DBUS_TYPE_STRING, &name,
713                                  DBUS_TYPE_UINT32, &flags,
714                                  DBUS_TYPE_INVALID))
715     {
716       dbus_message_unref (message);
717       _DBUS_SET_OOM (error);
718       return -1;
719     }
720   
721   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
722                                                      error);
723   
724   dbus_message_unref (message);
725   
726   if (reply == NULL)
727     {
728       _DBUS_ASSERT_ERROR_IS_SET (error);
729       return -1;
730     }  
731
732   if (dbus_set_error_from_message (error, reply))
733     {
734       _DBUS_ASSERT_ERROR_IS_SET (error);
735       dbus_message_unref (reply);
736       return -1;
737     }
738   
739   if (!dbus_message_get_args (reply, error,
740                               DBUS_TYPE_UINT32, &result,
741                               DBUS_TYPE_INVALID))
742     {
743       _DBUS_ASSERT_ERROR_IS_SET (error);
744       dbus_message_unref (reply);
745       return -1;
746     }
747
748   dbus_message_unref (reply);
749   
750   return result;
751 }
752
753 /**
754  * Checks whether a certain name has an owner.
755  *
756  * @param connection the connection
757  * @param name the name
758  * @param error location to store any errors
759  * @returns #TRUE if the name exists, #FALSE if not or on error
760  */
761 dbus_bool_t
762 dbus_bus_name_has_owner (DBusConnection *connection,
763                          const char     *name,
764                          DBusError      *error)
765 {
766   DBusMessage *message, *reply;
767   dbus_bool_t exists;
768
769   _dbus_return_val_if_fail (connection != NULL, FALSE);
770   _dbus_return_val_if_fail (name != NULL, FALSE);
771   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
772   _dbus_return_val_if_error_is_set (error, FALSE);
773   
774   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
775                                           DBUS_PATH_DBUS,
776                                           DBUS_INTERFACE_DBUS,
777                                           "NameHasOwner");
778   if (message == NULL)
779     {
780       _DBUS_SET_OOM (error);
781       return FALSE;
782     }
783   
784   if (!dbus_message_append_args (message,
785                                  DBUS_TYPE_STRING, &name,
786                                  DBUS_TYPE_INVALID))
787     {
788       dbus_message_unref (message);
789       _DBUS_SET_OOM (error);
790       return FALSE;
791     }
792   
793   reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
794   dbus_message_unref (message);
795
796   if (reply == NULL)
797     {
798       _DBUS_ASSERT_ERROR_IS_SET (error);
799       return FALSE;
800     }
801
802   if (!dbus_message_get_args (reply, error,
803                               DBUS_TYPE_BOOLEAN, &exists,
804                               DBUS_TYPE_INVALID))
805     {
806       _DBUS_ASSERT_ERROR_IS_SET (error);
807       dbus_message_unref (reply);
808       return FALSE;
809     }
810   
811   dbus_message_unref (reply);
812   return exists;
813 }
814
815 /**
816  * Starts a service that will request ownership of the given name.
817  * The returned result will be one of be one of
818  * #DBUS_START_REPLY_SUCCESS or #DBUS_START_REPLY_ALREADY_RUNNING if
819  * successful.  Pass #NULL if you don't care about the result.
820  * 
821  * The flags parameter is for future expansion, currently you should
822  * specify 0.
823  *
824  * @param connection the connection
825  * @param name the name we want the new service to request
826  * @param flags the flags (should always be 0 for now)
827  * @param result a place to store the result or #NULL
828  * @param error location to store any errors
829  * @returns #TRUE if the activation succeeded, #FALSE if not
830  */
831 dbus_bool_t
832 dbus_bus_start_service_by_name (DBusConnection *connection,
833                                 const char     *name,
834                                 dbus_uint32_t   flags,
835                                 dbus_uint32_t  *result,
836                                 DBusError      *error)
837 {
838   DBusMessage *msg;
839   DBusMessage *reply;
840
841   _dbus_return_val_if_fail (connection != NULL, FALSE);
842   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
843   
844   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
845                                       DBUS_PATH_DBUS,
846                                       DBUS_INTERFACE_DBUS,
847                                       "StartServiceByName");
848
849   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name,
850                                  DBUS_TYPE_UINT32, &flags, DBUS_TYPE_INVALID))
851     {
852       dbus_message_unref (msg);
853       _DBUS_SET_OOM (error);
854       return FALSE;
855     }
856
857   reply = dbus_connection_send_with_reply_and_block (connection, msg,
858                                                      -1, error);
859   dbus_message_unref (msg);
860
861   if (reply == NULL)
862     {
863       _DBUS_ASSERT_ERROR_IS_SET (error);
864       return FALSE;
865     }
866
867   if (dbus_set_error_from_message (error, reply))
868     {
869       _DBUS_ASSERT_ERROR_IS_SET (error);
870       dbus_message_unref (reply);
871       return FALSE;
872     }
873
874   if (result != NULL &&
875       !dbus_message_get_args (reply, error, DBUS_TYPE_UINT32,
876                               result, DBUS_TYPE_INVALID))
877     {
878       _DBUS_ASSERT_ERROR_IS_SET (error);
879       dbus_message_unref (reply);
880       return FALSE;
881     }
882   
883   dbus_message_unref (reply);
884   return TRUE;
885 }
886
887 static void
888 send_no_return_values (DBusConnection *connection,
889                        DBusMessage    *msg,
890                        DBusError      *error)
891 {
892   if (error)
893     {
894       /* Block to check success codepath */
895       DBusMessage *reply;
896       
897       reply = dbus_connection_send_with_reply_and_block (connection, msg,
898                                                          -1, error);
899       
900       if (reply == NULL)
901         _DBUS_ASSERT_ERROR_IS_SET (error);
902       else
903         dbus_message_unref (reply);
904     }
905   else
906     {
907       /* Silently-fail nonblocking codepath */
908       dbus_message_set_no_reply (msg, TRUE);
909       dbus_connection_send (connection, msg, NULL);
910     }
911 }
912
913 /**
914  * Adds a match rule to match messages going through the message bus.
915  * The "rule" argument is the string form of a match rule.
916  *
917  * If you pass #NULL for the error, this function will not
918  * block; the match thus won't be added until you flush the
919  * connection, and if there's an error adding the match
920  * (only possible error is lack of resources in the bus),
921  * you won't find out about it.
922  *
923  * If you pass non-#NULL for the error this function will
924  * block until it gets a reply.
925  *
926  * Normal API conventions would have the function return
927  * a boolean value indicating whether the error was set,
928  * but that would require blocking always to determine
929  * the return value.
930  * 
931  * @param connection connection to the message bus
932  * @param rule textual form of match rule
933  * @param error location to store any errors
934  */
935 void
936 dbus_bus_add_match (DBusConnection *connection,
937                     const char     *rule,
938                     DBusError      *error)
939 {
940   DBusMessage *msg;
941
942   _dbus_return_if_fail (rule != NULL);
943
944   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
945                                       DBUS_PATH_DBUS,
946                                       DBUS_INTERFACE_DBUS,
947                                       "AddMatch");
948
949   if (msg == NULL)
950     {
951       _DBUS_SET_OOM (error);
952       return;
953     }
954
955   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
956                                  DBUS_TYPE_INVALID))
957     {
958       dbus_message_unref (msg);
959       _DBUS_SET_OOM (error);
960       return;
961     }
962
963   send_no_return_values (connection, msg, error);
964
965   dbus_message_unref (msg);
966 }
967
968 /**
969  * Removes a previously-added match rule "by value" (the most
970  * recently-added identical rule gets removed).  The "rule" argument
971  * is the string form of a match rule.
972  *
973  * If you pass #NULL for the error, this function will not
974  * block; otherwise it will. See detailed explanation in
975  * docs for dbus_bus_add_match().
976  * 
977  * @param connection connection to the message bus
978  * @param rule textual form of match rule
979  * @param error location to store any errors
980  */
981 void
982 dbus_bus_remove_match (DBusConnection *connection,
983                        const char     *rule,
984                        DBusError      *error)
985 {
986   DBusMessage *msg;
987
988   _dbus_return_if_fail (rule != NULL);
989   
990   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
991                                       DBUS_PATH_DBUS,
992                                       DBUS_INTERFACE_DBUS,
993                                       "RemoveMatch");
994
995   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
996                                  DBUS_TYPE_INVALID))
997     {
998       dbus_message_unref (msg);
999       _DBUS_SET_OOM (error);
1000       return;
1001     }
1002
1003   send_no_return_values (connection, msg, error);
1004
1005   dbus_message_unref (msg);
1006 }
1007
1008 /** @} */