D-Bus  1.10.12
dbus-bus.c
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022  *
00023  */
00024 
00025 #include <config.h>
00026 #include "dbus-bus.h"
00027 #include "dbus-protocol.h"
00028 #include "dbus-internals.h"
00029 #include "dbus-message.h"
00030 #include "dbus-marshal-validate.h"
00031 #include "dbus-misc.h"
00032 #include "dbus-threads-internal.h"
00033 #include "dbus-connection-internal.h"
00034 #include "dbus-string.h"
00035 
00077 typedef struct
00078 {
00079   DBusConnection *connection; 
00080   char *unique_name; 
00082   unsigned int is_well_known : 1; 
00083 } BusData;
00084 
00087 static dbus_int32_t bus_data_slot = -1;
00088 
00090 #define N_BUS_TYPES 3
00091 
00092 static DBusConnection *bus_connections[N_BUS_TYPES];
00093 static char *bus_connection_addresses[N_BUS_TYPES] = { NULL, NULL, NULL };
00094 
00095 static DBusBusType activation_bus_type = DBUS_BUS_STARTER;
00096 
00097 static dbus_bool_t initialized = FALSE;
00098 
00099 static void
00100 addresses_shutdown_func (void *data)
00101 {
00102   int i;
00103 
00104   i = 0;
00105   while (i < N_BUS_TYPES)
00106     {
00107       if (bus_connections[i] != NULL)
00108         _dbus_warn_check_failed ("dbus_shutdown() called but connections were still live. This probably means the application did not drop all its references to bus connections.\n");
00109       
00110       dbus_free (bus_connection_addresses[i]);
00111       bus_connection_addresses[i] = NULL;
00112       ++i;
00113     }
00114 
00115   activation_bus_type = DBUS_BUS_STARTER;
00116 
00117   initialized = FALSE;
00118 }
00119 
00120 static dbus_bool_t
00121 get_from_env (char           **connection_p,
00122               const char      *env_var)
00123 {
00124   const char *s;
00125   
00126   _dbus_assert (*connection_p == NULL);
00127   
00128   s = _dbus_getenv (env_var);
00129   if (s == NULL || *s == '\0')
00130     return TRUE; /* successfully didn't use the env var */
00131   else
00132     {
00133       *connection_p = _dbus_strdup (s);
00134       return *connection_p != NULL;
00135     }
00136 }
00137 
00138 static dbus_bool_t
00139 init_session_address (void)
00140 {
00141   dbus_bool_t retval;
00142  
00143   retval = FALSE;
00144 
00145   /* First, look in the environment.  This is the normal case on 
00146    * freedesktop.org/Unix systems. */
00147   get_from_env (&bus_connection_addresses[DBUS_BUS_SESSION],
00148                      "DBUS_SESSION_BUS_ADDRESS");
00149   if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
00150     {
00151       dbus_bool_t supported;
00152       DBusString addr;
00153       DBusError error = DBUS_ERROR_INIT;
00154 
00155       if (!_dbus_string_init (&addr))
00156         return FALSE;
00157 
00158       supported = FALSE;
00159       /* So it's not in the environment - let's try a platform-specific method.
00160        * On MacOS, this involves asking launchd.  On Windows (not specified yet)
00161        * we might do a COM lookup.
00162        * Ignore errors - if we failed, fall back to autolaunch. */
00163       retval = _dbus_lookup_session_address (&supported, &addr, &error);
00164       if (supported && retval)
00165         {
00166           retval =_dbus_string_steal_data (&addr, &bus_connection_addresses[DBUS_BUS_SESSION]);
00167         }
00168       else if (supported && !retval)
00169         {
00170           if (dbus_error_is_set(&error))
00171             _dbus_warn ("Dynamic session lookup supported but failed: %s\n", error.message);
00172           else
00173             _dbus_warn ("Dynamic session lookup supported but failed silently\n");
00174         }
00175       _dbus_string_free (&addr);
00176     }
00177   else
00178     retval = TRUE;
00179 
00180   if (!retval)
00181     return FALSE;
00182 
00183   /* We have a hard-coded (but compile-time-configurable) fallback address for
00184    * the session bus. */
00185   if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
00186     bus_connection_addresses[DBUS_BUS_SESSION] =
00187       _dbus_strdup (DBUS_SESSION_BUS_CONNECT_ADDRESS);
00188 
00189   if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
00190     return FALSE;
00191 
00192   return TRUE;
00193 }
00194 
00195 static dbus_bool_t
00196 init_connections_unlocked (void)
00197 {
00198   if (!initialized)
00199     {
00200       const char *s;
00201       int i;
00202 
00203       i = 0;
00204       while (i < N_BUS_TYPES)
00205         {
00206           bus_connections[i] = NULL;
00207           ++i;
00208         }
00209 
00210       /* Don't init these twice, we may run this code twice if
00211        * init_connections_unlocked() fails midway through.
00212        * In practice, each block below should contain only one
00213        * "return FALSE" or running through twice may not
00214        * work right.
00215        */
00216       
00217        if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
00218          {
00219            _dbus_verbose ("Filling in system bus address...\n");
00220            
00221            if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SYSTEM],
00222                               "DBUS_SYSTEM_BUS_ADDRESS"))
00223              return FALSE;
00224          }
00225 
00226                   
00227        if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
00228          {
00229            /* Use default system bus address if none set in environment */
00230            bus_connection_addresses[DBUS_BUS_SYSTEM] =
00231              _dbus_strdup (DBUS_SYSTEM_BUS_DEFAULT_ADDRESS);
00232 
00233            if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
00234              return FALSE;
00235            
00236            _dbus_verbose ("  used default system bus \"%s\"\n",
00237                           bus_connection_addresses[DBUS_BUS_SYSTEM]);
00238          }
00239        else
00240          _dbus_verbose ("  used env var system bus \"%s\"\n",
00241                         bus_connection_addresses[DBUS_BUS_SYSTEM]);
00242           
00243       if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
00244         {
00245           _dbus_verbose ("Filling in session bus address...\n");
00246           
00247           if (!init_session_address ())
00248             return FALSE;
00249 
00250           _dbus_verbose ("  \"%s\"\n", bus_connection_addresses[DBUS_BUS_SESSION] ?
00251                          bus_connection_addresses[DBUS_BUS_SESSION] : "none set");
00252         }
00253 
00254       if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
00255         {
00256           _dbus_verbose ("Filling in activation bus address...\n");
00257           
00258           if (!get_from_env (&bus_connection_addresses[DBUS_BUS_STARTER],
00259                              "DBUS_STARTER_ADDRESS"))
00260             return FALSE;
00261           
00262           _dbus_verbose ("  \"%s\"\n", bus_connection_addresses[DBUS_BUS_STARTER] ?
00263                          bus_connection_addresses[DBUS_BUS_STARTER] : "none set");
00264         }
00265 
00266 
00267       if (bus_connection_addresses[DBUS_BUS_STARTER] != NULL)
00268         {
00269           s = _dbus_getenv ("DBUS_STARTER_BUS_TYPE");
00270               
00271           if (s != NULL)
00272             {
00273               _dbus_verbose ("Bus activation type was set to \"%s\"\n", s);
00274                   
00275               if (strcmp (s, "system") == 0)
00276                 activation_bus_type = DBUS_BUS_SYSTEM;
00277               else if (strcmp (s, "session") == 0)
00278                 activation_bus_type = DBUS_BUS_SESSION;
00279             }
00280         }
00281       else
00282         {
00283           /* Default to the session bus instead if available */
00284           if (bus_connection_addresses[DBUS_BUS_SESSION] != NULL)
00285             {
00286               bus_connection_addresses[DBUS_BUS_STARTER] =
00287                 _dbus_strdup (bus_connection_addresses[DBUS_BUS_SESSION]);
00288               if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
00289                 return FALSE;
00290             }
00291         }
00292       
00293       /* If we return FALSE we have to be sure that restarting
00294        * the above code will work right
00295        */
00296       
00297       if (!_dbus_register_shutdown_func (addresses_shutdown_func,
00298                                          NULL))
00299         return FALSE;
00300       
00301       initialized = TRUE;
00302     }
00303 
00304   return initialized;
00305 }
00306 
00307 static void
00308 bus_data_free (void *data)
00309 {
00310   BusData *bd = data;
00311   
00312   if (bd->is_well_known)
00313     {
00314       int i;
00315 
00316       if (!_DBUS_LOCK (bus))
00317         _dbus_assert_not_reached ("global locks should have been initialized "
00318             "when we attached bus data");
00319 
00320       /* We may be stored in more than one slot */
00321       /* This should now be impossible - these slots are supposed to
00322        * be cleared on disconnect, so should not need to be cleared on
00323        * finalize
00324        */
00325       i = 0;
00326       while (i < N_BUS_TYPES)
00327         {
00328           if (bus_connections[i] == bd->connection)
00329             bus_connections[i] = NULL;
00330           
00331           ++i;
00332         }
00333       _DBUS_UNLOCK (bus);
00334     }
00335   
00336   dbus_free (bd->unique_name);
00337   dbus_free (bd);
00338 
00339   dbus_connection_free_data_slot (&bus_data_slot);
00340 }
00341 
00342 static BusData*
00343 ensure_bus_data (DBusConnection *connection)
00344 {
00345   BusData *bd;
00346 
00347   if (!dbus_connection_allocate_data_slot (&bus_data_slot))
00348     return NULL;
00349 
00350   bd = dbus_connection_get_data (connection, bus_data_slot);
00351   if (bd == NULL)
00352     {      
00353       bd = dbus_new0 (BusData, 1);
00354       if (bd == NULL)
00355         {
00356           dbus_connection_free_data_slot (&bus_data_slot);
00357           return NULL;
00358         }
00359 
00360       bd->connection = connection;
00361       
00362       if (!dbus_connection_set_data (connection, bus_data_slot, bd,
00363                                      bus_data_free))
00364         {
00365           dbus_free (bd);
00366           dbus_connection_free_data_slot (&bus_data_slot);
00367           return NULL;
00368         }
00369 
00370       /* Data slot refcount now held by the BusData */
00371     }
00372   else
00373     {
00374       dbus_connection_free_data_slot (&bus_data_slot);
00375     }
00376 
00377   return bd;
00378 }
00379 
00386 void
00387 _dbus_bus_notify_shared_connection_disconnected_unlocked (DBusConnection *connection)
00388 {
00389   int i;
00390 
00391   if (!_DBUS_LOCK (bus))
00392     {
00393       /* If it was in bus_connections, we would have initialized global locks
00394        * when we added it. So, it can't be. */
00395       return;
00396     }
00397 
00398   /* We are expecting to have the connection saved in only one of these
00399    * slots, but someone could in a pathological case set system and session
00400    * bus to the same bus or something. Or set one of them to the starter
00401    * bus without setting the starter bus type in the env variable.
00402    * So we don't break the loop as soon as we find a match.
00403    */
00404   for (i = 0; i < N_BUS_TYPES; ++i)
00405     {
00406       if (bus_connections[i] == connection)
00407         {
00408           bus_connections[i] = NULL;
00409         }
00410     }
00411 
00412   _DBUS_UNLOCK (bus);
00413 }
00414 
00415 static DBusConnection *
00416 internal_bus_get (DBusBusType  type,
00417                   dbus_bool_t  private,
00418                   DBusError   *error)
00419 {
00420   const char *address;
00421   DBusConnection *connection;
00422   BusData *bd;
00423   DBusBusType address_type;
00424 
00425   _dbus_return_val_if_fail (type >= 0 && type < N_BUS_TYPES, NULL);
00426   _dbus_return_val_if_error_is_set (error, NULL);
00427 
00428   connection = NULL;
00429 
00430   if (!_DBUS_LOCK (bus))
00431     {
00432       _DBUS_SET_OOM (error);
00433       /* do not "goto out", that would try to unlock */
00434       return NULL;
00435     }
00436 
00437   if (!init_connections_unlocked ())
00438     {
00439       _DBUS_SET_OOM (error);
00440       goto out;
00441     }
00442 
00443   /* We want to use the activation address even if the
00444    * activating bus is the session or system bus,
00445    * per the spec.
00446    */
00447   address_type = type;
00448   
00449   /* Use the real type of the activation bus for getting its
00450    * connection, but only if the real type's address is available. (If
00451    * the activating bus isn't a well-known bus then
00452    * activation_bus_type == DBUS_BUS_STARTER)
00453    */
00454   if (type == DBUS_BUS_STARTER &&
00455       bus_connection_addresses[activation_bus_type] != NULL)
00456     type = activation_bus_type;
00457   
00458   if (!private && bus_connections[type] != NULL)
00459     {
00460       connection = bus_connections[type];
00461       dbus_connection_ref (connection);
00462       goto out;
00463     }
00464 
00465   address = bus_connection_addresses[address_type];
00466   if (address == NULL)
00467     {
00468       dbus_set_error (error, DBUS_ERROR_FAILED,
00469                       "Unable to determine the address of the message bus (try 'man dbus-launch' and 'man dbus-daemon' for help)");
00470       goto out;
00471     }
00472 
00473   if (private)
00474     connection = dbus_connection_open_private (address, error);
00475   else
00476     connection = dbus_connection_open (address, error);
00477   
00478   if (!connection)
00479     {
00480       goto out;
00481     }
00482 
00483   if (!dbus_bus_register (connection, error))
00484     {
00485       _dbus_connection_close_possibly_shared (connection);
00486       dbus_connection_unref (connection);
00487       connection = NULL;
00488       goto out;
00489     }
00490 
00491   if (!private)
00492     {
00493       /* store a weak ref to the connection (dbus-connection.c is
00494        * supposed to have a strong ref that it drops on disconnect,
00495        * since this is a shared connection)
00496        */
00497       bus_connections[type] = connection;
00498     }
00499 
00500   /* By default we're bound to the lifecycle of
00501    * the message bus.
00502    */
00503   dbus_connection_set_exit_on_disconnect (connection,
00504                                           TRUE);
00505 
00506   if (!_DBUS_LOCK (bus_datas))
00507     _dbus_assert_not_reached ("global locks were initialized already");
00508 
00509   bd = ensure_bus_data (connection);
00510   _dbus_assert (bd != NULL); /* it should have been created on
00511                                 register, so OOM not possible */
00512   bd->is_well_known = TRUE;
00513   _DBUS_UNLOCK (bus_datas);
00514 
00515 out:
00516   /* Return a reference to the caller, or NULL with error set. */
00517   if (connection == NULL)
00518     _DBUS_ASSERT_ERROR_IS_SET (error);
00519 
00520   _DBUS_UNLOCK (bus);
00521   return connection;
00522 }
00523 
00524  /* end of implementation details docs */
00526 
00557 DBusConnection *
00558 dbus_bus_get (DBusBusType  type,
00559               DBusError   *error)
00560 {
00561   return internal_bus_get (type, FALSE, error);
00562 }
00563 
00589 DBusConnection *
00590 dbus_bus_get_private (DBusBusType  type,
00591                       DBusError   *error)
00592 {
00593   return internal_bus_get (type, TRUE, error);
00594 }
00595 
00645 dbus_bool_t
00646 dbus_bus_register (DBusConnection *connection,
00647                    DBusError      *error)
00648 {
00649   DBusMessage *message, *reply;
00650   char *name;
00651   BusData *bd;
00652   dbus_bool_t retval;
00653 
00654   _dbus_return_val_if_fail (connection != NULL, FALSE);
00655   _dbus_return_val_if_error_is_set (error, FALSE);
00656 
00657   retval = FALSE;
00658   message = NULL;
00659   reply = NULL;
00660 
00661   if (!_DBUS_LOCK (bus_datas))
00662     {
00663       _DBUS_SET_OOM (error);
00664       /* do not "goto out", that would try to unlock */
00665       return FALSE;
00666     }
00667 
00668   bd = ensure_bus_data (connection);
00669   if (bd == NULL)
00670     {
00671       _DBUS_SET_OOM (error);
00672       goto out;
00673     }
00674 
00675   if (bd->unique_name != NULL)
00676     {
00677       _dbus_verbose ("Ignoring attempt to register the same DBusConnection %s with the message bus a second time.\n",
00678                      bd->unique_name);
00679       /* Success! */
00680       retval = TRUE;
00681       goto out;
00682     }
00683   
00684   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00685                                           DBUS_PATH_DBUS,
00686                                           DBUS_INTERFACE_DBUS,
00687                                           "Hello"); 
00688 
00689   if (!message)
00690     {
00691       _DBUS_SET_OOM (error);
00692       goto out;
00693     }
00694   
00695   reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
00696 
00697   if (reply == NULL)
00698     goto out;
00699   else if (dbus_set_error_from_message (error, reply))
00700     goto out;
00701   else if (!dbus_message_get_args (reply, error,
00702                                    DBUS_TYPE_STRING, &name,
00703                                    DBUS_TYPE_INVALID))
00704     goto out;
00705   
00706   bd->unique_name = _dbus_strdup (name);
00707   if (bd->unique_name == NULL)
00708     {
00709       _DBUS_SET_OOM (error);
00710       goto out;
00711     }
00712   
00713   retval = TRUE;
00714   
00715  out:
00716   _DBUS_UNLOCK (bus_datas);
00717 
00718   if (message)
00719     dbus_message_unref (message);
00720 
00721   if (reply)
00722     dbus_message_unref (reply);
00723 
00724   if (!retval)
00725     _DBUS_ASSERT_ERROR_IS_SET (error);
00726 
00727   return retval;
00728 }
00729 
00730 
00765 dbus_bool_t
00766 dbus_bus_set_unique_name (DBusConnection *connection,
00767                           const char     *unique_name)
00768 {
00769   BusData *bd;
00770   dbus_bool_t success = FALSE;
00771 
00772   _dbus_return_val_if_fail (connection != NULL, FALSE);
00773   _dbus_return_val_if_fail (unique_name != NULL, FALSE);
00774 
00775   if (!_DBUS_LOCK (bus_datas))
00776     {
00777       /* do not "goto out", that would try to unlock */
00778       return FALSE;
00779     }
00780 
00781   bd = ensure_bus_data (connection);
00782   if (bd == NULL)
00783     goto out;
00784 
00785   _dbus_assert (bd->unique_name == NULL);
00786   
00787   bd->unique_name = _dbus_strdup (unique_name);
00788   success = bd->unique_name != NULL;
00789 
00790 out:
00791   _DBUS_UNLOCK (bus_datas);
00792   
00793   return success;
00794 }
00795 
00814 const char*
00815 dbus_bus_get_unique_name (DBusConnection *connection)
00816 {
00817   BusData *bd;
00818   const char *unique_name = NULL;
00819 
00820   _dbus_return_val_if_fail (connection != NULL, NULL);
00821 
00822   if (!_DBUS_LOCK (bus_datas))
00823     {
00824       /* We'd have initialized locks when we gave it its unique name, if it
00825        * had one. Don't "goto out", that would try to unlock. */
00826       return NULL;
00827     }
00828 
00829   bd = ensure_bus_data (connection);
00830   if (bd == NULL)
00831     goto out;
00832 
00833   unique_name = bd->unique_name;
00834 
00835 out:
00836   _DBUS_UNLOCK (bus_datas);
00837 
00838   return unique_name;
00839 }
00840 
00864 unsigned long
00865 dbus_bus_get_unix_user (DBusConnection *connection,
00866                         const char     *name,
00867                         DBusError      *error)
00868 {
00869   DBusMessage *message, *reply;
00870   dbus_uint32_t uid;
00871 
00872   _dbus_return_val_if_fail (connection != NULL, DBUS_UID_UNSET);
00873   _dbus_return_val_if_fail (name != NULL, DBUS_UID_UNSET);
00874   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), DBUS_UID_UNSET);
00875   _dbus_return_val_if_error_is_set (error, DBUS_UID_UNSET);
00876   
00877   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00878                                           DBUS_PATH_DBUS,
00879                                           DBUS_INTERFACE_DBUS,
00880                                           "GetConnectionUnixUser");
00881 
00882   if (message == NULL)
00883     {
00884       _DBUS_SET_OOM (error);
00885       return DBUS_UID_UNSET;
00886     }
00887  
00888   if (!dbus_message_append_args (message,
00889                                  DBUS_TYPE_STRING, &name,
00890                                  DBUS_TYPE_INVALID))
00891     {
00892       dbus_message_unref (message);
00893       _DBUS_SET_OOM (error);
00894       return DBUS_UID_UNSET;
00895     }
00896   
00897   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
00898                                                      error);
00899   
00900   dbus_message_unref (message);
00901   
00902   if (reply == NULL)
00903     {
00904       _DBUS_ASSERT_ERROR_IS_SET (error);
00905       return DBUS_UID_UNSET;
00906     }  
00907 
00908   if (dbus_set_error_from_message (error, reply))
00909     {
00910       _DBUS_ASSERT_ERROR_IS_SET (error);
00911       dbus_message_unref (reply);
00912       return DBUS_UID_UNSET;
00913     }
00914   
00915   if (!dbus_message_get_args (reply, error,
00916                               DBUS_TYPE_UINT32, &uid,
00917                               DBUS_TYPE_INVALID))
00918     {
00919       _DBUS_ASSERT_ERROR_IS_SET (error);
00920       dbus_message_unref (reply);
00921       return DBUS_UID_UNSET;
00922     }
00923 
00924   dbus_message_unref (reply);
00925   
00926   return (unsigned long) uid;
00927 }
00928 
00947 char*
00948 dbus_bus_get_id (DBusConnection *connection,
00949                  DBusError      *error)
00950 {
00951   DBusMessage *message, *reply;
00952   char *id;
00953   const char *v_STRING;
00954 
00955   _dbus_return_val_if_fail (connection != NULL, NULL);
00956   _dbus_return_val_if_error_is_set (error, NULL);
00957   
00958   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00959                                           DBUS_PATH_DBUS,
00960                                           DBUS_INTERFACE_DBUS,
00961                                           "GetId");
00962   
00963   if (message == NULL)
00964     {
00965       _DBUS_SET_OOM (error);
00966       return NULL;
00967     }
00968   
00969   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
00970                                                      error);
00971   
00972   dbus_message_unref (message);
00973   
00974   if (reply == NULL)
00975     {
00976       _DBUS_ASSERT_ERROR_IS_SET (error);
00977       return NULL;
00978     }  
00979 
00980   if (dbus_set_error_from_message (error, reply))
00981     {
00982       _DBUS_ASSERT_ERROR_IS_SET (error);
00983       dbus_message_unref (reply);
00984       return NULL;
00985     }
00986 
00987   v_STRING = NULL;
00988   if (!dbus_message_get_args (reply, error,
00989                               DBUS_TYPE_STRING, &v_STRING,
00990                               DBUS_TYPE_INVALID))
00991     {
00992       _DBUS_ASSERT_ERROR_IS_SET (error);
00993       dbus_message_unref (reply);
00994       return NULL;
00995     }
00996 
00997   id = _dbus_strdup (v_STRING); /* may be NULL */
00998   
00999   dbus_message_unref (reply);
01000 
01001   if (id == NULL)
01002     _DBUS_SET_OOM (error);
01003 
01004   /* FIXME it might be nice to cache the ID locally */
01005   
01006   return id;
01007 }
01008 
01111 int
01112 dbus_bus_request_name (DBusConnection *connection,
01113                        const char     *name,
01114                        unsigned int    flags,
01115                        DBusError      *error)
01116 {
01117   DBusMessage *message, *reply;
01118   dbus_uint32_t result;
01119 
01120   _dbus_return_val_if_fail (connection != NULL, 0);
01121   _dbus_return_val_if_fail (name != NULL, 0);
01122   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
01123   _dbus_return_val_if_error_is_set (error, 0);
01124   
01125   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01126                                           DBUS_PATH_DBUS,
01127                                           DBUS_INTERFACE_DBUS,
01128                                           "RequestName");
01129 
01130   if (message == NULL)
01131     {
01132       _DBUS_SET_OOM (error);
01133       return -1;
01134     }
01135  
01136   if (!dbus_message_append_args (message,
01137                                  DBUS_TYPE_STRING, &name,
01138                                  DBUS_TYPE_UINT32, &flags,
01139                                  DBUS_TYPE_INVALID))
01140     {
01141       dbus_message_unref (message);
01142       _DBUS_SET_OOM (error);
01143       return -1;
01144     }
01145   
01146   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
01147                                                      error);
01148   
01149   dbus_message_unref (message);
01150   
01151   if (reply == NULL)
01152     {
01153       _DBUS_ASSERT_ERROR_IS_SET (error);
01154       return -1;
01155     }  
01156 
01157   if (dbus_set_error_from_message (error, reply))
01158     {
01159       _DBUS_ASSERT_ERROR_IS_SET (error);
01160       dbus_message_unref (reply);
01161       return -1;
01162     }
01163   
01164   if (!dbus_message_get_args (reply, error,
01165                               DBUS_TYPE_UINT32, &result,
01166                               DBUS_TYPE_INVALID))
01167     {
01168       _DBUS_ASSERT_ERROR_IS_SET (error);
01169       dbus_message_unref (reply);
01170       return -1;
01171     }
01172 
01173   dbus_message_unref (reply);
01174   
01175   return result;
01176 }
01177 
01178 
01197 int
01198 dbus_bus_release_name (DBusConnection *connection,
01199                        const char     *name,
01200                        DBusError      *error)
01201 {
01202   DBusMessage *message, *reply;
01203   dbus_uint32_t result;
01204 
01205   _dbus_return_val_if_fail (connection != NULL, 0);
01206   _dbus_return_val_if_fail (name != NULL, 0);
01207   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
01208   _dbus_return_val_if_error_is_set (error, 0);
01209 
01210   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01211                                           DBUS_PATH_DBUS,
01212                                           DBUS_INTERFACE_DBUS,
01213                                           "ReleaseName");
01214 
01215   if (message == NULL)
01216     {
01217       _DBUS_SET_OOM (error);
01218       return -1;
01219     }
01220 
01221   if (!dbus_message_append_args (message,
01222                                  DBUS_TYPE_STRING, &name,
01223                                  DBUS_TYPE_INVALID))
01224     {
01225       dbus_message_unref (message);
01226       _DBUS_SET_OOM (error);
01227       return -1;
01228     }
01229 
01230   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
01231                                                      error);
01232 
01233   dbus_message_unref (message);
01234 
01235   if (reply == NULL)
01236     {
01237       _DBUS_ASSERT_ERROR_IS_SET (error);
01238       return -1;
01239     }
01240 
01241   if (dbus_set_error_from_message (error, reply))
01242     {
01243       _DBUS_ASSERT_ERROR_IS_SET (error);
01244       dbus_message_unref (reply);
01245       return -1;
01246     }
01247 
01248   if (!dbus_message_get_args (reply, error,
01249                               DBUS_TYPE_UINT32, &result,
01250                               DBUS_TYPE_INVALID))
01251     {
01252       _DBUS_ASSERT_ERROR_IS_SET (error);
01253       dbus_message_unref (reply);
01254       return -1;
01255     }
01256 
01257   dbus_message_unref (reply);
01258 
01259   return result;
01260 }
01261 
01279 dbus_bool_t
01280 dbus_bus_name_has_owner (DBusConnection *connection,
01281                          const char     *name,
01282                          DBusError      *error)
01283 {
01284   DBusMessage *message, *reply;
01285   dbus_bool_t exists;
01286 
01287   _dbus_return_val_if_fail (connection != NULL, FALSE);
01288   _dbus_return_val_if_fail (name != NULL, FALSE);
01289   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
01290   _dbus_return_val_if_error_is_set (error, FALSE);
01291   
01292   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01293                                           DBUS_PATH_DBUS,
01294                                           DBUS_INTERFACE_DBUS,
01295                                           "NameHasOwner");
01296   if (message == NULL)
01297     {
01298       _DBUS_SET_OOM (error);
01299       return FALSE;
01300     }
01301   
01302   if (!dbus_message_append_args (message,
01303                                  DBUS_TYPE_STRING, &name,
01304                                  DBUS_TYPE_INVALID))
01305     {
01306       dbus_message_unref (message);
01307       _DBUS_SET_OOM (error);
01308       return FALSE;
01309     }
01310   
01311   reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
01312   dbus_message_unref (message);
01313 
01314   if (reply == NULL)
01315     {
01316       _DBUS_ASSERT_ERROR_IS_SET (error);
01317       return FALSE;
01318     }
01319 
01320   if (!dbus_message_get_args (reply, error,
01321                               DBUS_TYPE_BOOLEAN, &exists,
01322                               DBUS_TYPE_INVALID))
01323     {
01324       _DBUS_ASSERT_ERROR_IS_SET (error);
01325       dbus_message_unref (reply);
01326       return FALSE;
01327     }
01328   
01329   dbus_message_unref (reply);
01330   return exists;
01331 }
01332 
01355 dbus_bool_t
01356 dbus_bus_start_service_by_name (DBusConnection *connection,
01357                                 const char     *name,
01358                                 dbus_uint32_t   flags,
01359                                 dbus_uint32_t  *result,
01360                                 DBusError      *error)
01361 {
01362   DBusMessage *msg;
01363   DBusMessage *reply;
01364 
01365   _dbus_return_val_if_fail (connection != NULL, FALSE);
01366   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
01367   
01368   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01369                                       DBUS_PATH_DBUS,
01370                                       DBUS_INTERFACE_DBUS,
01371                                       "StartServiceByName");
01372 
01373   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name,
01374                                  DBUS_TYPE_UINT32, &flags, DBUS_TYPE_INVALID))
01375     {
01376       dbus_message_unref (msg);
01377       _DBUS_SET_OOM (error);
01378       return FALSE;
01379     }
01380 
01381   reply = dbus_connection_send_with_reply_and_block (connection, msg,
01382                                                      -1, error);
01383   dbus_message_unref (msg);
01384 
01385   if (reply == NULL)
01386     {
01387       _DBUS_ASSERT_ERROR_IS_SET (error);
01388       return FALSE;
01389     }
01390 
01391   if (dbus_set_error_from_message (error, reply))
01392     {
01393       _DBUS_ASSERT_ERROR_IS_SET (error);
01394       dbus_message_unref (reply);
01395       return FALSE;
01396     }
01397 
01398   if (result != NULL &&
01399       !dbus_message_get_args (reply, error, DBUS_TYPE_UINT32,
01400                               result, DBUS_TYPE_INVALID))
01401     {
01402       _DBUS_ASSERT_ERROR_IS_SET (error);
01403       dbus_message_unref (reply);
01404       return FALSE;
01405     }
01406   
01407   dbus_message_unref (reply);
01408   return TRUE;
01409 }
01410 
01411 static void
01412 send_no_return_values (DBusConnection *connection,
01413                        DBusMessage    *msg,
01414                        DBusError      *error)
01415 {
01416   if (error)
01417     {
01418       /* Block to check success codepath */
01419       DBusMessage *reply;
01420       
01421       reply = dbus_connection_send_with_reply_and_block (connection, msg,
01422                                                          -1, error);
01423       
01424       if (reply == NULL)
01425         _DBUS_ASSERT_ERROR_IS_SET (error);
01426       else
01427         dbus_message_unref (reply);
01428     }
01429   else
01430     {
01431       /* Silently-fail nonblocking codepath */
01432       dbus_message_set_no_reply (msg, TRUE);
01433       dbus_connection_send (connection, msg, NULL);
01434     }
01435 }
01436 
01525 void
01526 dbus_bus_add_match (DBusConnection *connection,
01527                     const char     *rule,
01528                     DBusError      *error)
01529 {
01530   DBusMessage *msg;
01531 
01532   _dbus_return_if_fail (rule != NULL);
01533 
01534   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01535                                       DBUS_PATH_DBUS,
01536                                       DBUS_INTERFACE_DBUS,
01537                                       "AddMatch");
01538 
01539   if (msg == NULL)
01540     {
01541       _DBUS_SET_OOM (error);
01542       return;
01543     }
01544 
01545   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
01546                                  DBUS_TYPE_INVALID))
01547     {
01548       dbus_message_unref (msg);
01549       _DBUS_SET_OOM (error);
01550       return;
01551     }
01552 
01553   send_no_return_values (connection, msg, error);
01554 
01555   dbus_message_unref (msg);
01556 }
01557 
01575 void
01576 dbus_bus_remove_match (DBusConnection *connection,
01577                        const char     *rule,
01578                        DBusError      *error)
01579 {
01580   DBusMessage *msg;
01581 
01582   _dbus_return_if_fail (rule != NULL);
01583   
01584   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01585                                       DBUS_PATH_DBUS,
01586                                       DBUS_INTERFACE_DBUS,
01587                                       "RemoveMatch");
01588 
01589   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
01590                                  DBUS_TYPE_INVALID))
01591     {
01592       dbus_message_unref (msg);
01593       _DBUS_SET_OOM (error);
01594       return;
01595     }
01596 
01597   send_no_return_values (connection, msg, error);
01598 
01599   dbus_message_unref (msg);
01600 }
01601