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 "dispatch.h"
00026 #include "connection.h"
00027 #include "driver.h"
00028 #include "services.h"
00029 #include "utils.h"
00030 #include "bus.h"
00031 #include "signals.h"
00032 #include "test.h"
00033 #include <dbus/dbus-internals.h>
00034 #include <string.h>
00035
00036 static dbus_bool_t
00037 send_one_message (DBusConnection *connection,
00038 BusContext *context,
00039 DBusConnection *sender,
00040 DBusConnection *addressed_recipient,
00041 DBusMessage *message,
00042 BusTransaction *transaction,
00043 DBusError *error)
00044 {
00045 if (!bus_context_check_security_policy (context,
00046 sender,
00047 addressed_recipient,
00048 connection,
00049 message,
00050 NULL))
00051 return TRUE;
00052
00053 if (!bus_transaction_send (transaction,
00054 connection,
00055 message))
00056 {
00057 BUS_SET_OOM (error);
00058 return FALSE;
00059 }
00060
00061 return TRUE;
00062 }
00063
00064 dbus_bool_t
00065 bus_dispatch_matches (BusTransaction *transaction,
00066 DBusConnection *sender,
00067 DBusConnection *addressed_recipient,
00068 DBusMessage *message,
00069 DBusError *error)
00070 {
00071 DBusError tmp_error;
00072 BusConnections *connections;
00073 DBusList *recipients;
00074 BusMatchmaker *matchmaker;
00075 DBusList *link;
00076 BusContext *context;
00077
00078 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00079
00080
00081
00082
00083
00084 _dbus_assert (sender == NULL || bus_connection_is_active (sender));
00085 _dbus_assert (dbus_message_get_sender (message) != NULL);
00086
00087 connections = bus_transaction_get_connections (transaction);
00088
00089 dbus_error_init (&tmp_error);
00090 context = bus_transaction_get_context (transaction);
00091 matchmaker = bus_context_get_matchmaker (context);
00092
00093 recipients = NULL;
00094 if (!bus_matchmaker_get_recipients (matchmaker,
00095 bus_context_get_connections (context),
00096 sender, addressed_recipient, message,
00097 &recipients))
00098 {
00099 BUS_SET_OOM (error);
00100 return FALSE;
00101 }
00102
00103 link = _dbus_list_get_first_link (&recipients);
00104 while (link != NULL)
00105 {
00106 DBusConnection *dest;
00107
00108 dest = link->data;
00109
00110 if (!send_one_message (dest, context, sender, addressed_recipient,
00111 message, transaction, &tmp_error))
00112 break;
00113
00114 link = _dbus_list_get_next_link (&recipients, link);
00115 }
00116
00117 _dbus_list_clear (&recipients);
00118
00119 if (dbus_error_is_set (&tmp_error))
00120 {
00121 dbus_move_error (&tmp_error, error);
00122 return FALSE;
00123 }
00124 else
00125 return TRUE;
00126 }
00127
00128 static DBusHandlerResult
00129 bus_dispatch (DBusConnection *connection,
00130 DBusMessage *message)
00131 {
00132 const char *sender, *service_name;
00133 DBusError error;
00134 BusTransaction *transaction;
00135 BusContext *context;
00136 DBusHandlerResult result;
00137 DBusConnection *addressed_recipient;
00138
00139 result = DBUS_HANDLER_RESULT_HANDLED;
00140
00141 transaction = NULL;
00142 addressed_recipient = NULL;
00143 dbus_error_init (&error);
00144
00145 context = bus_connection_get_context (connection);
00146 _dbus_assert (context != NULL);
00147
00148
00149
00150
00151 while (!bus_connection_preallocate_oom_error (connection))
00152 _dbus_wait_for_memory ();
00153
00154
00155 dbus_connection_ref (connection);
00156
00157 service_name = dbus_message_get_destination (message);
00158
00159 #ifdef DBUS_ENABLE_VERBOSE_MODE
00160 {
00161 const char *interface_name, *member_name, *error_name;
00162
00163 interface_name = dbus_message_get_interface (message);
00164 member_name = dbus_message_get_member (message);
00165 error_name = dbus_message_get_error_name (message);
00166
00167 _dbus_verbose ("DISPATCH: %s %s %s to %s\n",
00168 interface_name ? interface_name : "(no interface)",
00169 member_name ? member_name : "(no member)",
00170 error_name ? error_name : "(no error name)",
00171 service_name ? service_name : "peer");
00172 }
00173 #endif
00174
00175
00176
00177
00178
00179
00180
00181 if (service_name == NULL)
00182 {
00183 if (dbus_message_is_signal (message,
00184 DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
00185 "Disconnected"))
00186 {
00187 bus_connection_disconnected (connection);
00188 goto out;
00189 }
00190
00191 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL)
00192 {
00193
00194
00195
00196 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00197 goto out;
00198 }
00199 }
00200
00201
00202 transaction = bus_transaction_new (context);
00203 if (transaction == NULL)
00204 {
00205 BUS_SET_OOM (&error);
00206 goto out;
00207 }
00208
00209
00210 if (bus_connection_is_active (connection))
00211 {
00212 sender = bus_connection_get_name (connection);
00213 _dbus_assert (sender != NULL);
00214
00215 if (!dbus_message_set_sender (message, sender))
00216 {
00217 BUS_SET_OOM (&error);
00218 goto out;
00219 }
00220
00221
00222
00223
00224
00225
00226 service_name = dbus_message_get_destination (message);
00227 }
00228
00229 if (service_name &&
00230 strcmp (service_name, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS) == 0)
00231 {
00232 if (!bus_context_check_security_policy (context,
00233 connection, NULL, NULL, message, &error))
00234 {
00235 _dbus_verbose ("Security policy rejected message\n");
00236 goto out;
00237 }
00238
00239 _dbus_verbose ("Giving message to %s\n", DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
00240 if (!bus_driver_handle_message (connection, transaction, message, &error))
00241 goto out;
00242 }
00243 else if (!bus_connection_is_active (connection))
00244 {
00245 _dbus_verbose ("Received message from non-registered client. Disconnecting.\n");
00246 dbus_connection_disconnect (connection);
00247 goto out;
00248 }
00249 else if (service_name != NULL)
00250 {
00251 DBusString service_string;
00252 BusService *service;
00253 BusRegistry *registry;
00254
00255 _dbus_assert (service_name != NULL);
00256
00257 registry = bus_connection_get_registry (connection);
00258
00259 _dbus_string_init_const (&service_string, service_name);
00260 service = bus_registry_lookup (registry, &service_string);
00261
00262 if (service == NULL)
00263 {
00264 dbus_set_error (&error,
00265 DBUS_ERROR_SERVICE_DOES_NOT_EXIST,
00266 "Service \"%s\" does not exist",
00267 service_name);
00268 goto out;
00269 }
00270 else
00271 {
00272 addressed_recipient = bus_service_get_primary_owner (service);
00273 _dbus_assert (addressed_recipient != NULL);
00274
00275 if (!bus_context_check_security_policy (context,
00276 connection, addressed_recipient,
00277 addressed_recipient,
00278 message, &error))
00279 goto out;
00280
00281
00282 if (!bus_transaction_send (transaction, addressed_recipient, message))
00283 {
00284 BUS_SET_OOM (&error);
00285 goto out;
00286 }
00287 }
00288 }
00289
00290
00291
00292
00293 if (!bus_dispatch_matches (transaction, connection, addressed_recipient, message, &error))
00294 goto out;
00295
00296 out:
00297 if (dbus_error_is_set (&error))
00298 {
00299 if (!dbus_connection_get_is_connected (connection))
00300 {
00301
00302
00303
00304 _dbus_verbose ("Not sending error to connection we disconnected\n");
00305 }
00306 else if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
00307 {
00308 bus_connection_send_oom_error (connection, message);
00309
00310
00311 if (transaction != NULL)
00312 {
00313 bus_transaction_cancel_and_free (transaction);
00314 transaction = NULL;
00315 }
00316 }
00317 else
00318 {
00319
00320
00321
00322 _dbus_assert (transaction != NULL);
00323
00324 if (!bus_transaction_send_error_reply (transaction, connection,
00325 &error, message))
00326 {
00327 bus_connection_send_oom_error (connection, message);
00328
00329
00330 if (transaction != NULL)
00331 {
00332 bus_transaction_cancel_and_free (transaction);
00333 transaction = NULL;
00334 }
00335 }
00336 }
00337
00338 dbus_error_free (&error);
00339 }
00340
00341 if (transaction != NULL)
00342 {
00343 bus_transaction_execute_and_free (transaction);
00344 }
00345
00346 dbus_connection_unref (connection);
00347
00348 return result;
00349 }
00350
00351 static DBusHandlerResult
00352 bus_dispatch_message_filter (DBusConnection *connection,
00353 DBusMessage *message,
00354 void *user_data)
00355 {
00356 return bus_dispatch (connection, message);
00357 }
00358
00359 dbus_bool_t
00360 bus_dispatch_add_connection (DBusConnection *connection)
00361 {
00362 if (!dbus_connection_add_filter (connection,
00363 bus_dispatch_message_filter,
00364 NULL, NULL))
00365 return FALSE;
00366
00367 return TRUE;
00368 }
00369
00370 void
00371 bus_dispatch_remove_connection (DBusConnection *connection)
00372 {
00373
00374 bus_driver_remove_connection (connection);
00375
00376 dbus_connection_remove_filter (connection,
00377 bus_dispatch_message_filter,
00378 NULL);
00379 }
00380
00381 #ifdef DBUS_BUILD_TESTS
00382
00383 typedef dbus_bool_t (* Check1Func) (BusContext *context);
00384 typedef dbus_bool_t (* Check2Func) (BusContext *context,
00385 DBusConnection *connection);
00386
00387 static dbus_bool_t check_no_leftovers (BusContext *context);
00388
00389 static void
00390 block_connection_until_message_from_bus (BusContext *context,
00391 DBusConnection *connection)
00392 {
00393 while (dbus_connection_get_dispatch_status (connection) ==
00394 DBUS_DISPATCH_COMPLETE &&
00395 dbus_connection_get_is_connected (connection))
00396 {
00397 bus_test_run_bus_loop (context, TRUE);
00398 bus_test_run_clients_loop (FALSE);
00399 }
00400 }
00401
00402
00403 static DBusMessage*
00404 pop_message_waiting_for_memory (DBusConnection *connection)
00405 {
00406 while (dbus_connection_get_dispatch_status (connection) ==
00407 DBUS_DISPATCH_NEED_MEMORY)
00408 _dbus_wait_for_memory ();
00409
00410 return dbus_connection_pop_message (connection);
00411 }
00412
00413 static void
00414 warn_unexpected_real (DBusConnection *connection,
00415 DBusMessage *message,
00416 const char *expected,
00417 const char *function,
00418 int line)
00419 {
00420 _dbus_warn ("%s:%d received message interface \"%s\" member \"%s\" error name \"%s\" on %p, expecting %s\n",
00421 function, line,
00422 dbus_message_get_interface (message) ?
00423 dbus_message_get_interface (message) : "(unset)",
00424 dbus_message_get_member (message) ?
00425 dbus_message_get_member (message) : "(unset)",
00426 dbus_message_get_error_name (message) ?
00427 dbus_message_get_error_name (message) : "(unset)",
00428 connection,
00429 expected);
00430 }
00431
00432 #define warn_unexpected(connection, message, expected) \
00433 warn_unexpected_real (connection, message, expected, _DBUS_FUNCTION_NAME, __LINE__)
00434
00435 static void
00436 verbose_message_received (DBusConnection *connection,
00437 DBusMessage *message)
00438 {
00439 _dbus_verbose ("Received message interface \"%s\" member \"%s\" error name \"%s\" on %p\n",
00440 dbus_message_get_interface (message) ?
00441 dbus_message_get_interface (message) : "(unset)",
00442 dbus_message_get_member (message) ?
00443 dbus_message_get_member (message) : "(unset)",
00444 dbus_message_get_error_name (message) ?
00445 dbus_message_get_error_name (message) : "(unset)",
00446 connection);
00447 }
00448
00449 typedef struct
00450 {
00451 const char *expected_service_name;
00452 dbus_bool_t failed;
00453 } CheckServiceDeletedData;
00454
00455 static dbus_bool_t
00456 check_service_deleted_foreach (DBusConnection *connection,
00457 void *data)
00458 {
00459 CheckServiceDeletedData *d = data;
00460 DBusMessage *message;
00461 DBusError error;
00462 char *service_name;
00463
00464 dbus_error_init (&error);
00465 d->failed = TRUE;
00466 service_name = NULL;
00467
00468 message = pop_message_waiting_for_memory (connection);
00469 if (message == NULL)
00470 {
00471 _dbus_warn ("Did not receive a message on %p, expecting %s\n",
00472 connection, "ServiceDeleted");
00473 goto out;
00474 }
00475 else if (!dbus_message_is_signal (message,
00476 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
00477 "ServiceDeleted"))
00478 {
00479 warn_unexpected (connection, message, "ServiceDeleted");
00480
00481 goto out;
00482 }
00483 else
00484 {
00485 if (!dbus_message_get_args (message, &error,
00486 DBUS_TYPE_STRING, &service_name,
00487 DBUS_TYPE_INVALID))
00488 {
00489 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
00490 {
00491 _dbus_verbose ("no memory to get service name arg\n");
00492 }
00493 else
00494 {
00495 _dbus_assert (dbus_error_is_set (&error));
00496 _dbus_warn ("Did not get the expected single string argument\n");
00497 goto out;
00498 }
00499 }
00500 else if (strcmp (service_name, d->expected_service_name) != 0)
00501 {
00502 _dbus_warn ("expected deletion of service %s, got deletion of %s\n",
00503 d->expected_service_name,
00504 service_name);
00505 goto out;
00506 }
00507 }
00508
00509 d->failed = FALSE;
00510
00511 out:
00512 dbus_free (service_name);
00513 dbus_error_free (&error);
00514
00515 if (message)
00516 dbus_message_unref (message);
00517
00518 return !d->failed;
00519 }
00520
00521 static void
00522 kill_client_connection (BusContext *context,
00523 DBusConnection *connection)
00524 {
00525 char *base_service;
00526 const char *s;
00527 CheckServiceDeletedData csdd;
00528
00529 _dbus_verbose ("killing connection %p\n", connection);
00530
00531 s = dbus_bus_get_base_service (connection);
00532 _dbus_assert (s != NULL);
00533
00534 while ((base_service = _dbus_strdup (s)) == NULL)
00535 _dbus_wait_for_memory ();
00536
00537 dbus_connection_ref (connection);
00538
00539
00540 dbus_connection_disconnect (connection);
00541
00542 bus_test_run_everything (context);
00543
00544 _dbus_assert (bus_test_client_listed (connection));
00545
00546
00547 if (bus_connection_dispatch_one_message (connection))
00548 _dbus_assert_not_reached ("something received on connection being killed other than the disconnect");
00549
00550 _dbus_assert (!dbus_connection_get_is_connected (connection));
00551 dbus_connection_unref (connection);
00552 connection = NULL;
00553 _dbus_assert (!bus_test_client_listed (connection));
00554
00555 csdd.expected_service_name = base_service;
00556 csdd.failed = FALSE;
00557
00558 bus_test_clients_foreach (check_service_deleted_foreach,
00559 &csdd);
00560
00561 dbus_free (base_service);
00562
00563 if (csdd.failed)
00564 _dbus_assert_not_reached ("didn't get the expected ServiceDeleted messages");
00565
00566 if (!check_no_leftovers (context))
00567 _dbus_assert_not_reached ("stuff left in message queues after disconnecting a client");
00568 }
00569
00570 static void
00571 kill_client_connection_unchecked (DBusConnection *connection)
00572 {
00573
00574
00575
00576 _dbus_verbose ("Unchecked kill of connection %p\n", connection);
00577
00578 dbus_connection_ref (connection);
00579 dbus_connection_disconnect (connection);
00580
00581 if (bus_connection_dispatch_one_message (connection))
00582 _dbus_assert_not_reached ("message other than disconnect dispatched after failure to register");
00583
00584 _dbus_assert (!bus_test_client_listed (connection));
00585 dbus_connection_unref (connection);
00586 }
00587
00588 typedef struct
00589 {
00590 dbus_bool_t failed;
00591 } CheckNoMessagesData;
00592
00593 static dbus_bool_t
00594 check_no_messages_foreach (DBusConnection *connection,
00595 void *data)
00596 {
00597 CheckNoMessagesData *d = data;
00598 DBusMessage *message;
00599
00600 message = pop_message_waiting_for_memory (connection);
00601 if (message != NULL)
00602 {
00603 warn_unexpected (connection, message, "no messages");
00604
00605 d->failed = TRUE;
00606 }
00607
00608 if (message)
00609 dbus_message_unref (message);
00610 return !d->failed;
00611 }
00612
00613 typedef struct
00614 {
00615 DBusConnection *skip_connection;
00616 const char *expected_service_name;
00617 dbus_bool_t failed;
00618 } CheckServiceCreatedData;
00619
00620 static dbus_bool_t
00621 check_service_created_foreach (DBusConnection *connection,
00622 void *data)
00623 {
00624 CheckServiceCreatedData *d = data;
00625 DBusMessage *message;
00626 DBusError error;
00627 char *service_name;
00628
00629 if (connection == d->skip_connection)
00630 return TRUE;
00631
00632 dbus_error_init (&error);
00633 d->failed = TRUE;
00634 service_name = NULL;
00635
00636 message = pop_message_waiting_for_memory (connection);
00637 if (message == NULL)
00638 {
00639 _dbus_warn ("Did not receive a message on %p, expecting %s\n",
00640 connection, "ServiceCreated");
00641 goto out;
00642 }
00643 else if (!dbus_message_is_signal (message,
00644 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
00645 "ServiceCreated"))
00646 {
00647 warn_unexpected (connection, message, "ServiceCreated");
00648 goto out;
00649 }
00650 else
00651 {
00652 if (!dbus_message_get_args (message, &error,
00653 DBUS_TYPE_STRING, &service_name,
00654 DBUS_TYPE_INVALID))
00655 {
00656 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
00657 {
00658 _dbus_verbose ("no memory to get service name arg\n");
00659 }
00660 else
00661 {
00662 _dbus_assert (dbus_error_is_set (&error));
00663 _dbus_warn ("Did not get the expected single string argument\n");
00664 goto out;
00665 }
00666 }
00667 else if (strcmp (service_name, d->expected_service_name) != 0)
00668 {
00669 _dbus_warn ("expected creation of service %s, got creation of %s\n",
00670 d->expected_service_name,
00671 service_name);
00672 goto out;
00673 }
00674 }
00675
00676 d->failed = FALSE;
00677
00678 out:
00679 dbus_free (service_name);
00680 dbus_error_free (&error);
00681
00682 if (message)
00683 dbus_message_unref (message);
00684
00685 return !d->failed;
00686 }
00687
00688 static dbus_bool_t
00689 check_no_leftovers (BusContext *context)
00690 {
00691 CheckNoMessagesData nmd;
00692
00693 nmd.failed = FALSE;
00694 bus_test_clients_foreach (check_no_messages_foreach,
00695 &nmd);
00696
00697 if (nmd.failed)
00698 return FALSE;
00699 else
00700 return TRUE;
00701 }
00702
00703
00704
00705
00706 static dbus_bool_t
00707 check_hello_message (BusContext *context,
00708 DBusConnection *connection)
00709 {
00710 DBusMessage *message;
00711 dbus_uint32_t serial;
00712 dbus_bool_t retval;
00713 DBusError error;
00714 char *name;
00715 char *acquired;
00716
00717 retval = FALSE;
00718 dbus_error_init (&error);
00719 name = NULL;
00720 acquired = NULL;
00721 message = NULL;
00722
00723 _dbus_verbose ("check_hello_message for %p\n", connection);
00724
00725 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
00726 DBUS_PATH_ORG_FREEDESKTOP_DBUS,
00727 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
00728 "Hello");
00729
00730 if (message == NULL)
00731 return TRUE;
00732
00733 if (!dbus_connection_send (connection, message, &serial))
00734 {
00735 dbus_message_unref (message);
00736 return TRUE;
00737 }
00738
00739 dbus_message_unref (message);
00740 message = NULL;
00741
00742
00743 bus_test_run_clients_loop (TRUE);
00744
00745 dbus_connection_ref (connection);
00746 block_connection_until_message_from_bus (context, connection);
00747
00748 if (!dbus_connection_get_is_connected (connection))
00749 {
00750 _dbus_verbose ("connection was disconnected\n");
00751
00752 dbus_connection_unref (connection);
00753
00754 return TRUE;
00755 }
00756
00757 dbus_connection_unref (connection);
00758
00759 message = pop_message_waiting_for_memory (connection);
00760 if (message == NULL)
00761 {
00762 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
00763 "Hello", serial, connection);
00764 goto out;
00765 }
00766
00767 verbose_message_received (connection, message);
00768
00769 if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
00770 {
00771 _dbus_warn ("Message has wrong sender %s\n",
00772 dbus_message_get_sender (message) ?
00773 dbus_message_get_sender (message) : "(none)");
00774 goto out;
00775 }
00776
00777 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
00778 {
00779 if (dbus_message_is_error (message,
00780 DBUS_ERROR_NO_MEMORY))
00781 {
00782 ;
00783 }
00784 else
00785 {
00786 warn_unexpected (connection, message, "not this error");
00787
00788 goto out;
00789 }
00790 }
00791 else
00792 {
00793 CheckServiceCreatedData scd;
00794
00795 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
00796 {
00797 ;
00798 }
00799 else
00800 {
00801 warn_unexpected (connection, message, "method return for Hello");
00802
00803 goto out;
00804 }
00805
00806 retry_get_hello_name:
00807 if (!dbus_message_get_args (message, &error,
00808 DBUS_TYPE_STRING, &name,
00809 DBUS_TYPE_INVALID))
00810 {
00811 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
00812 {
00813 _dbus_verbose ("no memory to get service name arg from hello\n");
00814 dbus_error_free (&error);
00815 _dbus_wait_for_memory ();
00816 goto retry_get_hello_name;
00817 }
00818 else
00819 {
00820 _dbus_assert (dbus_error_is_set (&error));
00821 _dbus_warn ("Did not get the expected single string argument to hello\n");
00822 goto out;
00823 }
00824 }
00825
00826 _dbus_verbose ("Got hello name: %s\n", name);
00827
00828 while (!dbus_bus_set_base_service (connection, name))
00829 _dbus_wait_for_memory ();
00830
00831 scd.skip_connection = connection;
00832 scd.failed = FALSE;
00833 scd.expected_service_name = name;
00834 bus_test_clients_foreach (check_service_created_foreach,
00835 &scd);
00836
00837 if (scd.failed)
00838 goto out;
00839
00840
00841 dbus_message_unref (message);
00842 message = pop_message_waiting_for_memory (connection);
00843 if (message == NULL)
00844 {
00845 _dbus_warn ("Expecting %s, got nothing\n",
00846 "ServiceAcquired");
00847 goto out;
00848 }
00849
00850 retry_get_acquired_name:
00851 if (!dbus_message_get_args (message, &error,
00852 DBUS_TYPE_STRING, &acquired,
00853 DBUS_TYPE_INVALID))
00854 {
00855 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
00856 {
00857 _dbus_verbose ("no memory to get service name arg from acquired\n");
00858 dbus_error_free (&error);
00859 _dbus_wait_for_memory ();
00860 goto retry_get_acquired_name;
00861 }
00862 else
00863 {
00864 _dbus_assert (dbus_error_is_set (&error));
00865 _dbus_warn ("Did not get the expected single string argument to ServiceAcquired\n");
00866 goto out;
00867 }
00868 }
00869
00870 _dbus_verbose ("Got acquired name: %s\n", acquired);
00871
00872 if (strcmp (acquired, name) != 0)
00873 {
00874 _dbus_warn ("Acquired name is %s but expected %s\n",
00875 acquired, name);
00876 goto out;
00877 }
00878 }
00879
00880 if (!check_no_leftovers (context))
00881 goto out;
00882
00883 retval = TRUE;
00884
00885 out:
00886 dbus_error_free (&error);
00887
00888 dbus_free (name);
00889 dbus_free (acquired);
00890
00891 if (message)
00892 dbus_message_unref (message);
00893
00894 return retval;
00895 }
00896
00897
00898
00899
00900 static dbus_bool_t
00901 check_add_match_all (BusContext *context,
00902 DBusConnection *connection)
00903 {
00904 DBusMessage *message;
00905 dbus_bool_t retval;
00906 dbus_uint32_t serial;
00907 DBusError error;
00908
00909 retval = FALSE;
00910 dbus_error_init (&error);
00911 message = NULL;
00912
00913 _dbus_verbose ("check_add_match_all for %p\n", connection);
00914
00915 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
00916 DBUS_PATH_ORG_FREEDESKTOP_DBUS,
00917 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
00918 "AddMatch");
00919
00920 if (message == NULL)
00921 return TRUE;
00922
00923 if (!dbus_message_append_args (message, DBUS_TYPE_STRING, "",
00924 DBUS_TYPE_INVALID))
00925 {
00926 dbus_message_unref (message);
00927 return TRUE;
00928 }
00929
00930 if (!dbus_connection_send (connection, message, &serial))
00931 {
00932 dbus_message_unref (message);
00933 return TRUE;
00934 }
00935
00936 dbus_message_unref (message);
00937 message = NULL;
00938
00939
00940 bus_test_run_clients_loop (TRUE);
00941
00942 dbus_connection_ref (connection);
00943 block_connection_until_message_from_bus (context, connection);
00944
00945 if (!dbus_connection_get_is_connected (connection))
00946 {
00947 _dbus_verbose ("connection was disconnected\n");
00948
00949 dbus_connection_unref (connection);
00950
00951 return TRUE;
00952 }
00953
00954 dbus_connection_unref (connection);
00955
00956 message = pop_message_waiting_for_memory (connection);
00957 if (message == NULL)
00958 {
00959 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
00960 "AddMatch", serial, connection);
00961 goto out;
00962 }
00963
00964 verbose_message_received (connection, message);
00965
00966 if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
00967 {
00968 _dbus_warn ("Message has wrong sender %s\n",
00969 dbus_message_get_sender (message) ?
00970 dbus_message_get_sender (message) : "(none)");
00971 goto out;
00972 }
00973
00974 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
00975 {
00976 if (dbus_message_is_error (message,
00977 DBUS_ERROR_NO_MEMORY))
00978 {
00979 ;
00980 }
00981 else
00982 {
00983 warn_unexpected (connection, message, "not this error");
00984
00985 goto out;
00986 }
00987 }
00988 else
00989 {
00990 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
00991 {
00992 ;
00993 _dbus_assert (dbus_message_get_reply_serial (message) == serial);
00994 }
00995 else
00996 {
00997 warn_unexpected (connection, message, "method return for AddMatch");
00998
00999 goto out;
01000 }
01001 }
01002
01003 if (!check_no_leftovers (context))
01004 goto out;
01005
01006 retval = TRUE;
01007
01008 out:
01009 dbus_error_free (&error);
01010
01011 if (message)
01012 dbus_message_unref (message);
01013
01014 return retval;
01015 }
01016
01017
01018
01019
01020 static dbus_bool_t
01021 check_hello_connection (BusContext *context)
01022 {
01023 DBusConnection *connection;
01024 DBusError error;
01025
01026 dbus_error_init (&error);
01027
01028 connection = dbus_connection_open ("debug-pipe:name=test-server", &error);
01029 if (connection == NULL)
01030 {
01031 _DBUS_ASSERT_ERROR_IS_SET (&error);
01032 dbus_error_free (&error);
01033 return TRUE;
01034 }
01035
01036 if (!bus_setup_debug_client (connection))
01037 {
01038 dbus_connection_disconnect (connection);
01039 dbus_connection_unref (connection);
01040 return TRUE;
01041 }
01042
01043 if (!check_hello_message (context, connection))
01044 return FALSE;
01045
01046 if (dbus_bus_get_base_service (connection) == NULL)
01047 {
01048
01049
01050
01051 kill_client_connection_unchecked (connection);
01052 }
01053 else
01054 {
01055 if (!check_add_match_all (context, connection))
01056 return FALSE;
01057
01058 kill_client_connection (context, connection);
01059 }
01060
01061 return TRUE;
01062 }
01063
01064 #define NONEXISTENT_SERVICE_NAME "test.this.service.does.not.exist.ewuoiurjdfxcvn"
01065
01066
01067
01068
01069 static dbus_bool_t
01070 check_nonexistent_service_activation (BusContext *context,
01071 DBusConnection *connection)
01072 {
01073 DBusMessage *message;
01074 dbus_uint32_t serial;
01075 dbus_bool_t retval;
01076 DBusError error;
01077
01078 dbus_error_init (&error);
01079
01080 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
01081 DBUS_PATH_ORG_FREEDESKTOP_DBUS,
01082 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
01083 "ActivateService");
01084
01085 if (message == NULL)
01086 return TRUE;
01087
01088 if (!dbus_message_append_args (message,
01089 DBUS_TYPE_STRING, NONEXISTENT_SERVICE_NAME,
01090 DBUS_TYPE_UINT32, 0,
01091 DBUS_TYPE_INVALID))
01092 {
01093 dbus_message_unref (message);
01094 return TRUE;
01095 }
01096
01097 if (!dbus_connection_send (connection, message, &serial))
01098 {
01099 dbus_message_unref (message);
01100 return TRUE;
01101 }
01102
01103 dbus_message_unref (message);
01104 message = NULL;
01105
01106 bus_test_run_everything (context);
01107 block_connection_until_message_from_bus (context, connection);
01108 bus_test_run_everything (context);
01109
01110 if (!dbus_connection_get_is_connected (connection))
01111 {
01112 _dbus_verbose ("connection was disconnected\n");
01113 return TRUE;
01114 }
01115
01116 retval = FALSE;
01117
01118 message = pop_message_waiting_for_memory (connection);
01119 if (message == NULL)
01120 {
01121 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
01122 "ActivateService", serial, connection);
01123 goto out;
01124 }
01125
01126 verbose_message_received (connection, message);
01127
01128 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
01129 {
01130 if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
01131 {
01132 _dbus_warn ("Message has wrong sender %s\n",
01133 dbus_message_get_sender (message) ?
01134 dbus_message_get_sender (message) : "(none)");
01135 goto out;
01136 }
01137
01138 if (dbus_message_is_error (message,
01139 DBUS_ERROR_NO_MEMORY))
01140 {
01141 ;
01142 }
01143 else if (dbus_message_is_error (message,
01144 DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND))
01145 {
01146 ;
01147 }
01148 else
01149 {
01150 warn_unexpected (connection, message, "not this error");
01151 goto out;
01152 }
01153 }
01154 else
01155 {
01156 _dbus_warn ("Did not expect to successfully activate %s\n",
01157 NONEXISTENT_SERVICE_NAME);
01158 goto out;
01159 }
01160
01161 retval = TRUE;
01162
01163 out:
01164 if (message)
01165 dbus_message_unref (message);
01166
01167 return retval;
01168 }
01169
01170 static dbus_bool_t
01171 check_base_service_activated (BusContext *context,
01172 DBusConnection *connection,
01173 DBusMessage *initial_message,
01174 char **base_service_p)
01175 {
01176 DBusMessage *message;
01177 dbus_bool_t retval;
01178 DBusError error;
01179 char *base_service;
01180
01181 base_service = NULL;
01182 retval = FALSE;
01183
01184 dbus_error_init (&error);
01185
01186 message = initial_message;
01187 dbus_message_ref (message);
01188
01189 if (dbus_message_is_signal (message,
01190 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
01191 "ServiceCreated"))
01192 {
01193 char *service_name;
01194 CheckServiceCreatedData scd;
01195
01196 reget_service_name_arg:
01197 if (!dbus_message_get_args (message, &error,
01198 DBUS_TYPE_STRING, &service_name,
01199 DBUS_TYPE_INVALID))
01200 {
01201 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
01202 {
01203 dbus_error_free (&error);
01204 _dbus_wait_for_memory ();
01205 goto reget_service_name_arg;
01206 }
01207 else
01208 {
01209 _dbus_warn ("Message %s doesn't have a service name: %s\n",
01210 "ServiceCreated",
01211 error.message);
01212 dbus_error_free (&error);
01213 goto out;
01214 }
01215 }
01216
01217 if (*service_name != ':')
01218 {
01219 _dbus_warn ("Expected base service activation, got \"%s\" instead\n",
01220 service_name);
01221 goto out;
01222 }
01223
01224 base_service = service_name;
01225 service_name = NULL;
01226
01227 scd.skip_connection = connection;
01228 scd.failed = FALSE;
01229 scd.expected_service_name = base_service;
01230 bus_test_clients_foreach (check_service_created_foreach,
01231 &scd);
01232
01233 if (scd.failed)
01234 goto out;
01235 }
01236 else
01237 {
01238 warn_unexpected (connection, message, "ServiceCreated for base service");
01239
01240 goto out;
01241 }
01242
01243 retval = TRUE;
01244
01245 if (base_service_p)
01246 {
01247 *base_service_p = base_service;
01248 base_service = NULL;
01249 }
01250
01251 out:
01252 if (message)
01253 dbus_message_unref (message);
01254
01255 if (base_service)
01256 dbus_free (base_service);
01257
01258 return retval;
01259 }
01260
01261 static dbus_bool_t
01262 check_service_activated (BusContext *context,
01263 DBusConnection *connection,
01264 const char *activated_name,
01265 const char *base_service_name,
01266 DBusMessage *initial_message)
01267 {
01268 DBusMessage *message;
01269 dbus_bool_t retval;
01270 DBusError error;
01271 dbus_uint32_t activation_result;
01272
01273 retval = FALSE;
01274
01275 dbus_error_init (&error);
01276
01277 message = initial_message;
01278 dbus_message_ref (message);
01279
01280 if (dbus_message_is_signal (message,
01281 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
01282 "ServiceCreated"))
01283 {
01284 char *service_name;
01285 CheckServiceCreatedData scd;
01286
01287 reget_service_name_arg:
01288 if (!dbus_message_get_args (message, &error,
01289 DBUS_TYPE_STRING, &service_name,
01290 DBUS_TYPE_INVALID))
01291 {
01292 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
01293 {
01294 dbus_error_free (&error);
01295 _dbus_wait_for_memory ();
01296 goto reget_service_name_arg;
01297 }
01298 else
01299 {
01300 _dbus_warn ("Message %s doesn't have a service name: %s\n",
01301 "ServiceCreated",
01302 error.message);
01303 dbus_error_free (&error);
01304 goto out;
01305 }
01306 }
01307
01308 if (strcmp (service_name, activated_name) != 0)
01309 {
01310 _dbus_warn ("Expected to see service %s created, saw %s instead\n",
01311 activated_name, service_name);
01312 dbus_free (service_name);
01313 goto out;
01314 }
01315
01316 scd.skip_connection = connection;
01317 scd.failed = FALSE;
01318 scd.expected_service_name = service_name;
01319 bus_test_clients_foreach (check_service_created_foreach,
01320 &scd);
01321
01322 dbus_free (service_name);
01323
01324 if (scd.failed)
01325 goto out;
01326
01327 dbus_message_unref (message);
01328 message = pop_message_waiting_for_memory (connection);
01329 if (message == NULL)
01330 {
01331 _dbus_warn ("Expected a reply to %s, got nothing\n",
01332 "ActivateService");
01333 goto out;
01334 }
01335 }
01336 else
01337 {
01338 warn_unexpected (connection, message, "ServiceCreated for the activated name");
01339
01340 goto out;
01341 }
01342
01343 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN)
01344 {
01345 warn_unexpected (connection, message, "reply to ActivateService");
01346
01347 goto out;
01348 }
01349
01350 activation_result = 0;
01351 if (!dbus_message_get_args (message, &error,
01352 DBUS_TYPE_UINT32, &activation_result,
01353 DBUS_TYPE_INVALID))
01354 {
01355 if (!dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
01356 {
01357 _dbus_warn ("Did not have activation result first argument to %s: %s\n",
01358 "ActivateService", error.message);
01359 dbus_error_free (&error);
01360 goto out;
01361 }
01362
01363 dbus_error_free (&error);
01364 }
01365 else
01366 {
01367 if (activation_result == DBUS_ACTIVATION_REPLY_ACTIVATED)
01368 ;
01369 else if (activation_result == DBUS_ACTIVATION_REPLY_ALREADY_ACTIVE)
01370 ;
01371 else
01372 {
01373 _dbus_warn ("Activation result was 0x%x, no good.\n",
01374 activation_result);
01375 goto out;
01376 }
01377 }
01378
01379 dbus_message_unref (message);
01380 message = NULL;
01381
01382 if (!check_no_leftovers (context))
01383 {
01384 _dbus_warn ("Messages were left over after verifying existent activation results\n");
01385 goto out;
01386 }
01387
01388 retval = TRUE;
01389
01390 out:
01391 if (message)
01392 dbus_message_unref (message);
01393
01394 return retval;
01395 }
01396
01397 static dbus_bool_t
01398 check_service_deactivated (BusContext *context,
01399 DBusConnection *connection,
01400 const char *activated_name,
01401 const char *base_service)
01402 {
01403 DBusMessage *message;
01404 dbus_bool_t retval;
01405 DBusError error;
01406 CheckServiceDeletedData csdd;
01407
01408 message = NULL;
01409 retval = FALSE;
01410
01411 dbus_error_init (&error);
01412
01413
01414
01415
01416
01417 csdd.expected_service_name = activated_name;
01418 csdd.failed = FALSE;
01419 bus_test_clients_foreach (check_service_deleted_foreach,
01420 &csdd);
01421
01422 if (csdd.failed)
01423 goto out;
01424
01425 csdd.expected_service_name = base_service;
01426 csdd.failed = FALSE;
01427 bus_test_clients_foreach (check_service_deleted_foreach,
01428 &csdd);
01429
01430 if (csdd.failed)
01431 goto out;
01432
01433 if (!check_no_leftovers (context))
01434 {
01435 _dbus_warn ("Messages were left over after verifying results of service exiting\n");
01436 goto out;
01437 }
01438
01439 retval = TRUE;
01440
01441 out:
01442 if (message)
01443 dbus_message_unref (message);
01444
01445 return retval;
01446 }
01447
01448 static dbus_bool_t
01449 check_send_exit_to_service (BusContext *context,
01450 DBusConnection *connection,
01451 const char *service_name,
01452 const char *base_service)
01453 {
01454 dbus_bool_t got_error;
01455 DBusMessage *message;
01456 dbus_uint32_t serial;
01457 dbus_bool_t retval;
01458
01459 _dbus_verbose ("Sending exit message to the test service\n");
01460
01461 retval = FALSE;
01462
01463
01464 message = dbus_message_new_method_call (service_name,
01465 "/org/freedesktop/TestSuite",
01466 "org.freedesktop.TestSuite",
01467 "Exit");
01468
01469 if (message == NULL)
01470 {
01471
01472 if (!check_send_exit_to_service (context, connection,
01473 service_name, base_service))
01474 goto out;
01475
01476 return TRUE;
01477 }
01478
01479 if (!dbus_connection_send (connection, message, &serial))
01480 {
01481 dbus_message_unref (message);
01482
01483
01484 if (!check_send_exit_to_service (context, connection,
01485 service_name, base_service))
01486 goto out;
01487
01488 return TRUE;
01489 }
01490
01491 dbus_message_unref (message);
01492 message = NULL;
01493
01494
01495 bus_test_run_clients_loop (TRUE);
01496
01497
01498 bus_test_run_bus_loop (context, FALSE);
01499
01500
01501 bus_test_run_clients_loop (FALSE);
01502 message = dbus_connection_borrow_message (connection);
01503 got_error = message != NULL && dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR;
01504 if (message)
01505 {
01506 dbus_connection_return_message (connection, message);
01507 message = NULL;
01508 }
01509
01510 if (!got_error)
01511 {
01512
01513 block_connection_until_message_from_bus (context, connection);
01514
01515 bus_test_run_everything (context);
01516 }
01517
01518 if (got_error)
01519 {
01520 message = pop_message_waiting_for_memory (connection);
01521 _dbus_assert (message != NULL);
01522
01523 if (!dbus_message_is_error (message,
01524 DBUS_ERROR_NO_MEMORY))
01525 {
01526 warn_unexpected (connection, message,
01527 "a no memory error from asking test service to exit");
01528 goto out;
01529 }
01530
01531 _dbus_verbose ("Got error %s when asking test service to exit\n",
01532 dbus_message_get_error_name (message));
01533
01534
01535 if (!check_send_exit_to_service (context, connection,
01536 service_name, base_service))
01537 goto out;
01538 }
01539 else
01540 {
01541 if (!check_service_deactivated (context, connection,
01542 service_name, base_service))
01543 goto out;
01544 }
01545
01546 retval = TRUE;
01547
01548 out:
01549 if (message)
01550 dbus_message_unref (message);
01551
01552 return retval;
01553 }
01554
01555 static dbus_bool_t
01556 check_got_error (BusContext *context,
01557 DBusConnection *connection,
01558 const char *first_error_name,
01559 ...)
01560 {
01561 DBusMessage *message;
01562 dbus_bool_t retval;
01563 va_list ap;
01564 dbus_bool_t error_found;
01565 const char *error_name;
01566
01567 retval = FALSE;
01568
01569 message = pop_message_waiting_for_memory (connection);
01570 if (message == NULL)
01571 {
01572 _dbus_warn ("Did not get an expected error\n");
01573 goto out;
01574 }
01575
01576 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
01577 {
01578 warn_unexpected (connection, message, "an error");
01579
01580 goto out;
01581 }
01582
01583 error_found = FALSE;
01584
01585 va_start (ap, first_error_name);
01586 error_name = first_error_name;
01587 while (error_name != NULL)
01588 {
01589 if (dbus_message_is_error (message, error_name))
01590 {
01591 error_found = TRUE;
01592 break;
01593 }
01594 error_name = va_arg (ap, char*);
01595 }
01596 va_end (ap);
01597
01598 if (!error_found)
01599 {
01600 _dbus_warn ("Expected error %s or other, got %s instead\n",
01601 first_error_name,
01602 dbus_message_get_error_name (message));
01603 goto out;
01604 }
01605
01606 retval = TRUE;
01607
01608 out:
01609 if (message)
01610 dbus_message_unref (message);
01611
01612 return retval;
01613 }
01614
01615 #define EXISTENT_SERVICE_NAME "org.freedesktop.DBus.TestSuiteEchoService"
01616
01617
01618
01619
01620 static dbus_bool_t
01621 check_existent_service_activation (BusContext *context,
01622 DBusConnection *connection)
01623 {
01624 DBusMessage *message;
01625 dbus_uint32_t serial;
01626 dbus_bool_t retval;
01627 DBusError error;
01628 char *base_service;
01629
01630 base_service = NULL;
01631
01632 dbus_error_init (&error);
01633
01634 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
01635 DBUS_PATH_ORG_FREEDESKTOP_DBUS,
01636 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
01637 "ActivateService");
01638
01639 if (message == NULL)
01640 return TRUE;
01641
01642 if (!dbus_message_append_args (message,
01643 DBUS_TYPE_STRING, EXISTENT_SERVICE_NAME,
01644 DBUS_TYPE_UINT32, 0,
01645 DBUS_TYPE_INVALID))
01646 {
01647 dbus_message_unref (message);
01648 return TRUE;
01649 }
01650
01651 if (!dbus_connection_send (connection, message, &serial))
01652 {
01653 dbus_message_unref (message);
01654 return TRUE;
01655 }
01656
01657 dbus_message_unref (message);
01658 message = NULL;
01659
01660 bus_test_run_everything (context);
01661
01662
01663
01664
01665 block_connection_until_message_from_bus (context, connection);
01666
01667 bus_test_run_everything (context);
01668
01669 if (!dbus_connection_get_is_connected (connection))
01670 {
01671 _dbus_verbose ("connection was disconnected\n");
01672 return TRUE;
01673 }
01674
01675 retval = FALSE;
01676
01677 message = pop_message_waiting_for_memory (connection);
01678 if (message == NULL)
01679 {
01680 _dbus_warn ("Did not receive any messages after %s %d on %p\n",
01681 "ActivateService", serial, connection);
01682 goto out;
01683 }
01684
01685 verbose_message_received (connection, message);
01686 _dbus_verbose (" (after sending %s)\n", "ActivateService");
01687
01688 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
01689 {
01690 if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
01691 {
01692 _dbus_warn ("Message has wrong sender %s\n",
01693 dbus_message_get_sender (message) ?
01694 dbus_message_get_sender (message) : "(none)");
01695 goto out;
01696 }
01697
01698 if (dbus_message_is_error (message,
01699 DBUS_ERROR_NO_MEMORY))
01700 {
01701 ;
01702 }
01703 else if (dbus_message_is_error (message,
01704 DBUS_ERROR_SPAWN_CHILD_EXITED))
01705 {
01706 ;
01707 }
01708 else
01709 {
01710 _dbus_warn ("Did not expect error %s\n",
01711 dbus_message_get_error_name (message));
01712 goto out;
01713 }
01714 }
01715 else
01716 {
01717 dbus_bool_t got_service_deleted;
01718 dbus_bool_t got_error;
01719
01720 if (!check_base_service_activated (context, connection,
01721 message, &base_service))
01722 goto out;
01723
01724 dbus_message_unref (message);
01725 message = NULL;
01726
01727
01728 block_connection_until_message_from_bus (context, connection);
01729
01730 message = dbus_connection_borrow_message (connection);
01731 if (message == NULL)
01732 {
01733 _dbus_warn ("Did not receive any messages after base service creation notification\n");
01734 goto out;
01735 }
01736
01737 got_service_deleted = dbus_message_is_signal (message,
01738 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
01739 "ServiceDeleted");
01740 got_error = dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR;
01741
01742 dbus_connection_return_message (connection, message);
01743 message = NULL;
01744
01745 if (got_error)
01746 {
01747 if (!check_got_error (context, connection,
01748 DBUS_ERROR_SPAWN_CHILD_EXITED,
01749 DBUS_ERROR_NO_MEMORY,
01750 NULL))
01751 goto out;
01752
01753
01754
01755
01756 got_service_deleted = TRUE;
01757 }
01758
01759 if (got_service_deleted)
01760 {
01761
01762
01763
01764 CheckServiceDeletedData csdd;
01765
01766 csdd.expected_service_name = base_service;
01767 csdd.failed = FALSE;
01768 bus_test_clients_foreach (check_service_deleted_foreach,
01769 &csdd);
01770
01771 if (csdd.failed)
01772 goto out;
01773
01774
01775
01776
01777 if (!got_error)
01778 {
01779 block_connection_until_message_from_bus (context, connection);
01780
01781
01782 bus_test_run_everything (context);
01783
01784 if (!check_got_error (context, connection,
01785 DBUS_ERROR_SPAWN_CHILD_EXITED,
01786 NULL))
01787 goto out;
01788 }
01789 }
01790 else
01791 {
01792 message = pop_message_waiting_for_memory (connection);
01793 if (message == NULL)
01794 {
01795 _dbus_warn ("Failed to pop message we just put back! should have been a ServiceCreated\n");
01796 goto out;
01797 }
01798
01799 if (!check_service_activated (context, connection, EXISTENT_SERVICE_NAME,
01800 base_service, message))
01801 goto out;
01802
01803 dbus_message_unref (message);
01804 message = NULL;
01805
01806
01807 if (!check_no_leftovers (context))
01808 {
01809 _dbus_warn ("Messages were left over after successful activation\n");
01810 goto out;
01811 }
01812
01813 if (!check_send_exit_to_service (context, connection,
01814 EXISTENT_SERVICE_NAME, base_service))
01815 goto out;
01816 }
01817 }
01818
01819 retval = TRUE;
01820
01821 out:
01822 if (message)
01823 dbus_message_unref (message);
01824
01825 if (base_service)
01826 dbus_free (base_service);
01827
01828 return retval;
01829 }
01830
01831
01832
01833
01834 static dbus_bool_t
01835 check_segfault_service_activation (BusContext *context,
01836 DBusConnection *connection)
01837 {
01838 DBusMessage *message;
01839 dbus_uint32_t serial;
01840 dbus_bool_t retval;
01841 DBusError error;
01842
01843 dbus_error_init (&error);
01844
01845 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
01846 DBUS_PATH_ORG_FREEDESKTOP_DBUS,
01847 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
01848 "ActivateService");
01849
01850 if (message == NULL)
01851 return TRUE;
01852
01853 if (!dbus_message_append_args (message,
01854 DBUS_TYPE_STRING,
01855 "org.freedesktop.DBus.TestSuiteSegfaultService",
01856 DBUS_TYPE_UINT32, 0,
01857 DBUS_TYPE_INVALID))
01858 {
01859 dbus_message_unref (message);
01860 return TRUE;
01861 }
01862
01863 if (!dbus_connection_send (connection, message, &serial))
01864 {
01865 dbus_message_unref (message);
01866 return TRUE;
01867 }
01868
01869 dbus_message_unref (message);
01870 message = NULL;
01871
01872 bus_test_run_everything (context);
01873 block_connection_until_message_from_bus (context, connection);
01874 bus_test_run_everything (context);
01875
01876 if (!dbus_connection_get_is_connected (connection))
01877 {
01878 _dbus_verbose ("connection was disconnected\n");
01879 return TRUE;
01880 }
01881
01882 retval = FALSE;
01883
01884 message = pop_message_waiting_for_memory (connection);
01885 if (message == NULL)
01886 {
01887 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
01888 "ActivateService", serial, connection);
01889 goto out;
01890 }
01891
01892 verbose_message_received (connection, message);
01893
01894 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
01895 {
01896 if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
01897 {
01898 _dbus_warn ("Message has wrong sender %s\n",
01899 dbus_message_get_sender (message) ?
01900 dbus_message_get_sender (message) : "(none)");
01901 goto out;
01902 }
01903
01904 if (dbus_message_is_error (message,
01905 DBUS_ERROR_NO_MEMORY))
01906 {
01907 ;
01908 }
01909 else if (dbus_message_is_error (message,
01910 DBUS_ERROR_SPAWN_CHILD_SIGNALED))
01911 {
01912 ;
01913 }
01914 else
01915 {
01916 warn_unexpected (connection, message, "not this error");
01917
01918 goto out;
01919 }
01920 }
01921 else
01922 {
01923 _dbus_warn ("Did not expect to successfully activate segfault service\n");
01924 goto out;
01925 }
01926
01927 retval = TRUE;
01928
01929 out:
01930 if (message)
01931 dbus_message_unref (message);
01932
01933 return retval;
01934 }
01935
01936 typedef struct
01937 {
01938 Check1Func func;
01939 BusContext *context;
01940 } Check1Data;
01941
01942 static dbus_bool_t
01943 check_oom_check1_func (void *data)
01944 {
01945 Check1Data *d = data;
01946
01947 if (! (* d->func) (d->context))
01948 return FALSE;
01949
01950 if (!check_no_leftovers (d->context))
01951 {
01952 _dbus_warn ("Messages were left over, should be covered by test suite\n");
01953 return FALSE;
01954 }
01955
01956 return TRUE;
01957 }
01958
01959 static void
01960 check1_try_iterations (BusContext *context,
01961 const char *description,
01962 Check1Func func)
01963 {
01964 Check1Data d;
01965
01966 d.func = func;
01967 d.context = context;
01968
01969 if (!_dbus_test_oom_handling (description, check_oom_check1_func,
01970 &d))
01971 _dbus_assert_not_reached ("test failed");
01972 }
01973
01974 typedef struct
01975 {
01976 Check2Func func;
01977 BusContext *context;
01978 DBusConnection *connection;
01979 } Check2Data;
01980
01981 static dbus_bool_t
01982 check_oom_check2_func (void *data)
01983 {
01984 Check2Data *d = data;
01985
01986 if (! (* d->func) (d->context, d->connection))
01987 return FALSE;
01988
01989 if (!check_no_leftovers (d->context))
01990 {
01991 _dbus_warn ("Messages were left over, should be covered by test suite");
01992 return FALSE;
01993 }
01994
01995 return TRUE;
01996 }
01997
01998 static void
01999 check2_try_iterations (BusContext *context,
02000 DBusConnection *connection,
02001 const char *description,
02002 Check2Func func)
02003 {
02004 Check2Data d;
02005
02006 d.func = func;
02007 d.context = context;
02008 d.connection = connection;
02009
02010 if (!_dbus_test_oom_handling (description, check_oom_check2_func,
02011 &d))
02012 _dbus_assert_not_reached ("test failed");
02013 }
02014
02015 dbus_bool_t
02016 bus_dispatch_test (const DBusString *test_data_dir)
02017 {
02018 BusContext *context;
02019 DBusConnection *foo;
02020 DBusConnection *bar;
02021 DBusConnection *baz;
02022 DBusError error;
02023
02024 dbus_error_init (&error);
02025
02026 context = bus_context_new_test (test_data_dir,
02027 "valid-config-files/debug-allow-all.conf");
02028 if (context == NULL)
02029 return FALSE;
02030
02031 foo = dbus_connection_open ("debug-pipe:name=test-server", &error);
02032 if (foo == NULL)
02033 _dbus_assert_not_reached ("could not alloc connection");
02034
02035 if (!bus_setup_debug_client (foo))
02036 _dbus_assert_not_reached ("could not set up connection");
02037
02038 if (!check_hello_message (context, foo))
02039 _dbus_assert_not_reached ("hello message failed");
02040
02041 if (!check_add_match_all (context, foo))
02042 _dbus_assert_not_reached ("AddMatch message failed");
02043
02044 bar = dbus_connection_open ("debug-pipe:name=test-server", &error);
02045 if (bar == NULL)
02046 _dbus_assert_not_reached ("could not alloc connection");
02047
02048 if (!bus_setup_debug_client (bar))
02049 _dbus_assert_not_reached ("could not set up connection");
02050
02051 if (!check_hello_message (context, bar))
02052 _dbus_assert_not_reached ("hello message failed");
02053
02054 if (!check_add_match_all (context, bar))
02055 _dbus_assert_not_reached ("AddMatch message failed");
02056
02057 baz = dbus_connection_open ("debug-pipe:name=test-server", &error);
02058 if (baz == NULL)
02059 _dbus_assert_not_reached ("could not alloc connection");
02060
02061 if (!bus_setup_debug_client (baz))
02062 _dbus_assert_not_reached ("could not set up connection");
02063
02064 if (!check_hello_message (context, baz))
02065 _dbus_assert_not_reached ("hello message failed");
02066
02067 if (!check_add_match_all (context, baz))
02068 _dbus_assert_not_reached ("AddMatch message failed");
02069
02070 if (!check_no_leftovers (context))
02071 {
02072 _dbus_warn ("Messages were left over after setting up initial connections");
02073 _dbus_assert_not_reached ("initial connection setup failed");
02074 }
02075
02076 check1_try_iterations (context, "create_and_hello",
02077 check_hello_connection);
02078
02079 check2_try_iterations (context, foo, "nonexistent_service_activation",
02080 check_nonexistent_service_activation);
02081
02082 check2_try_iterations (context, foo, "segfault_service_activation",
02083 check_segfault_service_activation);
02084
02085 check2_try_iterations (context, foo, "existent_service_activation",
02086 check_existent_service_activation);
02087
02088 _dbus_verbose ("Disconnecting foo, bar, and baz\n");
02089
02090 kill_client_connection_unchecked (foo);
02091 kill_client_connection_unchecked (bar);
02092 kill_client_connection_unchecked (baz);
02093
02094 bus_context_unref (context);
02095
02096 return TRUE;
02097 }
02098
02099 dbus_bool_t
02100 bus_dispatch_sha1_test (const DBusString *test_data_dir)
02101 {
02102 BusContext *context;
02103 DBusConnection *foo;
02104 DBusError error;
02105
02106 dbus_error_init (&error);
02107
02108
02109 _dbus_verbose ("Testing SHA1 context\n");
02110
02111 context = bus_context_new_test (test_data_dir,
02112 "valid-config-files/debug-allow-all-sha1.conf");
02113 if (context == NULL)
02114 return FALSE;
02115
02116 foo = dbus_connection_open ("debug-pipe:name=test-server", &error);
02117 if (foo == NULL)
02118 _dbus_assert_not_reached ("could not alloc connection");
02119
02120 if (!bus_setup_debug_client (foo))
02121 _dbus_assert_not_reached ("could not set up connection");
02122
02123 if (!check_hello_message (context, foo))
02124 _dbus_assert_not_reached ("hello message failed");
02125
02126 if (!check_add_match_all (context, foo))
02127 _dbus_assert_not_reached ("addmatch message failed");
02128
02129 if (!check_no_leftovers (context))
02130 {
02131 _dbus_warn ("Messages were left over after setting up initial SHA-1 connection\n");
02132 _dbus_assert_not_reached ("initial connection setup failed");
02133 }
02134
02135 check1_try_iterations (context, "create_and_hello_sha1",
02136 check_hello_connection);
02137
02138 kill_client_connection_unchecked (foo);
02139
02140 bus_context_unref (context);
02141
02142 return TRUE;
02143 }
02144
02145 #endif