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