2006-10-01 Havoc Pennington <hp@redhat.com>
[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 "dbus-connection-internal.h"
32 #include <string.h>
33
34 /**
35  * @defgroup DBusBus Message bus APIs
36  * @ingroup DBus
37  * @brief Functions for communicating with the message bus
38  *
39  * @todo right now the default address of the system bus is hardcoded,
40  * so if you change it in the global config file suddenly you have to
41  * set DBUS_SYSTEM_BUS_ADDRESS env variable.  Might be nice if the
42  * client lib somehow read the config file, or if the bus on startup
43  * somehow wrote out its address to a well-known spot, but might also
44  * not be worth it.
45  */
46
47 /**
48  * @defgroup DBusBusInternals Message bus APIs internals
49  * @ingroup DBusInternals
50  * @brief Internals of functions for communicating with the message bus
51  *
52  * @{
53  */
54
55 /**
56  * Block of message-bus-related data we attach to each
57  * #DBusConnection used with these convenience functions.
58  *
59  */
60 typedef struct
61 {
62   DBusConnection *connection; /**< Connection we're associated with */
63   char *unique_name; /**< Unique name of this connection */
64
65   unsigned int is_well_known : 1; /**< Is one of the well-known connections in our global array */
66 } BusData;
67
68 /** The slot we have reserved to store BusData.
69  */
70 static dbus_int32_t bus_data_slot = -1;
71
72 /** Number of bus types */
73 #define N_BUS_TYPES 3
74
75 static DBusConnection *bus_connections[N_BUS_TYPES];
76 static char *bus_connection_addresses[N_BUS_TYPES] = { NULL, NULL, NULL };
77
78 static DBusBusType activation_bus_type = DBUS_BUS_STARTER;
79
80 static dbus_bool_t initialized = FALSE;
81
82 /**
83  * Lock for globals in this file
84  */
85 _DBUS_DEFINE_GLOBAL_LOCK (bus);
86
87 static void
88 addresses_shutdown_func (void *data)
89 {
90   int i;
91
92   i = 0;
93   while (i < N_BUS_TYPES)
94     {
95       if (bus_connections[i] != NULL)
96         _dbus_warn ("dbus_shutdown() called but connections were still live!");
97       
98       dbus_free (bus_connection_addresses[i]);
99       bus_connection_addresses[i] = NULL;
100       ++i;
101     }
102
103   activation_bus_type = DBUS_BUS_STARTER;
104 }
105
106 static dbus_bool_t
107 get_from_env (char           **connection_p,
108               const char      *env_var)
109 {
110   const char *s;
111   
112   _dbus_assert (*connection_p == NULL);
113   
114   s = _dbus_getenv (env_var);
115   if (s == NULL || *s == '\0')
116     return TRUE; /* successfully didn't use the env var */
117   else
118     {
119       *connection_p = _dbus_strdup (s);
120       return *connection_p != NULL;
121     }
122 }
123
124 static dbus_bool_t
125 init_connections_unlocked (void)
126 {
127   if (!initialized)
128     {
129       const char *s;
130       int i;
131
132       i = 0;
133       while (i < N_BUS_TYPES)
134         {
135           bus_connections[i] = NULL;
136           ++i;
137         }
138
139       /* Don't init these twice, we may run this code twice if
140        * init_connections_unlocked() fails midway through.
141        * In practice, each block below should contain only one
142        * "return FALSE" or running through twice may not
143        * work right.
144        */
145       
146        if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
147          {
148            _dbus_verbose ("Filling in system bus address...\n");
149            
150            if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SYSTEM],
151                               "DBUS_SYSTEM_BUS_ADDRESS"))
152              return FALSE;
153          }
154
155                   
156        if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
157          {
158            /* Use default system bus address if none set in environment */
159            bus_connection_addresses[DBUS_BUS_SYSTEM] =
160              _dbus_strdup (DBUS_SYSTEM_BUS_DEFAULT_ADDRESS);
161
162            if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
163              return FALSE;
164            
165            _dbus_verbose ("  used default system bus \"%s\"\n",
166                           bus_connection_addresses[DBUS_BUS_SYSTEM]);
167          }
168        else
169          _dbus_verbose ("  used env var system bus \"%s\"\n",
170                         bus_connection_addresses[DBUS_BUS_SYSTEM]);
171           
172       if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
173         {
174           _dbus_verbose ("Filling in session bus address...\n");
175           
176           if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SESSION],
177                              "DBUS_SESSION_BUS_ADDRESS"))
178             return FALSE;
179
180           if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
181             bus_connection_addresses[DBUS_BUS_SESSION] =
182               _dbus_strdup (DBUS_SESSION_BUS_DEFAULT_ADDRESS);
183           
184           if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
185              return FALSE;
186
187           _dbus_verbose ("  \"%s\"\n", bus_connection_addresses[DBUS_BUS_SESSION] ?
188                          bus_connection_addresses[DBUS_BUS_SESSION] : "none set");
189         }
190
191       if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
192         {
193           _dbus_verbose ("Filling in activation bus address...\n");
194           
195           if (!get_from_env (&bus_connection_addresses[DBUS_BUS_STARTER],
196                              "DBUS_STARTER_ADDRESS"))
197             return FALSE;
198           
199           _dbus_verbose ("  \"%s\"\n", bus_connection_addresses[DBUS_BUS_STARTER] ?
200                          bus_connection_addresses[DBUS_BUS_STARTER] : "none set");
201         }
202
203
204       if (bus_connection_addresses[DBUS_BUS_STARTER] != NULL)
205         {
206           s = _dbus_getenv ("DBUS_STARTER_BUS_TYPE");
207               
208           if (s != NULL)
209             {
210               _dbus_verbose ("Bus activation type was set to \"%s\"\n", s);
211                   
212               if (strcmp (s, "system") == 0)
213                 activation_bus_type = DBUS_BUS_SYSTEM;
214               else if (strcmp (s, "session") == 0)
215                 activation_bus_type = DBUS_BUS_SESSION;
216             }
217         }
218       else
219         {
220           /* Default to the session bus instead if available */
221           if (bus_connection_addresses[DBUS_BUS_SESSION] != NULL)
222             {
223               bus_connection_addresses[DBUS_BUS_STARTER] =
224                 _dbus_strdup (bus_connection_addresses[DBUS_BUS_SESSION]);
225               if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
226                 return FALSE;
227             }
228         }
229       
230       /* If we return FALSE we have to be sure that restarting
231        * the above code will work right
232        */
233       
234       if (!_dbus_setenv ("DBUS_ACTIVATION_ADDRESS", NULL))
235         return FALSE;
236
237       if (!_dbus_setenv ("DBUS_ACTIVATION_BUS_TYPE", NULL))
238         return FALSE;
239       
240       if (!_dbus_register_shutdown_func (addresses_shutdown_func,
241                                          NULL))
242         return FALSE;
243       
244       initialized = TRUE;
245     }
246
247   return initialized;
248 }
249
250 static void
251 bus_data_free (void *data)
252 {
253   BusData *bd = data;
254   
255   if (bd->is_well_known)
256     {
257       int i;
258       _DBUS_LOCK (bus);
259       /* We may be stored in more than one slot */
260       i = 0;
261       while (i < N_BUS_TYPES)
262         {
263           if (bus_connections[i] == bd->connection)
264             bus_connections[i] = NULL;
265           
266           ++i;
267         }
268       _DBUS_UNLOCK (bus);
269     }
270   
271   dbus_free (bd->unique_name);
272   dbus_free (bd);
273
274   dbus_connection_free_data_slot (&bus_data_slot);
275 }
276
277 static BusData*
278 ensure_bus_data (DBusConnection *connection)
279 {
280   BusData *bd;
281
282   if (!dbus_connection_allocate_data_slot (&bus_data_slot))
283     return NULL;
284
285   bd = dbus_connection_get_data (connection, bus_data_slot);
286   if (bd == NULL)
287     {      
288       bd = dbus_new0 (BusData, 1);
289       if (bd == NULL)
290         {
291           dbus_connection_free_data_slot (&bus_data_slot);
292           return NULL;
293         }
294
295       bd->connection = connection;
296       
297       if (!dbus_connection_set_data (connection, bus_data_slot, bd,
298                                      bus_data_free))
299         {
300           dbus_free (bd);
301           dbus_connection_free_data_slot (&bus_data_slot);
302           return NULL;
303         }
304
305       /* Data slot refcount now held by the BusData */
306     }
307   else
308     {
309       dbus_connection_free_data_slot (&bus_data_slot);
310     }
311
312   return bd;
313 }
314
315 /**
316  * Internal function that checks to see if this
317  * is a shared connection owned by the bus and if it is unref it.
318  *
319  * @param connection a connection that has been disconnected.
320  */
321 void
322 _dbus_bus_notify_shared_connection_disconnected_unlocked (DBusConnection *connection)
323 {
324   int i;
325   
326   _DBUS_LOCK (bus);
327
328   /* We are expecting to have the connection saved in only one of these
329    * slots, but someone could in a pathological case set system and session
330    * bus to the same bus or something. Or set one of them to the starter
331    * bus without setting the starter bus type in the env variable.
332    * So we don't break the loop as soon as we find a match.
333    */
334   for (i = 0; i < N_BUS_TYPES; ++i)
335     {
336       if (bus_connections[i] == connection)
337         {
338           bus_connections[i] = NULL;
339           _dbus_connection_unref_unlocked (connection);
340         }
341     }
342
343   _DBUS_UNLOCK (bus);
344 }
345
346 static DBusConnection *
347 internal_bus_get (DBusBusType  type,
348                   dbus_bool_t  private,
349                   DBusError   *error)
350 {
351   const char *address;
352   DBusConnection *connection;
353   BusData *bd;
354   DBusBusType address_type;
355
356   _dbus_return_val_if_fail (type >= 0 && type < N_BUS_TYPES, NULL);
357   _dbus_return_val_if_error_is_set (error, NULL);
358
359   _DBUS_LOCK (bus);
360
361   if (!init_connections_unlocked ())
362     {
363       _DBUS_UNLOCK (bus);
364       _DBUS_SET_OOM (error);
365       return NULL;
366     }
367
368   /* We want to use the activation address even if the
369    * activating bus is the session or system bus,
370    * per the spec.
371    */
372   address_type = type;
373   
374   /* Use the real type of the activation bus for getting its
375    * connection, but only if the real type's address is available. (If
376    * the activating bus isn't a well-known bus then
377    * activation_bus_type == DBUS_BUS_STARTER)
378    */
379   if (type == DBUS_BUS_STARTER &&
380       bus_connection_addresses[activation_bus_type] != NULL)
381     type = activation_bus_type;
382   
383   if (!private && bus_connections[type] != NULL)
384     {
385       connection = bus_connections[type];
386       dbus_connection_ref (connection);
387       
388       _DBUS_UNLOCK (bus);
389       return connection;
390     }
391
392   address = bus_connection_addresses[address_type];
393   if (address == NULL)
394     {
395       dbus_set_error (error, DBUS_ERROR_FAILED,
396                       "Unable to determine the address of the message bus (try 'man dbus-launch' and 'man dbus-daemon' for help)");
397       _DBUS_UNLOCK (bus);
398       return NULL;
399     }
400
401   if (private)
402     connection = dbus_connection_open_private (address, error);
403   else
404     connection = dbus_connection_open (address, error);
405   
406   if (!connection)
407     {
408       _DBUS_ASSERT_ERROR_IS_SET (error);
409       _DBUS_UNLOCK (bus);
410       return NULL;
411     }
412
413   /* By default we're bound to the lifecycle of
414    * the message bus.
415    */
416   dbus_connection_set_exit_on_disconnect (connection,
417                                           TRUE);
418   
419   if (!dbus_bus_register (connection, error))
420     {
421       _DBUS_ASSERT_ERROR_IS_SET (error);
422       _dbus_connection_close_possibly_shared (connection);
423       dbus_connection_unref (connection);
424
425       _DBUS_UNLOCK (bus);
426       return NULL;
427     }
428
429   if (!private)
430     {
431       /* get a hard ref to the connection */
432       bus_connections[type] = connection;
433       dbus_connection_ref (bus_connections[type]);
434     }
435   
436   bd = ensure_bus_data (connection);
437   _dbus_assert (bd != NULL);
438
439   bd->is_well_known = TRUE;
440
441   _DBUS_UNLOCK (bus);
442
443   /* Return a reference to the caller */
444   return connection;
445 }
446
447
448 /** @} */ /* end of implementation details docs */
449
450 /**
451  * @addtogroup DBusBus
452  * @{
453  */
454
455 /**
456  * Connects to a bus daemon and registers the client with it.  If a
457  * connection to the bus already exists, then that connection is
458  * returned.  The caller of this function owns a reference to the bus.
459  *
460  * The caller may NOT call dbus_connection_close() on this connection;
461  * see dbus_connection_open() and dbus_connection_close() for details
462  * on that.
463  *
464  * If this function obtains a new connection object never before
465  * returned from dbus_bus_get(), it will call
466  * dbus_connection_set_exit_on_disconnect(), so the application
467  * will exit if the connection closes. You can undo this
468  * by calling dbus_connection_set_exit_on_disconnect() yourself
469  * after you get the connection.
470  * 
471  * @param type bus type
472  * @param error address where an error can be returned.
473  * @returns a #DBusConnection with new ref
474  */
475 DBusConnection *
476 dbus_bus_get (DBusBusType  type,
477               DBusError   *error)
478 {
479   return internal_bus_get (type, FALSE, error);
480 }
481
482 /**
483  * Connects to a bus daemon and registers the client with it as with dbus_bus_register().
484  * Unlike dbus_bus_get(), always creates a new connection. This connection
485  * will not be saved or recycled by libdbus. Caller owns a reference
486  * to the bus and must either close it or know it to be closed
487  * prior to releasing this reference.
488  *
489  * See dbus_connection_open_private() for more details on when to
490  * close and unref this connection.
491  *
492  * This function calls
493  * dbus_connection_set_exit_on_disconnect() on the new connection, so the application
494  * will exit if the connection closes. You can undo this
495  * by calling dbus_connection_set_exit_on_disconnect() yourself
496  * after you get the connection.
497  *
498  * @param type bus type
499  * @param error address where an error can be returned.
500  * @returns a DBusConnection with new ref
501  */
502 DBusConnection *
503 dbus_bus_get_private (DBusBusType  type,
504                       DBusError   *error)
505 {
506   return internal_bus_get (type, TRUE, error);
507 }
508
509 /**
510  * Registers a connection with the bus. This must be the first
511  * thing an application does when connecting to the message bus.
512  * If registration succeeds, the unique name will be set,
513  * and can be obtained using dbus_bus_get_unique_name().
514  *
515  * If you use dbus_bus_get() or dbus_bus_get_private() this
516  * function will be called for you.
517  * 
518  * @param connection the connection
519  * @param error place to store errors
520  * @returns #TRUE on success
521  */
522 dbus_bool_t
523 dbus_bus_register (DBusConnection *connection,
524                    DBusError      *error)
525 {
526   DBusMessage *message, *reply;
527   char *name;
528   BusData *bd;
529   dbus_bool_t retval;
530
531   _dbus_return_val_if_fail (connection != NULL, FALSE);
532   _dbus_return_val_if_error_is_set (error, FALSE);
533
534   retval = FALSE;
535   
536   bd = ensure_bus_data (connection);
537   if (bd == NULL)
538     {
539       _DBUS_SET_OOM (error);
540       return FALSE;
541     }
542
543   if (bd->unique_name != NULL)
544     {
545       _dbus_warn ("Attempt to register the same DBusConnection with the message bus, but it is already registered\n");
546       /* This isn't an error, it's a programming bug. We'll be nice
547        * and not _dbus_assert_not_reached()
548        */
549       return TRUE;
550     }
551   
552   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
553                                           DBUS_PATH_DBUS,
554                                           DBUS_INTERFACE_DBUS,
555                                           "Hello"); 
556
557   if (!message)
558     {
559       _DBUS_SET_OOM (error);
560       return FALSE;
561     }
562   
563   reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
564
565   dbus_message_unref (message);
566   
567   if (reply == NULL)
568     goto out;
569   else if (dbus_set_error_from_message (error, reply))
570     goto out;
571   else if (!dbus_message_get_args (reply, error,
572                                    DBUS_TYPE_STRING, &name,
573                                    DBUS_TYPE_INVALID))
574     goto out;
575   
576   bd->unique_name = _dbus_strdup (name);
577   if (bd->unique_name == NULL)
578     {
579       _DBUS_SET_OOM (error);
580       goto out;
581     }
582   
583   retval = TRUE;
584   
585  out:
586   if (reply)
587     dbus_message_unref (reply);
588
589   if (!retval)
590     _DBUS_ASSERT_ERROR_IS_SET (error);
591   
592   return retval;
593 }
594
595
596 /**
597  * Sets the unique name of the connection.  Can only be used if you
598  * registered with the bus manually (i.e. if you did not call
599  * dbus_bus_register()). Can only be called once per connection.
600  *
601  * @param connection the connection
602  * @param unique_name the unique name
603  * @returns #FALSE if not enough memory
604  */
605 dbus_bool_t
606 dbus_bus_set_unique_name (DBusConnection *connection,
607                           const char     *unique_name)
608 {
609   BusData *bd;
610
611   _dbus_return_val_if_fail (connection != NULL, FALSE);
612   _dbus_return_val_if_fail (unique_name != NULL, FALSE);
613   
614   bd = ensure_bus_data (connection);
615   if (bd == NULL)
616     return FALSE;
617
618   _dbus_assert (bd->unique_name == NULL);
619   
620   bd->unique_name = _dbus_strdup (unique_name);
621   return bd->unique_name != NULL;
622 }
623
624 /**
625  * Gets the unique name of the connection.  Only possible after the
626  * connection has been registered with the message bus.
627  *
628  * The name remains valid for the duration of the connection and
629  * should not be freed by the caller.
630  * 
631  * @param connection the connection
632  * @returns the unique name or NULL on error
633  */
634 const char*
635 dbus_bus_get_unique_name (DBusConnection *connection)
636 {
637   BusData *bd;
638
639   _dbus_return_val_if_fail (connection != NULL, NULL);
640   
641   bd = ensure_bus_data (connection);
642   if (bd == NULL)
643     return NULL;
644   
645   return bd->unique_name;
646 }
647
648 /**
649  * Asks the bus to return the uid of the named
650  * connection.
651  *
652  * Not going to work on Windows, the bus should return
653  * an error then.
654  * 
655  * @param connection the connection
656  * @param name a name owned by the connection
657  * @param error location to store the error
658  * @returns a result code, -1 if error is set
659  */ 
660 unsigned long
661 dbus_bus_get_unix_user (DBusConnection *connection,
662                         const char     *name,
663                         DBusError      *error)
664 {
665   DBusMessage *message, *reply;
666   dbus_uint32_t uid;
667
668   _dbus_return_val_if_fail (connection != NULL, DBUS_UID_UNSET);
669   _dbus_return_val_if_fail (name != NULL, DBUS_UID_UNSET);
670   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), DBUS_UID_UNSET);
671   _dbus_return_val_if_error_is_set (error, DBUS_UID_UNSET);
672   
673   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
674                                           DBUS_PATH_DBUS,
675                                           DBUS_INTERFACE_DBUS,
676                                           "GetConnectionUnixUser");
677
678   if (message == NULL)
679     {
680       _DBUS_SET_OOM (error);
681       return DBUS_UID_UNSET;
682     }
683  
684   if (!dbus_message_append_args (message,
685                                  DBUS_TYPE_STRING, &name,
686                                  DBUS_TYPE_INVALID))
687     {
688       dbus_message_unref (message);
689       _DBUS_SET_OOM (error);
690       return DBUS_UID_UNSET;
691     }
692   
693   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
694                                                      error);
695   
696   dbus_message_unref (message);
697   
698   if (reply == NULL)
699     {
700       _DBUS_ASSERT_ERROR_IS_SET (error);
701       return DBUS_UID_UNSET;
702     }  
703
704   if (dbus_set_error_from_message (error, reply))
705     {
706       _DBUS_ASSERT_ERROR_IS_SET (error);
707       dbus_message_unref (reply);
708       return DBUS_UID_UNSET;
709     }
710   
711   if (!dbus_message_get_args (reply, error,
712                               DBUS_TYPE_UINT32, &uid,
713                               DBUS_TYPE_INVALID))
714     {
715       _DBUS_ASSERT_ERROR_IS_SET (error);
716       dbus_message_unref (reply);
717       return DBUS_UID_UNSET;
718     }
719
720   dbus_message_unref (reply);
721   
722   return (unsigned long) uid;
723 }
724
725
726 /**
727  * Asks the bus to assign the given name to this connection by invoking
728  * the RequestName method on the bus. This method is fully documented
729  * in the D-Bus specification. For quick reference, the flags and
730  * result codes are discussed here, but the specification is the
731  * canonical version of this information.
732  *
733  * The #DBUS_NAME_FLAG_ALLOW_REPLACEMENT flag indicates that the caller
734  * will allow other services to take over the name from the current owner.
735  *
736  * The #DBUS_NAME_FLAG_REPLACE_EXISTING flag indicates that the caller
737  * would like to take over the name from the current owner.
738  * If the current name owner did not use #DBUS_NAME_FLAG_ALLOW_REPLACEMENT
739  * then this flag indicates that the caller would like to be placed
740  * in the queue to own the name when the current owner lets go.
741  *
742  * If no flags are given, an application will receive the requested
743  * name only if the name is currently unowned; it will NOT give
744  * up the name if another application asks to take it over using
745  * #DBUS_NAME_FLAG_REPLACE_EXISTING.
746  *
747  * This function returns a result code. The possible result codes
748  * are as follows.
749  * 
750  * #DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER means that the name had no
751  * existing owner, and the caller is now the primary owner; or that
752  * the name had an owner, and the caller specified
753  * #DBUS_NAME_FLAG_REPLACE_EXISTING, and the current owner
754  * specified #DBUS_NAME_FLAG_ALLOW_REPLACEMENT.
755  *
756  * #DBUS_REQUEST_NAME_REPLY_IN_QUEUE happens only if the caller does NOT
757  * specify #DBUS_NAME_FLAG_DO_NOT_QUEUE and either the current owner
758  * did NOT specify #DBUS_NAME_FLAG_ALLOW_REPLACEMENT or the caller did NOT
759  * specify #DBUS_NAME_FLAG_REPLACE_EXISTING. In this case the caller ends up 
760  * in a queue to own the name after the current owner gives it up.
761  *
762  * #DBUS_REQUEST_NAME_REPLY_EXISTS happens if the name has an owner
763  * already and the caller specifies #DBUS_NAME_FLAG_DO_NOT_QUEUE
764  * and either the current owner has NOT specified 
765  * #DBUS_NAME_FLAG_ALLOW_REPLACEMENT or the caller did NOT specify 
766  * #DBUS_NAME_FLAG_REPLACE_EXISTING.
767  *
768  * #DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER happens if an application
769  * requests a name it already owns.
770  *
771  * When a service represents an application, say "text editor," then
772  * it should specify #DBUS_NAME_FLAG_ALLOW_REPLACEMENT if it wants
773  * the last editor started to be the user's editor vs. the first one
774  * started.  Then any editor that can be the user's editor should
775  * specify #DBUS_NAME_FLAG_REPLACE_EXISTING to either take over
776  * (last-started-wins) or be queued up (first-started-wins) according
777  * to whether #DBUS_NAME_FLAG_ALLOW_REPLACEMENT was given.
778  * 
779  * @param connection the connection
780  * @param name the name to request
781  * @param flags flags
782  * @param error location to store the error
783  * @returns a result code, -1 if error is set
784  */ 
785 int
786 dbus_bus_request_name (DBusConnection *connection,
787                        const char     *name,
788                        unsigned int    flags,
789                        DBusError      *error)
790 {
791   DBusMessage *message, *reply;
792   dbus_uint32_t result;
793
794   _dbus_return_val_if_fail (connection != NULL, 0);
795   _dbus_return_val_if_fail (name != NULL, 0);
796   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
797   _dbus_return_val_if_error_is_set (error, 0);
798   
799   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
800                                           DBUS_PATH_DBUS,
801                                           DBUS_INTERFACE_DBUS,
802                                           "RequestName");
803
804   if (message == NULL)
805     {
806       _DBUS_SET_OOM (error);
807       return -1;
808     }
809  
810   if (!dbus_message_append_args (message,
811                                  DBUS_TYPE_STRING, &name,
812                                  DBUS_TYPE_UINT32, &flags,
813                                  DBUS_TYPE_INVALID))
814     {
815       dbus_message_unref (message);
816       _DBUS_SET_OOM (error);
817       return -1;
818     }
819   
820   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
821                                                      error);
822   
823   dbus_message_unref (message);
824   
825   if (reply == NULL)
826     {
827       _DBUS_ASSERT_ERROR_IS_SET (error);
828       return -1;
829     }  
830
831   if (dbus_set_error_from_message (error, reply))
832     {
833       _DBUS_ASSERT_ERROR_IS_SET (error);
834       dbus_message_unref (reply);
835       return -1;
836     }
837   
838   if (!dbus_message_get_args (reply, error,
839                               DBUS_TYPE_UINT32, &result,
840                               DBUS_TYPE_INVALID))
841     {
842       _DBUS_ASSERT_ERROR_IS_SET (error);
843       dbus_message_unref (reply);
844       return -1;
845     }
846
847   dbus_message_unref (reply);
848   
849   return result;
850 }
851
852
853 /**
854  * Asks the bus to unassign the given name to this connection by invoking
855  * the ReleaseName method on the bus. This method is fully documented
856  * in the D-Bus specification.
857  *
858  * @param connection the connection
859  * @param name the name to remove 
860  * @param error location to store the error
861  * @returns a result code, -1 if error is set
862  */ 
863 int
864 dbus_bus_release_name (DBusConnection *connection,
865                        const char     *name,
866                        DBusError      *error)
867 {
868   DBusMessage *message, *reply;
869   dbus_uint32_t result;
870
871   _dbus_return_val_if_fail (connection != NULL, 0);
872   _dbus_return_val_if_fail (name != NULL, 0);
873   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
874   _dbus_return_val_if_error_is_set (error, 0);
875
876   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
877                                           DBUS_PATH_DBUS,
878                                           DBUS_INTERFACE_DBUS,
879                                           "ReleaseName");
880
881   if (message == NULL)
882     {
883       _DBUS_SET_OOM (error);
884       return -1;
885     }
886
887   if (!dbus_message_append_args (message,
888                                  DBUS_TYPE_STRING, &name,
889                                  DBUS_TYPE_INVALID))
890     {
891       dbus_message_unref (message);
892       _DBUS_SET_OOM (error);
893       return -1;
894     }
895
896   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
897                                                      error);
898
899   dbus_message_unref (message);
900
901   if (reply == NULL)
902     {
903       _DBUS_ASSERT_ERROR_IS_SET (error);
904       return -1;
905     }
906
907   if (dbus_set_error_from_message (error, reply))
908     {
909       _DBUS_ASSERT_ERROR_IS_SET (error);
910       dbus_message_unref (reply);
911       return -1;
912     }
913
914   if (!dbus_message_get_args (reply, error,
915                               DBUS_TYPE_UINT32, &result,
916                               DBUS_TYPE_INVALID))
917     {
918       _DBUS_ASSERT_ERROR_IS_SET (error);
919       dbus_message_unref (reply);
920       return -1;
921     }
922
923   dbus_message_unref (reply);
924
925   return result;
926 }
927
928 /**
929  * Checks whether a certain name has an owner.
930  *
931  * @param connection the connection
932  * @param name the name
933  * @param error location to store any errors
934  * @returns #TRUE if the name exists, #FALSE if not or on error
935  */
936 dbus_bool_t
937 dbus_bus_name_has_owner (DBusConnection *connection,
938                          const char     *name,
939                          DBusError      *error)
940 {
941   DBusMessage *message, *reply;
942   dbus_bool_t exists;
943
944   _dbus_return_val_if_fail (connection != NULL, FALSE);
945   _dbus_return_val_if_fail (name != NULL, FALSE);
946   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
947   _dbus_return_val_if_error_is_set (error, FALSE);
948   
949   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
950                                           DBUS_PATH_DBUS,
951                                           DBUS_INTERFACE_DBUS,
952                                           "NameHasOwner");
953   if (message == NULL)
954     {
955       _DBUS_SET_OOM (error);
956       return FALSE;
957     }
958   
959   if (!dbus_message_append_args (message,
960                                  DBUS_TYPE_STRING, &name,
961                                  DBUS_TYPE_INVALID))
962     {
963       dbus_message_unref (message);
964       _DBUS_SET_OOM (error);
965       return FALSE;
966     }
967   
968   reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
969   dbus_message_unref (message);
970
971   if (reply == NULL)
972     {
973       _DBUS_ASSERT_ERROR_IS_SET (error);
974       return FALSE;
975     }
976
977   if (!dbus_message_get_args (reply, error,
978                               DBUS_TYPE_BOOLEAN, &exists,
979                               DBUS_TYPE_INVALID))
980     {
981       _DBUS_ASSERT_ERROR_IS_SET (error);
982       dbus_message_unref (reply);
983       return FALSE;
984     }
985   
986   dbus_message_unref (reply);
987   return exists;
988 }
989
990 /**
991  * Starts a service that will request ownership of the given name.
992  * The returned result will be one of be one of
993  * #DBUS_START_REPLY_SUCCESS or #DBUS_START_REPLY_ALREADY_RUNNING if
994  * successful.  Pass #NULL if you don't care about the result.
995  * 
996  * The flags parameter is for future expansion, currently you should
997  * specify 0.
998  *
999  * @param connection the connection
1000  * @param name the name we want the new service to request
1001  * @param flags the flags (should always be 0 for now)
1002  * @param result a place to store the result or #NULL
1003  * @param error location to store any errors
1004  * @returns #TRUE if the activation succeeded, #FALSE if not
1005  */
1006 dbus_bool_t
1007 dbus_bus_start_service_by_name (DBusConnection *connection,
1008                                 const char     *name,
1009                                 dbus_uint32_t   flags,
1010                                 dbus_uint32_t  *result,
1011                                 DBusError      *error)
1012 {
1013   DBusMessage *msg;
1014   DBusMessage *reply;
1015
1016   _dbus_return_val_if_fail (connection != NULL, FALSE);
1017   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
1018   
1019   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
1020                                       DBUS_PATH_DBUS,
1021                                       DBUS_INTERFACE_DBUS,
1022                                       "StartServiceByName");
1023
1024   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name,
1025                                  DBUS_TYPE_UINT32, &flags, DBUS_TYPE_INVALID))
1026     {
1027       dbus_message_unref (msg);
1028       _DBUS_SET_OOM (error);
1029       return FALSE;
1030     }
1031
1032   reply = dbus_connection_send_with_reply_and_block (connection, msg,
1033                                                      -1, error);
1034   dbus_message_unref (msg);
1035
1036   if (reply == NULL)
1037     {
1038       _DBUS_ASSERT_ERROR_IS_SET (error);
1039       return FALSE;
1040     }
1041
1042   if (dbus_set_error_from_message (error, reply))
1043     {
1044       _DBUS_ASSERT_ERROR_IS_SET (error);
1045       dbus_message_unref (reply);
1046       return FALSE;
1047     }
1048
1049   if (result != NULL &&
1050       !dbus_message_get_args (reply, error, DBUS_TYPE_UINT32,
1051                               result, DBUS_TYPE_INVALID))
1052     {
1053       _DBUS_ASSERT_ERROR_IS_SET (error);
1054       dbus_message_unref (reply);
1055       return FALSE;
1056     }
1057   
1058   dbus_message_unref (reply);
1059   return TRUE;
1060 }
1061
1062 static void
1063 send_no_return_values (DBusConnection *connection,
1064                        DBusMessage    *msg,
1065                        DBusError      *error)
1066 {
1067   if (error)
1068     {
1069       /* Block to check success codepath */
1070       DBusMessage *reply;
1071       
1072       reply = dbus_connection_send_with_reply_and_block (connection, msg,
1073                                                          -1, error);
1074       
1075       if (reply == NULL)
1076         _DBUS_ASSERT_ERROR_IS_SET (error);
1077       else
1078         dbus_message_unref (reply);
1079     }
1080   else
1081     {
1082       /* Silently-fail nonblocking codepath */
1083       dbus_message_set_no_reply (msg, TRUE);
1084       dbus_connection_send (connection, msg, NULL);
1085     }
1086 }
1087
1088 /**
1089  * Adds a match rule to match messages going through the message bus.
1090  * The "rule" argument is the string form of a match rule.
1091  *
1092  * If you pass #NULL for the error, this function will not
1093  * block; the match thus won't be added until you flush the
1094  * connection, and if there's an error adding the match
1095  * (only possible error is lack of resources in the bus),
1096  * you won't find out about it.
1097  *
1098  * If you pass non-#NULL for the error this function will
1099  * block until it gets a reply.
1100  *
1101  * Normal API conventions would have the function return
1102  * a boolean value indicating whether the error was set,
1103  * but that would require blocking always to determine
1104  * the return value.
1105  *
1106  * The AddMatch method is fully documented in the D-Bus 
1107  * specification. For quick reference, the format of the 
1108  * match rules is discussed here, but the specification 
1109  * is the canonical version of this information.
1110  *
1111  * Rules are specified as a string of comma separated 
1112  * key/value pairs. An example is 
1113  * "type='signal',sender='org.freedesktop.DBus',
1114  * interface='org.freedesktop.DBus',member='Foo',
1115  * path='/bar/foo',destination=':452345.34'"
1116  *
1117  * Possible keys you can match on are type, sender, 
1118  * interface, member, path, destination and the special
1119  * arg keys.  Excluding a key from the rule indicates 
1120  * a wildcard match.  For instance excluding the
1121  * the member from a match rule but adding a sender would
1122  * let all messages from that sender through.  
1123  *
1124  * Matches are inclusive not exclusive so as long as one 
1125  * rule matches the message will get through.  It is important
1126  * to note this because every time a message is received the 
1127  * application will be paged into memory to process it.  This
1128  * can cause performance problems such as draining batteries
1129  * on embedded platforms.
1130  *
1131  * The special arg keys are used for further restricting the 
1132  * match based on the parameters sent by the signal or method.
1133  * For instance arg1='foo' will check the first argument, 
1134  * arg2='bar' the second and so on.  For performance reasons
1135  * there is a set limit on the highest number parameter that
1136  * can be checked which is set in dbus-protocol.h
1137  *
1138  * @param connection connection to the message bus
1139  * @param rule textual form of match rule
1140  * @param error location to store any errors
1141  */
1142 void
1143 dbus_bus_add_match (DBusConnection *connection,
1144                     const char     *rule,
1145                     DBusError      *error)
1146 {
1147   DBusMessage *msg;
1148
1149   _dbus_return_if_fail (rule != NULL);
1150
1151   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
1152                                       DBUS_PATH_DBUS,
1153                                       DBUS_INTERFACE_DBUS,
1154                                       "AddMatch");
1155
1156   if (msg == NULL)
1157     {
1158       _DBUS_SET_OOM (error);
1159       return;
1160     }
1161
1162   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
1163                                  DBUS_TYPE_INVALID))
1164     {
1165       dbus_message_unref (msg);
1166       _DBUS_SET_OOM (error);
1167       return;
1168     }
1169
1170   send_no_return_values (connection, msg, error);
1171
1172   dbus_message_unref (msg);
1173 }
1174
1175 /**
1176  * Removes a previously-added match rule "by value" (the most
1177  * recently-added identical rule gets removed).  The "rule" argument
1178  * is the string form of a match rule.
1179  *
1180  * If you pass #NULL for the error, this function will not
1181  * block; otherwise it will. See detailed explanation in
1182  * docs for dbus_bus_add_match().
1183  * 
1184  * @param connection connection to the message bus
1185  * @param rule textual form of match rule
1186  * @param error location to store any errors
1187  */
1188 void
1189 dbus_bus_remove_match (DBusConnection *connection,
1190                        const char     *rule,
1191                        DBusError      *error)
1192 {
1193   DBusMessage *msg;
1194
1195   _dbus_return_if_fail (rule != NULL);
1196   
1197   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
1198                                       DBUS_PATH_DBUS,
1199                                       DBUS_INTERFACE_DBUS,
1200                                       "RemoveMatch");
1201
1202   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
1203                                  DBUS_TYPE_INVALID))
1204     {
1205       dbus_message_unref (msg);
1206       _DBUS_SET_OOM (error);
1207       return;
1208     }
1209
1210   send_no_return_values (connection, msg, error);
1211
1212   dbus_message_unref (msg);
1213 }
1214
1215 /** @} */