[daemon-fix] Registering starters: unwanted release_kdbus_name when no error was...
[platform/upstream/dbus.git] / bus / dispatch.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dispatch.c  Message dispatcher
3  *
4  * Copyright (C) 2003  CodeFactory AB
5  * Copyright (C) 2003, 2004, 2005  Red Hat, Inc.
6  * Copyright (C) 2004  Imendio HB
7  *
8  * Licensed under the Academic Free License version 2.1
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23  *
24  */
25
26 #include <config.h>
27 #include "dispatch.h"
28 #include "connection.h"
29 #include "driver.h"
30 #include "services.h"
31 #include "activation.h"
32 #include "utils.h"
33 #include "bus.h"
34 #include "signals.h"
35 #include "test.h"
36 #include <dbus/dbus-internals.h>
37 #include <dbus/dbus-misc.h>
38 #include <string.h>
39 #include "kdbus-d.h"
40
41 #ifdef HAVE_UNIX_FD_PASSING
42 #include <dbus/dbus-sysdeps-unix.h>
43 #include <unistd.h>
44 #endif
45
46 /* This is hard-coded in the files in valid-config-files-*. We have to use
47  * the debug-pipe transport because the tests in this file require that
48  * dbus_connection_open_private() does not block. */
49 #define TEST_DEBUG_PIPE "debug-pipe:name=test-server"
50
51 static dbus_bool_t
52 send_one_message (DBusConnection *connection,
53                   BusContext     *context,
54                   DBusConnection *sender,
55                   DBusConnection *addressed_recipient,
56                   DBusMessage    *message,
57                   BusTransaction *transaction,
58                   DBusError      *error)
59 {
60   if (!bus_context_check_security_policy (context, transaction,
61                                           sender,
62                                           addressed_recipient,
63                                           connection,
64                                           message,
65                                           NULL))
66     return TRUE; /* silently don't send it */
67
68   if (dbus_message_contains_unix_fds(message) &&
69       !dbus_connection_can_send_type(connection, DBUS_TYPE_UNIX_FD))
70     return TRUE; /* silently don't send it */
71
72   if (!bus_transaction_send (transaction,
73                              connection,
74                              message))
75     {
76       BUS_SET_OOM (error);
77       return FALSE;
78     }
79
80   return TRUE;
81 }
82
83 dbus_bool_t
84 bus_dispatch_matches (BusTransaction *transaction,
85                       DBusConnection *sender,
86                       DBusConnection *addressed_recipient,
87                       DBusMessage    *message,
88                       DBusError      *error)
89 {
90   DBusError tmp_error;
91   BusConnections *connections;
92   DBusList *recipients;
93   BusMatchmaker *matchmaker;
94   DBusList *link;
95   BusContext *context;
96
97   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
98
99   /* sender and recipient can both be NULL for the bus driver,
100    * or for signals with no particular recipient
101    */
102
103   _dbus_assert (sender == NULL || bus_connection_is_active (sender));
104   _dbus_assert (dbus_message_get_sender (message) != NULL);
105
106   context = bus_transaction_get_context (transaction);
107
108   /* First, send the message to the addressed_recipient, if there is one. */
109   if (addressed_recipient != NULL)
110     {
111       if (!bus_context_check_security_policy (context, transaction,
112                                               sender, addressed_recipient,
113                                               addressed_recipient,
114                                               message, error))
115         return FALSE;
116
117       if (dbus_message_contains_unix_fds (message) &&
118           !dbus_connection_can_send_type (addressed_recipient,
119                                           DBUS_TYPE_UNIX_FD))
120         {
121           dbus_set_error (error,
122                           DBUS_ERROR_NOT_SUPPORTED,
123                           "Tried to send message with Unix file descriptors"
124                           "to a client that doesn't support that.");
125           return FALSE;
126       }
127
128       /* Dispatch the message */
129       if (!bus_transaction_send (transaction, addressed_recipient, message))
130         {
131           BUS_SET_OOM (error);
132           return FALSE;
133         }
134     }
135
136   /* Now dispatch to others who look interested in this message */
137   connections = bus_transaction_get_connections (transaction);
138   dbus_error_init (&tmp_error);
139   matchmaker = bus_context_get_matchmaker (context);
140
141   recipients = NULL;
142   if (!bus_matchmaker_get_recipients (matchmaker, connections,
143                                       sender, addressed_recipient, message,
144                                       &recipients))
145     {
146       BUS_SET_OOM (error);
147       return FALSE;
148     }
149
150   link = _dbus_list_get_first_link (&recipients);
151   while (link != NULL)
152     {
153       DBusConnection *dest;
154
155       dest = link->data;
156
157       if (!send_one_message (dest, context, sender, addressed_recipient,
158                              message, transaction, &tmp_error))
159         break;
160
161       link = _dbus_list_get_next_link (&recipients, link);
162     }
163
164   _dbus_list_clear (&recipients);
165
166   if (dbus_error_is_set (&tmp_error))
167     {
168       dbus_move_error (&tmp_error, error);
169       return FALSE;
170     }
171   else
172     return TRUE;
173 }
174
175 static DBusHandlerResult
176 bus_dispatch (DBusConnection *connection,
177               DBusMessage    *message)
178 {
179   const char *sender, *service_name;
180   DBusError error;
181   BusTransaction *transaction;
182   BusContext *context;
183   DBusHandlerResult result;
184   DBusConnection *addressed_recipient;
185
186   result = DBUS_HANDLER_RESULT_HANDLED;
187
188   transaction = NULL;
189   addressed_recipient = NULL;
190   dbus_error_init (&error);
191
192   context = bus_connection_get_context (connection);
193   _dbus_assert (context != NULL);
194
195   /* If we can't even allocate an OOM error, we just go to sleep
196    * until we can.
197    */
198   while (!bus_connection_preallocate_oom_error (connection))
199     _dbus_wait_for_memory ();
200
201   /* Ref connection in case we disconnect it at some point in here */
202   dbus_connection_ref (connection);
203
204   service_name = dbus_message_get_destination (message);
205
206 #ifdef DBUS_ENABLE_VERBOSE_MODE
207   {
208     const char *interface_name, *member_name, *error_name;
209
210     interface_name = dbus_message_get_interface (message);
211     member_name = dbus_message_get_member (message);
212     error_name = dbus_message_get_error_name (message);
213
214     _dbus_verbose ("DISPATCH: %s %s %s to %s\n",
215                    interface_name ? interface_name : "(no interface)",
216                    member_name ? member_name : "(no member)",
217                    error_name ? error_name : "(no error name)",
218                    service_name ? service_name : "peer");
219   }
220 #endif /* DBUS_ENABLE_VERBOSE_MODE */
221
222   /* Create our transaction */
223   transaction = bus_transaction_new (context);
224   if (transaction == NULL)
225     {
226       BUS_SET_OOM (&error);
227       goto out;
228     }
229
230   /* If service_name is NULL, if it's a signal we send it to all
231    * connections with a match rule. If it's not a signal, there
232    * are some special cases here but mostly we just bail out.
233    */
234   if (service_name == NULL)
235     {
236       if (dbus_message_is_signal (message,
237                                   DBUS_INTERFACE_LOCAL,
238                                   "Disconnected"))
239         {
240           bus_connection_disconnected (connection);
241           goto out;
242         }
243
244       if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL)
245         {
246           /* DBusConnection also handles some of these automatically, we leave
247            * it to do so.
248            */
249           result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
250           goto out;
251         }
252
253       if(bus_context_is_kdbus(context))
254       {
255           if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged"))
256           {
257               handleNameOwnerChanged(message, transaction, connection);
258               goto out;
259           }
260       }
261     }
262
263   /* Assign a sender to the message */
264   if(bus_context_is_kdbus(context) == FALSE)  //if using kdbus, sender must be set on library side
265     if (bus_connection_is_active (connection))
266     {
267       sender = bus_connection_get_name (connection);
268       _dbus_assert (sender != NULL);
269
270       if (!dbus_message_set_sender (message, sender))
271         {
272           BUS_SET_OOM (&error);
273           goto out;
274         }
275
276       /* We need to refetch the service name here, because
277        * dbus_message_set_sender can cause the header to be
278        * reallocated, and thus the service_name pointer will become
279        * invalid.
280        */
281       service_name = dbus_message_get_destination (message);
282     }
283
284   if (service_name &&
285       strcmp (service_name, DBUS_SERVICE_DBUS) == 0) /* to bus driver */
286     {
287       if (!bus_context_check_security_policy (context, transaction,
288                                               connection, NULL, NULL, message, &error))
289         {
290           _dbus_verbose ("Security policy rejected message\n");
291           goto out;
292         }
293
294       _dbus_verbose ("Giving message to %s\n", DBUS_SERVICE_DBUS);
295       if (!bus_driver_handle_message (connection, transaction, message, &error))
296         goto out;
297     }
298   else if (!bus_connection_is_active (connection)) /* clients must talk to bus driver first */
299     {
300       _dbus_verbose ("Received message from non-registered client. Disconnecting.\n");
301       dbus_connection_close (connection);
302       goto out;
303     }
304   else if (service_name != NULL) /* route to named service */
305     {
306       DBusString service_string;
307       BusService *service;
308       BusRegistry *registry;
309
310       _dbus_assert (service_name != NULL);
311
312       registry = bus_connection_get_registry (connection);
313
314       _dbus_string_init_const (&service_string, service_name);
315       service = bus_registry_lookup (registry, &service_string);
316
317       if (service == NULL && dbus_message_get_auto_start (message))
318         {
319           BusActivation *activation;
320           /* We can't do the security policy check here, since the addressed
321            * recipient service doesn't exist yet. We do it before sending the
322            * message after the service has been created.
323            */
324           activation = bus_connection_get_activation (connection);
325
326           if (!bus_activation_activate_service (activation, connection, transaction, TRUE,
327                                                 message, service_name, &error))
328             {
329               _DBUS_ASSERT_ERROR_IS_SET (&error);
330               _dbus_verbose ("bus_activation_activate_service() failed: %s\n", error.name);
331               goto out;
332             }
333
334           goto out;
335         }
336       else if (service == NULL)
337         {
338           dbus_set_error (&error,
339                           DBUS_ERROR_NAME_HAS_NO_OWNER,
340                           "Name \"%s\" does not exist",
341                           service_name);
342           goto out;
343         }
344       else
345         {
346           addressed_recipient = bus_service_get_primary_owners_connection (service);
347           _dbus_assert (addressed_recipient != NULL);
348         }
349     }
350
351   /* Now send the message to its destination (or not, if
352    * addressed_recipient == NULL), and match it against other connections'
353    * match rules.
354    */
355   if (!bus_dispatch_matches (transaction, connection, addressed_recipient, message, &error))
356     goto out;
357
358  out:
359   if (dbus_error_is_set (&error))
360     {
361       if (!dbus_connection_get_is_connected (connection))
362         {
363           /* If we disconnected it, we won't bother to send it any error
364            * messages.
365            */
366           _dbus_verbose ("Not sending error to connection we disconnected\n");
367         }
368       else if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
369         {
370           bus_connection_send_oom_error (connection, message);
371
372           /* cancel transaction due to OOM */
373           if (transaction != NULL)
374             {
375               bus_transaction_cancel_and_free (transaction);
376               transaction = NULL;
377             }
378         }
379       else
380         {
381           /* Try to send the real error, if no mem to do that, send
382            * the OOM error
383            */
384           _dbus_assert (transaction != NULL);
385           if (!bus_transaction_send_error_reply (transaction, connection,
386                                                  &error, message))
387             {
388               bus_connection_send_oom_error (connection, message);
389
390               /* cancel transaction due to OOM */
391               if (transaction != NULL)
392                 {
393                   bus_transaction_cancel_and_free (transaction);
394                   transaction = NULL;
395                 }
396             }
397         }
398
399
400       dbus_error_free (&error);
401     }
402
403   if (transaction != NULL)
404     {
405       bus_transaction_execute_and_free (transaction);
406     }
407
408   dbus_connection_unref (connection);
409
410   return result;
411 }
412
413 static DBusHandlerResult
414 bus_dispatch_message_filter (DBusConnection     *connection,
415                              DBusMessage        *message,
416                              void               *user_data)
417 {
418   return bus_dispatch (connection, message);
419 }
420
421 dbus_bool_t
422 bus_dispatch_add_connection (DBusConnection *connection)
423 {
424   if (!dbus_connection_add_filter (connection,
425                                    bus_dispatch_message_filter,
426                                    NULL, NULL))
427     return FALSE;
428
429   return TRUE;
430 }
431
432 void
433 bus_dispatch_remove_connection (DBusConnection *connection)
434 {
435   /* Here we tell the bus driver that we want to get off. */
436   bus_driver_remove_connection (connection);
437
438   dbus_connection_remove_filter (connection,
439                                  bus_dispatch_message_filter,
440                                  NULL);
441 }
442
443 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
444
445 #include <stdio.h>
446
447 /* This is used to know whether we need to block in order to finish
448  * sending a message, or whether the initial dbus_connection_send()
449  * already flushed the queue.
450  */
451 #define SEND_PENDING(connection) (dbus_connection_has_messages_to_send (connection))
452
453 typedef dbus_bool_t (* Check1Func) (BusContext     *context);
454 typedef dbus_bool_t (* Check2Func) (BusContext     *context,
455                                     DBusConnection *connection);
456
457 static dbus_bool_t check_no_leftovers (BusContext *context);
458
459 static void
460 block_connection_until_message_from_bus (BusContext     *context,
461                                          DBusConnection *connection,
462                                          const char     *what_is_expected)
463 {
464   _dbus_verbose ("expecting: %s\n", what_is_expected);
465
466   while (dbus_connection_get_dispatch_status (connection) ==
467          DBUS_DISPATCH_COMPLETE &&
468          dbus_connection_get_is_connected (connection))
469     {
470       bus_test_run_bus_loop (context, TRUE);
471       bus_test_run_clients_loop (FALSE);
472     }
473 }
474
475 static void
476 spin_connection_until_authenticated (BusContext     *context,
477                                      DBusConnection *connection)
478 {
479   _dbus_verbose ("Spinning to auth connection %p\n", connection);
480   while (!dbus_connection_get_is_authenticated (connection) &&
481          dbus_connection_get_is_connected (connection))
482     {
483       bus_test_run_bus_loop (context, FALSE);
484       bus_test_run_clients_loop (FALSE);
485     }
486   _dbus_verbose (" ... done spinning to auth connection %p\n", connection);
487 }
488
489 /* compensate for fact that pop_message() can return #NULL due to OOM */
490 static DBusMessage*
491 pop_message_waiting_for_memory (DBusConnection *connection)
492 {
493   while (dbus_connection_get_dispatch_status (connection) ==
494          DBUS_DISPATCH_NEED_MEMORY)
495     _dbus_wait_for_memory ();
496
497   return dbus_connection_pop_message (connection);
498 }
499
500 static DBusMessage*
501 borrow_message_waiting_for_memory (DBusConnection *connection)
502 {
503   while (dbus_connection_get_dispatch_status (connection) ==
504          DBUS_DISPATCH_NEED_MEMORY)
505     _dbus_wait_for_memory ();
506
507   return dbus_connection_borrow_message (connection);
508 }
509
510 static void
511 warn_unexpected_real (DBusConnection *connection,
512                       DBusMessage    *message,
513                       const char     *expected,
514                       const char     *function,
515                       int             line)
516 {
517   if (message)
518     _dbus_warn ("%s:%d received message interface \"%s\" member \"%s\" error name \"%s\" on %p, expecting %s\n",
519                 function, line,
520                 dbus_message_get_interface (message) ?
521                 dbus_message_get_interface (message) : "(unset)",
522                 dbus_message_get_member (message) ?
523                 dbus_message_get_member (message) : "(unset)",
524                 dbus_message_get_error_name (message) ?
525                 dbus_message_get_error_name (message) : "(unset)",
526                 connection,
527                 expected);
528   else
529     _dbus_warn ("%s:%d received no message on %p, expecting %s\n",
530                 function, line, connection, expected);
531 }
532
533 #define warn_unexpected(connection, message, expected) \
534   warn_unexpected_real (connection, message, expected, _DBUS_FUNCTION_NAME, __LINE__)
535
536 static void
537 verbose_message_received (DBusConnection *connection,
538                           DBusMessage    *message)
539 {
540   _dbus_verbose ("Received message interface \"%s\" member \"%s\" error name \"%s\" on %p\n",
541                  dbus_message_get_interface (message) ?
542                  dbus_message_get_interface (message) : "(unset)",
543                  dbus_message_get_member (message) ?
544                  dbus_message_get_member (message) : "(unset)",
545                  dbus_message_get_error_name (message) ?
546                  dbus_message_get_error_name (message) : "(unset)",
547                  connection);
548 }
549
550 typedef enum
551 {
552   SERVICE_CREATED,
553   OWNER_CHANGED,
554   SERVICE_DELETED
555 } ServiceInfoKind;
556
557 typedef struct
558 {
559   ServiceInfoKind expected_kind;
560   const char *expected_service_name;
561   dbus_bool_t failed;
562   DBusConnection *skip_connection;
563 } CheckServiceOwnerChangedData;
564
565 static dbus_bool_t
566 check_service_owner_changed_foreach (DBusConnection *connection,
567                                      void           *data)
568 {
569   CheckServiceOwnerChangedData *d = data;
570   DBusMessage *message;
571   DBusError error;
572   const char *service_name, *old_owner, *new_owner;
573
574   if (d->expected_kind == SERVICE_CREATED
575       && connection == d->skip_connection)
576     return TRUE;
577
578   dbus_error_init (&error);
579   d->failed = TRUE;
580
581   message = pop_message_waiting_for_memory (connection);
582   if (message == NULL)
583     {
584       _dbus_warn ("Did not receive a message on %p, expecting %s\n",
585                   connection, "NameOwnerChanged");
586       goto out;
587     }
588   else if (!dbus_message_is_signal (message,
589                                     DBUS_INTERFACE_DBUS,
590                                     "NameOwnerChanged"))
591     {
592       warn_unexpected (connection, message, "NameOwnerChanged");
593
594       goto out;
595     }
596   else
597     {
598     reget_service_info_data:
599       service_name = NULL;
600       old_owner = NULL;
601       new_owner = NULL;
602
603       dbus_message_get_args (message, &error,
604                              DBUS_TYPE_STRING, &service_name,
605                              DBUS_TYPE_STRING, &old_owner,
606                              DBUS_TYPE_STRING, &new_owner,
607                              DBUS_TYPE_INVALID);
608
609       if (dbus_error_is_set (&error))
610         {
611           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
612             {
613               dbus_error_free (&error);
614               _dbus_wait_for_memory ();
615               goto reget_service_info_data;
616             }
617           else
618             {
619               _dbus_warn ("Did not get the expected arguments\n");
620               goto out;
621             }
622         }
623
624       if ((d->expected_kind == SERVICE_CREATED    && ( old_owner[0] || !new_owner[0]))
625           || (d->expected_kind == OWNER_CHANGED   && (!old_owner[0] || !new_owner[0]))
626           || (d->expected_kind == SERVICE_DELETED && (!old_owner[0] ||  new_owner[0])))
627         {
628           _dbus_warn ("inconsistent NameOwnerChanged arguments\n");
629           goto out;
630         }
631
632       if (strcmp (service_name, d->expected_service_name) != 0)
633         {
634           _dbus_warn ("expected info on service %s, got info on %s\n",
635                       d->expected_service_name,
636                       service_name);
637           goto out;
638         }
639
640       if (*service_name == ':' && new_owner[0]
641           && strcmp (service_name, new_owner) != 0)
642         {
643           _dbus_warn ("inconsistent ServiceOwnedChanged message (\"%s\" [ %s -> %s ])\n",
644                       service_name, old_owner, new_owner);
645           goto out;
646         }
647     }
648
649   d->failed = FALSE;
650
651  out:
652   dbus_error_free (&error);
653
654   if (message)
655     dbus_message_unref (message);
656
657   return !d->failed;
658 }
659
660
661 static void
662 kill_client_connection (BusContext     *context,
663                         DBusConnection *connection)
664 {
665   char *base_service;
666   const char *s;
667   CheckServiceOwnerChangedData socd;
668
669   _dbus_verbose ("killing connection %p\n", connection);
670
671   s = dbus_bus_get_unique_name (connection);
672   _dbus_assert (s != NULL);
673
674   while ((base_service = _dbus_strdup (s)) == NULL)
675     _dbus_wait_for_memory ();
676
677   dbus_connection_ref (connection);
678
679   /* kick in the disconnect handler that unrefs the connection */
680   dbus_connection_close (connection);
681
682   bus_test_run_everything (context);
683
684   _dbus_assert (bus_test_client_listed (connection));
685
686   /* Run disconnect handler in test.c */
687   if (bus_connection_dispatch_one_message (connection))
688     _dbus_assert_not_reached ("something received on connection being killed other than the disconnect");
689
690   _dbus_assert (!dbus_connection_get_is_connected (connection));
691   dbus_connection_unref (connection);
692   connection = NULL;
693   _dbus_assert (!bus_test_client_listed (connection));
694
695   socd.expected_kind = SERVICE_DELETED;
696   socd.expected_service_name = base_service;
697   socd.failed = FALSE;
698   socd.skip_connection = NULL;
699
700   bus_test_clients_foreach (check_service_owner_changed_foreach,
701                             &socd);
702
703   dbus_free (base_service);
704
705   if (socd.failed)
706     _dbus_assert_not_reached ("didn't get the expected NameOwnerChanged (deletion) messages");
707
708   if (!check_no_leftovers (context))
709     _dbus_assert_not_reached ("stuff left in message queues after disconnecting a client");
710 }
711
712 static void
713 kill_client_connection_unchecked (DBusConnection *connection)
714 {
715   /* This kills the connection without expecting it to affect
716    * the rest of the bus.
717    */
718   _dbus_verbose ("Unchecked kill of connection %p\n", connection);
719
720   dbus_connection_ref (connection);
721   dbus_connection_close (connection);
722   /* dispatching disconnect handler will unref once */
723   if (bus_connection_dispatch_one_message (connection))
724     _dbus_assert_not_reached ("message other than disconnect dispatched after failure to register");
725
726   _dbus_assert (!bus_test_client_listed (connection));
727   dbus_connection_unref (connection);
728 }
729
730 typedef struct
731 {
732   dbus_bool_t failed;
733 } CheckNoMessagesData;
734
735 static dbus_bool_t
736 check_no_messages_foreach (DBusConnection *connection,
737                            void           *data)
738 {
739   CheckNoMessagesData *d = data;
740   DBusMessage *message;
741
742   message = pop_message_waiting_for_memory (connection);
743   if (message != NULL)
744     {
745       warn_unexpected (connection, message, "no messages");
746
747       d->failed = TRUE;
748     }
749
750   if (message)
751     dbus_message_unref (message);
752   return !d->failed;
753 }
754
755 static dbus_bool_t
756 check_no_leftovers (BusContext *context)
757 {
758   CheckNoMessagesData nmd;
759
760   nmd.failed = FALSE;
761   bus_test_clients_foreach (check_no_messages_foreach,
762                             &nmd);
763
764   if (nmd.failed)
765     {
766       _dbus_verbose ("leftover message found\n");
767       return FALSE;
768     }
769   else
770     return TRUE;
771 }
772
773 /* returns TRUE if the correct thing happens,
774  * but the correct thing may include OOM errors.
775  */
776 static dbus_bool_t
777 check_hello_message (BusContext     *context,
778                      DBusConnection *connection)
779 {
780   DBusMessage *message;
781   DBusMessage *name_message;
782   dbus_uint32_t serial;
783   dbus_bool_t retval;
784   DBusError error;
785   const char *name;
786   const char *acquired;
787
788   retval = FALSE;
789   dbus_error_init (&error);
790   name = NULL;
791   acquired = NULL;
792   message = NULL;
793   name_message = NULL;
794
795   _dbus_verbose ("check_hello_message for %p\n", connection);
796
797   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
798                                           DBUS_PATH_DBUS,
799                                           DBUS_INTERFACE_DBUS,
800                                           "Hello");
801
802   if (message == NULL)
803     return TRUE;
804
805   dbus_connection_ref (connection); /* because we may get disconnected */
806
807   if (!dbus_connection_send (connection, message, &serial))
808     {
809       dbus_message_unref (message);
810       dbus_connection_unref (connection);
811       return TRUE;
812     }
813
814   _dbus_assert (dbus_message_has_signature (message, ""));
815
816   dbus_message_unref (message);
817   message = NULL;
818
819   if (!dbus_connection_get_is_connected (connection))
820     {
821       _dbus_verbose ("connection was disconnected (presumably auth failed)\n");
822
823       dbus_connection_unref (connection);
824
825       return TRUE;
826     }
827
828   /* send our message */
829   bus_test_run_clients_loop (SEND_PENDING (connection));
830
831   if (!dbus_connection_get_is_connected (connection))
832     {
833       _dbus_verbose ("connection was disconnected (presumably auth failed)\n");
834
835       dbus_connection_unref (connection);
836
837       return TRUE;
838     }
839
840   block_connection_until_message_from_bus (context, connection, "reply to Hello");
841
842   if (!dbus_connection_get_is_connected (connection))
843     {
844       _dbus_verbose ("connection was disconnected (presumably auth failed)\n");
845
846       dbus_connection_unref (connection);
847
848       return TRUE;
849     }
850
851   dbus_connection_unref (connection);
852
853   message = pop_message_waiting_for_memory (connection);
854   if (message == NULL)
855     {
856       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
857                   "Hello", serial, connection);
858       goto out;
859     }
860
861   verbose_message_received (connection, message);
862
863   if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
864     {
865       _dbus_warn ("Message has wrong sender %s\n",
866                   dbus_message_get_sender (message) ?
867                   dbus_message_get_sender (message) : "(none)");
868       goto out;
869     }
870
871   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
872     {
873       if (dbus_message_is_error (message,
874                                  DBUS_ERROR_NO_MEMORY))
875         {
876           ; /* good, this is a valid response */
877         }
878       else
879         {
880           warn_unexpected (connection, message, "not this error");
881
882           goto out;
883         }
884     }
885   else
886     {
887       CheckServiceOwnerChangedData socd;
888
889       if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
890         {
891           ; /* good, expected */
892         }
893       else
894         {
895           warn_unexpected (connection, message, "method return for Hello");
896
897           goto out;
898         }
899
900     retry_get_hello_name:
901       if (!dbus_message_get_args (message, &error,
902                                   DBUS_TYPE_STRING, &name,
903                                   DBUS_TYPE_INVALID))
904         {
905           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
906             {
907               _dbus_verbose ("no memory to get service name arg from hello\n");
908               dbus_error_free (&error);
909               _dbus_wait_for_memory ();
910               goto retry_get_hello_name;
911             }
912           else
913             {
914               _dbus_assert (dbus_error_is_set (&error));
915               _dbus_warn ("Did not get the expected single string argument to hello\n");
916               goto out;
917             }
918         }
919
920       _dbus_verbose ("Got hello name: %s\n", name);
921
922       while (!dbus_bus_set_unique_name (connection, name))
923         _dbus_wait_for_memory ();
924
925       socd.expected_kind = SERVICE_CREATED;
926       socd.expected_service_name = name;
927       socd.failed = FALSE;
928       socd.skip_connection = connection; /* we haven't done AddMatch so won't get it ourselves */
929       bus_test_clients_foreach (check_service_owner_changed_foreach,
930                                 &socd);
931
932       if (socd.failed)
933         goto out;
934
935       name_message = message;
936       /* Client should also have gotten ServiceAcquired */
937
938       message = pop_message_waiting_for_memory (connection);
939       if (message == NULL)
940         {
941           _dbus_warn ("Expecting %s, got nothing\n",
942                       "NameAcquired");
943           goto out;
944         }
945       if (! dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
946                                     "NameAcquired"))
947         {
948           _dbus_warn ("Expecting %s, got smthg else\n",
949                       "NameAcquired");
950           goto out;
951         }
952
953     retry_get_acquired_name:
954       if (!dbus_message_get_args (message, &error,
955                                   DBUS_TYPE_STRING, &acquired,
956                                   DBUS_TYPE_INVALID))
957         {
958           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
959             {
960               _dbus_verbose ("no memory to get service name arg from acquired\n");
961               dbus_error_free (&error);
962               _dbus_wait_for_memory ();
963               goto retry_get_acquired_name;
964             }
965           else
966             {
967               _dbus_assert (dbus_error_is_set (&error));
968               _dbus_warn ("Did not get the expected single string argument to ServiceAcquired\n");
969               goto out;
970             }
971         }
972
973       _dbus_verbose ("Got acquired name: %s\n", acquired);
974
975       if (strcmp (acquired, name) != 0)
976         {
977           _dbus_warn ("Acquired name is %s but expected %s\n",
978                       acquired, name);
979           goto out;
980         }
981       acquired = NULL;
982     }
983
984   if (!check_no_leftovers (context))
985     goto out;
986
987   retval = TRUE;
988
989  out:
990   _dbus_verbose ("ending - retval = %d\n", retval);
991
992   dbus_error_free (&error);
993
994   if (message)
995     dbus_message_unref (message);
996
997   if (name_message)
998     dbus_message_unref (name_message);
999
1000   return retval;
1001 }
1002
1003 /* returns TRUE if the correct thing happens,
1004  * but the correct thing may include OOM errors.
1005  */
1006 static dbus_bool_t
1007 check_double_hello_message (BusContext     *context,
1008                             DBusConnection *connection)
1009 {
1010   DBusMessage *message;
1011   dbus_uint32_t serial;
1012   dbus_bool_t retval;
1013   DBusError error;
1014
1015   retval = FALSE;
1016   dbus_error_init (&error);
1017   message = NULL;
1018
1019   _dbus_verbose ("check_double_hello_message for %p\n", connection);
1020
1021   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
1022                                           DBUS_PATH_DBUS,
1023                                           DBUS_INTERFACE_DBUS,
1024                                           "Hello");
1025
1026   if (message == NULL)
1027     return TRUE;
1028
1029   if (!dbus_connection_send (connection, message, &serial))
1030     {
1031       dbus_message_unref (message);
1032       return TRUE;
1033     }
1034
1035   dbus_message_unref (message);
1036   message = NULL;
1037
1038   /* send our message */
1039   bus_test_run_clients_loop (SEND_PENDING (connection));
1040
1041   dbus_connection_ref (connection); /* because we may get disconnected */
1042   block_connection_until_message_from_bus (context, connection, "reply to Hello");
1043
1044   if (!dbus_connection_get_is_connected (connection))
1045     {
1046       _dbus_verbose ("connection was disconnected\n");
1047
1048       dbus_connection_unref (connection);
1049
1050       return TRUE;
1051     }
1052
1053   dbus_connection_unref (connection);
1054
1055   message = pop_message_waiting_for_memory (connection);
1056   if (message == NULL)
1057     {
1058       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1059                   "Hello", serial, connection);
1060       goto out;
1061     }
1062
1063   verbose_message_received (connection, message);
1064
1065   if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
1066     {
1067       _dbus_warn ("Message has wrong sender %s\n",
1068                   dbus_message_get_sender (message) ?
1069                   dbus_message_get_sender (message) : "(none)");
1070       goto out;
1071     }
1072
1073   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
1074     {
1075       warn_unexpected (connection, message, "method return for Hello");
1076       goto out;
1077     }
1078
1079   if (!check_no_leftovers (context))
1080     goto out;
1081
1082   retval = TRUE;
1083
1084  out:
1085   dbus_error_free (&error);
1086
1087   if (message)
1088     dbus_message_unref (message);
1089
1090   return retval;
1091 }
1092
1093 /* returns TRUE if the correct thing happens,
1094  * but the correct thing may include OOM errors.
1095  */
1096 static dbus_bool_t
1097 check_get_connection_unix_user (BusContext     *context,
1098                                 DBusConnection *connection)
1099 {
1100   DBusMessage *message;
1101   dbus_uint32_t serial;
1102   dbus_bool_t retval;
1103   DBusError error;
1104   const char *base_service_name;
1105   dbus_uint32_t uid;
1106
1107   retval = FALSE;
1108   dbus_error_init (&error);
1109   message = NULL;
1110
1111   _dbus_verbose ("check_get_connection_unix_user for %p\n", connection);
1112
1113   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
1114                                           DBUS_PATH_DBUS,
1115                                           DBUS_INTERFACE_DBUS,
1116                                           "GetConnectionUnixUser");
1117
1118   if (message == NULL)
1119     return TRUE;
1120
1121   base_service_name = dbus_bus_get_unique_name (connection);
1122
1123   if (!dbus_message_append_args (message,
1124                                  DBUS_TYPE_STRING, &base_service_name,
1125                                  DBUS_TYPE_INVALID))
1126     {
1127       dbus_message_unref (message);
1128       return TRUE;
1129     }
1130
1131   if (!dbus_connection_send (connection, message, &serial))
1132     {
1133       dbus_message_unref (message);
1134       return TRUE;
1135     }
1136
1137   /* send our message */
1138   bus_test_run_clients_loop (SEND_PENDING (connection));
1139
1140   dbus_message_unref (message);
1141   message = NULL;
1142
1143   dbus_connection_ref (connection); /* because we may get disconnected */
1144   block_connection_until_message_from_bus (context, connection, "reply to GetConnectionUnixUser");
1145
1146   if (!dbus_connection_get_is_connected (connection))
1147     {
1148       _dbus_verbose ("connection was disconnected\n");
1149
1150       dbus_connection_unref (connection);
1151
1152       return TRUE;
1153     }
1154
1155   dbus_connection_unref (connection);
1156
1157   message = pop_message_waiting_for_memory (connection);
1158   if (message == NULL)
1159     {
1160       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1161                   "GetConnectionUnixUser", serial, connection);
1162       goto out;
1163     }
1164
1165   verbose_message_received (connection, message);
1166
1167   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1168     {
1169       if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY))
1170         {
1171           ; /* good, this is a valid response */
1172         }
1173       else
1174         {
1175           warn_unexpected (connection, message, "not this error");
1176
1177           goto out;
1178         }
1179     }
1180   else
1181     {
1182       if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1183         {
1184           ; /* good, expected */
1185         }
1186       else
1187         {
1188           warn_unexpected (connection, message,
1189                            "method_return for GetConnectionUnixUser");
1190
1191           goto out;
1192         }
1193
1194     retry_get_property:
1195
1196       if (!dbus_message_get_args (message, &error,
1197                                   DBUS_TYPE_UINT32, &uid,
1198                                   DBUS_TYPE_INVALID))
1199         {
1200           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1201             {
1202               _dbus_verbose ("no memory to get uid by GetConnectionUnixUser\n");
1203               dbus_error_free (&error);
1204               _dbus_wait_for_memory ();
1205               goto retry_get_property;
1206             }
1207           else
1208             {
1209               _dbus_assert (dbus_error_is_set (&error));
1210               _dbus_warn ("Did not get the expected DBUS_TYPE_UINT32 from GetConnectionUnixUser\n");
1211               goto out;
1212             }
1213         }
1214     }
1215
1216   if (!check_no_leftovers (context))
1217     goto out;
1218
1219   retval = TRUE;
1220
1221  out:
1222   dbus_error_free (&error);
1223
1224   if (message)
1225     dbus_message_unref (message);
1226
1227   return retval;
1228 }
1229
1230 /* returns TRUE if the correct thing happens,
1231  * but the correct thing may include OOM errors.
1232  */
1233 static dbus_bool_t
1234 check_get_connection_unix_process_id (BusContext     *context,
1235                                       DBusConnection *connection)
1236 {
1237   DBusMessage *message;
1238   dbus_uint32_t serial;
1239   dbus_bool_t retval;
1240   DBusError error;
1241   const char *base_service_name;
1242   dbus_uint32_t pid;
1243
1244   retval = FALSE;
1245   dbus_error_init (&error);
1246   message = NULL;
1247
1248   _dbus_verbose ("check_get_connection_unix_process_id for %p\n", connection);
1249
1250   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
1251                                           DBUS_PATH_DBUS,
1252                                           DBUS_INTERFACE_DBUS,
1253                                           "GetConnectionUnixProcessID");
1254
1255   if (message == NULL)
1256     return TRUE;
1257
1258   base_service_name = dbus_bus_get_unique_name (connection);
1259
1260   if (!dbus_message_append_args (message,
1261                                  DBUS_TYPE_STRING, &base_service_name,
1262                                  DBUS_TYPE_INVALID))
1263     {
1264       dbus_message_unref (message);
1265       return TRUE;
1266     }
1267
1268   if (!dbus_connection_send (connection, message, &serial))
1269     {
1270       dbus_message_unref (message);
1271       return TRUE;
1272     }
1273
1274   /* send our message */
1275   bus_test_run_clients_loop (SEND_PENDING (connection));
1276
1277   dbus_message_unref (message);
1278   message = NULL;
1279
1280   dbus_connection_ref (connection); /* because we may get disconnected */
1281   block_connection_until_message_from_bus (context, connection, "reply to GetConnectionUnixProcessID");
1282
1283   if (!dbus_connection_get_is_connected (connection))
1284     {
1285       _dbus_verbose ("connection was disconnected\n");
1286
1287       dbus_connection_unref (connection);
1288
1289       return TRUE;
1290     }
1291
1292   dbus_connection_unref (connection);
1293
1294   message = pop_message_waiting_for_memory (connection);
1295   if (message == NULL)
1296     {
1297       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1298                   "GetConnectionUnixProcessID", serial, connection);
1299       goto out;
1300     }
1301
1302   verbose_message_received (connection, message);
1303
1304   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1305     {
1306       if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY))
1307         {
1308           ; /* good, this is a valid response */
1309         }
1310 #ifdef DBUS_WIN
1311       else if (dbus_message_is_error (message, DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN))
1312         {
1313           /* We are expecting this error, since we know in the test suite we aren't
1314            * talking to a client running on UNIX
1315            */
1316           _dbus_verbose ("Windows correctly does not support GetConnectionUnixProcessID\n");
1317         }
1318 #endif
1319       else
1320         {
1321           warn_unexpected (connection, message, "not this error");
1322
1323           goto out;
1324         }
1325     }
1326   else
1327     {
1328 #ifdef DBUS_WIN
1329       warn_unexpected (connection, message, "GetConnectionUnixProcessID to fail on Windows");
1330       goto out;
1331 #else
1332       if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1333         {
1334           ; /* good, expected */
1335         }
1336       else
1337         {
1338           warn_unexpected (connection, message,
1339                            "method_return for GetConnectionUnixProcessID");
1340
1341           goto out;
1342         }
1343
1344     retry_get_property:
1345
1346       if (!dbus_message_get_args (message, &error,
1347                                   DBUS_TYPE_UINT32, &pid,
1348                                   DBUS_TYPE_INVALID))
1349         {
1350           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1351             {
1352               _dbus_verbose ("no memory to get pid by GetConnectionUnixProcessID\n");
1353               dbus_error_free (&error);
1354               _dbus_wait_for_memory ();
1355               goto retry_get_property;
1356             }
1357           else
1358             {
1359               _dbus_assert (dbus_error_is_set (&error));
1360               _dbus_warn ("Did not get the expected DBUS_TYPE_UINT32 from GetConnectionUnixProcessID\n");
1361               goto out;
1362             }
1363         }
1364       else
1365         {
1366           /* test if returned pid is the same as our own pid
1367            *
1368            * @todo It would probably be good to restructure the tests
1369            *       in a way so our parent is the bus that we're testing
1370            *       cause then we can test that the pid returned matches
1371            *       getppid()
1372            */
1373           if (pid != (dbus_uint32_t) _dbus_getpid ())
1374             {
1375               _dbus_assert (dbus_error_is_set (&error));
1376               _dbus_warn ("Result from GetConnectionUnixProcessID is not our own pid\n");
1377               goto out;
1378             }
1379         }
1380 #endif /* !DBUS_WIN */
1381     }
1382
1383   if (!check_no_leftovers (context))
1384     goto out;
1385
1386   retval = TRUE;
1387
1388  out:
1389   dbus_error_free (&error);
1390
1391   if (message)
1392     dbus_message_unref (message);
1393
1394   return retval;
1395 }
1396
1397 /* returns TRUE if the correct thing happens,
1398  * but the correct thing may include OOM errors.
1399  */
1400 static dbus_bool_t
1401 check_add_match_all (BusContext     *context,
1402                      DBusConnection *connection)
1403 {
1404   DBusMessage *message;
1405   dbus_bool_t retval;
1406   dbus_uint32_t serial;
1407   DBusError error;
1408   const char *empty = "";
1409
1410   retval = FALSE;
1411   dbus_error_init (&error);
1412   message = NULL;
1413
1414   _dbus_verbose ("check_add_match_all for %p\n", connection);
1415
1416   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
1417                                           DBUS_PATH_DBUS,
1418                                           DBUS_INTERFACE_DBUS,
1419                                           "AddMatch");
1420
1421   if (message == NULL)
1422     return TRUE;
1423
1424   /* empty string match rule matches everything */
1425   if (!dbus_message_append_args (message, DBUS_TYPE_STRING, &empty,
1426                                  DBUS_TYPE_INVALID))
1427     {
1428       dbus_message_unref (message);
1429       return TRUE;
1430     }
1431
1432   if (!dbus_connection_send (connection, message, &serial))
1433     {
1434       dbus_message_unref (message);
1435       return TRUE;
1436     }
1437
1438   dbus_message_unref (message);
1439   message = NULL;
1440
1441   dbus_connection_ref (connection); /* because we may get disconnected */
1442
1443   /* send our message */
1444   bus_test_run_clients_loop (SEND_PENDING (connection));
1445
1446   if (!dbus_connection_get_is_connected (connection))
1447     {
1448       _dbus_verbose ("connection was disconnected\n");
1449
1450       dbus_connection_unref (connection);
1451
1452       return TRUE;
1453     }
1454
1455   block_connection_until_message_from_bus (context, connection, "reply to AddMatch");
1456
1457   if (!dbus_connection_get_is_connected (connection))
1458     {
1459       _dbus_verbose ("connection was disconnected\n");
1460
1461       dbus_connection_unref (connection);
1462
1463       return TRUE;
1464     }
1465
1466   dbus_connection_unref (connection);
1467
1468   message = pop_message_waiting_for_memory (connection);
1469   if (message == NULL)
1470     {
1471       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1472                   "AddMatch", serial, connection);
1473       goto out;
1474     }
1475
1476   verbose_message_received (connection, message);
1477
1478   if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
1479     {
1480       _dbus_warn ("Message has wrong sender %s\n",
1481                   dbus_message_get_sender (message) ?
1482                   dbus_message_get_sender (message) : "(none)");
1483       goto out;
1484     }
1485
1486   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1487     {
1488       if (dbus_message_is_error (message,
1489                                  DBUS_ERROR_NO_MEMORY))
1490         {
1491           ; /* good, this is a valid response */
1492         }
1493       else
1494         {
1495           warn_unexpected (connection, message, "not this error");
1496
1497           goto out;
1498         }
1499     }
1500   else
1501     {
1502       if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1503         {
1504           ; /* good, expected */
1505           _dbus_assert (dbus_message_get_reply_serial (message) == serial);
1506         }
1507       else
1508         {
1509           warn_unexpected (connection, message, "method return for AddMatch");
1510
1511           goto out;
1512         }
1513     }
1514
1515   if (!check_no_leftovers (context))
1516     goto out;
1517
1518   retval = TRUE;
1519
1520  out:
1521   dbus_error_free (&error);
1522
1523   if (message)
1524     dbus_message_unref (message);
1525
1526   return retval;
1527 }
1528
1529 /* returns TRUE if the correct thing happens,
1530  * but the correct thing may include OOM errors.
1531  */
1532 static dbus_bool_t
1533 check_hello_connection (BusContext *context)
1534 {
1535   DBusConnection *connection;
1536   DBusError error;
1537
1538   dbus_error_init (&error);
1539
1540   connection = dbus_connection_open_private (TEST_DEBUG_PIPE, &error);
1541   if (connection == NULL)
1542     {
1543       _DBUS_ASSERT_ERROR_IS_SET (&error);
1544       dbus_error_free (&error);
1545       return TRUE;
1546     }
1547
1548   if (!bus_setup_debug_client (connection))
1549     {
1550       dbus_connection_close (connection);
1551       dbus_connection_unref (connection);
1552       return TRUE;
1553     }
1554
1555   spin_connection_until_authenticated (context, connection);
1556
1557   if (!check_hello_message (context, connection))
1558     return FALSE;
1559
1560   if (dbus_bus_get_unique_name (connection) == NULL)
1561     {
1562       /* We didn't successfully register, so we can't
1563        * do the usual kill_client_connection() checks
1564        */
1565       kill_client_connection_unchecked (connection);
1566     }
1567   else
1568     {
1569       if (!check_add_match_all (context, connection))
1570         return FALSE;
1571
1572       kill_client_connection (context, connection);
1573     }
1574
1575   return TRUE;
1576 }
1577
1578 #define NONEXISTENT_SERVICE_NAME "test.this.service.does.not.exist.ewuoiurjdfxcvn"
1579
1580 /* returns TRUE if the correct thing happens,
1581  * but the correct thing may include OOM errors.
1582  */
1583 static dbus_bool_t
1584 check_nonexistent_service_no_auto_start (BusContext     *context,
1585                                          DBusConnection *connection)
1586 {
1587   DBusMessage *message;
1588   dbus_uint32_t serial;
1589   dbus_bool_t retval;
1590   const char *nonexistent = NONEXISTENT_SERVICE_NAME;
1591   dbus_uint32_t flags;
1592
1593   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
1594                                           DBUS_PATH_DBUS,
1595                                           DBUS_INTERFACE_DBUS,
1596                                           "StartServiceByName");
1597
1598   if (message == NULL)
1599     return TRUE;
1600
1601   dbus_message_set_auto_start (message, FALSE);
1602
1603   flags = 0;
1604   if (!dbus_message_append_args (message,
1605                                  DBUS_TYPE_STRING, &nonexistent,
1606                                  DBUS_TYPE_UINT32, &flags,
1607                                  DBUS_TYPE_INVALID))
1608     {
1609       dbus_message_unref (message);
1610       return TRUE;
1611     }
1612
1613   if (!dbus_connection_send (connection, message, &serial))
1614     {
1615       dbus_message_unref (message);
1616       return TRUE;
1617     }
1618
1619   dbus_message_unref (message);
1620   message = NULL;
1621
1622   bus_test_run_everything (context);
1623   block_connection_until_message_from_bus (context, connection, "reply to ActivateService on nonexistent");
1624   bus_test_run_everything (context);
1625
1626   if (!dbus_connection_get_is_connected (connection))
1627     {
1628       _dbus_verbose ("connection was disconnected\n");
1629       return TRUE;
1630     }
1631
1632   retval = FALSE;
1633
1634   message = pop_message_waiting_for_memory (connection);
1635   if (message == NULL)
1636     {
1637       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1638                   "StartServiceByName", serial, connection);
1639       goto out;
1640     }
1641
1642   verbose_message_received (connection, message);
1643
1644   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1645     {
1646       if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
1647         {
1648           _dbus_warn ("Message has wrong sender %s\n",
1649                       dbus_message_get_sender (message) ?
1650                       dbus_message_get_sender (message) : "(none)");
1651           goto out;
1652         }
1653
1654       if (dbus_message_is_error (message,
1655                                  DBUS_ERROR_NO_MEMORY))
1656         {
1657           ; /* good, this is a valid response */
1658         }
1659       else if (dbus_message_is_error (message,
1660                                       DBUS_ERROR_SERVICE_UNKNOWN))
1661         {
1662           ; /* good, this is expected also */
1663         }
1664       else
1665         {
1666           warn_unexpected (connection, message, "not this error");
1667           goto out;
1668         }
1669     }
1670   else
1671     {
1672       _dbus_warn ("Did not expect to successfully activate %s\n",
1673                   NONEXISTENT_SERVICE_NAME);
1674       goto out;
1675     }
1676
1677   retval = TRUE;
1678
1679  out:
1680   if (message)
1681     dbus_message_unref (message);
1682
1683   return retval;
1684 }
1685
1686 /* returns TRUE if the correct thing happens,
1687  * but the correct thing may include OOM errors.
1688  */
1689 static dbus_bool_t
1690 check_nonexistent_service_auto_start (BusContext     *context,
1691                                       DBusConnection *connection)
1692 {
1693   DBusMessage *message;
1694   dbus_uint32_t serial;
1695   dbus_bool_t retval;
1696
1697   message = dbus_message_new_method_call (NONEXISTENT_SERVICE_NAME,
1698                                           "/org/freedesktop/TestSuite",
1699                                           "org.freedesktop.TestSuite",
1700                                           "Echo");
1701
1702   if (message == NULL)
1703     return TRUE;
1704
1705   if (!dbus_connection_send (connection, message, &serial))
1706     {
1707       dbus_message_unref (message);
1708       return TRUE;
1709     }
1710
1711   dbus_message_unref (message);
1712   message = NULL;
1713
1714   bus_test_run_everything (context);
1715   block_connection_until_message_from_bus (context, connection, "reply to Echo");
1716   bus_test_run_everything (context);
1717
1718   if (!dbus_connection_get_is_connected (connection))
1719     {
1720       _dbus_verbose ("connection was disconnected\n");
1721       return TRUE;
1722     }
1723
1724   retval = FALSE;
1725
1726   message = pop_message_waiting_for_memory (connection);
1727
1728   if (message == NULL)
1729     {
1730       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1731                   "Echo message (auto activation)", serial, connection);
1732       goto out;
1733     }
1734
1735   verbose_message_received (connection, message);
1736
1737   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1738     {
1739       if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
1740         {
1741           _dbus_warn ("Message has wrong sender %s\n",
1742                       dbus_message_get_sender (message) ?
1743                       dbus_message_get_sender (message) : "(none)");
1744           goto out;
1745         }
1746
1747       if (dbus_message_is_error (message,
1748                                  DBUS_ERROR_NO_MEMORY))
1749         {
1750           ; /* good, this is a valid response */
1751         }
1752       else if (dbus_message_is_error (message,
1753                                       DBUS_ERROR_SERVICE_UNKNOWN))
1754         {
1755           ; /* good, this is expected also */
1756         }
1757       else
1758         {
1759           warn_unexpected (connection, message, "not this error");
1760           goto out;
1761         }
1762     }
1763   else
1764     {
1765       _dbus_warn ("Did not expect to successfully activate %s\n",
1766                   NONEXISTENT_SERVICE_NAME);
1767       goto out;
1768     }
1769
1770   retval = TRUE;
1771
1772  out:
1773   if (message)
1774     dbus_message_unref (message);
1775
1776   return retval;
1777 }
1778
1779 static dbus_bool_t
1780 check_base_service_activated (BusContext     *context,
1781                               DBusConnection *connection,
1782                               DBusMessage    *initial_message,
1783                               const char    **base_service_p)
1784 {
1785   DBusMessage *message;
1786   dbus_bool_t retval;
1787   DBusError error;
1788   const char *base_service, *base_service_from_bus, *old_owner;
1789
1790   retval = FALSE;
1791
1792   dbus_error_init (&error);
1793   base_service = NULL;
1794   old_owner = NULL;
1795   base_service_from_bus = NULL;
1796
1797   message = initial_message;
1798   dbus_message_ref (message);
1799
1800   if (dbus_message_is_signal (message,
1801                               DBUS_INTERFACE_DBUS,
1802                               "NameOwnerChanged"))
1803     {
1804       CheckServiceOwnerChangedData socd;
1805
1806     reget_service_name_arg:
1807       base_service = NULL;
1808       old_owner = NULL;
1809       base_service_from_bus = NULL;
1810
1811       if (!dbus_message_get_args (message, &error,
1812                                   DBUS_TYPE_STRING, &base_service,
1813                                   DBUS_TYPE_STRING, &old_owner,
1814                                   DBUS_TYPE_STRING, &base_service_from_bus,
1815                                   DBUS_TYPE_INVALID))
1816         {
1817           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1818             {
1819               dbus_error_free (&error);
1820               _dbus_wait_for_memory ();
1821               goto reget_service_name_arg;
1822             }
1823           else
1824             {
1825               _dbus_warn ("Message %s doesn't have a service name: %s\n",
1826                           "NameOwnerChanged (creation)",
1827                           error.message);
1828               goto out;
1829             }
1830         }
1831
1832       if (*base_service != ':')
1833         {
1834           _dbus_warn ("Expected base service activation, got \"%s\" instead\n",
1835                       base_service);
1836           goto out;
1837         }
1838
1839       if (strcmp (base_service, base_service_from_bus) != 0)
1840         {
1841           _dbus_warn ("Expected base service activation, got \"%s\" instead with owner \"%s\"\n",
1842                       base_service, base_service_from_bus);
1843           goto out;
1844         }
1845
1846       if (old_owner[0])
1847         {
1848           _dbus_warn ("Received an old_owner argument during base service activation, \"%s\"\n",
1849                       old_owner);
1850           goto out;
1851         }
1852
1853       socd.expected_kind = SERVICE_CREATED;
1854       socd.expected_service_name = base_service;
1855       socd.failed = FALSE;
1856       socd.skip_connection = connection;
1857       bus_test_clients_foreach (check_service_owner_changed_foreach,
1858                                 &socd);
1859
1860       if (socd.failed)
1861         goto out;
1862     }
1863   else
1864     {
1865       warn_unexpected (connection, message, "NameOwnerChanged (creation) for base service");
1866
1867       goto out;
1868     }
1869
1870   if (base_service_p)
1871     *base_service_p = base_service;
1872
1873   retval = TRUE;
1874
1875  out:
1876   if (message)
1877     dbus_message_unref (message);
1878   dbus_error_free (&error);
1879
1880   return retval;
1881 }
1882
1883 static dbus_bool_t
1884 check_service_activated (BusContext     *context,
1885                          DBusConnection *connection,
1886                          const char     *activated_name,
1887                          const char     *base_service_name,
1888                          DBusMessage    *initial_message)
1889 {
1890   DBusMessage *message;
1891   dbus_bool_t retval;
1892   DBusError error;
1893   dbus_uint32_t activation_result;
1894
1895   retval = FALSE;
1896
1897   dbus_error_init (&error);
1898
1899   message = initial_message;
1900   dbus_message_ref (message);
1901
1902   if (dbus_message_is_signal (message,
1903                               DBUS_INTERFACE_DBUS,
1904                               "NameOwnerChanged"))
1905     {
1906       CheckServiceOwnerChangedData socd;
1907       const char *service_name, *base_service_from_bus, *old_owner;
1908
1909     reget_service_name_arg:
1910       service_name = NULL;
1911       old_owner = NULL;
1912       base_service_from_bus = NULL;
1913
1914       if (!dbus_message_get_args (message, &error,
1915                                   DBUS_TYPE_STRING, &service_name,
1916                                    DBUS_TYPE_STRING, &old_owner,
1917                                   DBUS_TYPE_STRING, &base_service_from_bus,
1918                                   DBUS_TYPE_INVALID))
1919         {
1920           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1921             {
1922               dbus_error_free (&error);
1923               _dbus_wait_for_memory ();
1924               goto reget_service_name_arg;
1925             }
1926           else
1927             {
1928               _dbus_warn ("Message %s doesn't have a service name: %s\n",
1929                           "NameOwnerChanged (creation)",
1930                           error.message);
1931               goto out;
1932             }
1933         }
1934
1935       if (strcmp (service_name, activated_name) != 0)
1936         {
1937           _dbus_warn ("Expected to see service %s created, saw %s instead\n",
1938                       activated_name, service_name);
1939           goto out;
1940         }
1941
1942       if (strcmp (base_service_name, base_service_from_bus) != 0)
1943         {
1944           _dbus_warn ("NameOwnerChanged reports wrong base service: %s owner, expected %s instead\n",
1945                       base_service_from_bus, base_service_name);
1946           goto out;
1947         }
1948
1949       if (old_owner[0])
1950         {
1951           _dbus_warn ("expected a %s, got a %s\n",
1952                       "NameOwnerChanged (creation)",
1953                       "NameOwnerChanged (change)");
1954           goto out;
1955         }
1956
1957       socd.expected_kind = SERVICE_CREATED;
1958       socd.skip_connection = connection;
1959       socd.failed = FALSE;
1960       socd.expected_service_name = service_name;
1961       bus_test_clients_foreach (check_service_owner_changed_foreach,
1962                                 &socd);
1963
1964       if (socd.failed)
1965         goto out;
1966
1967       dbus_message_unref (message);
1968       service_name = NULL;
1969       old_owner = NULL;
1970       base_service_from_bus = NULL;
1971
1972       message = pop_message_waiting_for_memory (connection);
1973       if (message == NULL)
1974         {
1975           _dbus_warn ("Expected a reply to %s, got nothing\n",
1976                       "StartServiceByName");
1977           goto out;
1978         }
1979     }
1980   else
1981     {
1982       warn_unexpected (connection, message, "NameOwnerChanged for the activated name");
1983
1984       goto out;
1985     }
1986
1987   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN)
1988     {
1989       warn_unexpected (connection, message, "reply to StartServiceByName");
1990
1991       goto out;
1992     }
1993
1994   activation_result = 0;
1995   if (!dbus_message_get_args (message, &error,
1996                               DBUS_TYPE_UINT32, &activation_result,
1997                               DBUS_TYPE_INVALID))
1998     {
1999       if (!dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
2000         {
2001           _dbus_warn ("Did not have activation result first argument to %s: %s\n",
2002                       "StartServiceByName", error.message);
2003           goto out;
2004         }
2005
2006       dbus_error_free (&error);
2007     }
2008   else
2009     {
2010       if (activation_result == DBUS_START_REPLY_SUCCESS)
2011         ; /* Good */
2012       else if (activation_result == DBUS_START_REPLY_ALREADY_RUNNING)
2013         ; /* Good also */
2014       else
2015         {
2016           _dbus_warn ("Activation result was %u, no good.\n",
2017                       activation_result);
2018           goto out;
2019         }
2020     }
2021
2022   dbus_message_unref (message);
2023   message = NULL;
2024
2025   if (!check_no_leftovers (context))
2026     {
2027       _dbus_warn ("Messages were left over after verifying existent activation results\n");
2028       goto out;
2029     }
2030
2031   retval = TRUE;
2032
2033  out:
2034   if (message)
2035     dbus_message_unref (message);
2036   dbus_error_free (&error);
2037
2038   return retval;
2039 }
2040
2041 static dbus_bool_t
2042 check_service_auto_activated (BusContext     *context,
2043                               DBusConnection *connection,
2044                               const char     *activated_name,
2045                               const char     *base_service_name,
2046                               DBusMessage    *initial_message)
2047 {
2048   DBusMessage *message;
2049   dbus_bool_t retval;
2050   DBusError error;
2051
2052   retval = FALSE;
2053
2054   dbus_error_init (&error);
2055
2056   message = initial_message;
2057   dbus_message_ref (message);
2058
2059   if (dbus_message_is_signal (message,
2060                               DBUS_INTERFACE_DBUS,
2061                               "NameOwnerChanged"))
2062     {
2063       const char *service_name;
2064       CheckServiceOwnerChangedData socd;
2065
2066     reget_service_name_arg:
2067       if (!dbus_message_get_args (message, &error,
2068                                   DBUS_TYPE_STRING, &service_name,
2069                                   DBUS_TYPE_INVALID))
2070         {
2071           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
2072             {
2073               dbus_error_free (&error);
2074               _dbus_wait_for_memory ();
2075               goto reget_service_name_arg;
2076             }
2077           else
2078             {
2079               _dbus_warn ("Message %s doesn't have a service name: %s\n",
2080                           "NameOwnerChanged",
2081                           error.message);
2082               dbus_error_free (&error);
2083               goto out;
2084             }
2085         }
2086
2087       if (strcmp (service_name, activated_name) != 0)
2088         {
2089           _dbus_warn ("Expected to see service %s created, saw %s instead\n",
2090                       activated_name, service_name);
2091           goto out;
2092         }
2093
2094       socd.expected_kind = SERVICE_CREATED;
2095       socd.expected_service_name = service_name;
2096       socd.failed = FALSE;
2097       socd.skip_connection = connection;
2098       bus_test_clients_foreach (check_service_owner_changed_foreach,
2099                                 &socd);
2100
2101       if (socd.failed)
2102         goto out;
2103
2104       /* Note that this differs from regular activation in that we don't get a
2105        * reply to ActivateService here.
2106        */
2107
2108       dbus_message_unref (message);
2109       message = NULL;
2110       service_name = NULL;
2111     }
2112   else
2113     {
2114       warn_unexpected (connection, message, "NameOwnerChanged for the activated name");
2115
2116       goto out;
2117     }
2118
2119   retval = TRUE;
2120
2121  out:
2122   if (message)
2123     dbus_message_unref (message);
2124
2125   return retval;
2126 }
2127
2128 static dbus_bool_t
2129 check_service_deactivated (BusContext     *context,
2130                            DBusConnection *connection,
2131                            const char     *activated_name,
2132                            const char     *base_service)
2133 {
2134   dbus_bool_t retval;
2135   CheckServiceOwnerChangedData socd;
2136
2137   retval = FALSE;
2138
2139   /* Now we are expecting ServiceOwnerChanged (deletion) messages for the base
2140    * service and the activated_name.  The base service
2141    * notification is required to come last.
2142    */
2143   socd.expected_kind = SERVICE_DELETED;
2144   socd.expected_service_name = activated_name;
2145   socd.failed = FALSE;
2146   socd.skip_connection = NULL;
2147   bus_test_clients_foreach (check_service_owner_changed_foreach,
2148                             &socd);
2149
2150   if (socd.failed)
2151     goto out;
2152
2153   socd.expected_kind = SERVICE_DELETED;
2154   socd.expected_service_name = base_service;
2155   socd.failed = FALSE;
2156   socd.skip_connection = NULL;
2157   bus_test_clients_foreach (check_service_owner_changed_foreach,
2158                             &socd);
2159
2160   if (socd.failed)
2161     goto out;
2162
2163   retval = TRUE;
2164
2165  out:
2166   return retval;
2167 }
2168
2169 static dbus_bool_t
2170 check_send_exit_to_service (BusContext     *context,
2171                             DBusConnection *connection,
2172                             const char     *service_name,
2173                             const char     *base_service)
2174 {
2175   dbus_bool_t got_error;
2176   DBusMessage *message;
2177   dbus_uint32_t serial;
2178   dbus_bool_t retval;
2179
2180   _dbus_verbose ("Sending exit message to the test service\n");
2181
2182   retval = FALSE;
2183
2184   /* Kill off the test service by sending it a quit message */
2185   message = dbus_message_new_method_call (service_name,
2186                                           "/org/freedesktop/TestSuite",
2187                                           "org.freedesktop.TestSuite",
2188                                           "Exit");
2189
2190   if (message == NULL)
2191     {
2192       /* Do this again; we still need the service to exit... */
2193       if (!check_send_exit_to_service (context, connection,
2194                                        service_name, base_service))
2195         goto out;
2196
2197       return TRUE;
2198     }
2199
2200   if (!dbus_connection_send (connection, message, &serial))
2201     {
2202       dbus_message_unref (message);
2203
2204       /* Do this again; we still need the service to exit... */
2205       if (!check_send_exit_to_service (context, connection,
2206                                        service_name, base_service))
2207         goto out;
2208
2209       return TRUE;
2210     }
2211
2212   dbus_message_unref (message);
2213   message = NULL;
2214
2215   /* send message */
2216   bus_test_run_clients_loop (SEND_PENDING (connection));
2217
2218   /* read it in and write it out to test service */
2219   bus_test_run_bus_loop (context, FALSE);
2220
2221   /* see if we got an error during message bus dispatching */
2222   bus_test_run_clients_loop (FALSE);
2223   message = borrow_message_waiting_for_memory (connection);
2224   got_error = message != NULL && dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR;
2225   if (message)
2226     {
2227       dbus_connection_return_message (connection, message);
2228       message = NULL;
2229     }
2230
2231   if (!got_error)
2232     {
2233       /* If no error, wait for the test service to exit */
2234       block_connection_until_message_from_bus (context, connection, "test service to exit");
2235
2236       bus_test_run_everything (context);
2237     }
2238
2239   if (got_error)
2240     {
2241       message = pop_message_waiting_for_memory (connection);
2242       _dbus_assert (message != NULL);
2243
2244       if (dbus_message_get_reply_serial (message) != serial)
2245         {
2246           warn_unexpected (connection, message,
2247                            "error with the correct reply serial");
2248           goto out;
2249         }
2250
2251       if (!dbus_message_is_error (message,
2252                                   DBUS_ERROR_NO_MEMORY))
2253         {
2254           warn_unexpected (connection, message,
2255                            "a no memory error from asking test service to exit");
2256           goto out;
2257         }
2258
2259       _dbus_verbose ("Got error %s when asking test service to exit\n",
2260                      dbus_message_get_error_name (message));
2261
2262       /* Do this again; we still need the service to exit... */
2263       if (!check_send_exit_to_service (context, connection,
2264                                        service_name, base_service))
2265         goto out;
2266     }
2267   else
2268     {
2269       if (!check_service_deactivated (context, connection,
2270                                       service_name, base_service))
2271         goto out;
2272
2273       /* Should now have a NoReply error from the Exit() method
2274        * call; it should have come after all the deactivation
2275        * stuff.
2276        */
2277       message = pop_message_waiting_for_memory (connection);
2278
2279       if (message == NULL)
2280         {
2281           warn_unexpected (connection, NULL,
2282                            "reply to Exit() method call");
2283           goto out;
2284         }
2285       if (!dbus_message_is_error (message,
2286                                   DBUS_ERROR_NO_REPLY))
2287         {
2288           warn_unexpected (connection, message,
2289                            "NoReply error from Exit() method call");
2290           goto out;
2291         }
2292
2293       if (dbus_message_get_reply_serial (message) != serial)
2294         {
2295           warn_unexpected (connection, message,
2296                            "error with the correct reply serial");
2297           goto out;
2298         }
2299
2300       _dbus_verbose ("Got error %s after test service exited\n",
2301                      dbus_message_get_error_name (message));
2302
2303       if (!check_no_leftovers (context))
2304         {
2305           _dbus_warn ("Messages were left over after %s\n",
2306                       _DBUS_FUNCTION_NAME);
2307           goto out;
2308         }
2309     }
2310
2311   retval = TRUE;
2312
2313  out:
2314   if (message)
2315     dbus_message_unref (message);
2316
2317   return retval;
2318 }
2319
2320 static dbus_bool_t
2321 check_got_error (BusContext     *context,
2322                  DBusConnection *connection,
2323                  const char     *first_error_name,
2324                  ...)
2325 {
2326   DBusMessage *message;
2327   dbus_bool_t retval;
2328   va_list ap;
2329   dbus_bool_t error_found;
2330   const char *error_name;
2331
2332   retval = FALSE;
2333
2334   message = pop_message_waiting_for_memory (connection);
2335   if (message == NULL)
2336     {
2337       _dbus_warn ("Did not get an expected error\n");
2338       goto out;
2339     }
2340
2341   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
2342     {
2343       warn_unexpected (connection, message, "an error");
2344
2345       goto out;
2346     }
2347
2348   error_found = FALSE;
2349
2350   va_start (ap, first_error_name);
2351   error_name = first_error_name;
2352   while (error_name != NULL)
2353     {
2354       if (dbus_message_is_error (message, error_name))
2355         {
2356           error_found = TRUE;
2357           break;
2358         }
2359       error_name = va_arg (ap, char*);
2360     }
2361   va_end (ap);
2362
2363   if (!error_found)
2364     {
2365       _dbus_warn ("Expected error %s or other, got %s instead\n",
2366                   first_error_name,
2367                   dbus_message_get_error_name (message));
2368       goto out;
2369     }
2370
2371   retval = TRUE;
2372
2373  out:
2374   if (message)
2375     dbus_message_unref (message);
2376
2377   return retval;
2378 }
2379
2380 typedef enum
2381 {
2382   GOT_SERVICE_CREATED,
2383   GOT_SERVICE_DELETED,
2384   GOT_ERROR,
2385   GOT_SOMETHING_ELSE
2386 } GotServiceInfo;
2387
2388 static GotServiceInfo
2389 check_got_service_info (DBusMessage *message)
2390 {
2391   GotServiceInfo message_kind;
2392
2393   if (dbus_message_is_signal (message,
2394                               DBUS_INTERFACE_DBUS,
2395                               "NameOwnerChanged"))
2396     {
2397       DBusError error;
2398       const char *service_name, *old_owner, *new_owner;
2399       dbus_error_init (&error);
2400
2401     reget_service_info_data:
2402       service_name = NULL;
2403       old_owner = NULL;
2404       new_owner = NULL;
2405
2406       dbus_message_get_args (message, &error,
2407                              DBUS_TYPE_STRING, &service_name,
2408                              DBUS_TYPE_STRING, &old_owner,
2409                              DBUS_TYPE_STRING, &new_owner,
2410                              DBUS_TYPE_INVALID);
2411       if (dbus_error_is_set (&error))
2412         {
2413           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
2414             {
2415               dbus_error_free (&error);
2416               goto reget_service_info_data;
2417             }
2418           else
2419             {
2420               _dbus_warn ("unexpected arguments for NameOwnerChanged message\n");
2421               message_kind = GOT_SOMETHING_ELSE;
2422             }
2423         }
2424       else if (!old_owner[0])
2425         message_kind = GOT_SERVICE_CREATED;
2426       else if (!new_owner[0])
2427         message_kind = GOT_SERVICE_DELETED;
2428       else
2429         message_kind = GOT_SOMETHING_ELSE;
2430
2431       dbus_error_free (&error);
2432     }
2433   else if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
2434     message_kind = GOT_ERROR;
2435   else
2436     message_kind = GOT_SOMETHING_ELSE;
2437
2438   return message_kind;
2439 }
2440
2441 #define EXISTENT_SERVICE_NAME "org.freedesktop.DBus.TestSuiteEchoService"
2442
2443 /* returns TRUE if the correct thing happens,
2444  * but the correct thing may include OOM errors.
2445  */
2446 static dbus_bool_t
2447 check_existent_service_no_auto_start (BusContext     *context,
2448                                       DBusConnection *connection)
2449 {
2450   DBusMessage *message;
2451   DBusMessage *base_service_message;
2452   const char *base_service;
2453   dbus_uint32_t serial;
2454   dbus_bool_t retval;
2455   const char *existent = EXISTENT_SERVICE_NAME;
2456   dbus_uint32_t flags;
2457
2458   base_service_message = NULL;
2459
2460   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
2461                                           DBUS_PATH_DBUS,
2462                                           DBUS_INTERFACE_DBUS,
2463                                           "StartServiceByName");
2464
2465   if (message == NULL)
2466     return TRUE;
2467
2468   dbus_message_set_auto_start (message, FALSE);
2469
2470   flags = 0;
2471   if (!dbus_message_append_args (message,
2472                                  DBUS_TYPE_STRING, &existent,
2473                                  DBUS_TYPE_UINT32, &flags,
2474                                  DBUS_TYPE_INVALID))
2475     {
2476       dbus_message_unref (message);
2477       return TRUE;
2478     }
2479
2480   if (!dbus_connection_send (connection, message, &serial))
2481     {
2482       dbus_message_unref (message);
2483       return TRUE;
2484     }
2485
2486   dbus_message_unref (message);
2487   message = NULL;
2488
2489   bus_test_run_everything (context);
2490
2491   /* now wait for the message bus to hear back from the activated
2492    * service.
2493    */
2494   block_connection_until_message_from_bus (context, connection, "activated service to connect");
2495
2496   bus_test_run_everything (context);
2497
2498   if (!dbus_connection_get_is_connected (connection))
2499     {
2500       _dbus_verbose ("connection was disconnected\n");
2501       return TRUE;
2502     }
2503
2504   retval = FALSE;
2505
2506   message = pop_message_waiting_for_memory (connection);
2507   if (message == NULL)
2508     {
2509       _dbus_warn ("Did not receive any messages after %s %d on %p\n",
2510                   "StartServiceByName", serial, connection);
2511       goto out;
2512     }
2513
2514   verbose_message_received (connection, message);
2515   _dbus_verbose ("  (after sending %s)\n", "StartServiceByName");
2516
2517   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
2518     {
2519       if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
2520         {
2521           _dbus_warn ("Message has wrong sender %s\n",
2522                       dbus_message_get_sender (message) ?
2523                       dbus_message_get_sender (message) : "(none)");
2524           goto out;
2525         }
2526
2527       if (dbus_message_is_error (message,
2528                                  DBUS_ERROR_NO_MEMORY))
2529         {
2530           ; /* good, this is a valid response */
2531         }
2532       else if (dbus_message_is_error (message,
2533                                       DBUS_ERROR_SPAWN_CHILD_EXITED) ||
2534                dbus_message_is_error (message,
2535                                       DBUS_ERROR_SPAWN_CHILD_SIGNALED) ||
2536                dbus_message_is_error (message,
2537                                       DBUS_ERROR_SPAWN_EXEC_FAILED))
2538         {
2539           ; /* good, this is expected also */
2540         }
2541       else
2542         {
2543           _dbus_warn ("Did not expect error %s\n",
2544                       dbus_message_get_error_name (message));
2545           goto out;
2546         }
2547     }
2548   else
2549     {
2550       GotServiceInfo message_kind;
2551
2552       if (!check_base_service_activated (context, connection,
2553                                          message, &base_service))
2554         goto out;
2555
2556       base_service_message = message;
2557       message = NULL;
2558
2559       /* We may need to block here for the test service to exit or finish up */
2560       block_connection_until_message_from_bus (context, connection, "test service to exit or finish up");
2561
2562       message = dbus_connection_borrow_message (connection);
2563       if (message == NULL)
2564         {
2565           _dbus_warn ("Did not receive any messages after base service creation notification\n");
2566           goto out;
2567         }
2568
2569       message_kind = check_got_service_info (message);
2570
2571       dbus_connection_return_message (connection, message);
2572       message = NULL;
2573
2574       switch (message_kind)
2575         {
2576         case GOT_SOMETHING_ELSE:
2577           _dbus_warn ("Unexpected message after ActivateService "
2578                       "(should be an error or a service announcement");
2579           goto out;
2580
2581         case GOT_ERROR:
2582           if (!check_got_error (context, connection,
2583                                 DBUS_ERROR_SPAWN_CHILD_EXITED,
2584                                 DBUS_ERROR_NO_MEMORY,
2585                                 NULL))
2586             goto out;
2587           /* A service deleted should be coming along now after this error.
2588            * We can also get the error *after* the service deleted.
2589            */
2590
2591           /* fall through */
2592
2593         case GOT_SERVICE_DELETED:
2594           {
2595             /* The service started up and got a base address, but then
2596              * failed to register under EXISTENT_SERVICE_NAME
2597              */
2598             CheckServiceOwnerChangedData socd;
2599
2600             socd.expected_kind = SERVICE_DELETED;
2601             socd.expected_service_name = base_service;
2602             socd.failed = FALSE;
2603             socd.skip_connection = NULL;
2604
2605             bus_test_clients_foreach (check_service_owner_changed_foreach,
2606                                       &socd);
2607
2608             if (socd.failed)
2609               goto out;
2610
2611             /* Now we should get an error about the service exiting
2612              * if we didn't get it before.
2613              */
2614             if (message_kind != GOT_ERROR)
2615               {
2616                 block_connection_until_message_from_bus (context, connection, "error about service exiting");
2617
2618                 /* and process everything again */
2619                 bus_test_run_everything (context);
2620
2621                 if (!check_got_error (context, connection,
2622                                       DBUS_ERROR_SPAWN_CHILD_EXITED,
2623                                       DBUS_ERROR_NO_MEMORY,
2624                                       NULL))
2625                   goto out;
2626               }
2627             break;
2628           }
2629
2630         case GOT_SERVICE_CREATED:
2631           message = pop_message_waiting_for_memory (connection);
2632           if (message == NULL)
2633             {
2634               _dbus_warn ("Failed to pop message we just put back! "
2635                           "should have been a NameOwnerChanged (creation)\n");
2636               goto out;
2637             }
2638
2639           if (!check_service_activated (context, connection, EXISTENT_SERVICE_NAME,
2640                                         base_service, message))
2641             goto out;
2642
2643           dbus_message_unref (message);
2644           message = NULL;
2645
2646           if (!check_no_leftovers (context))
2647             {
2648               _dbus_warn ("Messages were left over after successful activation\n");
2649               goto out;
2650             }
2651
2652           if (!check_send_exit_to_service (context, connection,
2653                                            EXISTENT_SERVICE_NAME, base_service))
2654             goto out;
2655
2656           break;
2657         }
2658     }
2659
2660   retval = TRUE;
2661
2662  out:
2663   if (message)
2664     dbus_message_unref (message);
2665
2666   if (base_service_message)
2667     dbus_message_unref (base_service_message);
2668
2669   return retval;
2670 }
2671
2672 #ifndef DBUS_WIN_FIXME
2673 /* returns TRUE if the correct thing happens,
2674  * but the correct thing may include OOM errors.
2675  */
2676 static dbus_bool_t
2677 check_segfault_service_no_auto_start (BusContext     *context,
2678                                       DBusConnection *connection)
2679 {
2680   DBusMessage *message;
2681   dbus_uint32_t serial;
2682   dbus_bool_t retval;
2683   const char *segv_service;
2684   dbus_uint32_t flags;
2685
2686   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
2687                                           DBUS_PATH_DBUS,
2688                                           DBUS_INTERFACE_DBUS,
2689                                           "StartServiceByName");
2690
2691   if (message == NULL)
2692     return TRUE;
2693
2694   dbus_message_set_auto_start (message, FALSE);
2695
2696   segv_service = "org.freedesktop.DBus.TestSuiteSegfaultService";
2697   flags = 0;
2698   if (!dbus_message_append_args (message,
2699                                  DBUS_TYPE_STRING, &segv_service,
2700                                  DBUS_TYPE_UINT32, &flags,
2701                                  DBUS_TYPE_INVALID))
2702     {
2703       dbus_message_unref (message);
2704       return TRUE;
2705     }
2706
2707   if (!dbus_connection_send (connection, message, &serial))
2708     {
2709       dbus_message_unref (message);
2710       return TRUE;
2711     }
2712
2713   dbus_message_unref (message);
2714   message = NULL;
2715
2716   bus_test_run_everything (context);
2717   block_connection_until_message_from_bus (context, connection, "reply to activating segfault service");
2718   bus_test_run_everything (context);
2719
2720   if (!dbus_connection_get_is_connected (connection))
2721     {
2722       _dbus_verbose ("connection was disconnected\n");
2723       return TRUE;
2724     }
2725
2726   retval = FALSE;
2727
2728   message = pop_message_waiting_for_memory (connection);
2729   if (message == NULL)
2730     {
2731       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
2732                   "StartServiceByName", serial, connection);
2733       goto out;
2734     }
2735
2736   verbose_message_received (connection, message);
2737
2738   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
2739     {
2740       if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
2741         {
2742           _dbus_warn ("Message has wrong sender %s\n",
2743                       dbus_message_get_sender (message) ?
2744                       dbus_message_get_sender (message) : "(none)");
2745           goto out;
2746         }
2747
2748       if (dbus_message_is_error (message,
2749                                  DBUS_ERROR_NO_MEMORY))
2750         {
2751           ; /* good, this is a valid response */
2752         }
2753       else if (dbus_message_is_error (message,
2754                                       DBUS_ERROR_FAILED))
2755         {
2756           const char *servicehelper;
2757           servicehelper = bus_context_get_servicehelper (context);
2758           /* make sure this only happens with the launch helper */
2759           _dbus_assert (servicehelper != NULL);
2760         }
2761       else if (dbus_message_is_error (message,
2762                                       DBUS_ERROR_SPAWN_CHILD_SIGNALED))
2763         {
2764           ; /* good, this is expected also */
2765         }
2766       else
2767         {
2768           warn_unexpected (connection, message, "not this error");
2769
2770           goto out;
2771         }
2772     }
2773   else
2774     {
2775       _dbus_warn ("Did not expect to successfully activate segfault service\n");
2776       goto out;
2777     }
2778
2779   retval = TRUE;
2780
2781  out:
2782   if (message)
2783     dbus_message_unref (message);
2784
2785   return retval;
2786 }
2787
2788
2789 /* returns TRUE if the correct thing happens,
2790  * but the correct thing may include OOM errors.
2791  */
2792 static dbus_bool_t
2793 check_segfault_service_auto_start (BusContext     *context,
2794                                    DBusConnection *connection)
2795 {
2796   DBusMessage *message;
2797   dbus_uint32_t serial;
2798   dbus_bool_t retval;
2799
2800   message = dbus_message_new_method_call ("org.freedesktop.DBus.TestSuiteSegfaultService",
2801                                           "/org/freedesktop/TestSuite",
2802                                           "org.freedesktop.TestSuite",
2803                                           "Echo");
2804
2805   if (message == NULL)
2806     return TRUE;
2807
2808   if (!dbus_connection_send (connection, message, &serial))
2809     {
2810       dbus_message_unref (message);
2811       return TRUE;
2812     }
2813
2814   dbus_message_unref (message);
2815   message = NULL;
2816
2817   bus_test_run_everything (context);
2818   block_connection_until_message_from_bus (context, connection, "reply to Echo on segfault service");
2819   bus_test_run_everything (context);
2820
2821   if (!dbus_connection_get_is_connected (connection))
2822     {
2823       _dbus_verbose ("connection was disconnected\n");
2824       return TRUE;
2825     }
2826
2827   retval = FALSE;
2828
2829   message = pop_message_waiting_for_memory (connection);
2830   if (message == NULL)
2831     {
2832       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
2833                   "Echo message (auto activation)", serial, connection);
2834       goto out;
2835     }
2836
2837   verbose_message_received (connection, message);
2838
2839   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
2840     {
2841       if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
2842         {
2843           _dbus_warn ("Message has wrong sender %s\n",
2844                       dbus_message_get_sender (message) ?
2845                       dbus_message_get_sender (message) : "(none)");
2846           goto out;
2847         }
2848
2849       if (dbus_message_is_error (message,
2850                                  DBUS_ERROR_NO_MEMORY))
2851         {
2852           ; /* good, this is a valid response */
2853         }
2854       else if (dbus_message_is_error (message,
2855                                       DBUS_ERROR_SPAWN_CHILD_SIGNALED))
2856         {
2857           ; /* good, this is expected also */
2858         }
2859       else
2860         {
2861           warn_unexpected (connection, message, "not this error");
2862
2863           goto out;
2864         }
2865     }
2866   else
2867     {
2868       _dbus_warn ("Did not expect to successfully activate segfault service\n");
2869       goto out;
2870     }
2871
2872   retval = TRUE;
2873
2874  out:
2875   if (message)
2876     dbus_message_unref (message);
2877
2878   return retval;
2879 }
2880 #endif
2881
2882 #define TEST_ECHO_MESSAGE "Test echo message"
2883 #define TEST_RUN_HELLO_FROM_SELF_MESSAGE "Test sending message to self"
2884
2885 /* returns TRUE if the correct thing happens,
2886  * but the correct thing may include OOM errors.
2887  */
2888 static dbus_bool_t
2889 check_existent_hello_from_self (BusContext     *context,
2890                                 DBusConnection *connection)
2891 {
2892   DBusMessage *message;
2893   dbus_uint32_t serial;
2894   const char *text;
2895
2896   message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME,
2897                                           "/org/freedesktop/TestSuite",
2898                                           "org.freedesktop.TestSuite",
2899                                           "RunHelloFromSelf");
2900
2901   if (message == NULL)
2902     return TRUE;
2903
2904   text = TEST_RUN_HELLO_FROM_SELF_MESSAGE;
2905   if (!dbus_message_append_args (message,
2906                                  DBUS_TYPE_STRING, &text,
2907                                  DBUS_TYPE_INVALID))
2908     {
2909       dbus_message_unref (message);
2910       return TRUE;
2911     }
2912
2913   if (!dbus_connection_send (connection, message, &serial))
2914     {
2915       dbus_message_unref (message);
2916       return TRUE;
2917     }
2918
2919   dbus_message_unref (message);
2920   message = NULL;
2921
2922   bus_test_run_everything (context);
2923
2924   /* Note: if this test is run in OOM mode, it will block when the bus
2925    * doesn't send a reply due to OOM.
2926    */
2927   block_connection_until_message_from_bus (context, connection, "reply from running hello from self");
2928
2929   message = pop_message_waiting_for_memory (connection);
2930   if (message == NULL)
2931     {
2932       _dbus_warn ("Failed to pop message! Should have been reply from RunHelloFromSelf message\n");
2933       return FALSE;
2934     }
2935
2936   if (dbus_message_get_reply_serial (message) != serial)
2937     {
2938       _dbus_warn ("Wrong reply serial\n");
2939       dbus_message_unref (message);
2940       return FALSE;
2941     }
2942
2943   dbus_message_unref (message);
2944   message = NULL;
2945
2946   return TRUE;
2947 }
2948
2949 /* returns TRUE if the correct thing happens,
2950  * but the correct thing may include OOM errors.
2951  */
2952 static dbus_bool_t
2953 check_existent_ping (BusContext     *context,
2954                      DBusConnection *connection)
2955 {
2956   DBusMessage *message;
2957   dbus_uint32_t serial;
2958   message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME,
2959                                           "/org/freedesktop/TestSuite",
2960                                           "org.freedesktop.DBus.Peer",
2961                                           "Ping");
2962
2963   if (message == NULL)
2964     return TRUE;
2965
2966   if (!dbus_connection_send (connection, message, &serial))
2967     {
2968       dbus_message_unref (message);
2969       return TRUE;
2970     }
2971
2972   dbus_message_unref (message);
2973   message = NULL;
2974
2975   bus_test_run_everything (context);
2976
2977   /* Note: if this test is run in OOM mode, it will block when the bus
2978    * doesn't send a reply due to OOM.
2979    */
2980   block_connection_until_message_from_bus (context, connection, "reply from running Ping");
2981
2982   message = pop_message_waiting_for_memory (connection);
2983   if (message == NULL)
2984     {
2985       _dbus_warn ("Failed to pop message! Should have been reply from Ping message\n");
2986       return FALSE;
2987     }
2988
2989   if (dbus_message_get_reply_serial (message) != serial)
2990     {
2991       _dbus_warn ("Wrong reply serial\n");
2992       dbus_message_unref (message);
2993       return FALSE;
2994     }
2995
2996   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN)
2997     {
2998       _dbus_warn ("Unexpected message return during Ping\n");
2999       dbus_message_unref (message);
3000       return FALSE;
3001     }
3002
3003   dbus_message_unref (message);
3004   message = NULL;
3005
3006   return TRUE;
3007 }
3008
3009 /* returns TRUE if the correct thing happens,
3010  * but the correct thing may include OOM errors.
3011  */
3012 static dbus_bool_t
3013 check_existent_get_machine_id (BusContext     *context,
3014                                DBusConnection *connection)
3015 {
3016   DBusMessage *message;
3017   dbus_uint32_t serial;
3018   const char *machine_id;
3019
3020   message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME,
3021                                           "/org/freedesktop/TestSuite",
3022                                           "org.freedesktop.DBus.Peer",
3023                                           "GetMachineId");
3024
3025   if (message == NULL)
3026     return TRUE;
3027
3028   if (!dbus_connection_send (connection, message, &serial))
3029     {
3030       dbus_message_unref (message);
3031       return TRUE;
3032     }
3033
3034   dbus_message_unref (message);
3035   message = NULL;
3036
3037   bus_test_run_everything (context);
3038
3039   /* Note: if this test is run in OOM mode, it will block when the bus
3040    * doesn't send a reply due to OOM.
3041    */
3042   block_connection_until_message_from_bus (context, connection, "reply from running GetMachineId");
3043
3044   message = pop_message_waiting_for_memory (connection);
3045   if (message == NULL)
3046     {
3047       _dbus_warn ("Failed to pop message! Should have been reply from GetMachineId message\n");
3048       return FALSE;
3049     }
3050
3051   if (dbus_message_get_reply_serial (message) != serial)
3052     {
3053       _dbus_warn ("Wrong reply serial\n");
3054       dbus_message_unref (message);
3055       return FALSE;
3056     }
3057
3058   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN)
3059     {
3060       _dbus_warn ("Unexpected message return during GetMachineId\n");
3061       dbus_message_unref (message);
3062       return FALSE;
3063     }
3064
3065   machine_id = NULL;
3066   if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &machine_id, DBUS_TYPE_INVALID))
3067     {
3068       _dbus_warn ("Did not get a machine ID in reply to GetMachineId\n");
3069       dbus_message_unref (message);
3070       return FALSE;
3071     }
3072
3073   if (machine_id == NULL || strlen (machine_id) != 32)
3074     {
3075       _dbus_warn ("Machine id looks bogus: '%s'\n", machine_id ? machine_id : "null");
3076       dbus_message_unref (message);
3077       return FALSE;
3078     }
3079
3080   /* We can't check that the machine id is correct because during make check it is
3081    * just made up for each process separately
3082    */
3083
3084   dbus_message_unref (message);
3085   message = NULL;
3086
3087   return TRUE;
3088 }
3089
3090 /* returns TRUE if the correct thing happens,
3091  * but the correct thing may include OOM errors.
3092  */
3093 static dbus_bool_t
3094 check_existent_service_auto_start (BusContext     *context,
3095                                    DBusConnection *connection)
3096 {
3097   DBusMessage *message;
3098   DBusMessage *base_service_message;
3099   dbus_uint32_t serial;
3100   dbus_bool_t retval;
3101   const char *base_service;
3102   const char *text;
3103
3104   base_service_message = NULL;
3105
3106   message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME,
3107                                           "/org/freedesktop/TestSuite",
3108                                           "org.freedesktop.TestSuite",
3109                                           "Echo");
3110
3111   if (message == NULL)
3112     return TRUE;
3113
3114   text = TEST_ECHO_MESSAGE;
3115   if (!dbus_message_append_args (message,
3116                                  DBUS_TYPE_STRING, &text,
3117                                  DBUS_TYPE_INVALID))
3118     {
3119       dbus_message_unref (message);
3120       return TRUE;
3121     }
3122
3123   if (!dbus_connection_send (connection, message, &serial))
3124     {
3125       dbus_message_unref (message);
3126       return TRUE;
3127     }
3128
3129   dbus_message_unref (message);
3130   message = NULL;
3131
3132   bus_test_run_everything (context);
3133
3134   /* now wait for the message bus to hear back from the activated
3135    * service.
3136    */
3137   block_connection_until_message_from_bus (context, connection, "reply to Echo on existent service");
3138   bus_test_run_everything (context);
3139
3140   if (!dbus_connection_get_is_connected (connection))
3141     {
3142       _dbus_verbose ("connection was disconnected\n");
3143       return TRUE;
3144     }
3145
3146   retval = FALSE;
3147
3148   message = pop_message_waiting_for_memory (connection);
3149   if (message == NULL)
3150     {
3151       _dbus_warn ("Did not receive any messages after auto start %d on %p\n",
3152                   serial, connection);
3153       goto out;
3154     }
3155
3156   verbose_message_received (connection, message);
3157   _dbus_verbose ("  (after sending %s)\n", "auto start");
3158
3159   /* we should get zero or two ServiceOwnerChanged signals */
3160   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_SIGNAL)
3161     {
3162       GotServiceInfo message_kind;
3163
3164       if (!check_base_service_activated (context, connection,
3165                                          message, &base_service))
3166         goto out;
3167
3168       base_service_message = message;
3169       message = NULL;
3170
3171       /* We may need to block here for the test service to exit or finish up */
3172       block_connection_until_message_from_bus (context, connection, "service to exit");
3173
3174       /* Should get a service creation notification for the activated
3175        * service name, or a service deletion on the base service name
3176        */
3177       message = dbus_connection_borrow_message (connection);
3178       if (message == NULL)
3179         {
3180           _dbus_warn ("No message after auto activation "
3181                       "(should be a service announcement)\n");
3182           dbus_connection_return_message (connection, message);
3183           message = NULL;
3184           goto out;
3185         }
3186
3187       message_kind = check_got_service_info (message);
3188
3189       dbus_connection_return_message (connection, message);
3190       message = NULL;
3191
3192       switch (message_kind)
3193         {
3194         case GOT_SERVICE_CREATED:
3195           message = pop_message_waiting_for_memory (connection);
3196           if (message == NULL)
3197             {
3198               _dbus_warn ("Failed to pop message we just put back! "
3199                           "should have been a NameOwnerChanged (creation)\n");
3200               goto out;
3201             }
3202
3203           /* Check that ServiceOwnerChanged (creation) was correctly received */
3204           if (!check_service_auto_activated (context, connection, EXISTENT_SERVICE_NAME,
3205                                              base_service, message))
3206             goto out;
3207
3208           dbus_message_unref (message);
3209           message = NULL;
3210
3211           break;
3212
3213         case GOT_SERVICE_DELETED:
3214           {
3215             /* The service started up and got a base address, but then
3216              * failed to register under EXISTENT_SERVICE_NAME
3217              */
3218             CheckServiceOwnerChangedData socd;
3219
3220             socd.expected_kind = SERVICE_DELETED;
3221             socd.expected_service_name = base_service;
3222             socd.failed = FALSE;
3223             socd.skip_connection = NULL;
3224             bus_test_clients_foreach (check_service_owner_changed_foreach,
3225                                       &socd);
3226
3227             if (socd.failed)
3228               goto out;
3229
3230             break;
3231           }
3232
3233         case GOT_ERROR:
3234         case GOT_SOMETHING_ELSE:
3235           _dbus_warn ("Unexpected message after auto activation\n");
3236           goto out;
3237         }
3238     }
3239
3240   /* OK, now we've dealt with ServiceOwnerChanged signals, now should
3241    * come the method reply (or error) from the initial method call
3242    */
3243
3244   /* Note: if this test is run in OOM mode, it will block when the bus
3245    * doesn't send a reply due to OOM.
3246    */
3247   block_connection_until_message_from_bus (context, connection, "reply from echo message after auto-activation");
3248
3249   message = pop_message_waiting_for_memory (connection);
3250   if (message == NULL)
3251     {
3252       _dbus_warn ("Failed to pop message! Should have been reply from echo message\n");
3253       goto out;
3254     }
3255
3256   if (dbus_message_get_reply_serial (message) != serial)
3257     {
3258       _dbus_warn ("Wrong reply serial\n");
3259       goto out;
3260     }
3261
3262   dbus_message_unref (message);
3263   message = NULL;
3264
3265   if (!check_existent_ping (context, connection))
3266     goto out;
3267
3268   if (!check_existent_get_machine_id (context, connection))
3269     goto out;
3270
3271   if (!check_existent_hello_from_self (context, connection))
3272     goto out;
3273
3274   if (!check_send_exit_to_service (context, connection,
3275                                    EXISTENT_SERVICE_NAME,
3276                                    base_service))
3277     goto out;
3278
3279   retval = TRUE;
3280
3281  out:
3282   if (message)
3283     dbus_message_unref (message);
3284
3285   if (base_service_message)
3286     dbus_message_unref (base_service_message);
3287
3288   return retval;
3289 }
3290
3291 #define SERVICE_FILE_MISSING_NAME "org.freedesktop.DBus.TestSuiteEchoServiceDotServiceFileDoesNotExist"
3292
3293 /* returns TRUE if the correct thing happens,
3294  * but the correct thing may include OOM errors.
3295  */
3296 static dbus_bool_t
3297 check_launch_service_file_missing (BusContext     *context,
3298                                    DBusConnection *connection)
3299 {
3300   DBusMessage *message;
3301   dbus_uint32_t serial;
3302   dbus_bool_t retval;
3303
3304   message = dbus_message_new_method_call (SERVICE_FILE_MISSING_NAME,
3305                                           "/org/freedesktop/TestSuite",
3306                                           "org.freedesktop.TestSuite",
3307                                           "Echo");
3308
3309   if (message == NULL)
3310     return TRUE;
3311
3312   if (!dbus_connection_send (connection, message, &serial))
3313     {
3314       dbus_message_unref (message);
3315       return TRUE;
3316     }
3317
3318   dbus_message_unref (message);
3319   message = NULL;
3320
3321   bus_test_run_everything (context);
3322   block_connection_until_message_from_bus (context, connection, "reply to service file missing should fail to auto-start");
3323   bus_test_run_everything (context);
3324
3325   if (!dbus_connection_get_is_connected (connection))
3326     {
3327       _dbus_verbose ("connection was disconnected\n");
3328       return TRUE;
3329     }
3330
3331   retval = FALSE;
3332
3333   message = pop_message_waiting_for_memory (connection);
3334   if (message == NULL)
3335     {
3336       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
3337                   "Echo message (auto activation)", serial, connection);
3338       goto out;
3339     }
3340
3341   verbose_message_received (connection, message);
3342
3343   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
3344     {
3345       if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
3346         {
3347           _dbus_warn ("Message has wrong sender %s\n",
3348                       dbus_message_get_sender (message) ?
3349                       dbus_message_get_sender (message) : "(none)");
3350           goto out;
3351         }
3352
3353       if (dbus_message_is_error (message,
3354                                  DBUS_ERROR_NO_MEMORY))
3355         {
3356           ; /* good, this is a valid response */
3357         }
3358       else if (dbus_message_is_error (message,
3359                                       DBUS_ERROR_SERVICE_UNKNOWN))
3360         {
3361           _dbus_verbose("got service unknown\n");
3362           ; /* good, this is expected (only valid when using launch helper) */
3363         }
3364       else
3365         {
3366           warn_unexpected (connection, message, "not this error");
3367
3368           goto out;
3369         }
3370     }
3371   else
3372     {
3373       _dbus_warn ("Did not expect to successfully auto-start missing service\n");
3374       goto out;
3375     }
3376
3377   retval = TRUE;
3378
3379  out:
3380   if (message)
3381     dbus_message_unref (message);
3382
3383   return retval;
3384 }
3385
3386 #define SERVICE_USER_MISSING_NAME "org.freedesktop.DBus.TestSuiteNoUser"
3387
3388 /* returns TRUE if the correct thing happens,
3389  * but the correct thing may include OOM errors.
3390  */
3391 static dbus_bool_t
3392 check_launch_service_user_missing (BusContext     *context,
3393                                    DBusConnection *connection)
3394 {
3395   DBusMessage *message;
3396   dbus_uint32_t serial;
3397   dbus_bool_t retval;
3398
3399   message = dbus_message_new_method_call (SERVICE_USER_MISSING_NAME,
3400                                           "/org/freedesktop/TestSuite",
3401                                           "org.freedesktop.TestSuite",
3402                                           "Echo");
3403
3404   if (message == NULL)
3405     return TRUE;
3406
3407   if (!dbus_connection_send (connection, message, &serial))
3408     {
3409       dbus_message_unref (message);
3410       return TRUE;
3411     }
3412
3413   dbus_message_unref (message);
3414   message = NULL;
3415
3416   bus_test_run_everything (context);
3417   block_connection_until_message_from_bus (context, connection,
3418                                            "reply to service which should fail to auto-start (missing User)");
3419   bus_test_run_everything (context);
3420
3421   if (!dbus_connection_get_is_connected (connection))
3422     {
3423       _dbus_warn ("connection was disconnected\n");
3424       return TRUE;
3425     }
3426
3427   retval = FALSE;
3428
3429   message = pop_message_waiting_for_memory (connection);
3430   if (message == NULL)
3431     {
3432       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
3433                   "Echo message (auto activation)", serial, connection);
3434       goto out;
3435     }
3436
3437   verbose_message_received (connection, message);
3438
3439   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
3440     {
3441       if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
3442         {
3443           _dbus_warn ("Message has wrong sender %s\n",
3444                       dbus_message_get_sender (message) ?
3445                       dbus_message_get_sender (message) : "(none)");
3446           goto out;
3447         }
3448
3449       if (dbus_message_is_error (message,
3450                                  DBUS_ERROR_NO_MEMORY))
3451         {
3452           ; /* good, this is a valid response */
3453         }
3454       else if (dbus_message_is_error (message,
3455                                       DBUS_ERROR_SPAWN_FILE_INVALID))
3456         {
3457           _dbus_verbose("got service file invalid\n");
3458           ; /* good, this is expected (only valid when using launch helper) */
3459         }
3460       else
3461         {
3462           warn_unexpected (connection, message, "not this error");
3463
3464           goto out;
3465         }
3466     }
3467   else
3468     {
3469       _dbus_warn ("Did not expect to successfully auto-start missing service\n");
3470       goto out;
3471     }
3472
3473   retval = TRUE;
3474
3475  out:
3476   if (message)
3477     dbus_message_unref (message);
3478
3479   return retval;
3480 }
3481
3482 #define SERVICE_EXEC_MISSING_NAME "org.freedesktop.DBus.TestSuiteNoExec"
3483
3484 /* returns TRUE if the correct thing happens,
3485  * but the correct thing may include OOM errors.
3486  */
3487 static dbus_bool_t
3488 check_launch_service_exec_missing (BusContext     *context,
3489                                    DBusConnection *connection)
3490 {
3491   DBusMessage *message;
3492   dbus_uint32_t serial;
3493   dbus_bool_t retval;
3494
3495   message = dbus_message_new_method_call (SERVICE_EXEC_MISSING_NAME,
3496                                           "/org/freedesktop/TestSuite",
3497                                           "org.freedesktop.TestSuite",
3498                                           "Echo");
3499
3500   if (message == NULL)
3501     return TRUE;
3502
3503   if (!dbus_connection_send (connection, message, &serial))
3504     {
3505       dbus_message_unref (message);
3506       return TRUE;
3507     }
3508
3509   dbus_message_unref (message);
3510   message = NULL;
3511
3512   bus_test_run_everything (context);
3513   block_connection_until_message_from_bus (context, connection,
3514                                            "reply to service which should fail to auto-start (missing Exec)");
3515   bus_test_run_everything (context);
3516
3517   if (!dbus_connection_get_is_connected (connection))
3518     {
3519       _dbus_warn ("connection was disconnected\n");
3520       return TRUE;
3521     }
3522
3523   retval = FALSE;
3524
3525   message = pop_message_waiting_for_memory (connection);
3526   if (message == NULL)
3527     {
3528       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
3529                   "Echo message (auto activation)", serial, connection);
3530       goto out;
3531     }
3532
3533   verbose_message_received (connection, message);
3534
3535   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
3536     {
3537       if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
3538         {
3539           _dbus_warn ("Message has wrong sender %s\n",
3540                       dbus_message_get_sender (message) ?
3541                       dbus_message_get_sender (message) : "(none)");
3542           goto out;
3543         }
3544
3545       if (dbus_message_is_error (message,
3546                                  DBUS_ERROR_NO_MEMORY))
3547         {
3548           ; /* good, this is a valid response */
3549         }
3550       else if (dbus_message_is_error (message,
3551                                       DBUS_ERROR_SERVICE_UNKNOWN))
3552         {
3553           _dbus_verbose("could not activate as invalid service file was not added\n");
3554           ; /* good, this is expected as we shouldn't have been added to
3555              * the activation list with a missing Exec key */
3556         }
3557       else if (dbus_message_is_error (message,
3558                                       DBUS_ERROR_SPAWN_FILE_INVALID))
3559         {
3560           _dbus_verbose("got service file invalid\n");
3561           ; /* good, this is allowed, and is the message passed back from the
3562              * launch helper */
3563         }
3564       else
3565         {
3566           warn_unexpected (connection, message, "not this error");
3567
3568           goto out;
3569         }
3570     }
3571   else
3572     {
3573       _dbus_warn ("Did not expect to successfully auto-start missing service\n");
3574       goto out;
3575     }
3576
3577   retval = TRUE;
3578
3579  out:
3580   if (message)
3581     dbus_message_unref (message);
3582
3583   return retval;
3584 }
3585
3586 #define SERVICE_SERVICE_MISSING_NAME "org.freedesktop.DBus.TestSuiteNoService"
3587
3588 /* returns TRUE if the correct thing happens,
3589  * but the correct thing may include OOM errors.
3590  */
3591 static dbus_bool_t
3592 check_launch_service_service_missing (BusContext     *context,
3593                                       DBusConnection *connection)
3594 {
3595   DBusMessage *message;
3596   dbus_uint32_t serial;
3597   dbus_bool_t retval;
3598
3599   message = dbus_message_new_method_call (SERVICE_SERVICE_MISSING_NAME,
3600                                           "/org/freedesktop/TestSuite",
3601                                           "org.freedesktop.TestSuite",
3602                                           "Echo");
3603
3604   if (message == NULL)
3605     return TRUE;
3606
3607   if (!dbus_connection_send (connection, message, &serial))
3608     {
3609       dbus_message_unref (message);
3610       return TRUE;
3611     }
3612
3613   dbus_message_unref (message);
3614   message = NULL;
3615
3616   bus_test_run_everything (context);
3617   block_connection_until_message_from_bus (context, connection,
3618                                            "reply to service which should fail to auto-start (missing Service)");
3619   bus_test_run_everything (context);
3620
3621   if (!dbus_connection_get_is_connected (connection))
3622     {
3623       _dbus_warn ("connection was disconnected\n");
3624       return TRUE;
3625     }
3626
3627   retval = FALSE;
3628
3629   message = pop_message_waiting_for_memory (connection);
3630   if (message == NULL)
3631     {
3632       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
3633                   "Echo message (auto activation)", serial, connection);
3634       goto out;
3635     }
3636
3637   verbose_message_received (connection, message);
3638
3639   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
3640     {
3641       if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
3642         {
3643           _dbus_warn ("Message has wrong sender %s\n",
3644                       dbus_message_get_sender (message) ?
3645                       dbus_message_get_sender (message) : "(none)");
3646           goto out;
3647         }
3648
3649       if (dbus_message_is_error (message,
3650                                  DBUS_ERROR_NO_MEMORY))
3651         {
3652           ; /* good, this is a valid response */
3653         }
3654       else if (dbus_message_is_error (message,
3655                                       DBUS_ERROR_SERVICE_UNKNOWN))
3656         {
3657           _dbus_verbose("could not activate as invalid service file was not added\n");
3658           ; /* good, this is expected as we shouldn't have been added to
3659              * the activation list with a missing Exec key */
3660         }
3661       else if (dbus_message_is_error (message,
3662                                       DBUS_ERROR_SPAWN_FILE_INVALID))
3663         {
3664           _dbus_verbose("got service file invalid\n");
3665           ; /* good, this is allowed, and is the message passed back from the
3666              * launch helper */
3667         }
3668       else
3669         {
3670           warn_unexpected (connection, message, "not this error");
3671
3672           goto out;
3673         }
3674     }
3675   else
3676     {
3677       _dbus_warn ("Did not expect to successfully auto-start missing service\n");
3678       goto out;
3679     }
3680
3681   retval = TRUE;
3682
3683  out:
3684   if (message)
3685     dbus_message_unref (message);
3686
3687   return retval;
3688 }
3689
3690 #define SHELL_FAIL_SERVICE_NAME "org.freedesktop.DBus.TestSuiteShellEchoServiceFail"
3691
3692 /* returns TRUE if the correct thing happens,
3693  * but the correct thing may include OOM errors.
3694  */
3695 static dbus_bool_t
3696 check_shell_fail_service_auto_start (BusContext     *context,
3697                                      DBusConnection *connection)
3698 {
3699   DBusMessage *message;
3700   dbus_uint32_t serial;
3701   dbus_bool_t retval;
3702
3703   message = dbus_message_new_method_call (SHELL_FAIL_SERVICE_NAME,
3704                                           "/org/freedesktop/TestSuite",
3705                                           "org.freedesktop.TestSuite",
3706                                           "Echo");
3707
3708   if (message == NULL)
3709     return TRUE;
3710
3711   if (!dbus_connection_send (connection, message, &serial))
3712     {
3713       dbus_message_unref (message);
3714       return TRUE;
3715     }
3716
3717   dbus_message_unref (message);
3718   message = NULL;
3719
3720   bus_test_run_everything (context);
3721   block_connection_until_message_from_bus (context, connection, "reply to shell Echo on service which should fail to auto-start");
3722   bus_test_run_everything (context);
3723
3724   if (!dbus_connection_get_is_connected (connection))
3725     {
3726       _dbus_verbose ("connection was disconnected\n");
3727       return TRUE;
3728     }
3729
3730   retval = FALSE;
3731
3732   message = pop_message_waiting_for_memory (connection);
3733   if (message == NULL)
3734     {
3735       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
3736                   "Echo message (auto activation)", serial, connection);
3737       goto out;
3738     }
3739
3740   verbose_message_received (connection, message);
3741
3742   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
3743     {
3744       if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
3745         {
3746           _dbus_warn ("Message has wrong sender %s\n",
3747                       dbus_message_get_sender (message) ?
3748                       dbus_message_get_sender (message) : "(none)");
3749           goto out;
3750         }
3751
3752       if (dbus_message_is_error (message,
3753                                  DBUS_ERROR_NO_MEMORY))
3754         {
3755           ; /* good, this is a valid response */
3756         }
3757       else if (dbus_message_is_error (message,
3758                                       DBUS_ERROR_INVALID_ARGS))
3759         {
3760           _dbus_verbose("got invalid args\n");
3761           ; /* good, this is expected also */
3762         }
3763       else
3764         {
3765           warn_unexpected (connection, message, "not this error");
3766
3767           goto out;
3768         }
3769     }
3770   else
3771     {
3772       _dbus_warn ("Did not expect to successfully auto-start shell fail service\n");
3773       goto out;
3774     }
3775
3776   retval = TRUE;
3777
3778  out:
3779   if (message)
3780     dbus_message_unref (message);
3781
3782   return retval;
3783 }
3784
3785 #define SHELL_SUCCESS_SERVICE_NAME "org.freedesktop.DBus.TestSuiteShellEchoServiceSuccess"
3786
3787 /* returns TRUE if the correct thing happens,
3788  * but the correct thing may include OOM errors.
3789  */
3790 static dbus_bool_t
3791 check_shell_service_success_auto_start (BusContext     *context,
3792                                         DBusConnection *connection)
3793 {
3794   DBusMessage *message;
3795   DBusMessage *base_service_message;
3796   dbus_uint32_t serial;
3797   dbus_bool_t retval;
3798   const char *base_service;
3799   const char *argv[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
3800
3801   base_service_message = NULL;
3802
3803   message = dbus_message_new_method_call (SHELL_SUCCESS_SERVICE_NAME,
3804                                           "/org/freedesktop/TestSuite",
3805                                           "org.freedesktop.TestSuite",
3806                                           "Echo");
3807
3808   if (message == NULL)
3809     return TRUE;
3810
3811   if (!dbus_connection_send (connection, message, &serial))
3812     {
3813       dbus_message_unref (message);
3814       return TRUE;
3815     }
3816
3817   dbus_message_unref (message);
3818   message = NULL;
3819
3820   bus_test_run_everything (context);
3821
3822   /* now wait for the message bus to hear back from the activated
3823    * service.
3824    */
3825   block_connection_until_message_from_bus (context, connection, "reply to Echo on shell success service");
3826   bus_test_run_everything (context);
3827
3828   if (!dbus_connection_get_is_connected (connection))
3829     {
3830       _dbus_verbose ("connection was disconnected\n");
3831       return TRUE;
3832     }
3833
3834   retval = FALSE;
3835
3836   message = pop_message_waiting_for_memory (connection);
3837   if (message == NULL)
3838     {
3839       _dbus_warn ("Did not receive any messages after auto start %d on %p\n",
3840                   serial, connection);
3841       goto out;
3842     }
3843
3844   verbose_message_received (connection, message);
3845   _dbus_verbose ("  (after sending %s)\n", "auto start");
3846
3847   /* we should get zero or two ServiceOwnerChanged signals */
3848   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_SIGNAL)
3849     {
3850       GotServiceInfo message_kind;
3851
3852       if (!check_base_service_activated (context, connection,
3853                                          message, &base_service))
3854         goto out;
3855
3856       base_service_message = message;
3857       message = NULL;
3858
3859       /* We may need to block here for the test service to exit or finish up */
3860       block_connection_until_message_from_bus (context, connection, "service to exit");
3861
3862       /* Should get a service creation notification for the activated
3863        * service name, or a service deletion on the base service name
3864        */
3865       message = dbus_connection_borrow_message (connection);
3866       if (message == NULL)
3867         {
3868           _dbus_warn ("No message after auto activation "
3869                       "(should be a service announcement)\n");
3870           dbus_connection_return_message (connection, message);
3871           message = NULL;
3872           goto out;
3873         }
3874
3875       message_kind = check_got_service_info (message);
3876
3877       dbus_connection_return_message (connection, message);
3878       message = NULL;
3879
3880       switch (message_kind)
3881         {
3882         case GOT_SERVICE_CREATED:
3883           message = pop_message_waiting_for_memory (connection);
3884           if (message == NULL)
3885             {
3886               _dbus_warn ("Failed to pop message we just put back! "
3887                           "should have been a NameOwnerChanged (creation)\n");
3888               goto out;
3889             }
3890
3891           /* Check that ServiceOwnerChanged (creation) was correctly received */
3892           if (!check_service_auto_activated (context, connection, SHELL_SUCCESS_SERVICE_NAME,
3893                                              base_service, message))
3894             goto out;
3895
3896           dbus_message_unref (message);
3897           message = NULL;
3898
3899           break;
3900
3901         case GOT_SERVICE_DELETED:
3902           {
3903             /* The service started up and got a base address, but then
3904              * failed to register under SHELL_SUCCESS_SERVICE_NAME
3905              */
3906             CheckServiceOwnerChangedData socd;
3907
3908             socd.expected_kind = SERVICE_DELETED;
3909             socd.expected_service_name = base_service;
3910             socd.failed = FALSE;
3911             socd.skip_connection = NULL;
3912             bus_test_clients_foreach (check_service_owner_changed_foreach,
3913                                       &socd);
3914
3915             if (socd.failed)
3916               goto out;
3917
3918             break;
3919           }
3920
3921         case GOT_ERROR:
3922         case GOT_SOMETHING_ELSE:
3923           _dbus_warn ("Unexpected message after auto activation\n");
3924           goto out;
3925         }
3926     }
3927
3928   /* OK, now we've dealt with ServiceOwnerChanged signals, now should
3929    * come the method reply (or error) from the initial method call
3930    */
3931
3932   /* Note: if this test is run in OOM mode, it will block when the bus
3933    * doesn't send a reply due to OOM.
3934    */
3935   block_connection_until_message_from_bus (context, connection, "reply from echo message after auto-activation");
3936
3937   message = pop_message_waiting_for_memory (connection);
3938   if (message == NULL)
3939     {
3940       _dbus_warn ("Failed to pop message! Should have been reply from echo message\n");
3941       goto out;
3942     }
3943
3944   if (dbus_message_get_reply_serial (message) != serial)
3945     {
3946       _dbus_warn ("Wrong reply serial\n");
3947       goto out;
3948     }
3949
3950   if (!dbus_message_get_args (message, NULL,
3951                                        DBUS_TYPE_STRING, &argv[0],
3952                                        DBUS_TYPE_STRING, &argv[1],
3953                                        DBUS_TYPE_STRING, &argv[2],
3954                                        DBUS_TYPE_STRING, &argv[3],
3955                                        DBUS_TYPE_STRING, &argv[4],
3956                                        DBUS_TYPE_STRING, &argv[5],
3957                                        DBUS_TYPE_STRING, &argv[6],
3958                                        DBUS_TYPE_INVALID))
3959     {
3960       _dbus_warn ("Error getting arguments from return\n");
3961       goto out;
3962     }
3963
3964    /* don't worry about arg[0] as it may be different
3965       depending on the path to the tests
3966    */
3967   if (strcmp("-test", argv[1]) != 0)
3968     {
3969       _dbus_warn ("Unexpected argv[1] in shell success service test (expected: %s, got: %s)\n",
3970                   "-test", argv[1]);
3971       goto out;
3972     }
3973
3974   if (strcmp("that", argv[2]) != 0)
3975     {
3976       _dbus_warn ("Unexpected argv[2] in shell success service test (expected: %s, got: %s)\n",
3977                    "that", argv[2]);
3978       goto out;
3979     }
3980
3981   if (strcmp("we get", argv[3]) != 0)
3982     {
3983       _dbus_warn ("Unexpected argv[3] in shell success service test (expected: %s, got: %s)\n",
3984                    "we get", argv[3]);
3985       goto out;
3986     }
3987
3988   if (strcmp("back", argv[4]) != 0)
3989     {
3990       _dbus_warn ("Unexpected argv[4] in shell success service test (expected: %s, got: %s)\n",
3991                    "back", argv[4]);
3992       goto out;
3993     }
3994
3995   if (strcmp("--what", argv[5]) != 0)
3996     {
3997       _dbus_warn ("Unexpected argv[5] in shell success service test (expected: %s, got: %s)\n",
3998                    "--what", argv[5]);
3999       goto out;
4000     }
4001
4002   if (strcmp("we put in", argv[6]) != 0)
4003     {
4004       _dbus_warn ("Unexpected argv[6] in shell success service test (expected: %s, got: %s)\n",
4005                    "we put in", argv[6]);
4006       goto out;
4007     }
4008
4009   dbus_message_unref (message);
4010   message = NULL;
4011
4012   if (!check_send_exit_to_service (context, connection,
4013                                    SHELL_SUCCESS_SERVICE_NAME,
4014                                    base_service))
4015     goto out;
4016
4017   retval = TRUE;
4018
4019  out:
4020   if (message)
4021     dbus_message_unref (message);
4022
4023   if (base_service_message)
4024     dbus_message_unref (base_service_message);
4025
4026   return retval;
4027 }
4028
4029 typedef struct
4030 {
4031   Check1Func func;
4032   BusContext *context;
4033 } Check1Data;
4034
4035 static dbus_bool_t
4036 check_oom_check1_func (void *data)
4037 {
4038   Check1Data *d = data;
4039
4040   if (! (* d->func) (d->context))
4041     return FALSE;
4042
4043   if (!check_no_leftovers (d->context))
4044     {
4045       _dbus_warn ("Messages were left over, should be covered by test suite\n");
4046       return FALSE;
4047     }
4048
4049   return TRUE;
4050 }
4051
4052 static void
4053 check1_try_iterations (BusContext *context,
4054                        const char *description,
4055                        Check1Func  func)
4056 {
4057   Check1Data d;
4058
4059   d.func = func;
4060   d.context = context;
4061
4062   if (!_dbus_test_oom_handling (description, check_oom_check1_func,
4063                                 &d))
4064     _dbus_assert_not_reached ("test failed");
4065 }
4066
4067 static dbus_bool_t
4068 check_get_services (BusContext     *context,
4069                     DBusConnection *connection,
4070                     const char     *method,
4071                     char         ***services,
4072                     int            *len)
4073 {
4074   DBusMessage *message;
4075   dbus_uint32_t serial;
4076   dbus_bool_t retval;
4077   DBusError error;
4078   char **srvs;
4079   int l;
4080
4081   retval = FALSE;
4082   dbus_error_init (&error);
4083   message = NULL;
4084
4085   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
4086                                           DBUS_PATH_DBUS,
4087                                           DBUS_INTERFACE_DBUS,
4088                                           method);
4089
4090   if (message == NULL)
4091     return TRUE;
4092
4093   if (!dbus_connection_send (connection, message, &serial))
4094     {
4095       dbus_message_unref (message);
4096       return TRUE;
4097     }
4098
4099   /* send our message */
4100   bus_test_run_clients_loop (SEND_PENDING (connection));
4101
4102   dbus_message_unref (message);
4103   message = NULL;
4104
4105   dbus_connection_ref (connection); /* because we may get disconnected */
4106   block_connection_until_message_from_bus (context, connection, "reply to ListActivatableNames/ListNames");
4107
4108   if (!dbus_connection_get_is_connected (connection))
4109     {
4110       _dbus_verbose ("connection was disconnected\n");
4111
4112       dbus_connection_unref (connection);
4113
4114       return TRUE;
4115     }
4116
4117   dbus_connection_unref (connection);
4118
4119   message = pop_message_waiting_for_memory (connection);
4120   if (message == NULL)
4121     {
4122       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
4123                   method, serial, connection);
4124       goto out;
4125     }
4126
4127   verbose_message_received (connection, message);
4128
4129   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
4130     {
4131       if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY))
4132         {
4133           ; /* good, this is a valid response */
4134         }
4135       else
4136         {
4137           warn_unexpected (connection, message, "not this error");
4138
4139           goto out;
4140         }
4141     }
4142   else
4143     {
4144       if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
4145         {
4146           ; /* good, expected */
4147         }
4148       else
4149         {
4150           warn_unexpected (connection, message,
4151                            "method_return for ListActivatableNames/ListNames");
4152
4153           goto out;
4154         }
4155
4156     retry_get_property:
4157
4158       if (!dbus_message_get_args (message, &error,
4159                                   DBUS_TYPE_ARRAY,
4160                                   DBUS_TYPE_STRING,
4161                                   &srvs, &l,
4162                                   DBUS_TYPE_INVALID))
4163         {
4164           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
4165             {
4166               _dbus_verbose ("no memory to list services by %s\n", method);
4167               dbus_error_free (&error);
4168               _dbus_wait_for_memory ();
4169               goto retry_get_property;
4170             }
4171           else
4172             {
4173               _dbus_assert (dbus_error_is_set (&error));
4174               _dbus_warn ("Did not get the expected DBUS_TYPE_ARRAY from %s\n", method);
4175               goto out;
4176             }
4177         } else {
4178           *services = srvs;
4179           *len = l;
4180         }
4181     }
4182
4183   if (!check_no_leftovers (context))
4184     goto out;
4185
4186   retval = TRUE;
4187
4188  out:
4189   dbus_error_free (&error);
4190
4191   if (message)
4192     dbus_message_unref (message);
4193
4194   return retval;
4195 }
4196
4197 /* returns TRUE if the correct thing happens,
4198  * but the correct thing may include OOM errors.
4199  */
4200 static dbus_bool_t
4201 check_list_services (BusContext     *context,
4202                      DBusConnection *connection)
4203 {
4204   DBusMessage  *message;
4205   DBusMessage  *base_service_message;
4206   const char   *base_service;
4207   dbus_uint32_t serial;
4208   dbus_bool_t   retval;
4209   const char   *existent = EXISTENT_SERVICE_NAME;
4210   dbus_uint32_t flags;
4211   char        **services;
4212   int           len;
4213
4214   _dbus_verbose ("check_list_services for %p\n", connection);
4215
4216   if (!check_get_services (context, connection, "ListActivatableNames", &services, &len))
4217     {
4218       return TRUE;
4219     }
4220
4221   if (!_dbus_string_array_contains ((const char **)services, existent))
4222     {
4223       _dbus_warn ("Did not get the expected %s from ListActivatableNames\n", existent);
4224       dbus_free_string_array (services);
4225       return FALSE;
4226     }
4227
4228   dbus_free_string_array (services);
4229
4230   base_service_message = NULL;
4231
4232   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
4233                                           DBUS_PATH_DBUS,
4234                                           DBUS_INTERFACE_DBUS,
4235                                           "StartServiceByName");
4236
4237   if (message == NULL)
4238     return TRUE;
4239
4240   dbus_message_set_auto_start (message, FALSE);
4241
4242   flags = 0;
4243   if (!dbus_message_append_args (message,
4244                                  DBUS_TYPE_STRING, &existent,
4245                                  DBUS_TYPE_UINT32, &flags,
4246                                  DBUS_TYPE_INVALID))
4247     {
4248       dbus_message_unref (message);
4249       return TRUE;
4250     }
4251
4252   if (!dbus_connection_send (connection, message, &serial))
4253     {
4254       dbus_message_unref (message);
4255       return TRUE;
4256     }
4257
4258   dbus_message_unref (message);
4259   message = NULL;
4260
4261   bus_test_run_everything (context);
4262
4263   /* now wait for the message bus to hear back from the activated
4264    * service.
4265    */
4266   block_connection_until_message_from_bus (context, connection, "activated service to connect");
4267
4268   bus_test_run_everything (context);
4269
4270   if (!dbus_connection_get_is_connected (connection))
4271     {
4272       _dbus_verbose ("connection was disconnected\n");
4273       return TRUE;
4274     }
4275
4276   retval = FALSE;
4277
4278   message = pop_message_waiting_for_memory (connection);
4279   if (message == NULL)
4280     {
4281       _dbus_warn ("Did not receive any messages after %s %d on %p\n",
4282                   "StartServiceByName", serial, connection);
4283       goto out;
4284     }
4285
4286   verbose_message_received (connection, message);
4287   _dbus_verbose ("  (after sending %s)\n", "StartServiceByName");
4288
4289   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
4290     {
4291       if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
4292         {
4293           _dbus_warn ("Message has wrong sender %s\n",
4294                       dbus_message_get_sender (message) ?
4295                       dbus_message_get_sender (message) : "(none)");
4296           goto out;
4297         }
4298
4299       if (dbus_message_is_error (message,
4300                                  DBUS_ERROR_NO_MEMORY))
4301         {
4302           ; /* good, this is a valid response */
4303         }
4304       else if (dbus_message_is_error (message,
4305                                       DBUS_ERROR_SPAWN_CHILD_EXITED) ||
4306                dbus_message_is_error (message,
4307                                       DBUS_ERROR_SPAWN_CHILD_SIGNALED) ||
4308                dbus_message_is_error (message,
4309                                       DBUS_ERROR_SPAWN_EXEC_FAILED))
4310         {
4311           ; /* good, this is expected also */
4312         }
4313       else
4314         {
4315           _dbus_warn ("Did not expect error %s\n",
4316                       dbus_message_get_error_name (message));
4317           goto out;
4318         }
4319     }
4320   else
4321     {
4322       GotServiceInfo message_kind;
4323
4324       if (!check_base_service_activated (context, connection,
4325                                          message, &base_service))
4326         goto out;
4327
4328       base_service_message = message;
4329       message = NULL;
4330
4331       /* We may need to block here for the test service to exit or finish up */
4332       block_connection_until_message_from_bus (context, connection, "test service to exit or finish up");
4333
4334       message = dbus_connection_borrow_message (connection);
4335       if (message == NULL)
4336         {
4337           _dbus_warn ("Did not receive any messages after base service creation notification\n");
4338           goto out;
4339         }
4340
4341       message_kind = check_got_service_info (message);
4342
4343       dbus_connection_return_message (connection, message);
4344       message = NULL;
4345
4346       switch (message_kind)
4347         {
4348         case GOT_SOMETHING_ELSE:
4349         case GOT_ERROR:
4350         case GOT_SERVICE_DELETED:
4351           _dbus_warn ("Unexpected message after ActivateService "
4352                       "(should be an error or a service announcement)\n");
4353           goto out;
4354
4355         case GOT_SERVICE_CREATED:
4356           message = pop_message_waiting_for_memory (connection);
4357           if (message == NULL)
4358             {
4359               _dbus_warn ("Failed to pop message we just put back! "
4360                           "should have been a NameOwnerChanged (creation)\n");
4361               goto out;
4362             }
4363
4364           if (!check_service_activated (context, connection, EXISTENT_SERVICE_NAME,
4365                                         base_service, message))
4366             goto out;
4367
4368           dbus_message_unref (message);
4369           message = NULL;
4370
4371           if (!check_no_leftovers (context))
4372             {
4373               _dbus_warn ("Messages were left over after successful activation\n");
4374               goto out;
4375             }
4376
4377           break;
4378         }
4379     }
4380
4381   if (!check_get_services (context, connection, "ListNames", &services, &len))
4382     {
4383       return TRUE;
4384     }
4385
4386   if (!_dbus_string_array_contains ((const char **)services, existent))
4387     {
4388       _dbus_warn ("Did not get the expected %s from ListNames\n", existent);
4389       goto out;
4390     }
4391
4392   dbus_free_string_array (services);
4393
4394   if (!check_send_exit_to_service (context, connection,
4395                                    EXISTENT_SERVICE_NAME, base_service))
4396     goto out;
4397
4398   retval = TRUE;
4399
4400  out:
4401   if (message)
4402     dbus_message_unref (message);
4403
4404   if (base_service_message)
4405     dbus_message_unref (base_service_message);
4406
4407   return retval;
4408 }
4409
4410 typedef struct
4411 {
4412   Check2Func func;
4413   BusContext *context;
4414   DBusConnection *connection;
4415 } Check2Data;
4416
4417 static dbus_bool_t
4418 check_oom_check2_func (void *data)
4419 {
4420   Check2Data *d = data;
4421
4422   if (! (* d->func) (d->context, d->connection))
4423     return FALSE;
4424
4425   if (!check_no_leftovers (d->context))
4426     {
4427       _dbus_warn ("Messages were left over, should be covered by test suite\n");
4428       return FALSE;
4429     }
4430
4431   return TRUE;
4432 }
4433
4434 static void
4435 check2_try_iterations (BusContext     *context,
4436                        DBusConnection *connection,
4437                        const char     *description,
4438                        Check2Func      func)
4439 {
4440   Check2Data d;
4441
4442   d.func = func;
4443   d.context = context;
4444   d.connection = connection;
4445
4446   if (!_dbus_test_oom_handling (description, check_oom_check2_func,
4447                                 &d))
4448     {
4449       _dbus_warn ("%s failed during oom\n", description);
4450       _dbus_assert_not_reached ("test failed");
4451     }
4452 }
4453
4454 static dbus_bool_t
4455 setenv_TEST_LAUNCH_HELPER_CONFIG(const DBusString *test_data_dir,
4456                                  const char       *filename)
4457 {
4458   DBusString full;
4459   DBusString file;
4460
4461   if (!_dbus_string_init (&full))
4462     return FALSE;
4463
4464   if (!_dbus_string_copy (test_data_dir, 0, &full, 0))
4465     {
4466       _dbus_string_free (&full);
4467       return FALSE;
4468     }
4469
4470   _dbus_string_init_const (&file, filename);
4471
4472   if (!_dbus_concat_dir_and_file (&full, &file))
4473     {
4474       _dbus_string_free (&full);
4475       return FALSE;
4476     }
4477
4478   _dbus_verbose ("Setting TEST_LAUNCH_HELPER_CONFIG to '%s'\n",
4479                  _dbus_string_get_const_data (&full));
4480
4481   dbus_setenv ("TEST_LAUNCH_HELPER_CONFIG", _dbus_string_get_const_data (&full));
4482
4483   _dbus_string_free (&full);
4484
4485   return TRUE;
4486 }
4487
4488 static dbus_bool_t
4489 bus_dispatch_test_conf (const DBusString *test_data_dir,
4490                         const char       *filename,
4491                         dbus_bool_t       use_launcher)
4492 {
4493   BusContext *context;
4494   DBusConnection *foo;
4495   DBusConnection *bar;
4496   DBusConnection *baz;
4497   DBusError error;
4498
4499   /* save the config name for the activation helper */
4500   if (!setenv_TEST_LAUNCH_HELPER_CONFIG (test_data_dir, filename))
4501     _dbus_assert_not_reached ("no memory setting TEST_LAUNCH_HELPER_CONFIG");
4502
4503   dbus_error_init (&error);
4504
4505   context = bus_context_new_test (test_data_dir, filename);
4506   if (context == NULL)
4507     return FALSE;
4508
4509   foo = dbus_connection_open_private (TEST_DEBUG_PIPE, &error);
4510   if (foo == NULL)
4511     _dbus_assert_not_reached ("could not alloc connection");
4512
4513   if (!bus_setup_debug_client (foo))
4514     _dbus_assert_not_reached ("could not set up connection");
4515
4516   spin_connection_until_authenticated (context, foo);
4517
4518   if (!check_hello_message (context, foo))
4519     _dbus_assert_not_reached ("hello message failed");
4520
4521   if (!check_double_hello_message (context, foo))
4522     _dbus_assert_not_reached ("double hello message failed");
4523
4524   if (!check_add_match_all (context, foo))
4525     _dbus_assert_not_reached ("AddMatch message failed");
4526
4527   bar = dbus_connection_open_private (TEST_DEBUG_PIPE, &error);
4528   if (bar == NULL)
4529     _dbus_assert_not_reached ("could not alloc connection");
4530
4531   if (!bus_setup_debug_client (bar))
4532     _dbus_assert_not_reached ("could not set up connection");
4533
4534   spin_connection_until_authenticated (context, bar);
4535
4536   if (!check_hello_message (context, bar))
4537     _dbus_assert_not_reached ("hello message failed");
4538
4539   if (!check_add_match_all (context, bar))
4540     _dbus_assert_not_reached ("AddMatch message failed");
4541
4542   baz = dbus_connection_open_private (TEST_DEBUG_PIPE, &error);
4543   if (baz == NULL)
4544     _dbus_assert_not_reached ("could not alloc connection");
4545
4546   if (!bus_setup_debug_client (baz))
4547     _dbus_assert_not_reached ("could not set up connection");
4548
4549   spin_connection_until_authenticated (context, baz);
4550
4551   if (!check_hello_message (context, baz))
4552     _dbus_assert_not_reached ("hello message failed");
4553
4554   if (!check_add_match_all (context, baz))
4555     _dbus_assert_not_reached ("AddMatch message failed");
4556
4557 #ifdef DBUS_WIN_FIXME
4558   _dbus_warn("TODO: testing of GetConnectionUnixUser message skipped for now\n");
4559   _dbus_warn("TODO: testing of GetConnectionUnixProcessID message skipped for now\n");
4560 #else
4561   if (!check_get_connection_unix_user (context, baz))
4562     _dbus_assert_not_reached ("GetConnectionUnixUser message failed");
4563
4564   if (!check_get_connection_unix_process_id (context, baz))
4565     _dbus_assert_not_reached ("GetConnectionUnixProcessID message failed");
4566 #endif
4567
4568   if (!check_list_services (context, baz))
4569     _dbus_assert_not_reached ("ListActivatableNames message failed");
4570
4571   if (!check_no_leftovers (context))
4572     {
4573       _dbus_warn ("Messages were left over after setting up initial connections\n");
4574       _dbus_assert_not_reached ("initial connection setup failed");
4575     }
4576
4577   check1_try_iterations (context, "create_and_hello",
4578                          check_hello_connection);
4579
4580   check2_try_iterations (context, foo, "nonexistent_service_no_auto_start",
4581                          check_nonexistent_service_no_auto_start);
4582
4583 #ifdef DBUS_WIN_FIXME
4584   _dbus_warn("TODO: dispatch.c segfault_service_no_auto_start test\n");
4585 #else
4586   check2_try_iterations (context, foo, "segfault_service_no_auto_start",
4587                          check_segfault_service_no_auto_start);
4588 #endif
4589
4590   check2_try_iterations (context, foo, "existent_service_no_auto_start",
4591                          check_existent_service_no_auto_start);
4592
4593   check2_try_iterations (context, foo, "nonexistent_service_auto_start",
4594                          check_nonexistent_service_auto_start);
4595
4596
4597 #ifdef DBUS_WIN_FIXME
4598   _dbus_warn("TODO: dispatch.c segfault_service_auto_start test\n");
4599 #else
4600   /* only do the segfault test if we are not using the launcher */
4601   check2_try_iterations (context, foo, "segfault_service_auto_start",
4602                          check_segfault_service_auto_start);
4603 #endif
4604
4605   /* only do the shell fail test if we are not using the launcher */
4606   check2_try_iterations (context, foo, "shell_fail_service_auto_start",
4607                          check_shell_fail_service_auto_start);
4608
4609   /* specific to launcher */
4610   if (use_launcher)
4611     if (!check_launch_service_file_missing (context, foo))
4612       _dbus_assert_not_reached ("did not get service file not found error");
4613
4614 #if 0
4615   /* Note: need to resolve some issues with the testing code in order to run
4616    * this in oom (handle that we sometimes don't get replies back from the bus
4617    * when oom happens, without blocking the test).
4618    */
4619   check2_try_iterations (context, foo, "existent_service_auto_auto_start",
4620                          check_existent_service_auto_start);
4621 #endif
4622
4623   if (!check_existent_service_auto_start (context, foo))
4624     _dbus_assert_not_reached ("existent service auto start failed");
4625
4626   if (!check_shell_service_success_auto_start (context, foo))
4627     _dbus_assert_not_reached ("shell success service auto start failed");
4628
4629   _dbus_verbose ("Disconnecting foo, bar, and baz\n");
4630
4631   kill_client_connection_unchecked (foo);
4632   kill_client_connection_unchecked (bar);
4633   kill_client_connection_unchecked (baz);
4634
4635   bus_context_unref (context);
4636
4637   return TRUE;
4638 }
4639
4640 static dbus_bool_t
4641 bus_dispatch_test_conf_fail (const DBusString *test_data_dir,
4642                              const char       *filename)
4643 {
4644   BusContext *context;
4645   DBusConnection *foo;
4646   DBusError error;
4647
4648   /* save the config name for the activation helper */
4649   if (!setenv_TEST_LAUNCH_HELPER_CONFIG (test_data_dir, filename))
4650     _dbus_assert_not_reached ("no memory setting TEST_LAUNCH_HELPER_CONFIG");
4651
4652   dbus_error_init (&error);
4653
4654   context = bus_context_new_test (test_data_dir, filename);
4655   if (context == NULL)
4656     return FALSE;
4657
4658   foo = dbus_connection_open_private (TEST_DEBUG_PIPE, &error);
4659   if (foo == NULL)
4660     _dbus_assert_not_reached ("could not alloc connection");
4661
4662   if (!bus_setup_debug_client (foo))
4663     _dbus_assert_not_reached ("could not set up connection");
4664
4665   spin_connection_until_authenticated (context, foo);
4666
4667   if (!check_hello_message (context, foo))
4668     _dbus_assert_not_reached ("hello message failed");
4669
4670   if (!check_double_hello_message (context, foo))
4671     _dbus_assert_not_reached ("double hello message failed");
4672
4673   if (!check_add_match_all (context, foo))
4674     _dbus_assert_not_reached ("AddMatch message failed");
4675
4676   /* this only tests the activation.c user check */
4677   if (!check_launch_service_user_missing (context, foo))
4678     _dbus_assert_not_reached ("user missing did not trigger error");
4679
4680   /* this only tests the desktop.c exec check */
4681   if (!check_launch_service_exec_missing (context, foo))
4682     _dbus_assert_not_reached ("exec missing did not trigger error");
4683
4684   /* this only tests the desktop.c service check */
4685   if (!check_launch_service_service_missing (context, foo))
4686     _dbus_assert_not_reached ("service missing did not trigger error");
4687
4688   _dbus_verbose ("Disconnecting foo\n");
4689
4690   kill_client_connection_unchecked (foo);
4691
4692   bus_context_unref (context);
4693
4694   return TRUE;
4695 }
4696
4697 dbus_bool_t
4698 bus_dispatch_test (const DBusString *test_data_dir)
4699 {
4700   /* run normal activation tests */
4701   _dbus_verbose ("Normal activation tests\n");
4702   if (!bus_dispatch_test_conf (test_data_dir,
4703                                "valid-config-files/debug-allow-all.conf", FALSE))
4704     return FALSE;
4705
4706 #ifdef DBUS_WIN
4707   _dbus_warn("Info: Launch helper activation tests skipped because launch-helper is not supported yet\n");
4708 #else
4709   /* run launch-helper activation tests */
4710   _dbus_verbose ("Launch helper activation tests\n");
4711   if (!bus_dispatch_test_conf (test_data_dir,
4712                                "valid-config-files-system/debug-allow-all-pass.conf", TRUE))
4713     return FALSE;
4714
4715   /* run select launch-helper activation tests on broken service files */
4716   if (!bus_dispatch_test_conf_fail (test_data_dir,
4717                                     "valid-config-files-system/debug-allow-all-fail.conf"))
4718     return FALSE;
4719 #endif
4720
4721   return TRUE;
4722 }
4723
4724 dbus_bool_t
4725 bus_dispatch_sha1_test (const DBusString *test_data_dir)
4726 {
4727   BusContext *context;
4728   DBusConnection *foo;
4729   DBusError error;
4730
4731   dbus_error_init (&error);
4732
4733   /* Test SHA1 authentication */
4734   _dbus_verbose ("Testing SHA1 context\n");
4735
4736   context = bus_context_new_test (test_data_dir,
4737                                   "valid-config-files/debug-allow-all-sha1.conf");
4738   if (context == NULL)
4739     return FALSE;
4740
4741   foo = dbus_connection_open_private (TEST_DEBUG_PIPE, &error);
4742   if (foo == NULL)
4743     _dbus_assert_not_reached ("could not alloc connection");
4744
4745   if (!bus_setup_debug_client (foo))
4746     _dbus_assert_not_reached ("could not set up connection");
4747
4748   spin_connection_until_authenticated (context, foo);
4749
4750   if (!check_hello_message (context, foo))
4751     _dbus_assert_not_reached ("hello message failed");
4752
4753   if (!check_add_match_all (context, foo))
4754     _dbus_assert_not_reached ("addmatch message failed");
4755
4756   if (!check_no_leftovers (context))
4757     {
4758       _dbus_warn ("Messages were left over after setting up initial SHA-1 connection\n");
4759       _dbus_assert_not_reached ("initial connection setup failed");
4760     }
4761
4762   check1_try_iterations (context, "create_and_hello_sha1",
4763                          check_hello_connection);
4764
4765   kill_client_connection_unchecked (foo);
4766
4767   bus_context_unref (context);
4768
4769   return TRUE;
4770 }
4771
4772 #ifdef HAVE_UNIX_FD_PASSING
4773
4774 dbus_bool_t
4775 bus_unix_fds_passing_test(const DBusString *test_data_dir)
4776 {
4777   BusContext *context;
4778   DBusConnection *foo, *bar;
4779   DBusError error;
4780   DBusMessage *m;
4781   int one[2], two[2], x, y, z;
4782   char r;
4783
4784   dbus_error_init (&error);
4785
4786   context = bus_context_new_test (test_data_dir, "valid-config-files/debug-allow-all.conf");
4787   if (context == NULL)
4788     _dbus_assert_not_reached ("could not alloc context");
4789
4790   foo = dbus_connection_open_private (TEST_DEBUG_PIPE, &error);
4791   if (foo == NULL)
4792     _dbus_assert_not_reached ("could not alloc connection");
4793
4794   if (!bus_setup_debug_client (foo))
4795     _dbus_assert_not_reached ("could not set up connection");
4796
4797   spin_connection_until_authenticated (context, foo);
4798
4799   if (!check_hello_message (context, foo))
4800     _dbus_assert_not_reached ("hello message failed");
4801
4802   if (!check_add_match_all (context, foo))
4803     _dbus_assert_not_reached ("AddMatch message failed");
4804
4805   bar = dbus_connection_open_private (TEST_DEBUG_PIPE, &error);
4806   if (bar == NULL)
4807     _dbus_assert_not_reached ("could not alloc connection");
4808
4809   if (!bus_setup_debug_client (bar))
4810     _dbus_assert_not_reached ("could not set up connection");
4811
4812   spin_connection_until_authenticated (context, bar);
4813
4814   if (!check_hello_message (context, bar))
4815     _dbus_assert_not_reached ("hello message failed");
4816
4817   if (!check_add_match_all (context, bar))
4818     _dbus_assert_not_reached ("AddMatch message failed");
4819
4820   if (!(m = dbus_message_new_signal("/", "a.b.c", "d")))
4821     _dbus_assert_not_reached ("could not alloc message");
4822
4823   if (!(_dbus_full_duplex_pipe(one, one+1, TRUE, &error)))
4824     _dbus_assert_not_reached("Failed to allocate pipe #1");
4825
4826   if (!(_dbus_full_duplex_pipe(two, two+1, TRUE, &error)))
4827     _dbus_assert_not_reached("Failed to allocate pipe #2");
4828
4829   if (!dbus_message_append_args(m,
4830                                 DBUS_TYPE_UNIX_FD, one,
4831                                 DBUS_TYPE_UNIX_FD, two,
4832                                 DBUS_TYPE_UNIX_FD, two,
4833                                 DBUS_TYPE_INVALID))
4834     _dbus_assert_not_reached("Failed to attach fds.");
4835
4836   if (!_dbus_close(one[0], &error))
4837     _dbus_assert_not_reached("Failed to close pipe #1 ");
4838   if (!_dbus_close(two[0], &error))
4839     _dbus_assert_not_reached("Failed to close pipe #2 ");
4840
4841   if (!(dbus_connection_can_send_type(foo, DBUS_TYPE_UNIX_FD)))
4842     _dbus_assert_not_reached("Connection cannot do fd passing");
4843
4844   if (!(dbus_connection_can_send_type(bar, DBUS_TYPE_UNIX_FD)))
4845     _dbus_assert_not_reached("Connection cannot do fd passing");
4846
4847   if (!dbus_connection_send (foo, m, NULL))
4848     _dbus_assert_not_reached("Failed to send fds");
4849
4850   dbus_message_unref(m);
4851
4852   bus_test_run_clients_loop (SEND_PENDING (foo));
4853
4854   bus_test_run_everything (context);
4855
4856   block_connection_until_message_from_bus (context, foo, "unix fd reception on foo");
4857
4858   if (!(m = pop_message_waiting_for_memory (foo)))
4859     _dbus_assert_not_reached("Failed to receive msg");
4860
4861   if (!dbus_message_is_signal(m, "a.b.c", "d"))
4862     _dbus_assert_not_reached("bogus message received");
4863
4864   dbus_message_unref(m);
4865
4866   block_connection_until_message_from_bus (context, bar, "unix fd reception on bar");
4867
4868   if (!(m = pop_message_waiting_for_memory (bar)))
4869     _dbus_assert_not_reached("Failed to receive msg");
4870
4871   if (!dbus_message_is_signal(m, "a.b.c", "d"))
4872     _dbus_assert_not_reached("bogus message received");
4873
4874   if (!dbus_message_get_args(m,
4875                              &error,
4876                              DBUS_TYPE_UNIX_FD, &x,
4877                              DBUS_TYPE_UNIX_FD, &y,
4878                              DBUS_TYPE_UNIX_FD, &z,
4879                              DBUS_TYPE_INVALID))
4880     _dbus_assert_not_reached("Failed to parse fds.");
4881
4882   dbus_message_unref(m);
4883
4884   if (write(x, "X", 1) != 1)
4885     _dbus_assert_not_reached("Failed to write to pipe #1");
4886   if (write(y, "Y", 1) != 1)
4887     _dbus_assert_not_reached("Failed to write to pipe #2");
4888   if (write(z, "Z", 1) != 1)
4889     _dbus_assert_not_reached("Failed to write to pipe #2/2nd fd");
4890
4891   if (!_dbus_close(x, &error))
4892     _dbus_assert_not_reached("Failed to close pipe #1/other side ");
4893   if (!_dbus_close(y, &error))
4894     _dbus_assert_not_reached("Failed to close pipe #2/other side ");
4895   if (!_dbus_close(z, &error))
4896     _dbus_assert_not_reached("Failed to close pipe #2/other size 2nd fd ");
4897
4898   if (read(one[1], &r, 1) != 1 || r != 'X')
4899     _dbus_assert_not_reached("Failed to read value from pipe.");
4900   if (read(two[1], &r, 1) != 1 || r != 'Y')
4901     _dbus_assert_not_reached("Failed to read value from pipe.");
4902   if (read(two[1], &r, 1) != 1 || r != 'Z')
4903     _dbus_assert_not_reached("Failed to read value from pipe.");
4904
4905   if (!_dbus_close(one[1], &error))
4906     _dbus_assert_not_reached("Failed to close pipe #1 ");
4907   if (!_dbus_close(two[1], &error))
4908     _dbus_assert_not_reached("Failed to close pipe #2 ");
4909
4910   _dbus_verbose ("Disconnecting foo\n");
4911   kill_client_connection_unchecked (foo);
4912
4913   _dbus_verbose ("Disconnecting bar\n");
4914   kill_client_connection_unchecked (bar);
4915
4916   bus_context_unref (context);
4917
4918   return TRUE;
4919 }
4920 #endif
4921
4922 #endif /* DBUS_ENABLE_EMBEDDED_TESTS */