1#include <config.h> 2#include "../test-utils.h" 3 4static void 5die (const char *message, ...) 6{ 7 va_list args; 8 va_start (args, message); 9 vfprintf (stderr, message, args); 10 va_end (args); 11 exit (1); 12} 13 14#define PRIVSERVER_SERVICE "org.freedesktop.DBus.TestSuite.PrivServer" 15#define PRIVSERVER_INTERFACE PRIVSERVER_SERVICE 16#define PRIVSERVER_DIED_RULE \ 17 "type='signal',sender='" DBUS_SERVICE_DBUS "'," \ 18 "interface='" DBUS_INTERFACE_DBUS "',member='NameOwnerChanged'," \ 19 "arg0='" PRIVSERVER_SERVICE "',arg2=''" 20 21static DBusHandlerResult 22filter_session_message (DBusConnection *connection, 23 DBusMessage *message, 24 void *user_data) 25{ 26 dbus_bool_t *service_died_p = user_data; 27 const char *name, *old_owner, *new_owner; 28 29 if (dbus_message_is_signal (message, 30 DBUS_INTERFACE_DBUS, 31 "NameOwnerChanged") && 32 dbus_message_has_sender (message, DBUS_SERVICE_DBUS) && 33 dbus_message_get_args (message, NULL, 34 DBUS_TYPE_STRING, &name, 35 DBUS_TYPE_STRING, &old_owner, 36 DBUS_TYPE_STRING, &new_owner, 37 DBUS_TYPE_INVALID) && 38 strcmp (name, PRIVSERVER_SERVICE) == 0 && 39 old_owner[0] != '\0' && 40 new_owner[0] == '\0') 41 { 42 *service_died_p = TRUE; 43 } 44 45 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 46} 47 48static DBusHandlerResult 49filter_private_message (DBusConnection *connection, 50 DBusMessage *message, 51 void *user_data) 52{ 53 dbus_bool_t *private_conn_lost_p = user_data; 54 55 if (dbus_message_is_signal (message, 56 DBUS_INTERFACE_LOCAL, 57 "Disconnected")) 58 { 59 *private_conn_lost_p = TRUE; 60 } 61 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 62} 63 64static void 65open_shutdown_private_connection (dbus_bool_t use_guid) 66{ 67 DBusError error; 68 DBusLoop *loop; 69 DBusConnection *session; 70 DBusMessage *msg; 71 DBusMessage *reply; 72 DBusConnection *privconn; 73 char *addr; 74 dbus_bool_t service_died; 75 dbus_bool_t private_conn_lost; 76 77 dbus_error_init (&error); 78 service_died = FALSE; 79 private_conn_lost = FALSE; 80 81 loop = _dbus_loop_new (); 82 83 session = dbus_bus_get (DBUS_BUS_SESSION, &error); 84 if (!session) 85 die ("couldn't access session bus\n"); 86 dbus_connection_set_exit_on_disconnect (session, FALSE); 87 test_connection_setup (loop, session); 88 89 dbus_bus_add_match (session, PRIVSERVER_DIED_RULE, &error); 90 if (dbus_error_is_set (&error)) 91 die ("couldn't add match rule \"%s\": %s: %s", PRIVSERVER_DIED_RULE, 92 error.name, error.message); 93 94 if (!dbus_connection_add_filter (session, filter_session_message, 95 &service_died, NULL)) 96 die ("couldn't add filter to session bus\n"); 97 98 msg = dbus_message_new_method_call (PRIVSERVER_SERVICE, "/", 99 PRIVSERVER_INTERFACE, "GetPrivateAddress"); 100 if (!(reply = dbus_connection_send_with_reply_and_block (session, msg, -1, &error))) 101 die ("couldn't send message: %s\n", error.message); 102 dbus_message_unref (msg); 103 if (!dbus_message_get_args (reply, &error, DBUS_TYPE_STRING, &addr, DBUS_TYPE_INVALID)) 104 die ("couldn't parse message replym\n"); 105 printf ("got private temp address %s\n", addr); 106 addr = strdup (addr); 107 if (!use_guid) 108 { 109 char *comma = strrchr (addr, ','); 110 if (comma) 111 *comma = '\0'; 112 } 113 privconn = dbus_connection_open (addr, &error); 114 free (addr); 115 if (!privconn) 116 die ("couldn't connect to server direct connection: %s\n", error.message); 117 dbus_message_unref (reply); 118 119 dbus_connection_set_exit_on_disconnect (privconn, FALSE); 120 if (!dbus_connection_add_filter (privconn, filter_private_message, 121 &private_conn_lost, NULL)) 122 die ("couldn't add filter to private connection\n"); 123 test_connection_setup (loop, privconn); 124 125 msg = dbus_message_new_method_call (PRIVSERVER_SERVICE, "/", 126 PRIVSERVER_INTERFACE, "Quit"); 127 if (!dbus_connection_send (session, msg, NULL)) 128 die ("couldn't send Quit message\n"); 129 dbus_message_unref (msg); 130 131 while (!service_died || !private_conn_lost) 132 _dbus_loop_iterate (loop, TRUE); 133 134 dbus_connection_remove_filter (session, filter_session_message, 135 &service_died); 136 dbus_bus_remove_match (session, PRIVSERVER_DIED_RULE, NULL); 137 test_connection_shutdown (loop, session); 138 dbus_connection_unref (session); 139 140 test_connection_shutdown (loop, privconn); 141 dbus_connection_remove_filter (privconn, filter_private_message, 142 &private_conn_lost); 143 dbus_connection_unref (privconn); 144 145 _dbus_loop_unref (loop); 146} 147 148int 149main (int argc, char *argv[]) 150{ 151 open_shutdown_private_connection (TRUE); 152 153 dbus_shutdown (); 154 155 open_shutdown_private_connection (TRUE); 156 157 dbus_shutdown (); 158 159 open_shutdown_private_connection (FALSE); 160 161 dbus_shutdown (); 162 163 open_shutdown_private_connection (FALSE); 164 165 dbus_shutdown (); 166 167 return 0; 168} 169