00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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 <string.h>
00032
00059 typedef struct
00060 {
00061 DBusConnection *connection;
00062 char *unique_name;
00064 unsigned int is_well_known : 1;
00065 } BusData;
00066
00069 static dbus_int32_t bus_data_slot = -1;
00070
00072 #define N_BUS_TYPES 3
00073
00074 static DBusConnection *bus_connections[N_BUS_TYPES];
00075 static char *bus_connection_addresses[N_BUS_TYPES] = { NULL, NULL, NULL };
00076
00077 static DBusBusType activation_bus_type = DBUS_BUS_STARTER;
00078
00079 static dbus_bool_t initialized = FALSE;
00080
00084 _DBUS_DEFINE_GLOBAL_LOCK (bus);
00085
00086 static void
00087 addresses_shutdown_func (void *data)
00088 {
00089 int i;
00090
00091 i = 0;
00092 while (i < N_BUS_TYPES)
00093 {
00094 if (bus_connections[i] != NULL)
00095 _dbus_warn ("dbus_shutdown() called but connections were still live!");
00096
00097 dbus_free (bus_connection_addresses[i]);
00098 bus_connection_addresses[i] = NULL;
00099 ++i;
00100 }
00101
00102 activation_bus_type = DBUS_BUS_STARTER;
00103 }
00104
00105 static dbus_bool_t
00106 get_from_env (char **connection_p,
00107 const char *env_var)
00108 {
00109 const char *s;
00110
00111 _dbus_assert (*connection_p == NULL);
00112
00113 s = _dbus_getenv (env_var);
00114 if (s == NULL || *s == '\0')
00115 return TRUE;
00116 else
00117 {
00118 *connection_p = _dbus_strdup (s);
00119 return *connection_p != NULL;
00120 }
00121 }
00122
00123 static dbus_bool_t
00124 init_connections_unlocked (void)
00125 {
00126 if (!initialized)
00127 {
00128 const char *s;
00129 int i;
00130
00131 i = 0;
00132 while (i < N_BUS_TYPES)
00133 {
00134 bus_connections[i] = NULL;
00135 ++i;
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145 if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
00146 {
00147 _dbus_verbose ("Filling in system bus address...\n");
00148
00149 if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SYSTEM],
00150 "DBUS_SYSTEM_BUS_ADDRESS"))
00151 return FALSE;
00152 }
00153
00154
00155 if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
00156 {
00157
00158 bus_connection_addresses[DBUS_BUS_SYSTEM] =
00159 _dbus_strdup (DBUS_SYSTEM_BUS_DEFAULT_ADDRESS);
00160 if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
00161 return FALSE;
00162
00163 _dbus_verbose (" used default system bus \"%s\"\n",
00164 bus_connection_addresses[DBUS_BUS_SYSTEM]);
00165 }
00166 else
00167 _dbus_verbose (" used env var system bus \"%s\"\n",
00168 bus_connection_addresses[DBUS_BUS_SYSTEM]);
00169
00170 if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
00171 {
00172 _dbus_verbose ("Filling in session bus address...\n");
00173
00174 if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SESSION],
00175 "DBUS_SESSION_BUS_ADDRESS"))
00176 return FALSE;
00177 _dbus_verbose (" \"%s\"\n", bus_connection_addresses[DBUS_BUS_SESSION] ?
00178 bus_connection_addresses[DBUS_BUS_SESSION] : "none set");
00179 }
00180
00181 if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
00182 {
00183 _dbus_verbose ("Filling in activation bus address...\n");
00184
00185 if (!get_from_env (&bus_connection_addresses[DBUS_BUS_STARTER],
00186 "DBUS_STARTER_ADDRESS"))
00187 return FALSE;
00188
00189 _dbus_verbose (" \"%s\"\n", bus_connection_addresses[DBUS_BUS_STARTER] ?
00190 bus_connection_addresses[DBUS_BUS_STARTER] : "none set");
00191 }
00192
00193
00194 if (bus_connection_addresses[DBUS_BUS_STARTER] != NULL)
00195 {
00196 s = _dbus_getenv ("DBUS_STARTER_BUS_TYPE");
00197
00198 if (s != NULL)
00199 {
00200 _dbus_verbose ("Bus activation type was set to \"%s\"\n", s);
00201
00202 if (strcmp (s, "system") == 0)
00203 activation_bus_type = DBUS_BUS_SYSTEM;
00204 else if (strcmp (s, "session") == 0)
00205 activation_bus_type = DBUS_BUS_SESSION;
00206 }
00207 }
00208 else
00209 {
00210
00211 if (bus_connection_addresses[DBUS_BUS_SESSION] != NULL)
00212 {
00213 bus_connection_addresses[DBUS_BUS_STARTER] =
00214 _dbus_strdup (bus_connection_addresses[DBUS_BUS_SESSION]);
00215 if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
00216 return FALSE;
00217 }
00218 }
00219
00220
00221
00222
00223
00224 if (!_dbus_setenv ("DBUS_ACTIVATION_ADDRESS", NULL))
00225 return FALSE;
00226
00227 if (!_dbus_setenv ("DBUS_ACTIVATION_BUS_TYPE", NULL))
00228 return FALSE;
00229
00230 if (!_dbus_register_shutdown_func (addresses_shutdown_func,
00231 NULL))
00232 return FALSE;
00233
00234 initialized = TRUE;
00235 }
00236
00237 return initialized;
00238 }
00239
00240 static void
00241 bus_data_free (void *data)
00242 {
00243 BusData *bd = data;
00244
00245 if (bd->is_well_known)
00246 {
00247 int i;
00248 _DBUS_LOCK (bus);
00249
00250 i = 0;
00251 while (i < N_BUS_TYPES)
00252 {
00253 if (bus_connections[i] == bd->connection)
00254 bus_connections[i] = NULL;
00255
00256 ++i;
00257 }
00258 _DBUS_UNLOCK (bus);
00259 }
00260
00261 dbus_free (bd->unique_name);
00262 dbus_free (bd);
00263
00264 dbus_connection_free_data_slot (&bus_data_slot);
00265 }
00266
00267 static BusData*
00268 ensure_bus_data (DBusConnection *connection)
00269 {
00270 BusData *bd;
00271
00272 if (!dbus_connection_allocate_data_slot (&bus_data_slot))
00273 return NULL;
00274
00275 bd = dbus_connection_get_data (connection, bus_data_slot);
00276 if (bd == NULL)
00277 {
00278 bd = dbus_new0 (BusData, 1);
00279 if (bd == NULL)
00280 {
00281 dbus_connection_free_data_slot (&bus_data_slot);
00282 return NULL;
00283 }
00284
00285 bd->connection = connection;
00286
00287 if (!dbus_connection_set_data (connection, bus_data_slot, bd,
00288 bus_data_free))
00289 {
00290 dbus_free (bd);
00291 dbus_connection_free_data_slot (&bus_data_slot);
00292 return NULL;
00293 }
00294
00295
00296 }
00297 else
00298 {
00299 dbus_connection_free_data_slot (&bus_data_slot);
00300 }
00301
00302 return bd;
00303 }
00304
00306
00323 DBusConnection *
00324 dbus_bus_get (DBusBusType type,
00325 DBusError *error)
00326 {
00327 const char *address;
00328 DBusConnection *connection;
00329 BusData *bd;
00330 DBusBusType address_type;
00331
00332 _dbus_return_val_if_fail (type >= 0 && type < N_BUS_TYPES, NULL);
00333 _dbus_return_val_if_error_is_set (error, NULL);
00334
00335 _DBUS_LOCK (bus);
00336
00337 if (!init_connections_unlocked ())
00338 {
00339 _DBUS_UNLOCK (bus);
00340 _DBUS_SET_OOM (error);
00341 return NULL;
00342 }
00343
00344
00345
00346
00347
00348 address_type = type;
00349
00350
00351
00352
00353
00354
00355 if (type == DBUS_BUS_STARTER &&
00356 bus_connection_addresses[activation_bus_type] != NULL)
00357 type = activation_bus_type;
00358
00359 if (bus_connections[type] != NULL)
00360 {
00361 connection = bus_connections[type];
00362 dbus_connection_ref (connection);
00363
00364 _DBUS_UNLOCK (bus);
00365 return connection;
00366 }
00367
00368 address = bus_connection_addresses[address_type];
00369 if (address == NULL)
00370 {
00371 dbus_set_error (error, DBUS_ERROR_FAILED,
00372 "Unable to determine the address of the message bus");
00373 _DBUS_UNLOCK (bus);
00374 return NULL;
00375 }
00376
00377 connection = dbus_connection_open (address, error);
00378
00379 if (!connection)
00380 {
00381 _DBUS_ASSERT_ERROR_IS_SET (error);
00382 _DBUS_UNLOCK (bus);
00383 return NULL;
00384 }
00385
00386
00387
00388
00389 dbus_connection_set_exit_on_disconnect (connection,
00390 TRUE);
00391
00392 if (!dbus_bus_register (connection, error))
00393 {
00394 _DBUS_ASSERT_ERROR_IS_SET (error);
00395 dbus_connection_close (connection);
00396 dbus_connection_unref (connection);
00397
00398 _DBUS_UNLOCK (bus);
00399 return NULL;
00400 }
00401
00402 bus_connections[type] = connection;
00403 bd = ensure_bus_data (connection);
00404 _dbus_assert (bd != NULL);
00405
00406 bd->is_well_known = TRUE;
00407
00408 _DBUS_UNLOCK (bus);
00409 return connection;
00410 }
00411
00412
00423 dbus_bool_t
00424 dbus_bus_register (DBusConnection *connection,
00425 DBusError *error)
00426 {
00427 DBusMessage *message, *reply;
00428 char *name;
00429 BusData *bd;
00430 dbus_bool_t retval;
00431
00432 _dbus_return_val_if_fail (connection != NULL, FALSE);
00433 _dbus_return_val_if_error_is_set (error, FALSE);
00434
00435 retval = FALSE;
00436
00437 bd = ensure_bus_data (connection);
00438 if (bd == NULL)
00439 {
00440 _DBUS_SET_OOM (error);
00441 return FALSE;
00442 }
00443
00444 if (bd->unique_name != NULL)
00445 {
00446 _dbus_warn ("Attempt to register the same DBusConnection with the message bus, but it is already registered\n");
00447
00448
00449
00450 return TRUE;
00451 }
00452
00453 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00454 DBUS_PATH_DBUS,
00455 DBUS_INTERFACE_DBUS,
00456 "Hello");
00457
00458 if (!message)
00459 {
00460 _DBUS_SET_OOM (error);
00461 return FALSE;
00462 }
00463
00464 reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
00465
00466 dbus_message_unref (message);
00467
00468 if (reply == NULL)
00469 goto out;
00470 else if (dbus_set_error_from_message (error, reply))
00471 goto out;
00472 else if (!dbus_message_get_args (reply, error,
00473 DBUS_TYPE_STRING, &name,
00474 DBUS_TYPE_INVALID))
00475 goto out;
00476
00477 bd->unique_name = _dbus_strdup (name);
00478 if (bd->unique_name == NULL)
00479 {
00480 _DBUS_SET_OOM (error);
00481 goto out;
00482 }
00483
00484 retval = TRUE;
00485
00486 out:
00487 if (reply)
00488 dbus_message_unref (reply);
00489
00490 if (!retval)
00491 _DBUS_ASSERT_ERROR_IS_SET (error);
00492
00493 return retval;
00494 }
00495
00496
00506 dbus_bool_t
00507 dbus_bus_set_unique_name (DBusConnection *connection,
00508 const char *unique_name)
00509 {
00510 BusData *bd;
00511
00512 _dbus_return_val_if_fail (connection != NULL, FALSE);
00513 _dbus_return_val_if_fail (unique_name != NULL, FALSE);
00514
00515 bd = ensure_bus_data (connection);
00516 if (bd == NULL)
00517 return FALSE;
00518
00519 _dbus_assert (bd->unique_name == NULL);
00520
00521 bd->unique_name = _dbus_strdup (unique_name);
00522 return bd->unique_name != NULL;
00523 }
00524
00535 const char*
00536 dbus_bus_get_unique_name (DBusConnection *connection)
00537 {
00538 BusData *bd;
00539
00540 _dbus_return_val_if_fail (connection != NULL, NULL);
00541
00542 bd = ensure_bus_data (connection);
00543 if (bd == NULL)
00544 return NULL;
00545
00546 return bd->unique_name;
00547 }
00548
00558 unsigned long
00559 dbus_bus_get_unix_user (DBusConnection *connection,
00560 const char *name,
00561 DBusError *error)
00562 {
00563 DBusMessage *message, *reply;
00564 dbus_uint32_t uid;
00565
00566 _dbus_return_val_if_fail (connection != NULL, DBUS_UID_UNSET);
00567 _dbus_return_val_if_fail (name != NULL, DBUS_UID_UNSET);
00568 _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), DBUS_UID_UNSET);
00569 _dbus_return_val_if_error_is_set (error, DBUS_UID_UNSET);
00570
00571 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00572 DBUS_PATH_DBUS,
00573 DBUS_INTERFACE_DBUS,
00574 "GetConnectionUnixUser");
00575
00576 if (message == NULL)
00577 {
00578 _DBUS_SET_OOM (error);
00579 return DBUS_UID_UNSET;
00580 }
00581
00582 if (!dbus_message_append_args (message,
00583 DBUS_TYPE_STRING, &name,
00584 DBUS_TYPE_INVALID))
00585 {
00586 dbus_message_unref (message);
00587 _DBUS_SET_OOM (error);
00588 return DBUS_UID_UNSET;
00589 }
00590
00591 reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
00592 error);
00593
00594 dbus_message_unref (message);
00595
00596 if (reply == NULL)
00597 {
00598 _DBUS_ASSERT_ERROR_IS_SET (error);
00599 return DBUS_UID_UNSET;
00600 }
00601
00602 if (dbus_set_error_from_message (error, reply))
00603 {
00604 _DBUS_ASSERT_ERROR_IS_SET (error);
00605 dbus_message_unref (reply);
00606 return DBUS_UID_UNSET;
00607 }
00608
00609 if (!dbus_message_get_args (reply, error,
00610 DBUS_TYPE_UINT32, &uid,
00611 DBUS_TYPE_INVALID))
00612 {
00613 _DBUS_ASSERT_ERROR_IS_SET (error);
00614 dbus_message_unref (reply);
00615 return DBUS_UID_UNSET;
00616 }
00617
00618 dbus_message_unref (reply);
00619
00620 return (unsigned long) uid;
00621 }
00622
00623
00686 int
00687 dbus_bus_request_name (DBusConnection *connection,
00688 const char *name,
00689 unsigned int flags,
00690 DBusError *error)
00691 {
00692 DBusMessage *message, *reply;
00693 dbus_uint32_t result;
00694
00695 _dbus_return_val_if_fail (connection != NULL, 0);
00696 _dbus_return_val_if_fail (name != NULL, 0);
00697 _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
00698 _dbus_return_val_if_error_is_set (error, 0);
00699
00700 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00701 DBUS_PATH_DBUS,
00702 DBUS_INTERFACE_DBUS,
00703 "RequestName");
00704
00705 if (message == NULL)
00706 {
00707 _DBUS_SET_OOM (error);
00708 return -1;
00709 }
00710
00711 if (!dbus_message_append_args (message,
00712 DBUS_TYPE_STRING, &name,
00713 DBUS_TYPE_UINT32, &flags,
00714 DBUS_TYPE_INVALID))
00715 {
00716 dbus_message_unref (message);
00717 _DBUS_SET_OOM (error);
00718 return -1;
00719 }
00720
00721 reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
00722 error);
00723
00724 dbus_message_unref (message);
00725
00726 if (reply == NULL)
00727 {
00728 _DBUS_ASSERT_ERROR_IS_SET (error);
00729 return -1;
00730 }
00731
00732 if (dbus_set_error_from_message (error, reply))
00733 {
00734 _DBUS_ASSERT_ERROR_IS_SET (error);
00735 dbus_message_unref (reply);
00736 return -1;
00737 }
00738
00739 if (!dbus_message_get_args (reply, error,
00740 DBUS_TYPE_UINT32, &result,
00741 DBUS_TYPE_INVALID))
00742 {
00743 _DBUS_ASSERT_ERROR_IS_SET (error);
00744 dbus_message_unref (reply);
00745 return -1;
00746 }
00747
00748 dbus_message_unref (reply);
00749
00750 return result;
00751 }
00752
00761 dbus_bool_t
00762 dbus_bus_name_has_owner (DBusConnection *connection,
00763 const char *name,
00764 DBusError *error)
00765 {
00766 DBusMessage *message, *reply;
00767 dbus_bool_t exists;
00768
00769 _dbus_return_val_if_fail (connection != NULL, FALSE);
00770 _dbus_return_val_if_fail (name != NULL, FALSE);
00771 _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
00772 _dbus_return_val_if_error_is_set (error, FALSE);
00773
00774 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00775 DBUS_PATH_DBUS,
00776 DBUS_INTERFACE_DBUS,
00777 "NameHasOwner");
00778 if (message == NULL)
00779 {
00780 _DBUS_SET_OOM (error);
00781 return FALSE;
00782 }
00783
00784 if (!dbus_message_append_args (message,
00785 DBUS_TYPE_STRING, &name,
00786 DBUS_TYPE_INVALID))
00787 {
00788 dbus_message_unref (message);
00789 _DBUS_SET_OOM (error);
00790 return FALSE;
00791 }
00792
00793 reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
00794 dbus_message_unref (message);
00795
00796 if (reply == NULL)
00797 {
00798 _DBUS_ASSERT_ERROR_IS_SET (error);
00799 return FALSE;
00800 }
00801
00802 if (!dbus_message_get_args (reply, error,
00803 DBUS_TYPE_BOOLEAN, &exists,
00804 DBUS_TYPE_INVALID))
00805 {
00806 _DBUS_ASSERT_ERROR_IS_SET (error);
00807 dbus_message_unref (reply);
00808 return FALSE;
00809 }
00810
00811 dbus_message_unref (reply);
00812 return exists;
00813 }
00814
00831 dbus_bool_t
00832 dbus_bus_start_service_by_name (DBusConnection *connection,
00833 const char *name,
00834 dbus_uint32_t flags,
00835 dbus_uint32_t *result,
00836 DBusError *error)
00837 {
00838 DBusMessage *msg;
00839 DBusMessage *reply;
00840
00841 _dbus_return_val_if_fail (connection != NULL, FALSE);
00842 _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
00843
00844 msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00845 DBUS_PATH_DBUS,
00846 DBUS_INTERFACE_DBUS,
00847 "StartServiceByName");
00848
00849 if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name,
00850 DBUS_TYPE_UINT32, &flags, DBUS_TYPE_INVALID))
00851 {
00852 dbus_message_unref (msg);
00853 _DBUS_SET_OOM (error);
00854 return FALSE;
00855 }
00856
00857 reply = dbus_connection_send_with_reply_and_block (connection, msg,
00858 -1, error);
00859 dbus_message_unref (msg);
00860
00861 if (reply == NULL)
00862 {
00863 _DBUS_ASSERT_ERROR_IS_SET (error);
00864 return FALSE;
00865 }
00866
00867 if (dbus_set_error_from_message (error, reply))
00868 {
00869 _DBUS_ASSERT_ERROR_IS_SET (error);
00870 dbus_message_unref (reply);
00871 return FALSE;
00872 }
00873
00874 if (result != NULL &&
00875 !dbus_message_get_args (reply, error, DBUS_TYPE_UINT32,
00876 result, DBUS_TYPE_INVALID))
00877 {
00878 _DBUS_ASSERT_ERROR_IS_SET (error);
00879 dbus_message_unref (reply);
00880 return FALSE;
00881 }
00882
00883 dbus_message_unref (reply);
00884 return TRUE;
00885 }
00886
00887 static void
00888 send_no_return_values (DBusConnection *connection,
00889 DBusMessage *msg,
00890 DBusError *error)
00891 {
00892 if (error)
00893 {
00894
00895 DBusMessage *reply;
00896
00897 reply = dbus_connection_send_with_reply_and_block (connection, msg,
00898 -1, error);
00899
00900 if (reply == NULL)
00901 _DBUS_ASSERT_ERROR_IS_SET (error);
00902 else
00903 dbus_message_unref (reply);
00904 }
00905 else
00906 {
00907
00908 dbus_message_set_no_reply (msg, TRUE);
00909 dbus_connection_send (connection, msg, NULL);
00910 }
00911 }
00912
00935 void
00936 dbus_bus_add_match (DBusConnection *connection,
00937 const char *rule,
00938 DBusError *error)
00939 {
00940 DBusMessage *msg;
00941
00942 _dbus_return_if_fail (rule != NULL);
00943
00944 msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00945 DBUS_PATH_DBUS,
00946 DBUS_INTERFACE_DBUS,
00947 "AddMatch");
00948
00949 if (msg == NULL)
00950 {
00951 _DBUS_SET_OOM (error);
00952 return;
00953 }
00954
00955 if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
00956 DBUS_TYPE_INVALID))
00957 {
00958 dbus_message_unref (msg);
00959 _DBUS_SET_OOM (error);
00960 return;
00961 }
00962
00963 send_no_return_values (connection, msg, error);
00964
00965 dbus_message_unref (msg);
00966 }
00967
00981 void
00982 dbus_bus_remove_match (DBusConnection *connection,
00983 const char *rule,
00984 DBusError *error)
00985 {
00986 DBusMessage *msg;
00987
00988 _dbus_return_if_fail (rule != NULL);
00989
00990 msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00991 DBUS_PATH_DBUS,
00992 DBUS_INTERFACE_DBUS,
00993 "RemoveMatch");
00994
00995 if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
00996 DBUS_TYPE_INVALID))
00997 {
00998 dbus_message_unref (msg);
00999 _DBUS_SET_OOM (error);
01000 return;
01001 }
01002
01003 send_no_return_values (connection, msg, error);
01004
01005 dbus_message_unref (msg);
01006 }
01007