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