Merge branch 'dbus-1.4'
[platform/upstream/dbus.git] / test / name-test / test-privserver-client.c
1 #include <config.h>
2 #include "../test-utils.h"
3
4 static void
5 die (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
21 static DBusHandlerResult
22 filter_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
48 static DBusHandlerResult 
49 filter_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
64 static void
65 open_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   char *comma;
75   dbus_bool_t service_died;
76   dbus_bool_t private_conn_lost;
77
78   dbus_error_init (&error);
79   service_died = FALSE;
80   private_conn_lost = FALSE;
81
82   loop = _dbus_loop_new ();
83
84   session = dbus_bus_get (DBUS_BUS_SESSION, &error);
85   if (!session)
86     die ("couldn't access session bus\n");
87   dbus_connection_set_exit_on_disconnect (session, FALSE);
88   test_connection_setup (loop, session);
89
90   dbus_bus_add_match (session, PRIVSERVER_DIED_RULE, &error);
91   if (dbus_error_is_set (&error))
92     die ("couldn't add match rule \"%s\": %s: %s", PRIVSERVER_DIED_RULE,
93          error.name, error.message);
94
95   if (!dbus_connection_add_filter (session, filter_session_message,
96                                    &service_died, NULL))
97     die ("couldn't add filter to session bus\n");
98
99   msg = dbus_message_new_method_call (PRIVSERVER_SERVICE, "/",
100                                       PRIVSERVER_INTERFACE, "GetPrivateAddress");
101   if (!(reply = dbus_connection_send_with_reply_and_block (session, msg, -1, &error)))
102     die ("couldn't send message: %s\n", error.message);
103   dbus_message_unref (msg);
104   if (!dbus_message_get_args (reply, &error, DBUS_TYPE_STRING, &addr, DBUS_TYPE_INVALID))
105     die ("couldn't parse message replym\n");
106   printf ("got private temp address %s\n", addr);
107   addr = strdup (addr);
108   if (!use_guid)
109     {
110       char *comma = strrchr (addr, ',');
111       if (comma)
112         *comma = '\0';
113     }
114   privconn = dbus_connection_open (addr, &error);
115   free (addr);
116   if (!privconn)
117     die ("couldn't connect to server direct connection: %s\n", error.message);
118   dbus_message_unref (reply);
119
120   dbus_connection_set_exit_on_disconnect (privconn, FALSE);
121   if (!dbus_connection_add_filter (privconn, filter_private_message,
122                                    &private_conn_lost, NULL))
123     die ("couldn't add filter to private connection\n");
124   test_connection_setup (loop, privconn);
125
126   msg = dbus_message_new_method_call (PRIVSERVER_SERVICE, "/",
127                                       PRIVSERVER_INTERFACE, "Quit");
128   if (!dbus_connection_send (session, msg, NULL))
129     die ("couldn't send Quit message\n");
130   dbus_message_unref (msg);
131
132   while (!service_died || !private_conn_lost)
133     _dbus_loop_iterate (loop, TRUE);
134
135   dbus_connection_remove_filter (session, filter_session_message,
136                                  &service_died);
137   dbus_bus_remove_match (session, PRIVSERVER_DIED_RULE, NULL);
138   test_connection_shutdown (loop, session);
139   dbus_connection_unref (session);
140
141   test_connection_shutdown (loop, privconn);
142   dbus_connection_remove_filter (privconn, filter_private_message,
143                                  &private_conn_lost);
144   dbus_connection_unref (privconn);
145
146   _dbus_loop_unref (loop);
147 }
148
149 int
150 main (int argc, char *argv[])
151 {
152   open_shutdown_private_connection (TRUE);
153
154   dbus_shutdown ();
155
156   open_shutdown_private_connection (TRUE);
157
158   dbus_shutdown ();
159
160   open_shutdown_private_connection (FALSE);
161
162   dbus_shutdown ();
163
164   open_shutdown_private_connection (FALSE);
165
166   dbus_shutdown ();
167
168   return 0;
169 }