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