1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dispatch.c Message dispatcher
4 * Copyright (C) 2003 CodeFactory AB
5 * Copyright (C) 2003 Red Hat, Inc.
7 * Licensed under the Academic Free License version 1.2
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include "connection.h"
33 #include <dbus/dbus-internals.h>
37 send_one_message (DBusConnection *connection,
39 DBusConnection *sender,
40 DBusConnection *addressed_recipient,
42 BusTransaction *transaction,
45 if (!bus_context_check_security_policy (context,
51 return TRUE; /* silently don't send it */
53 if (!bus_transaction_send (transaction,
65 bus_dispatch_matches (BusTransaction *transaction,
66 DBusConnection *sender,
67 DBusConnection *addressed_recipient,
72 BusConnections *connections;
74 BusMatchmaker *matchmaker;
78 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
80 /* sender and recipient can both be NULL for the bus driver,
81 * or for signals with no particular recipient
84 _dbus_assert (sender == NULL || bus_connection_is_active (sender));
85 _dbus_assert (dbus_message_get_sender (message) != NULL);
87 connections = bus_transaction_get_connections (transaction);
89 dbus_error_init (&tmp_error);
90 context = bus_transaction_get_context (transaction);
91 matchmaker = bus_context_get_matchmaker (context);
94 if (!bus_matchmaker_get_recipients (matchmaker,
95 bus_context_get_connections (context),
96 sender, addressed_recipient, message,
103 link = _dbus_list_get_first_link (&recipients);
106 DBusConnection *dest;
110 if (!send_one_message (dest, context, sender, addressed_recipient,
111 message, transaction, &tmp_error))
114 link = _dbus_list_get_next_link (&recipients, link);
117 _dbus_list_clear (&recipients);
119 if (dbus_error_is_set (&tmp_error))
121 dbus_move_error (&tmp_error, error);
128 static DBusHandlerResult
129 bus_dispatch (DBusConnection *connection,
130 DBusMessage *message)
132 const char *sender, *service_name;
134 BusTransaction *transaction;
136 DBusHandlerResult result;
137 DBusConnection *addressed_recipient;
139 result = DBUS_HANDLER_RESULT_HANDLED;
142 addressed_recipient = NULL;
143 dbus_error_init (&error);
145 context = bus_connection_get_context (connection);
146 _dbus_assert (context != NULL);
148 /* If we can't even allocate an OOM error, we just go to sleep
151 while (!bus_connection_preallocate_oom_error (connection))
152 _dbus_wait_for_memory ();
154 /* Ref connection in case we disconnect it at some point in here */
155 dbus_connection_ref (connection);
157 service_name = dbus_message_get_destination (message);
159 #ifdef DBUS_ENABLE_VERBOSE_MODE
161 const char *interface_name, *member_name, *error_name;
163 interface_name = dbus_message_get_interface (message);
164 member_name = dbus_message_get_member (message);
165 error_name = dbus_message_get_error_name (message);
167 _dbus_verbose ("DISPATCH: %s %s %s to %s\n",
168 interface_name ? interface_name : "(no interface)",
169 member_name ? member_name : "(no member)",
170 error_name ? error_name : "(no error name)",
171 service_name ? service_name : "peer");
173 #endif /* DBUS_ENABLE_VERBOSE_MODE */
175 /* If service_name is NULL, if it's a signal we send it to all
176 * connections with a match rule. If it's not a signal, it goes to
177 * the bus daemon but doesn't go "on the bus"; e.g. a peer-to-peer
178 * ping. Handle these immediately, especially disconnection
179 * messages. There are no security policy checks on these.
181 if (service_name == NULL)
183 if (dbus_message_is_signal (message,
184 DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
187 bus_connection_disconnected (connection);
191 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL)
193 /* DBusConnection also handles some of these automatically, we leave
196 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
201 /* Create our transaction */
202 transaction = bus_transaction_new (context);
203 if (transaction == NULL)
205 BUS_SET_OOM (&error);
209 /* Assign a sender to the message */
210 if (bus_connection_is_active (connection))
212 sender = bus_connection_get_name (connection);
213 _dbus_assert (sender != NULL);
215 if (!dbus_message_set_sender (message, sender))
217 BUS_SET_OOM (&error);
221 /* We need to refetch the service name here, because
222 * dbus_message_set_sender can cause the header to be
223 * reallocated, and thus the service_name pointer will become
226 service_name = dbus_message_get_destination (message);
230 strcmp (service_name, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS) == 0) /* to bus driver */
232 if (!bus_context_check_security_policy (context,
233 connection, NULL, NULL, message, &error))
235 _dbus_verbose ("Security policy rejected message\n");
239 _dbus_verbose ("Giving message to %s\n", DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
240 if (!bus_driver_handle_message (connection, transaction, message, &error))
243 else if (!bus_connection_is_active (connection)) /* clients must talk to bus driver first */
245 _dbus_verbose ("Received message from non-registered client. Disconnecting.\n");
246 dbus_connection_disconnect (connection);
249 else if (service_name != NULL) /* route to named service */
251 DBusString service_string;
253 BusRegistry *registry;
255 _dbus_assert (service_name != NULL);
257 registry = bus_connection_get_registry (connection);
259 _dbus_string_init_const (&service_string, service_name);
260 service = bus_registry_lookup (registry, &service_string);
264 dbus_set_error (&error,
265 DBUS_ERROR_SERVICE_DOES_NOT_EXIST,
266 "Service \"%s\" does not exist",
272 addressed_recipient = bus_service_get_primary_owner (service);
273 _dbus_assert (addressed_recipient != NULL);
275 if (!bus_context_check_security_policy (context,
276 connection, addressed_recipient,
281 /* Dispatch the message */
282 if (!bus_transaction_send (transaction, addressed_recipient, message))
284 BUS_SET_OOM (&error);
290 /* Now match the messages against any match rules, which will send
291 * out signals and such. addressed_recipient may == NULL.
293 if (!bus_dispatch_matches (transaction, connection, addressed_recipient, message, &error))
297 if (dbus_error_is_set (&error))
299 if (!dbus_connection_get_is_connected (connection))
301 /* If we disconnected it, we won't bother to send it any error
304 _dbus_verbose ("Not sending error to connection we disconnected\n");
306 else if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
308 bus_connection_send_oom_error (connection, message);
310 /* cancel transaction due to OOM */
311 if (transaction != NULL)
313 bus_transaction_cancel_and_free (transaction);
319 /* Try to send the real error, if no mem to do that, send
322 _dbus_assert (transaction != NULL);
324 if (!bus_transaction_send_error_reply (transaction, connection,
327 bus_connection_send_oom_error (connection, message);
329 /* cancel transaction due to OOM */
330 if (transaction != NULL)
332 bus_transaction_cancel_and_free (transaction);
338 dbus_error_free (&error);
341 if (transaction != NULL)
343 bus_transaction_execute_and_free (transaction);
346 dbus_connection_unref (connection);
351 static DBusHandlerResult
352 bus_dispatch_message_filter (DBusConnection *connection,
353 DBusMessage *message,
356 return bus_dispatch (connection, message);
360 bus_dispatch_add_connection (DBusConnection *connection)
362 if (!dbus_connection_add_filter (connection,
363 bus_dispatch_message_filter,
371 bus_dispatch_remove_connection (DBusConnection *connection)
373 /* Here we tell the bus driver that we want to get off. */
374 bus_driver_remove_connection (connection);
376 dbus_connection_remove_filter (connection,
377 bus_dispatch_message_filter,
381 #ifdef DBUS_BUILD_TESTS
383 typedef dbus_bool_t (* Check1Func) (BusContext *context);
384 typedef dbus_bool_t (* Check2Func) (BusContext *context,
385 DBusConnection *connection);
387 static dbus_bool_t check_no_leftovers (BusContext *context);
390 block_connection_until_message_from_bus (BusContext *context,
391 DBusConnection *connection)
393 while (dbus_connection_get_dispatch_status (connection) ==
394 DBUS_DISPATCH_COMPLETE &&
395 dbus_connection_get_is_connected (connection))
397 bus_test_run_bus_loop (context, TRUE);
398 bus_test_run_clients_loop (FALSE);
402 /* compensate for fact that pop_message() can return #NULL due to OOM */
404 pop_message_waiting_for_memory (DBusConnection *connection)
406 while (dbus_connection_get_dispatch_status (connection) ==
407 DBUS_DISPATCH_NEED_MEMORY)
408 _dbus_wait_for_memory ();
410 return dbus_connection_pop_message (connection);
414 warn_unexpected_real (DBusConnection *connection,
415 DBusMessage *message,
416 const char *expected,
417 const char *function,
420 _dbus_warn ("%s:%d received message interface \"%s\" member \"%s\" error name \"%s\" on %p, expecting %s\n",
422 dbus_message_get_interface (message) ?
423 dbus_message_get_interface (message) : "(unset)",
424 dbus_message_get_member (message) ?
425 dbus_message_get_member (message) : "(unset)",
426 dbus_message_get_error_name (message) ?
427 dbus_message_get_error_name (message) : "(unset)",
432 #define warn_unexpected(connection, message, expected) \
433 warn_unexpected_real (connection, message, expected, _DBUS_FUNCTION_NAME, __LINE__)
436 verbose_message_received (DBusConnection *connection,
437 DBusMessage *message)
439 _dbus_verbose ("Received message interface \"%s\" member \"%s\" error name \"%s\" on %p\n",
440 dbus_message_get_interface (message) ?
441 dbus_message_get_interface (message) : "(unset)",
442 dbus_message_get_member (message) ?
443 dbus_message_get_member (message) : "(unset)",
444 dbus_message_get_error_name (message) ?
445 dbus_message_get_error_name (message) : "(unset)",
451 const char *expected_service_name;
453 } CheckServiceDeletedData;
456 check_service_deleted_foreach (DBusConnection *connection,
459 CheckServiceDeletedData *d = data;
460 DBusMessage *message;
464 dbus_error_init (&error);
468 message = pop_message_waiting_for_memory (connection);
471 _dbus_warn ("Did not receive a message on %p, expecting %s\n",
472 connection, "ServiceDeleted");
475 else if (!dbus_message_is_signal (message,
476 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
479 warn_unexpected (connection, message, "ServiceDeleted");
485 if (!dbus_message_get_args (message, &error,
486 DBUS_TYPE_STRING, &service_name,
489 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
491 _dbus_verbose ("no memory to get service name arg\n");
495 _dbus_assert (dbus_error_is_set (&error));
496 _dbus_warn ("Did not get the expected single string argument\n");
500 else if (strcmp (service_name, d->expected_service_name) != 0)
502 _dbus_warn ("expected deletion of service %s, got deletion of %s\n",
503 d->expected_service_name,
512 dbus_free (service_name);
513 dbus_error_free (&error);
516 dbus_message_unref (message);
522 kill_client_connection (BusContext *context,
523 DBusConnection *connection)
527 CheckServiceDeletedData csdd;
529 _dbus_verbose ("killing connection %p\n", connection);
531 s = dbus_bus_get_base_service (connection);
532 _dbus_assert (s != NULL);
534 while ((base_service = _dbus_strdup (s)) == NULL)
535 _dbus_wait_for_memory ();
537 dbus_connection_ref (connection);
539 /* kick in the disconnect handler that unrefs the connection */
540 dbus_connection_disconnect (connection);
542 bus_test_run_everything (context);
544 _dbus_assert (bus_test_client_listed (connection));
546 /* Run disconnect handler in test.c */
547 if (bus_connection_dispatch_one_message (connection))
548 _dbus_assert_not_reached ("something received on connection being killed other than the disconnect");
550 _dbus_assert (!dbus_connection_get_is_connected (connection));
551 dbus_connection_unref (connection);
553 _dbus_assert (!bus_test_client_listed (connection));
555 csdd.expected_service_name = base_service;
558 bus_test_clients_foreach (check_service_deleted_foreach,
561 dbus_free (base_service);
564 _dbus_assert_not_reached ("didn't get the expected ServiceDeleted messages");
566 if (!check_no_leftovers (context))
567 _dbus_assert_not_reached ("stuff left in message queues after disconnecting a client");
571 kill_client_connection_unchecked (DBusConnection *connection)
573 /* This kills the connection without expecting it to affect
574 * the rest of the bus.
576 _dbus_verbose ("Unchecked kill of connection %p\n", connection);
578 dbus_connection_ref (connection);
579 dbus_connection_disconnect (connection);
580 /* dispatching disconnect handler will unref once */
581 if (bus_connection_dispatch_one_message (connection))
582 _dbus_assert_not_reached ("message other than disconnect dispatched after failure to register");
584 _dbus_assert (!bus_test_client_listed (connection));
585 dbus_connection_unref (connection);
591 } CheckNoMessagesData;
594 check_no_messages_foreach (DBusConnection *connection,
597 CheckNoMessagesData *d = data;
598 DBusMessage *message;
600 message = pop_message_waiting_for_memory (connection);
603 warn_unexpected (connection, message, "no messages");
609 dbus_message_unref (message);
615 DBusConnection *skip_connection;
616 const char *expected_service_name;
618 } CheckServiceCreatedData;
621 check_service_created_foreach (DBusConnection *connection,
624 CheckServiceCreatedData *d = data;
625 DBusMessage *message;
629 if (connection == d->skip_connection)
632 dbus_error_init (&error);
636 message = pop_message_waiting_for_memory (connection);
639 _dbus_warn ("Did not receive a message on %p, expecting %s\n",
640 connection, "ServiceCreated");
643 else if (!dbus_message_is_signal (message,
644 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
647 warn_unexpected (connection, message, "ServiceCreated");
652 if (!dbus_message_get_args (message, &error,
653 DBUS_TYPE_STRING, &service_name,
656 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
658 _dbus_verbose ("no memory to get service name arg\n");
662 _dbus_assert (dbus_error_is_set (&error));
663 _dbus_warn ("Did not get the expected single string argument\n");
667 else if (strcmp (service_name, d->expected_service_name) != 0)
669 _dbus_warn ("expected creation of service %s, got creation of %s\n",
670 d->expected_service_name,
679 dbus_free (service_name);
680 dbus_error_free (&error);
683 dbus_message_unref (message);
689 check_no_leftovers (BusContext *context)
691 CheckNoMessagesData nmd;
694 bus_test_clients_foreach (check_no_messages_foreach,
703 /* returns TRUE if the correct thing happens,
704 * but the correct thing may include OOM errors.
707 check_hello_message (BusContext *context,
708 DBusConnection *connection)
710 DBusMessage *message;
711 dbus_uint32_t serial;
718 dbus_error_init (&error);
723 _dbus_verbose ("check_hello_message for %p\n", connection);
725 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
726 DBUS_PATH_ORG_FREEDESKTOP_DBUS,
727 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
733 if (!dbus_connection_send (connection, message, &serial))
735 dbus_message_unref (message);
739 dbus_message_unref (message);
742 /* send our message */
743 bus_test_run_clients_loop (TRUE);
745 dbus_connection_ref (connection); /* because we may get disconnected */
746 block_connection_until_message_from_bus (context, connection);
748 if (!dbus_connection_get_is_connected (connection))
750 _dbus_verbose ("connection was disconnected\n");
752 dbus_connection_unref (connection);
757 dbus_connection_unref (connection);
759 message = pop_message_waiting_for_memory (connection);
762 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
763 "Hello", serial, connection);
767 verbose_message_received (connection, message);
769 if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
771 _dbus_warn ("Message has wrong sender %s\n",
772 dbus_message_get_sender (message) ?
773 dbus_message_get_sender (message) : "(none)");
777 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
779 if (dbus_message_is_error (message,
780 DBUS_ERROR_NO_MEMORY))
782 ; /* good, this is a valid response */
786 warn_unexpected (connection, message, "not this error");
793 CheckServiceCreatedData scd;
795 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
797 ; /* good, expected */
801 warn_unexpected (connection, message, "method return for Hello");
806 retry_get_hello_name:
807 if (!dbus_message_get_args (message, &error,
808 DBUS_TYPE_STRING, &name,
811 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
813 _dbus_verbose ("no memory to get service name arg from hello\n");
814 dbus_error_free (&error);
815 _dbus_wait_for_memory ();
816 goto retry_get_hello_name;
820 _dbus_assert (dbus_error_is_set (&error));
821 _dbus_warn ("Did not get the expected single string argument to hello\n");
826 _dbus_verbose ("Got hello name: %s\n", name);
828 while (!dbus_bus_set_base_service (connection, name))
829 _dbus_wait_for_memory ();
831 scd.skip_connection = connection; /* we haven't done AddMatch so won't get it ourselves */
833 scd.expected_service_name = name;
834 bus_test_clients_foreach (check_service_created_foreach,
840 /* Client should also have gotten ServiceAcquired */
841 dbus_message_unref (message);
842 message = pop_message_waiting_for_memory (connection);
845 _dbus_warn ("Expecting %s, got nothing\n",
850 retry_get_acquired_name:
851 if (!dbus_message_get_args (message, &error,
852 DBUS_TYPE_STRING, &acquired,
855 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
857 _dbus_verbose ("no memory to get service name arg from acquired\n");
858 dbus_error_free (&error);
859 _dbus_wait_for_memory ();
860 goto retry_get_acquired_name;
864 _dbus_assert (dbus_error_is_set (&error));
865 _dbus_warn ("Did not get the expected single string argument to ServiceAcquired\n");
870 _dbus_verbose ("Got acquired name: %s\n", acquired);
872 if (strcmp (acquired, name) != 0)
874 _dbus_warn ("Acquired name is %s but expected %s\n",
880 if (!check_no_leftovers (context))
886 dbus_error_free (&error);
889 dbus_free (acquired);
892 dbus_message_unref (message);
897 /* returns TRUE if the correct thing happens,
898 * but the correct thing may include OOM errors.
901 check_add_match_all (BusContext *context,
902 DBusConnection *connection)
904 DBusMessage *message;
906 dbus_uint32_t serial;
910 dbus_error_init (&error);
913 _dbus_verbose ("check_add_match_all for %p\n", connection);
915 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
916 DBUS_PATH_ORG_FREEDESKTOP_DBUS,
917 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
923 if (!dbus_message_append_args (message, DBUS_TYPE_STRING, "", /* FIXME */
926 dbus_message_unref (message);
930 if (!dbus_connection_send (connection, message, &serial))
932 dbus_message_unref (message);
936 dbus_message_unref (message);
939 /* send our message */
940 bus_test_run_clients_loop (TRUE);
942 dbus_connection_ref (connection); /* because we may get disconnected */
943 block_connection_until_message_from_bus (context, connection);
945 if (!dbus_connection_get_is_connected (connection))
947 _dbus_verbose ("connection was disconnected\n");
949 dbus_connection_unref (connection);
954 dbus_connection_unref (connection);
956 message = pop_message_waiting_for_memory (connection);
959 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
960 "AddMatch", serial, connection);
964 verbose_message_received (connection, message);
966 if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
968 _dbus_warn ("Message has wrong sender %s\n",
969 dbus_message_get_sender (message) ?
970 dbus_message_get_sender (message) : "(none)");
974 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
976 if (dbus_message_is_error (message,
977 DBUS_ERROR_NO_MEMORY))
979 ; /* good, this is a valid response */
983 warn_unexpected (connection, message, "not this error");
990 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
992 ; /* good, expected */
993 _dbus_assert (dbus_message_get_reply_serial (message) == serial);
997 warn_unexpected (connection, message, "method return for AddMatch");
1003 if (!check_no_leftovers (context))
1009 dbus_error_free (&error);
1012 dbus_message_unref (message);
1017 /* returns TRUE if the correct thing happens,
1018 * but the correct thing may include OOM errors.
1021 check_hello_connection (BusContext *context)
1023 DBusConnection *connection;
1026 dbus_error_init (&error);
1028 connection = dbus_connection_open ("debug-pipe:name=test-server", &error);
1029 if (connection == NULL)
1031 _DBUS_ASSERT_ERROR_IS_SET (&error);
1032 dbus_error_free (&error);
1036 if (!bus_setup_debug_client (connection))
1038 dbus_connection_disconnect (connection);
1039 dbus_connection_unref (connection);
1043 if (!check_hello_message (context, connection))
1046 if (dbus_bus_get_base_service (connection) == NULL)
1048 /* We didn't successfully register, so we can't
1049 * do the usual kill_client_connection() checks
1051 kill_client_connection_unchecked (connection);
1055 if (!check_add_match_all (context, connection))
1058 kill_client_connection (context, connection);
1064 #define NONEXISTENT_SERVICE_NAME "test.this.service.does.not.exist.ewuoiurjdfxcvn"
1066 /* returns TRUE if the correct thing happens,
1067 * but the correct thing may include OOM errors.
1070 check_nonexistent_service_activation (BusContext *context,
1071 DBusConnection *connection)
1073 DBusMessage *message;
1074 dbus_uint32_t serial;
1078 dbus_error_init (&error);
1080 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
1081 DBUS_PATH_ORG_FREEDESKTOP_DBUS,
1082 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1085 if (message == NULL)
1088 if (!dbus_message_append_args (message,
1089 DBUS_TYPE_STRING, NONEXISTENT_SERVICE_NAME,
1090 DBUS_TYPE_UINT32, 0,
1093 dbus_message_unref (message);
1097 if (!dbus_connection_send (connection, message, &serial))
1099 dbus_message_unref (message);
1103 dbus_message_unref (message);
1106 bus_test_run_everything (context);
1107 block_connection_until_message_from_bus (context, connection);
1108 bus_test_run_everything (context);
1110 if (!dbus_connection_get_is_connected (connection))
1112 _dbus_verbose ("connection was disconnected\n");
1118 message = pop_message_waiting_for_memory (connection);
1119 if (message == NULL)
1121 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1122 "ActivateService", serial, connection);
1126 verbose_message_received (connection, message);
1128 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1130 if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
1132 _dbus_warn ("Message has wrong sender %s\n",
1133 dbus_message_get_sender (message) ?
1134 dbus_message_get_sender (message) : "(none)");
1138 if (dbus_message_is_error (message,
1139 DBUS_ERROR_NO_MEMORY))
1141 ; /* good, this is a valid response */
1143 else if (dbus_message_is_error (message,
1144 DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND))
1146 ; /* good, this is expected also */
1150 warn_unexpected (connection, message, "not this error");
1156 _dbus_warn ("Did not expect to successfully activate %s\n",
1157 NONEXISTENT_SERVICE_NAME);
1165 dbus_message_unref (message);
1171 check_base_service_activated (BusContext *context,
1172 DBusConnection *connection,
1173 DBusMessage *initial_message,
1174 char **base_service_p)
1176 DBusMessage *message;
1181 base_service = NULL;
1184 dbus_error_init (&error);
1186 message = initial_message;
1187 dbus_message_ref (message);
1189 if (dbus_message_is_signal (message,
1190 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1194 CheckServiceCreatedData scd;
1196 reget_service_name_arg:
1197 if (!dbus_message_get_args (message, &error,
1198 DBUS_TYPE_STRING, &service_name,
1201 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1203 dbus_error_free (&error);
1204 _dbus_wait_for_memory ();
1205 goto reget_service_name_arg;
1209 _dbus_warn ("Message %s doesn't have a service name: %s\n",
1212 dbus_error_free (&error);
1217 if (*service_name != ':')
1219 _dbus_warn ("Expected base service activation, got \"%s\" instead\n",
1224 base_service = service_name;
1225 service_name = NULL;
1227 scd.skip_connection = connection;
1229 scd.expected_service_name = base_service;
1230 bus_test_clients_foreach (check_service_created_foreach,
1238 warn_unexpected (connection, message, "ServiceCreated for base service");
1247 *base_service_p = base_service;
1248 base_service = NULL;
1253 dbus_message_unref (message);
1256 dbus_free (base_service);
1262 check_service_activated (BusContext *context,
1263 DBusConnection *connection,
1264 const char *activated_name,
1265 const char *base_service_name,
1266 DBusMessage *initial_message)
1268 DBusMessage *message;
1271 dbus_uint32_t activation_result;
1275 dbus_error_init (&error);
1277 message = initial_message;
1278 dbus_message_ref (message);
1280 if (dbus_message_is_signal (message,
1281 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1285 CheckServiceCreatedData scd;
1287 reget_service_name_arg:
1288 if (!dbus_message_get_args (message, &error,
1289 DBUS_TYPE_STRING, &service_name,
1292 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1294 dbus_error_free (&error);
1295 _dbus_wait_for_memory ();
1296 goto reget_service_name_arg;
1300 _dbus_warn ("Message %s doesn't have a service name: %s\n",
1303 dbus_error_free (&error);
1308 if (strcmp (service_name, activated_name) != 0)
1310 _dbus_warn ("Expected to see service %s created, saw %s instead\n",
1311 activated_name, service_name);
1312 dbus_free (service_name);
1316 scd.skip_connection = connection;
1318 scd.expected_service_name = service_name;
1319 bus_test_clients_foreach (check_service_created_foreach,
1322 dbus_free (service_name);
1327 dbus_message_unref (message);
1328 message = pop_message_waiting_for_memory (connection);
1329 if (message == NULL)
1331 _dbus_warn ("Expected a reply to %s, got nothing\n",
1338 warn_unexpected (connection, message, "ServiceCreated for the activated name");
1343 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN)
1345 warn_unexpected (connection, message, "reply to ActivateService");
1350 activation_result = 0;
1351 if (!dbus_message_get_args (message, &error,
1352 DBUS_TYPE_UINT32, &activation_result,
1355 if (!dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1357 _dbus_warn ("Did not have activation result first argument to %s: %s\n",
1358 "ActivateService", error.message);
1359 dbus_error_free (&error);
1363 dbus_error_free (&error);
1367 if (activation_result == DBUS_ACTIVATION_REPLY_ACTIVATED)
1369 else if (activation_result == DBUS_ACTIVATION_REPLY_ALREADY_ACTIVE)
1373 _dbus_warn ("Activation result was 0x%x, no good.\n",
1379 dbus_message_unref (message);
1382 if (!check_no_leftovers (context))
1384 _dbus_warn ("Messages were left over after verifying existent activation results\n");
1392 dbus_message_unref (message);
1398 check_service_deactivated (BusContext *context,
1399 DBusConnection *connection,
1400 const char *activated_name,
1401 const char *base_service)
1403 DBusMessage *message;
1406 CheckServiceDeletedData csdd;
1411 dbus_error_init (&error);
1413 /* Now we are expecting ServiceDeleted messages for the base
1414 * service and the activated_name. The base service
1415 * notification is required to come last.
1417 csdd.expected_service_name = activated_name;
1418 csdd.failed = FALSE;
1419 bus_test_clients_foreach (check_service_deleted_foreach,
1425 csdd.expected_service_name = base_service;
1426 csdd.failed = FALSE;
1427 bus_test_clients_foreach (check_service_deleted_foreach,
1433 if (!check_no_leftovers (context))
1435 _dbus_warn ("Messages were left over after verifying results of service exiting\n");
1443 dbus_message_unref (message);
1449 check_send_exit_to_service (BusContext *context,
1450 DBusConnection *connection,
1451 const char *service_name,
1452 const char *base_service)
1454 dbus_bool_t got_error;
1455 DBusMessage *message;
1456 dbus_uint32_t serial;
1459 _dbus_verbose ("Sending exit message to the test service\n");
1463 /* Kill off the test service by sending it a quit message */
1464 message = dbus_message_new_method_call (service_name,
1465 "/org/freedesktop/TestSuite",
1466 "org.freedesktop.TestSuite",
1469 if (message == NULL)
1471 /* Do this again; we still need the service to exit... */
1472 if (!check_send_exit_to_service (context, connection,
1473 service_name, base_service))
1479 if (!dbus_connection_send (connection, message, &serial))
1481 dbus_message_unref (message);
1483 /* Do this again; we still need the service to exit... */
1484 if (!check_send_exit_to_service (context, connection,
1485 service_name, base_service))
1491 dbus_message_unref (message);
1495 bus_test_run_clients_loop (TRUE);
1497 /* read it in and write it out to test service */
1498 bus_test_run_bus_loop (context, FALSE);
1500 /* see if we got an error during message bus dispatching */
1501 bus_test_run_clients_loop (FALSE);
1502 message = dbus_connection_borrow_message (connection);
1503 got_error = message != NULL && dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR;
1506 dbus_connection_return_message (connection, message);
1512 /* If no error, wait for the test service to exit */
1513 block_connection_until_message_from_bus (context, connection);
1515 bus_test_run_everything (context);
1520 message = pop_message_waiting_for_memory (connection);
1521 _dbus_assert (message != NULL);
1523 if (!dbus_message_is_error (message,
1524 DBUS_ERROR_NO_MEMORY))
1526 warn_unexpected (connection, message,
1527 "a no memory error from asking test service to exit");
1531 _dbus_verbose ("Got error %s when asking test service to exit\n",
1532 dbus_message_get_error_name (message));
1534 /* Do this again; we still need the service to exit... */
1535 if (!check_send_exit_to_service (context, connection,
1536 service_name, base_service))
1541 if (!check_service_deactivated (context, connection,
1542 service_name, base_service))
1550 dbus_message_unref (message);
1556 check_got_error (BusContext *context,
1557 DBusConnection *connection,
1558 const char *first_error_name,
1561 DBusMessage *message;
1564 dbus_bool_t error_found;
1565 const char *error_name;
1569 message = pop_message_waiting_for_memory (connection);
1570 if (message == NULL)
1572 _dbus_warn ("Did not get an expected error\n");
1576 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
1578 warn_unexpected (connection, message, "an error");
1583 error_found = FALSE;
1585 va_start (ap, first_error_name);
1586 error_name = first_error_name;
1587 while (error_name != NULL)
1589 if (dbus_message_is_error (message, error_name))
1594 error_name = va_arg (ap, char*);
1600 _dbus_warn ("Expected error %s or other, got %s instead\n",
1602 dbus_message_get_error_name (message));
1610 dbus_message_unref (message);
1615 #define EXISTENT_SERVICE_NAME "org.freedesktop.DBus.TestSuiteEchoService"
1617 /* returns TRUE if the correct thing happens,
1618 * but the correct thing may include OOM errors.
1621 check_existent_service_activation (BusContext *context,
1622 DBusConnection *connection)
1624 DBusMessage *message;
1625 dbus_uint32_t serial;
1630 base_service = NULL;
1632 dbus_error_init (&error);
1634 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
1635 DBUS_PATH_ORG_FREEDESKTOP_DBUS,
1636 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1639 if (message == NULL)
1642 if (!dbus_message_append_args (message,
1643 DBUS_TYPE_STRING, EXISTENT_SERVICE_NAME,
1644 DBUS_TYPE_UINT32, 0,
1647 dbus_message_unref (message);
1651 if (!dbus_connection_send (connection, message, &serial))
1653 dbus_message_unref (message);
1657 dbus_message_unref (message);
1660 bus_test_run_everything (context);
1662 /* now wait for the message bus to hear back from the activated
1665 block_connection_until_message_from_bus (context, connection);
1667 bus_test_run_everything (context);
1669 if (!dbus_connection_get_is_connected (connection))
1671 _dbus_verbose ("connection was disconnected\n");
1677 message = pop_message_waiting_for_memory (connection);
1678 if (message == NULL)
1680 _dbus_warn ("Did not receive any messages after %s %d on %p\n",
1681 "ActivateService", serial, connection);
1685 verbose_message_received (connection, message);
1686 _dbus_verbose (" (after sending %s)\n", "ActivateService");
1688 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1690 if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
1692 _dbus_warn ("Message has wrong sender %s\n",
1693 dbus_message_get_sender (message) ?
1694 dbus_message_get_sender (message) : "(none)");
1698 if (dbus_message_is_error (message,
1699 DBUS_ERROR_NO_MEMORY))
1701 ; /* good, this is a valid response */
1703 else if (dbus_message_is_error (message,
1704 DBUS_ERROR_SPAWN_CHILD_EXITED))
1706 ; /* good, this is expected also */
1710 _dbus_warn ("Did not expect error %s\n",
1711 dbus_message_get_error_name (message));
1717 dbus_bool_t got_service_deleted;
1718 dbus_bool_t got_error;
1720 if (!check_base_service_activated (context, connection,
1721 message, &base_service))
1724 dbus_message_unref (message);
1727 /* We may need to block here for the test service to exit or finish up */
1728 block_connection_until_message_from_bus (context, connection);
1730 message = dbus_connection_borrow_message (connection);
1731 if (message == NULL)
1733 _dbus_warn ("Did not receive any messages after base service creation notification\n");
1737 got_service_deleted = dbus_message_is_signal (message,
1738 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1740 got_error = dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR;
1742 dbus_connection_return_message (connection, message);
1747 if (!check_got_error (context, connection,
1748 DBUS_ERROR_SPAWN_CHILD_EXITED,
1749 DBUS_ERROR_NO_MEMORY,
1753 /* A service deleted should be coming along now after this error.
1754 * We can also get the error *after* the service deleted.
1756 got_service_deleted = TRUE;
1759 if (got_service_deleted)
1761 /* The service started up and got a base address, but then
1762 * failed to register under EXISTENT_SERVICE_NAME
1764 CheckServiceDeletedData csdd;
1766 csdd.expected_service_name = base_service;
1767 csdd.failed = FALSE;
1768 bus_test_clients_foreach (check_service_deleted_foreach,
1774 /* Now we should get an error about the service exiting
1775 * if we didn't get it before.
1779 block_connection_until_message_from_bus (context, connection);
1781 /* and process everything again */
1782 bus_test_run_everything (context);
1784 if (!check_got_error (context, connection,
1785 DBUS_ERROR_SPAWN_CHILD_EXITED,
1792 message = pop_message_waiting_for_memory (connection);
1793 if (message == NULL)
1795 _dbus_warn ("Failed to pop message we just put back! should have been a ServiceCreated\n");
1799 if (!check_service_activated (context, connection, EXISTENT_SERVICE_NAME,
1800 base_service, message))
1803 dbus_message_unref (message);
1807 if (!check_no_leftovers (context))
1809 _dbus_warn ("Messages were left over after successful activation\n");
1813 if (!check_send_exit_to_service (context, connection,
1814 EXISTENT_SERVICE_NAME, base_service))
1823 dbus_message_unref (message);
1826 dbus_free (base_service);
1831 /* returns TRUE if the correct thing happens,
1832 * but the correct thing may include OOM errors.
1835 check_segfault_service_activation (BusContext *context,
1836 DBusConnection *connection)
1838 DBusMessage *message;
1839 dbus_uint32_t serial;
1843 dbus_error_init (&error);
1845 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
1846 DBUS_PATH_ORG_FREEDESKTOP_DBUS,
1847 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1850 if (message == NULL)
1853 if (!dbus_message_append_args (message,
1855 "org.freedesktop.DBus.TestSuiteSegfaultService",
1856 DBUS_TYPE_UINT32, 0,
1859 dbus_message_unref (message);
1863 if (!dbus_connection_send (connection, message, &serial))
1865 dbus_message_unref (message);
1869 dbus_message_unref (message);
1872 bus_test_run_everything (context);
1873 block_connection_until_message_from_bus (context, connection);
1874 bus_test_run_everything (context);
1876 if (!dbus_connection_get_is_connected (connection))
1878 _dbus_verbose ("connection was disconnected\n");
1884 message = pop_message_waiting_for_memory (connection);
1885 if (message == NULL)
1887 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1888 "ActivateService", serial, connection);
1892 verbose_message_received (connection, message);
1894 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1896 if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
1898 _dbus_warn ("Message has wrong sender %s\n",
1899 dbus_message_get_sender (message) ?
1900 dbus_message_get_sender (message) : "(none)");
1904 if (dbus_message_is_error (message,
1905 DBUS_ERROR_NO_MEMORY))
1907 ; /* good, this is a valid response */
1909 else if (dbus_message_is_error (message,
1910 DBUS_ERROR_SPAWN_CHILD_SIGNALED))
1912 ; /* good, this is expected also */
1916 warn_unexpected (connection, message, "not this error");
1923 _dbus_warn ("Did not expect to successfully activate segfault service\n");
1931 dbus_message_unref (message);
1939 BusContext *context;
1943 check_oom_check1_func (void *data)
1945 Check1Data *d = data;
1947 if (! (* d->func) (d->context))
1950 if (!check_no_leftovers (d->context))
1952 _dbus_warn ("Messages were left over, should be covered by test suite\n");
1960 check1_try_iterations (BusContext *context,
1961 const char *description,
1967 d.context = context;
1969 if (!_dbus_test_oom_handling (description, check_oom_check1_func,
1971 _dbus_assert_not_reached ("test failed");
1977 BusContext *context;
1978 DBusConnection *connection;
1982 check_oom_check2_func (void *data)
1984 Check2Data *d = data;
1986 if (! (* d->func) (d->context, d->connection))
1989 if (!check_no_leftovers (d->context))
1991 _dbus_warn ("Messages were left over, should be covered by test suite");
1999 check2_try_iterations (BusContext *context,
2000 DBusConnection *connection,
2001 const char *description,
2007 d.context = context;
2008 d.connection = connection;
2010 if (!_dbus_test_oom_handling (description, check_oom_check2_func,
2012 _dbus_assert_not_reached ("test failed");
2016 bus_dispatch_test (const DBusString *test_data_dir)
2018 BusContext *context;
2019 DBusConnection *foo;
2020 DBusConnection *bar;
2021 DBusConnection *baz;
2024 dbus_error_init (&error);
2026 context = bus_context_new_test (test_data_dir,
2027 "valid-config-files/debug-allow-all.conf");
2028 if (context == NULL)
2031 foo = dbus_connection_open ("debug-pipe:name=test-server", &error);
2033 _dbus_assert_not_reached ("could not alloc connection");
2035 if (!bus_setup_debug_client (foo))
2036 _dbus_assert_not_reached ("could not set up connection");
2038 if (!check_hello_message (context, foo))
2039 _dbus_assert_not_reached ("hello message failed");
2041 if (!check_add_match_all (context, foo))
2042 _dbus_assert_not_reached ("AddMatch message failed");
2044 bar = dbus_connection_open ("debug-pipe:name=test-server", &error);
2046 _dbus_assert_not_reached ("could not alloc connection");
2048 if (!bus_setup_debug_client (bar))
2049 _dbus_assert_not_reached ("could not set up connection");
2051 if (!check_hello_message (context, bar))
2052 _dbus_assert_not_reached ("hello message failed");
2054 if (!check_add_match_all (context, bar))
2055 _dbus_assert_not_reached ("AddMatch message failed");
2057 baz = dbus_connection_open ("debug-pipe:name=test-server", &error);
2059 _dbus_assert_not_reached ("could not alloc connection");
2061 if (!bus_setup_debug_client (baz))
2062 _dbus_assert_not_reached ("could not set up connection");
2064 if (!check_hello_message (context, baz))
2065 _dbus_assert_not_reached ("hello message failed");
2067 if (!check_add_match_all (context, baz))
2068 _dbus_assert_not_reached ("AddMatch message failed");
2070 if (!check_no_leftovers (context))
2072 _dbus_warn ("Messages were left over after setting up initial connections");
2073 _dbus_assert_not_reached ("initial connection setup failed");
2076 check1_try_iterations (context, "create_and_hello",
2077 check_hello_connection);
2079 check2_try_iterations (context, foo, "nonexistent_service_activation",
2080 check_nonexistent_service_activation);
2082 check2_try_iterations (context, foo, "segfault_service_activation",
2083 check_segfault_service_activation);
2085 check2_try_iterations (context, foo, "existent_service_activation",
2086 check_existent_service_activation);
2088 _dbus_verbose ("Disconnecting foo, bar, and baz\n");
2090 kill_client_connection_unchecked (foo);
2091 kill_client_connection_unchecked (bar);
2092 kill_client_connection_unchecked (baz);
2094 bus_context_unref (context);
2100 bus_dispatch_sha1_test (const DBusString *test_data_dir)
2102 BusContext *context;
2103 DBusConnection *foo;
2106 dbus_error_init (&error);
2108 /* Test SHA1 authentication */
2109 _dbus_verbose ("Testing SHA1 context\n");
2111 context = bus_context_new_test (test_data_dir,
2112 "valid-config-files/debug-allow-all-sha1.conf");
2113 if (context == NULL)
2116 foo = dbus_connection_open ("debug-pipe:name=test-server", &error);
2118 _dbus_assert_not_reached ("could not alloc connection");
2120 if (!bus_setup_debug_client (foo))
2121 _dbus_assert_not_reached ("could not set up connection");
2123 if (!check_hello_message (context, foo))
2124 _dbus_assert_not_reached ("hello message failed");
2126 if (!check_add_match_all (context, foo))
2127 _dbus_assert_not_reached ("addmatch message failed");
2129 if (!check_no_leftovers (context))
2131 _dbus_warn ("Messages were left over after setting up initial SHA-1 connection\n");
2132 _dbus_assert_not_reached ("initial connection setup failed");
2135 check1_try_iterations (context, "create_and_hello_sha1",
2136 check_hello_connection);
2138 kill_client_connection_unchecked (foo);
2140 bus_context_unref (context);
2145 #endif /* DBUS_BUILD_TESTS */