* dbus/dbus-sysdeps.c (_dbus_user_at_console): fix memleak in OOM.
[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  * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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,
97                                       bus_context_get_connections (context),
98                                       sender, addressed_recipient, message,
99                                       &recipients))
100     {
101       BUS_SET_OOM (error);
102       return FALSE;
103     }
104
105   link = _dbus_list_get_first_link (&recipients);
106   while (link != NULL)
107     {
108       DBusConnection *dest;
109
110       dest = link->data;
111
112       if (!send_one_message (dest, context, sender, addressed_recipient,
113                              message, transaction, &tmp_error))
114         break;
115
116       link = _dbus_list_get_next_link (&recipients, link);
117     }
118
119   _dbus_list_clear (&recipients);
120   
121   if (dbus_error_is_set (&tmp_error))
122     {
123       dbus_move_error (&tmp_error, error);
124       return FALSE;
125     }
126   else
127     return TRUE;
128 }
129
130 static DBusHandlerResult
131 bus_dispatch (DBusConnection *connection,
132               DBusMessage    *message)
133 {
134   const char *sender, *service_name;
135   DBusError error;
136   BusTransaction *transaction;
137   BusContext *context;
138   DBusHandlerResult result;
139   DBusConnection *addressed_recipient;
140   
141   result = DBUS_HANDLER_RESULT_HANDLED;
142   
143   transaction = NULL;
144   addressed_recipient = NULL;
145   dbus_error_init (&error);
146   
147   context = bus_connection_get_context (connection);
148   _dbus_assert (context != NULL);
149   
150   /* If we can't even allocate an OOM error, we just go to sleep
151    * until we can.
152    */
153   while (!bus_connection_preallocate_oom_error (connection))
154     _dbus_wait_for_memory ();
155   
156   /* Ref connection in case we disconnect it at some point in here */
157   dbus_connection_ref (connection);
158   
159   service_name = dbus_message_get_destination (message);
160
161 #ifdef DBUS_ENABLE_VERBOSE_MODE
162   {
163     const char *interface_name, *member_name, *error_name;
164
165     interface_name = dbus_message_get_interface (message);
166     member_name = dbus_message_get_member (message);
167     error_name = dbus_message_get_error_name (message);
168     
169     _dbus_verbose ("DISPATCH: %s %s %s to %s\n",
170                    interface_name ? interface_name : "(no interface)",
171                    member_name ? member_name : "(no member)",
172                    error_name ? error_name : "(no error name)",
173                    service_name ? service_name : "peer");
174   }
175 #endif /* DBUS_ENABLE_VERBOSE_MODE */
176   
177   /* If service_name is NULL, if it's a signal we send it to all
178    * connections with a match rule. If it's not a signal, there
179    * are some special cases here but mostly we just bail out.
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 && dbus_message_get_auto_activation (message))
263         {
264           BusActivation *activation;
265
266           /* We can't do the security policy check here, since the addressed
267            * recipient service doesn't exist yet. We do it before sending the
268            * message after the service has been created.
269            */
270           activation = bus_connection_get_activation (connection);
271
272           if (!bus_activation_activate_service (activation, connection, transaction, TRUE,
273                                                 message, service_name, &error))
274             {
275               _DBUS_ASSERT_ERROR_IS_SET (&error);
276               _dbus_verbose ("bus_activation_activate_service() failed\n");
277               goto out;
278             }
279           
280           goto out;
281         }
282       else if (service == NULL)
283         {
284           dbus_set_error (&error,
285                           DBUS_ERROR_SERVICE_DOES_NOT_EXIST,
286                           "Service \"%s\" does not exist",
287                           service_name);
288           goto out;
289         }
290       else
291         {          
292           addressed_recipient = bus_service_get_primary_owner (service);
293           _dbus_assert (addressed_recipient != NULL);
294           
295           if (!bus_context_check_security_policy (context, transaction,
296                                                   connection, addressed_recipient,
297                                                   addressed_recipient,
298                                                   message, &error))
299             goto out;
300           
301           /* Dispatch the message */
302           if (!bus_transaction_send (transaction, addressed_recipient, message))
303             {
304               BUS_SET_OOM (&error);
305               goto out;
306             }
307         }
308     }
309
310   /* Now match the messages against any match rules, which will send
311    * out signals and such. addressed_recipient may == NULL.
312    */
313   if (!bus_dispatch_matches (transaction, connection, addressed_recipient, message, &error))
314     goto out;
315   
316  out:
317   if (dbus_error_is_set (&error))
318     {
319       if (!dbus_connection_get_is_connected (connection))
320         {
321           /* If we disconnected it, we won't bother to send it any error
322            * messages.
323            */
324           _dbus_verbose ("Not sending error to connection we disconnected\n");
325         }
326       else if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
327         {
328           bus_connection_send_oom_error (connection, message);
329
330           /* cancel transaction due to OOM */
331           if (transaction != NULL)
332             {
333               bus_transaction_cancel_and_free (transaction);
334               transaction = NULL;
335             }
336         }
337       else
338         {
339           /* Try to send the real error, if no mem to do that, send
340            * the OOM error
341            */
342           _dbus_assert (transaction != NULL);
343           
344           if (!bus_transaction_send_error_reply (transaction, connection,
345                                                  &error, message))
346             {
347               bus_connection_send_oom_error (connection, message);
348               
349               /* cancel transaction due to OOM */
350               if (transaction != NULL)
351                 {
352                   bus_transaction_cancel_and_free (transaction);
353                   transaction = NULL;
354                 }
355             }
356         }
357       
358       dbus_error_free (&error);
359     }
360
361   if (transaction != NULL)
362     {
363       bus_transaction_execute_and_free (transaction);
364     }
365
366   dbus_connection_unref (connection);
367
368   return result;
369 }
370
371 static DBusHandlerResult
372 bus_dispatch_message_filter (DBusConnection     *connection,
373                              DBusMessage        *message,
374                              void               *user_data)
375 {
376   return bus_dispatch (connection, message);
377 }
378
379 dbus_bool_t
380 bus_dispatch_add_connection (DBusConnection *connection)
381 {  
382   if (!dbus_connection_add_filter (connection,
383                                    bus_dispatch_message_filter,
384                                    NULL, NULL))
385     return FALSE;
386   
387   return TRUE;
388 }
389
390 void
391 bus_dispatch_remove_connection (DBusConnection *connection)
392 {
393   /* Here we tell the bus driver that we want to get off. */
394   bus_driver_remove_connection (connection);
395
396   dbus_connection_remove_filter (connection,
397                                  bus_dispatch_message_filter,
398                                  NULL);
399 }
400
401 #ifdef DBUS_BUILD_TESTS
402
403 #include <stdio.h>
404
405 typedef dbus_bool_t (* Check1Func) (BusContext     *context);
406 typedef dbus_bool_t (* Check2Func) (BusContext     *context,
407                                     DBusConnection *connection);
408
409 static dbus_bool_t check_no_leftovers (BusContext *context);
410
411 static void
412 block_connection_until_message_from_bus (BusContext     *context,
413                                          DBusConnection *connection)
414 {
415   while (dbus_connection_get_dispatch_status (connection) ==
416          DBUS_DISPATCH_COMPLETE &&
417          dbus_connection_get_is_connected (connection))
418     {
419       bus_test_run_bus_loop (context, TRUE);
420       bus_test_run_clients_loop (FALSE);
421     }
422 }
423
424 /* compensate for fact that pop_message() can return #NULL due to OOM */
425 static DBusMessage*
426 pop_message_waiting_for_memory (DBusConnection *connection)
427 {
428   while (dbus_connection_get_dispatch_status (connection) ==
429          DBUS_DISPATCH_NEED_MEMORY)
430     _dbus_wait_for_memory ();
431
432   return dbus_connection_pop_message (connection);
433 }
434
435 static DBusMessage*
436 borrow_message_waiting_for_memory (DBusConnection *connection)
437 {
438   while (dbus_connection_get_dispatch_status (connection) ==
439          DBUS_DISPATCH_NEED_MEMORY)
440     _dbus_wait_for_memory ();
441
442   return dbus_connection_borrow_message (connection);
443 }
444
445 static void
446 warn_unexpected_real (DBusConnection *connection,
447                       DBusMessage    *message,
448                       const char     *expected,
449                       const char     *function,
450                       int             line)
451 {
452   if (message)
453     _dbus_warn ("%s:%d received message interface \"%s\" member \"%s\" error name \"%s\" on %p, expecting %s\n",
454                 function, line,
455                 dbus_message_get_interface (message) ?
456                 dbus_message_get_interface (message) : "(unset)",
457                 dbus_message_get_member (message) ?
458                 dbus_message_get_member (message) : "(unset)",
459                 dbus_message_get_error_name (message) ?
460                 dbus_message_get_error_name (message) : "(unset)",
461                 connection,
462                 expected);
463   else
464     _dbus_warn ("%s:%d received no message on %p, expecting %s\n",
465                 function, line, connection, expected);
466 }
467
468 #define warn_unexpected(connection, message, expected) \
469   warn_unexpected_real (connection, message, expected, _DBUS_FUNCTION_NAME, __LINE__)
470
471 static void
472 verbose_message_received (DBusConnection *connection,
473                           DBusMessage    *message)
474 {
475   _dbus_verbose ("Received message interface \"%s\" member \"%s\" error name \"%s\" on %p\n",
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 }
484
485 typedef struct
486 {
487   const char *expected_service_name;
488   dbus_bool_t failed;
489 } CheckServiceDeletedData;
490
491 static dbus_bool_t
492 check_service_deleted_foreach (DBusConnection *connection,
493                                void           *data)
494 {
495   CheckServiceDeletedData *d = data;
496   DBusMessage *message;
497   DBusError error;
498   char *service_name;
499
500   dbus_error_init (&error);
501   d->failed = TRUE;
502   service_name = NULL;
503   
504   message = pop_message_waiting_for_memory (connection);
505   if (message == NULL)
506     {
507       _dbus_warn ("Did not receive a message on %p, expecting %s\n",
508                   connection, "ServiceDeleted");
509       goto out;
510     }
511   else if (!dbus_message_is_signal (message,
512                                     DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
513                                     "ServiceDeleted"))
514     {
515       warn_unexpected (connection, message, "ServiceDeleted");
516
517       goto out;
518     }
519   else
520     {
521       if (!dbus_message_get_args (message, &error,
522                                   DBUS_TYPE_STRING, &service_name,
523                                   DBUS_TYPE_INVALID))
524         {
525           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
526             {
527               _dbus_verbose ("no memory to get service name arg\n");
528             }
529           else
530             {
531               _dbus_assert (dbus_error_is_set (&error));
532               _dbus_warn ("Did not get the expected single string argument\n");
533               goto out;
534             }
535         }
536       else if (strcmp (service_name, d->expected_service_name) != 0)
537         {
538           _dbus_warn ("expected deletion of service %s, got deletion of %s\n",
539                       d->expected_service_name,
540                       service_name);
541           goto out;
542         }
543     }
544
545   d->failed = FALSE;
546   
547  out:
548   dbus_free (service_name);
549   dbus_error_free (&error);
550   
551   if (message)
552     dbus_message_unref (message);
553
554   return !d->failed;
555 }
556
557 static void
558 kill_client_connection (BusContext     *context,
559                         DBusConnection *connection)
560 {
561   char *base_service;
562   const char *s;
563   CheckServiceDeletedData csdd;
564
565   _dbus_verbose ("killing connection %p\n", connection);
566   
567   s = dbus_bus_get_base_service (connection);
568   _dbus_assert (s != NULL);
569
570   while ((base_service = _dbus_strdup (s)) == NULL)
571     _dbus_wait_for_memory ();
572
573   dbus_connection_ref (connection);
574   
575   /* kick in the disconnect handler that unrefs the connection */
576   dbus_connection_disconnect (connection);
577
578   bus_test_run_everything (context);
579   
580   _dbus_assert (bus_test_client_listed (connection));
581   
582   /* Run disconnect handler in test.c */
583   if (bus_connection_dispatch_one_message (connection))
584     _dbus_assert_not_reached ("something received on connection being killed other than the disconnect");
585   
586   _dbus_assert (!dbus_connection_get_is_connected (connection));
587   dbus_connection_unref (connection);
588   connection = NULL;
589   _dbus_assert (!bus_test_client_listed (connection));
590   
591   csdd.expected_service_name = base_service;
592   csdd.failed = FALSE;
593
594   bus_test_clients_foreach (check_service_deleted_foreach,
595                             &csdd);
596
597   dbus_free (base_service);
598   
599   if (csdd.failed)
600     _dbus_assert_not_reached ("didn't get the expected ServiceDeleted messages");
601   
602   if (!check_no_leftovers (context))
603     _dbus_assert_not_reached ("stuff left in message queues after disconnecting a client");
604 }
605
606 static void
607 kill_client_connection_unchecked (DBusConnection *connection)
608 {
609   /* This kills the connection without expecting it to affect
610    * the rest of the bus.
611    */  
612   _dbus_verbose ("Unchecked kill of connection %p\n", connection);
613
614   dbus_connection_ref (connection);
615   dbus_connection_disconnect (connection);
616   /* dispatching disconnect handler will unref once */
617   if (bus_connection_dispatch_one_message (connection))
618     _dbus_assert_not_reached ("message other than disconnect dispatched after failure to register");
619
620   _dbus_assert (!bus_test_client_listed (connection));
621   dbus_connection_unref (connection);
622 }
623
624 typedef struct
625 {
626   dbus_bool_t failed;
627 } CheckNoMessagesData;
628
629 static dbus_bool_t
630 check_no_messages_foreach (DBusConnection *connection,
631                            void           *data)
632 {
633   CheckNoMessagesData *d = data;
634   DBusMessage *message;
635
636   message = pop_message_waiting_for_memory (connection);
637   if (message != NULL)
638     {
639       warn_unexpected (connection, message, "no messages");
640
641       d->failed = TRUE;
642     }
643
644   if (message)
645     dbus_message_unref (message);
646   return !d->failed;
647 }
648
649 typedef struct
650 {
651   DBusConnection *skip_connection;
652   const char *expected_service_name;
653   dbus_bool_t failed;
654 } CheckServiceCreatedData;
655
656 static dbus_bool_t
657 check_service_created_foreach (DBusConnection *connection,
658                                void           *data)
659 {
660   CheckServiceCreatedData *d = data;
661   DBusMessage *message;
662   DBusError error;
663   char *service_name;
664
665   if (connection == d->skip_connection)
666     return TRUE;
667
668   dbus_error_init (&error);
669   d->failed = TRUE;
670   service_name = NULL;
671   
672   message = pop_message_waiting_for_memory (connection);
673   if (message == NULL)
674     {
675       _dbus_warn ("Did not receive a message on %p, expecting %s\n",
676                   connection, "ServiceCreated");
677       goto out;
678     }
679   else if (!dbus_message_is_signal (message,
680                                     DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
681                                     "ServiceCreated"))
682     {
683       warn_unexpected (connection, message, "ServiceCreated");
684       goto out;
685     }
686   else
687     {
688       if (!dbus_message_get_args (message, &error,
689                                   DBUS_TYPE_STRING, &service_name,
690                                   DBUS_TYPE_INVALID))
691         {
692           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
693             {
694               _dbus_verbose ("no memory to get service name arg\n");
695             }
696           else
697             {
698               _dbus_assert (dbus_error_is_set (&error));
699               _dbus_warn ("Did not get the expected single string argument\n");
700               goto out;
701             }
702         }
703       else if (strcmp (service_name, d->expected_service_name) != 0)
704         {
705           _dbus_warn ("expected creation of service %s, got creation of %s\n",
706                       d->expected_service_name,
707                       service_name);
708           goto out;
709         }
710     }
711
712   d->failed = FALSE;
713   
714  out:
715   dbus_free (service_name);
716   dbus_error_free (&error);
717   
718   if (message)
719     dbus_message_unref (message);
720
721   return !d->failed;
722 }
723
724 static dbus_bool_t
725 check_no_leftovers (BusContext *context)
726 {
727   CheckNoMessagesData nmd;
728
729   nmd.failed = FALSE;
730   bus_test_clients_foreach (check_no_messages_foreach,
731                             &nmd);
732   
733   if (nmd.failed)
734     return FALSE;
735   else
736     return TRUE;
737 }
738
739 /* returns TRUE if the correct thing happens,
740  * but the correct thing may include OOM errors.
741  */
742 static dbus_bool_t
743 check_hello_message (BusContext     *context,
744                      DBusConnection *connection)
745 {
746   DBusMessage *message;
747   dbus_uint32_t serial;
748   dbus_bool_t retval;
749   DBusError error;
750   char *name;
751   char *acquired;
752
753   retval = FALSE;
754   dbus_error_init (&error);
755   name = NULL;
756   acquired = NULL;
757   message = NULL;
758
759   _dbus_verbose ("check_hello_message for %p\n", connection);
760   
761   message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
762                                           DBUS_PATH_ORG_FREEDESKTOP_DBUS,
763                                           DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
764                                           "Hello");
765
766   if (message == NULL)
767     return TRUE;
768
769   if (!dbus_connection_send (connection, message, &serial))
770     {
771       dbus_message_unref (message);
772       return TRUE;
773     }
774
775   dbus_message_unref (message);
776   message = NULL;
777
778   /* send our message */
779   bus_test_run_clients_loop (TRUE);
780
781   dbus_connection_ref (connection); /* because we may get disconnected */
782   block_connection_until_message_from_bus (context, connection);
783
784   if (!dbus_connection_get_is_connected (connection))
785     {
786       _dbus_verbose ("connection was disconnected\n");
787       
788       dbus_connection_unref (connection);
789       
790       return TRUE;
791     }
792
793   dbus_connection_unref (connection);
794   
795   message = pop_message_waiting_for_memory (connection);
796   if (message == NULL)
797     {
798       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
799                   "Hello", serial, connection);
800       goto out;
801     }
802
803   verbose_message_received (connection, message);
804
805   if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
806     {
807       _dbus_warn ("Message has wrong sender %s\n",
808                   dbus_message_get_sender (message) ?
809                   dbus_message_get_sender (message) : "(none)");
810       goto out;
811     }
812   
813   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
814     {
815       if (dbus_message_is_error (message,
816                                  DBUS_ERROR_NO_MEMORY))
817         {
818           ; /* good, this is a valid response */
819         }
820       else
821         {
822           warn_unexpected (connection, message, "not this error");
823
824           goto out;
825         }
826     }
827   else
828     {
829       CheckServiceCreatedData scd;
830       
831       if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
832         {
833           ; /* good, expected */
834         }
835       else
836         {
837           warn_unexpected (connection, message, "method return for Hello");
838
839           goto out;
840         }
841
842     retry_get_hello_name:
843       if (!dbus_message_get_args (message, &error,
844                                   DBUS_TYPE_STRING, &name,
845                                   DBUS_TYPE_INVALID))
846         {
847           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
848             {
849               _dbus_verbose ("no memory to get service name arg from hello\n");
850               dbus_error_free (&error);
851               _dbus_wait_for_memory ();
852               goto retry_get_hello_name;
853             }
854           else
855             {
856               _dbus_assert (dbus_error_is_set (&error));
857               _dbus_warn ("Did not get the expected single string argument to hello\n");
858               goto out;
859             }
860         }
861
862       _dbus_verbose ("Got hello name: %s\n", name);
863
864       while (!dbus_bus_set_base_service (connection, name))
865         _dbus_wait_for_memory ();
866       
867       scd.skip_connection = connection; /* we haven't done AddMatch so won't get it ourselves */
868       scd.failed = FALSE;
869       scd.expected_service_name = name;
870       bus_test_clients_foreach (check_service_created_foreach,
871                                 &scd);
872       
873       if (scd.failed)
874         goto out;
875       
876       /* Client should also have gotten ServiceAcquired */
877       dbus_message_unref (message);
878       message = pop_message_waiting_for_memory (connection);
879       if (message == NULL)
880         {
881           _dbus_warn ("Expecting %s, got nothing\n",
882                       "ServiceAcquired");
883           goto out;
884         }
885       
886     retry_get_acquired_name:
887       if (!dbus_message_get_args (message, &error,
888                                   DBUS_TYPE_STRING, &acquired,
889                                   DBUS_TYPE_INVALID))
890         {
891           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
892             {
893               _dbus_verbose ("no memory to get service name arg from acquired\n");
894               dbus_error_free (&error);
895               _dbus_wait_for_memory ();
896               goto retry_get_acquired_name;
897             }
898           else
899             {
900               _dbus_assert (dbus_error_is_set (&error));
901               _dbus_warn ("Did not get the expected single string argument to ServiceAcquired\n");
902               goto out;
903             }
904         }
905
906       _dbus_verbose ("Got acquired name: %s\n", acquired);
907
908       if (strcmp (acquired, name) != 0)
909         {
910           _dbus_warn ("Acquired name is %s but expected %s\n",
911                       acquired, name);
912           goto out;
913         }
914     }
915
916   if (!check_no_leftovers (context))
917     goto out;
918   
919   retval = TRUE;
920   
921  out:
922   dbus_error_free (&error);
923   
924   dbus_free (name);
925   dbus_free (acquired);
926   
927   if (message)
928     dbus_message_unref (message);
929   
930   return retval;
931 }
932
933 /* returns TRUE if the correct thing happens,
934  * but the correct thing may include OOM errors.
935  */
936 static dbus_bool_t
937 check_double_hello_message (BusContext     *context,
938                             DBusConnection *connection)
939 {
940   DBusMessage *message;
941   dbus_uint32_t serial;
942   dbus_bool_t retval;
943   DBusError error;
944
945   retval = FALSE;
946   dbus_error_init (&error);
947   message = NULL;
948
949   _dbus_verbose ("check_double_hello_message for %p\n", connection);
950   
951   message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
952                                           DBUS_PATH_ORG_FREEDESKTOP_DBUS,
953                                           DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
954                                           "Hello");
955
956   if (message == NULL)
957     return TRUE;
958
959   if (!dbus_connection_send (connection, message, &serial))
960     {
961       dbus_message_unref (message);
962       return TRUE;
963     }
964
965   dbus_message_unref (message);
966   message = NULL;
967
968   /* send our message */
969   bus_test_run_clients_loop (TRUE);
970
971   dbus_connection_ref (connection); /* because we may get disconnected */
972   block_connection_until_message_from_bus (context, connection);
973
974   if (!dbus_connection_get_is_connected (connection))
975     {
976       _dbus_verbose ("connection was disconnected\n");
977       
978       dbus_connection_unref (connection);
979       
980       return TRUE;
981     }
982
983   dbus_connection_unref (connection);
984   
985   message = pop_message_waiting_for_memory (connection);
986   if (message == NULL)
987     {
988       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
989                   "Hello", serial, connection);
990       goto out;
991     }
992
993   verbose_message_received (connection, message);
994
995   if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
996     {
997       _dbus_warn ("Message has wrong sender %s\n",
998                   dbus_message_get_sender (message) ?
999                   dbus_message_get_sender (message) : "(none)");
1000       goto out;
1001     }
1002   
1003   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
1004     {
1005       warn_unexpected (connection, message, "method return for Hello");
1006       goto out;
1007     }
1008
1009   if (!check_no_leftovers (context))
1010     goto out;
1011   
1012   retval = TRUE;
1013   
1014  out:
1015   dbus_error_free (&error);
1016   
1017   if (message)
1018     dbus_message_unref (message);
1019   
1020   return retval;
1021 }
1022
1023 /* returns TRUE if the correct thing happens,
1024  * but the correct thing may include OOM errors.
1025  */
1026 static dbus_bool_t
1027 check_get_connection_unix_user (BusContext     *context,
1028                                 DBusConnection *connection)
1029 {
1030   DBusMessage *message;
1031   dbus_uint32_t serial;
1032   dbus_bool_t retval;
1033   DBusError error;
1034   const char *base_service_name;
1035   dbus_uint32_t uid;
1036
1037   retval = FALSE;
1038   dbus_error_init (&error);
1039   message = NULL;
1040
1041   _dbus_verbose ("check_get_connection_unix_user for %p\n", connection);
1042   
1043   message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
1044                                           DBUS_PATH_ORG_FREEDESKTOP_DBUS,
1045                                           DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1046                                           "GetConnectionUnixUser");
1047
1048   if (message == NULL)
1049     return TRUE;
1050
1051   base_service_name = dbus_bus_get_base_service (connection);
1052
1053   if (!dbus_message_append_args (message, 
1054                                  DBUS_TYPE_STRING, base_service_name,
1055                                  DBUS_TYPE_INVALID))
1056     {
1057       dbus_message_unref (message);
1058       return TRUE;
1059     }
1060
1061   if (!dbus_connection_send (connection, message, &serial))
1062     {
1063       dbus_message_unref (message);
1064       return TRUE;
1065     }
1066
1067   /* send our message */
1068   bus_test_run_clients_loop (TRUE);
1069
1070   dbus_message_unref (message);
1071   message = NULL;
1072
1073   dbus_connection_ref (connection); /* because we may get disconnected */
1074   block_connection_until_message_from_bus (context, connection);
1075
1076   if (!dbus_connection_get_is_connected (connection))
1077     {
1078       _dbus_verbose ("connection was disconnected\n");
1079       
1080       dbus_connection_unref (connection);
1081       
1082       return TRUE;
1083     }
1084
1085   dbus_connection_unref (connection);
1086
1087   message = pop_message_waiting_for_memory (connection);
1088   if (message == NULL)
1089     {
1090       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1091                   "GetConnectionUnixUser", serial, connection);
1092       goto out;
1093     }
1094
1095   verbose_message_received (connection, message);
1096
1097   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1098     {
1099       if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY))
1100         {
1101           ; /* good, this is a valid response */
1102         }
1103       else
1104         {
1105           warn_unexpected (connection, message, "not this error");
1106
1107           goto out;
1108         }
1109     }
1110   else
1111     {
1112       if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1113         {
1114           ; /* good, expected */
1115         }
1116       else
1117         {
1118           warn_unexpected (connection, message,
1119                            "method_return for GetConnectionUnixUser");
1120
1121           goto out;
1122         }
1123
1124     retry_get_property:
1125
1126       if (!dbus_message_get_args (message, &error,
1127                                   DBUS_TYPE_UINT32, &uid,
1128                                   DBUS_TYPE_INVALID))
1129         {
1130           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1131             {
1132               _dbus_verbose ("no memory to get uid by GetConnectionUnixUser\n");
1133               dbus_error_free (&error);
1134               _dbus_wait_for_memory ();
1135               goto retry_get_property;
1136             }
1137           else
1138             {
1139               _dbus_assert (dbus_error_is_set (&error));
1140               _dbus_warn ("Did not get the expected DBUS_TYPE_UINT32 from GetConnectionUnixUser\n");
1141               goto out;
1142             }
1143         }
1144     }
1145
1146   if (!check_no_leftovers (context))
1147     goto out;
1148
1149   retval = TRUE;
1150
1151  out:
1152   dbus_error_free (&error);
1153   
1154   if (message)
1155     dbus_message_unref (message);
1156   
1157   return retval;
1158 }
1159
1160 /* returns TRUE if the correct thing happens,
1161  * but the correct thing may include OOM errors.
1162  */
1163 static dbus_bool_t
1164 check_get_connection_unix_process_id (BusContext     *context,
1165                                       DBusConnection *connection)
1166 {
1167   DBusMessage *message;
1168   dbus_uint32_t serial;
1169   dbus_bool_t retval;
1170   DBusError error;
1171   const char *base_service_name;
1172   dbus_uint32_t pid;
1173
1174   retval = FALSE;
1175   dbus_error_init (&error);
1176   message = NULL;
1177
1178   _dbus_verbose ("check_get_connection_unix_process_id for %p\n", connection);
1179   
1180   message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
1181                                           DBUS_PATH_ORG_FREEDESKTOP_DBUS,
1182                                           DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1183                                           "GetConnectionUnixProcessID");
1184
1185   if (message == NULL)
1186     return TRUE;
1187
1188   base_service_name = dbus_bus_get_base_service (connection);
1189
1190   if (!dbus_message_append_args (message, 
1191                                  DBUS_TYPE_STRING, base_service_name,
1192                                  DBUS_TYPE_INVALID))
1193     {
1194       dbus_message_unref (message);
1195       return TRUE;
1196     }
1197
1198   if (!dbus_connection_send (connection, message, &serial))
1199     {
1200       dbus_message_unref (message);
1201       return TRUE;
1202     }
1203
1204   /* send our message */
1205   bus_test_run_clients_loop (TRUE);
1206
1207   dbus_message_unref (message);
1208   message = NULL;
1209
1210   dbus_connection_ref (connection); /* because we may get disconnected */
1211   block_connection_until_message_from_bus (context, connection);
1212
1213   if (!dbus_connection_get_is_connected (connection))
1214     {
1215       _dbus_verbose ("connection was disconnected\n");
1216       
1217       dbus_connection_unref (connection);
1218       
1219       return TRUE;
1220     }
1221
1222   dbus_connection_unref (connection);
1223
1224   message = pop_message_waiting_for_memory (connection);
1225   if (message == NULL)
1226     {
1227       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1228                   "GetConnectionUnixProcessID", serial, connection);
1229       goto out;
1230     }
1231
1232   verbose_message_received (connection, message);
1233
1234   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1235     {
1236       if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY))
1237         {
1238           ; /* good, this is a valid response */
1239         }
1240       else
1241         {
1242           warn_unexpected (connection, message, "not this error");
1243
1244           goto out;
1245         }
1246     }
1247   else
1248     {
1249       if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1250         {
1251           ; /* good, expected */
1252         }
1253       else
1254         {
1255           warn_unexpected (connection, message,
1256                            "method_return for GetConnectionUnixProcessID");
1257
1258           goto out;
1259         }
1260
1261     retry_get_property:
1262
1263       if (!dbus_message_get_args (message, &error,
1264                                   DBUS_TYPE_UINT32, &pid,
1265                                   DBUS_TYPE_INVALID))
1266         {
1267           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1268             {
1269               _dbus_verbose ("no memory to get pid by GetConnectionUnixProcessID\n");
1270               dbus_error_free (&error);
1271               _dbus_wait_for_memory ();
1272               goto retry_get_property;
1273             }
1274           else
1275             {
1276               _dbus_assert (dbus_error_is_set (&error));
1277               _dbus_warn ("Did not get the expected DBUS_TYPE_UINT32 from GetConnectionUnixProcessID\n");
1278               goto out;
1279             }
1280         } else {
1281
1282           /* test if returned pid is the same as our own pid
1283            *
1284            * @todo It would probably be good to restructure the tests
1285            *       in a way so our parent is the bus that we're testing
1286            *       cause then we can test that the pid returned matches
1287            *       getppid()
1288            */
1289           if (pid != (dbus_uint32_t) _dbus_getpid ())
1290             {
1291               _dbus_assert (dbus_error_is_set (&error));
1292               _dbus_warn ("Result from GetConnectionUnixProcessID is not our own pid\n");
1293               goto out;
1294             }
1295         }
1296     }
1297
1298   if (!check_no_leftovers (context))
1299     goto out;
1300
1301   retval = TRUE;
1302
1303  out:
1304   dbus_error_free (&error);
1305   
1306   if (message)
1307     dbus_message_unref (message);
1308   
1309   return retval;
1310 }
1311
1312 /* returns TRUE if the correct thing happens,
1313  * but the correct thing may include OOM errors.
1314  */
1315 static dbus_bool_t
1316 check_add_match_all (BusContext     *context,
1317                      DBusConnection *connection)
1318 {
1319   DBusMessage *message;
1320   dbus_bool_t retval;
1321   dbus_uint32_t serial;
1322   DBusError error;
1323
1324   retval = FALSE;
1325   dbus_error_init (&error);
1326   message = NULL;
1327
1328   _dbus_verbose ("check_add_match_all for %p\n", connection);
1329   
1330   message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
1331                                           DBUS_PATH_ORG_FREEDESKTOP_DBUS,
1332                                           DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1333                                           "AddMatch");
1334
1335   if (message == NULL)
1336     return TRUE;
1337
1338   /* empty string match rule matches everything */
1339   if (!dbus_message_append_args (message, DBUS_TYPE_STRING, "",
1340                                  DBUS_TYPE_INVALID))
1341     {
1342       dbus_message_unref (message);
1343       return TRUE;
1344     }
1345   
1346   if (!dbus_connection_send (connection, message, &serial))
1347     {
1348       dbus_message_unref (message);
1349       return TRUE;
1350     }
1351
1352   dbus_message_unref (message);
1353   message = NULL;
1354
1355   /* send our message */
1356   bus_test_run_clients_loop (TRUE);
1357
1358   dbus_connection_ref (connection); /* because we may get disconnected */
1359   block_connection_until_message_from_bus (context, connection);
1360
1361   if (!dbus_connection_get_is_connected (connection))
1362     {
1363       _dbus_verbose ("connection was disconnected\n");
1364       
1365       dbus_connection_unref (connection);
1366       
1367       return TRUE;
1368     }
1369
1370   dbus_connection_unref (connection);
1371   
1372   message = pop_message_waiting_for_memory (connection);
1373   if (message == NULL)
1374     {
1375       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1376                   "AddMatch", serial, connection);
1377       goto out;
1378     }
1379
1380   verbose_message_received (connection, message);
1381
1382   if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
1383     {
1384       _dbus_warn ("Message has wrong sender %s\n",
1385                   dbus_message_get_sender (message) ?
1386                   dbus_message_get_sender (message) : "(none)");
1387       goto out;
1388     }
1389   
1390   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1391     {
1392       if (dbus_message_is_error (message,
1393                                  DBUS_ERROR_NO_MEMORY))
1394         {
1395           ; /* good, this is a valid response */
1396         }
1397       else
1398         {
1399           warn_unexpected (connection, message, "not this error");
1400
1401           goto out;
1402         }
1403     }
1404   else
1405     {
1406       if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1407         {
1408           ; /* good, expected */
1409           _dbus_assert (dbus_message_get_reply_serial (message) == serial);
1410         }
1411       else
1412         {
1413           warn_unexpected (connection, message, "method return for AddMatch");
1414
1415           goto out;
1416         }
1417     }
1418
1419   if (!check_no_leftovers (context))
1420     goto out;
1421   
1422   retval = TRUE;
1423   
1424  out:
1425   dbus_error_free (&error);
1426   
1427   if (message)
1428     dbus_message_unref (message);
1429   
1430   return retval;
1431 }
1432
1433 /* returns TRUE if the correct thing happens,
1434  * but the correct thing may include OOM errors.
1435  */
1436 static dbus_bool_t
1437 check_hello_connection (BusContext *context)
1438 {
1439   DBusConnection *connection;
1440   DBusError error;
1441
1442   dbus_error_init (&error);
1443
1444   connection = dbus_connection_open ("debug-pipe:name=test-server", &error);
1445   if (connection == NULL)
1446     {
1447       _DBUS_ASSERT_ERROR_IS_SET (&error);
1448       dbus_error_free (&error);
1449       return TRUE;
1450     }
1451
1452   if (!bus_setup_debug_client (connection))
1453     {
1454       dbus_connection_disconnect (connection);
1455       dbus_connection_unref (connection);
1456       return TRUE;
1457     }
1458
1459   if (!check_hello_message (context, connection))
1460     return FALSE;
1461   
1462   if (dbus_bus_get_base_service (connection) == NULL)
1463     {
1464       /* We didn't successfully register, so we can't
1465        * do the usual kill_client_connection() checks
1466        */
1467       kill_client_connection_unchecked (connection);
1468     }
1469   else
1470     {
1471       if (!check_add_match_all (context, connection))
1472         return FALSE;
1473       
1474       kill_client_connection (context, connection);
1475     }
1476
1477   return TRUE;
1478 }
1479
1480 #define NONEXISTENT_SERVICE_NAME "test.this.service.does.not.exist.ewuoiurjdfxcvn"
1481
1482 /* returns TRUE if the correct thing happens,
1483  * but the correct thing may include OOM errors.
1484  */
1485 static dbus_bool_t
1486 check_nonexistent_service_activation (BusContext     *context,
1487                                       DBusConnection *connection)
1488 {
1489   DBusMessage *message;
1490   dbus_uint32_t serial;
1491   dbus_bool_t retval;
1492   DBusError error;
1493   
1494   dbus_error_init (&error);
1495   
1496   message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
1497                                           DBUS_PATH_ORG_FREEDESKTOP_DBUS,
1498                                           DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1499                                           "ActivateService");
1500
1501   if (message == NULL)
1502     return TRUE;
1503
1504   if (!dbus_message_append_args (message,
1505                                  DBUS_TYPE_STRING, NONEXISTENT_SERVICE_NAME,
1506                                  DBUS_TYPE_UINT32, 0,
1507                                  DBUS_TYPE_INVALID))
1508     {
1509       dbus_message_unref (message);
1510       return TRUE;
1511     }
1512   
1513   if (!dbus_connection_send (connection, message, &serial))
1514     {
1515       dbus_message_unref (message);
1516       return TRUE;
1517     }
1518
1519   dbus_message_unref (message);
1520   message = NULL;
1521
1522   bus_test_run_everything (context);
1523   block_connection_until_message_from_bus (context, connection);
1524   bus_test_run_everything (context);
1525
1526   if (!dbus_connection_get_is_connected (connection))
1527     {
1528       _dbus_verbose ("connection was disconnected\n");
1529       return TRUE;
1530     }
1531   
1532   retval = FALSE;
1533   
1534   message = pop_message_waiting_for_memory (connection);
1535   if (message == NULL)
1536     {
1537       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1538                   "ActivateService", serial, connection);
1539       goto out;
1540     }
1541
1542   verbose_message_received (connection, message);
1543
1544   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1545     {
1546       if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
1547         {
1548           _dbus_warn ("Message has wrong sender %s\n",
1549                       dbus_message_get_sender (message) ?
1550                       dbus_message_get_sender (message) : "(none)");
1551           goto out;
1552         }
1553       
1554       if (dbus_message_is_error (message,
1555                                  DBUS_ERROR_NO_MEMORY))
1556         {
1557           ; /* good, this is a valid response */
1558         }
1559       else if (dbus_message_is_error (message,
1560                                       DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND))
1561         {
1562           ; /* good, this is expected also */
1563         }
1564       else
1565         {
1566           warn_unexpected (connection, message, "not this error");
1567           goto out;
1568         }
1569     }
1570   else
1571     {
1572       _dbus_warn ("Did not expect to successfully activate %s\n",
1573                   NONEXISTENT_SERVICE_NAME);
1574       goto out;
1575     }
1576
1577   retval = TRUE;
1578   
1579  out:
1580   if (message)
1581     dbus_message_unref (message);
1582   
1583   return retval;
1584 }
1585
1586 /* returns TRUE if the correct thing happens,
1587  * but the correct thing may include OOM errors.
1588  */
1589 static dbus_bool_t
1590 check_nonexistent_service_auto_activation (BusContext     *context,
1591                                            DBusConnection *connection)
1592 {
1593   DBusMessage *message;
1594   dbus_uint32_t serial;
1595   dbus_bool_t retval;
1596   DBusError error;
1597     
1598   dbus_error_init (&error);
1599
1600   message = dbus_message_new_method_call (NONEXISTENT_SERVICE_NAME,
1601                                           "/org/freedesktop/TestSuite",
1602                                           "org.freedesktop.TestSuite",
1603                                           "Echo");
1604   
1605   if (message == NULL)
1606     return TRUE;
1607
1608   dbus_message_set_auto_activation (message, TRUE);
1609  
1610   if (!dbus_connection_send (connection, message, &serial))
1611     {
1612       dbus_message_unref (message);
1613       return TRUE;
1614     }
1615
1616   dbus_message_unref (message);
1617   message = NULL;
1618
1619   bus_test_run_everything (context);
1620   block_connection_until_message_from_bus (context, connection);
1621   bus_test_run_everything (context);
1622
1623   if (!dbus_connection_get_is_connected (connection))
1624     {
1625       _dbus_verbose ("connection was disconnected\n");
1626       return TRUE;
1627     }
1628   
1629   retval = FALSE;
1630   
1631   message = pop_message_waiting_for_memory (connection);
1632
1633   if (message == NULL)
1634     {
1635       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1636                   "Echo message (auto activation)", serial, connection);
1637       goto out;
1638     }
1639
1640   verbose_message_received (connection, message);
1641
1642   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1643     {
1644       if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
1645         {
1646           _dbus_warn ("Message has wrong sender %s\n",
1647                       dbus_message_get_sender (message) ?
1648                       dbus_message_get_sender (message) : "(none)");
1649           goto out;
1650         }
1651       
1652       if (dbus_message_is_error (message,
1653                                  DBUS_ERROR_NO_MEMORY))
1654         {
1655           ; /* good, this is a valid response */
1656         }
1657       else if (dbus_message_is_error (message,
1658                                       DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND))
1659         {
1660           ; /* good, this is expected also */
1661         }
1662       else
1663         {
1664           warn_unexpected (connection, message, "not this error");
1665           goto out;
1666         }
1667     }
1668   else
1669     {
1670       _dbus_warn ("Did not expect to successfully activate %s\n",
1671                   NONEXISTENT_SERVICE_NAME);
1672       goto out;
1673     }
1674
1675   retval = TRUE;
1676   
1677  out:
1678   if (message)
1679     dbus_message_unref (message);
1680   
1681   return retval;
1682 }
1683
1684 static dbus_bool_t
1685 check_base_service_activated (BusContext     *context,
1686                               DBusConnection *connection,
1687                               DBusMessage    *initial_message,
1688                               char          **base_service_p)
1689 {
1690   DBusMessage *message;
1691   dbus_bool_t retval;
1692   DBusError error;
1693   char *base_service;
1694   
1695   base_service = NULL;
1696   retval = FALSE;
1697   
1698   dbus_error_init (&error);
1699
1700   message = initial_message;
1701   dbus_message_ref (message);  
1702
1703   if (dbus_message_is_signal (message,
1704                               DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1705                               "ServiceCreated"))
1706     {
1707       char *service_name;
1708       CheckServiceCreatedData scd;
1709
1710     reget_service_name_arg:
1711       if (!dbus_message_get_args (message, &error,
1712                                   DBUS_TYPE_STRING, &service_name,
1713                                   DBUS_TYPE_INVALID))
1714         {
1715           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1716             {
1717               dbus_error_free (&error);
1718               _dbus_wait_for_memory ();
1719               goto reget_service_name_arg;
1720             }
1721           else
1722             {
1723               _dbus_warn ("Message %s doesn't have a service name: %s\n",
1724                           "ServiceCreated",
1725                           error.message);
1726               dbus_error_free (&error);
1727               goto out;
1728             }
1729         }
1730
1731       if (*service_name != ':')
1732         {
1733           _dbus_warn ("Expected base service activation, got \"%s\" instead\n",
1734                       service_name);
1735           goto out;
1736         }
1737               
1738       base_service = service_name;
1739       service_name = NULL;
1740       
1741       scd.skip_connection = connection;
1742       scd.failed = FALSE;
1743       scd.expected_service_name = base_service;
1744       bus_test_clients_foreach (check_service_created_foreach,
1745                                 &scd);
1746       
1747       if (scd.failed)
1748         goto out;
1749     }
1750   else
1751     {
1752       warn_unexpected (connection, message, "ServiceCreated for base service");
1753
1754       goto out;
1755     }
1756
1757   retval = TRUE;
1758
1759   if (base_service_p)
1760     {
1761       *base_service_p = base_service;
1762       base_service = NULL;
1763     }
1764   
1765  out:
1766   if (message)
1767     dbus_message_unref (message);
1768
1769   if (base_service)
1770     dbus_free (base_service);
1771   
1772   return retval;
1773 }
1774
1775 static dbus_bool_t
1776 check_service_activated (BusContext     *context,
1777                          DBusConnection *connection,
1778                          const char     *activated_name,
1779                          const char     *base_service_name,
1780                          DBusMessage    *initial_message)
1781 {
1782   DBusMessage *message;
1783   dbus_bool_t retval;
1784   DBusError error;
1785   dbus_uint32_t activation_result;
1786   
1787   retval = FALSE;
1788   
1789   dbus_error_init (&error);
1790
1791   message = initial_message;
1792   dbus_message_ref (message);
1793
1794   if (dbus_message_is_signal (message,
1795                               DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1796                               "ServiceCreated"))
1797     {
1798       char *service_name;
1799       CheckServiceCreatedData scd;
1800
1801     reget_service_name_arg:
1802       if (!dbus_message_get_args (message, &error,
1803                                   DBUS_TYPE_STRING, &service_name,
1804                                   DBUS_TYPE_INVALID))
1805         {
1806           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1807             {
1808               dbus_error_free (&error);
1809               _dbus_wait_for_memory ();
1810               goto reget_service_name_arg;
1811             }
1812           else
1813             {
1814               _dbus_warn ("Message %s doesn't have a service name: %s\n",
1815                           "ServiceCreated",
1816                           error.message);
1817               dbus_error_free (&error);
1818               goto out;
1819             }
1820         }
1821
1822       if (strcmp (service_name, activated_name) != 0)
1823         {
1824           _dbus_warn ("Expected to see service %s created, saw %s instead\n",
1825                       activated_name, service_name);
1826           dbus_free (service_name);
1827           goto out;
1828         }
1829       
1830       scd.skip_connection = connection;
1831       scd.failed = FALSE;
1832       scd.expected_service_name = service_name;
1833       bus_test_clients_foreach (check_service_created_foreach,
1834                                 &scd);
1835           
1836       dbus_free (service_name);
1837
1838       if (scd.failed)
1839         goto out;
1840           
1841       dbus_message_unref (message);
1842       message = pop_message_waiting_for_memory (connection);
1843       if (message == NULL)
1844         {
1845           _dbus_warn ("Expected a reply to %s, got nothing\n",
1846                       "ActivateService");
1847           goto out;
1848         }
1849     }
1850   else
1851     {
1852       warn_unexpected (connection, message, "ServiceCreated for the activated name");
1853       
1854       goto out;
1855     }
1856   
1857   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN)
1858     {
1859       warn_unexpected (connection, message, "reply to ActivateService");
1860
1861       goto out;
1862     }
1863
1864   activation_result = 0;
1865   if (!dbus_message_get_args (message, &error,
1866                               DBUS_TYPE_UINT32, &activation_result,
1867                               DBUS_TYPE_INVALID))
1868     {
1869       if (!dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1870         {
1871           _dbus_warn ("Did not have activation result first argument to %s: %s\n",
1872                       "ActivateService", error.message);
1873           dbus_error_free (&error);
1874           goto out;
1875         }
1876
1877       dbus_error_free (&error);
1878     }
1879   else
1880     {
1881       if (activation_result == DBUS_ACTIVATION_REPLY_ACTIVATED)
1882         ; /* Good */
1883       else if (activation_result == DBUS_ACTIVATION_REPLY_ALREADY_ACTIVE)
1884         ; /* Good also */
1885       else
1886         {
1887           _dbus_warn ("Activation result was 0x%x, no good.\n",
1888                       activation_result);
1889           goto out;
1890         }
1891     }
1892
1893   dbus_message_unref (message);
1894   message = NULL;
1895       
1896   if (!check_no_leftovers (context))
1897     {
1898       _dbus_warn ("Messages were left over after verifying existent activation results\n");
1899       goto out;
1900     }
1901
1902   retval = TRUE;
1903   
1904  out:
1905   if (message)
1906     dbus_message_unref (message);
1907   
1908   return retval;
1909 }
1910
1911 static dbus_bool_t
1912 check_service_auto_activated (BusContext     *context,
1913                               DBusConnection *connection,
1914                               const char     *activated_name,
1915                               const char     *base_service_name,
1916                               DBusMessage    *initial_message)
1917 {
1918   DBusMessage *message;
1919   dbus_bool_t retval;
1920   DBusError error;
1921   
1922   retval = FALSE;
1923   
1924   dbus_error_init (&error);
1925
1926   message = initial_message;
1927   dbus_message_ref (message);
1928
1929   if (dbus_message_is_signal (message,
1930                               DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1931                               "ServiceCreated"))
1932     {
1933       char *service_name;
1934       CheckServiceCreatedData scd;
1935       
1936     reget_service_name_arg:
1937       if (!dbus_message_get_args (message, &error,
1938                                   DBUS_TYPE_STRING, &service_name,
1939                                   DBUS_TYPE_INVALID))
1940         {
1941           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1942             {
1943               dbus_error_free (&error);
1944               _dbus_wait_for_memory ();
1945               goto reget_service_name_arg;
1946             }
1947           else
1948             {
1949               _dbus_warn ("Message %s doesn't have a service name: %s\n",
1950                           "ServiceCreated",
1951                           error.message);
1952               dbus_error_free (&error);
1953               goto out;
1954             }
1955         }
1956       
1957       if (strcmp (service_name, activated_name) != 0)
1958         {
1959           _dbus_warn ("Expected to see service %s created, saw %s instead\n",
1960                       activated_name, service_name);
1961           dbus_free (service_name);
1962           goto out;
1963         }
1964       
1965       scd.skip_connection = connection;
1966       scd.failed = FALSE;
1967       scd.expected_service_name = service_name;
1968       bus_test_clients_foreach (check_service_created_foreach,
1969                                 &scd);
1970       
1971       dbus_free (service_name);
1972       
1973       if (scd.failed)
1974         goto out;
1975       
1976       /* Note that this differs from regular activation in that we don't get a
1977        * reply to ActivateService here.
1978        */
1979       
1980       dbus_message_unref (message);
1981       message = NULL;
1982     }
1983   else
1984     {
1985       warn_unexpected (connection, message, "ServiceCreated for the activated name");
1986       
1987       goto out;
1988     }
1989   
1990   retval = TRUE;
1991   
1992  out:
1993   if (message)
1994     dbus_message_unref (message);
1995   
1996   return retval;
1997 }
1998
1999 static dbus_bool_t
2000 check_service_deactivated (BusContext     *context,
2001                            DBusConnection *connection,
2002                            const char     *activated_name,
2003                            const char     *base_service)
2004 {
2005   dbus_bool_t retval;
2006   CheckServiceDeletedData csdd;
2007
2008   retval = FALSE;
2009   
2010   /* Now we are expecting ServiceDeleted messages for the base
2011    * service and the activated_name.  The base service
2012    * notification is required to come last.
2013    */
2014   csdd.expected_service_name = activated_name;
2015   csdd.failed = FALSE;
2016   bus_test_clients_foreach (check_service_deleted_foreach,
2017                             &csdd);      
2018
2019   if (csdd.failed)
2020     goto out;
2021       
2022   csdd.expected_service_name = base_service;
2023   csdd.failed = FALSE;
2024   bus_test_clients_foreach (check_service_deleted_foreach,
2025                             &csdd);
2026
2027   if (csdd.failed)
2028     goto out;
2029
2030   retval = TRUE;
2031   
2032  out:
2033   return retval;
2034 }
2035
2036 static dbus_bool_t
2037 check_send_exit_to_service (BusContext     *context,
2038                             DBusConnection *connection,
2039                             const char     *service_name,
2040                             const char     *base_service)
2041 {
2042   dbus_bool_t got_error;
2043   DBusMessage *message;
2044   dbus_uint32_t serial;
2045   dbus_bool_t retval;
2046   
2047   _dbus_verbose ("Sending exit message to the test service\n");
2048
2049   retval = FALSE;
2050   
2051   /* Kill off the test service by sending it a quit message */
2052   message = dbus_message_new_method_call (service_name,
2053                                           "/org/freedesktop/TestSuite",
2054                                           "org.freedesktop.TestSuite",
2055                                           "Exit");
2056       
2057   if (message == NULL)
2058     {
2059       /* Do this again; we still need the service to exit... */
2060       if (!check_send_exit_to_service (context, connection,
2061                                        service_name, base_service))
2062         goto out;
2063       
2064       return TRUE;
2065     }
2066       
2067   if (!dbus_connection_send (connection, message, &serial))
2068     {
2069       dbus_message_unref (message);
2070
2071       /* Do this again; we still need the service to exit... */
2072       if (!check_send_exit_to_service (context, connection,
2073                                        service_name, base_service))
2074         goto out;
2075       
2076       return TRUE;
2077     }
2078
2079   dbus_message_unref (message);
2080   message = NULL;
2081
2082   /* send message */
2083   bus_test_run_clients_loop (TRUE);
2084
2085   /* read it in and write it out to test service */
2086   bus_test_run_bus_loop (context, FALSE);
2087
2088   /* see if we got an error during message bus dispatching */
2089   bus_test_run_clients_loop (FALSE);
2090   message = borrow_message_waiting_for_memory (connection);
2091   got_error = message != NULL && dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR;
2092   if (message)
2093     {
2094       dbus_connection_return_message (connection, message);
2095       message = NULL;
2096     }
2097           
2098   if (!got_error)
2099     {
2100       /* If no error, wait for the test service to exit */
2101       block_connection_until_message_from_bus (context, connection);
2102               
2103       bus_test_run_everything (context);
2104     }
2105
2106   if (got_error)
2107     {
2108       message = pop_message_waiting_for_memory (connection);
2109       _dbus_assert (message != NULL);
2110
2111       if (dbus_message_get_reply_serial (message) != serial)
2112         {
2113           warn_unexpected (connection, message,
2114                            "error with the correct reply serial");
2115           goto out;
2116         }
2117       
2118       if (!dbus_message_is_error (message,
2119                                   DBUS_ERROR_NO_MEMORY))
2120         {
2121           warn_unexpected (connection, message,
2122                            "a no memory error from asking test service to exit");
2123           goto out;
2124         }
2125
2126       _dbus_verbose ("Got error %s when asking test service to exit\n",
2127                      dbus_message_get_error_name (message));
2128
2129       /* Do this again; we still need the service to exit... */
2130       if (!check_send_exit_to_service (context, connection,
2131                                        service_name, base_service))
2132         goto out;
2133     }
2134   else
2135     {
2136       if (!check_service_deactivated (context, connection,
2137                                       service_name, base_service))
2138         goto out;
2139
2140       /* Should now have a NoReply error from the Exit() method
2141        * call; it should have come after all the deactivation
2142        * stuff.
2143        */
2144       message = pop_message_waiting_for_memory (connection);
2145           
2146       if (message == NULL)
2147         {
2148           warn_unexpected (connection, NULL,
2149                            "reply to Exit() method call");
2150           goto out;
2151         }
2152       if (!dbus_message_is_error (message,
2153                                   DBUS_ERROR_NO_REPLY))
2154         {
2155           warn_unexpected (connection, NULL,
2156                            "NoReply error from Exit() method call");
2157           goto out;
2158         }
2159
2160       if (dbus_message_get_reply_serial (message) != serial)
2161         {
2162           warn_unexpected (connection, message,
2163                            "error with the correct reply serial");
2164           goto out;
2165         }
2166           
2167       _dbus_verbose ("Got error %s after test service exited\n",
2168                      dbus_message_get_error_name (message));
2169       
2170       if (!check_no_leftovers (context))
2171         {
2172           _dbus_warn ("Messages were left over after %s\n",
2173                       _DBUS_FUNCTION_NAME);
2174           goto out;
2175         }
2176     }
2177   
2178   retval = TRUE;
2179   
2180  out:
2181   if (message)
2182     dbus_message_unref (message);
2183   
2184   return retval;
2185 }
2186
2187 static dbus_bool_t
2188 check_got_error (BusContext     *context,
2189                  DBusConnection *connection,
2190                  const char     *first_error_name,
2191                  ...)
2192 {
2193   DBusMessage *message;
2194   dbus_bool_t retval;
2195   va_list ap;
2196   dbus_bool_t error_found;
2197   const char *error_name;
2198   
2199   retval = FALSE;
2200   
2201   message = pop_message_waiting_for_memory (connection);
2202   if (message == NULL)
2203     {
2204       _dbus_warn ("Did not get an expected error\n");
2205       goto out;
2206     }
2207
2208   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
2209     {
2210       warn_unexpected (connection, message, "an error");
2211
2212       goto out;
2213     }
2214
2215   error_found = FALSE;
2216
2217   va_start (ap, first_error_name);
2218   error_name = first_error_name;
2219   while (error_name != NULL)
2220     {
2221       if (dbus_message_is_error (message, error_name))
2222         {
2223           error_found = TRUE;
2224           break;
2225         }
2226       error_name = va_arg (ap, char*);
2227     }
2228   va_end (ap);
2229
2230   if (!error_found)
2231     {
2232       _dbus_warn ("Expected error %s or other, got %s instead\n",
2233                   first_error_name,
2234                   dbus_message_get_error_name (message));
2235       goto out;
2236     }
2237
2238   retval = TRUE;
2239   
2240  out:
2241   if (message)
2242     dbus_message_unref (message);
2243   
2244   return retval;
2245 }
2246           
2247 #define EXISTENT_SERVICE_NAME "org.freedesktop.DBus.TestSuiteEchoService"
2248
2249 /* returns TRUE if the correct thing happens,
2250  * but the correct thing may include OOM errors.
2251  */
2252 static dbus_bool_t
2253 check_existent_service_activation (BusContext     *context,
2254                                    DBusConnection *connection)
2255 {
2256   DBusMessage *message;
2257   dbus_uint32_t serial;
2258   dbus_bool_t retval;
2259   DBusError error;
2260   char *base_service;
2261
2262   base_service = NULL;
2263   
2264   dbus_error_init (&error);
2265   
2266   message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
2267                                           DBUS_PATH_ORG_FREEDESKTOP_DBUS,
2268                                           DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
2269                                           "ActivateService");
2270
2271   if (message == NULL)
2272     return TRUE;
2273
2274   if (!dbus_message_append_args (message,
2275                                  DBUS_TYPE_STRING, EXISTENT_SERVICE_NAME,
2276                                  DBUS_TYPE_UINT32, 0,
2277                                  DBUS_TYPE_INVALID))
2278     {
2279       dbus_message_unref (message);
2280       return TRUE;
2281     }
2282   
2283   if (!dbus_connection_send (connection, message, &serial))
2284     {
2285       dbus_message_unref (message);
2286       return TRUE;
2287     }
2288
2289   dbus_message_unref (message);
2290   message = NULL;
2291
2292   bus_test_run_everything (context);
2293
2294   /* now wait for the message bus to hear back from the activated
2295    * service.
2296    */
2297   block_connection_until_message_from_bus (context, connection);
2298
2299   bus_test_run_everything (context);
2300
2301   if (!dbus_connection_get_is_connected (connection))
2302     {
2303       _dbus_verbose ("connection was disconnected\n");
2304       return TRUE;
2305     }
2306   
2307   retval = FALSE;
2308   
2309   message = pop_message_waiting_for_memory (connection);
2310   if (message == NULL)
2311     {
2312       _dbus_warn ("Did not receive any messages after %s %d on %p\n",
2313                   "ActivateService", serial, connection);
2314       goto out;
2315     }
2316
2317   verbose_message_received (connection, message);
2318   _dbus_verbose ("  (after sending %s)\n", "ActivateService");
2319
2320   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
2321     {
2322       if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
2323         {
2324           _dbus_warn ("Message has wrong sender %s\n",
2325                       dbus_message_get_sender (message) ?
2326                       dbus_message_get_sender (message) : "(none)");
2327           goto out;
2328         }
2329       
2330       if (dbus_message_is_error (message,
2331                                  DBUS_ERROR_NO_MEMORY))
2332         {
2333           ; /* good, this is a valid response */
2334         }
2335       else if (dbus_message_is_error (message,
2336                                       DBUS_ERROR_SPAWN_CHILD_EXITED) ||
2337                dbus_message_is_error (message,
2338                                       DBUS_ERROR_SPAWN_EXEC_FAILED))
2339         {
2340           ; /* good, this is expected also */
2341         }
2342       else
2343         {
2344           _dbus_warn ("Did not expect error %s\n",
2345                       dbus_message_get_error_name (message));
2346           goto out;
2347         }
2348     }
2349   else
2350     {
2351       dbus_bool_t got_service_deleted;
2352       dbus_bool_t got_error;
2353       
2354       if (!check_base_service_activated (context, connection,
2355                                          message, &base_service))
2356         goto out;
2357
2358       dbus_message_unref (message);
2359       message = NULL;
2360
2361       /* We may need to block here for the test service to exit or finish up */
2362       block_connection_until_message_from_bus (context, connection);
2363       
2364       message = dbus_connection_borrow_message (connection);
2365       if (message == NULL)
2366         {
2367           _dbus_warn ("Did not receive any messages after base service creation notification\n");
2368           goto out;
2369         }
2370
2371       got_service_deleted = dbus_message_is_signal (message,
2372                                                     DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
2373                                                     "ServiceDeleted");
2374       got_error = dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR;
2375       
2376       dbus_connection_return_message (connection, message);
2377       message = NULL;
2378
2379       if (got_error)
2380         {
2381           if (!check_got_error (context, connection,
2382                                 DBUS_ERROR_SPAWN_CHILD_EXITED,
2383                                 DBUS_ERROR_NO_MEMORY,
2384                                 NULL))
2385             goto out;
2386
2387           /* A service deleted should be coming along now after this error.
2388            * We can also get the error *after* the service deleted.
2389            */
2390           got_service_deleted = TRUE;
2391         }
2392       
2393       if (got_service_deleted)
2394         {
2395           /* The service started up and got a base address, but then
2396            * failed to register under EXISTENT_SERVICE_NAME
2397            */
2398           CheckServiceDeletedData csdd;
2399           
2400           csdd.expected_service_name = base_service;
2401           csdd.failed = FALSE;
2402           bus_test_clients_foreach (check_service_deleted_foreach,
2403                                     &csdd);
2404
2405           if (csdd.failed)
2406             goto out;
2407
2408           /* Now we should get an error about the service exiting
2409            * if we didn't get it before.
2410            */
2411           if (!got_error)
2412             {
2413               block_connection_until_message_from_bus (context, connection);
2414               
2415               /* and process everything again */
2416               bus_test_run_everything (context);
2417               
2418               if (!check_got_error (context, connection,
2419                                     DBUS_ERROR_SPAWN_CHILD_EXITED,
2420                                     NULL))
2421                 goto out;
2422             }
2423         }
2424       else
2425         {
2426           message = pop_message_waiting_for_memory (connection);
2427           if (message == NULL)
2428             {
2429               _dbus_warn ("Failed to pop message we just put back! should have been a ServiceCreated\n");
2430               goto out;
2431             }
2432           
2433           if (!check_service_activated (context, connection, EXISTENT_SERVICE_NAME,
2434                                         base_service, message))
2435             goto out;
2436           
2437           dbus_message_unref (message);
2438           message = NULL;
2439
2440
2441           if (!check_no_leftovers (context))
2442             {
2443               _dbus_warn ("Messages were left over after successful activation\n");
2444               goto out;
2445             }
2446
2447           if (!check_send_exit_to_service (context, connection,
2448                                            EXISTENT_SERVICE_NAME, base_service))
2449             goto out;
2450         }
2451     }
2452   
2453   retval = TRUE;
2454   
2455  out:
2456   if (message)
2457     dbus_message_unref (message);
2458
2459   if (base_service)
2460     dbus_free (base_service);
2461   
2462   return retval;
2463 }
2464
2465 /* returns TRUE if the correct thing happens,
2466  * but the correct thing may include OOM errors.
2467  */
2468 static dbus_bool_t
2469 check_segfault_service_activation (BusContext     *context,
2470                                    DBusConnection *connection)
2471 {
2472   DBusMessage *message;
2473   dbus_uint32_t serial;
2474   dbus_bool_t retval;
2475   DBusError error;
2476   
2477   dbus_error_init (&error);
2478   
2479   message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
2480                                           DBUS_PATH_ORG_FREEDESKTOP_DBUS,
2481                                           DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
2482                                           "ActivateService");
2483
2484   if (message == NULL)
2485     return TRUE;
2486
2487   if (!dbus_message_append_args (message,
2488                                  DBUS_TYPE_STRING,
2489                                  "org.freedesktop.DBus.TestSuiteSegfaultService",
2490                                  DBUS_TYPE_UINT32, 0,
2491                                  DBUS_TYPE_INVALID))
2492     {
2493       dbus_message_unref (message);
2494       return TRUE;
2495     }
2496   
2497   if (!dbus_connection_send (connection, message, &serial))
2498     {
2499       dbus_message_unref (message);
2500       return TRUE;
2501     }
2502
2503   dbus_message_unref (message);
2504   message = NULL;
2505
2506   bus_test_run_everything (context);
2507   block_connection_until_message_from_bus (context, connection);
2508   bus_test_run_everything (context);
2509
2510   if (!dbus_connection_get_is_connected (connection))
2511     {
2512       _dbus_verbose ("connection was disconnected\n");
2513       return TRUE;
2514     }
2515   
2516   retval = FALSE;
2517   
2518   message = pop_message_waiting_for_memory (connection);
2519   if (message == NULL)
2520     {
2521       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
2522                   "ActivateService", serial, connection);
2523       goto out;
2524     }
2525
2526   verbose_message_received (connection, message);
2527
2528   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
2529     {
2530       if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
2531         {
2532           _dbus_warn ("Message has wrong sender %s\n",
2533                       dbus_message_get_sender (message) ?
2534                       dbus_message_get_sender (message) : "(none)");
2535           goto out;
2536         }
2537       
2538       if (dbus_message_is_error (message,
2539                                  DBUS_ERROR_NO_MEMORY))
2540         {
2541           ; /* good, this is a valid response */
2542         }
2543       else if (dbus_message_is_error (message,
2544                                       DBUS_ERROR_SPAWN_CHILD_SIGNALED))
2545         {
2546           ; /* good, this is expected also */
2547         }
2548       else
2549         {
2550           warn_unexpected (connection, message, "not this error");
2551
2552           goto out;
2553         }
2554     }
2555   else
2556     {
2557       _dbus_warn ("Did not expect to successfully activate segfault service\n");
2558       goto out;
2559     }
2560
2561   retval = TRUE;
2562   
2563  out:
2564   if (message)
2565     dbus_message_unref (message);
2566   
2567   return retval;
2568 }
2569
2570
2571 /* returns TRUE if the correct thing happens,
2572  * but the correct thing may include OOM errors.
2573  */
2574 static dbus_bool_t
2575 check_segfault_service_auto_activation (BusContext     *context,
2576                                         DBusConnection *connection)
2577 {
2578   DBusMessage *message;
2579   dbus_uint32_t serial;
2580   dbus_bool_t retval;
2581   DBusError error;
2582
2583   dbus_error_init (&error);
2584
2585   dbus_error_init (&error);
2586
2587   message = dbus_message_new_method_call ("org.freedesktop.DBus.TestSuiteSegfaultService",
2588                                           "/org/freedesktop/TestSuite",
2589                                           "org.freedesktop.TestSuite",
2590                                           "Echo");
2591   
2592   if (message == NULL)
2593     return TRUE;
2594
2595   dbus_message_set_auto_activation (message, TRUE);
2596   
2597   if (!dbus_connection_send (connection, message, &serial))
2598     {
2599       dbus_message_unref (message);
2600       return TRUE;
2601     }
2602
2603   dbus_message_unref (message);
2604   message = NULL;
2605
2606   bus_test_run_everything (context);
2607   block_connection_until_message_from_bus (context, connection);
2608   bus_test_run_everything (context);
2609
2610   if (!dbus_connection_get_is_connected (connection))
2611     {
2612       _dbus_verbose ("connection was disconnected\n");
2613       return TRUE;
2614     }
2615   
2616   retval = FALSE;
2617   
2618   message = pop_message_waiting_for_memory (connection);
2619   if (message == NULL)
2620     {
2621       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
2622                   "Echo message (auto activation)", serial, connection);
2623       goto out;
2624     }
2625
2626   verbose_message_received (connection, message);
2627
2628   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
2629     {
2630       if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
2631         {
2632           _dbus_warn ("Message has wrong sender %s\n",
2633                       dbus_message_get_sender (message) ?
2634                       dbus_message_get_sender (message) : "(none)");
2635           goto out;
2636         }
2637       
2638       if (dbus_message_is_error (message,
2639                                  DBUS_ERROR_NO_MEMORY))
2640         {
2641           ; /* good, this is a valid response */
2642         }
2643       else if (dbus_message_is_error (message,
2644                                       DBUS_ERROR_SPAWN_CHILD_SIGNALED))
2645         {
2646           ; /* good, this is expected also */
2647         }
2648       else
2649         {
2650           warn_unexpected (connection, message, "not this error");
2651
2652           goto out;
2653         }
2654     }
2655   else
2656     {
2657       _dbus_warn ("Did not expect to successfully activate segfault service\n");
2658       goto out;
2659     }
2660
2661   retval = TRUE;
2662   
2663  out:
2664   if (message)
2665     dbus_message_unref (message);
2666   
2667   return retval;
2668 }
2669
2670 #define TEST_ECHO_MESSAGE "Test echo message"
2671
2672 /* returns TRUE if the correct thing happens,
2673  * but the correct thing may include OOM errors.
2674  */
2675 static dbus_bool_t
2676 check_existent_service_auto_activation (BusContext     *context,
2677                                         DBusConnection *connection)
2678 {
2679   DBusMessage *message;
2680   dbus_uint32_t serial;
2681   dbus_bool_t retval;
2682   DBusError error;
2683   char *base_service;
2684
2685   base_service = NULL;
2686
2687   dbus_error_init (&error);
2688
2689   message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME,
2690                                           "/org/freedesktop/TestSuite",
2691                                           "org.freedesktop.TestSuite",
2692                                           "Echo");
2693   
2694   if (message == NULL)
2695     return TRUE;
2696
2697   dbus_message_set_auto_activation (message, TRUE);
2698
2699   if (!dbus_message_append_args (message,
2700                                  DBUS_TYPE_STRING, TEST_ECHO_MESSAGE,
2701                                  DBUS_TYPE_INVALID))
2702     {
2703       dbus_message_unref (message);
2704       return TRUE;
2705     }
2706
2707   if (!dbus_connection_send (connection, message, &serial))
2708     {
2709       dbus_message_unref (message);
2710       return TRUE;
2711     }
2712
2713   dbus_message_unref (message);
2714   message = NULL;
2715
2716   bus_test_run_everything (context);
2717
2718   /* now wait for the message bus to hear back from the activated
2719    * service.
2720    */
2721   block_connection_until_message_from_bus (context, connection);
2722   bus_test_run_everything (context);
2723
2724   if (!dbus_connection_get_is_connected (connection))
2725     {
2726       _dbus_verbose ("connection was disconnected\n");
2727       return TRUE;
2728     }
2729
2730   retval = FALSE;
2731   
2732   /* Should get ServiceCreated for the base service, or an error. */
2733   message = pop_message_waiting_for_memory (connection);
2734   if (message == NULL)
2735     {
2736       _dbus_warn ("Did not receive any messages after auto activation %d on %p\n",
2737                   serial, connection);
2738       goto out;
2739     }
2740
2741   verbose_message_received (connection, message);
2742   _dbus_verbose ("  (after sending %s)\n", "ActivateService");
2743
2744   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
2745     {
2746       if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
2747         {
2748           _dbus_warn ("Message has wrong sender %s\n",
2749                       dbus_message_get_sender (message) ?
2750                       dbus_message_get_sender (message) : "(none)");
2751           goto out;
2752         }
2753
2754       if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY) ||
2755           dbus_message_is_error (message, DBUS_ERROR_SPAWN_CHILD_EXITED) ||
2756           dbus_message_is_error (message, DBUS_ERROR_TIMED_OUT))
2757         {
2758           ; /* good, those are expected */
2759           retval = TRUE;
2760           goto out;
2761         }
2762       else
2763         {
2764           _dbus_warn ("Did not expect error %s\n",
2765                       dbus_message_get_error_name (message));
2766           goto out;
2767         }
2768     }
2769   else
2770     {
2771       dbus_bool_t got_service_deleted;
2772       dbus_bool_t got_error;
2773       
2774       if (!check_base_service_activated (context, connection,
2775                                          message, &base_service))
2776         goto out;
2777
2778       dbus_message_unref (message);
2779       message = NULL;
2780
2781       /* We may need to block here for the test service to exit or finish up */
2782       block_connection_until_message_from_bus (context, connection);
2783
2784       /* Should get ServiceCreated for the activated service name,
2785        * ServiceDeleted on the base service name, or an error.
2786        */
2787       message = dbus_connection_borrow_message (connection);
2788       if (message == NULL)
2789         {
2790           _dbus_warn ("Did not receive any messages after base service creation notification\n");
2791           goto out;
2792         }
2793
2794       got_service_deleted = dbus_message_is_signal (message,
2795                                                     DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
2796                                                     "ServiceDeleted");
2797       got_error = dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR;
2798
2799       dbus_connection_return_message (connection, message);
2800       message = NULL;
2801
2802       if (got_error)
2803         {
2804           if (!check_got_error (context, connection,
2805                                 DBUS_ERROR_SPAWN_CHILD_EXITED,
2806                                 DBUS_ERROR_NO_MEMORY,
2807                                 NULL))
2808             goto out;
2809
2810           /* A service deleted should be coming along now after this error.
2811            * We can also get the error *after* the service deleted.
2812            */
2813           got_service_deleted = TRUE;
2814         }
2815       
2816       if (got_service_deleted)
2817         {
2818           /* The service started up and got a base address, but then
2819            * failed to register under EXISTENT_SERVICE_NAME
2820            */
2821           CheckServiceDeletedData csdd;
2822           
2823           csdd.expected_service_name = base_service;
2824           csdd.failed = FALSE;
2825           bus_test_clients_foreach (check_service_deleted_foreach,
2826                                     &csdd);
2827
2828           if (csdd.failed)
2829             goto out;
2830           
2831           /* Now we should get an error about the service exiting
2832            * if we didn't get it before.
2833            */
2834           if (!got_error)
2835             {
2836               block_connection_until_message_from_bus (context, connection);
2837               
2838               /* and process everything again */
2839               bus_test_run_everything (context);
2840
2841               if (!check_got_error (context, connection,
2842                                     DBUS_ERROR_SPAWN_CHILD_EXITED,
2843                                     NULL))
2844                 goto out;
2845             }
2846         }
2847       else
2848         {
2849           message = pop_message_waiting_for_memory (connection);
2850           if (message == NULL)
2851             {
2852               _dbus_warn ("Failed to pop message we just put back! should have been a ServiceCreated\n");
2853               goto out;
2854             }
2855
2856           /* Check that ServiceCreated was correctly received */
2857           if (!check_service_auto_activated (context, connection, EXISTENT_SERVICE_NAME,
2858                                              base_service, message))
2859             goto out;
2860
2861           dbus_message_unref (message);
2862           message = NULL;
2863         }
2864
2865       /* Note: if this test is run in OOM mode, it will block when the bus
2866        * doesn't send a reply due to OOM.
2867        */
2868       block_connection_until_message_from_bus (context, connection);
2869       
2870       message = pop_message_waiting_for_memory (connection);
2871       if (message == NULL)
2872         {
2873           _dbus_warn ("Failed to pop message! Should have been reply from echo message\n");
2874           goto out;
2875         }
2876
2877       if (dbus_message_get_reply_serial (message) != serial)
2878         {
2879           _dbus_warn ("Wrong reply serial\n");
2880           goto out;
2881         }
2882
2883       dbus_message_unref (message);
2884       message = NULL;
2885       
2886       if (!check_send_exit_to_service (context, connection,
2887                                        EXISTENT_SERVICE_NAME,
2888                                        base_service))
2889         goto out;
2890     }
2891   
2892   retval = TRUE;
2893
2894  out:
2895   if (message)
2896     dbus_message_unref (message);
2897
2898   if (base_service)
2899     dbus_free (base_service);
2900
2901   return retval;
2902 }
2903
2904 typedef struct
2905 {
2906   Check1Func func;
2907   BusContext *context;
2908 } Check1Data;
2909
2910 static dbus_bool_t
2911 check_oom_check1_func (void *data)
2912 {
2913   Check1Data *d = data;
2914
2915   if (! (* d->func) (d->context))
2916     return FALSE;
2917   
2918   if (!check_no_leftovers (d->context))
2919     {
2920       _dbus_warn ("Messages were left over, should be covered by test suite\n");
2921       return FALSE;
2922     }
2923
2924   return TRUE;
2925 }
2926
2927 static void
2928 check1_try_iterations (BusContext *context,
2929                        const char *description,
2930                        Check1Func  func)
2931 {
2932   Check1Data d;
2933
2934   d.func = func;
2935   d.context = context;
2936
2937   if (!_dbus_test_oom_handling (description, check_oom_check1_func,
2938                                 &d))
2939     _dbus_assert_not_reached ("test failed");
2940 }
2941
2942 typedef struct
2943 {
2944   Check2Func func;
2945   BusContext *context;
2946   DBusConnection *connection;
2947 } Check2Data;
2948
2949 static dbus_bool_t
2950 check_oom_check2_func (void *data)
2951 {
2952   Check2Data *d = data;
2953
2954   if (! (* d->func) (d->context, d->connection))
2955     return FALSE;
2956   
2957   if (!check_no_leftovers (d->context))
2958     {
2959       _dbus_warn ("Messages were left over, should be covered by test suite");
2960       return FALSE;
2961     }
2962
2963   return TRUE;
2964 }
2965
2966 static void
2967 check2_try_iterations (BusContext     *context,
2968                        DBusConnection *connection,
2969                        const char     *description,
2970                        Check2Func      func)
2971 {
2972   Check2Data d;
2973
2974   d.func = func;
2975   d.context = context;
2976   d.connection = connection;
2977   
2978   if (!_dbus_test_oom_handling (description, check_oom_check2_func,
2979                                 &d))
2980     {
2981       _dbus_warn ("%s failed during oom\n", description);
2982       _dbus_assert_not_reached ("test failed");
2983     }
2984 }
2985
2986 dbus_bool_t
2987 bus_dispatch_test (const DBusString *test_data_dir)
2988 {
2989   BusContext *context;
2990   DBusConnection *foo;
2991   DBusConnection *bar;
2992   DBusConnection *baz;
2993   DBusError error;
2994
2995   dbus_error_init (&error);
2996   
2997   context = bus_context_new_test (test_data_dir,
2998                                   "valid-config-files/debug-allow-all.conf");
2999   if (context == NULL)
3000     return FALSE;
3001   
3002   foo = dbus_connection_open ("debug-pipe:name=test-server", &error);
3003   if (foo == NULL)
3004     _dbus_assert_not_reached ("could not alloc connection");
3005
3006   if (!bus_setup_debug_client (foo))
3007     _dbus_assert_not_reached ("could not set up connection");
3008
3009   if (!check_hello_message (context, foo))
3010     _dbus_assert_not_reached ("hello message failed");
3011
3012   if (!check_double_hello_message (context, foo))
3013     _dbus_assert_not_reached ("double hello message failed");
3014
3015   if (!check_add_match_all (context, foo))
3016     _dbus_assert_not_reached ("AddMatch message failed");
3017   
3018   bar = dbus_connection_open ("debug-pipe:name=test-server", &error);
3019   if (bar == NULL)
3020     _dbus_assert_not_reached ("could not alloc connection");
3021
3022   if (!bus_setup_debug_client (bar))
3023     _dbus_assert_not_reached ("could not set up connection");
3024
3025   if (!check_hello_message (context, bar))
3026     _dbus_assert_not_reached ("hello message failed");
3027
3028   if (!check_add_match_all (context, bar))
3029     _dbus_assert_not_reached ("AddMatch message failed");
3030   
3031   baz = dbus_connection_open ("debug-pipe:name=test-server", &error);
3032   if (baz == NULL)
3033     _dbus_assert_not_reached ("could not alloc connection");
3034
3035   if (!bus_setup_debug_client (baz))
3036     _dbus_assert_not_reached ("could not set up connection");
3037
3038   if (!check_hello_message (context, baz))
3039     _dbus_assert_not_reached ("hello message failed");
3040
3041   if (!check_add_match_all (context, baz))
3042     _dbus_assert_not_reached ("AddMatch message failed");
3043
3044   if (!check_get_connection_unix_user (context, baz))
3045     _dbus_assert_not_reached ("GetConnectionUnixUser message failed");
3046
3047   if (!check_get_connection_unix_process_id (context, baz))
3048     _dbus_assert_not_reached ("GetConnectionUnixProcessID message failed");
3049   
3050   if (!check_no_leftovers (context))
3051     {
3052       _dbus_warn ("Messages were left over after setting up initial connections");
3053       _dbus_assert_not_reached ("initial connection setup failed");
3054     }
3055   
3056   check1_try_iterations (context, "create_and_hello",
3057                          check_hello_connection);
3058   
3059   check2_try_iterations (context, foo, "nonexistent_service_activation",
3060                          check_nonexistent_service_activation);
3061
3062   check2_try_iterations (context, foo, "segfault_service_activation",
3063                          check_segfault_service_activation);
3064   
3065   check2_try_iterations (context, foo, "existent_service_activation",
3066                          check_existent_service_activation);
3067   
3068   check2_try_iterations (context, foo, "nonexistent_service_auto_activation",
3069                          check_nonexistent_service_auto_activation);
3070   
3071   check2_try_iterations (context, foo, "segfault_service_auto_activation",
3072                          check_segfault_service_auto_activation);
3073
3074 #if 0
3075   /* Note: need to resolve some issues with the testing code in order to run
3076    * this in oom (handle that we sometimes don't get replies back from the bus
3077    * when oom happens, without blocking the test).
3078    */
3079   check2_try_iterations (context, foo, "existent_service_auto_activation",
3080                          check_existent_service_auto_activation);
3081 #endif
3082   
3083   if (!check_existent_service_auto_activation (context, foo))
3084     _dbus_assert_not_reached ("existent service auto activation failed");
3085
3086   _dbus_verbose ("Disconnecting foo, bar, and baz\n");
3087
3088   kill_client_connection_unchecked (foo);
3089   kill_client_connection_unchecked (bar);
3090   kill_client_connection_unchecked (baz);
3091
3092   bus_context_unref (context);
3093   
3094   return TRUE;
3095 }
3096
3097 dbus_bool_t
3098 bus_dispatch_sha1_test (const DBusString *test_data_dir)
3099 {
3100   BusContext *context;
3101   DBusConnection *foo;
3102   DBusError error;
3103
3104   dbus_error_init (&error);
3105   
3106   /* Test SHA1 authentication */
3107   _dbus_verbose ("Testing SHA1 context\n");
3108   
3109   context = bus_context_new_test (test_data_dir,
3110                                   "valid-config-files/debug-allow-all-sha1.conf");
3111   if (context == NULL)
3112     return FALSE;
3113
3114   foo = dbus_connection_open ("debug-pipe:name=test-server", &error);
3115   if (foo == NULL)
3116     _dbus_assert_not_reached ("could not alloc connection");
3117
3118   if (!bus_setup_debug_client (foo))
3119     _dbus_assert_not_reached ("could not set up connection");
3120
3121   if (!check_hello_message (context, foo))
3122     _dbus_assert_not_reached ("hello message failed");
3123
3124   if (!check_add_match_all (context, foo))
3125     _dbus_assert_not_reached ("addmatch message failed");
3126   
3127   if (!check_no_leftovers (context))
3128     {
3129       _dbus_warn ("Messages were left over after setting up initial SHA-1 connection\n");
3130       _dbus_assert_not_reached ("initial connection setup failed");
3131     }
3132   
3133   check1_try_iterations (context, "create_and_hello_sha1",
3134                          check_hello_connection);
3135
3136   kill_client_connection_unchecked (foo);
3137
3138   bus_context_unref (context);
3139
3140   return TRUE;
3141 }
3142
3143 #endif /* DBUS_BUILD_TESTS */