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