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