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