2003-10-14 Havoc Pennington <hp@redhat.com>
[platform/upstream/dbus.git] / bus / dispatch.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dispatch.c  Message dispatcher
3  *
4  * Copyright (C) 2003  CodeFactory AB
5  * Copyright (C) 2003  Red Hat, Inc.
6  *
7  * Licensed under the Academic Free License version 1.2
8  * 
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  * 
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  *
23  */
24
25 #include "dispatch.h"
26 #include "connection.h"
27 #include "driver.h"
28 #include "services.h"
29 #include "utils.h"
30 #include "bus.h"
31 #include "signals.h"
32 #include "test.h"
33 #include <dbus/dbus-internals.h>
34 #include <string.h>
35
36 static dbus_bool_t
37 send_one_message (DBusConnection *connection,
38                   BusContext     *context,
39                   DBusConnection *sender,
40                   DBusConnection *addressed_recipient,
41                   DBusMessage    *message,
42                   BusTransaction *transaction,
43                   DBusError      *error)
44 {
45   if (!bus_context_check_security_policy (context, transaction,
46                                           sender,
47                                           addressed_recipient,
48                                           connection,
49                                           message,
50                                           NULL))
51     return TRUE; /* silently don't send it */
52   
53   if (!bus_transaction_send (transaction,
54                              connection,
55                              message))
56     {
57       BUS_SET_OOM (error);
58       return FALSE;
59     }
60
61   return TRUE;
62 }
63
64 dbus_bool_t
65 bus_dispatch_matches (BusTransaction *transaction,
66                       DBusConnection *sender,
67                       DBusConnection *addressed_recipient,
68                       DBusMessage    *message,
69                       DBusError      *error)
70 {
71   DBusError tmp_error;
72   BusConnections *connections;
73   DBusList *recipients;
74   BusMatchmaker *matchmaker;
75   DBusList *link;
76   BusContext *context;
77
78   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
79
80   /* sender and recipient can both be NULL for the bus driver,
81    * or for signals with no particular recipient
82    */
83
84   _dbus_assert (sender == NULL || bus_connection_is_active (sender));
85   _dbus_assert (dbus_message_get_sender (message) != NULL);
86
87   connections = bus_transaction_get_connections (transaction);
88   
89   dbus_error_init (&tmp_error);
90   context = bus_transaction_get_context (transaction);
91   matchmaker = bus_context_get_matchmaker (context);
92
93   recipients = NULL;
94   if (!bus_matchmaker_get_recipients (matchmaker,
95                                       bus_context_get_connections (context),
96                                       sender, addressed_recipient, message,
97                                       &recipients))
98     {
99       BUS_SET_OOM (error);
100       return FALSE;
101     }
102
103   link = _dbus_list_get_first_link (&recipients);
104   while (link != NULL)
105     {
106       DBusConnection *dest;
107
108       dest = link->data;
109
110       if (!send_one_message (dest, context, sender, addressed_recipient,
111                              message, transaction, &tmp_error))
112         break;
113
114       link = _dbus_list_get_next_link (&recipients, link);
115     }
116
117   _dbus_list_clear (&recipients);
118   
119   if (dbus_error_is_set (&tmp_error))
120     {
121       dbus_move_error (&tmp_error, error);
122       return FALSE;
123     }
124   else
125     return TRUE;
126 }
127
128 static DBusHandlerResult
129 bus_dispatch (DBusConnection *connection,
130               DBusMessage    *message)
131 {
132   const char *sender, *service_name;
133   DBusError error;
134   BusTransaction *transaction;
135   BusContext *context;
136   DBusHandlerResult result;
137   DBusConnection *addressed_recipient;
138   
139   result = DBUS_HANDLER_RESULT_HANDLED;
140   
141   transaction = NULL;
142   addressed_recipient = NULL;
143   dbus_error_init (&error);
144   
145   context = bus_connection_get_context (connection);
146   _dbus_assert (context != NULL);
147   
148   /* If we can't even allocate an OOM error, we just go to sleep
149    * until we can.
150    */
151   while (!bus_connection_preallocate_oom_error (connection))
152     _dbus_wait_for_memory ();
153   
154   /* Ref connection in case we disconnect it at some point in here */
155   dbus_connection_ref (connection);
156   
157   service_name = dbus_message_get_destination (message);
158
159 #ifdef DBUS_ENABLE_VERBOSE_MODE
160   {
161     const char *interface_name, *member_name, *error_name;
162
163     interface_name = dbus_message_get_interface (message);
164     member_name = dbus_message_get_member (message);
165     error_name = dbus_message_get_error_name (message);
166     
167     _dbus_verbose ("DISPATCH: %s %s %s to %s\n",
168                    interface_name ? interface_name : "(no interface)",
169                    member_name ? member_name : "(no member)",
170                    error_name ? error_name : "(no error name)",
171                    service_name ? service_name : "peer");
172   }
173 #endif /* DBUS_ENABLE_VERBOSE_MODE */
174   
175   /* If service_name is NULL, if it's a signal we send it to all
176    * connections with a match rule. If it's not a signal, it goes to
177    * the bus daemon but doesn't go "on the bus"; e.g. a peer-to-peer
178    * ping. Handle these immediately, especially disconnection
179    * messages. There are no security policy checks on these.
180    */
181   if (service_name == NULL)
182     {
183       if (dbus_message_is_signal (message,
184                                   DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
185                                   "Disconnected"))
186         {
187           bus_connection_disconnected (connection);
188           goto out;
189         }
190
191       if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL)
192         {
193           /* DBusConnection also handles some of these automatically, we leave
194            * it to do so.
195            */
196           result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
197           goto out;
198         }
199     }
200   
201   /* Create our transaction */
202   transaction = bus_transaction_new (context);
203   if (transaction == NULL)
204     {
205       BUS_SET_OOM (&error);
206       goto out;
207     }
208   
209   /* Assign a sender to the message */
210   if (bus_connection_is_active (connection))
211     {
212       sender = bus_connection_get_name (connection);
213       _dbus_assert (sender != NULL);
214
215       if (!dbus_message_set_sender (message, sender))
216         {
217           BUS_SET_OOM (&error);
218           goto out;
219         }
220
221       /* We need to refetch the service name here, because
222        * dbus_message_set_sender can cause the header to be
223        * reallocated, and thus the service_name pointer will become
224        * invalid.
225        */
226       service_name = dbus_message_get_destination (message);
227     }
228   
229   if (service_name &&
230       strcmp (service_name, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS) == 0) /* to bus driver */
231     {
232       if (!bus_context_check_security_policy (context, transaction,
233                                               connection, NULL, NULL, message, &error))
234         {
235           _dbus_verbose ("Security policy rejected message\n");
236           goto out;
237         }
238
239       _dbus_verbose ("Giving message to %s\n", DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
240       if (!bus_driver_handle_message (connection, transaction, message, &error))
241         goto out;
242     }
243   else if (!bus_connection_is_active (connection)) /* clients must talk to bus driver first */
244     {
245       _dbus_verbose ("Received message from non-registered client. Disconnecting.\n");
246       dbus_connection_disconnect (connection);
247       goto out;
248     }
249   else if (service_name != NULL) /* route to named service */
250     {
251       DBusString service_string;
252       BusService *service;
253       BusRegistry *registry;
254
255       _dbus_assert (service_name != NULL);
256       
257       registry = bus_connection_get_registry (connection);
258       
259       _dbus_string_init_const (&service_string, service_name);
260       service = bus_registry_lookup (registry, &service_string);
261
262       if (service == NULL)
263         {
264           dbus_set_error (&error,
265                           DBUS_ERROR_SERVICE_DOES_NOT_EXIST,
266                           "Service \"%s\" does not exist",
267                           service_name);
268           goto out;
269         }
270       else
271         {          
272           addressed_recipient = bus_service_get_primary_owner (service);
273           _dbus_assert (addressed_recipient != NULL);
274           
275           if (!bus_context_check_security_policy (context, transaction,
276                                                   connection, addressed_recipient,
277                                                   addressed_recipient,
278                                                   message, &error))
279             goto out;
280           
281           /* Dispatch the message */
282           if (!bus_transaction_send (transaction, addressed_recipient, message))
283             {
284               BUS_SET_OOM (&error);
285               goto out;
286             }
287         }
288     }
289
290   /* Now match the messages against any match rules, which will send
291    * out signals and such. addressed_recipient may == NULL.
292    */
293   if (!bus_dispatch_matches (transaction, connection, addressed_recipient, message, &error))
294     goto out;
295   
296  out:
297   if (dbus_error_is_set (&error))
298     {
299       if (!dbus_connection_get_is_connected (connection))
300         {
301           /* If we disconnected it, we won't bother to send it any error
302            * messages.
303            */
304           _dbus_verbose ("Not sending error to connection we disconnected\n");
305         }
306       else if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
307         {
308           bus_connection_send_oom_error (connection, message);
309
310           /* cancel transaction due to OOM */
311           if (transaction != NULL)
312             {
313               bus_transaction_cancel_and_free (transaction);
314               transaction = NULL;
315             }
316         }
317       else
318         {
319           /* Try to send the real error, if no mem to do that, send
320            * the OOM error
321            */
322           _dbus_assert (transaction != NULL);
323           
324           if (!bus_transaction_send_error_reply (transaction, connection,
325                                                  &error, message))
326             {
327               bus_connection_send_oom_error (connection, message);
328               
329               /* cancel transaction due to OOM */
330               if (transaction != NULL)
331                 {
332                   bus_transaction_cancel_and_free (transaction);
333                   transaction = NULL;
334                 }
335             }
336         }
337       
338       dbus_error_free (&error);
339     }
340
341   if (transaction != NULL)
342     {
343       bus_transaction_execute_and_free (transaction);
344     }
345
346   dbus_connection_unref (connection);
347
348   return result;
349 }
350
351 static DBusHandlerResult
352 bus_dispatch_message_filter (DBusConnection     *connection,
353                              DBusMessage        *message,
354                              void               *user_data)
355 {
356   return bus_dispatch (connection, message);
357 }
358
359 dbus_bool_t
360 bus_dispatch_add_connection (DBusConnection *connection)
361 {  
362   if (!dbus_connection_add_filter (connection,
363                                    bus_dispatch_message_filter,
364                                    NULL, NULL))
365     return FALSE;
366   
367   return TRUE;
368 }
369
370 void
371 bus_dispatch_remove_connection (DBusConnection *connection)
372 {
373   /* Here we tell the bus driver that we want to get off. */
374   bus_driver_remove_connection (connection);
375
376   dbus_connection_remove_filter (connection,
377                                  bus_dispatch_message_filter,
378                                  NULL);
379 }
380
381 #ifdef DBUS_BUILD_TESTS
382
383 typedef dbus_bool_t (* Check1Func) (BusContext     *context);
384 typedef dbus_bool_t (* Check2Func) (BusContext     *context,
385                                     DBusConnection *connection);
386
387 static dbus_bool_t check_no_leftovers (BusContext *context);
388
389 static void
390 block_connection_until_message_from_bus (BusContext     *context,
391                                          DBusConnection *connection)
392 {
393   while (dbus_connection_get_dispatch_status (connection) ==
394          DBUS_DISPATCH_COMPLETE &&
395          dbus_connection_get_is_connected (connection))
396     {
397       bus_test_run_bus_loop (context, TRUE);
398       bus_test_run_clients_loop (FALSE);
399     }
400 }
401
402 /* compensate for fact that pop_message() can return #NULL due to OOM */
403 static DBusMessage*
404 pop_message_waiting_for_memory (DBusConnection *connection)
405 {
406   while (dbus_connection_get_dispatch_status (connection) ==
407          DBUS_DISPATCH_NEED_MEMORY)
408     _dbus_wait_for_memory ();
409
410   return dbus_connection_pop_message (connection);
411 }
412
413 static void
414 warn_unexpected_real (DBusConnection *connection,
415                       DBusMessage    *message,
416                       const char     *expected,
417                       const char     *function,
418                       int             line)
419 {
420   _dbus_warn ("%s:%d received message interface \"%s\" member \"%s\" error name \"%s\" on %p, expecting %s\n",
421               function, line,
422               dbus_message_get_interface (message) ?
423               dbus_message_get_interface (message) : "(unset)",
424               dbus_message_get_member (message) ?
425               dbus_message_get_member (message) : "(unset)",
426               dbus_message_get_error_name (message) ?
427               dbus_message_get_error_name (message) : "(unset)",
428               connection,
429               expected);
430 }
431
432 #define warn_unexpected(connection, message, expected) \
433   warn_unexpected_real (connection, message, expected, _DBUS_FUNCTION_NAME, __LINE__)
434
435 static void
436 verbose_message_received (DBusConnection *connection,
437                           DBusMessage    *message)
438 {
439   _dbus_verbose ("Received message interface \"%s\" member \"%s\" error name \"%s\" on %p\n",
440                  dbus_message_get_interface (message) ?
441                  dbus_message_get_interface (message) : "(unset)",
442                  dbus_message_get_member (message) ?
443                  dbus_message_get_member (message) : "(unset)",
444                  dbus_message_get_error_name (message) ?
445                  dbus_message_get_error_name (message) : "(unset)",
446                  connection);
447 }
448
449 typedef struct
450 {
451   const char *expected_service_name;
452   dbus_bool_t failed;
453 } CheckServiceDeletedData;
454
455 static dbus_bool_t
456 check_service_deleted_foreach (DBusConnection *connection,
457                                void           *data)
458 {
459   CheckServiceDeletedData *d = data;
460   DBusMessage *message;
461   DBusError error;
462   char *service_name;
463
464   dbus_error_init (&error);
465   d->failed = TRUE;
466   service_name = NULL;
467   
468   message = pop_message_waiting_for_memory (connection);
469   if (message == NULL)
470     {
471       _dbus_warn ("Did not receive a message on %p, expecting %s\n",
472                   connection, "ServiceDeleted");
473       goto out;
474     }
475   else if (!dbus_message_is_signal (message,
476                                     DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
477                                     "ServiceDeleted"))
478     {
479       warn_unexpected (connection, message, "ServiceDeleted");
480
481       goto out;
482     }
483   else
484     {
485       if (!dbus_message_get_args (message, &error,
486                                   DBUS_TYPE_STRING, &service_name,
487                                   DBUS_TYPE_INVALID))
488         {
489           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
490             {
491               _dbus_verbose ("no memory to get service name arg\n");
492             }
493           else
494             {
495               _dbus_assert (dbus_error_is_set (&error));
496               _dbus_warn ("Did not get the expected single string argument\n");
497               goto out;
498             }
499         }
500       else if (strcmp (service_name, d->expected_service_name) != 0)
501         {
502           _dbus_warn ("expected deletion of service %s, got deletion of %s\n",
503                       d->expected_service_name,
504                       service_name);
505           goto out;
506         }
507     }
508
509   d->failed = FALSE;
510   
511  out:
512   dbus_free (service_name);
513   dbus_error_free (&error);
514   
515   if (message)
516     dbus_message_unref (message);
517
518   return !d->failed;
519 }
520
521 static void
522 kill_client_connection (BusContext     *context,
523                         DBusConnection *connection)
524 {
525   char *base_service;
526   const char *s;
527   CheckServiceDeletedData csdd;
528
529   _dbus_verbose ("killing connection %p\n", connection);
530   
531   s = dbus_bus_get_base_service (connection);
532   _dbus_assert (s != NULL);
533
534   while ((base_service = _dbus_strdup (s)) == NULL)
535     _dbus_wait_for_memory ();
536
537   dbus_connection_ref (connection);
538   
539   /* kick in the disconnect handler that unrefs the connection */
540   dbus_connection_disconnect (connection);
541
542   bus_test_run_everything (context);
543   
544   _dbus_assert (bus_test_client_listed (connection));
545   
546   /* Run disconnect handler in test.c */
547   if (bus_connection_dispatch_one_message (connection))
548     _dbus_assert_not_reached ("something received on connection being killed other than the disconnect");
549   
550   _dbus_assert (!dbus_connection_get_is_connected (connection));
551   dbus_connection_unref (connection);
552   connection = NULL;
553   _dbus_assert (!bus_test_client_listed (connection));
554   
555   csdd.expected_service_name = base_service;
556   csdd.failed = FALSE;
557
558   bus_test_clients_foreach (check_service_deleted_foreach,
559                             &csdd);
560
561   dbus_free (base_service);
562   
563   if (csdd.failed)
564     _dbus_assert_not_reached ("didn't get the expected ServiceDeleted messages");
565   
566   if (!check_no_leftovers (context))
567     _dbus_assert_not_reached ("stuff left in message queues after disconnecting a client");
568 }
569
570 static void
571 kill_client_connection_unchecked (DBusConnection *connection)
572 {
573   /* This kills the connection without expecting it to affect
574    * the rest of the bus.
575    */  
576   _dbus_verbose ("Unchecked kill of connection %p\n", connection);
577
578   dbus_connection_ref (connection);
579   dbus_connection_disconnect (connection);
580   /* dispatching disconnect handler will unref once */
581   if (bus_connection_dispatch_one_message (connection))
582     _dbus_assert_not_reached ("message other than disconnect dispatched after failure to register");
583
584   _dbus_assert (!bus_test_client_listed (connection));
585   dbus_connection_unref (connection);
586 }
587
588 typedef struct
589 {
590   dbus_bool_t failed;
591 } CheckNoMessagesData;
592
593 static dbus_bool_t
594 check_no_messages_foreach (DBusConnection *connection,
595                            void           *data)
596 {
597   CheckNoMessagesData *d = data;
598   DBusMessage *message;
599
600   message = pop_message_waiting_for_memory (connection);
601   if (message != NULL)
602     {
603       warn_unexpected (connection, message, "no messages");
604
605       d->failed = TRUE;
606     }
607
608   if (message)
609     dbus_message_unref (message);
610   return !d->failed;
611 }
612
613 typedef struct
614 {
615   DBusConnection *skip_connection;
616   const char *expected_service_name;
617   dbus_bool_t failed;
618 } CheckServiceCreatedData;
619
620 static dbus_bool_t
621 check_service_created_foreach (DBusConnection *connection,
622                                void           *data)
623 {
624   CheckServiceCreatedData *d = data;
625   DBusMessage *message;
626   DBusError error;
627   char *service_name;
628
629   if (connection == d->skip_connection)
630     return TRUE;
631
632   dbus_error_init (&error);
633   d->failed = TRUE;
634   service_name = NULL;
635   
636   message = pop_message_waiting_for_memory (connection);
637   if (message == NULL)
638     {
639       _dbus_warn ("Did not receive a message on %p, expecting %s\n",
640                   connection, "ServiceCreated");
641       goto out;
642     }
643   else if (!dbus_message_is_signal (message,
644                                     DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
645                                     "ServiceCreated"))
646     {
647       warn_unexpected (connection, message, "ServiceCreated");
648       goto out;
649     }
650   else
651     {
652       if (!dbus_message_get_args (message, &error,
653                                   DBUS_TYPE_STRING, &service_name,
654                                   DBUS_TYPE_INVALID))
655         {
656           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
657             {
658               _dbus_verbose ("no memory to get service name arg\n");
659             }
660           else
661             {
662               _dbus_assert (dbus_error_is_set (&error));
663               _dbus_warn ("Did not get the expected single string argument\n");
664               goto out;
665             }
666         }
667       else if (strcmp (service_name, d->expected_service_name) != 0)
668         {
669           _dbus_warn ("expected creation of service %s, got creation of %s\n",
670                       d->expected_service_name,
671                       service_name);
672           goto out;
673         }
674     }
675
676   d->failed = FALSE;
677   
678  out:
679   dbus_free (service_name);
680   dbus_error_free (&error);
681   
682   if (message)
683     dbus_message_unref (message);
684
685   return !d->failed;
686 }
687
688 static dbus_bool_t
689 check_no_leftovers (BusContext *context)
690 {
691   CheckNoMessagesData nmd;
692
693   nmd.failed = FALSE;
694   bus_test_clients_foreach (check_no_messages_foreach,
695                             &nmd);
696   
697   if (nmd.failed)
698     return FALSE;
699   else
700     return TRUE;
701 }
702
703 /* returns TRUE if the correct thing happens,
704  * but the correct thing may include OOM errors.
705  */
706 static dbus_bool_t
707 check_hello_message (BusContext     *context,
708                      DBusConnection *connection)
709 {
710   DBusMessage *message;
711   dbus_uint32_t serial;
712   dbus_bool_t retval;
713   DBusError error;
714   char *name;
715   char *acquired;
716
717   retval = FALSE;
718   dbus_error_init (&error);
719   name = NULL;
720   acquired = NULL;
721   message = NULL;
722
723   _dbus_verbose ("check_hello_message for %p\n", connection);
724   
725   message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
726                                           DBUS_PATH_ORG_FREEDESKTOP_DBUS,
727                                           DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
728                                           "Hello");
729
730   if (message == NULL)
731     return TRUE;
732
733   if (!dbus_connection_send (connection, message, &serial))
734     {
735       dbus_message_unref (message);
736       return TRUE;
737     }
738
739   dbus_message_unref (message);
740   message = NULL;
741
742   /* send our message */
743   bus_test_run_clients_loop (TRUE);
744
745   dbus_connection_ref (connection); /* because we may get disconnected */
746   block_connection_until_message_from_bus (context, connection);
747
748   if (!dbus_connection_get_is_connected (connection))
749     {
750       _dbus_verbose ("connection was disconnected\n");
751       
752       dbus_connection_unref (connection);
753       
754       return TRUE;
755     }
756
757   dbus_connection_unref (connection);
758   
759   message = pop_message_waiting_for_memory (connection);
760   if (message == NULL)
761     {
762       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
763                   "Hello", serial, connection);
764       goto out;
765     }
766
767   verbose_message_received (connection, message);
768
769   if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
770     {
771       _dbus_warn ("Message has wrong sender %s\n",
772                   dbus_message_get_sender (message) ?
773                   dbus_message_get_sender (message) : "(none)");
774       goto out;
775     }
776   
777   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
778     {
779       if (dbus_message_is_error (message,
780                                  DBUS_ERROR_NO_MEMORY))
781         {
782           ; /* good, this is a valid response */
783         }
784       else
785         {
786           warn_unexpected (connection, message, "not this error");
787
788           goto out;
789         }
790     }
791   else
792     {
793       CheckServiceCreatedData scd;
794       
795       if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
796         {
797           ; /* good, expected */
798         }
799       else
800         {
801           warn_unexpected (connection, message, "method return for Hello");
802
803           goto out;
804         }
805
806     retry_get_hello_name:
807       if (!dbus_message_get_args (message, &error,
808                                   DBUS_TYPE_STRING, &name,
809                                   DBUS_TYPE_INVALID))
810         {
811           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
812             {
813               _dbus_verbose ("no memory to get service name arg from hello\n");
814               dbus_error_free (&error);
815               _dbus_wait_for_memory ();
816               goto retry_get_hello_name;
817             }
818           else
819             {
820               _dbus_assert (dbus_error_is_set (&error));
821               _dbus_warn ("Did not get the expected single string argument to hello\n");
822               goto out;
823             }
824         }
825
826       _dbus_verbose ("Got hello name: %s\n", name);
827
828       while (!dbus_bus_set_base_service (connection, name))
829         _dbus_wait_for_memory ();
830       
831       scd.skip_connection = connection; /* we haven't done AddMatch so won't get it ourselves */
832       scd.failed = FALSE;
833       scd.expected_service_name = name;
834       bus_test_clients_foreach (check_service_created_foreach,
835                                 &scd);
836       
837       if (scd.failed)
838         goto out;
839       
840       /* Client should also have gotten ServiceAcquired */
841       dbus_message_unref (message);
842       message = pop_message_waiting_for_memory (connection);
843       if (message == NULL)
844         {
845           _dbus_warn ("Expecting %s, got nothing\n",
846                       "ServiceAcquired");
847           goto out;
848         }
849       
850     retry_get_acquired_name:
851       if (!dbus_message_get_args (message, &error,
852                                   DBUS_TYPE_STRING, &acquired,
853                                   DBUS_TYPE_INVALID))
854         {
855           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
856             {
857               _dbus_verbose ("no memory to get service name arg from acquired\n");
858               dbus_error_free (&error);
859               _dbus_wait_for_memory ();
860               goto retry_get_acquired_name;
861             }
862           else
863             {
864               _dbus_assert (dbus_error_is_set (&error));
865               _dbus_warn ("Did not get the expected single string argument to ServiceAcquired\n");
866               goto out;
867             }
868         }
869
870       _dbus_verbose ("Got acquired name: %s\n", acquired);
871
872       if (strcmp (acquired, name) != 0)
873         {
874           _dbus_warn ("Acquired name is %s but expected %s\n",
875                       acquired, name);
876           goto out;
877         }
878     }
879
880   if (!check_no_leftovers (context))
881     goto out;
882   
883   retval = TRUE;
884   
885  out:
886   dbus_error_free (&error);
887   
888   dbus_free (name);
889   dbus_free (acquired);
890   
891   if (message)
892     dbus_message_unref (message);
893   
894   return retval;
895 }
896
897 /* returns TRUE if the correct thing happens,
898  * but the correct thing may include OOM errors.
899  */
900 static dbus_bool_t
901 check_add_match_all (BusContext     *context,
902                      DBusConnection *connection)
903 {
904   DBusMessage *message;
905   dbus_bool_t retval;
906   dbus_uint32_t serial;
907   DBusError error;
908
909   retval = FALSE;
910   dbus_error_init (&error);
911   message = NULL;
912
913   _dbus_verbose ("check_add_match_all for %p\n", connection);
914   
915   message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
916                                           DBUS_PATH_ORG_FREEDESKTOP_DBUS,
917                                           DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
918                                           "AddMatch");
919
920   if (message == NULL)
921     return TRUE;
922
923   /* empty string match rule matches everything */
924   if (!dbus_message_append_args (message, DBUS_TYPE_STRING, "",
925                                  DBUS_TYPE_INVALID))
926     {
927       dbus_message_unref (message);
928       return TRUE;
929     }
930   
931   if (!dbus_connection_send (connection, message, &serial))
932     {
933       dbus_message_unref (message);
934       return TRUE;
935     }
936
937   dbus_message_unref (message);
938   message = NULL;
939
940   /* send our message */
941   bus_test_run_clients_loop (TRUE);
942
943   dbus_connection_ref (connection); /* because we may get disconnected */
944   block_connection_until_message_from_bus (context, connection);
945
946   if (!dbus_connection_get_is_connected (connection))
947     {
948       _dbus_verbose ("connection was disconnected\n");
949       
950       dbus_connection_unref (connection);
951       
952       return TRUE;
953     }
954
955   dbus_connection_unref (connection);
956   
957   message = pop_message_waiting_for_memory (connection);
958   if (message == NULL)
959     {
960       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
961                   "AddMatch", serial, connection);
962       goto out;
963     }
964
965   verbose_message_received (connection, message);
966
967   if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
968     {
969       _dbus_warn ("Message has wrong sender %s\n",
970                   dbus_message_get_sender (message) ?
971                   dbus_message_get_sender (message) : "(none)");
972       goto out;
973     }
974   
975   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
976     {
977       if (dbus_message_is_error (message,
978                                  DBUS_ERROR_NO_MEMORY))
979         {
980           ; /* good, this is a valid response */
981         }
982       else
983         {
984           warn_unexpected (connection, message, "not this error");
985
986           goto out;
987         }
988     }
989   else
990     {
991       if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
992         {
993           ; /* good, expected */
994           _dbus_assert (dbus_message_get_reply_serial (message) == serial);
995         }
996       else
997         {
998           warn_unexpected (connection, message, "method return for AddMatch");
999
1000           goto out;
1001         }
1002     }
1003
1004   if (!check_no_leftovers (context))
1005     goto out;
1006   
1007   retval = TRUE;
1008   
1009  out:
1010   dbus_error_free (&error);
1011   
1012   if (message)
1013     dbus_message_unref (message);
1014   
1015   return retval;
1016 }
1017
1018 /* returns TRUE if the correct thing happens,
1019  * but the correct thing may include OOM errors.
1020  */
1021 static dbus_bool_t
1022 check_hello_connection (BusContext *context)
1023 {
1024   DBusConnection *connection;
1025   DBusError error;
1026
1027   dbus_error_init (&error);
1028
1029   connection = dbus_connection_open ("debug-pipe:name=test-server", &error);
1030   if (connection == NULL)
1031     {
1032       _DBUS_ASSERT_ERROR_IS_SET (&error);
1033       dbus_error_free (&error);
1034       return TRUE;
1035     }
1036
1037   if (!bus_setup_debug_client (connection))
1038     {
1039       dbus_connection_disconnect (connection);
1040       dbus_connection_unref (connection);
1041       return TRUE;
1042     }
1043
1044   if (!check_hello_message (context, connection))
1045     return FALSE;
1046   
1047   if (dbus_bus_get_base_service (connection) == NULL)
1048     {
1049       /* We didn't successfully register, so we can't
1050        * do the usual kill_client_connection() checks
1051        */
1052       kill_client_connection_unchecked (connection);
1053     }
1054   else
1055     {
1056       if (!check_add_match_all (context, connection))
1057         return FALSE;
1058       
1059       kill_client_connection (context, connection);
1060     }
1061
1062   return TRUE;
1063 }
1064
1065 #define NONEXISTENT_SERVICE_NAME "test.this.service.does.not.exist.ewuoiurjdfxcvn"
1066
1067 /* returns TRUE if the correct thing happens,
1068  * but the correct thing may include OOM errors.
1069  */
1070 static dbus_bool_t
1071 check_nonexistent_service_activation (BusContext     *context,
1072                                       DBusConnection *connection)
1073 {
1074   DBusMessage *message;
1075   dbus_uint32_t serial;
1076   dbus_bool_t retval;
1077   DBusError error;
1078   
1079   dbus_error_init (&error);
1080   
1081   message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
1082                                           DBUS_PATH_ORG_FREEDESKTOP_DBUS,
1083                                           DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1084                                           "ActivateService");
1085
1086   if (message == NULL)
1087     return TRUE;
1088
1089   if (!dbus_message_append_args (message,
1090                                  DBUS_TYPE_STRING, NONEXISTENT_SERVICE_NAME,
1091                                  DBUS_TYPE_UINT32, 0,
1092                                  DBUS_TYPE_INVALID))
1093     {
1094       dbus_message_unref (message);
1095       return TRUE;
1096     }
1097   
1098   if (!dbus_connection_send (connection, message, &serial))
1099     {
1100       dbus_message_unref (message);
1101       return TRUE;
1102     }
1103
1104   dbus_message_unref (message);
1105   message = NULL;
1106
1107   bus_test_run_everything (context);
1108   block_connection_until_message_from_bus (context, connection);
1109   bus_test_run_everything (context);
1110
1111   if (!dbus_connection_get_is_connected (connection))
1112     {
1113       _dbus_verbose ("connection was disconnected\n");
1114       return TRUE;
1115     }
1116   
1117   retval = FALSE;
1118   
1119   message = pop_message_waiting_for_memory (connection);
1120   if (message == NULL)
1121     {
1122       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1123                   "ActivateService", serial, connection);
1124       goto out;
1125     }
1126
1127   verbose_message_received (connection, message);
1128
1129   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1130     {
1131       if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
1132         {
1133           _dbus_warn ("Message has wrong sender %s\n",
1134                       dbus_message_get_sender (message) ?
1135                       dbus_message_get_sender (message) : "(none)");
1136           goto out;
1137         }
1138       
1139       if (dbus_message_is_error (message,
1140                                  DBUS_ERROR_NO_MEMORY))
1141         {
1142           ; /* good, this is a valid response */
1143         }
1144       else if (dbus_message_is_error (message,
1145                                       DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND))
1146         {
1147           ; /* good, this is expected also */
1148         }
1149       else
1150         {
1151           warn_unexpected (connection, message, "not this error");
1152           goto out;
1153         }
1154     }
1155   else
1156     {
1157       _dbus_warn ("Did not expect to successfully activate %s\n",
1158                   NONEXISTENT_SERVICE_NAME);
1159       goto out;
1160     }
1161
1162   retval = TRUE;
1163   
1164  out:
1165   if (message)
1166     dbus_message_unref (message);
1167   
1168   return retval;
1169 }
1170
1171 static dbus_bool_t
1172 check_base_service_activated (BusContext     *context,
1173                               DBusConnection *connection,
1174                               DBusMessage    *initial_message,
1175                               char          **base_service_p)
1176 {
1177   DBusMessage *message;
1178   dbus_bool_t retval;
1179   DBusError error;
1180   char *base_service;
1181   
1182   base_service = NULL;
1183   retval = FALSE;
1184   
1185   dbus_error_init (&error);
1186
1187   message = initial_message;
1188   dbus_message_ref (message);  
1189
1190   if (dbus_message_is_signal (message,
1191                               DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1192                               "ServiceCreated"))
1193     {
1194       char *service_name;
1195       CheckServiceCreatedData scd;
1196
1197     reget_service_name_arg:
1198       if (!dbus_message_get_args (message, &error,
1199                                   DBUS_TYPE_STRING, &service_name,
1200                                   DBUS_TYPE_INVALID))
1201         {
1202           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1203             {
1204               dbus_error_free (&error);
1205               _dbus_wait_for_memory ();
1206               goto reget_service_name_arg;
1207             }
1208           else
1209             {
1210               _dbus_warn ("Message %s doesn't have a service name: %s\n",
1211                           "ServiceCreated",
1212                           error.message);
1213               dbus_error_free (&error);
1214               goto out;
1215             }
1216         }
1217
1218       if (*service_name != ':')
1219         {
1220           _dbus_warn ("Expected base service activation, got \"%s\" instead\n",
1221                       service_name);
1222           goto out;
1223         }
1224               
1225       base_service = service_name;
1226       service_name = NULL;
1227       
1228       scd.skip_connection = connection;
1229       scd.failed = FALSE;
1230       scd.expected_service_name = base_service;
1231       bus_test_clients_foreach (check_service_created_foreach,
1232                                 &scd);
1233       
1234       if (scd.failed)
1235         goto out;
1236     }
1237   else
1238     {
1239       warn_unexpected (connection, message, "ServiceCreated for base service");
1240
1241       goto out;
1242     }
1243
1244   retval = TRUE;
1245
1246   if (base_service_p)
1247     {
1248       *base_service_p = base_service;
1249       base_service = NULL;
1250     }
1251   
1252  out:
1253   if (message)
1254     dbus_message_unref (message);
1255
1256   if (base_service)
1257     dbus_free (base_service);
1258   
1259   return retval;
1260 }
1261
1262 static dbus_bool_t
1263 check_service_activated (BusContext     *context,
1264                          DBusConnection *connection,
1265                          const char     *activated_name,
1266                          const char     *base_service_name,
1267                          DBusMessage    *initial_message)
1268 {
1269   DBusMessage *message;
1270   dbus_bool_t retval;
1271   DBusError error;
1272   dbus_uint32_t activation_result;
1273   
1274   retval = FALSE;
1275   
1276   dbus_error_init (&error);
1277
1278   message = initial_message;
1279   dbus_message_ref (message);
1280
1281   if (dbus_message_is_signal (message,
1282                               DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1283                               "ServiceCreated"))
1284     {
1285       char *service_name;
1286       CheckServiceCreatedData scd;
1287
1288     reget_service_name_arg:
1289       if (!dbus_message_get_args (message, &error,
1290                                   DBUS_TYPE_STRING, &service_name,
1291                                   DBUS_TYPE_INVALID))
1292         {
1293           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1294             {
1295               dbus_error_free (&error);
1296               _dbus_wait_for_memory ();
1297               goto reget_service_name_arg;
1298             }
1299           else
1300             {
1301               _dbus_warn ("Message %s doesn't have a service name: %s\n",
1302                           "ServiceCreated",
1303                           error.message);
1304               dbus_error_free (&error);
1305               goto out;
1306             }
1307         }
1308
1309       if (strcmp (service_name, activated_name) != 0)
1310         {
1311           _dbus_warn ("Expected to see service %s created, saw %s instead\n",
1312                       activated_name, service_name);
1313           dbus_free (service_name);
1314           goto out;
1315         }
1316       
1317       scd.skip_connection = connection;
1318       scd.failed = FALSE;
1319       scd.expected_service_name = service_name;
1320       bus_test_clients_foreach (check_service_created_foreach,
1321                                 &scd);
1322           
1323       dbus_free (service_name);
1324
1325       if (scd.failed)
1326         goto out;
1327           
1328       dbus_message_unref (message);
1329       message = pop_message_waiting_for_memory (connection);
1330       if (message == NULL)
1331         {
1332           _dbus_warn ("Expected a reply to %s, got nothing\n",
1333                       "ActivateService");
1334           goto out;
1335         }
1336     }
1337   else
1338     {
1339       warn_unexpected (connection, message, "ServiceCreated for the activated name");
1340       
1341       goto out;
1342     }
1343   
1344   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN)
1345     {
1346       warn_unexpected (connection, message, "reply to ActivateService");
1347
1348       goto out;
1349     }
1350
1351   activation_result = 0;
1352   if (!dbus_message_get_args (message, &error,
1353                               DBUS_TYPE_UINT32, &activation_result,
1354                               DBUS_TYPE_INVALID))
1355     {
1356       if (!dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1357         {
1358           _dbus_warn ("Did not have activation result first argument to %s: %s\n",
1359                       "ActivateService", error.message);
1360           dbus_error_free (&error);
1361           goto out;
1362         }
1363
1364       dbus_error_free (&error);
1365     }
1366   else
1367     {
1368       if (activation_result == DBUS_ACTIVATION_REPLY_ACTIVATED)
1369         ; /* Good */
1370       else if (activation_result == DBUS_ACTIVATION_REPLY_ALREADY_ACTIVE)
1371         ; /* Good also */
1372       else
1373         {
1374           _dbus_warn ("Activation result was 0x%x, no good.\n",
1375                       activation_result);
1376           goto out;
1377         }
1378     }
1379
1380   dbus_message_unref (message);
1381   message = NULL;
1382       
1383   if (!check_no_leftovers (context))
1384     {
1385       _dbus_warn ("Messages were left over after verifying existent activation results\n");
1386       goto out;
1387     }
1388
1389   retval = TRUE;
1390   
1391  out:
1392   if (message)
1393     dbus_message_unref (message);
1394   
1395   return retval;
1396 }
1397
1398 static dbus_bool_t
1399 check_service_deactivated (BusContext     *context,
1400                            DBusConnection *connection,
1401                            const char     *activated_name,
1402                            const char     *base_service)
1403 {
1404   DBusMessage *message;
1405   dbus_bool_t retval;
1406   DBusError error;
1407   CheckServiceDeletedData csdd;
1408
1409   message = NULL;
1410   retval = FALSE;
1411   
1412   dbus_error_init (&error);
1413
1414   /* Now we are expecting ServiceDeleted messages for the base
1415    * service and the activated_name.  The base service
1416    * notification is required to come last.
1417    */
1418   csdd.expected_service_name = activated_name;
1419   csdd.failed = FALSE;
1420   bus_test_clients_foreach (check_service_deleted_foreach,
1421                             &csdd);      
1422
1423   if (csdd.failed)
1424     goto out;
1425       
1426   csdd.expected_service_name = base_service;
1427   csdd.failed = FALSE;
1428   bus_test_clients_foreach (check_service_deleted_foreach,
1429                             &csdd);
1430
1431   if (csdd.failed)
1432     goto out;
1433       
1434   if (!check_no_leftovers (context))
1435     {
1436       _dbus_warn ("Messages were left over after verifying results of service exiting\n");
1437       goto out;
1438     }
1439
1440   retval = TRUE;
1441   
1442  out:
1443   if (message)
1444     dbus_message_unref (message);
1445   
1446   return retval;
1447 }
1448
1449 static dbus_bool_t
1450 check_send_exit_to_service (BusContext     *context,
1451                             DBusConnection *connection,
1452                             const char     *service_name,
1453                             const char     *base_service)
1454 {
1455   dbus_bool_t got_error;
1456   DBusMessage *message;
1457   dbus_uint32_t serial;
1458   dbus_bool_t retval;
1459   
1460   _dbus_verbose ("Sending exit message to the test service\n");
1461
1462   retval = FALSE;
1463   
1464   /* Kill off the test service by sending it a quit message */
1465   message = dbus_message_new_method_call (service_name,
1466                                           "/org/freedesktop/TestSuite",
1467                                           "org.freedesktop.TestSuite",
1468                                           "Exit");
1469       
1470   if (message == NULL)
1471     {
1472       /* Do this again; we still need the service to exit... */
1473       if (!check_send_exit_to_service (context, connection,
1474                                        service_name, base_service))
1475         goto out;
1476       
1477       return TRUE;
1478     }
1479       
1480   if (!dbus_connection_send (connection, message, &serial))
1481     {
1482       dbus_message_unref (message);
1483
1484       /* Do this again; we still need the service to exit... */
1485       if (!check_send_exit_to_service (context, connection,
1486                                        service_name, base_service))
1487         goto out;
1488       
1489       return TRUE;
1490     }
1491
1492   dbus_message_unref (message);
1493   message = NULL;
1494
1495   /* send message */
1496   bus_test_run_clients_loop (TRUE);
1497
1498   /* read it in and write it out to test service */
1499   bus_test_run_bus_loop (context, FALSE);
1500
1501   /* see if we got an error during message bus dispatching */
1502   bus_test_run_clients_loop (FALSE);
1503   message = dbus_connection_borrow_message (connection);
1504   got_error = message != NULL && dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR;
1505   if (message)
1506     {
1507       dbus_connection_return_message (connection, message);
1508       message = NULL;
1509     }
1510           
1511   if (!got_error)
1512     {
1513       /* If no error, wait for the test service to exit */
1514       block_connection_until_message_from_bus (context, connection);
1515               
1516       bus_test_run_everything (context);
1517     }
1518
1519   if (got_error)
1520     {
1521       message = pop_message_waiting_for_memory (connection);
1522       _dbus_assert (message != NULL);
1523
1524       if (!dbus_message_is_error (message,
1525                                   DBUS_ERROR_NO_MEMORY))
1526         {
1527           warn_unexpected (connection, message,
1528                            "a no memory error from asking test service to exit");
1529           goto out;
1530         }
1531
1532       _dbus_verbose ("Got error %s when asking test service to exit\n",
1533                      dbus_message_get_error_name (message));
1534
1535       /* Do this again; we still need the service to exit... */
1536       if (!check_send_exit_to_service (context, connection,
1537                                        service_name, base_service))
1538         goto out;
1539     }
1540   else
1541     {
1542       if (!check_service_deactivated (context, connection,
1543                                       service_name, base_service))
1544         goto out;
1545     }
1546
1547   retval = TRUE;
1548   
1549  out:
1550   if (message)
1551     dbus_message_unref (message);
1552   
1553   return retval;
1554 }
1555
1556 static dbus_bool_t
1557 check_got_error (BusContext     *context,
1558                  DBusConnection *connection,
1559                  const char     *first_error_name,
1560                  ...)
1561 {
1562   DBusMessage *message;
1563   dbus_bool_t retval;
1564   va_list ap;
1565   dbus_bool_t error_found;
1566   const char *error_name;
1567   
1568   retval = FALSE;
1569   
1570   message = pop_message_waiting_for_memory (connection);
1571   if (message == NULL)
1572     {
1573       _dbus_warn ("Did not get an expected error\n");
1574       goto out;
1575     }
1576
1577   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
1578     {
1579       warn_unexpected (connection, message, "an error");
1580
1581       goto out;
1582     }
1583
1584   error_found = FALSE;
1585
1586   va_start (ap, first_error_name);
1587   error_name = first_error_name;
1588   while (error_name != NULL)
1589     {
1590       if (dbus_message_is_error (message, error_name))
1591         {
1592           error_found = TRUE;
1593           break;
1594         }
1595       error_name = va_arg (ap, char*);
1596     }
1597   va_end (ap);
1598
1599   if (!error_found)
1600     {
1601       _dbus_warn ("Expected error %s or other, got %s instead\n",
1602                   first_error_name,
1603                   dbus_message_get_error_name (message));
1604       goto out;
1605     }
1606
1607   retval = TRUE;
1608   
1609  out:
1610   if (message)
1611     dbus_message_unref (message);
1612   
1613   return retval;
1614 }
1615           
1616 #define EXISTENT_SERVICE_NAME "org.freedesktop.DBus.TestSuiteEchoService"
1617
1618 /* returns TRUE if the correct thing happens,
1619  * but the correct thing may include OOM errors.
1620  */
1621 static dbus_bool_t
1622 check_existent_service_activation (BusContext     *context,
1623                                    DBusConnection *connection)
1624 {
1625   DBusMessage *message;
1626   dbus_uint32_t serial;
1627   dbus_bool_t retval;
1628   DBusError error;
1629   char *base_service;
1630
1631   base_service = NULL;
1632   
1633   dbus_error_init (&error);
1634   
1635   message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
1636                                           DBUS_PATH_ORG_FREEDESKTOP_DBUS,
1637                                           DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1638                                           "ActivateService");
1639
1640   if (message == NULL)
1641     return TRUE;
1642
1643   if (!dbus_message_append_args (message,
1644                                  DBUS_TYPE_STRING, EXISTENT_SERVICE_NAME,
1645                                  DBUS_TYPE_UINT32, 0,
1646                                  DBUS_TYPE_INVALID))
1647     {
1648       dbus_message_unref (message);
1649       return TRUE;
1650     }
1651   
1652   if (!dbus_connection_send (connection, message, &serial))
1653     {
1654       dbus_message_unref (message);
1655       return TRUE;
1656     }
1657
1658   dbus_message_unref (message);
1659   message = NULL;
1660
1661   bus_test_run_everything (context);
1662
1663   /* now wait for the message bus to hear back from the activated
1664    * service.
1665    */
1666   block_connection_until_message_from_bus (context, connection);
1667
1668   bus_test_run_everything (context);
1669
1670   if (!dbus_connection_get_is_connected (connection))
1671     {
1672       _dbus_verbose ("connection was disconnected\n");
1673       return TRUE;
1674     }
1675   
1676   retval = FALSE;
1677   
1678   message = pop_message_waiting_for_memory (connection);
1679   if (message == NULL)
1680     {
1681       _dbus_warn ("Did not receive any messages after %s %d on %p\n",
1682                   "ActivateService", serial, connection);
1683       goto out;
1684     }
1685
1686   verbose_message_received (connection, message);
1687   _dbus_verbose ("  (after sending %s)\n", "ActivateService");
1688
1689   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1690     {
1691       if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
1692         {
1693           _dbus_warn ("Message has wrong sender %s\n",
1694                       dbus_message_get_sender (message) ?
1695                       dbus_message_get_sender (message) : "(none)");
1696           goto out;
1697         }
1698       
1699       if (dbus_message_is_error (message,
1700                                  DBUS_ERROR_NO_MEMORY))
1701         {
1702           ; /* good, this is a valid response */
1703         }
1704       else if (dbus_message_is_error (message,
1705                                       DBUS_ERROR_SPAWN_CHILD_EXITED))
1706         {
1707           ; /* good, this is expected also */
1708         }
1709       else
1710         {
1711           _dbus_warn ("Did not expect error %s\n",
1712                       dbus_message_get_error_name (message));
1713           goto out;
1714         }
1715     }
1716   else
1717     {
1718       dbus_bool_t got_service_deleted;
1719       dbus_bool_t got_error;
1720       
1721       if (!check_base_service_activated (context, connection,
1722                                          message, &base_service))
1723         goto out;
1724
1725       dbus_message_unref (message);
1726       message = NULL;
1727
1728       /* We may need to block here for the test service to exit or finish up */
1729       block_connection_until_message_from_bus (context, connection);
1730       
1731       message = dbus_connection_borrow_message (connection);
1732       if (message == NULL)
1733         {
1734           _dbus_warn ("Did not receive any messages after base service creation notification\n");
1735           goto out;
1736         }
1737
1738       got_service_deleted = dbus_message_is_signal (message,
1739                                                     DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1740                                                     "ServiceDeleted");
1741       got_error = dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR;
1742       
1743       dbus_connection_return_message (connection, message);
1744       message = NULL;
1745
1746       if (got_error)
1747         {
1748           if (!check_got_error (context, connection,
1749                                 DBUS_ERROR_SPAWN_CHILD_EXITED,
1750                                 DBUS_ERROR_NO_MEMORY,
1751                                 NULL))
1752             goto out;
1753
1754           /* A service deleted should be coming along now after this error.
1755            * We can also get the error *after* the service deleted.
1756            */
1757           got_service_deleted = TRUE;
1758         }
1759       
1760       if (got_service_deleted)
1761         {
1762           /* The service started up and got a base address, but then
1763            * failed to register under EXISTENT_SERVICE_NAME
1764            */
1765           CheckServiceDeletedData csdd;
1766           
1767           csdd.expected_service_name = base_service;
1768           csdd.failed = FALSE;
1769           bus_test_clients_foreach (check_service_deleted_foreach,
1770                                     &csdd);
1771
1772           if (csdd.failed)
1773             goto out;
1774
1775           /* Now we should get an error about the service exiting
1776            * if we didn't get it before.
1777            */
1778           if (!got_error)
1779             {
1780               block_connection_until_message_from_bus (context, connection);
1781               
1782               /* and process everything again */
1783               bus_test_run_everything (context);
1784               
1785               if (!check_got_error (context, connection,
1786                                     DBUS_ERROR_SPAWN_CHILD_EXITED,
1787                                     NULL))
1788                 goto out;
1789             }
1790         }
1791       else
1792         {
1793           message = pop_message_waiting_for_memory (connection);
1794           if (message == NULL)
1795             {
1796               _dbus_warn ("Failed to pop message we just put back! should have been a ServiceCreated\n");
1797               goto out;
1798             }
1799           
1800           if (!check_service_activated (context, connection, EXISTENT_SERVICE_NAME,
1801                                         base_service, message))
1802             goto out;
1803           
1804           dbus_message_unref (message);
1805           message = NULL;
1806
1807
1808           if (!check_no_leftovers (context))
1809             {
1810               _dbus_warn ("Messages were left over after successful activation\n");
1811               goto out;
1812             }
1813
1814           if (!check_send_exit_to_service (context, connection,
1815                                            EXISTENT_SERVICE_NAME, base_service))
1816             goto out;
1817         }
1818     }
1819   
1820   retval = TRUE;
1821   
1822  out:
1823   if (message)
1824     dbus_message_unref (message);
1825
1826   if (base_service)
1827     dbus_free (base_service);
1828   
1829   return retval;
1830 }
1831
1832 /* returns TRUE if the correct thing happens,
1833  * but the correct thing may include OOM errors.
1834  */
1835 static dbus_bool_t
1836 check_segfault_service_activation (BusContext     *context,
1837                                    DBusConnection *connection)
1838 {
1839   DBusMessage *message;
1840   dbus_uint32_t serial;
1841   dbus_bool_t retval;
1842   DBusError error;
1843   
1844   dbus_error_init (&error);
1845   
1846   message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
1847                                           DBUS_PATH_ORG_FREEDESKTOP_DBUS,
1848                                           DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1849                                           "ActivateService");
1850
1851   if (message == NULL)
1852     return TRUE;
1853
1854   if (!dbus_message_append_args (message,
1855                                  DBUS_TYPE_STRING,
1856                                  "org.freedesktop.DBus.TestSuiteSegfaultService",
1857                                  DBUS_TYPE_UINT32, 0,
1858                                  DBUS_TYPE_INVALID))
1859     {
1860       dbus_message_unref (message);
1861       return TRUE;
1862     }
1863   
1864   if (!dbus_connection_send (connection, message, &serial))
1865     {
1866       dbus_message_unref (message);
1867       return TRUE;
1868     }
1869
1870   dbus_message_unref (message);
1871   message = NULL;
1872
1873   bus_test_run_everything (context);
1874   block_connection_until_message_from_bus (context, connection);
1875   bus_test_run_everything (context);
1876
1877   if (!dbus_connection_get_is_connected (connection))
1878     {
1879       _dbus_verbose ("connection was disconnected\n");
1880       return TRUE;
1881     }
1882   
1883   retval = FALSE;
1884   
1885   message = pop_message_waiting_for_memory (connection);
1886   if (message == NULL)
1887     {
1888       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1889                   "ActivateService", serial, connection);
1890       goto out;
1891     }
1892
1893   verbose_message_received (connection, message);
1894
1895   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1896     {
1897       if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
1898         {
1899           _dbus_warn ("Message has wrong sender %s\n",
1900                       dbus_message_get_sender (message) ?
1901                       dbus_message_get_sender (message) : "(none)");
1902           goto out;
1903         }
1904       
1905       if (dbus_message_is_error (message,
1906                                  DBUS_ERROR_NO_MEMORY))
1907         {
1908           ; /* good, this is a valid response */
1909         }
1910       else if (dbus_message_is_error (message,
1911                                       DBUS_ERROR_SPAWN_CHILD_SIGNALED))
1912         {
1913           ; /* good, this is expected also */
1914         }
1915       else
1916         {
1917           warn_unexpected (connection, message, "not this error");
1918
1919           goto out;
1920         }
1921     }
1922   else
1923     {
1924       _dbus_warn ("Did not expect to successfully activate segfault service\n");
1925       goto out;
1926     }
1927
1928   retval = TRUE;
1929   
1930  out:
1931   if (message)
1932     dbus_message_unref (message);
1933   
1934   return retval;
1935 }
1936
1937 typedef struct
1938 {
1939   Check1Func func;
1940   BusContext *context;
1941 } Check1Data;
1942
1943 static dbus_bool_t
1944 check_oom_check1_func (void *data)
1945 {
1946   Check1Data *d = data;
1947
1948   if (! (* d->func) (d->context))
1949     return FALSE;
1950   
1951   if (!check_no_leftovers (d->context))
1952     {
1953       _dbus_warn ("Messages were left over, should be covered by test suite\n");
1954       return FALSE;
1955     }
1956
1957   return TRUE;
1958 }
1959
1960 static void
1961 check1_try_iterations (BusContext *context,
1962                        const char *description,
1963                        Check1Func  func)
1964 {
1965   Check1Data d;
1966
1967   d.func = func;
1968   d.context = context;
1969
1970   if (!_dbus_test_oom_handling (description, check_oom_check1_func,
1971                                 &d))
1972     _dbus_assert_not_reached ("test failed");
1973 }
1974
1975 typedef struct
1976 {
1977   Check2Func func;
1978   BusContext *context;
1979   DBusConnection *connection;
1980 } Check2Data;
1981
1982 static dbus_bool_t
1983 check_oom_check2_func (void *data)
1984 {
1985   Check2Data *d = data;
1986
1987   if (! (* d->func) (d->context, d->connection))
1988     return FALSE;
1989   
1990   if (!check_no_leftovers (d->context))
1991     {
1992       _dbus_warn ("Messages were left over, should be covered by test suite");
1993       return FALSE;
1994     }
1995
1996   return TRUE;
1997 }
1998
1999 static void
2000 check2_try_iterations (BusContext     *context,
2001                        DBusConnection *connection,
2002                        const char     *description,
2003                        Check2Func      func)
2004 {
2005   Check2Data d;
2006
2007   d.func = func;
2008   d.context = context;
2009   d.connection = connection;
2010   
2011   if (!_dbus_test_oom_handling (description, check_oom_check2_func,
2012                                 &d))
2013     _dbus_assert_not_reached ("test failed");
2014 }
2015
2016 dbus_bool_t
2017 bus_dispatch_test (const DBusString *test_data_dir)
2018 {
2019   BusContext *context;
2020   DBusConnection *foo;
2021   DBusConnection *bar;
2022   DBusConnection *baz;
2023   DBusError error;
2024
2025   dbus_error_init (&error);
2026   
2027   context = bus_context_new_test (test_data_dir,
2028                                   "valid-config-files/debug-allow-all.conf");
2029   if (context == NULL)
2030     return FALSE;
2031   
2032   foo = dbus_connection_open ("debug-pipe:name=test-server", &error);
2033   if (foo == NULL)
2034     _dbus_assert_not_reached ("could not alloc connection");
2035
2036   if (!bus_setup_debug_client (foo))
2037     _dbus_assert_not_reached ("could not set up connection");
2038
2039   if (!check_hello_message (context, foo))
2040     _dbus_assert_not_reached ("hello message failed");
2041
2042   if (!check_add_match_all (context, foo))
2043     _dbus_assert_not_reached ("AddMatch message failed");
2044   
2045   bar = dbus_connection_open ("debug-pipe:name=test-server", &error);
2046   if (bar == NULL)
2047     _dbus_assert_not_reached ("could not alloc connection");
2048
2049   if (!bus_setup_debug_client (bar))
2050     _dbus_assert_not_reached ("could not set up connection");
2051
2052   if (!check_hello_message (context, bar))
2053     _dbus_assert_not_reached ("hello message failed");
2054
2055   if (!check_add_match_all (context, bar))
2056     _dbus_assert_not_reached ("AddMatch message failed");
2057   
2058   baz = dbus_connection_open ("debug-pipe:name=test-server", &error);
2059   if (baz == NULL)
2060     _dbus_assert_not_reached ("could not alloc connection");
2061
2062   if (!bus_setup_debug_client (baz))
2063     _dbus_assert_not_reached ("could not set up connection");
2064
2065   if (!check_hello_message (context, baz))
2066     _dbus_assert_not_reached ("hello message failed");
2067
2068   if (!check_add_match_all (context, baz))
2069     _dbus_assert_not_reached ("AddMatch message failed");
2070   
2071   if (!check_no_leftovers (context))
2072     {
2073       _dbus_warn ("Messages were left over after setting up initial connections");
2074       _dbus_assert_not_reached ("initial connection setup failed");
2075     }
2076   
2077   check1_try_iterations (context, "create_and_hello",
2078                          check_hello_connection);
2079   
2080   check2_try_iterations (context, foo, "nonexistent_service_activation",
2081                          check_nonexistent_service_activation);
2082
2083   check2_try_iterations (context, foo, "segfault_service_activation",
2084                          check_segfault_service_activation);
2085   
2086   check2_try_iterations (context, foo, "existent_service_activation",
2087                          check_existent_service_activation);
2088   
2089   _dbus_verbose ("Disconnecting foo, bar, and baz\n");
2090
2091   kill_client_connection_unchecked (foo);
2092   kill_client_connection_unchecked (bar);
2093   kill_client_connection_unchecked (baz);
2094
2095   bus_context_unref (context);
2096   
2097   return TRUE;
2098 }
2099
2100 dbus_bool_t
2101 bus_dispatch_sha1_test (const DBusString *test_data_dir)
2102 {
2103   BusContext *context;
2104   DBusConnection *foo;
2105   DBusError error;
2106
2107   dbus_error_init (&error);
2108   
2109   /* Test SHA1 authentication */
2110   _dbus_verbose ("Testing SHA1 context\n");
2111   
2112   context = bus_context_new_test (test_data_dir,
2113                                   "valid-config-files/debug-allow-all-sha1.conf");
2114   if (context == NULL)
2115     return FALSE;
2116
2117   foo = dbus_connection_open ("debug-pipe:name=test-server", &error);
2118   if (foo == NULL)
2119     _dbus_assert_not_reached ("could not alloc connection");
2120
2121   if (!bus_setup_debug_client (foo))
2122     _dbus_assert_not_reached ("could not set up connection");
2123
2124   if (!check_hello_message (context, foo))
2125     _dbus_assert_not_reached ("hello message failed");
2126
2127   if (!check_add_match_all (context, foo))
2128     _dbus_assert_not_reached ("addmatch message failed");
2129   
2130   if (!check_no_leftovers (context))
2131     {
2132       _dbus_warn ("Messages were left over after setting up initial SHA-1 connection\n");
2133       _dbus_assert_not_reached ("initial connection setup failed");
2134     }
2135   
2136   check1_try_iterations (context, "create_and_hello_sha1",
2137                          check_hello_connection);
2138
2139   kill_client_connection_unchecked (foo);
2140
2141   bus_context_unref (context);
2142
2143   return TRUE;
2144 }
2145
2146 #endif /* DBUS_BUILD_TESTS */