• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List

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_setenv ("DBUS_ACTIVATION_ADDRESS", NULL))
00310         return FALSE;
00311 
00312       if (!_dbus_setenv ("DBUS_ACTIVATION_BUS_TYPE", NULL))
00313         return FALSE;
00314       
00315       if (!_dbus_register_shutdown_func (addresses_shutdown_func,
00316                                          NULL))
00317         return FALSE;
00318       
00319       initialized = TRUE;
00320     }
00321 
00322   return initialized;
00323 }
00324 
00325 static void
00326 bus_data_free (void *data)
00327 {
00328   BusData *bd = data;
00329   
00330   if (bd->is_well_known)
00331     {
00332       int i;
00333       _DBUS_LOCK (bus);
00334       /* We may be stored in more than one slot */
00335       /* This should now be impossible - these slots are supposed to
00336        * be cleared on disconnect, so should not need to be cleared on
00337        * finalize
00338        */
00339       i = 0;
00340       while (i < N_BUS_TYPES)
00341         {
00342           if (bus_connections[i] == bd->connection)
00343             bus_connections[i] = NULL;
00344           
00345           ++i;
00346         }
00347       _DBUS_UNLOCK (bus);
00348     }
00349   
00350   dbus_free (bd->unique_name);
00351   dbus_free (bd);
00352 
00353   dbus_connection_free_data_slot (&bus_data_slot);
00354 }
00355 
00356 static BusData*
00357 ensure_bus_data (DBusConnection *connection)
00358 {
00359   BusData *bd;
00360 
00361   if (!dbus_connection_allocate_data_slot (&bus_data_slot))
00362     return NULL;
00363 
00364   bd = dbus_connection_get_data (connection, bus_data_slot);
00365   if (bd == NULL)
00366     {      
00367       bd = dbus_new0 (BusData, 1);
00368       if (bd == NULL)
00369         {
00370           dbus_connection_free_data_slot (&bus_data_slot);
00371           return NULL;
00372         }
00373 
00374       bd->connection = connection;
00375       
00376       if (!dbus_connection_set_data (connection, bus_data_slot, bd,
00377                                      bus_data_free))
00378         {
00379           dbus_free (bd);
00380           dbus_connection_free_data_slot (&bus_data_slot);
00381           return NULL;
00382         }
00383 
00384       /* Data slot refcount now held by the BusData */
00385     }
00386   else
00387     {
00388       dbus_connection_free_data_slot (&bus_data_slot);
00389     }
00390 
00391   return bd;
00392 }
00393 
00400 void
00401 _dbus_bus_notify_shared_connection_disconnected_unlocked (DBusConnection *connection)
00402 {
00403   int i;
00404   
00405   _DBUS_LOCK (bus);
00406 
00407   /* We are expecting to have the connection saved in only one of these
00408    * slots, but someone could in a pathological case set system and session
00409    * bus to the same bus or something. Or set one of them to the starter
00410    * bus without setting the starter bus type in the env variable.
00411    * So we don't break the loop as soon as we find a match.
00412    */
00413   for (i = 0; i < N_BUS_TYPES; ++i)
00414     {
00415       if (bus_connections[i] == connection)
00416         {
00417           bus_connections[i] = NULL;
00418         }
00419     }
00420 
00421   _DBUS_UNLOCK (bus);
00422 }
00423 
00424 static DBusConnection *
00425 internal_bus_get (DBusBusType  type,
00426                   dbus_bool_t  private,
00427                   DBusError   *error)
00428 {
00429   const char *address;
00430   DBusConnection *connection;
00431   BusData *bd;
00432   DBusBusType address_type;
00433 
00434   _dbus_return_val_if_fail (type >= 0 && type < N_BUS_TYPES, NULL);
00435   _dbus_return_val_if_error_is_set (error, NULL);
00436 
00437   _DBUS_LOCK (bus);
00438 
00439   if (!init_connections_unlocked ())
00440     {
00441       _DBUS_UNLOCK (bus);
00442       _DBUS_SET_OOM (error);
00443       return NULL;
00444     }
00445 
00446   /* We want to use the activation address even if the
00447    * activating bus is the session or system bus,
00448    * per the spec.
00449    */
00450   address_type = type;
00451   
00452   /* Use the real type of the activation bus for getting its
00453    * connection, but only if the real type's address is available. (If
00454    * the activating bus isn't a well-known bus then
00455    * activation_bus_type == DBUS_BUS_STARTER)
00456    */
00457   if (type == DBUS_BUS_STARTER &&
00458       bus_connection_addresses[activation_bus_type] != NULL)
00459     type = activation_bus_type;
00460   
00461   if (!private && bus_connections[type] != NULL)
00462     {
00463       connection = bus_connections[type];
00464       dbus_connection_ref (connection);
00465       
00466       _DBUS_UNLOCK (bus);
00467       return connection;
00468     }
00469 
00470   address = bus_connection_addresses[address_type];
00471   if (address == NULL)
00472     {
00473       dbus_set_error (error, DBUS_ERROR_FAILED,
00474                       "Unable to determine the address of the message bus (try 'man dbus-launch' and 'man dbus-daemon' for help)");
00475       _DBUS_UNLOCK (bus);
00476       return NULL;
00477     }
00478 
00479   if (private)
00480     connection = dbus_connection_open_private (address, error);
00481   else
00482     connection = dbus_connection_open (address, error);
00483   
00484   if (!connection)
00485     {
00486       _DBUS_ASSERT_ERROR_IS_SET (error);
00487       _DBUS_UNLOCK (bus);
00488       return NULL;
00489     }
00490 
00491   if (!dbus_bus_register (connection, error))
00492     {
00493       _DBUS_ASSERT_ERROR_IS_SET (error);
00494       _dbus_connection_close_possibly_shared (connection);
00495       dbus_connection_unref (connection);
00496 
00497       _DBUS_UNLOCK (bus);
00498       return NULL;
00499     }
00500 
00501   if (!private)
00502     {
00503       /* store a weak ref to the connection (dbus-connection.c is
00504        * supposed to have a strong ref that it drops on disconnect,
00505        * since this is a shared connection)
00506        */
00507       bus_connections[type] = connection;
00508     }
00509 
00510   /* By default we're bound to the lifecycle of
00511    * the message bus.
00512    */
00513   dbus_connection_set_exit_on_disconnect (connection,
00514                                           TRUE);
00515  
00516   _DBUS_LOCK (bus_datas);
00517   bd = ensure_bus_data (connection);
00518   _dbus_assert (bd != NULL); /* it should have been created on
00519                                 register, so OOM not possible */
00520   bd->is_well_known = TRUE;
00521   _DBUS_UNLOCK (bus_datas);
00522 
00523   
00524   _DBUS_UNLOCK (bus);
00525 
00526   /* Return a reference to the caller */
00527   return connection;
00528 }
00529 
00530  /* end of implementation details docs */
00532 
00563 DBusConnection *
00564 dbus_bus_get (DBusBusType  type,
00565               DBusError   *error)
00566 {
00567   return internal_bus_get (type, FALSE, error);
00568 }
00569 
00595 DBusConnection *
00596 dbus_bus_get_private (DBusBusType  type,
00597                       DBusError   *error)
00598 {
00599   return internal_bus_get (type, TRUE, error);
00600 }
00601 
00651 dbus_bool_t
00652 dbus_bus_register (DBusConnection *connection,
00653                    DBusError      *error)
00654 {
00655   DBusMessage *message, *reply;
00656   char *name;
00657   BusData *bd;
00658   dbus_bool_t retval;
00659 
00660   _dbus_return_val_if_fail (connection != NULL, FALSE);
00661   _dbus_return_val_if_error_is_set (error, FALSE);
00662 
00663   retval = FALSE;
00664 
00665   _DBUS_LOCK (bus_datas);
00666 
00667   bd = ensure_bus_data (connection);
00668   if (bd == NULL)
00669     {
00670       _DBUS_SET_OOM (error);
00671       _DBUS_UNLOCK (bus_datas);
00672       return FALSE;
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       _DBUS_UNLOCK (bus_datas);
00680 
00681       /* Success! */
00682       return TRUE;
00683     }
00684   
00685   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00686                                           DBUS_PATH_DBUS,
00687                                           DBUS_INTERFACE_DBUS,
00688                                           "Hello"); 
00689 
00690   if (!message)
00691     {
00692       _DBUS_SET_OOM (error);
00693 
00694       _DBUS_UNLOCK (bus_datas);
00695       return FALSE;
00696     }
00697   
00698   reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
00699 
00700   dbus_message_unref (message);
00701   
00702   if (reply == NULL)
00703     goto out;
00704   else if (dbus_set_error_from_message (error, reply))
00705     goto out;
00706   else if (!dbus_message_get_args (reply, error,
00707                                    DBUS_TYPE_STRING, &name,
00708                                    DBUS_TYPE_INVALID))
00709     goto out;
00710   
00711   bd->unique_name = _dbus_strdup (name);
00712   if (bd->unique_name == NULL)
00713     {
00714       _DBUS_SET_OOM (error);
00715       goto out;
00716     }
00717   
00718   retval = TRUE;
00719   
00720  out:
00721   if (reply)
00722     dbus_message_unref (reply);
00723 
00724   if (!retval)
00725     _DBUS_ASSERT_ERROR_IS_SET (error);
00726 
00727   _DBUS_UNLOCK (bus_datas);
00728   
00729   return retval;
00730 }
00731 
00732 
00767 dbus_bool_t
00768 dbus_bus_set_unique_name (DBusConnection *connection,
00769                           const char     *unique_name)
00770 {
00771   BusData *bd;
00772   dbus_bool_t success;
00773 
00774   _dbus_return_val_if_fail (connection != NULL, FALSE);
00775   _dbus_return_val_if_fail (unique_name != NULL, FALSE);
00776 
00777   _DBUS_LOCK (bus_datas);
00778   
00779   bd = ensure_bus_data (connection);
00780   if (bd == NULL)
00781     return FALSE;
00782 
00783   _dbus_assert (bd->unique_name == NULL);
00784   
00785   bd->unique_name = _dbus_strdup (unique_name);
00786   success = bd->unique_name != NULL;
00787   
00788   _DBUS_UNLOCK (bus_datas);
00789   
00790   return success;
00791 }
00792 
00811 const char*
00812 dbus_bus_get_unique_name (DBusConnection *connection)
00813 {
00814   BusData *bd;
00815   const char *unique_name;
00816 
00817   _dbus_return_val_if_fail (connection != NULL, NULL);
00818 
00819   _DBUS_LOCK (bus_datas);
00820   
00821   bd = ensure_bus_data (connection);
00822   if (bd == NULL)
00823     return NULL;
00824 
00825   unique_name = bd->unique_name;
00826 
00827   _DBUS_UNLOCK (bus_datas);
00828   
00829   return unique_name;
00830 }
00831 
00855 unsigned long
00856 dbus_bus_get_unix_user (DBusConnection *connection,
00857                         const char     *name,
00858                         DBusError      *error)
00859 {
00860   DBusMessage *message, *reply;
00861   dbus_uint32_t uid;
00862 
00863   _dbus_return_val_if_fail (connection != NULL, DBUS_UID_UNSET);
00864   _dbus_return_val_if_fail (name != NULL, DBUS_UID_UNSET);
00865   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), DBUS_UID_UNSET);
00866   _dbus_return_val_if_error_is_set (error, DBUS_UID_UNSET);
00867   
00868   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00869                                           DBUS_PATH_DBUS,
00870                                           DBUS_INTERFACE_DBUS,
00871                                           "GetConnectionUnixUser");
00872 
00873   if (message == NULL)
00874     {
00875       _DBUS_SET_OOM (error);
00876       return DBUS_UID_UNSET;
00877     }
00878  
00879   if (!dbus_message_append_args (message,
00880                                  DBUS_TYPE_STRING, &name,
00881                                  DBUS_TYPE_INVALID))
00882     {
00883       dbus_message_unref (message);
00884       _DBUS_SET_OOM (error);
00885       return DBUS_UID_UNSET;
00886     }
00887   
00888   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
00889                                                      error);
00890   
00891   dbus_message_unref (message);
00892   
00893   if (reply == NULL)
00894     {
00895       _DBUS_ASSERT_ERROR_IS_SET (error);
00896       return DBUS_UID_UNSET;
00897     }  
00898 
00899   if (dbus_set_error_from_message (error, reply))
00900     {
00901       _DBUS_ASSERT_ERROR_IS_SET (error);
00902       dbus_message_unref (reply);
00903       return DBUS_UID_UNSET;
00904     }
00905   
00906   if (!dbus_message_get_args (reply, error,
00907                               DBUS_TYPE_UINT32, &uid,
00908                               DBUS_TYPE_INVALID))
00909     {
00910       _DBUS_ASSERT_ERROR_IS_SET (error);
00911       dbus_message_unref (reply);
00912       return DBUS_UID_UNSET;
00913     }
00914 
00915   dbus_message_unref (reply);
00916   
00917   return (unsigned long) uid;
00918 }
00919 
00938 char*
00939 dbus_bus_get_id (DBusConnection *connection,
00940                  DBusError      *error)
00941 {
00942   DBusMessage *message, *reply;
00943   char *id;
00944   const char *v_STRING;
00945 
00946   _dbus_return_val_if_fail (connection != NULL, NULL);
00947   _dbus_return_val_if_error_is_set (error, NULL);
00948   
00949   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00950                                           DBUS_PATH_DBUS,
00951                                           DBUS_INTERFACE_DBUS,
00952                                           "GetId");
00953   
00954   if (message == NULL)
00955     {
00956       _DBUS_SET_OOM (error);
00957       return NULL;
00958     }
00959   
00960   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
00961                                                      error);
00962   
00963   dbus_message_unref (message);
00964   
00965   if (reply == NULL)
00966     {
00967       _DBUS_ASSERT_ERROR_IS_SET (error);
00968       return NULL;
00969     }  
00970 
00971   if (dbus_set_error_from_message (error, reply))
00972     {
00973       _DBUS_ASSERT_ERROR_IS_SET (error);
00974       dbus_message_unref (reply);
00975       return NULL;
00976     }
00977 
00978   v_STRING = NULL;
00979   if (!dbus_message_get_args (reply, error,
00980                               DBUS_TYPE_STRING, &v_STRING,
00981                               DBUS_TYPE_INVALID))
00982     {
00983       _DBUS_ASSERT_ERROR_IS_SET (error);
00984       dbus_message_unref (reply);
00985       return NULL;
00986     }
00987 
00988   id = _dbus_strdup (v_STRING); /* may be NULL */
00989   
00990   dbus_message_unref (reply);
00991 
00992   if (id == NULL)
00993     _DBUS_SET_OOM (error);
00994 
00995   /* FIXME it might be nice to cache the ID locally */
00996   
00997   return id;
00998 }
00999 
01102 int
01103 dbus_bus_request_name (DBusConnection *connection,
01104                        const char     *name,
01105                        unsigned int    flags,
01106                        DBusError      *error)
01107 {
01108   DBusMessage *message, *reply;
01109   dbus_uint32_t result;
01110 
01111   _dbus_return_val_if_fail (connection != NULL, 0);
01112   _dbus_return_val_if_fail (name != NULL, 0);
01113   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
01114   _dbus_return_val_if_error_is_set (error, 0);
01115   
01116   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01117                                           DBUS_PATH_DBUS,
01118                                           DBUS_INTERFACE_DBUS,
01119                                           "RequestName");
01120 
01121   if (message == NULL)
01122     {
01123       _DBUS_SET_OOM (error);
01124       return -1;
01125     }
01126  
01127   if (!dbus_message_append_args (message,
01128                                  DBUS_TYPE_STRING, &name,
01129                                  DBUS_TYPE_UINT32, &flags,
01130                                  DBUS_TYPE_INVALID))
01131     {
01132       dbus_message_unref (message);
01133       _DBUS_SET_OOM (error);
01134       return -1;
01135     }
01136   
01137   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
01138                                                      error);
01139   
01140   dbus_message_unref (message);
01141   
01142   if (reply == NULL)
01143     {
01144       _DBUS_ASSERT_ERROR_IS_SET (error);
01145       return -1;
01146     }  
01147 
01148   if (dbus_set_error_from_message (error, reply))
01149     {
01150       _DBUS_ASSERT_ERROR_IS_SET (error);
01151       dbus_message_unref (reply);
01152       return -1;
01153     }
01154   
01155   if (!dbus_message_get_args (reply, error,
01156                               DBUS_TYPE_UINT32, &result,
01157                               DBUS_TYPE_INVALID))
01158     {
01159       _DBUS_ASSERT_ERROR_IS_SET (error);
01160       dbus_message_unref (reply);
01161       return -1;
01162     }
01163 
01164   dbus_message_unref (reply);
01165   
01166   return result;
01167 }
01168 
01169 
01188 int
01189 dbus_bus_release_name (DBusConnection *connection,
01190                        const char     *name,
01191                        DBusError      *error)
01192 {
01193   DBusMessage *message, *reply;
01194   dbus_uint32_t result;
01195 
01196   _dbus_return_val_if_fail (connection != NULL, 0);
01197   _dbus_return_val_if_fail (name != NULL, 0);
01198   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
01199   _dbus_return_val_if_error_is_set (error, 0);
01200 
01201   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01202                                           DBUS_PATH_DBUS,
01203                                           DBUS_INTERFACE_DBUS,
01204                                           "ReleaseName");
01205 
01206   if (message == NULL)
01207     {
01208       _DBUS_SET_OOM (error);
01209       return -1;
01210     }
01211 
01212   if (!dbus_message_append_args (message,
01213                                  DBUS_TYPE_STRING, &name,
01214                                  DBUS_TYPE_INVALID))
01215     {
01216       dbus_message_unref (message);
01217       _DBUS_SET_OOM (error);
01218       return -1;
01219     }
01220 
01221   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
01222                                                      error);
01223 
01224   dbus_message_unref (message);
01225 
01226   if (reply == NULL)
01227     {
01228       _DBUS_ASSERT_ERROR_IS_SET (error);
01229       return -1;
01230     }
01231 
01232   if (dbus_set_error_from_message (error, reply))
01233     {
01234       _DBUS_ASSERT_ERROR_IS_SET (error);
01235       dbus_message_unref (reply);
01236       return -1;
01237     }
01238 
01239   if (!dbus_message_get_args (reply, error,
01240                               DBUS_TYPE_UINT32, &result,
01241                               DBUS_TYPE_INVALID))
01242     {
01243       _DBUS_ASSERT_ERROR_IS_SET (error);
01244       dbus_message_unref (reply);
01245       return -1;
01246     }
01247 
01248   dbus_message_unref (reply);
01249 
01250   return result;
01251 }
01252 
01270 dbus_bool_t
01271 dbus_bus_name_has_owner (DBusConnection *connection,
01272                          const char     *name,
01273                          DBusError      *error)
01274 {
01275   DBusMessage *message, *reply;
01276   dbus_bool_t exists;
01277 
01278   _dbus_return_val_if_fail (connection != NULL, FALSE);
01279   _dbus_return_val_if_fail (name != NULL, FALSE);
01280   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
01281   _dbus_return_val_if_error_is_set (error, FALSE);
01282   
01283   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01284                                           DBUS_PATH_DBUS,
01285                                           DBUS_INTERFACE_DBUS,
01286                                           "NameHasOwner");
01287   if (message == NULL)
01288     {
01289       _DBUS_SET_OOM (error);
01290       return FALSE;
01291     }
01292   
01293   if (!dbus_message_append_args (message,
01294                                  DBUS_TYPE_STRING, &name,
01295                                  DBUS_TYPE_INVALID))
01296     {
01297       dbus_message_unref (message);
01298       _DBUS_SET_OOM (error);
01299       return FALSE;
01300     }
01301   
01302   reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
01303   dbus_message_unref (message);
01304 
01305   if (reply == NULL)
01306     {
01307       _DBUS_ASSERT_ERROR_IS_SET (error);
01308       return FALSE;
01309     }
01310 
01311   if (!dbus_message_get_args (reply, error,
01312                               DBUS_TYPE_BOOLEAN, &exists,
01313                               DBUS_TYPE_INVALID))
01314     {
01315       _DBUS_ASSERT_ERROR_IS_SET (error);
01316       dbus_message_unref (reply);
01317       return FALSE;
01318     }
01319   
01320   dbus_message_unref (reply);
01321   return exists;
01322 }
01323 
01346 dbus_bool_t
01347 dbus_bus_start_service_by_name (DBusConnection *connection,
01348                                 const char     *name,
01349                                 dbus_uint32_t   flags,
01350                                 dbus_uint32_t  *result,
01351                                 DBusError      *error)
01352 {
01353   DBusMessage *msg;
01354   DBusMessage *reply;
01355 
01356   _dbus_return_val_if_fail (connection != NULL, FALSE);
01357   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
01358   
01359   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01360                                       DBUS_PATH_DBUS,
01361                                       DBUS_INTERFACE_DBUS,
01362                                       "StartServiceByName");
01363 
01364   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name,
01365                                  DBUS_TYPE_UINT32, &flags, DBUS_TYPE_INVALID))
01366     {
01367       dbus_message_unref (msg);
01368       _DBUS_SET_OOM (error);
01369       return FALSE;
01370     }
01371 
01372   reply = dbus_connection_send_with_reply_and_block (connection, msg,
01373                                                      -1, error);
01374   dbus_message_unref (msg);
01375 
01376   if (reply == NULL)
01377     {
01378       _DBUS_ASSERT_ERROR_IS_SET (error);
01379       return FALSE;
01380     }
01381 
01382   if (dbus_set_error_from_message (error, reply))
01383     {
01384       _DBUS_ASSERT_ERROR_IS_SET (error);
01385       dbus_message_unref (reply);
01386       return FALSE;
01387     }
01388 
01389   if (result != NULL &&
01390       !dbus_message_get_args (reply, error, DBUS_TYPE_UINT32,
01391                               result, DBUS_TYPE_INVALID))
01392     {
01393       _DBUS_ASSERT_ERROR_IS_SET (error);
01394       dbus_message_unref (reply);
01395       return FALSE;
01396     }
01397   
01398   dbus_message_unref (reply);
01399   return TRUE;
01400 }
01401 
01402 static void
01403 send_no_return_values (DBusConnection *connection,
01404                        DBusMessage    *msg,
01405                        DBusError      *error)
01406 {
01407   if (error)
01408     {
01409       /* Block to check success codepath */
01410       DBusMessage *reply;
01411       
01412       reply = dbus_connection_send_with_reply_and_block (connection, msg,
01413                                                          -1, error);
01414       
01415       if (reply == NULL)
01416         _DBUS_ASSERT_ERROR_IS_SET (error);
01417       else
01418         dbus_message_unref (reply);
01419     }
01420   else
01421     {
01422       /* Silently-fail nonblocking codepath */
01423       dbus_message_set_no_reply (msg, TRUE);
01424       dbus_connection_send (connection, msg, NULL);
01425     }
01426 }
01427 
01510 void
01511 dbus_bus_add_match (DBusConnection *connection,
01512                     const char     *rule,
01513                     DBusError      *error)
01514 {
01515   DBusMessage *msg;
01516 
01517   _dbus_return_if_fail (rule != NULL);
01518 
01519   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01520                                       DBUS_PATH_DBUS,
01521                                       DBUS_INTERFACE_DBUS,
01522                                       "AddMatch");
01523 
01524   if (msg == NULL)
01525     {
01526       _DBUS_SET_OOM (error);
01527       return;
01528     }
01529 
01530   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
01531                                  DBUS_TYPE_INVALID))
01532     {
01533       dbus_message_unref (msg);
01534       _DBUS_SET_OOM (error);
01535       return;
01536     }
01537 
01538   send_no_return_values (connection, msg, error);
01539 
01540   dbus_message_unref (msg);
01541 }
01542 
01560 void
01561 dbus_bus_remove_match (DBusConnection *connection,
01562                        const char     *rule,
01563                        DBusError      *error)
01564 {
01565   DBusMessage *msg;
01566 
01567   _dbus_return_if_fail (rule != NULL);
01568   
01569   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01570                                       DBUS_PATH_DBUS,
01571                                       DBUS_INTERFACE_DBUS,
01572                                       "RemoveMatch");
01573 
01574   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
01575                                  DBUS_TYPE_INVALID))
01576     {
01577       dbus_message_unref (msg);
01578       _DBUS_SET_OOM (error);
01579       return;
01580     }
01581 
01582   send_no_return_values (connection, msg, error);
01583 
01584   dbus_message_unref (msg);
01585 }
01586 

Generated on Wed Nov 19 2014 17:15:20 for D-Bus by  doxygen 1.7.1