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