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