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
00063 typedef struct
00064 {
00065 DBusConnection *connection;
00066 char *unique_name;
00068 unsigned int is_well_known : 1;
00069 } BusData;
00070
00073 static dbus_int32_t bus_data_slot = -1;
00074
00076 #define N_BUS_TYPES 3
00077
00078 static DBusConnection *bus_connections[N_BUS_TYPES];
00079 static char *bus_connection_addresses[N_BUS_TYPES] = { NULL, NULL, NULL };
00080
00081 static DBusBusType activation_bus_type = DBUS_BUS_STARTER;
00082
00083 static dbus_bool_t initialized = FALSE;
00084
00088 _DBUS_DEFINE_GLOBAL_LOCK (bus);
00089
00090 static void
00091 addresses_shutdown_func (void *data)
00092 {
00093 int i;
00094
00095 i = 0;
00096 while (i < N_BUS_TYPES)
00097 {
00098 if (bus_connections[i] != NULL)
00099 _dbus_warn ("dbus_shutdown() called but connections were still live!");
00100
00101 dbus_free (bus_connection_addresses[i]);
00102 bus_connection_addresses[i] = NULL;
00103 ++i;
00104 }
00105
00106 activation_bus_type = DBUS_BUS_STARTER;
00107 }
00108
00109 static dbus_bool_t
00110 get_from_env (char **connection_p,
00111 const char *env_var)
00112 {
00113 const char *s;
00114
00115 _dbus_assert (*connection_p == NULL);
00116
00117 s = _dbus_getenv (env_var);
00118 if (s == NULL || *s == '\0')
00119 return TRUE;
00120 else
00121 {
00122 *connection_p = _dbus_strdup (s);
00123 return *connection_p != NULL;
00124 }
00125 }
00126
00127 static dbus_bool_t
00128 init_connections_unlocked (void)
00129 {
00130 if (!initialized)
00131 {
00132 const char *s;
00133 int i;
00134
00135 i = 0;
00136 while (i < N_BUS_TYPES)
00137 {
00138 bus_connections[i] = NULL;
00139 ++i;
00140 }
00141
00142
00143
00144
00145
00146
00147
00148
00149 if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
00150 {
00151 _dbus_verbose ("Filling in system bus address...\n");
00152
00153 if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SYSTEM],
00154 "DBUS_SYSTEM_BUS_ADDRESS"))
00155 return FALSE;
00156 }
00157
00158
00159 if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
00160 {
00161
00162 bus_connection_addresses[DBUS_BUS_SYSTEM] =
00163 _dbus_strdup (DBUS_SYSTEM_BUS_DEFAULT_ADDRESS);
00164 if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
00165 return FALSE;
00166
00167 _dbus_verbose (" used default system bus \"%s\"\n",
00168 bus_connection_addresses[DBUS_BUS_SYSTEM]);
00169 }
00170 else
00171 _dbus_verbose (" used env var system bus \"%s\"\n",
00172 bus_connection_addresses[DBUS_BUS_SYSTEM]);
00173
00174 if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
00175 {
00176 _dbus_verbose ("Filling in session bus address...\n");
00177
00178 if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SESSION],
00179 "DBUS_SESSION_BUS_ADDRESS"))
00180 return FALSE;
00181 _dbus_verbose (" \"%s\"\n", bus_connection_addresses[DBUS_BUS_SESSION] ?
00182 bus_connection_addresses[DBUS_BUS_SESSION] : "none set");
00183 }
00184
00185 if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
00186 {
00187 _dbus_verbose ("Filling in activation bus address...\n");
00188
00189 if (!get_from_env (&bus_connection_addresses[DBUS_BUS_STARTER],
00190 "DBUS_STARTER_ADDRESS"))
00191 return FALSE;
00192
00193 _dbus_verbose (" \"%s\"\n", bus_connection_addresses[DBUS_BUS_STARTER] ?
00194 bus_connection_addresses[DBUS_BUS_STARTER] : "none set");
00195 }
00196
00197
00198 if (bus_connection_addresses[DBUS_BUS_STARTER] != NULL)
00199 {
00200 s = _dbus_getenv ("DBUS_STARTER_BUS_TYPE");
00201
00202 if (s != NULL)
00203 {
00204 _dbus_verbose ("Bus activation type was set to \"%s\"\n", s);
00205
00206 if (strcmp (s, "system") == 0)
00207 activation_bus_type = DBUS_BUS_SYSTEM;
00208 else if (strcmp (s, "session") == 0)
00209 activation_bus_type = DBUS_BUS_SESSION;
00210 }
00211 }
00212 else
00213 {
00214
00215 if (bus_connection_addresses[DBUS_BUS_SESSION] != NULL)
00216 {
00217 bus_connection_addresses[DBUS_BUS_STARTER] =
00218 _dbus_strdup (bus_connection_addresses[DBUS_BUS_SESSION]);
00219 if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
00220 return FALSE;
00221 }
00222 }
00223
00224
00225
00226
00227
00228 if (!_dbus_setenv ("DBUS_ACTIVATION_ADDRESS", NULL))
00229 return FALSE;
00230
00231 if (!_dbus_setenv ("DBUS_ACTIVATION_BUS_TYPE", NULL))
00232 return FALSE;
00233
00234 if (!_dbus_register_shutdown_func (addresses_shutdown_func,
00235 NULL))
00236 return FALSE;
00237
00238 initialized = TRUE;
00239 }
00240
00241 return initialized;
00242 }
00243
00244 static void
00245 bus_data_free (void *data)
00246 {
00247 BusData *bd = data;
00248
00249 if (bd->is_well_known)
00250 {
00251 int i;
00252 _DBUS_LOCK (bus);
00253
00254 i = 0;
00255 while (i < N_BUS_TYPES)
00256 {
00257 if (bus_connections[i] == bd->connection)
00258 bus_connections[i] = NULL;
00259
00260 ++i;
00261 }
00262 _DBUS_UNLOCK (bus);
00263 }
00264
00265 dbus_free (bd->unique_name);
00266 dbus_free (bd);
00267
00268 dbus_connection_free_data_slot (&bus_data_slot);
00269 }
00270
00271 static BusData*
00272 ensure_bus_data (DBusConnection *connection)
00273 {
00274 BusData *bd;
00275
00276 if (!dbus_connection_allocate_data_slot (&bus_data_slot))
00277 return NULL;
00278
00279 bd = dbus_connection_get_data (connection, bus_data_slot);
00280 if (bd == NULL)
00281 {
00282 bd = dbus_new0 (BusData, 1);
00283 if (bd == NULL)
00284 {
00285 dbus_connection_free_data_slot (&bus_data_slot);
00286 return NULL;
00287 }
00288
00289 bd->connection = connection;
00290
00291 if (!dbus_connection_set_data (connection, bus_data_slot, bd,
00292 bus_data_free))
00293 {
00294 dbus_free (bd);
00295 dbus_connection_free_data_slot (&bus_data_slot);
00296 return NULL;
00297 }
00298
00299
00300 }
00301 else
00302 {
00303 dbus_connection_free_data_slot (&bus_data_slot);
00304 }
00305
00306 return bd;
00307 }
00308
00310
00327 DBusConnection *
00328 dbus_bus_get (DBusBusType type,
00329 DBusError *error)
00330 {
00331 const char *address;
00332 DBusConnection *connection;
00333 BusData *bd;
00334 DBusBusType address_type;
00335
00336 _dbus_return_val_if_fail (type >= 0 && type < N_BUS_TYPES, NULL);
00337 _dbus_return_val_if_error_is_set (error, NULL);
00338
00339 _DBUS_LOCK (bus);
00340
00341 if (!init_connections_unlocked ())
00342 {
00343 _DBUS_UNLOCK (bus);
00344 _DBUS_SET_OOM (error);
00345 return NULL;
00346 }
00347
00348
00349
00350
00351
00352 address_type = type;
00353
00354
00355
00356
00357
00358
00359 if (type == DBUS_BUS_STARTER &&
00360 bus_connection_addresses[activation_bus_type] != NULL)
00361 type = activation_bus_type;
00362
00363 if (bus_connections[type] != NULL)
00364 {
00365 connection = bus_connections[type];
00366 dbus_connection_ref (connection);
00367
00368 _DBUS_UNLOCK (bus);
00369 return connection;
00370 }
00371
00372 address = bus_connection_addresses[address_type];
00373 if (address == NULL)
00374 {
00375 dbus_set_error (error, DBUS_ERROR_FAILED,
00376 "Unable to determine the address of the message bus");
00377 _DBUS_UNLOCK (bus);
00378 return NULL;
00379 }
00380
00381 connection = dbus_connection_open (address, error);
00382
00383 if (!connection)
00384 {
00385 _DBUS_ASSERT_ERROR_IS_SET (error);
00386 _DBUS_UNLOCK (bus);
00387 return NULL;
00388 }
00389
00390
00391
00392
00393 dbus_connection_set_exit_on_disconnect (connection,
00394 TRUE);
00395
00396 if (!dbus_bus_register (connection, error))
00397 {
00398 _DBUS_ASSERT_ERROR_IS_SET (error);
00399 dbus_connection_close (connection);
00400 dbus_connection_unref (connection);
00401
00402 _DBUS_UNLOCK (bus);
00403 return NULL;
00404 }
00405
00406 bus_connections[type] = connection;
00407 bd = ensure_bus_data (connection);
00408 _dbus_assert (bd != NULL);
00409
00410 bd->is_well_known = TRUE;
00411
00412 _DBUS_UNLOCK (bus);
00413 return connection;
00414 }
00415
00416
00427 dbus_bool_t
00428 dbus_bus_register (DBusConnection *connection,
00429 DBusError *error)
00430 {
00431 DBusMessage *message, *reply;
00432 char *name;
00433 BusData *bd;
00434 dbus_bool_t retval;
00435
00436 _dbus_return_val_if_fail (connection != NULL, FALSE);
00437 _dbus_return_val_if_error_is_set (error, FALSE);
00438
00439 retval = FALSE;
00440
00441 bd = ensure_bus_data (connection);
00442 if (bd == NULL)
00443 {
00444 _DBUS_SET_OOM (error);
00445 return FALSE;
00446 }
00447
00448 if (bd->unique_name != NULL)
00449 {
00450 _dbus_warn ("Attempt to register the same DBusConnection with the message bus, but it is already registered\n");
00451
00452
00453
00454 return TRUE;
00455 }
00456
00457 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00458 DBUS_PATH_DBUS,
00459 DBUS_INTERFACE_DBUS,
00460 "Hello");
00461
00462 if (!message)
00463 {
00464 _DBUS_SET_OOM (error);
00465 return FALSE;
00466 }
00467
00468 reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
00469
00470 dbus_message_unref (message);
00471
00472 if (reply == NULL)
00473 goto out;
00474 else if (dbus_set_error_from_message (error, reply))
00475 goto out;
00476 else if (!dbus_message_get_args (reply, error,
00477 DBUS_TYPE_STRING, &name,
00478 DBUS_TYPE_INVALID))
00479 goto out;
00480
00481 bd->unique_name = _dbus_strdup (name);
00482 if (bd->unique_name == NULL)
00483 {
00484 _DBUS_SET_OOM (error);
00485 goto out;
00486 }
00487
00488 retval = TRUE;
00489
00490 out:
00491 if (reply)
00492 dbus_message_unref (reply);
00493
00494 if (!retval)
00495 _DBUS_ASSERT_ERROR_IS_SET (error);
00496
00497 return retval;
00498 }
00499
00500
00510 dbus_bool_t
00511 dbus_bus_set_unique_name (DBusConnection *connection,
00512 const char *unique_name)
00513 {
00514 BusData *bd;
00515
00516 _dbus_return_val_if_fail (connection != NULL, FALSE);
00517 _dbus_return_val_if_fail (unique_name != NULL, FALSE);
00518
00519 bd = ensure_bus_data (connection);
00520 if (bd == NULL)
00521 return FALSE;
00522
00523 _dbus_assert (bd->unique_name == NULL);
00524
00525 bd->unique_name = _dbus_strdup (unique_name);
00526 return bd->unique_name != NULL;
00527 }
00528
00536 const char*
00537 dbus_bus_get_unique_name (DBusConnection *connection)
00538 {
00539 BusData *bd;
00540
00541 _dbus_return_val_if_fail (connection != NULL, NULL);
00542
00543 bd = ensure_bus_data (connection);
00544 if (bd == NULL)
00545 return NULL;
00546
00547 return bd->unique_name;
00548 }
00549
00559 unsigned long
00560 dbus_bus_get_unix_user (DBusConnection *connection,
00561 const char *name,
00562 DBusError *error)
00563 {
00564 DBusMessage *message, *reply;
00565 dbus_uint32_t uid;
00566
00567 _dbus_return_val_if_fail (connection != NULL, DBUS_UID_UNSET);
00568 _dbus_return_val_if_fail (name != NULL, DBUS_UID_UNSET);
00569 _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), DBUS_UID_UNSET);
00570 _dbus_return_val_if_error_is_set (error, DBUS_UID_UNSET);
00571
00572 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00573 DBUS_PATH_DBUS,
00574 DBUS_INTERFACE_DBUS,
00575 "GetConnectionUnixUser");
00576
00577 if (message == NULL)
00578 {
00579 _DBUS_SET_OOM (error);
00580 return DBUS_UID_UNSET;
00581 }
00582
00583 if (!dbus_message_append_args (message,
00584 DBUS_TYPE_STRING, &name,
00585 DBUS_TYPE_INVALID))
00586 {
00587 dbus_message_unref (message);
00588 _DBUS_SET_OOM (error);
00589 return DBUS_UID_UNSET;
00590 }
00591
00592 reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
00593 error);
00594
00595 dbus_message_unref (message);
00596
00597 if (reply == NULL)
00598 {
00599 _DBUS_ASSERT_ERROR_IS_SET (error);
00600 return DBUS_UID_UNSET;
00601 }
00602
00603 if (dbus_set_error_from_message (error, reply))
00604 {
00605 _DBUS_ASSERT_ERROR_IS_SET (error);
00606 dbus_message_unref (reply);
00607 return DBUS_UID_UNSET;
00608 }
00609
00610 if (!dbus_message_get_args (reply, error,
00611 DBUS_TYPE_UINT32, &uid,
00612 DBUS_TYPE_INVALID))
00613 {
00614 _DBUS_ASSERT_ERROR_IS_SET (error);
00615 dbus_message_unref (reply);
00616 return DBUS_UID_UNSET;
00617 }
00618
00619 dbus_message_unref (reply);
00620
00621 return (unsigned long) uid;
00622 }
00623
00624
00640 int
00641 dbus_bus_request_name (DBusConnection *connection,
00642 const char *name,
00643 unsigned int flags,
00644 DBusError *error)
00645 {
00646 DBusMessage *message, *reply;
00647 dbus_uint32_t result;
00648
00649 _dbus_return_val_if_fail (connection != NULL, 0);
00650 _dbus_return_val_if_fail (name != NULL, 0);
00651 _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
00652 _dbus_return_val_if_error_is_set (error, 0);
00653
00654 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00655 DBUS_PATH_DBUS,
00656 DBUS_INTERFACE_DBUS,
00657 "RequestName");
00658
00659 if (message == NULL)
00660 {
00661 _DBUS_SET_OOM (error);
00662 return -1;
00663 }
00664
00665 if (!dbus_message_append_args (message,
00666 DBUS_TYPE_STRING, &name,
00667 DBUS_TYPE_UINT32, &flags,
00668 DBUS_TYPE_INVALID))
00669 {
00670 dbus_message_unref (message);
00671 _DBUS_SET_OOM (error);
00672 return -1;
00673 }
00674
00675 reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
00676 error);
00677
00678 dbus_message_unref (message);
00679
00680 if (reply == NULL)
00681 {
00682 _DBUS_ASSERT_ERROR_IS_SET (error);
00683 return -1;
00684 }
00685
00686 if (dbus_set_error_from_message (error, reply))
00687 {
00688 _DBUS_ASSERT_ERROR_IS_SET (error);
00689 dbus_message_unref (reply);
00690 return -1;
00691 }
00692
00693 if (!dbus_message_get_args (reply, error,
00694 DBUS_TYPE_UINT32, &result,
00695 DBUS_TYPE_INVALID))
00696 {
00697 _DBUS_ASSERT_ERROR_IS_SET (error);
00698 dbus_message_unref (reply);
00699 return -1;
00700 }
00701
00702 dbus_message_unref (reply);
00703
00704 return result;
00705 }
00706
00715 dbus_bool_t
00716 dbus_bus_name_has_owner (DBusConnection *connection,
00717 const char *name,
00718 DBusError *error)
00719 {
00720 DBusMessage *message, *reply;
00721 dbus_bool_t exists;
00722
00723 _dbus_return_val_if_fail (connection != NULL, FALSE);
00724 _dbus_return_val_if_fail (name != NULL, FALSE);
00725 _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
00726 _dbus_return_val_if_error_is_set (error, FALSE);
00727
00728 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00729 DBUS_PATH_DBUS,
00730 DBUS_INTERFACE_DBUS,
00731 "NameHasOwner");
00732 if (message == NULL)
00733 {
00734 _DBUS_SET_OOM (error);
00735 return FALSE;
00736 }
00737
00738 if (!dbus_message_append_args (message,
00739 DBUS_TYPE_STRING, &name,
00740 DBUS_TYPE_INVALID))
00741 {
00742 dbus_message_unref (message);
00743 _DBUS_SET_OOM (error);
00744 return FALSE;
00745 }
00746
00747 reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
00748 dbus_message_unref (message);
00749
00750 if (reply == NULL)
00751 {
00752 _DBUS_ASSERT_ERROR_IS_SET (error);
00753 return FALSE;
00754 }
00755
00756 if (!dbus_message_get_args (reply, error,
00757 DBUS_TYPE_BOOLEAN, &exists,
00758 DBUS_TYPE_INVALID))
00759 {
00760 _DBUS_ASSERT_ERROR_IS_SET (error);
00761 dbus_message_unref (reply);
00762 return FALSE;
00763 }
00764
00765 dbus_message_unref (reply);
00766 return exists;
00767 }
00768
00784 dbus_bool_t
00785 dbus_bus_start_service_by_name (DBusConnection *connection,
00786 const char *name,
00787 dbus_uint32_t flags,
00788 dbus_uint32_t *result,
00789 DBusError *error)
00790 {
00791 DBusMessage *msg;
00792 DBusMessage *reply;
00793
00794 _dbus_return_val_if_fail (connection != NULL, FALSE);
00795 _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
00796
00797 msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00798 DBUS_PATH_DBUS,
00799 DBUS_INTERFACE_DBUS,
00800 "StartServiceByName");
00801
00802 if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name,
00803 DBUS_TYPE_UINT32, &flags, DBUS_TYPE_INVALID))
00804 {
00805 dbus_message_unref (msg);
00806 _DBUS_SET_OOM (error);
00807 return FALSE;
00808 }
00809
00810 reply = dbus_connection_send_with_reply_and_block (connection, msg,
00811 -1, error);
00812 dbus_message_unref (msg);
00813
00814 if (reply == NULL)
00815 {
00816 _DBUS_ASSERT_ERROR_IS_SET (error);
00817 return FALSE;
00818 }
00819
00820 if (dbus_set_error_from_message (error, reply))
00821 {
00822 _DBUS_ASSERT_ERROR_IS_SET (error);
00823 dbus_message_unref (reply);
00824 return FALSE;
00825 }
00826
00827 if (result != NULL &&
00828 !dbus_message_get_args (reply, error, DBUS_TYPE_UINT32,
00829 result, DBUS_TYPE_INVALID))
00830 {
00831 _DBUS_ASSERT_ERROR_IS_SET (error);
00832 dbus_message_unref (reply);
00833 return FALSE;
00834 }
00835
00836 dbus_message_unref (reply);
00837 return TRUE;
00838 }
00839
00840 static void
00841 send_no_return_values (DBusConnection *connection,
00842 DBusMessage *msg,
00843 DBusError *error)
00844 {
00845 if (error)
00846 {
00847
00848 DBusMessage *reply;
00849
00850 reply = dbus_connection_send_with_reply_and_block (connection, msg,
00851 -1, error);
00852
00853 if (reply == NULL)
00854 _DBUS_ASSERT_ERROR_IS_SET (error);
00855 else
00856 dbus_message_unref (reply);
00857 }
00858 else
00859 {
00860
00861 dbus_message_set_no_reply (msg, TRUE);
00862 dbus_connection_send (connection, msg, NULL);
00863 }
00864 }
00865
00888 void
00889 dbus_bus_add_match (DBusConnection *connection,
00890 const char *rule,
00891 DBusError *error)
00892 {
00893 DBusMessage *msg;
00894
00895 _dbus_return_if_fail (rule != NULL);
00896
00897 msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00898 DBUS_PATH_DBUS,
00899 DBUS_INTERFACE_DBUS,
00900 "AddMatch");
00901
00902 if (msg == NULL)
00903 {
00904 _DBUS_SET_OOM (error);
00905 return;
00906 }
00907
00908 if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
00909 DBUS_TYPE_INVALID))
00910 {
00911 dbus_message_unref (msg);
00912 _DBUS_SET_OOM (error);
00913 return;
00914 }
00915
00916 send_no_return_values (connection, msg, error);
00917
00918 dbus_message_unref (msg);
00919 }
00920
00934 void
00935 dbus_bus_remove_match (DBusConnection *connection,
00936 const char *rule,
00937 DBusError *error)
00938 {
00939 DBusMessage *msg;
00940
00941 _dbus_return_if_fail (rule != NULL);
00942
00943 msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
00944 DBUS_PATH_DBUS,
00945 DBUS_INTERFACE_DBUS,
00946 "RemoveMatch");
00947
00948 if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
00949 DBUS_TYPE_INVALID))
00950 {
00951 dbus_message_unref (msg);
00952 _DBUS_SET_OOM (error);
00953 return;
00954 }
00955
00956 send_no_return_values (connection, msg, error);
00957
00958 dbus_message_unref (msg);
00959 }
00960