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