D-Bus
1.10.12
|
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 00002 /* dbus-bus.c Convenience functions for communicating with the bus. 00003 * 00004 * Copyright (C) 2003 CodeFactory AB 00005 * Copyright (C) 2003 Red Hat, Inc. 00006 * 00007 * Licensed under the Academic Free License version 2.1 00008 * 00009 * This program is free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00022 * 00023 */ 00024 00025 #include <config.h> 00026 #include "dbus-bus.h" 00027 #include "dbus-protocol.h" 00028 #include "dbus-internals.h" 00029 #include "dbus-message.h" 00030 #include "dbus-marshal-validate.h" 00031 #include "dbus-misc.h" 00032 #include "dbus-threads-internal.h" 00033 #include "dbus-connection-internal.h" 00034 #include "dbus-string.h" 00035 00077 typedef struct 00078 { 00079 DBusConnection *connection; 00080 char *unique_name; 00082 unsigned int is_well_known : 1; 00083 } BusData; 00084 00087 static dbus_int32_t bus_data_slot = -1; 00088 00090 #define N_BUS_TYPES 3 00091 00092 static DBusConnection *bus_connections[N_BUS_TYPES]; 00093 static char *bus_connection_addresses[N_BUS_TYPES] = { NULL, NULL, NULL }; 00094 00095 static DBusBusType activation_bus_type = DBUS_BUS_STARTER; 00096 00097 static dbus_bool_t initialized = FALSE; 00098 00099 static void 00100 addresses_shutdown_func (void *data) 00101 { 00102 int i; 00103 00104 i = 0; 00105 while (i < N_BUS_TYPES) 00106 { 00107 if (bus_connections[i] != NULL) 00108 _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"); 00109 00110 dbus_free (bus_connection_addresses[i]); 00111 bus_connection_addresses[i] = NULL; 00112 ++i; 00113 } 00114 00115 activation_bus_type = DBUS_BUS_STARTER; 00116 00117 initialized = FALSE; 00118 } 00119 00120 static dbus_bool_t 00121 get_from_env (char **connection_p, 00122 const char *env_var) 00123 { 00124 const char *s; 00125 00126 _dbus_assert (*connection_p == NULL); 00127 00128 s = _dbus_getenv (env_var); 00129 if (s == NULL || *s == '\0') 00130 return TRUE; /* successfully didn't use the env var */ 00131 else 00132 { 00133 *connection_p = _dbus_strdup (s); 00134 return *connection_p != NULL; 00135 } 00136 } 00137 00138 static dbus_bool_t 00139 init_session_address (void) 00140 { 00141 dbus_bool_t retval; 00142 00143 retval = FALSE; 00144 00145 /* First, look in the environment. This is the normal case on 00146 * freedesktop.org/Unix systems. */ 00147 get_from_env (&bus_connection_addresses[DBUS_BUS_SESSION], 00148 "DBUS_SESSION_BUS_ADDRESS"); 00149 if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL) 00150 { 00151 dbus_bool_t supported; 00152 DBusString addr; 00153 DBusError error = DBUS_ERROR_INIT; 00154 00155 if (!_dbus_string_init (&addr)) 00156 return FALSE; 00157 00158 supported = FALSE; 00159 /* So it's not in the environment - let's try a platform-specific method. 00160 * On MacOS, this involves asking launchd. On Windows (not specified yet) 00161 * we might do a COM lookup. 00162 * Ignore errors - if we failed, fall back to autolaunch. */ 00163 retval = _dbus_lookup_session_address (&supported, &addr, &error); 00164 if (supported && retval) 00165 { 00166 retval =_dbus_string_steal_data (&addr, &bus_connection_addresses[DBUS_BUS_SESSION]); 00167 } 00168 else if (supported && !retval) 00169 { 00170 if (dbus_error_is_set(&error)) 00171 _dbus_warn ("Dynamic session lookup supported but failed: %s\n", error.message); 00172 else 00173 _dbus_warn ("Dynamic session lookup supported but failed silently\n"); 00174 } 00175 _dbus_string_free (&addr); 00176 } 00177 else 00178 retval = TRUE; 00179 00180 if (!retval) 00181 return FALSE; 00182 00183 /* We have a hard-coded (but compile-time-configurable) fallback address for 00184 * the session bus. */ 00185 if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL) 00186 bus_connection_addresses[DBUS_BUS_SESSION] = 00187 _dbus_strdup (DBUS_SESSION_BUS_CONNECT_ADDRESS); 00188 00189 if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL) 00190 return FALSE; 00191 00192 return TRUE; 00193 } 00194 00195 static dbus_bool_t 00196 init_connections_unlocked (void) 00197 { 00198 if (!initialized) 00199 { 00200 const char *s; 00201 int i; 00202 00203 i = 0; 00204 while (i < N_BUS_TYPES) 00205 { 00206 bus_connections[i] = NULL; 00207 ++i; 00208 } 00209 00210 /* Don't init these twice, we may run this code twice if 00211 * init_connections_unlocked() fails midway through. 00212 * In practice, each block below should contain only one 00213 * "return FALSE" or running through twice may not 00214 * work right. 00215 */ 00216 00217 if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL) 00218 { 00219 _dbus_verbose ("Filling in system bus address...\n"); 00220 00221 if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SYSTEM], 00222 "DBUS_SYSTEM_BUS_ADDRESS")) 00223 return FALSE; 00224 } 00225 00226 00227 if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL) 00228 { 00229 /* Use default system bus address if none set in environment */ 00230 bus_connection_addresses[DBUS_BUS_SYSTEM] = 00231 _dbus_strdup (DBUS_SYSTEM_BUS_DEFAULT_ADDRESS); 00232 00233 if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL) 00234 return FALSE; 00235 00236 _dbus_verbose (" used default system bus \"%s\"\n", 00237 bus_connection_addresses[DBUS_BUS_SYSTEM]); 00238 } 00239 else 00240 _dbus_verbose (" used env var system bus \"%s\"\n", 00241 bus_connection_addresses[DBUS_BUS_SYSTEM]); 00242 00243 if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL) 00244 { 00245 _dbus_verbose ("Filling in session bus address...\n"); 00246 00247 if (!init_session_address ()) 00248 return FALSE; 00249 00250 _dbus_verbose (" \"%s\"\n", bus_connection_addresses[DBUS_BUS_SESSION] ? 00251 bus_connection_addresses[DBUS_BUS_SESSION] : "none set"); 00252 } 00253 00254 if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL) 00255 { 00256 _dbus_verbose ("Filling in activation bus address...\n"); 00257 00258 if (!get_from_env (&bus_connection_addresses[DBUS_BUS_STARTER], 00259 "DBUS_STARTER_ADDRESS")) 00260 return FALSE; 00261 00262 _dbus_verbose (" \"%s\"\n", bus_connection_addresses[DBUS_BUS_STARTER] ? 00263 bus_connection_addresses[DBUS_BUS_STARTER] : "none set"); 00264 } 00265 00266 00267 if (bus_connection_addresses[DBUS_BUS_STARTER] != NULL) 00268 { 00269 s = _dbus_getenv ("DBUS_STARTER_BUS_TYPE"); 00270 00271 if (s != NULL) 00272 { 00273 _dbus_verbose ("Bus activation type was set to \"%s\"\n", s); 00274 00275 if (strcmp (s, "system") == 0) 00276 activation_bus_type = DBUS_BUS_SYSTEM; 00277 else if (strcmp (s, "session") == 0) 00278 activation_bus_type = DBUS_BUS_SESSION; 00279 } 00280 } 00281 else 00282 { 00283 /* Default to the session bus instead if available */ 00284 if (bus_connection_addresses[DBUS_BUS_SESSION] != NULL) 00285 { 00286 bus_connection_addresses[DBUS_BUS_STARTER] = 00287 _dbus_strdup (bus_connection_addresses[DBUS_BUS_SESSION]); 00288 if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL) 00289 return FALSE; 00290 } 00291 } 00292 00293 /* If we return FALSE we have to be sure that restarting 00294 * the above code will work right 00295 */ 00296 00297 if (!_dbus_register_shutdown_func (addresses_shutdown_func, 00298 NULL)) 00299 return FALSE; 00300 00301 initialized = TRUE; 00302 } 00303 00304 return initialized; 00305 } 00306 00307 static void 00308 bus_data_free (void *data) 00309 { 00310 BusData *bd = data; 00311 00312 if (bd->is_well_known) 00313 { 00314 int i; 00315 00316 if (!_DBUS_LOCK (bus)) 00317 _dbus_assert_not_reached ("global locks should have been initialized " 00318 "when we attached bus data"); 00319 00320 /* We may be stored in more than one slot */ 00321 /* This should now be impossible - these slots are supposed to 00322 * be cleared on disconnect, so should not need to be cleared on 00323 * finalize 00324 */ 00325 i = 0; 00326 while (i < N_BUS_TYPES) 00327 { 00328 if (bus_connections[i] == bd->connection) 00329 bus_connections[i] = NULL; 00330 00331 ++i; 00332 } 00333 _DBUS_UNLOCK (bus); 00334 } 00335 00336 dbus_free (bd->unique_name); 00337 dbus_free (bd); 00338 00339 dbus_connection_free_data_slot (&bus_data_slot); 00340 } 00341 00342 static BusData* 00343 ensure_bus_data (DBusConnection *connection) 00344 { 00345 BusData *bd; 00346 00347 if (!dbus_connection_allocate_data_slot (&bus_data_slot)) 00348 return NULL; 00349 00350 bd = dbus_connection_get_data (connection, bus_data_slot); 00351 if (bd == NULL) 00352 { 00353 bd = dbus_new0 (BusData, 1); 00354 if (bd == NULL) 00355 { 00356 dbus_connection_free_data_slot (&bus_data_slot); 00357 return NULL; 00358 } 00359 00360 bd->connection = connection; 00361 00362 if (!dbus_connection_set_data (connection, bus_data_slot, bd, 00363 bus_data_free)) 00364 { 00365 dbus_free (bd); 00366 dbus_connection_free_data_slot (&bus_data_slot); 00367 return NULL; 00368 } 00369 00370 /* Data slot refcount now held by the BusData */ 00371 } 00372 else 00373 { 00374 dbus_connection_free_data_slot (&bus_data_slot); 00375 } 00376 00377 return bd; 00378 } 00379 00386 void 00387 _dbus_bus_notify_shared_connection_disconnected_unlocked (DBusConnection *connection) 00388 { 00389 int i; 00390 00391 if (!_DBUS_LOCK (bus)) 00392 { 00393 /* If it was in bus_connections, we would have initialized global locks 00394 * when we added it. So, it can't be. */ 00395 return; 00396 } 00397 00398 /* We are expecting to have the connection saved in only one of these 00399 * slots, but someone could in a pathological case set system and session 00400 * bus to the same bus or something. Or set one of them to the starter 00401 * bus without setting the starter bus type in the env variable. 00402 * So we don't break the loop as soon as we find a match. 00403 */ 00404 for (i = 0; i < N_BUS_TYPES; ++i) 00405 { 00406 if (bus_connections[i] == connection) 00407 { 00408 bus_connections[i] = NULL; 00409 } 00410 } 00411 00412 _DBUS_UNLOCK (bus); 00413 } 00414 00415 static DBusConnection * 00416 internal_bus_get (DBusBusType type, 00417 dbus_bool_t private, 00418 DBusError *error) 00419 { 00420 const char *address; 00421 DBusConnection *connection; 00422 BusData *bd; 00423 DBusBusType address_type; 00424 00425 _dbus_return_val_if_fail (type >= 0 && type < N_BUS_TYPES, NULL); 00426 _dbus_return_val_if_error_is_set (error, NULL); 00427 00428 connection = NULL; 00429 00430 if (!_DBUS_LOCK (bus)) 00431 { 00432 _DBUS_SET_OOM (error); 00433 /* do not "goto out", that would try to unlock */ 00434 return NULL; 00435 } 00436 00437 if (!init_connections_unlocked ()) 00438 { 00439 _DBUS_SET_OOM (error); 00440 goto out; 00441 } 00442 00443 /* We want to use the activation address even if the 00444 * activating bus is the session or system bus, 00445 * per the spec. 00446 */ 00447 address_type = type; 00448 00449 /* Use the real type of the activation bus for getting its 00450 * connection, but only if the real type's address is available. (If 00451 * the activating bus isn't a well-known bus then 00452 * activation_bus_type == DBUS_BUS_STARTER) 00453 */ 00454 if (type == DBUS_BUS_STARTER && 00455 bus_connection_addresses[activation_bus_type] != NULL) 00456 type = activation_bus_type; 00457 00458 if (!private && bus_connections[type] != NULL) 00459 { 00460 connection = bus_connections[type]; 00461 dbus_connection_ref (connection); 00462 goto out; 00463 } 00464 00465 address = bus_connection_addresses[address_type]; 00466 if (address == NULL) 00467 { 00468 dbus_set_error (error, DBUS_ERROR_FAILED, 00469 "Unable to determine the address of the message bus (try 'man dbus-launch' and 'man dbus-daemon' for help)"); 00470 goto out; 00471 } 00472 00473 if (private) 00474 connection = dbus_connection_open_private (address, error); 00475 else 00476 connection = dbus_connection_open (address, error); 00477 00478 if (!connection) 00479 { 00480 goto out; 00481 } 00482 00483 if (!dbus_bus_register (connection, error)) 00484 { 00485 _dbus_connection_close_possibly_shared (connection); 00486 dbus_connection_unref (connection); 00487 connection = NULL; 00488 goto out; 00489 } 00490 00491 if (!private) 00492 { 00493 /* store a weak ref to the connection (dbus-connection.c is 00494 * supposed to have a strong ref that it drops on disconnect, 00495 * since this is a shared connection) 00496 */ 00497 bus_connections[type] = connection; 00498 } 00499 00500 /* By default we're bound to the lifecycle of 00501 * the message bus. 00502 */ 00503 dbus_connection_set_exit_on_disconnect (connection, 00504 TRUE); 00505 00506 if (!_DBUS_LOCK (bus_datas)) 00507 _dbus_assert_not_reached ("global locks were initialized already"); 00508 00509 bd = ensure_bus_data (connection); 00510 _dbus_assert (bd != NULL); /* it should have been created on 00511 register, so OOM not possible */ 00512 bd->is_well_known = TRUE; 00513 _DBUS_UNLOCK (bus_datas); 00514 00515 out: 00516 /* Return a reference to the caller, or NULL with error set. */ 00517 if (connection == NULL) 00518 _DBUS_ASSERT_ERROR_IS_SET (error); 00519 00520 _DBUS_UNLOCK (bus); 00521 return connection; 00522 } 00523 00524 /* end of implementation details docs */ 00526 00557 DBusConnection * 00558 dbus_bus_get (DBusBusType type, 00559 DBusError *error) 00560 { 00561 return internal_bus_get (type, FALSE, error); 00562 } 00563 00589 DBusConnection * 00590 dbus_bus_get_private (DBusBusType type, 00591 DBusError *error) 00592 { 00593 return internal_bus_get (type, TRUE, error); 00594 } 00595 00645 dbus_bool_t 00646 dbus_bus_register (DBusConnection *connection, 00647 DBusError *error) 00648 { 00649 DBusMessage *message, *reply; 00650 char *name; 00651 BusData *bd; 00652 dbus_bool_t retval; 00653 00654 _dbus_return_val_if_fail (connection != NULL, FALSE); 00655 _dbus_return_val_if_error_is_set (error, FALSE); 00656 00657 retval = FALSE; 00658 message = NULL; 00659 reply = NULL; 00660 00661 if (!_DBUS_LOCK (bus_datas)) 00662 { 00663 _DBUS_SET_OOM (error); 00664 /* do not "goto out", that would try to unlock */ 00665 return FALSE; 00666 } 00667 00668 bd = ensure_bus_data (connection); 00669 if (bd == NULL) 00670 { 00671 _DBUS_SET_OOM (error); 00672 goto out; 00673 } 00674 00675 if (bd->unique_name != NULL) 00676 { 00677 _dbus_verbose ("Ignoring attempt to register the same DBusConnection %s with the message bus a second time.\n", 00678 bd->unique_name); 00679 /* Success! */ 00680 retval = TRUE; 00681 goto out; 00682 } 00683 00684 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, 00685 DBUS_PATH_DBUS, 00686 DBUS_INTERFACE_DBUS, 00687 "Hello"); 00688 00689 if (!message) 00690 { 00691 _DBUS_SET_OOM (error); 00692 goto out; 00693 } 00694 00695 reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error); 00696 00697 if (reply == NULL) 00698 goto out; 00699 else if (dbus_set_error_from_message (error, reply)) 00700 goto out; 00701 else if (!dbus_message_get_args (reply, error, 00702 DBUS_TYPE_STRING, &name, 00703 DBUS_TYPE_INVALID)) 00704 goto out; 00705 00706 bd->unique_name = _dbus_strdup (name); 00707 if (bd->unique_name == NULL) 00708 { 00709 _DBUS_SET_OOM (error); 00710 goto out; 00711 } 00712 00713 retval = TRUE; 00714 00715 out: 00716 _DBUS_UNLOCK (bus_datas); 00717 00718 if (message) 00719 dbus_message_unref (message); 00720 00721 if (reply) 00722 dbus_message_unref (reply); 00723 00724 if (!retval) 00725 _DBUS_ASSERT_ERROR_IS_SET (error); 00726 00727 return retval; 00728 } 00729 00730 00765 dbus_bool_t 00766 dbus_bus_set_unique_name (DBusConnection *connection, 00767 const char *unique_name) 00768 { 00769 BusData *bd; 00770 dbus_bool_t success = FALSE; 00771 00772 _dbus_return_val_if_fail (connection != NULL, FALSE); 00773 _dbus_return_val_if_fail (unique_name != NULL, FALSE); 00774 00775 if (!_DBUS_LOCK (bus_datas)) 00776 { 00777 /* do not "goto out", that would try to unlock */ 00778 return FALSE; 00779 } 00780 00781 bd = ensure_bus_data (connection); 00782 if (bd == NULL) 00783 goto out; 00784 00785 _dbus_assert (bd->unique_name == NULL); 00786 00787 bd->unique_name = _dbus_strdup (unique_name); 00788 success = bd->unique_name != NULL; 00789 00790 out: 00791 _DBUS_UNLOCK (bus_datas); 00792 00793 return success; 00794 } 00795 00814 const char* 00815 dbus_bus_get_unique_name (DBusConnection *connection) 00816 { 00817 BusData *bd; 00818 const char *unique_name = NULL; 00819 00820 _dbus_return_val_if_fail (connection != NULL, NULL); 00821 00822 if (!_DBUS_LOCK (bus_datas)) 00823 { 00824 /* We'd have initialized locks when we gave it its unique name, if it 00825 * had one. Don't "goto out", that would try to unlock. */ 00826 return NULL; 00827 } 00828 00829 bd = ensure_bus_data (connection); 00830 if (bd == NULL) 00831 goto out; 00832 00833 unique_name = bd->unique_name; 00834 00835 out: 00836 _DBUS_UNLOCK (bus_datas); 00837 00838 return unique_name; 00839 } 00840 00864 unsigned long 00865 dbus_bus_get_unix_user (DBusConnection *connection, 00866 const char *name, 00867 DBusError *error) 00868 { 00869 DBusMessage *message, *reply; 00870 dbus_uint32_t uid; 00871 00872 _dbus_return_val_if_fail (connection != NULL, DBUS_UID_UNSET); 00873 _dbus_return_val_if_fail (name != NULL, DBUS_UID_UNSET); 00874 _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), DBUS_UID_UNSET); 00875 _dbus_return_val_if_error_is_set (error, DBUS_UID_UNSET); 00876 00877 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, 00878 DBUS_PATH_DBUS, 00879 DBUS_INTERFACE_DBUS, 00880 "GetConnectionUnixUser"); 00881 00882 if (message == NULL) 00883 { 00884 _DBUS_SET_OOM (error); 00885 return DBUS_UID_UNSET; 00886 } 00887 00888 if (!dbus_message_append_args (message, 00889 DBUS_TYPE_STRING, &name, 00890 DBUS_TYPE_INVALID)) 00891 { 00892 dbus_message_unref (message); 00893 _DBUS_SET_OOM (error); 00894 return DBUS_UID_UNSET; 00895 } 00896 00897 reply = dbus_connection_send_with_reply_and_block (connection, message, -1, 00898 error); 00899 00900 dbus_message_unref (message); 00901 00902 if (reply == NULL) 00903 { 00904 _DBUS_ASSERT_ERROR_IS_SET (error); 00905 return DBUS_UID_UNSET; 00906 } 00907 00908 if (dbus_set_error_from_message (error, reply)) 00909 { 00910 _DBUS_ASSERT_ERROR_IS_SET (error); 00911 dbus_message_unref (reply); 00912 return DBUS_UID_UNSET; 00913 } 00914 00915 if (!dbus_message_get_args (reply, error, 00916 DBUS_TYPE_UINT32, &uid, 00917 DBUS_TYPE_INVALID)) 00918 { 00919 _DBUS_ASSERT_ERROR_IS_SET (error); 00920 dbus_message_unref (reply); 00921 return DBUS_UID_UNSET; 00922 } 00923 00924 dbus_message_unref (reply); 00925 00926 return (unsigned long) uid; 00927 } 00928 00947 char* 00948 dbus_bus_get_id (DBusConnection *connection, 00949 DBusError *error) 00950 { 00951 DBusMessage *message, *reply; 00952 char *id; 00953 const char *v_STRING; 00954 00955 _dbus_return_val_if_fail (connection != NULL, NULL); 00956 _dbus_return_val_if_error_is_set (error, NULL); 00957 00958 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, 00959 DBUS_PATH_DBUS, 00960 DBUS_INTERFACE_DBUS, 00961 "GetId"); 00962 00963 if (message == NULL) 00964 { 00965 _DBUS_SET_OOM (error); 00966 return NULL; 00967 } 00968 00969 reply = dbus_connection_send_with_reply_and_block (connection, message, -1, 00970 error); 00971 00972 dbus_message_unref (message); 00973 00974 if (reply == NULL) 00975 { 00976 _DBUS_ASSERT_ERROR_IS_SET (error); 00977 return NULL; 00978 } 00979 00980 if (dbus_set_error_from_message (error, reply)) 00981 { 00982 _DBUS_ASSERT_ERROR_IS_SET (error); 00983 dbus_message_unref (reply); 00984 return NULL; 00985 } 00986 00987 v_STRING = NULL; 00988 if (!dbus_message_get_args (reply, error, 00989 DBUS_TYPE_STRING, &v_STRING, 00990 DBUS_TYPE_INVALID)) 00991 { 00992 _DBUS_ASSERT_ERROR_IS_SET (error); 00993 dbus_message_unref (reply); 00994 return NULL; 00995 } 00996 00997 id = _dbus_strdup (v_STRING); /* may be NULL */ 00998 00999 dbus_message_unref (reply); 01000 01001 if (id == NULL) 01002 _DBUS_SET_OOM (error); 01003 01004 /* FIXME it might be nice to cache the ID locally */ 01005 01006 return id; 01007 } 01008 01111 int 01112 dbus_bus_request_name (DBusConnection *connection, 01113 const char *name, 01114 unsigned int flags, 01115 DBusError *error) 01116 { 01117 DBusMessage *message, *reply; 01118 dbus_uint32_t result; 01119 01120 _dbus_return_val_if_fail (connection != NULL, 0); 01121 _dbus_return_val_if_fail (name != NULL, 0); 01122 _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0); 01123 _dbus_return_val_if_error_is_set (error, 0); 01124 01125 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, 01126 DBUS_PATH_DBUS, 01127 DBUS_INTERFACE_DBUS, 01128 "RequestName"); 01129 01130 if (message == NULL) 01131 { 01132 _DBUS_SET_OOM (error); 01133 return -1; 01134 } 01135 01136 if (!dbus_message_append_args (message, 01137 DBUS_TYPE_STRING, &name, 01138 DBUS_TYPE_UINT32, &flags, 01139 DBUS_TYPE_INVALID)) 01140 { 01141 dbus_message_unref (message); 01142 _DBUS_SET_OOM (error); 01143 return -1; 01144 } 01145 01146 reply = dbus_connection_send_with_reply_and_block (connection, message, -1, 01147 error); 01148 01149 dbus_message_unref (message); 01150 01151 if (reply == NULL) 01152 { 01153 _DBUS_ASSERT_ERROR_IS_SET (error); 01154 return -1; 01155 } 01156 01157 if (dbus_set_error_from_message (error, reply)) 01158 { 01159 _DBUS_ASSERT_ERROR_IS_SET (error); 01160 dbus_message_unref (reply); 01161 return -1; 01162 } 01163 01164 if (!dbus_message_get_args (reply, error, 01165 DBUS_TYPE_UINT32, &result, 01166 DBUS_TYPE_INVALID)) 01167 { 01168 _DBUS_ASSERT_ERROR_IS_SET (error); 01169 dbus_message_unref (reply); 01170 return -1; 01171 } 01172 01173 dbus_message_unref (reply); 01174 01175 return result; 01176 } 01177 01178 01197 int 01198 dbus_bus_release_name (DBusConnection *connection, 01199 const char *name, 01200 DBusError *error) 01201 { 01202 DBusMessage *message, *reply; 01203 dbus_uint32_t result; 01204 01205 _dbus_return_val_if_fail (connection != NULL, 0); 01206 _dbus_return_val_if_fail (name != NULL, 0); 01207 _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0); 01208 _dbus_return_val_if_error_is_set (error, 0); 01209 01210 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, 01211 DBUS_PATH_DBUS, 01212 DBUS_INTERFACE_DBUS, 01213 "ReleaseName"); 01214 01215 if (message == NULL) 01216 { 01217 _DBUS_SET_OOM (error); 01218 return -1; 01219 } 01220 01221 if (!dbus_message_append_args (message, 01222 DBUS_TYPE_STRING, &name, 01223 DBUS_TYPE_INVALID)) 01224 { 01225 dbus_message_unref (message); 01226 _DBUS_SET_OOM (error); 01227 return -1; 01228 } 01229 01230 reply = dbus_connection_send_with_reply_and_block (connection, message, -1, 01231 error); 01232 01233 dbus_message_unref (message); 01234 01235 if (reply == NULL) 01236 { 01237 _DBUS_ASSERT_ERROR_IS_SET (error); 01238 return -1; 01239 } 01240 01241 if (dbus_set_error_from_message (error, reply)) 01242 { 01243 _DBUS_ASSERT_ERROR_IS_SET (error); 01244 dbus_message_unref (reply); 01245 return -1; 01246 } 01247 01248 if (!dbus_message_get_args (reply, error, 01249 DBUS_TYPE_UINT32, &result, 01250 DBUS_TYPE_INVALID)) 01251 { 01252 _DBUS_ASSERT_ERROR_IS_SET (error); 01253 dbus_message_unref (reply); 01254 return -1; 01255 } 01256 01257 dbus_message_unref (reply); 01258 01259 return result; 01260 } 01261 01279 dbus_bool_t 01280 dbus_bus_name_has_owner (DBusConnection *connection, 01281 const char *name, 01282 DBusError *error) 01283 { 01284 DBusMessage *message, *reply; 01285 dbus_bool_t exists; 01286 01287 _dbus_return_val_if_fail (connection != NULL, FALSE); 01288 _dbus_return_val_if_fail (name != NULL, FALSE); 01289 _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE); 01290 _dbus_return_val_if_error_is_set (error, FALSE); 01291 01292 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, 01293 DBUS_PATH_DBUS, 01294 DBUS_INTERFACE_DBUS, 01295 "NameHasOwner"); 01296 if (message == NULL) 01297 { 01298 _DBUS_SET_OOM (error); 01299 return FALSE; 01300 } 01301 01302 if (!dbus_message_append_args (message, 01303 DBUS_TYPE_STRING, &name, 01304 DBUS_TYPE_INVALID)) 01305 { 01306 dbus_message_unref (message); 01307 _DBUS_SET_OOM (error); 01308 return FALSE; 01309 } 01310 01311 reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error); 01312 dbus_message_unref (message); 01313 01314 if (reply == NULL) 01315 { 01316 _DBUS_ASSERT_ERROR_IS_SET (error); 01317 return FALSE; 01318 } 01319 01320 if (!dbus_message_get_args (reply, error, 01321 DBUS_TYPE_BOOLEAN, &exists, 01322 DBUS_TYPE_INVALID)) 01323 { 01324 _DBUS_ASSERT_ERROR_IS_SET (error); 01325 dbus_message_unref (reply); 01326 return FALSE; 01327 } 01328 01329 dbus_message_unref (reply); 01330 return exists; 01331 } 01332 01355 dbus_bool_t 01356 dbus_bus_start_service_by_name (DBusConnection *connection, 01357 const char *name, 01358 dbus_uint32_t flags, 01359 dbus_uint32_t *result, 01360 DBusError *error) 01361 { 01362 DBusMessage *msg; 01363 DBusMessage *reply; 01364 01365 _dbus_return_val_if_fail (connection != NULL, FALSE); 01366 _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE); 01367 01368 msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS, 01369 DBUS_PATH_DBUS, 01370 DBUS_INTERFACE_DBUS, 01371 "StartServiceByName"); 01372 01373 if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name, 01374 DBUS_TYPE_UINT32, &flags, DBUS_TYPE_INVALID)) 01375 { 01376 dbus_message_unref (msg); 01377 _DBUS_SET_OOM (error); 01378 return FALSE; 01379 } 01380 01381 reply = dbus_connection_send_with_reply_and_block (connection, msg, 01382 -1, error); 01383 dbus_message_unref (msg); 01384 01385 if (reply == NULL) 01386 { 01387 _DBUS_ASSERT_ERROR_IS_SET (error); 01388 return FALSE; 01389 } 01390 01391 if (dbus_set_error_from_message (error, reply)) 01392 { 01393 _DBUS_ASSERT_ERROR_IS_SET (error); 01394 dbus_message_unref (reply); 01395 return FALSE; 01396 } 01397 01398 if (result != NULL && 01399 !dbus_message_get_args (reply, error, DBUS_TYPE_UINT32, 01400 result, DBUS_TYPE_INVALID)) 01401 { 01402 _DBUS_ASSERT_ERROR_IS_SET (error); 01403 dbus_message_unref (reply); 01404 return FALSE; 01405 } 01406 01407 dbus_message_unref (reply); 01408 return TRUE; 01409 } 01410 01411 static void 01412 send_no_return_values (DBusConnection *connection, 01413 DBusMessage *msg, 01414 DBusError *error) 01415 { 01416 if (error) 01417 { 01418 /* Block to check success codepath */ 01419 DBusMessage *reply; 01420 01421 reply = dbus_connection_send_with_reply_and_block (connection, msg, 01422 -1, error); 01423 01424 if (reply == NULL) 01425 _DBUS_ASSERT_ERROR_IS_SET (error); 01426 else 01427 dbus_message_unref (reply); 01428 } 01429 else 01430 { 01431 /* Silently-fail nonblocking codepath */ 01432 dbus_message_set_no_reply (msg, TRUE); 01433 dbus_connection_send (connection, msg, NULL); 01434 } 01435 } 01436 01525 void 01526 dbus_bus_add_match (DBusConnection *connection, 01527 const char *rule, 01528 DBusError *error) 01529 { 01530 DBusMessage *msg; 01531 01532 _dbus_return_if_fail (rule != NULL); 01533 01534 msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS, 01535 DBUS_PATH_DBUS, 01536 DBUS_INTERFACE_DBUS, 01537 "AddMatch"); 01538 01539 if (msg == NULL) 01540 { 01541 _DBUS_SET_OOM (error); 01542 return; 01543 } 01544 01545 if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule, 01546 DBUS_TYPE_INVALID)) 01547 { 01548 dbus_message_unref (msg); 01549 _DBUS_SET_OOM (error); 01550 return; 01551 } 01552 01553 send_no_return_values (connection, msg, error); 01554 01555 dbus_message_unref (msg); 01556 } 01557 01575 void 01576 dbus_bus_remove_match (DBusConnection *connection, 01577 const char *rule, 01578 DBusError *error) 01579 { 01580 DBusMessage *msg; 01581 01582 _dbus_return_if_fail (rule != NULL); 01583 01584 msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS, 01585 DBUS_PATH_DBUS, 01586 DBUS_INTERFACE_DBUS, 01587 "RemoveMatch"); 01588 01589 if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule, 01590 DBUS_TYPE_INVALID)) 01591 { 01592 dbus_message_unref (msg); 01593 _DBUS_SET_OOM (error); 01594 return; 01595 } 01596 01597 send_no_return_values (connection, msg, error); 01598 01599 dbus_message_unref (msg); 01600 } 01601