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