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