• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <config.h>
2 
3 #include "test-utils.h"
4 #ifdef HAVE_UNISTD_H
5 #include <unistd.h>
6 #endif
7 
8 static DBusLoop *loop;
9 static dbus_bool_t already_quit = FALSE;
10 static dbus_bool_t hello_from_self_reply_received = FALSE;
11 
12 static void
quit(void)13 quit (void)
14 {
15   if (!already_quit)
16     {
17       _dbus_loop_quit (loop);
18       already_quit = TRUE;
19     }
20 }
21 
22 static void
die(const char * message)23 die (const char *message)
24 {
25   fprintf (stderr, "*** test-service: %s", message);
26   exit (1);
27 }
28 
29 static void
check_hello_from_self_reply(DBusPendingCall * pcall,void * user_data)30 check_hello_from_self_reply (DBusPendingCall *pcall,
31                              void *user_data)
32 {
33   DBusMessage *reply;
34   DBusMessage *echo_message, *echo_reply = NULL;
35   DBusError error;
36   DBusConnection *connection;
37 
38   int type;
39 
40   dbus_error_init (&error);
41 
42   connection = dbus_bus_get (DBUS_BUS_STARTER, &error);
43   if (connection == NULL)
44     {
45       fprintf (stderr, "*** Failed to open connection to activating message bus: %s\n",
46                error.message);
47       dbus_error_free (&error);
48       die("no memory");
49     }
50 
51 
52   echo_message = (DBusMessage *)user_data;
53 
54   reply = dbus_pending_call_steal_reply (pcall);
55 
56   type = dbus_message_get_type (reply);
57 
58   if (type == DBUS_MESSAGE_TYPE_METHOD_RETURN)
59     {
60       const char *s;
61       printf ("Reply from HelloFromSelf received\n");
62 
63       if (!dbus_message_get_args (echo_message,
64                               &error,
65                               DBUS_TYPE_STRING, &s,
66                               DBUS_TYPE_INVALID))
67         {
68             echo_reply = dbus_message_new_error (echo_message,
69                                       error.name,
70                                       error.message);
71 
72             if (echo_reply == NULL)
73               die ("No memory\n");
74 
75         }
76       else
77         {
78           echo_reply = dbus_message_new_method_return (echo_message);
79           if (echo_reply == NULL)
80             die ("No memory\n");
81 
82           if (!dbus_message_append_args (echo_reply,
83                                  DBUS_TYPE_STRING, &s,
84                                  DBUS_TYPE_INVALID))
85             die ("No memory");
86         }
87 
88       if (!dbus_connection_send (connection, echo_reply, NULL))
89         die ("No memory\n");
90 
91       dbus_message_unref (echo_reply);
92     }
93   else if (type == DBUS_MESSAGE_TYPE_ERROR)
94     {
95       dbus_set_error_from_message (&error, reply);
96       printf ("Error type in reply: %s\n", error.message);
97 
98       if (strcmp (error.name, DBUS_ERROR_NO_MEMORY) != 0)
99         {
100             echo_reply = dbus_message_new_error (echo_reply,
101                                       error.name,
102                                       error.message);
103 
104             if (echo_reply == NULL)
105               die ("No memory\n");
106 
107             if (!dbus_connection_send (connection, echo_reply, NULL))
108               die ("No memory\n");
109 
110             dbus_message_unref (echo_reply);
111         }
112       dbus_error_free (&error);
113     }
114   else
115      _dbus_assert_not_reached ("Unexpected message received\n");
116 
117   hello_from_self_reply_received = TRUE;
118 
119   dbus_message_unref (reply);
120   dbus_message_unref (echo_message);
121   dbus_pending_call_unref (pcall);
122   dbus_connection_unref (connection);
123 }
124 
125 static DBusHandlerResult
handle_run_hello_from_self(DBusConnection * connection,DBusMessage * message)126 handle_run_hello_from_self (DBusConnection     *connection,
127                                                DBusMessage        *message)
128 {
129   DBusError error;
130   DBusMessage *reply, *self_message;
131   DBusPendingCall *pcall;
132   char *s;
133 
134   _dbus_verbose ("sending reply to Echo method\n");
135 
136   dbus_error_init (&error);
137 
138   if (!dbus_message_get_args (message,
139                               &error,
140                               DBUS_TYPE_STRING, &s,
141                               DBUS_TYPE_INVALID))
142     {
143       reply = dbus_message_new_error (message,
144                                       error.name,
145                                       error.message);
146 
147       if (reply == NULL)
148         die ("No memory\n");
149 
150       if (!dbus_connection_send (connection, reply, NULL))
151         die ("No memory\n");
152 
153       dbus_message_unref (reply);
154 
155       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
156     }
157     printf ("Sending HelloFromSelf\n");
158 
159  _dbus_verbose ("*** Sending message to self\n");
160  self_message = dbus_message_new_method_call ("org.freedesktop.DBus.TestSuiteEchoService",
161                                           "/org/freedesktop/TestSuite",
162                                           "org.freedesktop.TestSuite",
163                                           "HelloFromSelf");
164 
165   if (self_message == NULL)
166     die ("No memory");
167 
168   if (!dbus_connection_send_with_reply (connection, self_message, &pcall, -1))
169     die("No memory");
170 
171   dbus_message_ref (message);
172   if (!dbus_pending_call_set_notify (pcall, check_hello_from_self_reply, (void *)message, NULL))
173     die("No memory");
174 
175   printf ("Sent HelloFromSelf\n");
176   return DBUS_HANDLER_RESULT_HANDLED;
177 }
178 
179 static DBusHandlerResult
handle_echo(DBusConnection * connection,DBusMessage * message)180 handle_echo (DBusConnection     *connection,
181              DBusMessage        *message)
182 {
183   DBusError error;
184   DBusMessage *reply;
185   char *s;
186 
187   _dbus_verbose ("sending reply to Echo method\n");
188 
189   dbus_error_init (&error);
190 
191   if (!dbus_message_get_args (message,
192                               &error,
193                               DBUS_TYPE_STRING, &s,
194                               DBUS_TYPE_INVALID))
195     {
196       reply = dbus_message_new_error (message,
197                                       error.name,
198                                       error.message);
199 
200       if (reply == NULL)
201         die ("No memory\n");
202 
203       if (!dbus_connection_send (connection, reply, NULL))
204         die ("No memory\n");
205 
206       dbus_message_unref (reply);
207 
208       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
209     }
210 
211   reply = dbus_message_new_method_return (message);
212   if (reply == NULL)
213     die ("No memory\n");
214 
215   if (!dbus_message_append_args (reply,
216                                  DBUS_TYPE_STRING, &s,
217                                  DBUS_TYPE_INVALID))
218     die ("No memory");
219 
220   if (!dbus_connection_send (connection, reply, NULL))
221     die ("No memory\n");
222 
223   fprintf (stderr, "Echo service echoed string: \"%s\"\n", s);
224 
225   dbus_message_unref (reply);
226 
227   return DBUS_HANDLER_RESULT_HANDLED;
228 }
229 
230 static DBusHandlerResult
handle_delay_echo(DBusConnection * connection,DBusMessage * message)231 handle_delay_echo (DBusConnection     *connection,
232                    DBusMessage        *message)
233 {
234   DBusError error;
235   DBusMessage *reply;
236   char *s;
237 
238   _dbus_verbose ("sleeping for a short time\n");
239 
240   _dbus_sleep_milliseconds (50);
241 
242   _dbus_verbose ("sending reply to DelayEcho method\n");
243 
244   dbus_error_init (&error);
245 
246   if (!dbus_message_get_args (message,
247                               &error,
248                               DBUS_TYPE_STRING, &s,
249                               DBUS_TYPE_INVALID))
250     {
251       reply = dbus_message_new_error (message,
252                                       error.name,
253                                       error.message);
254 
255       if (reply == NULL)
256         die ("No memory\n");
257 
258       if (!dbus_connection_send (connection, reply, NULL))
259         die ("No memory\n");
260 
261       dbus_message_unref (reply);
262 
263       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
264     }
265 
266   reply = dbus_message_new_method_return (message);
267   if (reply == NULL)
268     die ("No memory\n");
269 
270   if (!dbus_message_append_args (reply,
271                                  DBUS_TYPE_STRING, &s,
272                                  DBUS_TYPE_INVALID))
273     die ("No memory");
274 
275   if (!dbus_connection_send (connection, reply, NULL))
276     die ("No memory\n");
277 
278   fprintf (stderr, "DelayEcho service echoed string: \"%s\"\n", s);
279 
280   dbus_message_unref (reply);
281 
282   return DBUS_HANDLER_RESULT_HANDLED;
283 }
284 
285 
286 static void
path_unregistered_func(DBusConnection * connection,void * user_data)287 path_unregistered_func (DBusConnection  *connection,
288                         void            *user_data)
289 {
290   /* connection was finalized */
291 }
292 
293 static DBusHandlerResult
path_message_func(DBusConnection * connection,DBusMessage * message,void * user_data)294 path_message_func (DBusConnection  *connection,
295                    DBusMessage     *message,
296                    void            *user_data)
297 {
298   if (dbus_message_is_method_call (message,
299                                    "org.freedesktop.TestSuite",
300                                    "Echo"))
301     return handle_echo (connection, message);
302   else if (dbus_message_is_method_call (message,
303                                         "org.freedesktop.TestSuite",
304                                         "DelayEcho"))
305     return handle_delay_echo (connection, message);
306   else if (dbus_message_is_method_call (message,
307                                         "org.freedesktop.TestSuite",
308                                         "Exit"))
309     {
310       quit ();
311       return DBUS_HANDLER_RESULT_HANDLED;
312     }
313   else if (dbus_message_is_method_call (message,
314                                         "org.freedesktop.TestSuite",
315                                         "EmitFoo"))
316     {
317       /* Emit the Foo signal */
318       DBusMessage *signal;
319       double v_DOUBLE;
320 
321       _dbus_verbose ("emitting signal Foo\n");
322 
323       signal = dbus_message_new_signal ("/org/freedesktop/TestSuite",
324                                         "org.freedesktop.TestSuite",
325                                         "Foo");
326       if (signal == NULL)
327         die ("No memory\n");
328 
329       v_DOUBLE = 42.6;
330       if (!dbus_message_append_args (signal,
331                                      DBUS_TYPE_DOUBLE, &v_DOUBLE,
332                                      DBUS_TYPE_INVALID))
333         die ("No memory");
334 
335       if (!dbus_connection_send (connection, signal, NULL))
336         die ("No memory\n");
337 
338       return DBUS_HANDLER_RESULT_HANDLED;
339     }
340 
341   else if (dbus_message_is_method_call (message,
342                                    "org.freedesktop.TestSuite",
343                                    "RunHelloFromSelf"))
344     {
345       return handle_run_hello_from_self (connection, message);
346     }
347   else if (dbus_message_is_method_call (message,
348                                         "org.freedesktop.TestSuite",
349                                         "HelloFromSelf"))
350     {
351         DBusMessage *reply;
352         printf ("Received the HelloFromSelf message\n");
353 
354         reply = dbus_message_new_method_return (message);
355         if (reply == NULL)
356           die ("No memory");
357 
358         if (!dbus_connection_send (connection, reply, NULL))
359           die ("No memory");
360 
361         return DBUS_HANDLER_RESULT_HANDLED;
362     }
363   else
364     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
365 }
366 
367 static DBusObjectPathVTable
368 echo_vtable = {
369   path_unregistered_func,
370   path_message_func,
371   NULL,
372 };
373 
374 
375 static const char* echo_path = "/org/freedesktop/TestSuite" ;
376 
377 static DBusHandlerResult
filter_func(DBusConnection * connection,DBusMessage * message,void * user_data)378 filter_func (DBusConnection     *connection,
379              DBusMessage        *message,
380              void               *user_data)
381 {
382   if (dbus_message_is_signal (message,
383                               DBUS_INTERFACE_LOCAL,
384                               "Disconnected"))
385     {
386       quit ();
387       return DBUS_HANDLER_RESULT_HANDLED;
388     }
389   else
390     {
391       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
392     }
393 }
394 
395 int
main(int argc,char ** argv)396 main (int    argc,
397       char **argv)
398 {
399   DBusError error;
400   int result;
401   DBusConnection *connection;
402   const char *name;
403   dbus_bool_t do_fork;
404 
405   if (argc != 3)
406     {
407       name = "org.freedesktop.DBus.TestSuiteEchoService";
408       do_fork = FALSE;
409     }
410   else
411     {
412       name = argv[1];
413 #ifndef DBUS_WIN
414       do_fork = strcmp (argv[2], "fork") == 0;
415 #else
416       do_fork = FALSE;
417 #endif
418     }
419 
420   /* The bare minimum for simulating a program "daemonizing"; the intent
421    * is to test services which move from being legacy init scripts to
422    * activated services.
423    * https://bugzilla.redhat.com/show_bug.cgi?id=545267
424    */
425 #ifndef DBUS_WIN
426    if (do_fork)
427     {
428       pid_t pid = fork ();
429       if (pid != 0)
430         exit (0);
431       sleep (1);
432     }
433 #endif
434 
435   dbus_error_init (&error);
436   connection = dbus_bus_get (DBUS_BUS_STARTER, &error);
437   if (connection == NULL)
438     {
439       fprintf (stderr, "*** Failed to open connection to activating message bus: %s\n",
440                error.message);
441       dbus_error_free (&error);
442       return 1;
443     }
444 
445   loop = _dbus_loop_new ();
446   if (loop == NULL)
447     die ("No memory\n");
448 
449   if (!test_connection_setup (loop, connection))
450     die ("No memory\n");
451 
452   if (!dbus_connection_add_filter (connection,
453                                    filter_func, NULL, NULL))
454     die ("No memory");
455 
456   if (!dbus_connection_register_object_path (connection,
457                                              echo_path,
458                                              &echo_vtable,
459                                              (void*) 0xdeadbeef))
460     die ("No memory");
461 
462   {
463     void *d;
464     if (!dbus_connection_get_object_path_data (connection, echo_path, &d))
465       die ("No memory");
466     if (d != (void*) 0xdeadbeef)
467       die ("dbus_connection_get_object_path_data() doesn't seem to work right\n");
468   }
469 
470   result = dbus_bus_request_name (connection, name,
471                                   0, &error);
472   if (dbus_error_is_set (&error))
473     {
474       fprintf (stderr, "Error %s\n", error.message);
475       _dbus_verbose ("*** Failed to acquire service: %s\n",
476                      error.message);
477       dbus_error_free (&error);
478       exit (1);
479     }
480 
481   _dbus_verbose ("*** Test service entering main loop\n");
482   _dbus_loop_run (loop);
483 
484   test_connection_shutdown (loop, connection);
485 
486   dbus_connection_remove_filter (connection, filter_func, NULL);
487 
488   dbus_connection_unref (connection);
489 
490   _dbus_loop_unref (loop);
491   loop = NULL;
492 
493   dbus_shutdown ();
494 
495   _dbus_verbose ("*** Test service exiting\n");
496 
497   return 0;
498 }
499