1#include <config.h> 2 3#include "test-utils.h" 4#ifdef HAVE_UNISTD_H 5#include <unistd.h> 6#endif 7 8static DBusLoop *loop; 9static dbus_bool_t already_quit = FALSE; 10static dbus_bool_t hello_from_self_reply_received = FALSE; 11 12static void 13quit (void) 14{ 15 if (!already_quit) 16 { 17 _dbus_loop_quit (loop); 18 already_quit = TRUE; 19 } 20} 21 22static void 23die (const char *message) 24{ 25 fprintf (stderr, "*** test-service: %s", message); 26 exit (1); 27} 28 29static void 30check_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 125static DBusHandlerResult 126handle_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 179static DBusHandlerResult 180handle_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 230static DBusHandlerResult 231handle_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 286static void 287path_unregistered_func (DBusConnection *connection, 288 void *user_data) 289{ 290 /* connection was finalized */ 291} 292 293static DBusHandlerResult 294path_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 367static DBusObjectPathVTable 368echo_vtable = { 369 path_unregistered_func, 370 path_message_func, 371 NULL, 372}; 373 374 375static const char* echo_path = "/org/freedesktop/TestSuite" ; 376 377static DBusHandlerResult 378filter_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 395int 396main (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