D-Bus  1.4.18
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-threads-internal.h"
00032 #include "dbus-connection-internal.h"
00033 #include "dbus-string.h"
00034 
00076 typedef struct
00077 {
00078   DBusConnection *connection; 
00079   char *unique_name; 
00081   unsigned int is_well_known : 1; 
00082 } BusData;
00083 
00086 static dbus_int32_t bus_data_slot = -1;
00087 
00089 #define N_BUS_TYPES 3
00090 
00091 static DBusConnection *bus_connections[N_BUS_TYPES];
00092 static char *bus_connection_addresses[N_BUS_TYPES] = { NULL, NULL, NULL };
00093 
00094 static DBusBusType activation_bus_type = DBUS_BUS_STARTER;
00095 
00096 static dbus_bool_t initialized = FALSE;
00097 
00101 _DBUS_DEFINE_GLOBAL_LOCK (bus);
00102 
00109 _DBUS_DEFINE_GLOBAL_LOCK (bus_datas);
00110 
00111 static void
00112 addresses_shutdown_func (void *data)
00113 {
00114   int i;
00115 
00116   i = 0;
00117   while (i < N_BUS_TYPES)
00118     {
00119       if (bus_connections[i] != NULL)
00120         _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");
00121       
00122       dbus_free (bus_connection_addresses[i]);
00123       bus_connection_addresses[i] = NULL;
00124       ++i;
00125     }
00126 
00127   activation_bus_type = DBUS_BUS_STARTER;
00128 
00129   initialized = FALSE;
00130 }
00131 
00132 static dbus_bool_t
00133 get_from_env (char           **connection_p,
00134               const char      *env_var)
00135 {
00136   const char *s;
00137   
00138   _dbus_assert (*connection_p == NULL);
00139   
00140   s = _dbus_getenv (env_var);
00141   if (s == NULL || *s == '\0')
00142     return TRUE; /* successfully didn't use the env var */
00143   else
00144     {
00145       *connection_p = _dbus_strdup (s);
00146       return *connection_p != NULL;
00147     }
00148 }
00149 
00150 static dbus_bool_t
00151 init_session_address (void)
00152 {
00153   dbus_bool_t retval;
00154  
00155   retval = FALSE;
00156 
00157   /* First, look in the environment.  This is the normal case on 
00158    * freedesktop.org/Unix systems. */
00159   get_from_env (&bus_connection_addresses[DBUS_BUS_SESSION],
00160                      "DBUS_SESSION_BUS_ADDRESS");
00161   if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
00162     {
00163       dbus_bool_t supported;
00164       DBusString addr;
00165       DBusError error = DBUS_ERROR_INIT;
00166 
00167       if (!_dbus_string_init (&addr))
00168         return FALSE;
00169 
00170       supported = FALSE;
00171       /* So it's not in the environment - let's try a platform-specific method.
00172        * On MacOS, this involves asking launchd.  On Windows (not specified yet)
00173        * we might do a COM lookup.
00174        * Ignore errors - if we failed, fall back to autolaunch. */
00175       retval = _dbus_lookup_session_address (&supported, &addr, &error);
00176       if (supported && retval)
00177         {
00178           retval =_dbus_string_steal_data (&addr, &bus_connection_addresses[DBUS_BUS_SESSION]);
00179         }
00180       else if (supported && !retval)
00181         {
00182           if (dbus_error_is_set(&error))
00183             _dbus_warn ("Dynamic session lookup supported but failed: %s\n", error.message);
00184           else
00185             _dbus_warn ("Dynamic session lookup supported but failed silently\n");
00186         }
00187       _dbus_string_free (&addr);
00188     }
00189   else
00190     retval = TRUE;
00191 
00192   if (!retval)
00193     return FALSE;
00194 
00195   /* The DBUS_SESSION_BUS_DEFAULT_ADDRESS should have really been named
00196    * DBUS_SESSION_BUS_FALLBACK_ADDRESS. 
00197    */
00198   if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
00199     bus_connection_addresses[DBUS_BUS_SESSION] =
00200       _dbus_strdup (DBUS_SESSION_BUS_DEFAULT_ADDRESS);
00201   if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
00202     return FALSE;
00203 
00204   return TRUE;
00205 }
00206 
00207 static dbus_bool_t
00208 init_connections_unlocked (void)
00209 {
00210   if (!initialized)
00211     {
00212       const char *s;
00213       int i;
00214 
00215       i = 0;
00216       while (i < N_BUS_TYPES)
00217         {
00218           bus_connections[i] = NULL;
00219           ++i;
00220         }
00221 
00222       /* Don't init these twice, we may run this code twice if
00223        * init_connections_unlocked() fails midway through.
00224        * In practice, each block below should contain only one
00225        * "return FALSE" or running through twice may not
00226        * work right.
00227        */
00228       
00229        if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
00230          {
00231            _dbus_verbose ("Filling in system bus address...\n");
00232            
00233            if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SYSTEM],
00234                               "DBUS_SYSTEM_BUS_ADDRESS"))
00235              return FALSE;
00236          }
00237 
00238                   
00239        if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
00240          {
00241            /* Use default system bus address if none set in environment */
00242            bus_connection_addresses[DBUS_BUS_SYSTEM] =
00243              _dbus_strdup (DBUS_SYSTEM_BUS_DEFAULT_ADDRESS);
00244 
00245            if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
00246              return FALSE;
00247            
00248            _dbus_verbose ("  used default system bus \"%s\"\n",
00249                           bus_connection_addresses[DBUS_BUS_SYSTEM]);
00250          }
00251        else
00252          _dbus_verbose ("  used env var system bus \"%s\"\n",
00253                         bus_connection_addresses[DBUS_BUS_SYSTEM]);
00254           
00255       if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
00256         {
00257           _dbus_verbose ("Filling in session bus address...\n");
00258           
00259           if (!init_session_address ())
00260             return FALSE;
00261 
00262           _dbus_verbose ("  \"%s\"\n", bus_connection_addresses[DBUS_BUS_SESSION] ?
00263                          bus_connection_addresses[DBUS_BUS_SESSION] : "none set");
00264         }
00265 
00266       if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
00267         {
00268           _dbus_verbose ("Filling in activation bus address...\n");
00269           
00270           if (!get_from_env (&bus_connection_addresses[DBUS_BUS_STARTER],
00271                              "DBUS_STARTER_ADDRESS"))
00272             return FALSE;
00273           
00274           _dbus_verbose ("  \"%s\"\n", bus_connection_addresses[DBUS_BUS_STARTER] ?
00275                          bus_connection_addresses[DBUS_BUS_STARTER] : "none set");
00276         }
00277 
00278 
00279       if (bus_connection_addresses[DBUS_BUS_STARTER] != NULL)
00280         {
00281           s = _dbus_getenv ("DBUS_STARTER_BUS_TYPE");
00282               
00283           if (s != NULL)
00284             {
00285               _dbus_verbose ("Bus activation type was set to \"%s\"\n", s);
00286                   
00287               if (strcmp (s, "system") == 0)
00288                 activation_bus_type = DBUS_BUS_SYSTEM;
00289               else if (strcmp (s, "session") == 0)
00290                 activation_bus_type = DBUS_BUS_SESSION;
00291             }
00292         }
00293       else
00294         {
00295           /* Default to the session bus instead if available */
00296           if (bus_connection_addresses[DBUS_BUS_SESSION] != NULL)
00297             {
00298               bus_connection_addresses[DBUS_BUS_STARTER] =
00299                 _dbus_strdup (bus_connection_addresses[DBUS_BUS_SESSION]);
00300               if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
00301                 return FALSE;
00302             }
00303         }
00304       
00305       /* If we return FALSE we have to be sure that restarting
00306        * the above code will work right
00307        */
00308       
00309       if (!_dbus_register_shutdown_func (addresses_shutdown_func,
00310                                          NULL))
00311         return FALSE;
00312       
00313       initialized = TRUE;
00314     }
00315 
00316   return initialized;
00317 }
00318 
00319 static void
00320 bus_data_free (void *data)
00321 {
00322   BusData *bd = data;
00323   
00324   if (bd->is_well_known)
00325     {
00326       int i;
00327       _DBUS_LOCK (bus);
00328       /* We may be stored in more than one slot */
00329       /* This should now be impossible - these slots are supposed to
00330        * be cleared on disconnect, so should not need to be cleared on
00331        * finalize
00332        */
00333       i = 0;
00334       while (i < N_BUS_TYPES)
00335         {
00336           if (bus_connections[i] == bd->connection)
00337             bus_connections[i] = NULL;
00338           
00339           ++i;
00340         }
00341       _DBUS_UNLOCK (bus);
00342     }
00343   
00344   dbus_free (bd->unique_name);
00345   dbus_free (bd);
00346 
00347   dbus_connection_free_data_slot (&bus_data_slot);
00348 }
00349 
00350 static BusData*
00351 ensure_bus_data (DBusConnection *connection)
00352 {
00353   BusData *bd;
00354 
00355   if (!dbus_connection_allocate_data_slot (&bus_data_slot))
00356     return NULL;
00357 
00358   bd = dbus_connection_get_data (connection, bus_data_slot);
00359   if (bd == NULL)
00360     {      
00361       bd = dbus_new0 (BusData, 1);
00362       if (bd == NULL)
00363         {
00364           dbus_connection_free_data_slot (&bus_data_slot);
00365           return NULL;
00366         }
00367 
00368       bd->connection = connection;
00369       
00370       if (!dbus_connection_set_data (connection, bus_data_slot, bd,
00371                                      bus_data_free))
00372         {
00373           dbus_free (bd);
00374           dbus_connection_free_data_slot (&bus_data_slot);
00375           return NULL;
00376         }
00377 
00378       /* Data slot refcount now held by the BusData */
00379     }
00380   else
00381     {
00382       dbus_connection_free_data_slot (&bus_data_slot);
00383     }
00384 
00385   return bd;
00386 }
00387 
00394 void
00395 _dbus_bus_notify_shared_connection_disconnected_unlocked (DBusConnection *connection)
00396 {
00397   int i;
00398   
00399   _DBUS_LOCK (bus);
00400 
00401   /* We are expecting to have the connection saved in only one of these
00402    * slots, but someone could in a pathological case set system and session
00403    * bus to the same bus or something. Or set one of them to the starter
00404    * bus without setting the starter bus type in the env variable.
00405    * So we don't break the loop as soon as we find a match.
00406    */
00407   for (i = 0; i < N_BUS_TYPES; ++i)
00408     {
00409       if (bus_connections[i] == connection)
00410         {
00411           bus_connections[i] = NULL;
00412         }
00413     }
00414 
00415   _DBUS_UNLOCK (bus);
00416 }
00417 
00418 static DBusConnection *
00419 internal_bus_get (DBusBusType  type,
00420                   dbus_bool_t  private,
00421                   DBusError   *error)
00422 {
00423   const char *address;
00424   DBusConnection *connection;
00425   BusData *bd;
00426   DBusBusType address_type;
00427 
00428   _dbus_return_val_if_fail (type >= 0 && type < N_BUS_TYPES, NULL);
00429   _dbus_return_val_if_error_is_set (error, NULL);
00430 
00431   _DBUS_LOCK (bus);
00432 
00433   if (!init_connections_unlocked ())
00434     {
00435       _DBUS_UNLOCK (bus);
00436       _DBUS_SET_OOM (error);
00437       return NULL;
00438     }
00439 
00440   /* We want to use the activation address even if the
00441    * activating bus is the session or system bus,
00442    * per the spec.
00443    */
00444   address_type = type;
00445   
00446   /* Use the real type of the activation bus for getting its
00447    * connection, but only if the real type's address is available. (If
00448    * the activating bus isn't a well-known bus then
00449    * activation_bus_type == DBUS_BUS_STARTER)
00450    */
00451   if (type == DBUS_BUS_STARTER &&
00452       bus_connection_addresses[activation_bus_type] != NULL)
00453     type = activation_bus_type;
00454   
00455   if (!private && bus_connections[type] != NULL)
00456     {
00457       connection = bus_connections[type];
00458       dbus_connection_ref (connection);
00459       
00460       _DBUS_UNLOCK (bus);
00461       return connection;
00462     }
00463 
00464   address = bus_connection_addresses[address_type];
00465   if (address == NULL)
00466     {
00467       dbus_set_error (error, DBUS_ERROR_FAILED,
00468                       "Unable to determine the address of the message bus (try 'man dbus-launch' and 'man dbus-daemon' for help)");
00469       _DBUS_UNLOCK (bus);
00470       return NULL;
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       _DBUS_ASSERT_ERROR_IS_SET (error);
00481       _DBUS_UNLOCK (bus);
00482       return NULL;
00483     }
00484 
00485   if (!dbus_bus_register (connection, error))
00486     {
00487       _DBUS_ASSERT_ERROR_IS_SET (error);
00488       _dbus_connection_close_possibly_shared (connection);
00489       dbus_connection_unref (connection);
00490 
00491       _DBUS_UNLOCK (bus);
00492       return NULL;
00493     }
00494 
00495   if (!private)
00496     {
00497       /* store a weak ref to the connection (dbus-connection.c is
00498        * supposed to have a strong ref that it drops on disconnect,
00499        * since this is a shared connection)
00500        */
00501       bus_connections[type] = connection;
00502     }
00503 
00504   /* By default we're bound to the lifecycle of
00505    * the message bus.
00506    */
00507   dbus_connection_set_exit_on_disconnect (connection,
00508                                           TRUE);
00509  
00510   _DBUS_LOCK (bus_datas);
00511   bd = ensure_bus_data (connection);
00512   _dbus_assert (bd != NULL); /* it should have been created on
00513                                 register, so OOM not possible */
00514   bd->is_well_known = TRUE;
00515   _DBUS_UNLOCK (bus_datas);
00516 
00517   
00518   _DBUS_UNLOCK (bus);
00519 
00520   /* Return a reference to the caller */
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 
00659   _DBUS_LOCK (bus_datas);
00660 
00661   bd = ensure_bus_data (connection);
00662   if (bd == NULL)
00663     {
00664       _DBUS_SET_OOM (error);
00665       _DBUS_UNLOCK (bus_datas);
00666       return FALSE;
00667     }
00668 
00669   if (bd->unique_name != NULL)
00670     {
00671       _dbus_verbose ("Ignoring attempt to register the same DBusConnection %s with the message bus a second time.\n",
00672                      bd->unique_name);
00673       _DBUS_UNLOCK (bus_datas);
00674 
00675       /* Success! */
00676       return TRUE;
00677     }
00678   
00679   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00680                                           DBUS_PATH_DBUS,
00681                                           DBUS_INTERFACE_DBUS,
00682                                           "Hello"); 
00683 
00684   if (!message)
00685     {
00686       _DBUS_SET_OOM (error);
00687 
00688       _DBUS_UNLOCK (bus_datas);
00689       return FALSE;
00690     }
00691   
00692   reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
00693 
00694   dbus_message_unref (message);
00695   
00696   if (reply == NULL)
00697     goto out;
00698   else if (dbus_set_error_from_message (error, reply))
00699     goto out;
00700   else if (!dbus_message_get_args (reply, error,
00701                                    DBUS_TYPE_STRING, &name,
00702                                    DBUS_TYPE_INVALID))
00703     goto out;
00704   
00705   bd->unique_name = _dbus_strdup (name);
00706   if (bd->unique_name == NULL)
00707     {
00708       _DBUS_SET_OOM (error);
00709       goto out;
00710     }
00711   
00712   retval = TRUE;
00713   
00714  out:
00715   if (reply)
00716     dbus_message_unref (reply);
00717 
00718   if (!retval)
00719     _DBUS_ASSERT_ERROR_IS_SET (error);
00720 
00721   _DBUS_UNLOCK (bus_datas);
00722   
00723   return retval;
00724 }
00725 
00726 
00761 dbus_bool_t
00762 dbus_bus_set_unique_name (DBusConnection *connection,
00763                           const char     *unique_name)
00764 {
00765   BusData *bd;
00766   dbus_bool_t success = FALSE;
00767 
00768   _dbus_return_val_if_fail (connection != NULL, FALSE);
00769   _dbus_return_val_if_fail (unique_name != NULL, FALSE);
00770 
00771   _DBUS_LOCK (bus_datas);
00772   
00773   bd = ensure_bus_data (connection);
00774   if (bd == NULL)
00775     goto out;
00776 
00777   _dbus_assert (bd->unique_name == NULL);
00778   
00779   bd->unique_name = _dbus_strdup (unique_name);
00780   success = bd->unique_name != NULL;
00781 
00782 out:
00783   _DBUS_UNLOCK (bus_datas);
00784   
00785   return success;
00786 }
00787 
00806 const char*
00807 dbus_bus_get_unique_name (DBusConnection *connection)
00808 {
00809   BusData *bd;
00810   const char *unique_name = NULL;
00811 
00812   _dbus_return_val_if_fail (connection != NULL, NULL);
00813 
00814   _DBUS_LOCK (bus_datas);
00815   
00816   bd = ensure_bus_data (connection);
00817   if (bd == NULL)
00818     goto out;
00819 
00820   unique_name = bd->unique_name;
00821 
00822 out:
00823   _DBUS_UNLOCK (bus_datas);
00824 
00825   return unique_name;
00826 }
00827 
00851 unsigned long
00852 dbus_bus_get_unix_user (DBusConnection *connection,
00853                         const char     *name,
00854                         DBusError      *error)
00855 {
00856   DBusMessage *message, *reply;
00857   dbus_uint32_t uid;
00858 
00859   _dbus_return_val_if_fail (connection != NULL, DBUS_UID_UNSET);
00860   _dbus_return_val_if_fail (name != NULL, DBUS_UID_UNSET);
00861   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), DBUS_UID_UNSET);
00862   _dbus_return_val_if_error_is_set (error, DBUS_UID_UNSET);
00863   
00864   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00865                                           DBUS_PATH_DBUS,
00866                                           DBUS_INTERFACE_DBUS,
00867                                           "GetConnectionUnixUser");
00868 
00869   if (message == NULL)
00870     {
00871       _DBUS_SET_OOM (error);
00872       return DBUS_UID_UNSET;
00873     }
00874  
00875   if (!dbus_message_append_args (message,
00876                                  DBUS_TYPE_STRING, &name,
00877                                  DBUS_TYPE_INVALID))
00878     {
00879       dbus_message_unref (message);
00880       _DBUS_SET_OOM (error);
00881       return DBUS_UID_UNSET;
00882     }
00883   
00884   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
00885                                                      error);
00886   
00887   dbus_message_unref (message);
00888   
00889   if (reply == NULL)
00890     {
00891       _DBUS_ASSERT_ERROR_IS_SET (error);
00892       return DBUS_UID_UNSET;
00893     }  
00894 
00895   if (dbus_set_error_from_message (error, reply))
00896     {
00897       _DBUS_ASSERT_ERROR_IS_SET (error);
00898       dbus_message_unref (reply);
00899       return DBUS_UID_UNSET;
00900     }
00901   
00902   if (!dbus_message_get_args (reply, error,
00903                               DBUS_TYPE_UINT32, &uid,
00904                               DBUS_TYPE_INVALID))
00905     {
00906       _DBUS_ASSERT_ERROR_IS_SET (error);
00907       dbus_message_unref (reply);
00908       return DBUS_UID_UNSET;
00909     }
00910 
00911   dbus_message_unref (reply);
00912   
00913   return (unsigned long) uid;
00914 }
00915 
00934 char*
00935 dbus_bus_get_id (DBusConnection *connection,
00936                  DBusError      *error)
00937 {
00938   DBusMessage *message, *reply;
00939   char *id;
00940   const char *v_STRING;
00941 
00942   _dbus_return_val_if_fail (connection != NULL, NULL);
00943   _dbus_return_val_if_error_is_set (error, NULL);
00944   
00945   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00946                                           DBUS_PATH_DBUS,
00947                                           DBUS_INTERFACE_DBUS,
00948                                           "GetId");
00949   
00950   if (message == NULL)
00951     {
00952       _DBUS_SET_OOM (error);
00953       return NULL;
00954     }
00955   
00956   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
00957                                                      error);
00958   
00959   dbus_message_unref (message);
00960   
00961   if (reply == NULL)
00962     {
00963       _DBUS_ASSERT_ERROR_IS_SET (error);
00964       return NULL;
00965     }  
00966 
00967   if (dbus_set_error_from_message (error, reply))
00968     {
00969       _DBUS_ASSERT_ERROR_IS_SET (error);
00970       dbus_message_unref (reply);
00971       return NULL;
00972     }
00973 
00974   v_STRING = NULL;
00975   if (!dbus_message_get_args (reply, error,
00976                               DBUS_TYPE_STRING, &v_STRING,
00977                               DBUS_TYPE_INVALID))
00978     {
00979       _DBUS_ASSERT_ERROR_IS_SET (error);
00980       dbus_message_unref (reply);
00981       return NULL;
00982     }
00983 
00984   id = _dbus_strdup (v_STRING); /* may be NULL */
00985   
00986   dbus_message_unref (reply);
00987 
00988   if (id == NULL)
00989     _DBUS_SET_OOM (error);
00990 
00991   /* FIXME it might be nice to cache the ID locally */
00992   
00993   return id;
00994 }
00995 
01098 int
01099 dbus_bus_request_name (DBusConnection *connection,
01100                        const char     *name,
01101                        unsigned int    flags,
01102                        DBusError      *error)
01103 {
01104   DBusMessage *message, *reply;
01105   dbus_uint32_t result;
01106 
01107   _dbus_return_val_if_fail (connection != NULL, 0);
01108   _dbus_return_val_if_fail (name != NULL, 0);
01109   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
01110   _dbus_return_val_if_error_is_set (error, 0);
01111   
01112   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01113                                           DBUS_PATH_DBUS,
01114                                           DBUS_INTERFACE_DBUS,
01115                                           "RequestName");
01116 
01117   if (message == NULL)
01118     {
01119       _DBUS_SET_OOM (error);
01120       return -1;
01121     }
01122  
01123   if (!dbus_message_append_args (message,
01124                                  DBUS_TYPE_STRING, &name,
01125                                  DBUS_TYPE_UINT32, &flags,
01126                                  DBUS_TYPE_INVALID))
01127     {
01128       dbus_message_unref (message);
01129       _DBUS_SET_OOM (error);
01130       return -1;
01131     }
01132   
01133   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
01134                                                      error);
01135   
01136   dbus_message_unref (message);
01137   
01138   if (reply == NULL)
01139     {
01140       _DBUS_ASSERT_ERROR_IS_SET (error);
01141       return -1;
01142     }  
01143 
01144   if (dbus_set_error_from_message (error, reply))
01145     {
01146       _DBUS_ASSERT_ERROR_IS_SET (error);
01147       dbus_message_unref (reply);
01148       return -1;
01149     }
01150   
01151   if (!dbus_message_get_args (reply, error,
01152                               DBUS_TYPE_UINT32, &result,
01153                               DBUS_TYPE_INVALID))
01154     {
01155       _DBUS_ASSERT_ERROR_IS_SET (error);
01156       dbus_message_unref (reply);
01157       return -1;
01158     }
01159 
01160   dbus_message_unref (reply);
01161   
01162   return result;
01163 }
01164 
01165 
01184 int
01185 dbus_bus_release_name (DBusConnection *connection,
01186                        const char     *name,
01187                        DBusError      *error)
01188 {
01189   DBusMessage *message, *reply;
01190   dbus_uint32_t result;
01191 
01192   _dbus_return_val_if_fail (connection != NULL, 0);
01193   _dbus_return_val_if_fail (name != NULL, 0);
01194   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
01195   _dbus_return_val_if_error_is_set (error, 0);
01196 
01197   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01198                                           DBUS_PATH_DBUS,
01199                                           DBUS_INTERFACE_DBUS,
01200                                           "ReleaseName");
01201 
01202   if (message == NULL)
01203     {
01204       _DBUS_SET_OOM (error);
01205       return -1;
01206     }
01207 
01208   if (!dbus_message_append_args (message,
01209                                  DBUS_TYPE_STRING, &name,
01210                                  DBUS_TYPE_INVALID))
01211     {
01212       dbus_message_unref (message);
01213       _DBUS_SET_OOM (error);
01214       return -1;
01215     }
01216 
01217   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
01218                                                      error);
01219 
01220   dbus_message_unref (message);
01221 
01222   if (reply == NULL)
01223     {
01224       _DBUS_ASSERT_ERROR_IS_SET (error);
01225       return -1;
01226     }
01227 
01228   if (dbus_set_error_from_message (error, reply))
01229     {
01230       _DBUS_ASSERT_ERROR_IS_SET (error);
01231       dbus_message_unref (reply);
01232       return -1;
01233     }
01234 
01235   if (!dbus_message_get_args (reply, error,
01236                               DBUS_TYPE_UINT32, &result,
01237                               DBUS_TYPE_INVALID))
01238     {
01239       _DBUS_ASSERT_ERROR_IS_SET (error);
01240       dbus_message_unref (reply);
01241       return -1;
01242     }
01243 
01244   dbus_message_unref (reply);
01245 
01246   return result;
01247 }
01248 
01266 dbus_bool_t
01267 dbus_bus_name_has_owner (DBusConnection *connection,
01268                          const char     *name,
01269                          DBusError      *error)
01270 {
01271   DBusMessage *message, *reply;
01272   dbus_bool_t exists;
01273 
01274   _dbus_return_val_if_fail (connection != NULL, FALSE);
01275   _dbus_return_val_if_fail (name != NULL, FALSE);
01276   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
01277   _dbus_return_val_if_error_is_set (error, FALSE);
01278   
01279   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01280                                           DBUS_PATH_DBUS,
01281                                           DBUS_INTERFACE_DBUS,
01282                                           "NameHasOwner");
01283   if (message == NULL)
01284     {
01285       _DBUS_SET_OOM (error);
01286       return FALSE;
01287     }
01288   
01289   if (!dbus_message_append_args (message,
01290                                  DBUS_TYPE_STRING, &name,
01291                                  DBUS_TYPE_INVALID))
01292     {
01293       dbus_message_unref (message);
01294       _DBUS_SET_OOM (error);
01295       return FALSE;
01296     }
01297   
01298   reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
01299   dbus_message_unref (message);
01300 
01301   if (reply == NULL)
01302     {
01303       _DBUS_ASSERT_ERROR_IS_SET (error);
01304       return FALSE;
01305     }
01306 
01307   if (!dbus_message_get_args (reply, error,
01308                               DBUS_TYPE_BOOLEAN, &exists,
01309                               DBUS_TYPE_INVALID))
01310     {
01311       _DBUS_ASSERT_ERROR_IS_SET (error);
01312       dbus_message_unref (reply);
01313       return FALSE;
01314     }
01315   
01316   dbus_message_unref (reply);
01317   return exists;
01318 }
01319 
01342 dbus_bool_t
01343 dbus_bus_start_service_by_name (DBusConnection *connection,
01344                                 const char     *name,
01345                                 dbus_uint32_t   flags,
01346                                 dbus_uint32_t  *result,
01347                                 DBusError      *error)
01348 {
01349   DBusMessage *msg;
01350   DBusMessage *reply;
01351 
01352   _dbus_return_val_if_fail (connection != NULL, FALSE);
01353   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
01354   
01355   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01356                                       DBUS_PATH_DBUS,
01357                                       DBUS_INTERFACE_DBUS,
01358                                       "StartServiceByName");
01359 
01360   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name,
01361                                  DBUS_TYPE_UINT32, &flags, DBUS_TYPE_INVALID))
01362     {
01363       dbus_message_unref (msg);
01364       _DBUS_SET_OOM (error);
01365       return FALSE;
01366     }
01367 
01368   reply = dbus_connection_send_with_reply_and_block (connection, msg,
01369                                                      -1, error);
01370   dbus_message_unref (msg);
01371 
01372   if (reply == NULL)
01373     {
01374       _DBUS_ASSERT_ERROR_IS_SET (error);
01375       return FALSE;
01376     }
01377 
01378   if (dbus_set_error_from_message (error, reply))
01379     {
01380       _DBUS_ASSERT_ERROR_IS_SET (error);
01381       dbus_message_unref (reply);
01382       return FALSE;
01383     }
01384 
01385   if (result != NULL &&
01386       !dbus_message_get_args (reply, error, DBUS_TYPE_UINT32,
01387                               result, DBUS_TYPE_INVALID))
01388     {
01389       _DBUS_ASSERT_ERROR_IS_SET (error);
01390       dbus_message_unref (reply);
01391       return FALSE;
01392     }
01393   
01394   dbus_message_unref (reply);
01395   return TRUE;
01396 }
01397 
01398 static void
01399 send_no_return_values (DBusConnection *connection,
01400                        DBusMessage    *msg,
01401                        DBusError      *error)
01402 {
01403   if (error)
01404     {
01405       /* Block to check success codepath */
01406       DBusMessage *reply;
01407       
01408       reply = dbus_connection_send_with_reply_and_block (connection, msg,
01409                                                          -1, error);
01410       
01411       if (reply == NULL)
01412         _DBUS_ASSERT_ERROR_IS_SET (error);
01413       else
01414         dbus_message_unref (reply);
01415     }
01416   else
01417     {
01418       /* Silently-fail nonblocking codepath */
01419       dbus_message_set_no_reply (msg, TRUE);
01420       dbus_connection_send (connection, msg, NULL);
01421     }
01422 }
01423 
01506 void
01507 dbus_bus_add_match (DBusConnection *connection,
01508                     const char     *rule,
01509                     DBusError      *error)
01510 {
01511   DBusMessage *msg;
01512 
01513   _dbus_return_if_fail (rule != NULL);
01514 
01515   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01516                                       DBUS_PATH_DBUS,
01517                                       DBUS_INTERFACE_DBUS,
01518                                       "AddMatch");
01519 
01520   if (msg == NULL)
01521     {
01522       _DBUS_SET_OOM (error);
01523       return;
01524     }
01525 
01526   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
01527                                  DBUS_TYPE_INVALID))
01528     {
01529       dbus_message_unref (msg);
01530       _DBUS_SET_OOM (error);
01531       return;
01532     }
01533 
01534   send_no_return_values (connection, msg, error);
01535 
01536   dbus_message_unref (msg);
01537 }
01538 
01556 void
01557 dbus_bus_remove_match (DBusConnection *connection,
01558                        const char     *rule,
01559                        DBusError      *error)
01560 {
01561   DBusMessage *msg;
01562 
01563   _dbus_return_if_fail (rule != NULL);
01564   
01565   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01566                                       DBUS_PATH_DBUS,
01567                                       DBUS_INTERFACE_DBUS,
01568                                       "RemoveMatch");
01569 
01570   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
01571                                  DBUS_TYPE_INVALID))
01572     {
01573       dbus_message_unref (msg);
01574       _DBUS_SET_OOM (error);
01575       return;
01576     }
01577 
01578   send_no_return_values (connection, msg, error);
01579 
01580   dbus_message_unref (msg);
01581 }
01582