dbus-bus.c

00001 /* -*- mode: C; c-file-style: "gnu" -*- */
00002 /* dbus-bus.c  Convenience functions for communicating with the bus.
00003  *
00004  * Copyright (C) 2003  CodeFactory AB
00005  * Copyright (C) 2003  Red Hat, Inc.
00006  *
00007  * Licensed under the Academic Free License version 2.1
00008  * 
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  * 
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022  *
00023  */
00024 
00025 #include "dbus-bus.h"
00026 #include "dbus-protocol.h"
00027 #include "dbus-internals.h"
00028 #include "dbus-message.h"
00029 #include "dbus-marshal-validate.h"
00030 #include "dbus-threads-internal.h"
00031 #include "dbus-connection-internal.h"
00032 #include <string.h>
00033 
00075 typedef struct
00076 {
00077   DBusConnection *connection; 
00078   char *unique_name; 
00080   unsigned int is_well_known : 1; 
00081 } BusData;
00082 
00085 static dbus_int32_t bus_data_slot = -1;
00086 
00088 #define N_BUS_TYPES 3
00089 
00090 static DBusConnection *bus_connections[N_BUS_TYPES];
00091 static char *bus_connection_addresses[N_BUS_TYPES] = { NULL, NULL, NULL };
00092 
00093 static DBusBusType activation_bus_type = DBUS_BUS_STARTER;
00094 
00095 static dbus_bool_t initialized = FALSE;
00096 
00100 _DBUS_DEFINE_GLOBAL_LOCK (bus);
00101 
00108 _DBUS_DEFINE_GLOBAL_LOCK (bus_datas);
00109 
00110 static void
00111 addresses_shutdown_func (void *data)
00112 {
00113   int i;
00114 
00115   i = 0;
00116   while (i < N_BUS_TYPES)
00117     {
00118       if (bus_connections[i] != NULL)
00119         _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");
00120       
00121       dbus_free (bus_connection_addresses[i]);
00122       bus_connection_addresses[i] = NULL;
00123       ++i;
00124     }
00125 
00126   activation_bus_type = DBUS_BUS_STARTER;
00127 }
00128 
00129 static dbus_bool_t
00130 get_from_env (char           **connection_p,
00131               const char      *env_var)
00132 {
00133   const char *s;
00134   
00135   _dbus_assert (*connection_p == NULL);
00136   
00137   s = _dbus_getenv (env_var);
00138   if (s == NULL || *s == '\0')
00139     return TRUE; /* successfully didn't use the env var */
00140   else
00141     {
00142       *connection_p = _dbus_strdup (s);
00143       return *connection_p != NULL;
00144     }
00145 }
00146 
00147 static dbus_bool_t
00148 init_connections_unlocked (void)
00149 {
00150   if (!initialized)
00151     {
00152       const char *s;
00153       int i;
00154 
00155       i = 0;
00156       while (i < N_BUS_TYPES)
00157         {
00158           bus_connections[i] = NULL;
00159           ++i;
00160         }
00161 
00162       /* Don't init these twice, we may run this code twice if
00163        * init_connections_unlocked() fails midway through.
00164        * In practice, each block below should contain only one
00165        * "return FALSE" or running through twice may not
00166        * work right.
00167        */
00168       
00169        if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
00170          {
00171            _dbus_verbose ("Filling in system bus address...\n");
00172            
00173            if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SYSTEM],
00174                               "DBUS_SYSTEM_BUS_ADDRESS"))
00175              return FALSE;
00176          }
00177 
00178                   
00179        if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
00180          {
00181            /* Use default system bus address if none set in environment */
00182            bus_connection_addresses[DBUS_BUS_SYSTEM] =
00183              _dbus_strdup (DBUS_SYSTEM_BUS_DEFAULT_ADDRESS);
00184 
00185            if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
00186              return FALSE;
00187            
00188            _dbus_verbose ("  used default system bus \"%s\"\n",
00189                           bus_connection_addresses[DBUS_BUS_SYSTEM]);
00190          }
00191        else
00192          _dbus_verbose ("  used env var system bus \"%s\"\n",
00193                         bus_connection_addresses[DBUS_BUS_SYSTEM]);
00194           
00195       if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
00196         {
00197           _dbus_verbose ("Filling in session bus address...\n");
00198           
00199           if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SESSION],
00200                              "DBUS_SESSION_BUS_ADDRESS"))
00201             return FALSE;
00202 
00203           if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
00204             bus_connection_addresses[DBUS_BUS_SESSION] =
00205               _dbus_strdup (DBUS_SESSION_BUS_DEFAULT_ADDRESS);
00206           
00207           if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
00208              return FALSE;
00209 
00210           _dbus_verbose ("  \"%s\"\n", bus_connection_addresses[DBUS_BUS_SESSION] ?
00211                          bus_connection_addresses[DBUS_BUS_SESSION] : "none set");
00212         }
00213 
00214       if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
00215         {
00216           _dbus_verbose ("Filling in activation bus address...\n");
00217           
00218           if (!get_from_env (&bus_connection_addresses[DBUS_BUS_STARTER],
00219                              "DBUS_STARTER_ADDRESS"))
00220             return FALSE;
00221           
00222           _dbus_verbose ("  \"%s\"\n", bus_connection_addresses[DBUS_BUS_STARTER] ?
00223                          bus_connection_addresses[DBUS_BUS_STARTER] : "none set");
00224         }
00225 
00226 
00227       if (bus_connection_addresses[DBUS_BUS_STARTER] != NULL)
00228         {
00229           s = _dbus_getenv ("DBUS_STARTER_BUS_TYPE");
00230               
00231           if (s != NULL)
00232             {
00233               _dbus_verbose ("Bus activation type was set to \"%s\"\n", s);
00234                   
00235               if (strcmp (s, "system") == 0)
00236                 activation_bus_type = DBUS_BUS_SYSTEM;
00237               else if (strcmp (s, "session") == 0)
00238                 activation_bus_type = DBUS_BUS_SESSION;
00239             }
00240         }
00241       else
00242         {
00243           /* Default to the session bus instead if available */
00244           if (bus_connection_addresses[DBUS_BUS_SESSION] != NULL)
00245             {
00246               bus_connection_addresses[DBUS_BUS_STARTER] =
00247                 _dbus_strdup (bus_connection_addresses[DBUS_BUS_SESSION]);
00248               if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
00249                 return FALSE;
00250             }
00251         }
00252       
00253       /* If we return FALSE we have to be sure that restarting
00254        * the above code will work right
00255        */
00256       
00257       if (!_dbus_setenv ("DBUS_ACTIVATION_ADDRESS", NULL))
00258         return FALSE;
00259 
00260       if (!_dbus_setenv ("DBUS_ACTIVATION_BUS_TYPE", NULL))
00261         return FALSE;
00262       
00263       if (!_dbus_register_shutdown_func (addresses_shutdown_func,
00264                                          NULL))
00265         return FALSE;
00266       
00267       initialized = TRUE;
00268     }
00269 
00270   return initialized;
00271 }
00272 
00273 static void
00274 bus_data_free (void *data)
00275 {
00276   BusData *bd = data;
00277   
00278   if (bd->is_well_known)
00279     {
00280       int i;
00281       _DBUS_LOCK (bus);
00282       /* We may be stored in more than one slot */
00283       /* This should now be impossible - these slots are supposed to
00284        * be cleared on disconnect, so should not need to be cleared on
00285        * finalize
00286        */
00287       i = 0;
00288       while (i < N_BUS_TYPES)
00289         {
00290           if (bus_connections[i] == bd->connection)
00291             bus_connections[i] = NULL;
00292           
00293           ++i;
00294         }
00295       _DBUS_UNLOCK (bus);
00296     }
00297   
00298   dbus_free (bd->unique_name);
00299   dbus_free (bd);
00300 
00301   dbus_connection_free_data_slot (&bus_data_slot);
00302 }
00303 
00304 static BusData*
00305 ensure_bus_data (DBusConnection *connection)
00306 {
00307   BusData *bd;
00308 
00309   if (!dbus_connection_allocate_data_slot (&bus_data_slot))
00310     return NULL;
00311 
00312   bd = dbus_connection_get_data (connection, bus_data_slot);
00313   if (bd == NULL)
00314     {      
00315       bd = dbus_new0 (BusData, 1);
00316       if (bd == NULL)
00317         {
00318           dbus_connection_free_data_slot (&bus_data_slot);
00319           return NULL;
00320         }
00321 
00322       bd->connection = connection;
00323       
00324       if (!dbus_connection_set_data (connection, bus_data_slot, bd,
00325                                      bus_data_free))
00326         {
00327           dbus_free (bd);
00328           dbus_connection_free_data_slot (&bus_data_slot);
00329           return NULL;
00330         }
00331 
00332       /* Data slot refcount now held by the BusData */
00333     }
00334   else
00335     {
00336       dbus_connection_free_data_slot (&bus_data_slot);
00337     }
00338 
00339   return bd;
00340 }
00341 
00348 void
00349 _dbus_bus_notify_shared_connection_disconnected_unlocked (DBusConnection *connection)
00350 {
00351   int i;
00352   
00353   _DBUS_LOCK (bus);
00354 
00355   /* We are expecting to have the connection saved in only one of these
00356    * slots, but someone could in a pathological case set system and session
00357    * bus to the same bus or something. Or set one of them to the starter
00358    * bus without setting the starter bus type in the env variable.
00359    * So we don't break the loop as soon as we find a match.
00360    */
00361   for (i = 0; i < N_BUS_TYPES; ++i)
00362     {
00363       if (bus_connections[i] == connection)
00364         {
00365           bus_connections[i] = NULL;
00366         }
00367     }
00368 
00369   _DBUS_UNLOCK (bus);
00370 }
00371 
00372 static DBusConnection *
00373 internal_bus_get (DBusBusType  type,
00374                   dbus_bool_t  private,
00375                   DBusError   *error)
00376 {
00377   const char *address;
00378   DBusConnection *connection;
00379   BusData *bd;
00380   DBusBusType address_type;
00381 
00382   _dbus_return_val_if_fail (type >= 0 && type < N_BUS_TYPES, NULL);
00383   _dbus_return_val_if_error_is_set (error, NULL);
00384 
00385   _DBUS_LOCK (bus);
00386 
00387   if (!init_connections_unlocked ())
00388     {
00389       _DBUS_UNLOCK (bus);
00390       _DBUS_SET_OOM (error);
00391       return NULL;
00392     }
00393 
00394   /* We want to use the activation address even if the
00395    * activating bus is the session or system bus,
00396    * per the spec.
00397    */
00398   address_type = type;
00399   
00400   /* Use the real type of the activation bus for getting its
00401    * connection, but only if the real type's address is available. (If
00402    * the activating bus isn't a well-known bus then
00403    * activation_bus_type == DBUS_BUS_STARTER)
00404    */
00405   if (type == DBUS_BUS_STARTER &&
00406       bus_connection_addresses[activation_bus_type] != NULL)
00407     type = activation_bus_type;
00408   
00409   if (!private && bus_connections[type] != NULL)
00410     {
00411       connection = bus_connections[type];
00412       dbus_connection_ref (connection);
00413       
00414       _DBUS_UNLOCK (bus);
00415       return connection;
00416     }
00417 
00418   address = bus_connection_addresses[address_type];
00419   if (address == NULL)
00420     {
00421       dbus_set_error (error, DBUS_ERROR_FAILED,
00422                       "Unable to determine the address of the message bus (try 'man dbus-launch' and 'man dbus-daemon' for help)");
00423       _DBUS_UNLOCK (bus);
00424       return NULL;
00425     }
00426 
00427   if (private)
00428     connection = dbus_connection_open_private (address, error);
00429   else
00430     connection = dbus_connection_open (address, error);
00431   
00432   if (!connection)
00433     {
00434       _DBUS_ASSERT_ERROR_IS_SET (error);
00435       _DBUS_UNLOCK (bus);
00436       return NULL;
00437     }
00438 
00439   /* By default we're bound to the lifecycle of
00440    * the message bus.
00441    */
00442   dbus_connection_set_exit_on_disconnect (connection,
00443                                           TRUE);
00444   
00445   if (!dbus_bus_register (connection, error))
00446     {
00447       _DBUS_ASSERT_ERROR_IS_SET (error);
00448       _dbus_connection_close_possibly_shared (connection);
00449       dbus_connection_unref (connection);
00450 
00451       _DBUS_UNLOCK (bus);
00452       return NULL;
00453     }
00454 
00455   if (!private)
00456     {
00457       /* store a weak ref to the connection (dbus-connection.c is
00458        * supposed to have a strong ref that it drops on disconnect,
00459        * since this is a shared connection)
00460        */
00461       bus_connections[type] = connection;
00462     }
00463 
00464   _DBUS_LOCK (bus_datas);
00465   bd = ensure_bus_data (connection);
00466   _dbus_assert (bd != NULL); /* it should have been created on
00467                                 register, so OOM not possible */
00468   bd->is_well_known = TRUE;
00469   _DBUS_UNLOCK (bus_datas);
00470 
00471   
00472   _DBUS_UNLOCK (bus);
00473 
00474   /* Return a reference to the caller */
00475   return connection;
00476 }
00477 
00478  /* end of implementation details docs */
00480 
00511 DBusConnection *
00512 dbus_bus_get (DBusBusType  type,
00513               DBusError   *error)
00514 {
00515   return internal_bus_get (type, FALSE, error);
00516 }
00517 
00543 DBusConnection *
00544 dbus_bus_get_private (DBusBusType  type,
00545                       DBusError   *error)
00546 {
00547   return internal_bus_get (type, TRUE, error);
00548 }
00549 
00599 dbus_bool_t
00600 dbus_bus_register (DBusConnection *connection,
00601                    DBusError      *error)
00602 {
00603   DBusMessage *message, *reply;
00604   char *name;
00605   BusData *bd;
00606   dbus_bool_t retval;
00607 
00608   _dbus_return_val_if_fail (connection != NULL, FALSE);
00609   _dbus_return_val_if_error_is_set (error, FALSE);
00610 
00611   retval = FALSE;
00612 
00613   _DBUS_LOCK (bus_datas);
00614 
00615   bd = ensure_bus_data (connection);
00616   if (bd == NULL)
00617     {
00618       _DBUS_SET_OOM (error);
00619       _DBUS_UNLOCK (bus_datas);
00620       return FALSE;
00621     }
00622 
00623   if (bd->unique_name != NULL)
00624     {
00625       _dbus_verbose ("Ignoring attempt to register the same DBusConnection %s with the message bus a second time.\n",
00626                      bd->unique_name);
00627       _DBUS_UNLOCK (bus_datas);
00628 
00629       /* Success! */
00630       return TRUE;
00631     }
00632   
00633   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00634                                           DBUS_PATH_DBUS,
00635                                           DBUS_INTERFACE_DBUS,
00636                                           "Hello"); 
00637 
00638   if (!message)
00639     {
00640       _DBUS_SET_OOM (error);
00641 
00642       _DBUS_UNLOCK (bus_datas);
00643       return FALSE;
00644     }
00645   
00646   reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
00647 
00648   dbus_message_unref (message);
00649   
00650   if (reply == NULL)
00651     goto out;
00652   else if (dbus_set_error_from_message (error, reply))
00653     goto out;
00654   else if (!dbus_message_get_args (reply, error,
00655                                    DBUS_TYPE_STRING, &name,
00656                                    DBUS_TYPE_INVALID))
00657     goto out;
00658   
00659   bd->unique_name = _dbus_strdup (name);
00660   if (bd->unique_name == NULL)
00661     {
00662       _DBUS_SET_OOM (error);
00663       goto out;
00664     }
00665   
00666   retval = TRUE;
00667   
00668  out:
00669   if (reply)
00670     dbus_message_unref (reply);
00671 
00672   if (!retval)
00673     _DBUS_ASSERT_ERROR_IS_SET (error);
00674 
00675   _DBUS_UNLOCK (bus_datas);
00676   
00677   return retval;
00678 }
00679 
00680 
00715 dbus_bool_t
00716 dbus_bus_set_unique_name (DBusConnection *connection,
00717                           const char     *unique_name)
00718 {
00719   BusData *bd;
00720   dbus_bool_t success;
00721 
00722   _dbus_return_val_if_fail (connection != NULL, FALSE);
00723   _dbus_return_val_if_fail (unique_name != NULL, FALSE);
00724 
00725   _DBUS_LOCK (bus_datas);
00726   
00727   bd = ensure_bus_data (connection);
00728   if (bd == NULL)
00729     return FALSE;
00730 
00731   _dbus_assert (bd->unique_name == NULL);
00732   
00733   bd->unique_name = _dbus_strdup (unique_name);
00734   success = bd->unique_name != NULL;
00735   
00736   _DBUS_UNLOCK (bus_datas);
00737   
00738   return success;
00739 }
00740 
00759 const char*
00760 dbus_bus_get_unique_name (DBusConnection *connection)
00761 {
00762   BusData *bd;
00763   const char *unique_name;
00764 
00765   _dbus_return_val_if_fail (connection != NULL, NULL);
00766 
00767   _DBUS_LOCK (bus_datas);
00768   
00769   bd = ensure_bus_data (connection);
00770   if (bd == NULL)
00771     return NULL;
00772 
00773   unique_name = bd->unique_name;
00774 
00775   _DBUS_UNLOCK (bus_datas);
00776   
00777   return unique_name;
00778 }
00779 
00803 unsigned long
00804 dbus_bus_get_unix_user (DBusConnection *connection,
00805                         const char     *name,
00806                         DBusError      *error)
00807 {
00808   DBusMessage *message, *reply;
00809   dbus_uint32_t uid;
00810 
00811   _dbus_return_val_if_fail (connection != NULL, DBUS_UID_UNSET);
00812   _dbus_return_val_if_fail (name != NULL, DBUS_UID_UNSET);
00813   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), DBUS_UID_UNSET);
00814   _dbus_return_val_if_error_is_set (error, DBUS_UID_UNSET);
00815   
00816   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00817                                           DBUS_PATH_DBUS,
00818                                           DBUS_INTERFACE_DBUS,
00819                                           "GetConnectionUnixUser");
00820 
00821   if (message == NULL)
00822     {
00823       _DBUS_SET_OOM (error);
00824       return DBUS_UID_UNSET;
00825     }
00826  
00827   if (!dbus_message_append_args (message,
00828                                  DBUS_TYPE_STRING, &name,
00829                                  DBUS_TYPE_INVALID))
00830     {
00831       dbus_message_unref (message);
00832       _DBUS_SET_OOM (error);
00833       return DBUS_UID_UNSET;
00834     }
00835   
00836   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
00837                                                      error);
00838   
00839   dbus_message_unref (message);
00840   
00841   if (reply == NULL)
00842     {
00843       _DBUS_ASSERT_ERROR_IS_SET (error);
00844       return DBUS_UID_UNSET;
00845     }  
00846 
00847   if (dbus_set_error_from_message (error, reply))
00848     {
00849       _DBUS_ASSERT_ERROR_IS_SET (error);
00850       dbus_message_unref (reply);
00851       return DBUS_UID_UNSET;
00852     }
00853   
00854   if (!dbus_message_get_args (reply, error,
00855                               DBUS_TYPE_UINT32, &uid,
00856                               DBUS_TYPE_INVALID))
00857     {
00858       _DBUS_ASSERT_ERROR_IS_SET (error);
00859       dbus_message_unref (reply);
00860       return DBUS_UID_UNSET;
00861     }
00862 
00863   dbus_message_unref (reply);
00864   
00865   return (unsigned long) uid;
00866 }
00867 
00868 
00971 int
00972 dbus_bus_request_name (DBusConnection *connection,
00973                        const char     *name,
00974                        unsigned int    flags,
00975                        DBusError      *error)
00976 {
00977   DBusMessage *message, *reply;
00978   dbus_uint32_t result;
00979 
00980   _dbus_return_val_if_fail (connection != NULL, 0);
00981   _dbus_return_val_if_fail (name != NULL, 0);
00982   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
00983   _dbus_return_val_if_error_is_set (error, 0);
00984   
00985   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00986                                           DBUS_PATH_DBUS,
00987                                           DBUS_INTERFACE_DBUS,
00988                                           "RequestName");
00989 
00990   if (message == NULL)
00991     {
00992       _DBUS_SET_OOM (error);
00993       return -1;
00994     }
00995  
00996   if (!dbus_message_append_args (message,
00997                                  DBUS_TYPE_STRING, &name,
00998                                  DBUS_TYPE_UINT32, &flags,
00999                                  DBUS_TYPE_INVALID))
01000     {
01001       dbus_message_unref (message);
01002       _DBUS_SET_OOM (error);
01003       return -1;
01004     }
01005   
01006   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
01007                                                      error);
01008   
01009   dbus_message_unref (message);
01010   
01011   if (reply == NULL)
01012     {
01013       _DBUS_ASSERT_ERROR_IS_SET (error);
01014       return -1;
01015     }  
01016 
01017   if (dbus_set_error_from_message (error, reply))
01018     {
01019       _DBUS_ASSERT_ERROR_IS_SET (error);
01020       dbus_message_unref (reply);
01021       return -1;
01022     }
01023   
01024   if (!dbus_message_get_args (reply, error,
01025                               DBUS_TYPE_UINT32, &result,
01026                               DBUS_TYPE_INVALID))
01027     {
01028       _DBUS_ASSERT_ERROR_IS_SET (error);
01029       dbus_message_unref (reply);
01030       return -1;
01031     }
01032 
01033   dbus_message_unref (reply);
01034   
01035   return result;
01036 }
01037 
01038 
01057 int
01058 dbus_bus_release_name (DBusConnection *connection,
01059                        const char     *name,
01060                        DBusError      *error)
01061 {
01062   DBusMessage *message, *reply;
01063   dbus_uint32_t result;
01064 
01065   _dbus_return_val_if_fail (connection != NULL, 0);
01066   _dbus_return_val_if_fail (name != NULL, 0);
01067   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
01068   _dbus_return_val_if_error_is_set (error, 0);
01069 
01070   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01071                                           DBUS_PATH_DBUS,
01072                                           DBUS_INTERFACE_DBUS,
01073                                           "ReleaseName");
01074 
01075   if (message == NULL)
01076     {
01077       _DBUS_SET_OOM (error);
01078       return -1;
01079     }
01080 
01081   if (!dbus_message_append_args (message,
01082                                  DBUS_TYPE_STRING, &name,
01083                                  DBUS_TYPE_INVALID))
01084     {
01085       dbus_message_unref (message);
01086       _DBUS_SET_OOM (error);
01087       return -1;
01088     }
01089 
01090   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
01091                                                      error);
01092 
01093   dbus_message_unref (message);
01094 
01095   if (reply == NULL)
01096     {
01097       _DBUS_ASSERT_ERROR_IS_SET (error);
01098       return -1;
01099     }
01100 
01101   if (dbus_set_error_from_message (error, reply))
01102     {
01103       _DBUS_ASSERT_ERROR_IS_SET (error);
01104       dbus_message_unref (reply);
01105       return -1;
01106     }
01107 
01108   if (!dbus_message_get_args (reply, error,
01109                               DBUS_TYPE_UINT32, &result,
01110                               DBUS_TYPE_INVALID))
01111     {
01112       _DBUS_ASSERT_ERROR_IS_SET (error);
01113       dbus_message_unref (reply);
01114       return -1;
01115     }
01116 
01117   dbus_message_unref (reply);
01118 
01119   return result;
01120 }
01121 
01139 dbus_bool_t
01140 dbus_bus_name_has_owner (DBusConnection *connection,
01141                          const char     *name,
01142                          DBusError      *error)
01143 {
01144   DBusMessage *message, *reply;
01145   dbus_bool_t exists;
01146 
01147   _dbus_return_val_if_fail (connection != NULL, FALSE);
01148   _dbus_return_val_if_fail (name != NULL, FALSE);
01149   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
01150   _dbus_return_val_if_error_is_set (error, FALSE);
01151   
01152   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01153                                           DBUS_PATH_DBUS,
01154                                           DBUS_INTERFACE_DBUS,
01155                                           "NameHasOwner");
01156   if (message == NULL)
01157     {
01158       _DBUS_SET_OOM (error);
01159       return FALSE;
01160     }
01161   
01162   if (!dbus_message_append_args (message,
01163                                  DBUS_TYPE_STRING, &name,
01164                                  DBUS_TYPE_INVALID))
01165     {
01166       dbus_message_unref (message);
01167       _DBUS_SET_OOM (error);
01168       return FALSE;
01169     }
01170   
01171   reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
01172   dbus_message_unref (message);
01173 
01174   if (reply == NULL)
01175     {
01176       _DBUS_ASSERT_ERROR_IS_SET (error);
01177       return FALSE;
01178     }
01179 
01180   if (!dbus_message_get_args (reply, error,
01181                               DBUS_TYPE_BOOLEAN, &exists,
01182                               DBUS_TYPE_INVALID))
01183     {
01184       _DBUS_ASSERT_ERROR_IS_SET (error);
01185       dbus_message_unref (reply);
01186       return FALSE;
01187     }
01188   
01189   dbus_message_unref (reply);
01190   return exists;
01191 }
01192 
01215 dbus_bool_t
01216 dbus_bus_start_service_by_name (DBusConnection *connection,
01217                                 const char     *name,
01218                                 dbus_uint32_t   flags,
01219                                 dbus_uint32_t  *result,
01220                                 DBusError      *error)
01221 {
01222   DBusMessage *msg;
01223   DBusMessage *reply;
01224 
01225   _dbus_return_val_if_fail (connection != NULL, FALSE);
01226   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
01227   
01228   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01229                                       DBUS_PATH_DBUS,
01230                                       DBUS_INTERFACE_DBUS,
01231                                       "StartServiceByName");
01232 
01233   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name,
01234                                  DBUS_TYPE_UINT32, &flags, DBUS_TYPE_INVALID))
01235     {
01236       dbus_message_unref (msg);
01237       _DBUS_SET_OOM (error);
01238       return FALSE;
01239     }
01240 
01241   reply = dbus_connection_send_with_reply_and_block (connection, msg,
01242                                                      -1, error);
01243   dbus_message_unref (msg);
01244 
01245   if (reply == NULL)
01246     {
01247       _DBUS_ASSERT_ERROR_IS_SET (error);
01248       return FALSE;
01249     }
01250 
01251   if (dbus_set_error_from_message (error, reply))
01252     {
01253       _DBUS_ASSERT_ERROR_IS_SET (error);
01254       dbus_message_unref (reply);
01255       return FALSE;
01256     }
01257 
01258   if (result != NULL &&
01259       !dbus_message_get_args (reply, error, DBUS_TYPE_UINT32,
01260                               result, DBUS_TYPE_INVALID))
01261     {
01262       _DBUS_ASSERT_ERROR_IS_SET (error);
01263       dbus_message_unref (reply);
01264       return FALSE;
01265     }
01266   
01267   dbus_message_unref (reply);
01268   return TRUE;
01269 }
01270 
01271 static void
01272 send_no_return_values (DBusConnection *connection,
01273                        DBusMessage    *msg,
01274                        DBusError      *error)
01275 {
01276   if (error)
01277     {
01278       /* Block to check success codepath */
01279       DBusMessage *reply;
01280       
01281       reply = dbus_connection_send_with_reply_and_block (connection, msg,
01282                                                          -1, error);
01283       
01284       if (reply == NULL)
01285         _DBUS_ASSERT_ERROR_IS_SET (error);
01286       else
01287         dbus_message_unref (reply);
01288     }
01289   else
01290     {
01291       /* Silently-fail nonblocking codepath */
01292       dbus_message_set_no_reply (msg, TRUE);
01293       dbus_connection_send (connection, msg, NULL);
01294     }
01295 }
01296 
01372 void
01373 dbus_bus_add_match (DBusConnection *connection,
01374                     const char     *rule,
01375                     DBusError      *error)
01376 {
01377   DBusMessage *msg;
01378 
01379   _dbus_return_if_fail (rule != NULL);
01380 
01381   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01382                                       DBUS_PATH_DBUS,
01383                                       DBUS_INTERFACE_DBUS,
01384                                       "AddMatch");
01385 
01386   if (msg == NULL)
01387     {
01388       _DBUS_SET_OOM (error);
01389       return;
01390     }
01391 
01392   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
01393                                  DBUS_TYPE_INVALID))
01394     {
01395       dbus_message_unref (msg);
01396       _DBUS_SET_OOM (error);
01397       return;
01398     }
01399 
01400   send_no_return_values (connection, msg, error);
01401 
01402   dbus_message_unref (msg);
01403 }
01404 
01422 void
01423 dbus_bus_remove_match (DBusConnection *connection,
01424                        const char     *rule,
01425                        DBusError      *error)
01426 {
01427   DBusMessage *msg;
01428 
01429   _dbus_return_if_fail (rule != NULL);
01430   
01431   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01432                                       DBUS_PATH_DBUS,
01433                                       DBUS_INTERFACE_DBUS,
01434                                       "RemoveMatch");
01435 
01436   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
01437                                  DBUS_TYPE_INVALID))
01438     {
01439       dbus_message_unref (msg);
01440       _DBUS_SET_OOM (error);
01441       return;
01442     }
01443 
01444   send_no_return_values (connection, msg, error);
01445 
01446   dbus_message_unref (msg);
01447 }
01448 

Generated on Fri Sep 21 18:12:11 2007 for D-Bus by  doxygen 1.5.1