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 
00060 typedef struct
00061 {
00062   DBusConnection *connection; 
00063   char *unique_name; 
00065   unsigned int is_well_known : 1; 
00066 } BusData;
00067 
00070 static dbus_int32_t bus_data_slot = -1;
00071 
00073 #define N_BUS_TYPES 3
00074 
00075 static DBusConnection *bus_connections[N_BUS_TYPES];
00076 static char *bus_connection_addresses[N_BUS_TYPES] = { NULL, NULL, NULL };
00077 
00078 static DBusBusType activation_bus_type = DBUS_BUS_STARTER;
00079 
00080 static dbus_bool_t initialized = FALSE;
00081 
00085 _DBUS_DEFINE_GLOBAL_LOCK (bus);
00086 
00087 static void
00088 addresses_shutdown_func (void *data)
00089 {
00090   int i;
00091 
00092   i = 0;
00093   while (i < N_BUS_TYPES)
00094     {
00095       if (bus_connections[i] != NULL)
00096         _dbus_warn ("dbus_shutdown() called but connections were still live!");
00097       
00098       dbus_free (bus_connection_addresses[i]);
00099       bus_connection_addresses[i] = NULL;
00100       ++i;
00101     }
00102 
00103   activation_bus_type = DBUS_BUS_STARTER;
00104 }
00105 
00106 static dbus_bool_t
00107 get_from_env (char           **connection_p,
00108               const char      *env_var)
00109 {
00110   const char *s;
00111   
00112   _dbus_assert (*connection_p == NULL);
00113   
00114   s = _dbus_getenv (env_var);
00115   if (s == NULL || *s == '\0')
00116     return TRUE; /* successfully didn't use the env var */
00117   else
00118     {
00119       *connection_p = _dbus_strdup (s);
00120       return *connection_p != NULL;
00121     }
00122 }
00123 
00124 static dbus_bool_t
00125 init_connections_unlocked (void)
00126 {
00127   if (!initialized)
00128     {
00129       const char *s;
00130       int i;
00131 
00132       i = 0;
00133       while (i < N_BUS_TYPES)
00134         {
00135           bus_connections[i] = NULL;
00136           ++i;
00137         }
00138 
00139       /* Don't init these twice, we may run this code twice if
00140        * init_connections_unlocked() fails midway through.
00141        * In practice, each block below should contain only one
00142        * "return FALSE" or running through twice may not
00143        * work right.
00144        */
00145       
00146        if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
00147          {
00148            _dbus_verbose ("Filling in system bus address...\n");
00149            
00150            if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SYSTEM],
00151                               "DBUS_SYSTEM_BUS_ADDRESS"))
00152              return FALSE;
00153          }
00154 
00155                   
00156        if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
00157          {
00158            /* Use default system bus address if none set in environment */
00159            bus_connection_addresses[DBUS_BUS_SYSTEM] =
00160              _dbus_strdup (DBUS_SYSTEM_BUS_DEFAULT_ADDRESS);
00161            if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
00162              return FALSE;
00163            
00164            _dbus_verbose ("  used default system bus \"%s\"\n",
00165                           bus_connection_addresses[DBUS_BUS_SYSTEM]);
00166          }
00167        else
00168          _dbus_verbose ("  used env var system bus \"%s\"\n",
00169                         bus_connection_addresses[DBUS_BUS_SYSTEM]);
00170           
00171       if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
00172         {
00173           _dbus_verbose ("Filling in session bus address...\n");
00174           
00175           if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SESSION],
00176                              "DBUS_SESSION_BUS_ADDRESS"))
00177             return FALSE;
00178           _dbus_verbose ("  \"%s\"\n", bus_connection_addresses[DBUS_BUS_SESSION] ?
00179                          bus_connection_addresses[DBUS_BUS_SESSION] : "none set");
00180         }
00181 
00182       if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
00183         {
00184           _dbus_verbose ("Filling in activation bus address...\n");
00185           
00186           if (!get_from_env (&bus_connection_addresses[DBUS_BUS_STARTER],
00187                              "DBUS_STARTER_ADDRESS"))
00188             return FALSE;
00189           
00190           _dbus_verbose ("  \"%s\"\n", bus_connection_addresses[DBUS_BUS_STARTER] ?
00191                          bus_connection_addresses[DBUS_BUS_STARTER] : "none set");
00192         }
00193 
00194 
00195       if (bus_connection_addresses[DBUS_BUS_STARTER] != NULL)
00196         {
00197           s = _dbus_getenv ("DBUS_STARTER_BUS_TYPE");
00198               
00199           if (s != NULL)
00200             {
00201               _dbus_verbose ("Bus activation type was set to \"%s\"\n", s);
00202                   
00203               if (strcmp (s, "system") == 0)
00204                 activation_bus_type = DBUS_BUS_SYSTEM;
00205               else if (strcmp (s, "session") == 0)
00206                 activation_bus_type = DBUS_BUS_SESSION;
00207             }
00208         }
00209       else
00210         {
00211           /* Default to the session bus instead if available */
00212           if (bus_connection_addresses[DBUS_BUS_SESSION] != NULL)
00213             {
00214               bus_connection_addresses[DBUS_BUS_STARTER] =
00215                 _dbus_strdup (bus_connection_addresses[DBUS_BUS_SESSION]);
00216               if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
00217                 return FALSE;
00218             }
00219         }
00220       
00221       /* If we return FALSE we have to be sure that restarting
00222        * the above code will work right
00223        */
00224       
00225       if (!_dbus_setenv ("DBUS_ACTIVATION_ADDRESS", NULL))
00226         return FALSE;
00227 
00228       if (!_dbus_setenv ("DBUS_ACTIVATION_BUS_TYPE", NULL))
00229         return FALSE;
00230       
00231       if (!_dbus_register_shutdown_func (addresses_shutdown_func,
00232                                          NULL))
00233         return FALSE;
00234       
00235       initialized = TRUE;
00236     }
00237 
00238   return initialized;
00239 }
00240 
00241 static void
00242 bus_data_free (void *data)
00243 {
00244   BusData *bd = data;
00245   
00246   if (bd->is_well_known)
00247     {
00248       int i;
00249       _DBUS_LOCK (bus);
00250       /* We may be stored in more than one slot */
00251       i = 0;
00252       while (i < N_BUS_TYPES)
00253         {
00254           if (bus_connections[i] == bd->connection)
00255             bus_connections[i] = NULL;
00256           
00257           ++i;
00258         }
00259       _DBUS_UNLOCK (bus);
00260     }
00261   
00262   dbus_free (bd->unique_name);
00263   dbus_free (bd);
00264 
00265   dbus_connection_free_data_slot (&bus_data_slot);
00266 }
00267 
00268 static BusData*
00269 ensure_bus_data (DBusConnection *connection)
00270 {
00271   BusData *bd;
00272 
00273   if (!dbus_connection_allocate_data_slot (&bus_data_slot))
00274     return NULL;
00275 
00276   bd = dbus_connection_get_data (connection, bus_data_slot);
00277   if (bd == NULL)
00278     {      
00279       bd = dbus_new0 (BusData, 1);
00280       if (bd == NULL)
00281         {
00282           dbus_connection_free_data_slot (&bus_data_slot);
00283           return NULL;
00284         }
00285 
00286       bd->connection = connection;
00287       
00288       if (!dbus_connection_set_data (connection, bus_data_slot, bd,
00289                                      bus_data_free))
00290         {
00291           dbus_free (bd);
00292           dbus_connection_free_data_slot (&bus_data_slot);
00293           return NULL;
00294         }
00295 
00296       /* Data slot refcount now held by the BusData */
00297     }
00298   else
00299     {
00300       dbus_connection_free_data_slot (&bus_data_slot);
00301     }
00302 
00303   return bd;
00304 }
00305 
00306 /* internal function that checks to see if this
00307    is a shared connection owned by the bus and if it is unref it */
00308 void
00309 _dbus_bus_check_connection_and_unref_unlocked (DBusConnection *connection)
00310 {
00311   _DBUS_LOCK (bus);
00312 
00313   if (bus_connections[DBUS_BUS_SYSTEM] == connection)
00314     {
00315       bus_connections[DBUS_BUS_SYSTEM] = NULL;
00316       _dbus_connection_unref_unlocked (connection);
00317     }
00318   else if (bus_connections[DBUS_BUS_SESSION] == connection)
00319     {
00320       bus_connections[DBUS_BUS_SESSION] = NULL;
00321       _dbus_connection_unref_unlocked (connection);
00322     }
00323   else if (bus_connections[DBUS_BUS_STARTER] == connection)
00324     {
00325       bus_connections[DBUS_BUS_STARTER] = NULL;
00326       _dbus_connection_unref_unlocked (connection);
00327     }
00328 
00329   _DBUS_UNLOCK (bus);
00330 }
00331 
00332 static DBusConnection *
00333 internal_bus_get (DBusBusType  type,
00334               DBusError   *error, dbus_bool_t private)
00335 {
00336   const char *address;
00337   DBusConnection *connection;
00338   BusData *bd;
00339   DBusBusType address_type;
00340 
00341   _dbus_return_val_if_fail (type >= 0 && type < N_BUS_TYPES, NULL);
00342   _dbus_return_val_if_error_is_set (error, NULL);
00343 
00344   _DBUS_LOCK (bus);
00345 
00346   if (!init_connections_unlocked ())
00347     {
00348       _DBUS_UNLOCK (bus);
00349       _DBUS_SET_OOM (error);
00350       return NULL;
00351     }
00352 
00353   /* We want to use the activation address even if the
00354    * activating bus is the session or system bus,
00355    * per the spec.
00356    */
00357   address_type = type;
00358   
00359   /* Use the real type of the activation bus for getting its
00360    * connection, but only if the real type's address is available. (If
00361    * the activating bus isn't a well-known bus then
00362    * activation_bus_type == DBUS_BUS_STARTER)
00363    */
00364   if (type == DBUS_BUS_STARTER &&
00365       bus_connection_addresses[activation_bus_type] != NULL)
00366     type = activation_bus_type;
00367   
00368   if (!private && bus_connections[type] != NULL)
00369     {
00370       connection = bus_connections[type];
00371       dbus_connection_ref (connection);
00372       
00373       _DBUS_UNLOCK (bus);
00374       return connection;
00375     }
00376 
00377   address = bus_connection_addresses[address_type];
00378   if (address == NULL)
00379     {
00380       dbus_set_error (error, DBUS_ERROR_FAILED,
00381                       "Unable to determine the address of the message bus (try 'man dbus-launch' and 'man dbus-daemon' for help)");
00382       _DBUS_UNLOCK (bus);
00383       return NULL;
00384     }
00385 
00386   if (private)
00387     connection = dbus_connection_open_private(address, error);
00388   else
00389     connection = dbus_connection_open (address, error);
00390   
00391   if (!connection)
00392     {
00393       _DBUS_ASSERT_ERROR_IS_SET (error);
00394       _DBUS_UNLOCK (bus);
00395       return NULL;
00396     }
00397 
00398   /* By default we're bound to the lifecycle of
00399    * the message bus.
00400    */
00401   dbus_connection_set_exit_on_disconnect (connection,
00402                                           TRUE);
00403   
00404   if (!dbus_bus_register (connection, error))
00405     {
00406       _DBUS_ASSERT_ERROR_IS_SET (error);
00407       _dbus_connection_close_internal (connection);
00408       dbus_connection_unref (connection);
00409 
00410       _DBUS_UNLOCK (bus);
00411       return NULL;
00412     }
00413 
00414   if (!private)
00415     {
00416       /* get a hard ref to the connection */
00417       bus_connections[type] = connection;
00418       dbus_connection_ref (bus_connections[type]);
00419     }
00420   
00421   bd = ensure_bus_data (connection);
00422   _dbus_assert (bd != NULL);
00423 
00424   bd->is_well_known = TRUE;
00425 
00426   _DBUS_UNLOCK (bus);
00427   return connection;
00428 }
00429 
00430  /* end of implementation details docs */
00432 
00447 DBusConnection *
00448 dbus_bus_get (DBusBusType  type,
00449               DBusError   *error) {
00450   return internal_bus_get(type, error, FALSE);
00451 }
00452 
00463 DBusConnection *
00464 dbus_bus_get_private (DBusBusType  type,
00465               DBusError   *error) {
00466   return internal_bus_get(type, error, TRUE);
00467 }
00468 
00479 dbus_bool_t
00480 dbus_bus_register (DBusConnection *connection,
00481                    DBusError      *error)
00482 {
00483   DBusMessage *message, *reply;
00484   char *name;
00485   BusData *bd;
00486   dbus_bool_t retval;
00487 
00488   _dbus_return_val_if_fail (connection != NULL, FALSE);
00489   _dbus_return_val_if_error_is_set (error, FALSE);
00490 
00491   retval = FALSE;
00492   
00493   bd = ensure_bus_data (connection);
00494   if (bd == NULL)
00495     {
00496       _DBUS_SET_OOM (error);
00497       return FALSE;
00498     }
00499 
00500   if (bd->unique_name != NULL)
00501     {
00502       _dbus_warn ("Attempt to register the same DBusConnection with the message bus, but it is already registered\n");
00503       /* This isn't an error, it's a programming bug. We'll be nice
00504        * and not _dbus_assert_not_reached()
00505        */
00506       return TRUE;
00507     }
00508   
00509   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00510                                           DBUS_PATH_DBUS,
00511                                           DBUS_INTERFACE_DBUS,
00512                                           "Hello"); 
00513 
00514   if (!message)
00515     {
00516       _DBUS_SET_OOM (error);
00517       return FALSE;
00518     }
00519   
00520   reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
00521 
00522   dbus_message_unref (message);
00523   
00524   if (reply == NULL)
00525     goto out;
00526   else if (dbus_set_error_from_message (error, reply))
00527     goto out;
00528   else if (!dbus_message_get_args (reply, error,
00529                                    DBUS_TYPE_STRING, &name,
00530                                    DBUS_TYPE_INVALID))
00531     goto out;
00532   
00533   bd->unique_name = _dbus_strdup (name);
00534   if (bd->unique_name == NULL)
00535     {
00536       _DBUS_SET_OOM (error);
00537       goto out;
00538     }
00539   
00540   retval = TRUE;
00541   
00542  out:
00543   if (reply)
00544     dbus_message_unref (reply);
00545 
00546   if (!retval)
00547     _DBUS_ASSERT_ERROR_IS_SET (error);
00548   
00549   return retval;
00550 }
00551 
00552 
00562 dbus_bool_t
00563 dbus_bus_set_unique_name (DBusConnection *connection,
00564                           const char     *unique_name)
00565 {
00566   BusData *bd;
00567 
00568   _dbus_return_val_if_fail (connection != NULL, FALSE);
00569   _dbus_return_val_if_fail (unique_name != NULL, FALSE);
00570   
00571   bd = ensure_bus_data (connection);
00572   if (bd == NULL)
00573     return FALSE;
00574 
00575   _dbus_assert (bd->unique_name == NULL);
00576   
00577   bd->unique_name = _dbus_strdup (unique_name);
00578   return bd->unique_name != NULL;
00579 }
00580 
00591 const char*
00592 dbus_bus_get_unique_name (DBusConnection *connection)
00593 {
00594   BusData *bd;
00595 
00596   _dbus_return_val_if_fail (connection != NULL, NULL);
00597   
00598   bd = ensure_bus_data (connection);
00599   if (bd == NULL)
00600     return NULL;
00601   
00602   return bd->unique_name;
00603 }
00604 
00614 unsigned long
00615 dbus_bus_get_unix_user (DBusConnection *connection,
00616                         const char     *name,
00617                         DBusError      *error)
00618 {
00619   DBusMessage *message, *reply;
00620   dbus_uint32_t uid;
00621 
00622   _dbus_return_val_if_fail (connection != NULL, DBUS_UID_UNSET);
00623   _dbus_return_val_if_fail (name != NULL, DBUS_UID_UNSET);
00624   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), DBUS_UID_UNSET);
00625   _dbus_return_val_if_error_is_set (error, DBUS_UID_UNSET);
00626   
00627   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00628                                           DBUS_PATH_DBUS,
00629                                           DBUS_INTERFACE_DBUS,
00630                                           "GetConnectionUnixUser");
00631 
00632   if (message == NULL)
00633     {
00634       _DBUS_SET_OOM (error);
00635       return DBUS_UID_UNSET;
00636     }
00637  
00638   if (!dbus_message_append_args (message,
00639                                  DBUS_TYPE_STRING, &name,
00640                                  DBUS_TYPE_INVALID))
00641     {
00642       dbus_message_unref (message);
00643       _DBUS_SET_OOM (error);
00644       return DBUS_UID_UNSET;
00645     }
00646   
00647   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
00648                                                      error);
00649   
00650   dbus_message_unref (message);
00651   
00652   if (reply == NULL)
00653     {
00654       _DBUS_ASSERT_ERROR_IS_SET (error);
00655       return DBUS_UID_UNSET;
00656     }  
00657 
00658   if (dbus_set_error_from_message (error, reply))
00659     {
00660       _DBUS_ASSERT_ERROR_IS_SET (error);
00661       dbus_message_unref (reply);
00662       return DBUS_UID_UNSET;
00663     }
00664   
00665   if (!dbus_message_get_args (reply, error,
00666                               DBUS_TYPE_UINT32, &uid,
00667                               DBUS_TYPE_INVALID))
00668     {
00669       _DBUS_ASSERT_ERROR_IS_SET (error);
00670       dbus_message_unref (reply);
00671       return DBUS_UID_UNSET;
00672     }
00673 
00674   dbus_message_unref (reply);
00675   
00676   return (unsigned long) uid;
00677 }
00678 
00679 
00739 int
00740 dbus_bus_request_name (DBusConnection *connection,
00741                        const char     *name,
00742                        unsigned int    flags,
00743                        DBusError      *error)
00744 {
00745   DBusMessage *message, *reply;
00746   dbus_uint32_t result;
00747 
00748   _dbus_return_val_if_fail (connection != NULL, 0);
00749   _dbus_return_val_if_fail (name != NULL, 0);
00750   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
00751   _dbus_return_val_if_error_is_set (error, 0);
00752   
00753   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00754                                           DBUS_PATH_DBUS,
00755                                           DBUS_INTERFACE_DBUS,
00756                                           "RequestName");
00757 
00758   if (message == NULL)
00759     {
00760       _DBUS_SET_OOM (error);
00761       return -1;
00762     }
00763  
00764   if (!dbus_message_append_args (message,
00765                                  DBUS_TYPE_STRING, &name,
00766                                  DBUS_TYPE_UINT32, &flags,
00767                                  DBUS_TYPE_INVALID))
00768     {
00769       dbus_message_unref (message);
00770       _DBUS_SET_OOM (error);
00771       return -1;
00772     }
00773   
00774   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
00775                                                      error);
00776   
00777   dbus_message_unref (message);
00778   
00779   if (reply == NULL)
00780     {
00781       _DBUS_ASSERT_ERROR_IS_SET (error);
00782       return -1;
00783     }  
00784 
00785   if (dbus_set_error_from_message (error, reply))
00786     {
00787       _DBUS_ASSERT_ERROR_IS_SET (error);
00788       dbus_message_unref (reply);
00789       return -1;
00790     }
00791   
00792   if (!dbus_message_get_args (reply, error,
00793                               DBUS_TYPE_UINT32, &result,
00794                               DBUS_TYPE_INVALID))
00795     {
00796       _DBUS_ASSERT_ERROR_IS_SET (error);
00797       dbus_message_unref (reply);
00798       return -1;
00799     }
00800 
00801   dbus_message_unref (reply);
00802   
00803   return result;
00804 }
00805 
00806 
00817 int
00818 dbus_bus_release_name (DBusConnection *connection,
00819                        const char     *name,
00820                        DBusError      *error)
00821 {
00822   DBusMessage *message, *reply;
00823   dbus_uint32_t result;
00824 
00825   _dbus_return_val_if_fail (connection != NULL, 0);
00826   _dbus_return_val_if_fail (name != NULL, 0);
00827   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
00828   _dbus_return_val_if_error_is_set (error, 0);
00829 
00830   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00831                                           DBUS_PATH_DBUS,
00832                                           DBUS_INTERFACE_DBUS,
00833                                           "ReleaseName");
00834 
00835   if (message == NULL)
00836     {
00837       _DBUS_SET_OOM (error);
00838       return -1;
00839     }
00840 
00841   if (!dbus_message_append_args (message,
00842                                  DBUS_TYPE_STRING, &name,
00843                                  DBUS_TYPE_INVALID))
00844     {
00845       dbus_message_unref (message);
00846       _DBUS_SET_OOM (error);
00847       return -1;
00848     }
00849 
00850   reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
00851                                                      error);
00852 
00853   dbus_message_unref (message);
00854 
00855   if (reply == NULL)
00856     {
00857       _DBUS_ASSERT_ERROR_IS_SET (error);
00858       return -1;
00859     }
00860 
00861   if (dbus_set_error_from_message (error, reply))
00862     {
00863       _DBUS_ASSERT_ERROR_IS_SET (error);
00864       dbus_message_unref (reply);
00865       return -1;
00866     }
00867 
00868   if (!dbus_message_get_args (reply, error,
00869                               DBUS_TYPE_UINT32, &result,
00870                               DBUS_TYPE_INVALID))
00871     {
00872       _DBUS_ASSERT_ERROR_IS_SET (error);
00873       dbus_message_unref (reply);
00874       return -1;
00875     }
00876 
00877   dbus_message_unref (reply);
00878 
00879   return result;
00880 }
00881 
00890 dbus_bool_t
00891 dbus_bus_name_has_owner (DBusConnection *connection,
00892                          const char     *name,
00893                          DBusError      *error)
00894 {
00895   DBusMessage *message, *reply;
00896   dbus_bool_t exists;
00897 
00898   _dbus_return_val_if_fail (connection != NULL, FALSE);
00899   _dbus_return_val_if_fail (name != NULL, FALSE);
00900   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
00901   _dbus_return_val_if_error_is_set (error, FALSE);
00902   
00903   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00904                                           DBUS_PATH_DBUS,
00905                                           DBUS_INTERFACE_DBUS,
00906                                           "NameHasOwner");
00907   if (message == NULL)
00908     {
00909       _DBUS_SET_OOM (error);
00910       return FALSE;
00911     }
00912   
00913   if (!dbus_message_append_args (message,
00914                                  DBUS_TYPE_STRING, &name,
00915                                  DBUS_TYPE_INVALID))
00916     {
00917       dbus_message_unref (message);
00918       _DBUS_SET_OOM (error);
00919       return FALSE;
00920     }
00921   
00922   reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
00923   dbus_message_unref (message);
00924 
00925   if (reply == NULL)
00926     {
00927       _DBUS_ASSERT_ERROR_IS_SET (error);
00928       return FALSE;
00929     }
00930 
00931   if (!dbus_message_get_args (reply, error,
00932                               DBUS_TYPE_BOOLEAN, &exists,
00933                               DBUS_TYPE_INVALID))
00934     {
00935       _DBUS_ASSERT_ERROR_IS_SET (error);
00936       dbus_message_unref (reply);
00937       return FALSE;
00938     }
00939   
00940   dbus_message_unref (reply);
00941   return exists;
00942 }
00943 
00960 dbus_bool_t
00961 dbus_bus_start_service_by_name (DBusConnection *connection,
00962                                 const char     *name,
00963                                 dbus_uint32_t   flags,
00964                                 dbus_uint32_t  *result,
00965                                 DBusError      *error)
00966 {
00967   DBusMessage *msg;
00968   DBusMessage *reply;
00969 
00970   _dbus_return_val_if_fail (connection != NULL, FALSE);
00971   _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
00972   
00973   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00974                                       DBUS_PATH_DBUS,
00975                                       DBUS_INTERFACE_DBUS,
00976                                       "StartServiceByName");
00977 
00978   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name,
00979                                  DBUS_TYPE_UINT32, &flags, DBUS_TYPE_INVALID))
00980     {
00981       dbus_message_unref (msg);
00982       _DBUS_SET_OOM (error);
00983       return FALSE;
00984     }
00985 
00986   reply = dbus_connection_send_with_reply_and_block (connection, msg,
00987                                                      -1, error);
00988   dbus_message_unref (msg);
00989 
00990   if (reply == NULL)
00991     {
00992       _DBUS_ASSERT_ERROR_IS_SET (error);
00993       return FALSE;
00994     }
00995 
00996   if (dbus_set_error_from_message (error, reply))
00997     {
00998       _DBUS_ASSERT_ERROR_IS_SET (error);
00999       dbus_message_unref (reply);
01000       return FALSE;
01001     }
01002 
01003   if (result != NULL &&
01004       !dbus_message_get_args (reply, error, DBUS_TYPE_UINT32,
01005                               result, DBUS_TYPE_INVALID))
01006     {
01007       _DBUS_ASSERT_ERROR_IS_SET (error);
01008       dbus_message_unref (reply);
01009       return FALSE;
01010     }
01011   
01012   dbus_message_unref (reply);
01013   return TRUE;
01014 }
01015 
01016 static void
01017 send_no_return_values (DBusConnection *connection,
01018                        DBusMessage    *msg,
01019                        DBusError      *error)
01020 {
01021   if (error)
01022     {
01023       /* Block to check success codepath */
01024       DBusMessage *reply;
01025       
01026       reply = dbus_connection_send_with_reply_and_block (connection, msg,
01027                                                          -1, error);
01028       
01029       if (reply == NULL)
01030         _DBUS_ASSERT_ERROR_IS_SET (error);
01031       else
01032         dbus_message_unref (reply);
01033     }
01034   else
01035     {
01036       /* Silently-fail nonblocking codepath */
01037       dbus_message_set_no_reply (msg, TRUE);
01038       dbus_connection_send (connection, msg, NULL);
01039     }
01040 }
01041 
01096 void
01097 dbus_bus_add_match (DBusConnection *connection,
01098                     const char     *rule,
01099                     DBusError      *error)
01100 {
01101   DBusMessage *msg;
01102 
01103   _dbus_return_if_fail (rule != NULL);
01104 
01105   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01106                                       DBUS_PATH_DBUS,
01107                                       DBUS_INTERFACE_DBUS,
01108                                       "AddMatch");
01109 
01110   if (msg == NULL)
01111     {
01112       _DBUS_SET_OOM (error);
01113       return;
01114     }
01115 
01116   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
01117                                  DBUS_TYPE_INVALID))
01118     {
01119       dbus_message_unref (msg);
01120       _DBUS_SET_OOM (error);
01121       return;
01122     }
01123 
01124   send_no_return_values (connection, msg, error);
01125 
01126   dbus_message_unref (msg);
01127 }
01128 
01142 void
01143 dbus_bus_remove_match (DBusConnection *connection,
01144                        const char     *rule,
01145                        DBusError      *error)
01146 {
01147   DBusMessage *msg;
01148 
01149   _dbus_return_if_fail (rule != NULL);
01150   
01151   msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
01152                                       DBUS_PATH_DBUS,
01153                                       DBUS_INTERFACE_DBUS,
01154                                       "RemoveMatch");
01155 
01156   if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
01157                                  DBUS_TYPE_INVALID))
01158     {
01159       dbus_message_unref (msg);
01160       _DBUS_SET_OOM (error);
01161       return;
01162     }
01163 
01164   send_no_return_values (connection, msg, error);
01165 
01166   dbus_message_unref (msg);
01167 }
01168 

Generated on Fri Oct 20 11:46:23 2006 for D-Bus by  doxygen 1.4.7