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