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 "activation.h"
00026 #include "connection.h"
00027 #include "driver.h"
00028 #include "dispatch.h"
00029 #include "services.h"
00030 #include "utils.h"
00031 #include <dbus/dbus-string.h>
00032 #include <dbus/dbus-internals.h>
00033 #include <string.h>
00034
00035 static dbus_bool_t bus_driver_send_welcome_message (DBusConnection *connection,
00036 DBusMessage *hello_message,
00037 BusTransaction *transaction,
00038 DBusError *error);
00039
00040 dbus_bool_t
00041 bus_driver_send_service_deleted (const char *service_name,
00042 BusTransaction *transaction,
00043 DBusError *error)
00044 {
00045 DBusMessage *message;
00046 dbus_bool_t retval;
00047
00048 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00049
00050 _dbus_verbose ("sending service deleted: %s\n", service_name);
00051
00052 message = dbus_message_new (DBUS_MESSAGE_SERVICE_DELETED,
00053 DBUS_SERVICE_BROADCAST);
00054 if (message == NULL)
00055 {
00056 BUS_SET_OOM (error);
00057 return FALSE;
00058 }
00059
00060 if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS) ||
00061 !dbus_message_append_args (message,
00062 DBUS_TYPE_STRING, service_name,
00063 DBUS_TYPE_INVALID))
00064 {
00065 dbus_message_unref (message);
00066 BUS_SET_OOM (error);
00067 return FALSE;
00068 }
00069
00070 retval = bus_dispatch_broadcast_message (transaction, NULL, message, error);
00071 dbus_message_unref (message);
00072
00073 return retval;
00074 }
00075
00076 dbus_bool_t
00077 bus_driver_send_service_created (const char *service_name,
00078 BusTransaction *transaction,
00079 DBusError *error)
00080 {
00081 DBusMessage *message;
00082 dbus_bool_t retval;
00083
00084 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00085
00086 message = dbus_message_new (DBUS_MESSAGE_SERVICE_CREATED,
00087 DBUS_SERVICE_BROADCAST);
00088 if (message == NULL)
00089 {
00090 BUS_SET_OOM (error);
00091 return FALSE;
00092 }
00093
00094 if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS))
00095 {
00096 dbus_message_unref (message);
00097 BUS_SET_OOM (error);
00098 return FALSE;
00099 }
00100
00101 if (!dbus_message_append_args (message,
00102 DBUS_TYPE_STRING, service_name,
00103 DBUS_TYPE_INVALID))
00104 {
00105 dbus_message_unref (message);
00106 BUS_SET_OOM (error);
00107 return FALSE;
00108 }
00109
00110 retval = bus_dispatch_broadcast_message (transaction, NULL, message, error);
00111 dbus_message_unref (message);
00112
00113 return retval;
00114 }
00115
00116 dbus_bool_t
00117 bus_driver_send_service_lost (DBusConnection *connection,
00118 const char *service_name,
00119 BusTransaction *transaction,
00120 DBusError *error)
00121 {
00122 DBusMessage *message;
00123
00124 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00125
00126 message = dbus_message_new (DBUS_MESSAGE_SERVICE_LOST,
00127 bus_connection_get_name (connection));
00128 if (message == NULL)
00129 {
00130 BUS_SET_OOM (error);
00131 return FALSE;
00132 }
00133
00134 if (!dbus_message_append_args (message,
00135 DBUS_TYPE_STRING, service_name,
00136 DBUS_TYPE_INVALID))
00137 {
00138 dbus_message_unref (message);
00139 BUS_SET_OOM (error);
00140 return FALSE;
00141 }
00142
00143 if (!bus_transaction_send_from_driver (transaction, connection, message))
00144 {
00145 dbus_message_unref (message);
00146 BUS_SET_OOM (error);
00147 return FALSE;
00148 }
00149 else
00150 {
00151 dbus_message_unref (message);
00152 return TRUE;
00153 }
00154 }
00155
00156 dbus_bool_t
00157 bus_driver_send_service_acquired (DBusConnection *connection,
00158 const char *service_name,
00159 BusTransaction *transaction,
00160 DBusError *error)
00161 {
00162 DBusMessage *message;
00163
00164 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00165
00166 message = dbus_message_new (DBUS_MESSAGE_SERVICE_ACQUIRED,
00167 bus_connection_get_name (connection));
00168
00169 if (message == NULL)
00170 {
00171 BUS_SET_OOM (error);
00172 return FALSE;
00173 }
00174
00175 if (!dbus_message_append_args (message,
00176 DBUS_TYPE_STRING, service_name,
00177 DBUS_TYPE_INVALID))
00178 {
00179 dbus_message_unref (message);
00180 BUS_SET_OOM (error);
00181 return FALSE;
00182 }
00183
00184 if (!bus_transaction_send_from_driver (transaction, connection, message))
00185 {
00186 dbus_message_unref (message);
00187 BUS_SET_OOM (error);
00188 return FALSE;
00189 }
00190 else
00191 {
00192 dbus_message_unref (message);
00193 return TRUE;
00194 }
00195 }
00196
00197 static dbus_bool_t
00198 create_unique_client_name (BusRegistry *registry,
00199 DBusString *str)
00200 {
00201
00202
00203
00204
00205
00206
00207
00208 static int next_major_number = 0;
00209 static int next_minor_number = 0;
00210 int len;
00211
00212 len = _dbus_string_get_length (str);
00213
00214 while (TRUE)
00215 {
00216
00217
00218
00219 if (next_minor_number <= 0)
00220 {
00221 next_major_number += 1;
00222 next_minor_number = 0;
00223 if (next_major_number <= 0)
00224 _dbus_assert_not_reached ("INT_MAX * INT_MAX clients were added");
00225 }
00226
00227 _dbus_assert (next_major_number > 0);
00228 _dbus_assert (next_minor_number >= 0);
00229
00230
00231
00232 if (!_dbus_string_append (str, ":"))
00233 return FALSE;
00234
00235 if (!_dbus_string_append_int (str, next_major_number))
00236 return FALSE;
00237
00238 if (!_dbus_string_append (str, "-"))
00239 return FALSE;
00240
00241 if (!_dbus_string_append_int (str, next_minor_number))
00242 return FALSE;
00243
00244 next_minor_number += 1;
00245
00246
00247 if (bus_registry_lookup (registry, str) == NULL)
00248 break;
00249
00250
00251 _dbus_string_set_length (str, len);
00252 }
00253
00254 return TRUE;
00255 }
00256
00257 static dbus_bool_t
00258 bus_driver_handle_hello (DBusConnection *connection,
00259 BusTransaction *transaction,
00260 DBusMessage *message,
00261 DBusError *error)
00262 {
00263 DBusString unique_name;
00264 BusService *service;
00265 dbus_bool_t retval;
00266 BusRegistry *registry;
00267 BusConnections *connections;
00268
00269 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00270
00271
00272
00273
00274
00275
00276
00277 connections = bus_connection_get_connections (connection);
00278 if (!bus_connections_check_limits (connections, connection,
00279 error))
00280 {
00281 _DBUS_ASSERT_ERROR_IS_SET (error);
00282 return FALSE;
00283 }
00284
00285 if (!_dbus_string_init (&unique_name))
00286 {
00287 BUS_SET_OOM (error);
00288 return FALSE;
00289 }
00290
00291 retval = FALSE;
00292
00293 registry = bus_connection_get_registry (connection);
00294
00295 if (!create_unique_client_name (registry, &unique_name))
00296 {
00297 BUS_SET_OOM (error);
00298 goto out_0;
00299 }
00300
00301 if (!bus_connection_complete (connection, &unique_name, error))
00302 {
00303 _DBUS_ASSERT_ERROR_IS_SET (error);
00304 goto out_0;
00305 }
00306
00307 if (!dbus_message_set_sender (message,
00308 bus_connection_get_name (connection)))
00309 {
00310 BUS_SET_OOM (error);
00311 goto out_0;
00312 }
00313
00314 if (!bus_driver_send_welcome_message (connection, message, transaction, error))
00315 goto out_0;
00316
00317
00318 service = bus_registry_ensure (registry,
00319 &unique_name, connection, transaction, error);
00320 if (service == NULL)
00321 goto out_0;
00322
00323 bus_service_set_prohibit_replacement (service, TRUE);
00324
00325 retval = TRUE;
00326
00327 out_0:
00328 _dbus_string_free (&unique_name);
00329 return retval;
00330 }
00331
00332 static dbus_bool_t
00333 bus_driver_send_welcome_message (DBusConnection *connection,
00334 DBusMessage *hello_message,
00335 BusTransaction *transaction,
00336 DBusError *error)
00337 {
00338 DBusMessage *welcome;
00339 const char *name;
00340
00341 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00342
00343 name = bus_connection_get_name (connection);
00344 _dbus_assert (name != NULL);
00345
00346 welcome = dbus_message_new_reply (hello_message);
00347 if (welcome == NULL)
00348 {
00349 BUS_SET_OOM (error);
00350 return FALSE;
00351 }
00352
00353 if (!dbus_message_append_args (welcome,
00354 DBUS_TYPE_STRING, name,
00355 DBUS_TYPE_INVALID))
00356 {
00357 dbus_message_unref (welcome);
00358 BUS_SET_OOM (error);
00359 return FALSE;
00360 }
00361
00362 if (!bus_transaction_send_from_driver (transaction, connection, welcome))
00363 {
00364 dbus_message_unref (welcome);
00365 BUS_SET_OOM (error);
00366 return FALSE;
00367 }
00368 else
00369 {
00370 dbus_message_unref (welcome);
00371 return TRUE;
00372 }
00373 }
00374
00375 static dbus_bool_t
00376 bus_driver_handle_list_services (DBusConnection *connection,
00377 BusTransaction *transaction,
00378 DBusMessage *message,
00379 DBusError *error)
00380 {
00381 DBusMessage *reply;
00382 int len;
00383 char **services;
00384 BusRegistry *registry;
00385
00386 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00387
00388 registry = bus_connection_get_registry (connection);
00389
00390 reply = dbus_message_new_reply (message);
00391 if (reply == NULL)
00392 {
00393 BUS_SET_OOM (error);
00394 return FALSE;
00395 }
00396
00397 if (!bus_registry_list_services (registry, &services, &len))
00398 {
00399 dbus_message_unref (reply);
00400 BUS_SET_OOM (error);
00401 return FALSE;
00402 }
00403
00404 if (!dbus_message_append_args (reply,
00405 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, services, len,
00406 DBUS_TYPE_INVALID))
00407 {
00408 dbus_free_string_array (services);
00409 dbus_message_unref (reply);
00410 BUS_SET_OOM (error);
00411 return FALSE;
00412 }
00413
00414 dbus_free_string_array (services);
00415
00416 if (!bus_transaction_send_from_driver (transaction, connection, reply))
00417 {
00418 dbus_message_unref (reply);
00419 BUS_SET_OOM (error);
00420 return FALSE;
00421 }
00422 else
00423 {
00424 dbus_message_unref (reply);
00425 return TRUE;
00426 }
00427 }
00428
00429 static dbus_bool_t
00430 bus_driver_handle_acquire_service (DBusConnection *connection,
00431 BusTransaction *transaction,
00432 DBusMessage *message,
00433 DBusError *error)
00434 {
00435 DBusMessage *reply;
00436 DBusString service_name;
00437 char *name;
00438 int service_reply;
00439 int flags;
00440 dbus_bool_t retval;
00441 BusRegistry *registry;
00442
00443 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00444
00445 registry = bus_connection_get_registry (connection);
00446
00447 if (!dbus_message_get_args (message, error,
00448 DBUS_TYPE_STRING, &name,
00449 DBUS_TYPE_UINT32, &flags,
00450 DBUS_TYPE_INVALID))
00451 return FALSE;
00452
00453 _dbus_verbose ("Trying to own service %s with flags 0x%x\n", name, flags);
00454
00455 retval = FALSE;
00456 reply = NULL;
00457
00458 _dbus_string_init_const (&service_name, name);
00459
00460 if (!bus_registry_acquire_service (registry, connection,
00461 &service_name, flags,
00462 &service_reply, transaction,
00463 error))
00464 goto out;
00465
00466 reply = dbus_message_new_reply (message);
00467 if (reply == NULL)
00468 {
00469 BUS_SET_OOM (error);
00470 goto out;
00471 }
00472
00473 if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, service_reply, DBUS_TYPE_INVALID))
00474 {
00475 BUS_SET_OOM (error);
00476 goto out;
00477 }
00478
00479 if (!bus_transaction_send_from_driver (transaction, connection, reply))
00480 {
00481 BUS_SET_OOM (error);
00482 goto out;
00483 }
00484
00485 retval = TRUE;
00486
00487 out:
00488 dbus_free (name);
00489 if (reply)
00490 dbus_message_unref (reply);
00491 return retval;
00492 }
00493
00494 static dbus_bool_t
00495 bus_driver_handle_service_exists (DBusConnection *connection,
00496 BusTransaction *transaction,
00497 DBusMessage *message,
00498 DBusError *error)
00499 {
00500 DBusMessage *reply;
00501 DBusString service_name;
00502 BusService *service;
00503 char *name;
00504 dbus_bool_t retval;
00505 BusRegistry *registry;
00506
00507 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00508
00509 registry = bus_connection_get_registry (connection);
00510
00511 if (!dbus_message_get_args (message, error,
00512 DBUS_TYPE_STRING, &name,
00513 DBUS_TYPE_INVALID))
00514 return FALSE;
00515
00516 retval = FALSE;
00517
00518 _dbus_string_init_const (&service_name, name);
00519 service = bus_registry_lookup (registry, &service_name);
00520
00521 reply = dbus_message_new_reply (message);
00522 if (reply == NULL)
00523 {
00524 BUS_SET_OOM (error);
00525 goto out;
00526 }
00527
00528 if (!dbus_message_append_args (reply,
00529 DBUS_TYPE_UINT32, service != NULL,
00530 0))
00531 {
00532 BUS_SET_OOM (error);
00533 goto out;
00534 }
00535
00536 if (!bus_transaction_send_from_driver (transaction, connection, reply))
00537 {
00538 BUS_SET_OOM (error);
00539 goto out;
00540 }
00541
00542 retval = TRUE;
00543
00544 out:
00545 if (reply)
00546 dbus_message_unref (reply);
00547 dbus_free (name);
00548
00549 return retval;
00550 }
00551
00552 static dbus_bool_t
00553 bus_driver_handle_activate_service (DBusConnection *connection,
00554 BusTransaction *transaction,
00555 DBusMessage *message,
00556 DBusError *error)
00557 {
00558 dbus_uint32_t flags;
00559 char *name;
00560 dbus_bool_t retval;
00561 BusActivation *activation;
00562
00563 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00564
00565 activation = bus_connection_get_activation (connection);
00566
00567 if (!dbus_message_get_args (message, error,
00568 DBUS_TYPE_STRING, &name,
00569 DBUS_TYPE_UINT32, &flags,
00570 DBUS_TYPE_INVALID))
00571 {
00572 _DBUS_ASSERT_ERROR_IS_SET (error);
00573 _dbus_verbose ("No memory to get arguments to ActivateService\n");
00574 return FALSE;
00575 }
00576
00577 retval = FALSE;
00578
00579 if (!bus_activation_activate_service (activation, connection, transaction,
00580 message, name, error))
00581 {
00582 _DBUS_ASSERT_ERROR_IS_SET (error);
00583 _dbus_verbose ("bus_activation_activate_service() failed\n");
00584 goto out;
00585 }
00586
00587 retval = TRUE;
00588
00589 out:
00590 dbus_free (name);
00591 return retval;
00592 }
00593
00594
00595
00596
00597
00598 struct
00599 {
00600 const char *name;
00601 dbus_bool_t (* handler) (DBusConnection *connection,
00602 BusTransaction *transaction,
00603 DBusMessage *message,
00604 DBusError *error);
00605 } message_handlers[] = {
00606 { DBUS_MESSAGE_ACQUIRE_SERVICE, bus_driver_handle_acquire_service },
00607 { DBUS_MESSAGE_ACTIVATE_SERVICE, bus_driver_handle_activate_service },
00608 { DBUS_MESSAGE_HELLO, bus_driver_handle_hello },
00609 { DBUS_MESSAGE_SERVICE_EXISTS, bus_driver_handle_service_exists },
00610 { DBUS_MESSAGE_LIST_SERVICES, bus_driver_handle_list_services }
00611 };
00612
00613 dbus_bool_t
00614 bus_driver_handle_message (DBusConnection *connection,
00615 BusTransaction *transaction,
00616 DBusMessage *message,
00617 DBusError *error)
00618 {
00619 const char *name, *sender;
00620 int i;
00621
00622 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00623
00624 _dbus_verbose ("Driver got a message: %s\n",
00625 dbus_message_get_name (message));
00626
00627 name = dbus_message_get_name (message);
00628 sender = dbus_message_get_sender (message);
00629
00630
00631 _dbus_assert (sender != NULL || strcmp (name, DBUS_MESSAGE_HELLO) == 0);
00632
00633 if (dbus_message_get_reply_serial (message) == 0)
00634 {
00635 _dbus_verbose ("Client sent a reply to the bus driver, ignoring it\n");
00636 return TRUE;
00637 }
00638
00639 i = 0;
00640 while (i < _DBUS_N_ELEMENTS (message_handlers))
00641 {
00642 if (strcmp (message_handlers[i].name, name) == 0)
00643 {
00644 _dbus_verbose ("Running driver handler for %s\n", name);
00645 if ((* message_handlers[i].handler) (connection, transaction, message, error))
00646 {
00647 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00648 _dbus_verbose ("Driver handler succeeded\n");
00649 return TRUE;
00650 }
00651 else
00652 {
00653 _DBUS_ASSERT_ERROR_IS_SET (error);
00654 _dbus_verbose ("Driver handler returned failure\n");
00655 return FALSE;
00656 }
00657 }
00658
00659 ++i;
00660 }
00661
00662 _dbus_verbose ("No driver handler for %s\n", name);
00663
00664 dbus_set_error (error, DBUS_ERROR_UNKNOWN_MESSAGE,
00665 "%s does not understand message %s",
00666 DBUS_SERVICE_DBUS, name);
00667
00668 return FALSE;
00669 }
00670
00671 void
00672 bus_driver_remove_connection (DBusConnection *connection)
00673 {
00674
00675
00676
00677 }