| #include <config.h> |
| #include "../test-utils.h" |
| |
| static void |
| die (const char *message, ...) |
| { |
| va_list args; |
| va_start (args, message); |
| vfprintf (stderr, message, args); |
| va_end (args); |
| exit (1); |
| } |
| |
| #define PRIVSERVER_SERVICE "org.freedesktop.DBus.TestSuite.PrivServer" |
| #define PRIVSERVER_INTERFACE PRIVSERVER_SERVICE |
| #define PRIVSERVER_DIED_RULE \ |
| "type='signal',sender='" DBUS_SERVICE_DBUS "'," \ |
| "interface='" DBUS_INTERFACE_DBUS "',member='NameOwnerChanged'," \ |
| "arg0='" PRIVSERVER_SERVICE "',arg2=''" |
| |
| static DBusHandlerResult |
| filter_session_message (DBusConnection *connection, |
| DBusMessage *message, |
| void *user_data) |
| { |
| dbus_bool_t *service_died_p = user_data; |
| const char *name, *old_owner, *new_owner; |
| |
| if (dbus_message_is_signal (message, |
| DBUS_INTERFACE_DBUS, |
| "NameOwnerChanged") && |
| dbus_message_has_sender (message, DBUS_SERVICE_DBUS) && |
| dbus_message_get_args (message, NULL, |
| DBUS_TYPE_STRING, &name, |
| DBUS_TYPE_STRING, &old_owner, |
| DBUS_TYPE_STRING, &new_owner, |
| DBUS_TYPE_INVALID) && |
| strcmp (name, PRIVSERVER_SERVICE) == 0 && |
| old_owner[0] != '\0' && |
| new_owner[0] == '\0') |
| { |
| *service_died_p = TRUE; |
| } |
| |
| return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| } |
| |
| static DBusHandlerResult |
| filter_private_message (DBusConnection *connection, |
| DBusMessage *message, |
| void *user_data) |
| { |
| dbus_bool_t *private_conn_lost_p = user_data; |
| |
| if (dbus_message_is_signal (message, |
| DBUS_INTERFACE_LOCAL, |
| "Disconnected")) |
| { |
| *private_conn_lost_p = TRUE; |
| } |
| return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| } |
| |
| static void |
| open_shutdown_private_connection (dbus_bool_t use_guid) |
| { |
| DBusError error; |
| DBusLoop *loop; |
| DBusConnection *session; |
| DBusMessage *msg; |
| DBusMessage *reply; |
| DBusConnection *privconn; |
| char *addr; |
| char *comma; |
| dbus_bool_t service_died; |
| dbus_bool_t private_conn_lost; |
| |
| dbus_error_init (&error); |
| service_died = FALSE; |
| private_conn_lost = FALSE; |
| |
| loop = _dbus_loop_new (); |
| |
| session = dbus_bus_get (DBUS_BUS_SESSION, &error); |
| if (!session) |
| die ("couldn't access session bus\n"); |
| dbus_connection_set_exit_on_disconnect (session, FALSE); |
| test_connection_setup (loop, session); |
| |
| dbus_bus_add_match (session, PRIVSERVER_DIED_RULE, &error); |
| if (dbus_error_is_set (&error)) |
| die ("couldn't add match rule \"%s\": %s: %s", PRIVSERVER_DIED_RULE, |
| error.name, error.message); |
| |
| if (!dbus_connection_add_filter (session, filter_session_message, |
| &service_died, NULL)) |
| die ("couldn't add filter to session bus\n"); |
| |
| msg = dbus_message_new_method_call (PRIVSERVER_SERVICE, "/", |
| PRIVSERVER_INTERFACE, "GetPrivateAddress"); |
| if (!(reply = dbus_connection_send_with_reply_and_block (session, msg, -1, &error))) |
| die ("couldn't send message: %s\n", error.message); |
| dbus_message_unref (msg); |
| if (!dbus_message_get_args (reply, &error, DBUS_TYPE_STRING, &addr, DBUS_TYPE_INVALID)) |
| die ("couldn't parse message replym\n"); |
| printf ("got private temp address %s\n", addr); |
| addr = strdup (addr); |
| if (!use_guid) |
| { |
| char *comma = strrchr (addr, ','); |
| if (comma) |
| *comma = '\0'; |
| } |
| privconn = dbus_connection_open (addr, &error); |
| free (addr); |
| if (!privconn) |
| die ("couldn't connect to server direct connection: %s\n", error.message); |
| dbus_message_unref (reply); |
| |
| dbus_connection_set_exit_on_disconnect (privconn, FALSE); |
| if (!dbus_connection_add_filter (privconn, filter_private_message, |
| &private_conn_lost, NULL)) |
| die ("couldn't add filter to private connection\n"); |
| test_connection_setup (loop, privconn); |
| |
| msg = dbus_message_new_method_call (PRIVSERVER_SERVICE, "/", |
| PRIVSERVER_INTERFACE, "Quit"); |
| if (!dbus_connection_send (session, msg, NULL)) |
| die ("couldn't send Quit message\n"); |
| dbus_message_unref (msg); |
| |
| while (!service_died || !private_conn_lost) |
| _dbus_loop_iterate (loop, TRUE); |
| |
| dbus_connection_remove_filter (session, filter_session_message, |
| &service_died); |
| dbus_bus_remove_match (session, PRIVSERVER_DIED_RULE, NULL); |
| test_connection_shutdown (loop, session); |
| dbus_connection_unref (session); |
| |
| test_connection_shutdown (loop, privconn); |
| dbus_connection_remove_filter (privconn, filter_private_message, |
| &private_conn_lost); |
| dbus_connection_unref (privconn); |
| |
| _dbus_loop_unref (loop); |
| } |
| |
| int |
| main (int argc, char *argv[]) |
| { |
| open_shutdown_private_connection (TRUE); |
| |
| dbus_shutdown (); |
| |
| open_shutdown_private_connection (TRUE); |
| |
| dbus_shutdown (); |
| |
| open_shutdown_private_connection (FALSE); |
| |
| dbus_shutdown (); |
| |
| open_shutdown_private_connection (FALSE); |
| |
| dbus_shutdown (); |
| |
| return 0; |
| } |