dbus-bus.c

00001 /* -*- mode: C; c-file-style: "gnu" -*- */
00002 /* dbus-bus.c  Convenience functions for communicating with the bus.
00003  *
00004  * Copyright (C) 2003  CodeFactory AB
00005  * Copyright (C) 2003  Red Hat, Inc.
00006  *
00007  * Licensed under the Academic Free License version 2.1
00008  * 
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  * 
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022  *
00023  */
00024 
00025 #include "dbus-bus.h"
00026 #include "dbus-protocol.h"
00027 #include "dbus-internals.h"
00028 #include "dbus-message.h"
00029 #include "dbus-marshal-validate.h"
00030 #include "dbus-threads-internal.h"
00031 #include <string.h>
00032 
00059 typedef struct
00060 {
00061   DBusConnection *connection; 
00062   char *unique_name; 
00064   unsigned int is_well_known : 1; 
00065 } BusData;
00066 
00069 static dbus_int32_t bus_data_slot = -1;
00070 
00072 #define N_BUS_TYPES 3
00073 
00074 static DBusConnection *bus_connections[N_BUS_TYPES];
00075 static char *bus_connection_addresses[N_BUS_TYPES] = { NULL, NULL, NULL };
00076 
00077 static DBusBusType activation_bus_type = DBUS_BUS_STARTER;
00078 
00079 static dbus_bool_t initialized = FALSE;
00080 
00084 _DBUS_DEFINE_GLOBAL_LOCK (bus);
00085 
00086 static void
00087 addresses_shutdown_func (void *data)
00088 {
00089   int i;
00090 
00091   i = 0;
00092   while (i < N_BUS_TYPES)
00093     {
00094       if (bus_connections[i] != NULL)
00095         _dbus_warn ("dbus_shutdown() called but connections were still live!");
00096       
00097       dbus_free (bus_connection_addresses[i]);
00098       bus_connection_addresses[i] = NULL;
00099       ++i;
00100     }
00101 
00102   activation_bus_type = DBUS_BUS_STARTER;
00103 }
00104 
00105 static dbus_bool_t
00106 get_from_env (char           **connection_p,
00107               const char      *env_var)
00108 {
00109   const char *s;
00110   
00111   _dbus_assert (*connection_p == NULL);
00112   
00113   s = _dbus_getenv (env_var);
00114   if (s == NULL || *s == '\0')
00115     return TRUE; /* successfully didn't use the env var */
00116   else
00117     {
00118       *connection_p = _dbus_strdup (s);
00119       return *connection_p != NULL;
00120     }
00121 }
00122 
00123 static dbus_bool_t
00124 init_connections_unlocked (void)
00125 {
00126   if (!initialized)
00127     {
00128       const char *s;
00129       int i;
00130 
00131       i = 0;
00132       while (i < N_BUS_TYPES)
00133         {
00134           bus_connections[i] = NULL;
00135           ++i;
00136         }
00137 
00138       /* Don't init these twice, we may run this code twice if
00139        * init_connections_unlocked() fails midway through.
00140        * In practice, each block below should contain only one
00141        * "return FALSE" or running through twice may not
00142        * work right.
00143        */
00144       
00145        if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
00146          {
00147            _dbus_verbose ("Filling in system bus address...\n");
00148            
00149            if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SYSTEM],
00150                               "DBUS_SYSTEM_BUS_ADDRESS"))
00151              return FALSE;
00152          }
00153 
00154                   
00155        if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
00156          {
00157            /* Use default system bus address if none set in environment */
00158            bus_connection_addresses[DBUS_BUS_SYSTEM] =
00159              _dbus_strdup (DBUS_SYSTEM_BUS_DEFAULT_ADDRESS);
00160            if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
00161              return FALSE;
00162            
00163            _dbus_verbose ("  used default system bus \"%s\"\n",
00164                           bus_connection_addresses[DBUS_BUS_SYSTEM]);
00165          }
00166        else
00167          _dbus_verbose ("  used env var system bus \"%s\"\n",
00168                         bus_connection_addresses[DBUS_BUS_SYSTEM]);
00169           
00170       if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
00171         {
00172           _dbus_verbose ("Filling in session bus address...\n");
00173           
00174           if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SESSION],
00175                              "DBUS_SESSION_BUS_ADDRESS"))
00176             return FALSE;
00177           _dbus_verbose ("  \"%s\"\n", bus_connection_addresses[DBUS_BUS_SESSION] ?
00178                          bus_connection_addresses[DBUS_BUS_SESSION] : "none set");
00179         }
00180 
00181       if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
00182         {
00183           _dbus_verbose ("Filling in activation bus address...\n");
00184           
00185           if (!get_from_env (&bus_connection_addresses[DBUS_BUS_STARTER],
00186                              "DBUS_STARTER_ADDRESS"))
00187             return FALSE;
00188           
00189           _dbus_verbose ("  \"%s\"\n", bus_connection_addresses[DBUS_BUS_STARTER] ?
00190                          bus_connection_addresses[DBUS_BUS_STARTER] : "none set");
00191         }
00192 
00193 
00194       if (bus_connection_addresses[DBUS_BUS_STARTER] != NULL)
00195         {
00196           s = _dbus_getenv ("DBUS_STARTER_BUS_TYPE");
00197               
00198           if (s != NULL)
00199             {
00200               _dbus_verbose ("Bus activation type was set to \"%s\"\n", s);
00201                   
00202               if (strcmp (s, "system") == 0)
00203                 activation_bus_type = DBUS_BUS_SYSTEM;
00204               else if (strcmp (s, "session") == 0)
00205                 activation_bus_type = DBUS_BUS_SESSION;
00206             }
00207         }
00208       else
00209         {
00210           /* Default to the session bus instead if available */
00211           if (bus_connection_addresses[DBUS_BUS_SESSION] != NULL)
00212             {
00213               bus_connection_addresses[DBUS_BUS_STARTER] =
00214                 _dbus_strdup (bus_connection_addresses[DBUS_BUS_SESSION]);
00215               if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
00216                 return FALSE;
00217             }
00218         }
00219       
00220       /* If we return FALSE we have to be sure that restarting
00221        * the above code will work right
00222        */
00223       
00224       if (!_dbus_setenv ("DBUS_ACTIVATION_ADDRESS", NULL))
00225         return FALSE;
00226 
00227       if (!_dbus_setenv ("DBUS_ACTIVATION_BUS_TYPE", NULL))
00228         return FALSE;
00229       
00230       if (!_dbus_register_shutdown_func (addresses_shutdown_func,
00231                                          NULL))
00232         return FALSE;
00233       
00234       initialized = TRUE;
00235     }
00236 
00237   return initialized;
00238 }
00239 
00240 static void
00241 bus_data_free (void *data)
00242 {
00243   BusData *bd = data;
00244   
00245   if (bd->is_well_known)
00246     {
00247       int i;
00248       _DBUS_LOCK (bus);
00249       /* We may be stored in more than one slot */
00250       i = 0;
00251       while (i < N_BUS_TYPES)
00252         {
00253           if (bus_connections[i] == bd->connection)
00254             bus_connections[i] = NULL;
00255           
00256           ++i;
00257         }
00258       _DBUS_UNLOCK (bus);
00259     }
00260   
00261   dbus_free (bd->unique_name);
00262   dbus_free (bd);
00263 
00264   dbus_connection_free_data_slot (&bus_data_slot);
00265 }
00266 
00267 static BusData*
00268 ensure_bus_data (DBusConnection *connection)
00269 {
00270   BusData *bd;
00271 
00272   if (!dbus_connection_allocate_data_slot (&bus_data_slot))
00273     return NULL;
00274 
00275   bd = dbus_connection_get_data (connection, bus_data_slot);
00276   if (bd == NULL)
00277     {      
00278       bd = dbus_new0 (BusData, 1);
00279       if (bd == NULL)
00280         {
00281           dbus_connection_free_data_slot (&bus_data_slot);
00282           return NULL;
00283         }
00284 
00285       bd->connection = connection;
00286       
00287       if (!dbus_connection_set_data (connection, bus_data_slot, bd,
00288                                      bus_data_free))
00289         {
00290           dbus_free (bd);
00291           dbus_connection_free_data_slot (&bus_data_slot);
00292           return NULL;
00293         }
00294 
00295       /* Data slot refcount now held by the BusData */
00296     }
00297   else
00298     {
00299       dbus_connection_free_data_slot (&bus_data_slot);
00300     }
00301 
00302   return bd;
00303 }
00304 
00305 static DBusConnection *
00306 internal_bus_get (DBusBusType  type,
00307               DBusError   *error, dbus_bool_t private)
00308 {
00309   const char *address;
00310   DBusConnection *connection;
00311   BusData *bd;
00312   DBusBusType address_type;
00313 
00314   _dbus_return_val_if_fail (type >= 0 && type < N_BUS_TYPES, NULL);
00315   _dbus_return_val_if_error_is_set (error, NULL);
00316 
00317   _DBUS_LOCK (bus);
00318 
00319   if (!init_connections_unlocked ())
00320     {
00321       _DBUS_UNLOCK (bus);
00322       _DBUS_SET_OOM (error);
00323       return NULL;
00324     }
00325 
00326   /* We want to use the activation address even if the
00327    * activating bus is the session or system bus,
00328    * per the spec.
00329    */
00330   address_type = type;
00331   
00332   /* Use the real type of the activation bus for getting its
00333    * connection, but only if the real type's address is available. (If
00334    * the activating bus isn't a well-known bus then
00335    * activation_bus_type == DBUS_BUS_STARTER)
00336    */
00337   if (type == DBUS_BUS_STARTER &&
00338       bus_connection_addresses[activation_bus_type] != NULL)
00339     type = activation_bus_type;
00340   
00341   if (!private && bus_connections[type] != NULL)
00342     {
00343       connection = bus_connections[type];
00344       dbus_connection_ref (connection);
00345       
00346       _DBUS_UNLOCK (bus);
00347       return connection;
00348     }
00349 
00350   address = bus_connection_addresses[address_type];
00351   if (address == NULL)
00352     {
00353       dbus_set_error (error, DBUS_ERROR_FAILED,
00354                       "Unable to determine the address of the message bus");
00355       _DBUS_UNLOCK (bus);
00356       return NULL;
00357     }
00358 
00359   if (private)
00360     connection = dbus_connection_open_private(address, error);
00361   else
00362     connection = dbus_connection_open (address, error);
00363   
00364   if (!connection)
00365     {
00366       _DBUS_ASSERT_ERROR_IS_SET (error);
00367       _DBUS_UNLOCK (bus);
00368       return NULL;
00369     }
00370 
00371   /* By default we're bound to the lifecycle of
00372    * the message bus.
00373    */
00374   dbus_connection_set_exit_on_disconnect (connection,
00375                                           TRUE);
00376   
00377   if (!dbus_bus_register (connection, error))
00378     {
00379       _DBUS_ASSERT_ERROR_IS_SET (error);
00380       dbus_connection_close (connection);
00381       dbus_connection_unref (connection);
00382 
00383       _DBUS_UNLOCK (bus);
00384       return NULL;
00385     }
00386 
00387   if (!private)
00388     bus_connections[type] = connection;
00389   
00390   bd = ensure_bus_data (connection);
00391   _dbus_assert (bd != NULL);
00392 
00393   bd->is_well_known = TRUE;
00394 
00395   _DBUS_UNLOCK (bus);
00396   return connection;
00397 }
00398 
00399  /* end of implementation details docs */
00401 
00418 DBusConnection *
00419 dbus_bus_get (DBusBusType  type,
00420               DBusError   *error) {
00421   return internal_bus_get(type, error, FALSE);
00422 }
00423 
00434 DBusConnection *
00435 dbus_bus_get_private (DBusBusType  type,
00436               DBusError   *error) {
00437   return internal_bus_get(type, error, TRUE);
00438 }
00439 
00450 dbus_bool_t
00451 dbus_bus_register (DBusConnection *connection,
00452                    DBusError      *error)
00453 {
00454   DBusMessage *message, *reply;
00455   char *name;
00456   BusData *bd;
00457   dbus_bool_t retval;
00458 
00459   _dbus_return_val_if_fail (connection != NULL, FALSE);
00460   _dbus_return_val_if_error_is_set (error, FALSE);
00461 
00462   retval = FALSE;
00463   
00464   bd = ensure_bus_data (connection);
00465   if (bd == NULL)
00466     {
00467       _DBUS_SET_OOM (error);
00468       return FALSE;
00469     }
00470 
00471   if (bd->unique_name != NULL)
00472     {
00473       _dbus_warn ("Attempt to register the same DBusConnection with the message bus, but it is already registered\n");
00474       /* This isn't an error, it's a programming bug. We'll be nice
00475        * and not _dbus_assert_not_reached()
00476        */
00477       return TRUE;
00478     }
00479   
00480   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00481                                           DBUS_PATH_DBUS,
00482                                           DBUS_INTERFACE_DBUS,
00483                                           "Hello"); 
00484 
00485   if (!message)
00486     {
00487       _DBUS_SET_OOM (error);
00488       return FALSE;
00489     }
00490   
00491   reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
00492 
00493   dbus_message_unref (message);
00494   
00495   if (reply == NULL)
00496     goto out;
00497   else if (dbus_set_error_from_message (error, reply))
00498     goto out;
00499   else if (!dbus_message_get_args (reply, error,
00500                                    DBUS_TYPE_STRING, &name,
00501                                    DBUS_TYPE_INVALID))
00502     goto out;
00503   
00504   bd->unique_name = _dbus_strdup (name);
00505   if (bd->unique_name == NULL)
00506     {
00507       _DBUS_SET_OOM (error);
00508       goto out;
00509     }
00510   
00511   retval = TRUE;
00512   
00513  out:
00514   if (reply)
00515     dbus_message_unref (reply);
00516 
00517   if (!retval)
00518     _DBUS_ASSERT_ERROR_IS_SET (error);
00519   
00520   return retval;
00521 }
00522 
00523 
00533 dbus_bool_t
00534 dbus_bus_set_unique_name (DBusConnection *connection,
00535                           const char     *unique_name)
00536 {
00537   BusData *bd;
00538 
00539   _dbus_return_val_if_fail (connection != NULL, FALSE);
00540   _dbus_return_val_if_fail (unique_name != NULL, FALSE);
00541   
00542   bd = ensure_bus_data (connection);
00543   if (bd == NULL)
00544     return FALSE;
00545 
00546   _dbus_assert (bd->unique_name == NULL);
00547   
00548   bd->unique_name = _dbus_strdup (unique_name);
00549   return bd->unique_name != NULL;
00550 }
00551 
00562 const char*
00563 dbus_bus_get_unique_name (DBusConnection *connection)
00564 {
00565   BusData *bd;
00566 
00567   _dbus_return_val_if_fail (connection != NULL, NULL);
00568   
00569   bd = ensure_bus_data (connection);
00570   if (bd == NULL)
00571     return NULL;
00572   
00573   return bd->unique_name;
00574 }
00575 
00585 unsigned long
00586 dbus_bus_get_unix_user (DBusConnection *connection,
00587                         const char     *name,
00588                         DBusError      *error)
00589 {
00590   DBusMessage *message, *reply;
00591   dbus_uint32_t uid;
00592 
00593   _dbus_return_val_if_fail (connection != NULL, DBUS_UID_UNSET);
00594   _dbus_return_val_if_fail (name != NULL, DBUS_UID_UNSET);
00595   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), DBUS_UID_UNSET);
00596   _dbus_return_val_if_error_is_set (error, DBUS_UID_UNSET);
00597   
00598   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00599                                           DBUS_PATH_DBUS,
00600                                           DBUS_INTERFACE_DBUS,
00601                                           "GetConnectionUnixUser");
00602 
00603   if (message == NULL)
00604     {
00605       _DBUS_SET_OOM (error);
00606       return DBUS_UID_UNSET;
00607     }
00608  
00609   if (!dbus_message_append_args (message,
00610                                  DBUS_TYPE_STRING, &name,
00611                                  DBUS_TYPE_INVALID))
00612     {
00613       dbus_message_unref (message);
00614       _DBUS_SET_OOM (error);
00615       return DBUS_UID_UNSET;
00616     }
00617   
00618   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
00619                                                      error);
00620   
00621   dbus_message_unref (message);
00622   
00623   if (reply == NULL)
00624     {
00625       _DBUS_ASSERT_ERROR_IS_SET (error);
00626       return DBUS_UID_UNSET;
00627     }  
00628 
00629   if (dbus_set_error_from_message (error, reply))
00630     {
00631       _DBUS_ASSERT_ERROR_IS_SET (error);
00632       dbus_message_unref (reply);
00633       return DBUS_UID_UNSET;
00634     }
00635   
00636   if (!dbus_message_get_args (reply, error,
00637                               DBUS_TYPE_UINT32, &uid,
00638                               DBUS_TYPE_INVALID))
00639     {
00640       _DBUS_ASSERT_ERROR_IS_SET (error);
00641       dbus_message_unref (reply);
00642       return DBUS_UID_UNSET;
00643     }
00644 
00645   dbus_message_unref (reply);
00646   
00647   return (unsigned long) uid;
00648 }
00649 
00650 
00714 int
00715 dbus_bus_request_name (DBusConnection *connection,
00716                        const char     *name,
00717                        unsigned int    flags,
00718                        DBusError      *error)
00719 {
00720   DBusMessage *message, *reply;
00721   dbus_uint32_t result;
00722 
00723   _dbus_return_val_if_fail (connection != NULL, 0);
00724   _dbus_return_val_if_fail (name != NULL, 0);
00725   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
00726   _dbus_return_val_if_error_is_set (error, 0);
00727   
00728   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00729                                           DBUS_PATH_DBUS,
00730                                           DBUS_INTERFACE_DBUS,
00731                                           "RequestName");
00732 
00733   if (message == NULL)
00734     {
00735       _DBUS_SET_OOM (error);
00736       return -1;
00737     }
00738  
00739   if (!dbus_message_append_args (message,
00740                                  DBUS_TYPE_STRING, &name,
00741                                  DBUS_TYPE_UINT32, &flags,
00742                                  DBUS_TYPE_INVALID))
00743     {
00744       dbus_message_unref (message);
00745       _DBUS_SET_OOM (error);
00746       return -1;
00747     }
00748   
00749   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
00750                                                      error);
00751   
00752   dbus_message_unref (message);
00753   
00754   if (reply == NULL)
00755     {
00756       _DBUS_ASSERT_ERROR_IS_SET (error);
00757       return -1;
00758     }  
00759 
00760   if (dbus_set_error_from_message (error, reply))
00761     {
00762       _DBUS_ASSERT_ERROR_IS_SET (error);
00763       dbus_message_unref (reply);
00764       return -1;
00765     }
00766   
00767   if (!dbus_message_get_args (reply, error,
00768                               DBUS_TYPE_UINT32, &result,
00769                               DBUS_TYPE_INVALID))
00770     {
00771       _DBUS_ASSERT_ERROR_IS_SET (error);
00772       dbus_message_unref (reply);
00773       return -1;
00774     }
00775 
00776   dbus_message_unref (reply);
00777   
00778   return result;
00779 }
00780 
00781 int
00782 dbus_bus_release_name (DBusConnection *connection,
00783                        const char     *name,
00784                        DBusError      *error)
00785 {
00786   DBusMessage *message, *reply;
00787   dbus_uint32_t result;
00788 
00789   _dbus_return_val_if_fail (connection != NULL, 0);
00790   _dbus_return_val_if_fail (name != NULL, 0);
00791   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
00792   _dbus_return_val_if_error_is_set (error, 0);
00793 
00794   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00795                                           DBUS_PATH_DBUS,
00796                                           DBUS_INTERFACE_DBUS,
00797                                           "ReleaseName");
00798 
00799   if (message == NULL)
00800     {
00801       _DBUS_SET_OOM (error);
00802       return -1;
00803     }
00804 
00805   if (!dbus_message_append_args (message,
00806                                  DBUS_TYPE_STRING, &name,
00807                                  DBUS_TYPE_INVALID))
00808     {
00809       dbus_message_unref (message);
00810       _DBUS_SET_OOM (error);
00811       return -1;
00812     }
00813 
00814   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
00815                                                      error);
00816 
00817   dbus_message_unref (message);
00818 
00819   if (reply == NULL)
00820     {
00821       _DBUS_ASSERT_ERROR_IS_SET (error);
00822       return -1;
00823     }
00824 
00825   if (dbus_set_error_from_message (error, reply))
00826     {
00827       _DBUS_ASSERT_ERROR_IS_SET (error);
00828       dbus_message_unref (reply);
00829       return -1;
00830     }
00831 
00832   if (!dbus_message_get_args (reply, error,
00833                               DBUS_TYPE_UINT32, &result,
00834                               DBUS_TYPE_INVALID))
00835     {
00836       _DBUS_ASSERT_ERROR_IS_SET (error);
00837       dbus_message_unref (reply);
00838       return -1;
00839     }
00840 
00841   dbus_message_unref (reply);
00842 
00843   return result;
00844 }
00845 
00854 dbus_bool_t
00855 dbus_bus_name_has_owner (DBusConnection *connection,
00856                          const char     *name,
00857                          DBusError      *error)
00858 {
00859   DBusMessage *message, *reply;
00860   dbus_bool_t exists;
00861 
00862   _dbus_return_val_if_fail (connection != NULL, FALSE);
00863   _dbus_return_val_if_fail (name != NULL, FALSE);
00864   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
00865   _dbus_return_val_if_error_is_set (error, FALSE);
00866   
00867   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00868                                           DBUS_PATH_DBUS,
00869                                           DBUS_INTERFACE_DBUS,
00870                                           "NameHasOwner");
00871   if (message == NULL)
00872     {
00873       _DBUS_SET_OOM (error);
00874       return FALSE;
00875     }
00876   
00877   if (!dbus_message_append_args (message,
00878                                  DBUS_TYPE_STRING, &name,
00879                                  DBUS_TYPE_INVALID))
00880     {
00881       dbus_message_unref (message);
00882       _DBUS_SET_OOM (error);
00883       return FALSE;
00884     }
00885   
00886   reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
00887   dbus_message_unref (message);
00888 
00889   if (reply == NULL)
00890     {
00891       _DBUS_ASSERT_ERROR_IS_SET (error);
00892       return FALSE;
00893     }
00894 
00895   if (!dbus_message_get_args (reply, error,
00896                               DBUS_TYPE_BOOLEAN, &exists,
00897                               DBUS_TYPE_INVALID))
00898     {
00899       _DBUS_ASSERT_ERROR_IS_SET (error);
00900       dbus_message_unref (reply);
00901       return FALSE;
00902     }
00903   
00904   dbus_message_unref (reply);
00905   return exists;
00906 }
00907 
00924 dbus_bool_t
00925 dbus_bus_start_service_by_name (DBusConnection *connection,
00926                                 const char     *name,
00927                                 dbus_uint32_t   flags,
00928                                 dbus_uint32_t  *result,
00929                                 DBusError      *error)
00930 {
00931   DBusMessage *msg;
00932   DBusMessage *reply;
00933 
00934   _dbus_return_val_if_fail (connection != NULL, FALSE);
00935   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
00936   
00937   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00938                                       DBUS_PATH_DBUS,
00939                                       DBUS_INTERFACE_DBUS,
00940                                       "StartServiceByName");
00941 
00942   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name,
00943                                  DBUS_TYPE_UINT32, &flags, DBUS_TYPE_INVALID))
00944     {
00945       dbus_message_unref (msg);
00946       _DBUS_SET_OOM (error);
00947       return FALSE;
00948     }
00949 
00950   reply = dbus_connection_send_with_reply_and_block (connection, msg,
00951                                                      -1, error);
00952   dbus_message_unref (msg);
00953 
00954   if (reply == NULL)
00955     {
00956       _DBUS_ASSERT_ERROR_IS_SET (error);
00957       return FALSE;
00958     }
00959 
00960   if (dbus_set_error_from_message (error, reply))
00961     {
00962       _DBUS_ASSERT_ERROR_IS_SET (error);
00963       dbus_message_unref (reply);
00964       return FALSE;
00965     }
00966 
00967   if (result != NULL &&
00968       !dbus_message_get_args (reply, error, DBUS_TYPE_UINT32,
00969                               result, DBUS_TYPE_INVALID))
00970     {
00971       _DBUS_ASSERT_ERROR_IS_SET (error);
00972       dbus_message_unref (reply);
00973       return FALSE;
00974     }
00975   
00976   dbus_message_unref (reply);
00977   return TRUE;
00978 }
00979 
00980 static void
00981 send_no_return_values (DBusConnection *connection,
00982                        DBusMessage    *msg,
00983                        DBusError      *error)
00984 {
00985   if (error)
00986     {
00987       /* Block to check success codepath */
00988       DBusMessage *reply;
00989       
00990       reply = dbus_connection_send_with_reply_and_block (connection, msg,
00991                                                          -1, error);
00992       
00993       if (reply == NULL)
00994         _DBUS_ASSERT_ERROR_IS_SET (error);
00995       else
00996         dbus_message_unref (reply);
00997     }
00998   else
00999     {
01000       /* Silently-fail nonblocking codepath */
01001       dbus_message_set_no_reply (msg, TRUE);
01002       dbus_connection_send (connection, msg, NULL);
01003     }
01004 }
01005 
01028 void
01029 dbus_bus_add_match (DBusConnection *connection,
01030                     const char     *rule,
01031                     DBusError      *error)
01032 {
01033   DBusMessage *msg;
01034 
01035   _dbus_return_if_fail (rule != NULL);
01036 
01037   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01038                                       DBUS_PATH_DBUS,
01039                                       DBUS_INTERFACE_DBUS,
01040                                       "AddMatch");
01041 
01042   if (msg == NULL)
01043     {
01044       _DBUS_SET_OOM (error);
01045       return;
01046     }
01047 
01048   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
01049                                  DBUS_TYPE_INVALID))
01050     {
01051       dbus_message_unref (msg);
01052       _DBUS_SET_OOM (error);
01053       return;
01054     }
01055 
01056   send_no_return_values (connection, msg, error);
01057 
01058   dbus_message_unref (msg);
01059 }
01060 
01074 void
01075 dbus_bus_remove_match (DBusConnection *connection,
01076                        const char     *rule,
01077                        DBusError      *error)
01078 {
01079   DBusMessage *msg;
01080 
01081   _dbus_return_if_fail (rule != NULL);
01082   
01083   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01084                                       DBUS_PATH_DBUS,
01085                                       DBUS_INTERFACE_DBUS,
01086                                       "RemoveMatch");
01087 
01088   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
01089                                  DBUS_TYPE_INVALID))
01090     {
01091       dbus_message_unref (msg);
01092       _DBUS_SET_OOM (error);
01093       return;
01094     }
01095 
01096   send_no_return_values (connection, msg, error);
01097 
01098   dbus_message_unref (msg);
01099 }
01100 
01101 #ifdef DBUS_BUILD_TESTS
01102 const char *
01103 dbus_bus_connection_get_unique_name (DBusConnection *connection)
01104 {
01105   BusData *bd;
01106   bd = dbus_connection_get_data (connection, bus_data_slot);
01107   
01108   return bd->unique_name;
01109 }
01110 #endif /* DBUS_BUILD_TESTS */
01111 
01112 

Generated on Tue Jul 7 15:13:58 2009 for D-BUS by  doxygen 1.4.6