• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <config.h>
2 #include "../test-utils.h"
3 
4 static void
die(const char * message,...)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
filter_session_message(DBusConnection * connection,DBusMessage * message,void * user_data)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
filter_private_message(DBusConnection * connection,DBusMessage * message,void * user_data)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
open_shutdown_private_connection(dbus_bool_t use_guid)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   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 
148 int
main(int argc,char * argv[])149 main (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