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., 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   initialized = FALSE;
00129 }
00130 
00131 static dbus_bool_t
00132 get_from_env (char           **connection_p,
00133               const char      *env_var)
00134 {
00135   const char *s;
00136   
00137   _dbus_assert (*connection_p == NULL);
00138   
00139   s = _dbus_getenv (env_var);
00140   if (s == NULL || *s == '\0')
00141     return TRUE; /* successfully didn't use the env var */
00142   else
00143     {
00144       *connection_p = _dbus_strdup (s);
00145       return *connection_p != NULL;
00146     }
00147 }
00148 
00149 static dbus_bool_t
00150 init_connections_unlocked (void)
00151 {
00152   if (!initialized)
00153     {
00154       const char *s;
00155       int i;
00156 
00157       i = 0;
00158       while (i < N_BUS_TYPES)
00159         {
00160           bus_connections[i] = NULL;
00161           ++i;
00162         }
00163 
00164       /* Don't init these twice, we may run this code twice if
00165        * init_connections_unlocked() fails midway through.
00166        * In practice, each block below should contain only one
00167        * "return FALSE" or running through twice may not
00168        * work right.
00169        */
00170       
00171        if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
00172          {
00173            _dbus_verbose ("Filling in system bus address...\n");
00174            
00175            if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SYSTEM],
00176                               "DBUS_SYSTEM_BUS_ADDRESS"))
00177              return FALSE;
00178          }
00179 
00180                   
00181        if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
00182          {
00183            /* Use default system bus address if none set in environment */
00184            bus_connection_addresses[DBUS_BUS_SYSTEM] =
00185              _dbus_strdup (DBUS_SYSTEM_BUS_DEFAULT_ADDRESS);
00186 
00187            if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
00188              return FALSE;
00189            
00190            _dbus_verbose ("  used default system bus \"%s\"\n",
00191                           bus_connection_addresses[DBUS_BUS_SYSTEM]);
00192          }
00193        else
00194          _dbus_verbose ("  used env var system bus \"%s\"\n",
00195                         bus_connection_addresses[DBUS_BUS_SYSTEM]);
00196           
00197       if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
00198         {
00199           _dbus_verbose ("Filling in session bus address...\n");
00200           
00201           if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SESSION],
00202                              "DBUS_SESSION_BUS_ADDRESS"))
00203             return FALSE;
00204 
00205           if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
00206             bus_connection_addresses[DBUS_BUS_SESSION] =
00207               _dbus_strdup (DBUS_SESSION_BUS_DEFAULT_ADDRESS);
00208           
00209           if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
00210              return FALSE;
00211 
00212           _dbus_verbose ("  \"%s\"\n", bus_connection_addresses[DBUS_BUS_SESSION] ?
00213                          bus_connection_addresses[DBUS_BUS_SESSION] : "none set");
00214         }
00215 
00216       if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
00217         {
00218           _dbus_verbose ("Filling in activation bus address...\n");
00219           
00220           if (!get_from_env (&bus_connection_addresses[DBUS_BUS_STARTER],
00221                              "DBUS_STARTER_ADDRESS"))
00222             return FALSE;
00223           
00224           _dbus_verbose ("  \"%s\"\n", bus_connection_addresses[DBUS_BUS_STARTER] ?
00225                          bus_connection_addresses[DBUS_BUS_STARTER] : "none set");
00226         }
00227 
00228 
00229       if (bus_connection_addresses[DBUS_BUS_STARTER] != NULL)
00230         {
00231           s = _dbus_getenv ("DBUS_STARTER_BUS_TYPE");
00232               
00233           if (s != NULL)
00234             {
00235               _dbus_verbose ("Bus activation type was set to \"%s\"\n", s);
00236                   
00237               if (strcmp (s, "system") == 0)
00238                 activation_bus_type = DBUS_BUS_SYSTEM;
00239               else if (strcmp (s, "session") == 0)
00240                 activation_bus_type = DBUS_BUS_SESSION;
00241             }
00242         }
00243       else
00244         {
00245           /* Default to the session bus instead if available */
00246           if (bus_connection_addresses[DBUS_BUS_SESSION] != NULL)
00247             {
00248               bus_connection_addresses[DBUS_BUS_STARTER] =
00249                 _dbus_strdup (bus_connection_addresses[DBUS_BUS_SESSION]);
00250               if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
00251                 return FALSE;
00252             }
00253         }
00254       
00255       /* If we return FALSE we have to be sure that restarting
00256        * the above code will work right
00257        */
00258       
00259       if (!_dbus_setenv ("DBUS_ACTIVATION_ADDRESS", NULL))
00260         return FALSE;
00261 
00262       if (!_dbus_setenv ("DBUS_ACTIVATION_BUS_TYPE", NULL))
00263         return FALSE;
00264       
00265       if (!_dbus_register_shutdown_func (addresses_shutdown_func,
00266                                          NULL))
00267         return FALSE;
00268       
00269       initialized = TRUE;
00270     }
00271 
00272   return initialized;
00273 }
00274 
00275 static void
00276 bus_data_free (void *data)
00277 {
00278   BusData *bd = data;
00279   
00280   if (bd->is_well_known)
00281     {
00282       int i;
00283       _DBUS_LOCK (bus);
00284       /* We may be stored in more than one slot */
00285       /* This should now be impossible - these slots are supposed to
00286        * be cleared on disconnect, so should not need to be cleared on
00287        * finalize
00288        */
00289       i = 0;
00290       while (i < N_BUS_TYPES)
00291         {
00292           if (bus_connections[i] == bd->connection)
00293             bus_connections[i] = NULL;
00294           
00295           ++i;
00296         }
00297       _DBUS_UNLOCK (bus);
00298     }
00299   
00300   dbus_free (bd->unique_name);
00301   dbus_free (bd);
00302 
00303   dbus_connection_free_data_slot (&bus_data_slot);
00304 }
00305 
00306 static BusData*
00307 ensure_bus_data (DBusConnection *connection)
00308 {
00309   BusData *bd;
00310 
00311   if (!dbus_connection_allocate_data_slot (&bus_data_slot))
00312     return NULL;
00313 
00314   bd = dbus_connection_get_data (connection, bus_data_slot);
00315   if (bd == NULL)
00316     {      
00317       bd = dbus_new0 (BusData, 1);
00318       if (bd == NULL)
00319         {
00320           dbus_connection_free_data_slot (&bus_data_slot);
00321           return NULL;
00322         }
00323 
00324       bd->connection = connection;
00325       
00326       if (!dbus_connection_set_data (connection, bus_data_slot, bd,
00327                                      bus_data_free))
00328         {
00329           dbus_free (bd);
00330           dbus_connection_free_data_slot (&bus_data_slot);
00331           return NULL;
00332         }
00333 
00334       /* Data slot refcount now held by the BusData */
00335     }
00336   else
00337     {
00338       dbus_connection_free_data_slot (&bus_data_slot);
00339     }
00340 
00341   return bd;
00342 }
00343 
00350 void
00351 _dbus_bus_notify_shared_connection_disconnected_unlocked (DBusConnection *connection)
00352 {
00353   int i;
00354   
00355   _DBUS_LOCK (bus);
00356 
00357   /* We are expecting to have the connection saved in only one of these
00358    * slots, but someone could in a pathological case set system and session
00359    * bus to the same bus or something. Or set one of them to the starter
00360    * bus without setting the starter bus type in the env variable.
00361    * So we don't break the loop as soon as we find a match.
00362    */
00363   for (i = 0; i < N_BUS_TYPES; ++i)
00364     {
00365       if (bus_connections[i] == connection)
00366         {
00367           bus_connections[i] = NULL;
00368         }
00369     }
00370 
00371   _DBUS_UNLOCK (bus);
00372 }
00373 
00374 static DBusConnection *
00375 internal_bus_get (DBusBusType  type,
00376                   dbus_bool_t  private,
00377                   DBusError   *error)
00378 {
00379   const char *address;
00380   DBusConnection *connection;
00381   BusData *bd;
00382   DBusBusType address_type;
00383 
00384   _dbus_return_val_if_fail (type >= 0 && type < N_BUS_TYPES, NULL);
00385   _dbus_return_val_if_error_is_set (error, NULL);
00386 
00387   _DBUS_LOCK (bus);
00388 
00389   if (!init_connections_unlocked ())
00390     {
00391       _DBUS_UNLOCK (bus);
00392       _DBUS_SET_OOM (error);
00393       return NULL;
00394     }
00395 
00396   /* We want to use the activation address even if the
00397    * activating bus is the session or system bus,
00398    * per the spec.
00399    */
00400   address_type = type;
00401   
00402   /* Use the real type of the activation bus for getting its
00403    * connection, but only if the real type's address is available. (If
00404    * the activating bus isn't a well-known bus then
00405    * activation_bus_type == DBUS_BUS_STARTER)
00406    */
00407   if (type == DBUS_BUS_STARTER &&
00408       bus_connection_addresses[activation_bus_type] != NULL)
00409     type = activation_bus_type;
00410   
00411   if (!private && bus_connections[type] != NULL)
00412     {
00413       connection = bus_connections[type];
00414       dbus_connection_ref (connection);
00415       
00416       _DBUS_UNLOCK (bus);
00417       return connection;
00418     }
00419 
00420   address = bus_connection_addresses[address_type];
00421   if (address == NULL)
00422     {
00423       dbus_set_error (error, DBUS_ERROR_FAILED,
00424                       "Unable to determine the address of the message bus (try 'man dbus-launch' and 'man dbus-daemon' for help)");
00425       _DBUS_UNLOCK (bus);
00426       return NULL;
00427     }
00428 
00429   if (private)
00430     connection = dbus_connection_open_private (address, error);
00431   else
00432     connection = dbus_connection_open (address, error);
00433   
00434   if (!connection)
00435     {
00436       _DBUS_ASSERT_ERROR_IS_SET (error);
00437       _DBUS_UNLOCK (bus);
00438       return NULL;
00439     }
00440 
00441   if (!dbus_bus_register (connection, error))
00442     {
00443       _DBUS_ASSERT_ERROR_IS_SET (error);
00444       _dbus_connection_close_possibly_shared (connection);
00445       dbus_connection_unref (connection);
00446 
00447       _DBUS_UNLOCK (bus);
00448       return NULL;
00449     }
00450 
00451   if (!private)
00452     {
00453       /* store a weak ref to the connection (dbus-connection.c is
00454        * supposed to have a strong ref that it drops on disconnect,
00455        * since this is a shared connection)
00456        */
00457       bus_connections[type] = connection;
00458     }
00459 
00460   /* By default we're bound to the lifecycle of
00461    * the message bus.
00462    */
00463   dbus_connection_set_exit_on_disconnect (connection,
00464                                           TRUE);
00465  
00466   _DBUS_LOCK (bus_datas);
00467   bd = ensure_bus_data (connection);
00468   _dbus_assert (bd != NULL); /* it should have been created on
00469                                 register, so OOM not possible */
00470   bd->is_well_known = TRUE;
00471   _DBUS_UNLOCK (bus_datas);
00472 
00473   
00474   _DBUS_UNLOCK (bus);
00475 
00476   /* Return a reference to the caller */
00477   return connection;
00478 }
00479 
00480  /* end of implementation details docs */
00482 
00513 DBusConnection *
00514 dbus_bus_get (DBusBusType  type,
00515               DBusError   *error)
00516 {
00517   return internal_bus_get (type, FALSE, error);
00518 }
00519 
00545 DBusConnection *
00546 dbus_bus_get_private (DBusBusType  type,
00547                       DBusError   *error)
00548 {
00549   return internal_bus_get (type, TRUE, error);
00550 }
00551 
00601 dbus_bool_t
00602 dbus_bus_register (DBusConnection *connection,
00603                    DBusError      *error)
00604 {
00605   DBusMessage *message, *reply;
00606   char *name;
00607   BusData *bd;
00608   dbus_bool_t retval;
00609 
00610   _dbus_return_val_if_fail (connection != NULL, FALSE);
00611   _dbus_return_val_if_error_is_set (error, FALSE);
00612 
00613   retval = FALSE;
00614 
00615   _DBUS_LOCK (bus_datas);
00616 
00617   bd = ensure_bus_data (connection);
00618   if (bd == NULL)
00619     {
00620       _DBUS_SET_OOM (error);
00621       _DBUS_UNLOCK (bus_datas);
00622       return FALSE;
00623     }
00624 
00625   if (bd->unique_name != NULL)
00626     {
00627       _dbus_verbose ("Ignoring attempt to register the same DBusConnection %s with the message bus a second time.\n",
00628                      bd->unique_name);
00629       _DBUS_UNLOCK (bus_datas);
00630 
00631       /* Success! */
00632       return TRUE;
00633     }
00634   
00635   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00636                                           DBUS_PATH_DBUS,
00637                                           DBUS_INTERFACE_DBUS,
00638                                           "Hello"); 
00639 
00640   if (!message)
00641     {
00642       _DBUS_SET_OOM (error);
00643 
00644       _DBUS_UNLOCK (bus_datas);
00645       return FALSE;
00646     }
00647   
00648   reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
00649 
00650   dbus_message_unref (message);
00651   
00652   if (reply == NULL)
00653     goto out;
00654   else if (dbus_set_error_from_message (error, reply))
00655     goto out;
00656   else if (!dbus_message_get_args (reply, error,
00657                                    DBUS_TYPE_STRING, &name,
00658                                    DBUS_TYPE_INVALID))
00659     goto out;
00660   
00661   bd->unique_name = _dbus_strdup (name);
00662   if (bd->unique_name == NULL)
00663     {
00664       _DBUS_SET_OOM (error);
00665       goto out;
00666     }
00667   
00668   retval = TRUE;
00669   
00670  out:
00671   if (reply)
00672     dbus_message_unref (reply);
00673 
00674   if (!retval)
00675     _DBUS_ASSERT_ERROR_IS_SET (error);
00676 
00677   _DBUS_UNLOCK (bus_datas);
00678   
00679   return retval;
00680 }
00681 
00682 
00717 dbus_bool_t
00718 dbus_bus_set_unique_name (DBusConnection *connection,
00719                           const char     *unique_name)
00720 {
00721   BusData *bd;
00722   dbus_bool_t success;
00723 
00724   _dbus_return_val_if_fail (connection != NULL, FALSE);
00725   _dbus_return_val_if_fail (unique_name != NULL, FALSE);
00726 
00727   _DBUS_LOCK (bus_datas);
00728   
00729   bd = ensure_bus_data (connection);
00730   if (bd == NULL)
00731     return FALSE;
00732 
00733   _dbus_assert (bd->unique_name == NULL);
00734   
00735   bd->unique_name = _dbus_strdup (unique_name);
00736   success = bd->unique_name != NULL;
00737   
00738   _DBUS_UNLOCK (bus_datas);
00739   
00740   return success;
00741 }
00742 
00761 const char*
00762 dbus_bus_get_unique_name (DBusConnection *connection)
00763 {
00764   BusData *bd;
00765   const char *unique_name;
00766 
00767   _dbus_return_val_if_fail (connection != NULL, NULL);
00768 
00769   _DBUS_LOCK (bus_datas);
00770   
00771   bd = ensure_bus_data (connection);
00772   if (bd == NULL)
00773     return NULL;
00774 
00775   unique_name = bd->unique_name;
00776 
00777   _DBUS_UNLOCK (bus_datas);
00778   
00779   return unique_name;
00780 }
00781 
00805 unsigned long
00806 dbus_bus_get_unix_user (DBusConnection *connection,
00807                         const char     *name,
00808                         DBusError      *error)
00809 {
00810   DBusMessage *message, *reply;
00811   dbus_uint32_t uid;
00812 
00813   _dbus_return_val_if_fail (connection != NULL, DBUS_UID_UNSET);
00814   _dbus_return_val_if_fail (name != NULL, DBUS_UID_UNSET);
00815   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), DBUS_UID_UNSET);
00816   _dbus_return_val_if_error_is_set (error, DBUS_UID_UNSET);
00817   
00818   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00819                                           DBUS_PATH_DBUS,
00820                                           DBUS_INTERFACE_DBUS,
00821                                           "GetConnectionUnixUser");
00822 
00823   if (message == NULL)
00824     {
00825       _DBUS_SET_OOM (error);
00826       return DBUS_UID_UNSET;
00827     }
00828  
00829   if (!dbus_message_append_args (message,
00830                                  DBUS_TYPE_STRING, &name,
00831                                  DBUS_TYPE_INVALID))
00832     {
00833       dbus_message_unref (message);
00834       _DBUS_SET_OOM (error);
00835       return DBUS_UID_UNSET;
00836     }
00837   
00838   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
00839                                                      error);
00840   
00841   dbus_message_unref (message);
00842   
00843   if (reply == NULL)
00844     {
00845       _DBUS_ASSERT_ERROR_IS_SET (error);
00846       return DBUS_UID_UNSET;
00847     }  
00848 
00849   if (dbus_set_error_from_message (error, reply))
00850     {
00851       _DBUS_ASSERT_ERROR_IS_SET (error);
00852       dbus_message_unref (reply);
00853       return DBUS_UID_UNSET;
00854     }
00855   
00856   if (!dbus_message_get_args (reply, error,
00857                               DBUS_TYPE_UINT32, &uid,
00858                               DBUS_TYPE_INVALID))
00859     {
00860       _DBUS_ASSERT_ERROR_IS_SET (error);
00861       dbus_message_unref (reply);
00862       return DBUS_UID_UNSET;
00863     }
00864 
00865   dbus_message_unref (reply);
00866   
00867   return (unsigned long) uid;
00868 }
00869 
00888 char*
00889 dbus_bus_get_id (DBusConnection *connection,
00890                  DBusError      *error)
00891 {
00892   DBusMessage *message, *reply;
00893   char *id;
00894   const char *v_STRING;
00895 
00896   _dbus_return_val_if_fail (connection != NULL, NULL);
00897   _dbus_return_val_if_error_is_set (error, NULL);
00898   
00899   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00900                                           DBUS_PATH_DBUS,
00901                                           DBUS_INTERFACE_DBUS,
00902                                           "GetId");
00903   
00904   if (message == NULL)
00905     {
00906       _DBUS_SET_OOM (error);
00907       return NULL;
00908     }
00909   
00910   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
00911                                                      error);
00912   
00913   dbus_message_unref (message);
00914   
00915   if (reply == NULL)
00916     {
00917       _DBUS_ASSERT_ERROR_IS_SET (error);
00918       return NULL;
00919     }  
00920 
00921   if (dbus_set_error_from_message (error, reply))
00922     {
00923       _DBUS_ASSERT_ERROR_IS_SET (error);
00924       dbus_message_unref (reply);
00925       return NULL;
00926     }
00927 
00928   v_STRING = NULL;
00929   if (!dbus_message_get_args (reply, error,
00930                               DBUS_TYPE_STRING, &v_STRING,
00931                               DBUS_TYPE_INVALID))
00932     {
00933       _DBUS_ASSERT_ERROR_IS_SET (error);
00934       dbus_message_unref (reply);
00935       return NULL;
00936     }
00937 
00938   id = _dbus_strdup (v_STRING); /* may be NULL */
00939   
00940   dbus_message_unref (reply);
00941 
00942   if (id == NULL)
00943     _DBUS_SET_OOM (error);
00944 
00945   /* FIXME it might be nice to cache the ID locally */
00946   
00947   return id;
00948 }
00949 
01052 int
01053 dbus_bus_request_name (DBusConnection *connection,
01054                        const char     *name,
01055                        unsigned int    flags,
01056                        DBusError      *error)
01057 {
01058   DBusMessage *message, *reply;
01059   dbus_uint32_t result;
01060 
01061   _dbus_return_val_if_fail (connection != NULL, 0);
01062   _dbus_return_val_if_fail (name != NULL, 0);
01063   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
01064   _dbus_return_val_if_error_is_set (error, 0);
01065   
01066   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01067                                           DBUS_PATH_DBUS,
01068                                           DBUS_INTERFACE_DBUS,
01069                                           "RequestName");
01070 
01071   if (message == NULL)
01072     {
01073       _DBUS_SET_OOM (error);
01074       return -1;
01075     }
01076  
01077   if (!dbus_message_append_args (message,
01078                                  DBUS_TYPE_STRING, &name,
01079                                  DBUS_TYPE_UINT32, &flags,
01080                                  DBUS_TYPE_INVALID))
01081     {
01082       dbus_message_unref (message);
01083       _DBUS_SET_OOM (error);
01084       return -1;
01085     }
01086   
01087   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
01088                                                      error);
01089   
01090   dbus_message_unref (message);
01091   
01092   if (reply == NULL)
01093     {
01094       _DBUS_ASSERT_ERROR_IS_SET (error);
01095       return -1;
01096     }  
01097 
01098   if (dbus_set_error_from_message (error, reply))
01099     {
01100       _DBUS_ASSERT_ERROR_IS_SET (error);
01101       dbus_message_unref (reply);
01102       return -1;
01103     }
01104   
01105   if (!dbus_message_get_args (reply, error,
01106                               DBUS_TYPE_UINT32, &result,
01107                               DBUS_TYPE_INVALID))
01108     {
01109       _DBUS_ASSERT_ERROR_IS_SET (error);
01110       dbus_message_unref (reply);
01111       return -1;
01112     }
01113 
01114   dbus_message_unref (reply);
01115   
01116   return result;
01117 }
01118 
01119 
01138 int
01139 dbus_bus_release_name (DBusConnection *connection,
01140                        const char     *name,
01141                        DBusError      *error)
01142 {
01143   DBusMessage *message, *reply;
01144   dbus_uint32_t result;
01145 
01146   _dbus_return_val_if_fail (connection != NULL, 0);
01147   _dbus_return_val_if_fail (name != NULL, 0);
01148   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
01149   _dbus_return_val_if_error_is_set (error, 0);
01150 
01151   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01152                                           DBUS_PATH_DBUS,
01153                                           DBUS_INTERFACE_DBUS,
01154                                           "ReleaseName");
01155 
01156   if (message == NULL)
01157     {
01158       _DBUS_SET_OOM (error);
01159       return -1;
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 -1;
01169     }
01170 
01171   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
01172                                                      error);
01173 
01174   dbus_message_unref (message);
01175 
01176   if (reply == NULL)
01177     {
01178       _DBUS_ASSERT_ERROR_IS_SET (error);
01179       return -1;
01180     }
01181 
01182   if (dbus_set_error_from_message (error, reply))
01183     {
01184       _DBUS_ASSERT_ERROR_IS_SET (error);
01185       dbus_message_unref (reply);
01186       return -1;
01187     }
01188 
01189   if (!dbus_message_get_args (reply, error,
01190                               DBUS_TYPE_UINT32, &result,
01191                               DBUS_TYPE_INVALID))
01192     {
01193       _DBUS_ASSERT_ERROR_IS_SET (error);
01194       dbus_message_unref (reply);
01195       return -1;
01196     }
01197 
01198   dbus_message_unref (reply);
01199 
01200   return result;
01201 }
01202 
01220 dbus_bool_t
01221 dbus_bus_name_has_owner (DBusConnection *connection,
01222                          const char     *name,
01223                          DBusError      *error)
01224 {
01225   DBusMessage *message, *reply;
01226   dbus_bool_t exists;
01227 
01228   _dbus_return_val_if_fail (connection != NULL, FALSE);
01229   _dbus_return_val_if_fail (name != NULL, FALSE);
01230   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
01231   _dbus_return_val_if_error_is_set (error, FALSE);
01232   
01233   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01234                                           DBUS_PATH_DBUS,
01235                                           DBUS_INTERFACE_DBUS,
01236                                           "NameHasOwner");
01237   if (message == NULL)
01238     {
01239       _DBUS_SET_OOM (error);
01240       return FALSE;
01241     }
01242   
01243   if (!dbus_message_append_args (message,
01244                                  DBUS_TYPE_STRING, &name,
01245                                  DBUS_TYPE_INVALID))
01246     {
01247       dbus_message_unref (message);
01248       _DBUS_SET_OOM (error);
01249       return FALSE;
01250     }
01251   
01252   reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
01253   dbus_message_unref (message);
01254 
01255   if (reply == NULL)
01256     {
01257       _DBUS_ASSERT_ERROR_IS_SET (error);
01258       return FALSE;
01259     }
01260 
01261   if (!dbus_message_get_args (reply, error,
01262                               DBUS_TYPE_BOOLEAN, &exists,
01263                               DBUS_TYPE_INVALID))
01264     {
01265       _DBUS_ASSERT_ERROR_IS_SET (error);
01266       dbus_message_unref (reply);
01267       return FALSE;
01268     }
01269   
01270   dbus_message_unref (reply);
01271   return exists;
01272 }
01273 
01296 dbus_bool_t
01297 dbus_bus_start_service_by_name (DBusConnection *connection,
01298                                 const char     *name,
01299                                 dbus_uint32_t   flags,
01300                                 dbus_uint32_t  *result,
01301                                 DBusError      *error)
01302 {
01303   DBusMessage *msg;
01304   DBusMessage *reply;
01305 
01306   _dbus_return_val_if_fail (connection != NULL, FALSE);
01307   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
01308   
01309   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01310                                       DBUS_PATH_DBUS,
01311                                       DBUS_INTERFACE_DBUS,
01312                                       "StartServiceByName");
01313 
01314   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name,
01315                                  DBUS_TYPE_UINT32, &flags, DBUS_TYPE_INVALID))
01316     {
01317       dbus_message_unref (msg);
01318       _DBUS_SET_OOM (error);
01319       return FALSE;
01320     }
01321 
01322   reply = dbus_connection_send_with_reply_and_block (connection, msg,
01323                                                      -1, error);
01324   dbus_message_unref (msg);
01325 
01326   if (reply == NULL)
01327     {
01328       _DBUS_ASSERT_ERROR_IS_SET (error);
01329       return FALSE;
01330     }
01331 
01332   if (dbus_set_error_from_message (error, reply))
01333     {
01334       _DBUS_ASSERT_ERROR_IS_SET (error);
01335       dbus_message_unref (reply);
01336       return FALSE;
01337     }
01338 
01339   if (result != NULL &&
01340       !dbus_message_get_args (reply, error, DBUS_TYPE_UINT32,
01341                               result, DBUS_TYPE_INVALID))
01342     {
01343       _DBUS_ASSERT_ERROR_IS_SET (error);
01344       dbus_message_unref (reply);
01345       return FALSE;
01346     }
01347   
01348   dbus_message_unref (reply);
01349   return TRUE;
01350 }
01351 
01352 static void
01353 send_no_return_values (DBusConnection *connection,
01354                        DBusMessage    *msg,
01355                        DBusError      *error)
01356 {
01357   if (error)
01358     {
01359       /* Block to check success codepath */
01360       DBusMessage *reply;
01361       
01362       reply = dbus_connection_send_with_reply_and_block (connection, msg,
01363                                                          -1, error);
01364       
01365       if (reply == NULL)
01366         _DBUS_ASSERT_ERROR_IS_SET (error);
01367       else
01368         dbus_message_unref (reply);
01369     }
01370   else
01371     {
01372       /* Silently-fail nonblocking codepath */
01373       dbus_message_set_no_reply (msg, TRUE);
01374       dbus_connection_send (connection, msg, NULL);
01375     }
01376 }
01377 
01460 void
01461 dbus_bus_add_match (DBusConnection *connection,
01462                     const char     *rule,
01463                     DBusError      *error)
01464 {
01465   DBusMessage *msg;
01466 
01467   _dbus_return_if_fail (rule != NULL);
01468 
01469   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01470                                       DBUS_PATH_DBUS,
01471                                       DBUS_INTERFACE_DBUS,
01472                                       "AddMatch");
01473 
01474   if (msg == NULL)
01475     {
01476       _DBUS_SET_OOM (error);
01477       return;
01478     }
01479 
01480   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
01481                                  DBUS_TYPE_INVALID))
01482     {
01483       dbus_message_unref (msg);
01484       _DBUS_SET_OOM (error);
01485       return;
01486     }
01487 
01488   send_no_return_values (connection, msg, error);
01489 
01490   dbus_message_unref (msg);
01491 }
01492 
01510 void
01511 dbus_bus_remove_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                                       "RemoveMatch");
01523 
01524   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
01525                                  DBUS_TYPE_INVALID))
01526     {
01527       dbus_message_unref (msg);
01528       _DBUS_SET_OOM (error);
01529       return;
01530     }
01531 
01532   send_no_return_values (connection, msg, error);
01533 
01534   dbus_message_unref (msg);
01535 }
01536 

Generated on Tue Feb 24 16:40:39 2009 for D-Bus by  doxygen 1.5.1