* dbus/dbus-auth.c (client_try_next_mechanism): Remove logic to
[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.0
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 <string.h>
30
31 /**
32  * @defgroup DBusBus Message bus APIs
33  * @ingroup DBus
34  * @brief Functions for communicating with the message bus
35  *
36  * @todo right now the default address of the system bus is hardcoded,
37  * so if you change it in the global config file suddenly you have to
38  * set DBUS_SYSTEM_BUS_ADDRESS env variable.  Might be nice if the
39  * client lib somehow read the config file, or if the bus on startup
40  * somehow wrote out its address to a well-known spot, but might also
41  * not be worth it.
42  */
43
44 /**
45  * @defgroup DBusBusInternals Message bus APIs internals
46  * @ingroup DBusInternals
47  * @brief Internals of functions for communicating with the message bus
48  *
49  * @{
50  */
51
52 /**
53  * Block of message-bus-related data we attach to each
54  * #DBusConnection used with these convenience functions.
55  *
56  *
57  * @todo get rid of most of these; they should be done
58  * with DBusGProxy and the Qt equivalent, i.e. the same
59  * way any other interface would be used.
60  */
61 typedef struct
62 {
63   DBusConnection *connection; /**< Connection we're associated with */
64   char *base_service; /**< Base service name of this connection */
65
66   unsigned int is_well_known : 1; /**< Is one of the well-known connections in our global array */
67 } BusData;
68
69 /** The slot we have reserved to store BusData.
70  */
71 static dbus_int32_t bus_data_slot = -1;
72
73 /** Number of bus types */
74 #define N_BUS_TYPES 3
75
76 static DBusConnection *bus_connections[N_BUS_TYPES];
77 static char *bus_connection_addresses[N_BUS_TYPES] = { NULL, NULL, NULL };
78
79 static DBusBusType activation_bus_type = DBUS_BUS_ACTIVATION;
80
81 static dbus_bool_t initialized = FALSE;
82
83 /**
84  * Lock for globals in this file
85  */
86 _DBUS_DEFINE_GLOBAL_LOCK (bus);
87
88 static void
89 addresses_shutdown_func (void *data)
90 {
91   int i;
92
93   i = 0;
94   while (i < N_BUS_TYPES)
95     {
96       if (bus_connections[i] != NULL)
97         _dbus_warn ("dbus_shutdown() called but connections were still live!");
98       
99       dbus_free (bus_connection_addresses[i]);
100       bus_connection_addresses[i] = NULL;
101       ++i;
102     }
103
104   activation_bus_type = DBUS_BUS_ACTIVATION;
105 }
106
107 static dbus_bool_t
108 get_from_env (char           **connection_p,
109               const char      *env_var)
110 {
111   const char *s;
112   
113   _dbus_assert (*connection_p == NULL);
114   
115   s = _dbus_getenv (env_var);
116   if (s == NULL || *s == '\0')
117     return TRUE; /* successfully didn't use the env var */
118   else
119     {
120       *connection_p = _dbus_strdup (s);
121       return *connection_p != NULL;
122     }
123 }
124
125 static dbus_bool_t
126 init_connections_unlocked (void)
127 {
128   if (!initialized)
129     {
130       const char *s;
131       int i;
132
133       i = 0;
134       while (i < N_BUS_TYPES)
135         {
136           bus_connections[i] = NULL;
137           ++i;
138         }
139
140       /* Don't init these twice, we may run this code twice if
141        * init_connections_unlocked() fails midway through.
142        * In practice, each block below should contain only one
143        * "return FALSE" or running through twice may not
144        * work right.
145        */
146       
147        if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
148          {
149            _dbus_verbose ("Filling in system bus address...\n");
150            
151            if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SYSTEM],
152                               "DBUS_SYSTEM_BUS_ADDRESS"))
153              return FALSE;
154          }
155
156                   
157        if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
158          {
159            /* Use default system bus address if none set in environment */
160            bus_connection_addresses[DBUS_BUS_SYSTEM] =
161              _dbus_strdup (DBUS_SYSTEM_BUS_DEFAULT_ADDRESS);
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           _dbus_verbose ("  \"%s\"\n", bus_connection_addresses[DBUS_BUS_SESSION] ?
180                          bus_connection_addresses[DBUS_BUS_SESSION] : "none set");
181         }
182
183       if (bus_connection_addresses[DBUS_BUS_ACTIVATION] == NULL)
184         {
185           _dbus_verbose ("Filling in activation bus address...\n");
186           
187           if (!get_from_env (&bus_connection_addresses[DBUS_BUS_ACTIVATION],
188                              "DBUS_ACTIVATION_ADDRESS"))
189             return FALSE;
190           
191           _dbus_verbose ("  \"%s\"\n", bus_connection_addresses[DBUS_BUS_ACTIVATION] ?
192                          bus_connection_addresses[DBUS_BUS_ACTIVATION] : "none set");
193         }
194
195
196       if (bus_connection_addresses[DBUS_BUS_ACTIVATION] != NULL)
197         {
198           s = _dbus_getenv ("DBUS_ACTIVATION_BUS_TYPE");
199               
200           if (s != NULL)
201             {
202               _dbus_verbose ("Bus activation type was set to \"%s\"\n", s);
203                   
204               if (strcmp (s, "system") == 0)
205                 activation_bus_type = DBUS_BUS_SYSTEM;
206               else if (strcmp (s, "session") == 0)
207                 activation_bus_type = DBUS_BUS_SESSION;
208             }
209         }
210       else
211         {
212           /* Default to the session bus instead if available */
213           if (bus_connection_addresses[DBUS_BUS_SESSION] != NULL)
214             {
215               bus_connection_addresses[DBUS_BUS_ACTIVATION] =
216                 _dbus_strdup (bus_connection_addresses[DBUS_BUS_SESSION]);
217               if (bus_connection_addresses[DBUS_BUS_ACTIVATION] == NULL)
218                 return FALSE;
219             }
220         }
221       
222       /* If we return FALSE we have to be sure that restarting
223        * the above code will work right
224        */
225       
226       if (!_dbus_setenv ("DBUS_ACTIVATION_ADDRESS", NULL))
227         return FALSE;
228
229       if (!_dbus_setenv ("DBUS_ACTIVATION_BUS_TYPE", NULL))
230         return FALSE;
231       
232       if (!_dbus_register_shutdown_func (addresses_shutdown_func,
233                                          NULL))
234         return FALSE;
235       
236       initialized = TRUE;
237     }
238
239   return initialized;
240 }
241
242 static void
243 bus_data_free (void *data)
244 {
245   BusData *bd = data;
246   
247   if (bd->is_well_known)
248     {
249       int i;
250       _DBUS_LOCK (bus);
251       /* We may be stored in more than one slot */
252       i = 0;
253       while (i < N_BUS_TYPES)
254         {
255           if (bus_connections[i] == bd->connection)
256             bus_connections[i] = NULL;
257           
258           ++i;
259         }
260       _DBUS_UNLOCK (bus);
261     }
262   
263   dbus_free (bd->base_service);
264   dbus_free (bd);
265
266   dbus_connection_free_data_slot (&bus_data_slot);
267 }
268
269 static BusData*
270 ensure_bus_data (DBusConnection *connection)
271 {
272   BusData *bd;
273
274   if (!dbus_connection_allocate_data_slot (&bus_data_slot))
275     return NULL;
276
277   bd = dbus_connection_get_data (connection, bus_data_slot);
278   if (bd == NULL)
279     {      
280       bd = dbus_new0 (BusData, 1);
281       if (bd == NULL)
282         {
283           dbus_connection_free_data_slot (&bus_data_slot);
284           return NULL;
285         }
286
287       bd->connection = connection;
288       
289       if (!dbus_connection_set_data (connection, bus_data_slot, bd,
290                                      bus_data_free))
291         {
292           dbus_free (bd);
293           dbus_connection_free_data_slot (&bus_data_slot);
294           return NULL;
295         }
296
297       /* Data slot refcount now held by the BusData */
298     }
299   else
300     {
301       dbus_connection_free_data_slot (&bus_data_slot);
302     }
303
304   return bd;
305 }
306
307 /** @} */ /* end of implementation details docs */
308
309 /**
310  * @addtogroup DBusBus
311  * @{
312  */
313
314 /**
315  * Connects to a bus daemon and registers the client with it.
316  * If a connection to the bus already exists, then that connection is returned.
317  *
318  * @todo alex thinks we should nullify the connection when we get a disconnect-message.
319  *
320  * @param type bus type
321  * @param error address where an error can be returned.
322  * @returns a DBusConnection
323  */
324 DBusConnection *
325 dbus_bus_get (DBusBusType  type,
326               DBusError   *error)
327 {
328   const char *address;
329   DBusConnection *connection;
330   BusData *bd;
331   DBusBusType address_type;
332
333   _dbus_return_val_if_fail (type >= 0 && type < N_BUS_TYPES, NULL);
334   _dbus_return_val_if_error_is_set (error, NULL);
335
336   _DBUS_LOCK (bus);
337
338   if (!init_connections_unlocked ())
339     {
340       _DBUS_UNLOCK (bus);
341       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
342       return NULL;
343     }
344
345   /* We want to use the activation address even if the
346    * activating bus is the session or system bus,
347    * per the spec.
348    */
349   address_type = type;
350   
351   /* Use the real type of the activation bus for getting its
352    * connection, but only if the real type's address is available. (If
353    * the activating bus isn't a well-known bus then
354    * activation_bus_type == DBUS_BUS_ACTIVATION)
355    */
356   if (type == DBUS_BUS_ACTIVATION &&
357       bus_connection_addresses[activation_bus_type] != NULL)
358     type = activation_bus_type;
359   
360   if (bus_connections[type] != NULL)
361     {
362       connection = bus_connections[type];
363       dbus_connection_ref (connection);
364       
365       _DBUS_UNLOCK (bus);
366       return connection;
367     }
368
369   address = bus_connection_addresses[address_type];
370   if (address == NULL)
371     {
372       dbus_set_error (error, DBUS_ERROR_FAILED,
373                       "Unable to determine the address of the message bus");
374       _DBUS_UNLOCK (bus);
375       return NULL;
376     }
377
378   connection = dbus_connection_open (address, error);
379   
380   if (!connection)
381     {
382       _DBUS_ASSERT_ERROR_IS_SET (error);
383       _DBUS_UNLOCK (bus);
384       return NULL;
385     }
386
387   /* By default we're bound to the lifecycle of
388    * the message bus.
389    */
390   dbus_connection_set_exit_on_disconnect (connection,
391                                           TRUE);
392   
393   if (!dbus_bus_register (connection, error))
394     {
395       _DBUS_ASSERT_ERROR_IS_SET (error);
396       dbus_connection_disconnect (connection);
397       dbus_connection_unref (connection);
398
399       _DBUS_UNLOCK (bus);
400       return NULL;
401     }
402
403   bus_connections[type] = connection;
404   bd = ensure_bus_data (connection);
405   _dbus_assert (bd != NULL);
406
407   bd->is_well_known = TRUE;
408
409   _DBUS_UNLOCK (bus);
410   return connection;
411 }
412
413
414 /**
415  * Registers a connection with the bus. This must be the first
416  * thing an application does when connecting to the message bus.
417  * If registration succeeds, the base service name will be set,
418  * and can be obtained using dbus_bus_get_base_service().
419  *
420  * @todo if we get an error reply, it has to be converted into
421  * DBusError and returned
422  * 
423  * @param connection the connection
424  * @param error place to store errors
425  * @returns #TRUE on success
426  */
427 dbus_bool_t
428 dbus_bus_register (DBusConnection *connection,
429                    DBusError      *error)
430 {
431   DBusMessage *message, *reply;
432   char *name;
433   BusData *bd;
434   dbus_bool_t retval;
435
436   _dbus_return_val_if_fail (connection != NULL, FALSE);
437   _dbus_return_val_if_error_is_set (error, FALSE);
438
439   retval = FALSE;
440   
441   bd = ensure_bus_data (connection);
442   if (bd == NULL)
443     {
444       _DBUS_SET_OOM (error);
445       return FALSE;
446     }
447
448   if (bd->base_service != NULL)
449     {
450       _dbus_warn ("Attempt to register the same DBusConnection with the message bus, but it is already registered\n");
451       /* This isn't an error, it's a programming bug. We'll be nice
452        * and not _dbus_assert_not_reached()
453        */
454       return TRUE;
455     }
456   
457   message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
458                                           DBUS_PATH_ORG_FREEDESKTOP_DBUS,
459                                           DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
460                                           "Hello"); 
461
462   if (!message)
463     {
464       _DBUS_SET_OOM (error);
465       return FALSE;
466     }
467   
468   reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
469
470   dbus_message_unref (message);
471   
472   if (reply == NULL)
473     goto out;
474   else if (dbus_set_error_from_message (error, reply))
475     goto out;
476   else if (!dbus_message_get_args (reply, error,
477                                    DBUS_TYPE_STRING, &name,
478                                    DBUS_TYPE_INVALID))
479     goto out;
480   
481   bd->base_service = name;
482
483   retval = TRUE;
484   
485  out:
486   if (reply)
487     dbus_message_unref (reply);
488
489   if (!retval)
490     _DBUS_ASSERT_ERROR_IS_SET (error);
491   
492   return retval;
493 }
494
495
496 /**
497  * Sets the base service name of the connection.
498  * Can only be used if you registered with the
499  * bus manually (i.e. if you did not call
500  * dbus_bus_register()). Can only be called
501  * once per connection.
502  *
503  * @param connection the connection
504  * @param base_service the base service name
505  * @returns #FALSE if not enough memory
506  */
507 dbus_bool_t
508 dbus_bus_set_base_service (DBusConnection *connection,
509                            const char     *base_service)
510 {
511   BusData *bd;
512
513   _dbus_return_val_if_fail (connection != NULL, FALSE);
514   _dbus_return_val_if_fail (base_service != NULL, FALSE);
515   
516   bd = ensure_bus_data (connection);
517   if (bd == NULL)
518     return FALSE;
519
520   _dbus_assert (bd->base_service == NULL);
521   
522   bd->base_service = _dbus_strdup (base_service);
523   return bd->base_service != NULL;
524 }
525
526 /**
527  * Gets the base service name of the connection.
528  * Only possible after the connection has been registered
529  * with the message bus.
530  *
531  * @param connection the connection
532  * @returns the base service name
533  */
534 const char*
535 dbus_bus_get_base_service (DBusConnection *connection)
536 {
537   BusData *bd;
538
539   _dbus_return_val_if_fail (connection != NULL, NULL);
540   
541   bd = ensure_bus_data (connection);
542   if (bd == NULL)
543     return NULL;
544   
545   return bd->base_service;
546 }
547
548 /**
549  * Asks the bus to try to acquire a certain service.
550  *
551  * @todo these docs are not complete, need to document the
552  * return value and flags
553  * 
554  * @todo if we get an error reply, it has to be converted into
555  * DBusError and returned
556  *
557  * @param connection the connection
558  * @param service_name the service name
559  * @param flags flags
560  * @param error location to store the error
561  * @returns a result code, -1 if error is set
562  */ 
563 int
564 dbus_bus_acquire_service (DBusConnection *connection,
565                           const char     *service_name,
566                           unsigned int    flags,
567                           DBusError      *error)
568 {
569   DBusMessage *message, *reply;
570   dbus_uint32_t service_result;
571
572   _dbus_return_val_if_fail (connection != NULL, 0);
573   _dbus_return_val_if_fail (service_name != NULL, 0);
574   _dbus_return_val_if_error_is_set (error, 0);
575   
576   message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
577                                           DBUS_PATH_ORG_FREEDESKTOP_DBUS,
578                                           DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
579                                           "AcquireService");
580
581   if (message == NULL)
582     {
583       _DBUS_SET_OOM (error);
584       return -1;
585     }
586  
587   if (!dbus_message_append_args (message,
588                                  DBUS_TYPE_STRING, service_name,
589                                  DBUS_TYPE_UINT32, flags,
590                                  DBUS_TYPE_INVALID))
591     {
592       dbus_message_unref (message);
593       _DBUS_SET_OOM (error);
594       return -1;
595     }
596   
597   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
598                                                      error);
599   
600   dbus_message_unref (message);
601   
602   if (reply == NULL)
603     {
604       _DBUS_ASSERT_ERROR_IS_SET (error);
605       return -1;
606     }  
607
608   if (dbus_set_error_from_message (error, reply))
609     {
610       _DBUS_ASSERT_ERROR_IS_SET (error);
611       dbus_message_unref (reply);
612       return -1;
613     }
614   
615   if (!dbus_message_get_args (reply, error,
616                               DBUS_TYPE_UINT32, &service_result,
617                               DBUS_TYPE_INVALID))
618     {
619       _DBUS_ASSERT_ERROR_IS_SET (error);
620       dbus_message_unref (reply);
621       return -1;
622     }
623
624   dbus_message_unref (reply);
625   
626   return service_result;
627 }
628
629 /**
630  * Checks whether a certain service exists.
631  *
632  * @todo the SERVICE_EXISTS message should use BOOLEAN not UINT32
633  *
634  * @param connection the connection
635  * @param service_name the service name
636  * @param error location to store any errors
637  * @returns #TRUE if the service exists, #FALSE if not or on error
638  */
639 dbus_bool_t
640 dbus_bus_service_exists (DBusConnection *connection,
641                          const char     *service_name,
642                          DBusError      *error)
643 {
644   DBusMessage *message, *reply;
645   unsigned int exists;
646
647   _dbus_return_val_if_fail (connection != NULL, FALSE);
648   _dbus_return_val_if_fail (service_name != NULL, FALSE);
649   _dbus_return_val_if_error_is_set (error, FALSE);
650   
651   message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
652                                           DBUS_PATH_ORG_FREEDESKTOP_DBUS,
653                                           DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
654                                           "ServiceExists");
655   if (message == NULL)
656     {
657       _DBUS_SET_OOM (error);
658       return FALSE;
659     }
660   
661   if (!dbus_message_append_args (message,
662                                  DBUS_TYPE_STRING, service_name,
663                                  DBUS_TYPE_INVALID))
664     {
665       dbus_message_unref (message);
666       _DBUS_SET_OOM (error);
667       return FALSE;
668     }
669   
670   reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
671   dbus_message_unref (message);
672
673   if (reply == NULL)
674     {
675       _DBUS_ASSERT_ERROR_IS_SET (error);
676       return FALSE;
677     }
678
679   if (!dbus_message_get_args (reply, error,
680                               DBUS_TYPE_UINT32, &exists,
681                               DBUS_TYPE_INVALID))
682     {
683       _DBUS_ASSERT_ERROR_IS_SET (error);
684       return FALSE;
685     }
686   
687   return (exists != FALSE);
688 }
689
690 /**
691  * Activates a given service
692  *
693  * @param connection the connection
694  * @param service_name the service name
695  * @param flags the flags
696  * @param result a place to store the result of the activation, which will
697  * be one of DBUS_ACTIVATION_REPLY_ACTIVATED or
698  * DBUS_ACTIVATION_REPLY_ALREADY_ACTIVE if successful.  Pass NULL if you
699  * don't care about the result.
700  * @param error location to store any errors
701  * @returns #TRUE if the activation succeeded, #FALSE if not
702  *
703  * @todo document what the flags do
704  */
705 dbus_bool_t
706 dbus_bus_activate_service (DBusConnection *connection,
707                            const char     *service_name,
708                            dbus_uint32_t   flags,
709                            dbus_uint32_t  *result,
710                            DBusError      *error)
711 {
712   DBusMessage *msg;
713   DBusMessage *reply;
714
715   msg = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
716                                       DBUS_PATH_ORG_FREEDESKTOP_DBUS,
717                                       DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
718                                       "ActivateService");
719
720   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, service_name,
721                                  DBUS_TYPE_UINT32, flags, DBUS_TYPE_INVALID))
722     {
723       dbus_message_unref (msg);
724       _DBUS_SET_OOM (error);
725       return FALSE;
726     }
727
728   reply = dbus_connection_send_with_reply_and_block (connection, msg,
729                                                      -1, error);
730   dbus_message_unref (msg);
731
732   if (reply == NULL)
733     {
734       _DBUS_ASSERT_ERROR_IS_SET (error);
735       return FALSE;
736     }
737
738   if (dbus_set_error_from_message (error, reply))
739     {
740       _DBUS_ASSERT_ERROR_IS_SET (error);
741       dbus_message_unref (reply);
742       return FALSE;
743     }
744
745   if (result != NULL &&
746       !dbus_message_get_args (reply, error, DBUS_TYPE_UINT32,
747                               result, DBUS_TYPE_INVALID))
748     {
749       _DBUS_ASSERT_ERROR_IS_SET (error);
750       dbus_message_unref (reply);
751       return FALSE;
752     }
753   
754   dbus_message_unref (reply);
755   return TRUE;
756 }
757
758 static void
759 send_no_return_values (DBusConnection *connection,
760                        DBusMessage    *msg,
761                        DBusError      *error)
762 {
763   if (error)
764     {
765       /* Block to check success codepath */
766       DBusMessage *reply;
767       
768       reply = dbus_connection_send_with_reply_and_block (connection, msg,
769                                                          -1, error);
770       
771       if (reply == NULL)
772         {
773           _DBUS_ASSERT_ERROR_IS_SET (error);
774           return;
775         }
776
777       if (dbus_set_error_from_message (error, reply))
778         {
779           _DBUS_ASSERT_ERROR_IS_SET (error);
780           dbus_message_unref (reply);
781           return;
782         }
783
784       dbus_message_unref (reply);
785     }
786   else
787     {
788       /* Silently-fail nonblocking codepath */
789       if (!dbus_connection_send (connection, msg, NULL))
790         return;
791     }
792 }
793
794 /**
795  * Adds a match rule to match messages going through the message bus.
796  * The "rule" argument is the string form of a match rule.
797  *
798  * If you pass #NULL for the error, this function will not
799  * block; the match thus won't be added until you flush the
800  * connection, and if there's an error adding the match
801  * (only possible error is lack of resources in the bus),
802  * you won't find out about it.
803  *
804  * If you pass non-#NULL for the error this function will
805  * block until it gets a reply.
806  *
807  * Normal API conventions would have the function return
808  * a boolean value indicating whether the error was set,
809  * but that would require blocking always to determine
810  * the return value.
811  * 
812  * @param connection connection to the message bus
813  * @param rule textual form of match rule
814  * @param error location to store any errors
815  */
816 void
817 dbus_bus_add_match (DBusConnection *connection,
818                     const char     *rule,
819                     DBusError      *error)
820 {
821   DBusMessage *msg;
822
823   msg = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
824                                       DBUS_PATH_ORG_FREEDESKTOP_DBUS,
825                                       DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
826                                       "AddMatch");
827
828   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, rule,
829                                  DBUS_TYPE_INVALID))
830     {
831       dbus_message_unref (msg);
832       _DBUS_SET_OOM (error);
833       return;
834     }
835
836   send_no_return_values (connection, msg, error);
837
838   dbus_message_unref (msg);
839 }
840
841 /**
842  * Removes a previously-added match rule "by value" (the most
843  * recently-added identical rule gets removed).  The "rule" argument
844  * is the string form of a match rule.
845  *
846  * If you pass #NULL for the error, this function will not
847  * block; otherwise it will. See detailed explanation in
848  * docs for dbus_bus_add_match().
849  * 
850  * @param connection connection to the message bus
851  * @param rule textual form of match rule
852  * @param error location to store any errors
853  */
854 void
855 dbus_bus_remove_match (DBusConnection *connection,
856                        const char     *rule,
857                        DBusError      *error)
858 {
859   DBusMessage *msg;
860
861   msg = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
862                                       DBUS_PATH_ORG_FREEDESKTOP_DBUS,
863                                       DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
864                                       "RemoveMatch");
865
866   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, rule,
867                                  DBUS_TYPE_INVALID))
868     {
869       dbus_message_unref (msg);
870       _DBUS_SET_OOM (error);
871       return;
872     }
873
874   send_no_return_values (connection, msg, error);
875
876   dbus_message_unref (msg);
877 }
878
879 /** @} */