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