Sophie

Sophie

distrib > Mandriva > 2007.0 > x86_64 > media > main-release > by-pkgid > 926d2d1e3111287cee1b0a4fad4fb4f6 > files > 151

lib64dbus-1_3-devel-0.92-6mdv2007.0.x86_64.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>dispatch.c Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.2.15 -->
<center>
<a class="qindex" href="index.html">Main Page</a> &nbsp; <a class="qindex" href="modules.html">Modules</a> &nbsp; <a class="qindex" href="annotated.html">Data Structures</a> &nbsp; <a class="qindex" href="files.html">File List</a> &nbsp; <a class="qindex" href="functions.html">Data Fields</a> &nbsp; <a class="qindex" href="pages.html">Related Pages</a> &nbsp; </center>
<hr><h1>dispatch.c</h1><div class="fragment"><pre>00001 <font class="comment">/* -*- mode: C; c-file-style: "gnu" -*- */</font>
00002 <font class="comment">/* dispatch.c  Message dispatcher</font>
00003 <font class="comment"> *</font>
00004 <font class="comment"> * Copyright (C) 2003  CodeFactory AB</font>
00005 <font class="comment"> * Copyright (C) 2003  Red Hat, Inc.</font>
00006 <font class="comment"> *</font>
00007 <font class="comment"> * Licensed under the Academic Free License version 1.2</font>
00008 <font class="comment"> * </font>
00009 <font class="comment"> * This program is free software; you can redistribute it and/or modify</font>
00010 <font class="comment"> * it under the terms of the GNU General Public License as published by</font>
00011 <font class="comment"> * the Free Software Foundation; either version 2 of the License, or</font>
00012 <font class="comment"> * (at your option) any later version.</font>
00013 <font class="comment"> *</font>
00014 <font class="comment"> * This program is distributed in the hope that it will be useful,</font>
00015 <font class="comment"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</font>
00016 <font class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</font>
00017 <font class="comment"> * GNU General Public License for more details.</font>
00018 <font class="comment"> * </font>
00019 <font class="comment"> * You should have received a copy of the GNU General Public License</font>
00020 <font class="comment"> * along with this program; if not, write to the Free Software</font>
00021 <font class="comment"> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA</font>
00022 <font class="comment"> *</font>
00023 <font class="comment"> */</font>
00024 
00025 <font class="preprocessor">#include "dispatch.h"</font>
00026 <font class="preprocessor">#include "connection.h"</font>
00027 <font class="preprocessor">#include "driver.h"</font>
00028 <font class="preprocessor">#include "services.h"</font>
00029 <font class="preprocessor">#include "utils.h"</font>
00030 <font class="preprocessor">#include "bus.h"</font>
00031 <font class="preprocessor">#include "signals.h"</font>
00032 <font class="preprocessor">#include "test.h"</font>
00033 <font class="preprocessor">#include &lt;dbus/dbus-internals.h&gt;</font>
00034 <font class="preprocessor">#include &lt;string.h&gt;</font>
00035 
00036 <font class="keyword">static</font> dbus_bool_t
00037 send_one_message (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
00038                   BusContext     *context,
00039                   <a class="code" href="structDBusConnection.html">DBusConnection</a> *sender,
00040                   <a class="code" href="structDBusConnection.html">DBusConnection</a> *addressed_recipient,
00041                   <a class="code" href="structDBusMessage.html">DBusMessage</a>    *message,
00042                   BusTransaction *transaction,
00043                   <a class="code" href="structDBusError.html">DBusError</a>      *error)
00044 {
00045   <font class="keywordflow">if</font> (!bus_context_check_security_policy (context,
00046                                           sender,
00047                                           addressed_recipient,
00048                                           connection,
00049                                           message,
00050                                           NULL))
00051     <font class="keywordflow">return</font> TRUE; <font class="comment">/* silently don't send it */</font>
00052   
00053   <font class="keywordflow">if</font> (!bus_transaction_send (transaction,
00054                              connection,
00055                              message))
00056     {
00057       BUS_SET_OOM (error);
00058       <font class="keywordflow">return</font> FALSE;
00059     }
00060 
00061   <font class="keywordflow">return</font> TRUE;
00062 }
00063 
00064 dbus_bool_t
00065 bus_dispatch_matches (BusTransaction *transaction,
00066                       <a class="code" href="structDBusConnection.html">DBusConnection</a> *sender,
00067                       <a class="code" href="structDBusConnection.html">DBusConnection</a> *addressed_recipient,
00068                       <a class="code" href="structDBusMessage.html">DBusMessage</a>    *message,
00069                       <a class="code" href="structDBusError.html">DBusError</a>      *error)
00070 {
00071   <a class="code" href="structDBusError.html">DBusError</a> tmp_error;
00072   BusConnections *connections;
00073   <a class="code" href="structDBusList.html">DBusList</a> *recipients;
00074   BusMatchmaker *matchmaker;
00075   <a class="code" href="structDBusList.html">DBusList</a> *link;
00076   BusContext *context;
00077 
00078   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00079 
00080   <font class="comment">/* sender and recipient can both be NULL for the bus driver,</font>
00081 <font class="comment">   * or for signals with no particular recipient</font>
00082 <font class="comment">   */</font>
00083 
00084   _dbus_assert (sender == NULL || bus_connection_is_active (sender));
00085   _dbus_assert (dbus_message_get_sender (message) != NULL);
00086 
00087   connections = bus_transaction_get_connections (transaction);
00088   
00089   dbus_error_init (&amp;tmp_error);
00090   context = bus_transaction_get_context (transaction);
00091   matchmaker = bus_context_get_matchmaker (context);
00092 
00093   recipients = NULL;
00094   <font class="keywordflow">if</font> (!bus_matchmaker_get_recipients (matchmaker,
00095                                       bus_context_get_connections (context),
00096                                       sender, addressed_recipient, message,
00097                                       &amp;recipients))
00098     {
00099       BUS_SET_OOM (error);
00100       <font class="keywordflow">return</font> FALSE;
00101     }
00102 
00103   link = _dbus_list_get_first_link (&amp;recipients);
00104   <font class="keywordflow">while</font> (link != NULL)
00105     {
00106       <a class="code" href="structDBusConnection.html">DBusConnection</a> *dest;
00107 
00108       dest = link-&gt;<a class="code" href="structDBusList.html#m2">data</a>;
00109 
00110       <font class="keywordflow">if</font> (!send_one_message (dest, context, sender, addressed_recipient,
00111                              message, transaction, &amp;tmp_error))
00112         <font class="keywordflow">break</font>;
00113 
00114       link = _dbus_list_get_next_link (&amp;recipients, link);
00115     }
00116 
00117   _dbus_list_clear (&amp;recipients);
00118   
00119   <font class="keywordflow">if</font> (dbus_error_is_set (&amp;tmp_error))
00120     {
00121       dbus_move_error (&amp;tmp_error, error);
00122       <font class="keywordflow">return</font> FALSE;
00123     }
00124   <font class="keywordflow">else</font>
00125     <font class="keywordflow">return</font> TRUE;
00126 }
00127 
00128 <font class="keyword">static</font> DBusHandlerResult
00129 bus_dispatch (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
00130               <a class="code" href="structDBusMessage.html">DBusMessage</a>    *message)
00131 {
00132   <font class="keyword">const</font> <font class="keywordtype">char</font> *sender, *service_name;
00133   <a class="code" href="structDBusError.html">DBusError</a> error;
00134   BusTransaction *transaction;
00135   BusContext *context;
00136   DBusHandlerResult result;
00137   <a class="code" href="structDBusConnection.html">DBusConnection</a> *addressed_recipient;
00138   
00139   result = DBUS_HANDLER_RESULT_HANDLED;
00140   
00141   transaction = NULL;
00142   addressed_recipient = NULL;
00143   dbus_error_init (&amp;error);
00144   
00145   context = bus_connection_get_context (connection);
00146   _dbus_assert (context != NULL);
00147   
00148   <font class="comment">/* If we can't even allocate an OOM error, we just go to sleep</font>
00149 <font class="comment">   * until we can.</font>
00150 <font class="comment">   */</font>
00151   <font class="keywordflow">while</font> (!bus_connection_preallocate_oom_error (connection))
00152     _dbus_wait_for_memory ();
00153   
00154   <font class="comment">/* Ref connection in case we disconnect it at some point in here */</font>
00155   dbus_connection_ref (connection);
00156   
00157   service_name = dbus_message_get_destination (message);
00158 
00159 <font class="preprocessor">#ifdef DBUS_ENABLE_VERBOSE_MODE</font>
00160 <font class="preprocessor"></font>  {
00161     <font class="keyword">const</font> <font class="keywordtype">char</font> *interface_name, *member_name, *error_name;
00162 
00163     interface_name = dbus_message_get_interface (message);
00164     member_name = dbus_message_get_member (message);
00165     error_name = dbus_message_get_error_name (message);
00166     
00167     _dbus_verbose (<font class="stringliteral">"DISPATCH: %s %s %s to %s\n"</font>,
00168                    interface_name ? interface_name : <font class="stringliteral">"(no interface)"</font>,
00169                    member_name ? member_name : <font class="stringliteral">"(no member)"</font>,
00170                    error_name ? error_name : <font class="stringliteral">"(no error name)"</font>,
00171                    service_name ? service_name : <font class="stringliteral">"peer"</font>);
00172   }
00173 <font class="preprocessor">#endif </font><font class="comment">/* DBUS_ENABLE_VERBOSE_MODE */</font>
00174   
00175   <font class="comment">/* If service_name is NULL, if it's a signal we send it to all</font>
00176 <font class="comment">   * connections with a match rule. If it's not a signal, it goes to</font>
00177 <font class="comment">   * the bus daemon but doesn't go "on the bus"; e.g. a peer-to-peer</font>
00178 <font class="comment">   * ping. Handle these immediately, especially disconnection</font>
00179 <font class="comment">   * messages. There are no security policy checks on these.</font>
00180 <font class="comment">   */</font>
00181   <font class="keywordflow">if</font> (service_name == NULL)
00182     {
00183       <font class="keywordflow">if</font> (dbus_message_is_signal (message,
00184                                   DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
00185                                   <font class="stringliteral">"Disconnected"</font>))
00186         {
00187           bus_connection_disconnected (connection);
00188           <font class="keywordflow">goto</font> out;
00189         }
00190 
00191       <font class="keywordflow">if</font> (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL)
00192         {
00193           <font class="comment">/* DBusConnection also handles some of these automatically, we leave</font>
00194 <font class="comment">           * it to do so.</font>
00195 <font class="comment">           */</font>
00196           result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00197           <font class="keywordflow">goto</font> out;
00198         }
00199     }
00200   
00201   <font class="comment">/* Create our transaction */</font>
00202   transaction = bus_transaction_new (context);
00203   <font class="keywordflow">if</font> (transaction == NULL)
00204     {
00205       BUS_SET_OOM (&amp;error);
00206       <font class="keywordflow">goto</font> out;
00207     }
00208   
00209   <font class="comment">/* Assign a sender to the message */</font>
00210   <font class="keywordflow">if</font> (bus_connection_is_active (connection))
00211     {
00212       sender = bus_connection_get_name (connection);
00213       _dbus_assert (sender != NULL);
00214 
00215       <font class="keywordflow">if</font> (!dbus_message_set_sender (message, sender))
00216         {
00217           BUS_SET_OOM (&amp;error);
00218           <font class="keywordflow">goto</font> out;
00219         }
00220 
00221       <font class="comment">/* We need to refetch the service name here, because</font>
00222 <font class="comment">       * dbus_message_set_sender can cause the header to be</font>
00223 <font class="comment">       * reallocated, and thus the service_name pointer will become</font>
00224 <font class="comment">       * invalid.</font>
00225 <font class="comment">       */</font>
00226       service_name = dbus_message_get_destination (message);
00227     }
00228   
00229   <font class="keywordflow">if</font> (service_name &amp;&amp;
00230       strcmp (service_name, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS) == 0) <font class="comment">/* to bus driver */</font>
00231     {
00232       <font class="keywordflow">if</font> (!bus_context_check_security_policy (context,
00233                                               connection, NULL, NULL, message, &amp;error))
00234         {
00235           _dbus_verbose (<font class="stringliteral">"Security policy rejected message\n"</font>);
00236           <font class="keywordflow">goto</font> out;
00237         }
00238 
00239       _dbus_verbose (<font class="stringliteral">"Giving message to %s\n"</font>, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
00240       <font class="keywordflow">if</font> (!bus_driver_handle_message (connection, transaction, message, &amp;error))
00241         <font class="keywordflow">goto</font> out;
00242     }
00243   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (!bus_connection_is_active (connection)) <font class="comment">/* clients must talk to bus driver first */</font>
00244     {
00245       _dbus_verbose (<font class="stringliteral">"Received message from non-registered client. Disconnecting.\n"</font>);
00246       dbus_connection_disconnect (connection);
00247       <font class="keywordflow">goto</font> out;
00248     }
00249   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (service_name != NULL) <font class="comment">/* route to named service */</font>
00250     {
00251       <a class="code" href="structDBusString.html">DBusString</a> service_string;
00252       BusService *service;
00253       BusRegistry *registry;
00254 
00255       _dbus_assert (service_name != NULL);
00256       
00257       registry = bus_connection_get_registry (connection);
00258       
00259       _dbus_string_init_const (&amp;service_string, service_name);
00260       service = bus_registry_lookup (registry, &amp;service_string);
00261 
00262       <font class="keywordflow">if</font> (service == NULL)
00263         {
00264           dbus_set_error (&amp;error,
00265                           DBUS_ERROR_SERVICE_DOES_NOT_EXIST,
00266                           <font class="stringliteral">"Service \"%s\" does not exist"</font>,
00267                           service_name);
00268           <font class="keywordflow">goto</font> out;
00269         }
00270       <font class="keywordflow">else</font>
00271         {          
00272           addressed_recipient = bus_service_get_primary_owner (service);
00273           _dbus_assert (addressed_recipient != NULL);
00274           
00275           <font class="keywordflow">if</font> (!bus_context_check_security_policy (context,
00276                                                   connection, addressed_recipient,
00277                                                   addressed_recipient,
00278                                                   message, &amp;error))
00279             <font class="keywordflow">goto</font> out;
00280           
00281           <font class="comment">/* Dispatch the message */</font>
00282           <font class="keywordflow">if</font> (!bus_transaction_send (transaction, addressed_recipient, message))
00283             {
00284               BUS_SET_OOM (&amp;error);
00285               <font class="keywordflow">goto</font> out;
00286             }
00287         }
00288     }
00289 
00290   <font class="comment">/* Now match the messages against any match rules, which will send</font>
00291 <font class="comment">   * out signals and such. addressed_recipient may == NULL.</font>
00292 <font class="comment">   */</font>
00293   <font class="keywordflow">if</font> (!bus_dispatch_matches (transaction, connection, addressed_recipient, message, &amp;error))
00294     <font class="keywordflow">goto</font> out;
00295   
00296  out:
00297   <font class="keywordflow">if</font> (dbus_error_is_set (&amp;error))
00298     {
00299       <font class="keywordflow">if</font> (!dbus_connection_get_is_connected (connection))
00300         {
00301           <font class="comment">/* If we disconnected it, we won't bother to send it any error</font>
00302 <font class="comment">           * messages.</font>
00303 <font class="comment">           */</font>
00304           _dbus_verbose (<font class="stringliteral">"Not sending error to connection we disconnected\n"</font>);
00305         }
00306       <font class="keywordflow">else</font> <font class="keywordflow">if</font> (dbus_error_has_name (&amp;error, DBUS_ERROR_NO_MEMORY))
00307         {
00308           bus_connection_send_oom_error (connection, message);
00309 
00310           <font class="comment">/* cancel transaction due to OOM */</font>
00311           <font class="keywordflow">if</font> (transaction != NULL)
00312             {
00313               bus_transaction_cancel_and_free (transaction);
00314               transaction = NULL;
00315             }
00316         }
00317       <font class="keywordflow">else</font>
00318         {
00319           <font class="comment">/* Try to send the real error, if no mem to do that, send</font>
00320 <font class="comment">           * the OOM error</font>
00321 <font class="comment">           */</font>
00322           _dbus_assert (transaction != NULL);
00323           
00324           <font class="keywordflow">if</font> (!bus_transaction_send_error_reply (transaction, connection,
00325                                                  &amp;error, message))
00326             {
00327               bus_connection_send_oom_error (connection, message);
00328               
00329               <font class="comment">/* cancel transaction due to OOM */</font>
00330               <font class="keywordflow">if</font> (transaction != NULL)
00331                 {
00332                   bus_transaction_cancel_and_free (transaction);
00333                   transaction = NULL;
00334                 }
00335             }
00336         }
00337       
00338       dbus_error_free (&amp;error);
00339     }
00340 
00341   <font class="keywordflow">if</font> (transaction != NULL)
00342     {
00343       bus_transaction_execute_and_free (transaction);
00344     }
00345 
00346   dbus_connection_unref (connection);
00347 
00348   <font class="keywordflow">return</font> result;
00349 }
00350 
00351 <font class="keyword">static</font> DBusHandlerResult
00352 bus_dispatch_message_filter (<a class="code" href="structDBusConnection.html">DBusConnection</a>     *connection,
00353                              <a class="code" href="structDBusMessage.html">DBusMessage</a>        *message,
00354                              <font class="keywordtype">void</font>               *user_data)
00355 {
00356   <font class="keywordflow">return</font> bus_dispatch (connection, message);
00357 }
00358 
00359 dbus_bool_t
00360 bus_dispatch_add_connection (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
00361 {  
00362   <font class="keywordflow">if</font> (!dbus_connection_add_filter (connection,
00363                                    bus_dispatch_message_filter,
00364                                    NULL, NULL))
00365     <font class="keywordflow">return</font> FALSE;
00366   
00367   <font class="keywordflow">return</font> TRUE;
00368 }
00369 
00370 <font class="keywordtype">void</font>
00371 bus_dispatch_remove_connection (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
00372 {
00373   <font class="comment">/* Here we tell the bus driver that we want to get off. */</font>
00374   bus_driver_remove_connection (connection);
00375 
00376   dbus_connection_remove_filter (connection,
00377                                  bus_dispatch_message_filter,
00378                                  NULL);
00379 }
00380 
00381 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font>
00382 <font class="preprocessor"></font>
00383 <font class="keyword">typedef</font> dbus_bool_t (* Check1Func) (BusContext     *context);
00384 <font class="keyword">typedef</font> dbus_bool_t (* Check2Func) (BusContext     *context,
00385                                     <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection);
00386 
00387 <font class="keyword">static</font> dbus_bool_t check_no_leftovers (BusContext *context);
00388 
00389 <font class="keyword">static</font> <font class="keywordtype">void</font>
00390 block_connection_until_message_from_bus (BusContext     *context,
00391                                          <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
00392 {
00393   <font class="keywordflow">while</font> (dbus_connection_get_dispatch_status (connection) ==
00394          DBUS_DISPATCH_COMPLETE &amp;&amp;
00395          dbus_connection_get_is_connected (connection))
00396     {
00397       bus_test_run_bus_loop (context, TRUE);
00398       bus_test_run_clients_loop (FALSE);
00399     }
00400 }
00401 
00402 <font class="comment">/* compensate for fact that pop_message() can return #NULL due to OOM */</font>
00403 <font class="keyword">static</font> <a class="code" href="structDBusMessage.html">DBusMessage</a>*
00404 pop_message_waiting_for_memory (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
00405 {
00406   <font class="keywordflow">while</font> (dbus_connection_get_dispatch_status (connection) ==
00407          DBUS_DISPATCH_NEED_MEMORY)
00408     _dbus_wait_for_memory ();
00409 
00410   <font class="keywordflow">return</font> dbus_connection_pop_message (connection);
00411 }
00412 
00413 <font class="keyword">static</font> <font class="keywordtype">void</font>
00414 warn_unexpected_real (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
00415                       <a class="code" href="structDBusMessage.html">DBusMessage</a>    *message,
00416                       <font class="keyword">const</font> <font class="keywordtype">char</font>     *expected,
00417                       <font class="keyword">const</font> <font class="keywordtype">char</font>     *function,
00418                       <font class="keywordtype">int</font>             line)
00419 {
00420   _dbus_warn (<font class="stringliteral">"%s:%d received message interface \"%s\" member \"%s\" error name \"%s\" on %p, expecting %s\n"</font>,
00421               function, line,
00422               dbus_message_get_interface (message) ?
00423               dbus_message_get_interface (message) : "(unset)",
00424               dbus_message_get_member (message) ?
00425               dbus_message_get_member (message) : "(unset)",
00426               dbus_message_get_error_name (message) ?
00427               dbus_message_get_error_name (message) : "(unset)",
00428               connection,
00429               expected);
00430 }
00431 
00432 <font class="preprocessor">#define warn_unexpected(connection, message, expected) \</font>
00433 <font class="preprocessor">  warn_unexpected_real (connection, message, expected, _DBUS_FUNCTION_NAME, __LINE__)</font>
00434 <font class="preprocessor"></font>
00435 <font class="keyword">static</font> <font class="keywordtype">void</font>
00436 verbose_message_received (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
00437                           <a class="code" href="structDBusMessage.html">DBusMessage</a>    *message)
00438 {
00439   _dbus_verbose (<font class="stringliteral">"Received message interface \"%s\" member \"%s\" error name \"%s\" on %p\n"</font>,
00440                  dbus_message_get_interface (message) ?
00441                  dbus_message_get_interface (message) : "(unset)",
00442                  dbus_message_get_member (message) ?
00443                  dbus_message_get_member (message) : "(unset)",
00444                  dbus_message_get_error_name (message) ?
00445                  dbus_message_get_error_name (message) : "(unset)",
00446                  connection);
00447 }
00448 
00449 <font class="keyword">typedef</font> <font class="keyword">struct</font>
00450 <font class="keyword"></font>{
00451   <font class="keyword">const</font> <font class="keywordtype">char</font> *expected_service_name;
00452   dbus_bool_t failed;
00453 } CheckServiceDeletedData;
00454 
00455 <font class="keyword">static</font> dbus_bool_t
00456 check_service_deleted_foreach (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
00457                                <font class="keywordtype">void</font>           *data)
00458 {
00459   CheckServiceDeletedData *d = data;
00460   <a class="code" href="structDBusMessage.html">DBusMessage</a> *message;
00461   <a class="code" href="structDBusError.html">DBusError</a> error;
00462   <font class="keywordtype">char</font> *service_name;
00463 
00464   dbus_error_init (&amp;error);
00465   d-&gt;failed = TRUE;
00466   service_name = NULL;
00467   
00468   message = pop_message_waiting_for_memory (connection);
00469   <font class="keywordflow">if</font> (message == NULL)
00470     {
00471       _dbus_warn (<font class="stringliteral">"Did not receive a message on %p, expecting %s\n"</font>,
00472                   connection, <font class="stringliteral">"ServiceDeleted"</font>);
00473       <font class="keywordflow">goto</font> out;
00474     }
00475   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (!dbus_message_is_signal (message,
00476                                     DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
00477                                     <font class="stringliteral">"ServiceDeleted"</font>))
00478     {
00479       warn_unexpected (connection, message, <font class="stringliteral">"ServiceDeleted"</font>);
00480 
00481       <font class="keywordflow">goto</font> out;
00482     }
00483   <font class="keywordflow">else</font>
00484     {
00485       <font class="keywordflow">if</font> (!dbus_message_get_args (message, &amp;error,
00486                                   DBUS_TYPE_STRING, &amp;service_name,
00487                                   DBUS_TYPE_INVALID))
00488         {
00489           <font class="keywordflow">if</font> (dbus_error_has_name (&amp;error, DBUS_ERROR_NO_MEMORY))
00490             {
00491               _dbus_verbose (<font class="stringliteral">"no memory to get service name arg\n"</font>);
00492             }
00493           <font class="keywordflow">else</font>
00494             {
00495               _dbus_assert (dbus_error_is_set (&amp;error));
00496               _dbus_warn (<font class="stringliteral">"Did not get the expected single string argument\n"</font>);
00497               <font class="keywordflow">goto</font> out;
00498             }
00499         }
00500       <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (service_name, d-&gt;expected_service_name) != 0)
00501         {
00502           _dbus_warn (<font class="stringliteral">"expected deletion of service %s, got deletion of %s\n"</font>,
00503                       d-&gt;expected_service_name,
00504                       service_name);
00505           <font class="keywordflow">goto</font> out;
00506         }
00507     }
00508 
00509   d-&gt;failed = FALSE;
00510   
00511  out:
00512   dbus_free (service_name);
00513   dbus_error_free (&amp;error);
00514   
00515   <font class="keywordflow">if</font> (message)
00516     dbus_message_unref (message);
00517 
00518   <font class="keywordflow">return</font> !d-&gt;failed;
00519 }
00520 
00521 <font class="keyword">static</font> <font class="keywordtype">void</font>
00522 kill_client_connection (BusContext     *context,
00523                         <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
00524 {
00525   <font class="keywordtype">char</font> *base_service;
00526   <font class="keyword">const</font> <font class="keywordtype">char</font> *s;
00527   CheckServiceDeletedData csdd;
00528 
00529   _dbus_verbose (<font class="stringliteral">"killing connection %p\n"</font>, connection);
00530   
00531   s = dbus_bus_get_base_service (connection);
00532   _dbus_assert (s != NULL);
00533 
00534   <font class="keywordflow">while</font> ((base_service = _dbus_strdup (s)) == NULL)
00535     _dbus_wait_for_memory ();
00536 
00537   dbus_connection_ref (connection);
00538   
00539   <font class="comment">/* kick in the disconnect handler that unrefs the connection */</font>
00540   dbus_connection_disconnect (connection);
00541 
00542   bus_test_run_everything (context);
00543   
00544   _dbus_assert (bus_test_client_listed (connection));
00545   
00546   <font class="comment">/* Run disconnect handler in test.c */</font>
00547   <font class="keywordflow">if</font> (bus_connection_dispatch_one_message (connection))
00548     _dbus_assert_not_reached (<font class="stringliteral">"something received on connection being killed other than the disconnect"</font>);
00549   
00550   _dbus_assert (!dbus_connection_get_is_connected (connection));
00551   dbus_connection_unref (connection);
00552   connection = NULL;
00553   _dbus_assert (!bus_test_client_listed (connection));
00554   
00555   csdd.expected_service_name = base_service;
00556   csdd.failed = FALSE;
00557 
00558   bus_test_clients_foreach (check_service_deleted_foreach,
00559                             &amp;csdd);
00560 
00561   dbus_free (base_service);
00562   
00563   <font class="keywordflow">if</font> (csdd.failed)
00564     _dbus_assert_not_reached (<font class="stringliteral">"didn't get the expected ServiceDeleted messages"</font>);
00565   
00566   <font class="keywordflow">if</font> (!check_no_leftovers (context))
00567     _dbus_assert_not_reached (<font class="stringliteral">"stuff left in message queues after disconnecting a client"</font>);
00568 }
00569 
00570 <font class="keyword">static</font> <font class="keywordtype">void</font>
00571 kill_client_connection_unchecked (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
00572 {
00573   <font class="comment">/* This kills the connection without expecting it to affect</font>
00574 <font class="comment">   * the rest of the bus.</font>
00575 <font class="comment">   */</font>  
00576   _dbus_verbose (<font class="stringliteral">"Unchecked kill of connection %p\n"</font>, connection);
00577 
00578   dbus_connection_ref (connection);
00579   dbus_connection_disconnect (connection);
00580   <font class="comment">/* dispatching disconnect handler will unref once */</font>
00581   <font class="keywordflow">if</font> (bus_connection_dispatch_one_message (connection))
00582     _dbus_assert_not_reached (<font class="stringliteral">"message other than disconnect dispatched after failure to register"</font>);
00583 
00584   _dbus_assert (!bus_test_client_listed (connection));
00585   dbus_connection_unref (connection);
00586 }
00587 
00588 <font class="keyword">typedef</font> <font class="keyword">struct</font>
00589 <font class="keyword"></font>{
00590   dbus_bool_t failed;
00591 } CheckNoMessagesData;
00592 
00593 <font class="keyword">static</font> dbus_bool_t
00594 check_no_messages_foreach (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
00595                            <font class="keywordtype">void</font>           *data)
00596 {
00597   CheckNoMessagesData *d = data;
00598   <a class="code" href="structDBusMessage.html">DBusMessage</a> *message;
00599 
00600   message = pop_message_waiting_for_memory (connection);
00601   <font class="keywordflow">if</font> (message != NULL)
00602     {
00603       warn_unexpected (connection, message, <font class="stringliteral">"no messages"</font>);
00604 
00605       d-&gt;failed = TRUE;
00606     }
00607 
00608   <font class="keywordflow">if</font> (message)
00609     dbus_message_unref (message);
00610   <font class="keywordflow">return</font> !d-&gt;failed;
00611 }
00612 
00613 <font class="keyword">typedef</font> <font class="keyword">struct</font>
00614 <font class="keyword"></font>{
00615   <a class="code" href="structDBusConnection.html">DBusConnection</a> *skip_connection;
00616   <font class="keyword">const</font> <font class="keywordtype">char</font> *expected_service_name;
00617   dbus_bool_t failed;
00618 } CheckServiceCreatedData;
00619 
00620 <font class="keyword">static</font> dbus_bool_t
00621 check_service_created_foreach (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
00622                                <font class="keywordtype">void</font>           *data)
00623 {
00624   CheckServiceCreatedData *d = data;
00625   <a class="code" href="structDBusMessage.html">DBusMessage</a> *message;
00626   <a class="code" href="structDBusError.html">DBusError</a> error;
00627   <font class="keywordtype">char</font> *service_name;
00628 
00629   <font class="keywordflow">if</font> (connection == d-&gt;skip_connection)
00630     <font class="keywordflow">return</font> TRUE;
00631 
00632   dbus_error_init (&amp;error);
00633   d-&gt;failed = TRUE;
00634   service_name = NULL;
00635   
00636   message = pop_message_waiting_for_memory (connection);
00637   <font class="keywordflow">if</font> (message == NULL)
00638     {
00639       _dbus_warn (<font class="stringliteral">"Did not receive a message on %p, expecting %s\n"</font>,
00640                   connection, <font class="stringliteral">"ServiceCreated"</font>);
00641       <font class="keywordflow">goto</font> out;
00642     }
00643   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (!dbus_message_is_signal (message,
00644                                     DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
00645                                     <font class="stringliteral">"ServiceCreated"</font>))
00646     {
00647       warn_unexpected (connection, message, <font class="stringliteral">"ServiceCreated"</font>);
00648       <font class="keywordflow">goto</font> out;
00649     }
00650   <font class="keywordflow">else</font>
00651     {
00652       <font class="keywordflow">if</font> (!dbus_message_get_args (message, &amp;error,
00653                                   DBUS_TYPE_STRING, &amp;service_name,
00654                                   DBUS_TYPE_INVALID))
00655         {
00656           <font class="keywordflow">if</font> (dbus_error_has_name (&amp;error, DBUS_ERROR_NO_MEMORY))
00657             {
00658               _dbus_verbose (<font class="stringliteral">"no memory to get service name arg\n"</font>);
00659             }
00660           <font class="keywordflow">else</font>
00661             {
00662               _dbus_assert (dbus_error_is_set (&amp;error));
00663               _dbus_warn (<font class="stringliteral">"Did not get the expected single string argument\n"</font>);
00664               <font class="keywordflow">goto</font> out;
00665             }
00666         }
00667       <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (service_name, d-&gt;expected_service_name) != 0)
00668         {
00669           _dbus_warn (<font class="stringliteral">"expected creation of service %s, got creation of %s\n"</font>,
00670                       d-&gt;expected_service_name,
00671                       service_name);
00672           <font class="keywordflow">goto</font> out;
00673         }
00674     }
00675 
00676   d-&gt;failed = FALSE;
00677   
00678  out:
00679   dbus_free (service_name);
00680   dbus_error_free (&amp;error);
00681   
00682   <font class="keywordflow">if</font> (message)
00683     dbus_message_unref (message);
00684 
00685   <font class="keywordflow">return</font> !d-&gt;failed;
00686 }
00687 
00688 <font class="keyword">static</font> dbus_bool_t
00689 check_no_leftovers (BusContext *context)
00690 {
00691   CheckNoMessagesData nmd;
00692 
00693   nmd.failed = FALSE;
00694   bus_test_clients_foreach (check_no_messages_foreach,
00695                             &amp;nmd);
00696   
00697   <font class="keywordflow">if</font> (nmd.failed)
00698     <font class="keywordflow">return</font> FALSE;
00699   <font class="keywordflow">else</font>
00700     <font class="keywordflow">return</font> TRUE;
00701 }
00702 
00703 <font class="comment">/* returns TRUE if the correct thing happens,</font>
00704 <font class="comment"> * but the correct thing may include OOM errors.</font>
00705 <font class="comment"> */</font>
00706 <font class="keyword">static</font> dbus_bool_t
00707 check_hello_message (BusContext     *context,
00708                      <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
00709 {
00710   <a class="code" href="structDBusMessage.html">DBusMessage</a> *message;
00711   dbus_uint32_t serial;
00712   dbus_bool_t retval;
00713   <a class="code" href="structDBusError.html">DBusError</a> error;
00714   <font class="keywordtype">char</font> *name;
00715   <font class="keywordtype">char</font> *acquired;
00716 
00717   retval = FALSE;
00718   dbus_error_init (&amp;error);
00719   name = NULL;
00720   acquired = NULL;
00721   message = NULL;
00722 
00723   _dbus_verbose (<font class="stringliteral">"check_hello_message for %p\n"</font>, connection);
00724   
00725   message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
00726                                           DBUS_PATH_ORG_FREEDESKTOP_DBUS,
00727                                           DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
00728                                           <font class="stringliteral">"Hello"</font>);
00729 
00730   <font class="keywordflow">if</font> (message == NULL)
00731     <font class="keywordflow">return</font> TRUE;
00732 
00733   <font class="keywordflow">if</font> (!dbus_connection_send (connection, message, &amp;serial))
00734     {
00735       dbus_message_unref (message);
00736       <font class="keywordflow">return</font> TRUE;
00737     }
00738 
00739   dbus_message_unref (message);
00740   message = NULL;
00741 
00742   <font class="comment">/* send our message */</font>
00743   bus_test_run_clients_loop (TRUE);
00744 
00745   dbus_connection_ref (connection); <font class="comment">/* because we may get disconnected */</font>
00746   block_connection_until_message_from_bus (context, connection);
00747 
00748   <font class="keywordflow">if</font> (!dbus_connection_get_is_connected (connection))
00749     {
00750       _dbus_verbose (<font class="stringliteral">"connection was disconnected\n"</font>);
00751       
00752       dbus_connection_unref (connection);
00753       
00754       <font class="keywordflow">return</font> TRUE;
00755     }
00756 
00757   dbus_connection_unref (connection);
00758   
00759   message = pop_message_waiting_for_memory (connection);
00760   <font class="keywordflow">if</font> (message == NULL)
00761     {
00762       _dbus_warn (<font class="stringliteral">"Did not receive a reply to %s %d on %p\n"</font>,
00763                   <font class="stringliteral">"Hello"</font>, serial, connection);
00764       <font class="keywordflow">goto</font> out;
00765     }
00766 
00767   verbose_message_received (connection, message);
00768 
00769   <font class="keywordflow">if</font> (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
00770     {
00771       _dbus_warn (<font class="stringliteral">"Message has wrong sender %s\n"</font>,
00772                   dbus_message_get_sender (message) ?
00773                   dbus_message_get_sender (message) : "(none)");
00774       <font class="keywordflow">goto</font> out;
00775     }
00776   
00777   <font class="keywordflow">if</font> (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
00778     {
00779       <font class="keywordflow">if</font> (dbus_message_is_error (message,
00780                                  DBUS_ERROR_NO_MEMORY))
00781         {
00782           ; <font class="comment">/* good, this is a valid response */</font>
00783         }
00784       <font class="keywordflow">else</font>
00785         {
00786           warn_unexpected (connection, message, <font class="stringliteral">"not this error"</font>);
00787 
00788           <font class="keywordflow">goto</font> out;
00789         }
00790     }
00791   <font class="keywordflow">else</font>
00792     {
00793       CheckServiceCreatedData scd;
00794       
00795       <font class="keywordflow">if</font> (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
00796         {
00797           ; <font class="comment">/* good, expected */</font>
00798         }
00799       <font class="keywordflow">else</font>
00800         {
00801           warn_unexpected (connection, message, <font class="stringliteral">"method return for Hello"</font>);
00802 
00803           <font class="keywordflow">goto</font> out;
00804         }
00805 
00806     retry_get_hello_name:
00807       <font class="keywordflow">if</font> (!dbus_message_get_args (message, &amp;error,
00808                                   DBUS_TYPE_STRING, &amp;name,
00809                                   DBUS_TYPE_INVALID))
00810         {
00811           <font class="keywordflow">if</font> (dbus_error_has_name (&amp;error, DBUS_ERROR_NO_MEMORY))
00812             {
00813               _dbus_verbose (<font class="stringliteral">"no memory to get service name arg from hello\n"</font>);
00814               dbus_error_free (&amp;error);
00815               _dbus_wait_for_memory ();
00816               <font class="keywordflow">goto</font> retry_get_hello_name;
00817             }
00818           <font class="keywordflow">else</font>
00819             {
00820               _dbus_assert (dbus_error_is_set (&amp;error));
00821               _dbus_warn (<font class="stringliteral">"Did not get the expected single string argument to hello\n"</font>);
00822               <font class="keywordflow">goto</font> out;
00823             }
00824         }
00825 
00826       _dbus_verbose (<font class="stringliteral">"Got hello name: %s\n"</font>, name);
00827 
00828       <font class="keywordflow">while</font> (!dbus_bus_set_base_service (connection, name))
00829         _dbus_wait_for_memory ();
00830       
00831       scd.skip_connection = connection; <font class="comment">/* we haven't done AddMatch so won't get it ourselves */</font>
00832       scd.failed = FALSE;
00833       scd.expected_service_name = name;
00834       bus_test_clients_foreach (check_service_created_foreach,
00835                                 &amp;scd);
00836       
00837       <font class="keywordflow">if</font> (scd.failed)
00838         <font class="keywordflow">goto</font> out;
00839       
00840       <font class="comment">/* Client should also have gotten ServiceAcquired */</font>
00841       dbus_message_unref (message);
00842       message = pop_message_waiting_for_memory (connection);
00843       <font class="keywordflow">if</font> (message == NULL)
00844         {
00845           _dbus_warn (<font class="stringliteral">"Expecting %s, got nothing\n"</font>,
00846                       <font class="stringliteral">"ServiceAcquired"</font>);
00847           <font class="keywordflow">goto</font> out;
00848         }
00849       
00850     retry_get_acquired_name:
00851       <font class="keywordflow">if</font> (!dbus_message_get_args (message, &amp;error,
00852                                   DBUS_TYPE_STRING, &amp;acquired,
00853                                   DBUS_TYPE_INVALID))
00854         {
00855           <font class="keywordflow">if</font> (dbus_error_has_name (&amp;error, DBUS_ERROR_NO_MEMORY))
00856             {
00857               _dbus_verbose (<font class="stringliteral">"no memory to get service name arg from acquired\n"</font>);
00858               dbus_error_free (&amp;error);
00859               _dbus_wait_for_memory ();
00860               <font class="keywordflow">goto</font> retry_get_acquired_name;
00861             }
00862           <font class="keywordflow">else</font>
00863             {
00864               _dbus_assert (dbus_error_is_set (&amp;error));
00865               _dbus_warn (<font class="stringliteral">"Did not get the expected single string argument to ServiceAcquired\n"</font>);
00866               <font class="keywordflow">goto</font> out;
00867             }
00868         }
00869 
00870       _dbus_verbose (<font class="stringliteral">"Got acquired name: %s\n"</font>, acquired);
00871 
00872       <font class="keywordflow">if</font> (strcmp (acquired, name) != 0)
00873         {
00874           _dbus_warn (<font class="stringliteral">"Acquired name is %s but expected %s\n"</font>,
00875                       acquired, name);
00876           <font class="keywordflow">goto</font> out;
00877         }
00878     }
00879 
00880   <font class="keywordflow">if</font> (!check_no_leftovers (context))
00881     <font class="keywordflow">goto</font> out;
00882   
00883   retval = TRUE;
00884   
00885  out:
00886   dbus_error_free (&amp;error);
00887   
00888   dbus_free (name);
00889   dbus_free (acquired);
00890   
00891   <font class="keywordflow">if</font> (message)
00892     dbus_message_unref (message);
00893   
00894   <font class="keywordflow">return</font> retval;
00895 }
00896 
00897 <font class="comment">/* returns TRUE if the correct thing happens,</font>
00898 <font class="comment"> * but the correct thing may include OOM errors.</font>
00899 <font class="comment"> */</font>
00900 <font class="keyword">static</font> dbus_bool_t
00901 check_add_match_all (BusContext     *context,
00902                      <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
00903 {
00904   <a class="code" href="structDBusMessage.html">DBusMessage</a> *message;
00905   dbus_bool_t retval;
00906   dbus_uint32_t serial;
00907   <a class="code" href="structDBusError.html">DBusError</a> error;
00908 
00909   retval = FALSE;
00910   dbus_error_init (&amp;error);
00911   message = NULL;
00912 
00913   _dbus_verbose (<font class="stringliteral">"check_add_match_all for %p\n"</font>, connection);
00914   
00915   message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
00916                                           DBUS_PATH_ORG_FREEDESKTOP_DBUS,
00917                                           DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
00918                                           <font class="stringliteral">"AddMatch"</font>);
00919 
00920   <font class="keywordflow">if</font> (message == NULL)
00921     <font class="keywordflow">return</font> TRUE;
00922 
00923   <font class="keywordflow">if</font> (!dbus_message_append_args (message, DBUS_TYPE_STRING, <font class="stringliteral">""</font>, <font class="comment">/* FIXME */</font>
00924                                  DBUS_TYPE_INVALID))
00925     {
00926       dbus_message_unref (message);
00927       <font class="keywordflow">return</font> TRUE;
00928     }
00929   
00930   <font class="keywordflow">if</font> (!dbus_connection_send (connection, message, &amp;serial))
00931     {
00932       dbus_message_unref (message);
00933       <font class="keywordflow">return</font> TRUE;
00934     }
00935 
00936   dbus_message_unref (message);
00937   message = NULL;
00938 
00939   <font class="comment">/* send our message */</font>
00940   bus_test_run_clients_loop (TRUE);
00941 
00942   dbus_connection_ref (connection); <font class="comment">/* because we may get disconnected */</font>
00943   block_connection_until_message_from_bus (context, connection);
00944 
00945   <font class="keywordflow">if</font> (!dbus_connection_get_is_connected (connection))
00946     {
00947       _dbus_verbose (<font class="stringliteral">"connection was disconnected\n"</font>);
00948       
00949       dbus_connection_unref (connection);
00950       
00951       <font class="keywordflow">return</font> TRUE;
00952     }
00953 
00954   dbus_connection_unref (connection);
00955   
00956   message = pop_message_waiting_for_memory (connection);
00957   <font class="keywordflow">if</font> (message == NULL)
00958     {
00959       _dbus_warn (<font class="stringliteral">"Did not receive a reply to %s %d on %p\n"</font>,
00960                   <font class="stringliteral">"AddMatch"</font>, serial, connection);
00961       <font class="keywordflow">goto</font> out;
00962     }
00963 
00964   verbose_message_received (connection, message);
00965 
00966   <font class="keywordflow">if</font> (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
00967     {
00968       _dbus_warn (<font class="stringliteral">"Message has wrong sender %s\n"</font>,
00969                   dbus_message_get_sender (message) ?
00970                   dbus_message_get_sender (message) : "(none)");
00971       <font class="keywordflow">goto</font> out;
00972     }
00973   
00974   <font class="keywordflow">if</font> (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
00975     {
00976       <font class="keywordflow">if</font> (dbus_message_is_error (message,
00977                                  DBUS_ERROR_NO_MEMORY))
00978         {
00979           ; <font class="comment">/* good, this is a valid response */</font>
00980         }
00981       <font class="keywordflow">else</font>
00982         {
00983           warn_unexpected (connection, message, <font class="stringliteral">"not this error"</font>);
00984 
00985           <font class="keywordflow">goto</font> out;
00986         }
00987     }
00988   <font class="keywordflow">else</font>
00989     {
00990       <font class="keywordflow">if</font> (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
00991         {
00992           ; <font class="comment">/* good, expected */</font>
00993           _dbus_assert (dbus_message_get_reply_serial (message) == serial);
00994         }
00995       <font class="keywordflow">else</font>
00996         {
00997           warn_unexpected (connection, message, <font class="stringliteral">"method return for AddMatch"</font>);
00998 
00999           <font class="keywordflow">goto</font> out;
01000         }
01001     }
01002 
01003   <font class="keywordflow">if</font> (!check_no_leftovers (context))
01004     <font class="keywordflow">goto</font> out;
01005   
01006   retval = TRUE;
01007   
01008  out:
01009   dbus_error_free (&amp;error);
01010   
01011   <font class="keywordflow">if</font> (message)
01012     dbus_message_unref (message);
01013   
01014   <font class="keywordflow">return</font> retval;
01015 }
01016 
01017 <font class="comment">/* returns TRUE if the correct thing happens,</font>
01018 <font class="comment"> * but the correct thing may include OOM errors.</font>
01019 <font class="comment"> */</font>
01020 <font class="keyword">static</font> dbus_bool_t
01021 check_hello_connection (BusContext *context)
01022 {
01023   <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection;
01024   <a class="code" href="structDBusError.html">DBusError</a> error;
01025 
01026   dbus_error_init (&amp;error);
01027 
01028   connection = dbus_connection_open (<font class="stringliteral">"debug-pipe:name=test-server"</font>, &amp;error);
01029   <font class="keywordflow">if</font> (connection == NULL)
01030     {
01031       _DBUS_ASSERT_ERROR_IS_SET (&amp;error);
01032       dbus_error_free (&amp;error);
01033       <font class="keywordflow">return</font> TRUE;
01034     }
01035 
01036   <font class="keywordflow">if</font> (!bus_setup_debug_client (connection))
01037     {
01038       dbus_connection_disconnect (connection);
01039       dbus_connection_unref (connection);
01040       <font class="keywordflow">return</font> TRUE;
01041     }
01042 
01043   <font class="keywordflow">if</font> (!check_hello_message (context, connection))
01044     <font class="keywordflow">return</font> FALSE;
01045   
01046   <font class="keywordflow">if</font> (dbus_bus_get_base_service (connection) == NULL)
01047     {
01048       <font class="comment">/* We didn't successfully register, so we can't</font>
01049 <font class="comment">       * do the usual kill_client_connection() checks</font>
01050 <font class="comment">       */</font>
01051       kill_client_connection_unchecked (connection);
01052     }
01053   <font class="keywordflow">else</font>
01054     {
01055       <font class="keywordflow">if</font> (!check_add_match_all (context, connection))
01056         <font class="keywordflow">return</font> FALSE;
01057       
01058       kill_client_connection (context, connection);
01059     }
01060 
01061   <font class="keywordflow">return</font> TRUE;
01062 }
01063 
01064 <font class="preprocessor">#define NONEXISTENT_SERVICE_NAME "test.this.service.does.not.exist.ewuoiurjdfxcvn"</font>
01065 <font class="preprocessor"></font>
01066 <font class="comment">/* returns TRUE if the correct thing happens,</font>
01067 <font class="comment"> * but the correct thing may include OOM errors.</font>
01068 <font class="comment"> */</font>
01069 <font class="keyword">static</font> dbus_bool_t
01070 check_nonexistent_service_activation (BusContext     *context,
01071                                       <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
01072 {
01073   <a class="code" href="structDBusMessage.html">DBusMessage</a> *message;
01074   dbus_uint32_t serial;
01075   dbus_bool_t retval;
01076   <a class="code" href="structDBusError.html">DBusError</a> error;
01077   
01078   dbus_error_init (&amp;error);
01079   
01080   message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
01081                                           DBUS_PATH_ORG_FREEDESKTOP_DBUS,
01082                                           DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
01083                                           <font class="stringliteral">"ActivateService"</font>);
01084 
01085   <font class="keywordflow">if</font> (message == NULL)
01086     <font class="keywordflow">return</font> TRUE;
01087 
01088   <font class="keywordflow">if</font> (!dbus_message_append_args (message,
01089                                  DBUS_TYPE_STRING, NONEXISTENT_SERVICE_NAME,
01090                                  DBUS_TYPE_UINT32, 0,
01091                                  DBUS_TYPE_INVALID))
01092     {
01093       dbus_message_unref (message);
01094       <font class="keywordflow">return</font> TRUE;
01095     }
01096   
01097   <font class="keywordflow">if</font> (!dbus_connection_send (connection, message, &amp;serial))
01098     {
01099       dbus_message_unref (message);
01100       <font class="keywordflow">return</font> TRUE;
01101     }
01102 
01103   dbus_message_unref (message);
01104   message = NULL;
01105 
01106   bus_test_run_everything (context);
01107   block_connection_until_message_from_bus (context, connection);
01108   bus_test_run_everything (context);
01109 
01110   <font class="keywordflow">if</font> (!dbus_connection_get_is_connected (connection))
01111     {
01112       _dbus_verbose (<font class="stringliteral">"connection was disconnected\n"</font>);
01113       <font class="keywordflow">return</font> TRUE;
01114     }
01115   
01116   retval = FALSE;
01117   
01118   message = pop_message_waiting_for_memory (connection);
01119   <font class="keywordflow">if</font> (message == NULL)
01120     {
01121       _dbus_warn (<font class="stringliteral">"Did not receive a reply to %s %d on %p\n"</font>,
01122                   <font class="stringliteral">"ActivateService"</font>, serial, connection);
01123       <font class="keywordflow">goto</font> out;
01124     }
01125 
01126   verbose_message_received (connection, message);
01127 
01128   <font class="keywordflow">if</font> (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
01129     {
01130       <font class="keywordflow">if</font> (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
01131         {
01132           _dbus_warn (<font class="stringliteral">"Message has wrong sender %s\n"</font>,
01133                       dbus_message_get_sender (message) ?
01134                       dbus_message_get_sender (message) : "(none)");
01135           <font class="keywordflow">goto</font> out;
01136         }
01137       
01138       <font class="keywordflow">if</font> (dbus_message_is_error (message,
01139                                  DBUS_ERROR_NO_MEMORY))
01140         {
01141           ; <font class="comment">/* good, this is a valid response */</font>
01142         }
01143       <font class="keywordflow">else</font> <font class="keywordflow">if</font> (dbus_message_is_error (message,
01144                                       DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND))
01145         {
01146           ; <font class="comment">/* good, this is expected also */</font>
01147         }
01148       <font class="keywordflow">else</font>
01149         {
01150           warn_unexpected (connection, message, <font class="stringliteral">"not this error"</font>);
01151           <font class="keywordflow">goto</font> out;
01152         }
01153     }
01154   <font class="keywordflow">else</font>
01155     {
01156       _dbus_warn (<font class="stringliteral">"Did not expect to successfully activate %s\n"</font>,
01157                   NONEXISTENT_SERVICE_NAME);
01158       <font class="keywordflow">goto</font> out;
01159     }
01160 
01161   retval = TRUE;
01162   
01163  out:
01164   <font class="keywordflow">if</font> (message)
01165     dbus_message_unref (message);
01166   
01167   <font class="keywordflow">return</font> retval;
01168 }
01169 
01170 <font class="keyword">static</font> dbus_bool_t
01171 check_base_service_activated (BusContext     *context,
01172                               <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
01173                               <a class="code" href="structDBusMessage.html">DBusMessage</a>    *initial_message,
01174                               <font class="keywordtype">char</font>          **base_service_p)
01175 {
01176   <a class="code" href="structDBusMessage.html">DBusMessage</a> *message;
01177   dbus_bool_t retval;
01178   <a class="code" href="structDBusError.html">DBusError</a> error;
01179   <font class="keywordtype">char</font> *base_service;
01180   
01181   base_service = NULL;
01182   retval = FALSE;
01183   
01184   dbus_error_init (&amp;error);
01185 
01186   message = initial_message;
01187   dbus_message_ref (message);  
01188 
01189   <font class="keywordflow">if</font> (dbus_message_is_signal (message,
01190                               DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
01191                               <font class="stringliteral">"ServiceCreated"</font>))
01192     {
01193       <font class="keywordtype">char</font> *service_name;
01194       CheckServiceCreatedData scd;
01195 
01196     reget_service_name_arg:
01197       <font class="keywordflow">if</font> (!dbus_message_get_args (message, &amp;error,
01198                                   DBUS_TYPE_STRING, &amp;service_name,
01199                                   DBUS_TYPE_INVALID))
01200         {
01201           <font class="keywordflow">if</font> (dbus_error_has_name (&amp;error, DBUS_ERROR_NO_MEMORY))
01202             {
01203               dbus_error_free (&amp;error);
01204               _dbus_wait_for_memory ();
01205               <font class="keywordflow">goto</font> reget_service_name_arg;
01206             }
01207           <font class="keywordflow">else</font>
01208             {
01209               _dbus_warn (<font class="stringliteral">"Message %s doesn't have a service name: %s\n"</font>,
01210                           <font class="stringliteral">"ServiceCreated"</font>,
01211                           error.<a class="code" href="structDBusError.html#m1">message</a>);
01212               dbus_error_free (&amp;error);
01213               <font class="keywordflow">goto</font> out;
01214             }
01215         }
01216 
01217       <font class="keywordflow">if</font> (*service_name != <font class="charliteral">':'</font>)
01218         {
01219           _dbus_warn (<font class="stringliteral">"Expected base service activation, got \"%s\" instead\n"</font>,
01220                       service_name);
01221           <font class="keywordflow">goto</font> out;
01222         }
01223               
01224       base_service = service_name;
01225       service_name = NULL;
01226       
01227       scd.skip_connection = connection;
01228       scd.failed = FALSE;
01229       scd.expected_service_name = base_service;
01230       bus_test_clients_foreach (check_service_created_foreach,
01231                                 &amp;scd);
01232       
01233       <font class="keywordflow">if</font> (scd.failed)
01234         <font class="keywordflow">goto</font> out;
01235     }
01236   <font class="keywordflow">else</font>
01237     {
01238       warn_unexpected (connection, message, <font class="stringliteral">"ServiceCreated for base service"</font>);
01239 
01240       <font class="keywordflow">goto</font> out;
01241     }
01242 
01243   retval = TRUE;
01244 
01245   <font class="keywordflow">if</font> (base_service_p)
01246     {
01247       *base_service_p = base_service;
01248       base_service = NULL;
01249     }
01250   
01251  out:
01252   <font class="keywordflow">if</font> (message)
01253     dbus_message_unref (message);
01254 
01255   <font class="keywordflow">if</font> (base_service)
01256     dbus_free (base_service);
01257   
01258   <font class="keywordflow">return</font> retval;
01259 }
01260 
01261 <font class="keyword">static</font> dbus_bool_t
01262 check_service_activated (BusContext     *context,
01263                          <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
01264                          <font class="keyword">const</font> <font class="keywordtype">char</font>     *activated_name,
01265                          <font class="keyword">const</font> <font class="keywordtype">char</font>     *base_service_name,
01266                          <a class="code" href="structDBusMessage.html">DBusMessage</a>    *initial_message)
01267 {
01268   <a class="code" href="structDBusMessage.html">DBusMessage</a> *message;
01269   dbus_bool_t retval;
01270   <a class="code" href="structDBusError.html">DBusError</a> error;
01271   dbus_uint32_t activation_result;
01272   
01273   retval = FALSE;
01274   
01275   dbus_error_init (&amp;error);
01276 
01277   message = initial_message;
01278   dbus_message_ref (message);
01279 
01280   <font class="keywordflow">if</font> (dbus_message_is_signal (message,
01281                               DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
01282                               <font class="stringliteral">"ServiceCreated"</font>))
01283     {
01284       <font class="keywordtype">char</font> *service_name;
01285       CheckServiceCreatedData scd;
01286 
01287     reget_service_name_arg:
01288       <font class="keywordflow">if</font> (!dbus_message_get_args (message, &amp;error,
01289                                   DBUS_TYPE_STRING, &amp;service_name,
01290                                   DBUS_TYPE_INVALID))
01291         {
01292           <font class="keywordflow">if</font> (dbus_error_has_name (&amp;error, DBUS_ERROR_NO_MEMORY))
01293             {
01294               dbus_error_free (&amp;error);
01295               _dbus_wait_for_memory ();
01296               <font class="keywordflow">goto</font> reget_service_name_arg;
01297             }
01298           <font class="keywordflow">else</font>
01299             {
01300               _dbus_warn (<font class="stringliteral">"Message %s doesn't have a service name: %s\n"</font>,
01301                           <font class="stringliteral">"ServiceCreated"</font>,
01302                           error.<a class="code" href="structDBusError.html#m1">message</a>);
01303               dbus_error_free (&amp;error);
01304               <font class="keywordflow">goto</font> out;
01305             }
01306         }
01307 
01308       <font class="keywordflow">if</font> (strcmp (service_name, activated_name) != 0)
01309         {
01310           _dbus_warn (<font class="stringliteral">"Expected to see service %s created, saw %s instead\n"</font>,
01311                       activated_name, service_name);
01312           dbus_free (service_name);
01313           <font class="keywordflow">goto</font> out;
01314         }
01315       
01316       scd.skip_connection = connection;
01317       scd.failed = FALSE;
01318       scd.expected_service_name = service_name;
01319       bus_test_clients_foreach (check_service_created_foreach,
01320                                 &amp;scd);
01321           
01322       dbus_free (service_name);
01323 
01324       <font class="keywordflow">if</font> (scd.failed)
01325         <font class="keywordflow">goto</font> out;
01326           
01327       dbus_message_unref (message);
01328       message = pop_message_waiting_for_memory (connection);
01329       <font class="keywordflow">if</font> (message == NULL)
01330         {
01331           _dbus_warn (<font class="stringliteral">"Expected a reply to %s, got nothing\n"</font>,
01332                       <font class="stringliteral">"ActivateService"</font>);
01333           <font class="keywordflow">goto</font> out;
01334         }
01335     }
01336   <font class="keywordflow">else</font>
01337     {
01338       warn_unexpected (connection, message, <font class="stringliteral">"ServiceCreated for the activated name"</font>);
01339       
01340       <font class="keywordflow">goto</font> out;
01341     }
01342   
01343   <font class="keywordflow">if</font> (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN)
01344     {
01345       warn_unexpected (connection, message, <font class="stringliteral">"reply to ActivateService"</font>);
01346 
01347       <font class="keywordflow">goto</font> out;
01348     }
01349 
01350   activation_result = 0;
01351   <font class="keywordflow">if</font> (!dbus_message_get_args (message, &amp;error,
01352                               DBUS_TYPE_UINT32, &amp;activation_result,
01353                               DBUS_TYPE_INVALID))
01354     {
01355       <font class="keywordflow">if</font> (!dbus_error_has_name (&amp;error, DBUS_ERROR_NO_MEMORY))
01356         {
01357           _dbus_warn (<font class="stringliteral">"Did not have activation result first argument to %s: %s\n"</font>,
01358                       <font class="stringliteral">"ActivateService"</font>, error.<a class="code" href="structDBusError.html#m1">message</a>);
01359           dbus_error_free (&amp;error);
01360           <font class="keywordflow">goto</font> out;
01361         }
01362 
01363       dbus_error_free (&amp;error);
01364     }
01365   <font class="keywordflow">else</font>
01366     {
01367       <font class="keywordflow">if</font> (activation_result == DBUS_ACTIVATION_REPLY_ACTIVATED)
01368         ; <font class="comment">/* Good */</font>
01369       <font class="keywordflow">else</font> <font class="keywordflow">if</font> (activation_result == DBUS_ACTIVATION_REPLY_ALREADY_ACTIVE)
01370         ; <font class="comment">/* Good also */</font>
01371       <font class="keywordflow">else</font>
01372         {
01373           _dbus_warn (<font class="stringliteral">"Activation result was 0x%x, no good.\n"</font>,
01374                       activation_result);
01375           <font class="keywordflow">goto</font> out;
01376         }
01377     }
01378 
01379   dbus_message_unref (message);
01380   message = NULL;
01381       
01382   <font class="keywordflow">if</font> (!check_no_leftovers (context))
01383     {
01384       _dbus_warn (<font class="stringliteral">"Messages were left over after verifying existent activation results\n"</font>);
01385       <font class="keywordflow">goto</font> out;
01386     }
01387 
01388   retval = TRUE;
01389   
01390  out:
01391   <font class="keywordflow">if</font> (message)
01392     dbus_message_unref (message);
01393   
01394   <font class="keywordflow">return</font> retval;
01395 }
01396 
01397 <font class="keyword">static</font> dbus_bool_t
01398 check_service_deactivated (BusContext     *context,
01399                            <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
01400                            <font class="keyword">const</font> <font class="keywordtype">char</font>     *activated_name,
01401                            <font class="keyword">const</font> <font class="keywordtype">char</font>     *base_service)
01402 {
01403   <a class="code" href="structDBusMessage.html">DBusMessage</a> *message;
01404   dbus_bool_t retval;
01405   <a class="code" href="structDBusError.html">DBusError</a> error;
01406   CheckServiceDeletedData csdd;
01407 
01408   message = NULL;
01409   retval = FALSE;
01410   
01411   dbus_error_init (&amp;error);
01412 
01413   <font class="comment">/* Now we are expecting ServiceDeleted messages for the base</font>
01414 <font class="comment">   * service and the activated_name.  The base service</font>
01415 <font class="comment">   * notification is required to come last.</font>
01416 <font class="comment">   */</font>
01417   csdd.expected_service_name = activated_name;
01418   csdd.failed = FALSE;
01419   bus_test_clients_foreach (check_service_deleted_foreach,
01420                             &amp;csdd);      
01421 
01422   <font class="keywordflow">if</font> (csdd.failed)
01423     <font class="keywordflow">goto</font> out;
01424       
01425   csdd.expected_service_name = base_service;
01426   csdd.failed = FALSE;
01427   bus_test_clients_foreach (check_service_deleted_foreach,
01428                             &amp;csdd);
01429 
01430   <font class="keywordflow">if</font> (csdd.failed)
01431     <font class="keywordflow">goto</font> out;
01432       
01433   <font class="keywordflow">if</font> (!check_no_leftovers (context))
01434     {
01435       _dbus_warn (<font class="stringliteral">"Messages were left over after verifying results of service exiting\n"</font>);
01436       <font class="keywordflow">goto</font> out;
01437     }
01438 
01439   retval = TRUE;
01440   
01441  out:
01442   <font class="keywordflow">if</font> (message)
01443     dbus_message_unref (message);
01444   
01445   <font class="keywordflow">return</font> retval;
01446 }
01447 
01448 <font class="keyword">static</font> dbus_bool_t
01449 check_send_exit_to_service (BusContext     *context,
01450                             <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
01451                             <font class="keyword">const</font> <font class="keywordtype">char</font>     *service_name,
01452                             <font class="keyword">const</font> <font class="keywordtype">char</font>     *base_service)
01453 {
01454   dbus_bool_t got_error;
01455   <a class="code" href="structDBusMessage.html">DBusMessage</a> *message;
01456   dbus_uint32_t serial;
01457   dbus_bool_t retval;
01458   
01459   _dbus_verbose (<font class="stringliteral">"Sending exit message to the test service\n"</font>);
01460 
01461   retval = FALSE;
01462   
01463   <font class="comment">/* Kill off the test service by sending it a quit message */</font>
01464   message = dbus_message_new_method_call (service_name,
01465                                           <font class="stringliteral">"/org/freedesktop/TestSuite"</font>,
01466                                           <font class="stringliteral">"org.freedesktop.TestSuite"</font>,
01467                                           <font class="stringliteral">"Exit"</font>);
01468       
01469   <font class="keywordflow">if</font> (message == NULL)
01470     {
01471       <font class="comment">/* Do this again; we still need the service to exit... */</font>
01472       <font class="keywordflow">if</font> (!check_send_exit_to_service (context, connection,
01473                                        service_name, base_service))
01474         <font class="keywordflow">goto</font> out;
01475       
01476       <font class="keywordflow">return</font> TRUE;
01477     }
01478       
01479   <font class="keywordflow">if</font> (!dbus_connection_send (connection, message, &amp;serial))
01480     {
01481       dbus_message_unref (message);
01482 
01483       <font class="comment">/* Do this again; we still need the service to exit... */</font>
01484       <font class="keywordflow">if</font> (!check_send_exit_to_service (context, connection,
01485                                        service_name, base_service))
01486         <font class="keywordflow">goto</font> out;
01487       
01488       <font class="keywordflow">return</font> TRUE;
01489     }
01490 
01491   dbus_message_unref (message);
01492   message = NULL;
01493 
01494   <font class="comment">/* send message */</font>
01495   bus_test_run_clients_loop (TRUE);
01496 
01497   <font class="comment">/* read it in and write it out to test service */</font>
01498   bus_test_run_bus_loop (context, FALSE);
01499 
01500   <font class="comment">/* see if we got an error during message bus dispatching */</font>
01501   bus_test_run_clients_loop (FALSE);
01502   message = dbus_connection_borrow_message (connection);
01503   got_error = message != NULL &amp;&amp; dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR;
01504   <font class="keywordflow">if</font> (message)
01505     {
01506       dbus_connection_return_message (connection, message);
01507       message = NULL;
01508     }
01509           
01510   <font class="keywordflow">if</font> (!got_error)
01511     {
01512       <font class="comment">/* If no error, wait for the test service to exit */</font>
01513       block_connection_until_message_from_bus (context, connection);
01514               
01515       bus_test_run_everything (context);
01516     }
01517 
01518   <font class="keywordflow">if</font> (got_error)
01519     {
01520       message = pop_message_waiting_for_memory (connection);
01521       _dbus_assert (message != NULL);
01522 
01523       <font class="keywordflow">if</font> (!dbus_message_is_error (message,
01524                                   DBUS_ERROR_NO_MEMORY))
01525         {
01526           warn_unexpected (connection, message,
01527                            <font class="stringliteral">"a no memory error from asking test service to exit"</font>);
01528           <font class="keywordflow">goto</font> out;
01529         }
01530 
01531       _dbus_verbose (<font class="stringliteral">"Got error %s when asking test service to exit\n"</font>,
01532                      dbus_message_get_error_name (message));
01533 
01534       <font class="comment">/* Do this again; we still need the service to exit... */</font>
01535       <font class="keywordflow">if</font> (!check_send_exit_to_service (context, connection,
01536                                        service_name, base_service))
01537         <font class="keywordflow">goto</font> out;
01538     }
01539   <font class="keywordflow">else</font>
01540     {
01541       <font class="keywordflow">if</font> (!check_service_deactivated (context, connection,
01542                                       service_name, base_service))
01543         <font class="keywordflow">goto</font> out;
01544     }
01545 
01546   retval = TRUE;
01547   
01548  out:
01549   <font class="keywordflow">if</font> (message)
01550     dbus_message_unref (message);
01551   
01552   <font class="keywordflow">return</font> retval;
01553 }
01554 
01555 <font class="keyword">static</font> dbus_bool_t
01556 check_got_error (BusContext     *context,
01557                  <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
01558                  <font class="keyword">const</font> <font class="keywordtype">char</font>     *first_error_name,
01559                  ...)
01560 {
01561   <a class="code" href="structDBusMessage.html">DBusMessage</a> *message;
01562   dbus_bool_t retval;
01563   va_list ap;
01564   dbus_bool_t error_found;
01565   <font class="keyword">const</font> <font class="keywordtype">char</font> *error_name;
01566   
01567   retval = FALSE;
01568   
01569   message = pop_message_waiting_for_memory (connection);
01570   <font class="keywordflow">if</font> (message == NULL)
01571     {
01572       _dbus_warn (<font class="stringliteral">"Did not get an expected error\n"</font>);
01573       <font class="keywordflow">goto</font> out;
01574     }
01575 
01576   <font class="keywordflow">if</font> (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
01577     {
01578       warn_unexpected (connection, message, <font class="stringliteral">"an error"</font>);
01579 
01580       <font class="keywordflow">goto</font> out;
01581     }
01582 
01583   error_found = FALSE;
01584 
01585   va_start (ap, first_error_name);
01586   error_name = first_error_name;
01587   <font class="keywordflow">while</font> (error_name != NULL)
01588     {
01589       <font class="keywordflow">if</font> (dbus_message_is_error (message, error_name))
01590         {
01591           error_found = TRUE;
01592           <font class="keywordflow">break</font>;
01593         }
01594       error_name = va_arg (ap, <font class="keywordtype">char</font>*);
01595     }
01596   va_end (ap);
01597 
01598   <font class="keywordflow">if</font> (!error_found)
01599     {
01600       _dbus_warn (<font class="stringliteral">"Expected error %s or other, got %s instead\n"</font>,
01601                   first_error_name,
01602                   dbus_message_get_error_name (message));
01603       <font class="keywordflow">goto</font> out;
01604     }
01605 
01606   retval = TRUE;
01607   
01608  out:
01609   <font class="keywordflow">if</font> (message)
01610     dbus_message_unref (message);
01611   
01612   <font class="keywordflow">return</font> retval;
01613 }
01614           
01615 <font class="preprocessor">#define EXISTENT_SERVICE_NAME "org.freedesktop.DBus.TestSuiteEchoService"</font>
01616 <font class="preprocessor"></font>
01617 <font class="comment">/* returns TRUE if the correct thing happens,</font>
01618 <font class="comment"> * but the correct thing may include OOM errors.</font>
01619 <font class="comment"> */</font>
01620 <font class="keyword">static</font> dbus_bool_t
01621 check_existent_service_activation (BusContext     *context,
01622                                    <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
01623 {
01624   <a class="code" href="structDBusMessage.html">DBusMessage</a> *message;
01625   dbus_uint32_t serial;
01626   dbus_bool_t retval;
01627   <a class="code" href="structDBusError.html">DBusError</a> error;
01628   <font class="keywordtype">char</font> *base_service;
01629 
01630   base_service = NULL;
01631   
01632   dbus_error_init (&amp;error);
01633   
01634   message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
01635                                           DBUS_PATH_ORG_FREEDESKTOP_DBUS,
01636                                           DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
01637                                           <font class="stringliteral">"ActivateService"</font>);
01638 
01639   <font class="keywordflow">if</font> (message == NULL)
01640     <font class="keywordflow">return</font> TRUE;
01641 
01642   <font class="keywordflow">if</font> (!dbus_message_append_args (message,
01643                                  DBUS_TYPE_STRING, EXISTENT_SERVICE_NAME,
01644                                  DBUS_TYPE_UINT32, 0,
01645                                  DBUS_TYPE_INVALID))
01646     {
01647       dbus_message_unref (message);
01648       <font class="keywordflow">return</font> TRUE;
01649     }
01650   
01651   <font class="keywordflow">if</font> (!dbus_connection_send (connection, message, &amp;serial))
01652     {
01653       dbus_message_unref (message);
01654       <font class="keywordflow">return</font> TRUE;
01655     }
01656 
01657   dbus_message_unref (message);
01658   message = NULL;
01659 
01660   bus_test_run_everything (context);
01661 
01662   <font class="comment">/* now wait for the message bus to hear back from the activated</font>
01663 <font class="comment">   * service.</font>
01664 <font class="comment">   */</font>
01665   block_connection_until_message_from_bus (context, connection);
01666 
01667   bus_test_run_everything (context);
01668 
01669   <font class="keywordflow">if</font> (!dbus_connection_get_is_connected (connection))
01670     {
01671       _dbus_verbose (<font class="stringliteral">"connection was disconnected\n"</font>);
01672       <font class="keywordflow">return</font> TRUE;
01673     }
01674   
01675   retval = FALSE;
01676   
01677   message = pop_message_waiting_for_memory (connection);
01678   <font class="keywordflow">if</font> (message == NULL)
01679     {
01680       _dbus_warn (<font class="stringliteral">"Did not receive any messages after %s %d on %p\n"</font>,
01681                   <font class="stringliteral">"ActivateService"</font>, serial, connection);
01682       <font class="keywordflow">goto</font> out;
01683     }
01684 
01685   verbose_message_received (connection, message);
01686   _dbus_verbose (<font class="stringliteral">"  (after sending %s)\n"</font>, <font class="stringliteral">"ActivateService"</font>);
01687 
01688   <font class="keywordflow">if</font> (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
01689     {
01690       <font class="keywordflow">if</font> (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
01691         {
01692           _dbus_warn (<font class="stringliteral">"Message has wrong sender %s\n"</font>,
01693                       dbus_message_get_sender (message) ?
01694                       dbus_message_get_sender (message) : "(none)");
01695           <font class="keywordflow">goto</font> out;
01696         }
01697       
01698       <font class="keywordflow">if</font> (dbus_message_is_error (message,
01699                                  DBUS_ERROR_NO_MEMORY))
01700         {
01701           ; <font class="comment">/* good, this is a valid response */</font>
01702         }
01703       <font class="keywordflow">else</font> <font class="keywordflow">if</font> (dbus_message_is_error (message,
01704                                       DBUS_ERROR_SPAWN_CHILD_EXITED))
01705         {
01706           ; <font class="comment">/* good, this is expected also */</font>
01707         }
01708       <font class="keywordflow">else</font>
01709         {
01710           _dbus_warn (<font class="stringliteral">"Did not expect error %s\n"</font>,
01711                       dbus_message_get_error_name (message));
01712           <font class="keywordflow">goto</font> out;
01713         }
01714     }
01715   <font class="keywordflow">else</font>
01716     {
01717       dbus_bool_t got_service_deleted;
01718       dbus_bool_t got_error;
01719       
01720       <font class="keywordflow">if</font> (!check_base_service_activated (context, connection,
01721                                          message, &amp;base_service))
01722         <font class="keywordflow">goto</font> out;
01723 
01724       dbus_message_unref (message);
01725       message = NULL;
01726 
01727       <font class="comment">/* We may need to block here for the test service to exit or finish up */</font>
01728       block_connection_until_message_from_bus (context, connection);
01729       
01730       message = dbus_connection_borrow_message (connection);
01731       <font class="keywordflow">if</font> (message == NULL)
01732         {
01733           _dbus_warn (<font class="stringliteral">"Did not receive any messages after base service creation notification\n"</font>);
01734           <font class="keywordflow">goto</font> out;
01735         }
01736 
01737       got_service_deleted = dbus_message_is_signal (message,
01738                                                     DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
01739                                                     <font class="stringliteral">"ServiceDeleted"</font>);
01740       got_error = dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR;
01741       
01742       dbus_connection_return_message (connection, message);
01743       message = NULL;
01744 
01745       <font class="keywordflow">if</font> (got_error)
01746         {
01747           <font class="keywordflow">if</font> (!check_got_error (context, connection,
01748                                 DBUS_ERROR_SPAWN_CHILD_EXITED,
01749                                 DBUS_ERROR_NO_MEMORY,
01750                                 NULL))
01751             <font class="keywordflow">goto</font> out;
01752 
01753           <font class="comment">/* A service deleted should be coming along now after this error.</font>
01754 <font class="comment">           * We can also get the error *after* the service deleted.</font>
01755 <font class="comment">           */</font>
01756           got_service_deleted = TRUE;
01757         }
01758       
01759       <font class="keywordflow">if</font> (got_service_deleted)
01760         {
01761           <font class="comment">/* The service started up and got a base address, but then</font>
01762 <font class="comment">           * failed to register under EXISTENT_SERVICE_NAME</font>
01763 <font class="comment">           */</font>
01764           CheckServiceDeletedData csdd;
01765           
01766           csdd.expected_service_name = base_service;
01767           csdd.failed = FALSE;
01768           bus_test_clients_foreach (check_service_deleted_foreach,
01769                                     &amp;csdd);
01770 
01771           <font class="keywordflow">if</font> (csdd.failed)
01772             <font class="keywordflow">goto</font> out;
01773 
01774           <font class="comment">/* Now we should get an error about the service exiting</font>
01775 <font class="comment">           * if we didn't get it before.</font>
01776 <font class="comment">           */</font>
01777           <font class="keywordflow">if</font> (!got_error)
01778             {
01779               block_connection_until_message_from_bus (context, connection);
01780               
01781               <font class="comment">/* and process everything again */</font>
01782               bus_test_run_everything (context);
01783               
01784               <font class="keywordflow">if</font> (!check_got_error (context, connection,
01785                                     DBUS_ERROR_SPAWN_CHILD_EXITED,
01786                                     NULL))
01787                 <font class="keywordflow">goto</font> out;
01788             }
01789         }
01790       <font class="keywordflow">else</font>
01791         {
01792           message = pop_message_waiting_for_memory (connection);
01793           <font class="keywordflow">if</font> (message == NULL)
01794             {
01795               _dbus_warn (<font class="stringliteral">"Failed to pop message we just put back! should have been a ServiceCreated\n"</font>);
01796               <font class="keywordflow">goto</font> out;
01797             }
01798           
01799           <font class="keywordflow">if</font> (!check_service_activated (context, connection, EXISTENT_SERVICE_NAME,
01800                                         base_service, message))
01801             <font class="keywordflow">goto</font> out;
01802           
01803           dbus_message_unref (message);
01804           message = NULL;
01805 
01806 
01807           <font class="keywordflow">if</font> (!check_no_leftovers (context))
01808             {
01809               _dbus_warn (<font class="stringliteral">"Messages were left over after successful activation\n"</font>);
01810               <font class="keywordflow">goto</font> out;
01811             }
01812 
01813           <font class="keywordflow">if</font> (!check_send_exit_to_service (context, connection,
01814                                            EXISTENT_SERVICE_NAME, base_service))
01815             <font class="keywordflow">goto</font> out;
01816         }
01817     }
01818   
01819   retval = TRUE;
01820   
01821  out:
01822   <font class="keywordflow">if</font> (message)
01823     dbus_message_unref (message);
01824 
01825   <font class="keywordflow">if</font> (base_service)
01826     dbus_free (base_service);
01827   
01828   <font class="keywordflow">return</font> retval;
01829 }
01830 
01831 <font class="comment">/* returns TRUE if the correct thing happens,</font>
01832 <font class="comment"> * but the correct thing may include OOM errors.</font>
01833 <font class="comment"> */</font>
01834 <font class="keyword">static</font> dbus_bool_t
01835 check_segfault_service_activation (BusContext     *context,
01836                                    <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
01837 {
01838   <a class="code" href="structDBusMessage.html">DBusMessage</a> *message;
01839   dbus_uint32_t serial;
01840   dbus_bool_t retval;
01841   <a class="code" href="structDBusError.html">DBusError</a> error;
01842   
01843   dbus_error_init (&amp;error);
01844   
01845   message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
01846                                           DBUS_PATH_ORG_FREEDESKTOP_DBUS,
01847                                           DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
01848                                           <font class="stringliteral">"ActivateService"</font>);
01849 
01850   <font class="keywordflow">if</font> (message == NULL)
01851     <font class="keywordflow">return</font> TRUE;
01852 
01853   <font class="keywordflow">if</font> (!dbus_message_append_args (message,
01854                                  DBUS_TYPE_STRING,
01855                                  <font class="stringliteral">"org.freedesktop.DBus.TestSuiteSegfaultService"</font>,
01856                                  DBUS_TYPE_UINT32, 0,
01857                                  DBUS_TYPE_INVALID))
01858     {
01859       dbus_message_unref (message);
01860       <font class="keywordflow">return</font> TRUE;
01861     }
01862   
01863   <font class="keywordflow">if</font> (!dbus_connection_send (connection, message, &amp;serial))
01864     {
01865       dbus_message_unref (message);
01866       <font class="keywordflow">return</font> TRUE;
01867     }
01868 
01869   dbus_message_unref (message);
01870   message = NULL;
01871 
01872   bus_test_run_everything (context);
01873   block_connection_until_message_from_bus (context, connection);
01874   bus_test_run_everything (context);
01875 
01876   <font class="keywordflow">if</font> (!dbus_connection_get_is_connected (connection))
01877     {
01878       _dbus_verbose (<font class="stringliteral">"connection was disconnected\n"</font>);
01879       <font class="keywordflow">return</font> TRUE;
01880     }
01881   
01882   retval = FALSE;
01883   
01884   message = pop_message_waiting_for_memory (connection);
01885   <font class="keywordflow">if</font> (message == NULL)
01886     {
01887       _dbus_warn (<font class="stringliteral">"Did not receive a reply to %s %d on %p\n"</font>,
01888                   <font class="stringliteral">"ActivateService"</font>, serial, connection);
01889       <font class="keywordflow">goto</font> out;
01890     }
01891 
01892   verbose_message_received (connection, message);
01893 
01894   <font class="keywordflow">if</font> (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
01895     {
01896       <font class="keywordflow">if</font> (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
01897         {
01898           _dbus_warn (<font class="stringliteral">"Message has wrong sender %s\n"</font>,
01899                       dbus_message_get_sender (message) ?
01900                       dbus_message_get_sender (message) : "(none)");
01901           <font class="keywordflow">goto</font> out;
01902         }
01903       
01904       <font class="keywordflow">if</font> (dbus_message_is_error (message,
01905                                  DBUS_ERROR_NO_MEMORY))
01906         {
01907           ; <font class="comment">/* good, this is a valid response */</font>
01908         }
01909       <font class="keywordflow">else</font> <font class="keywordflow">if</font> (dbus_message_is_error (message,
01910                                       DBUS_ERROR_SPAWN_CHILD_SIGNALED))
01911         {
01912           ; <font class="comment">/* good, this is expected also */</font>
01913         }
01914       <font class="keywordflow">else</font>
01915         {
01916           warn_unexpected (connection, message, <font class="stringliteral">"not this error"</font>);
01917 
01918           <font class="keywordflow">goto</font> out;
01919         }
01920     }
01921   <font class="keywordflow">else</font>
01922     {
01923       _dbus_warn (<font class="stringliteral">"Did not expect to successfully activate segfault service\n"</font>);
01924       <font class="keywordflow">goto</font> out;
01925     }
01926 
01927   retval = TRUE;
01928   
01929  out:
01930   <font class="keywordflow">if</font> (message)
01931     dbus_message_unref (message);
01932   
01933   <font class="keywordflow">return</font> retval;
01934 }
01935 
01936 <font class="keyword">typedef</font> <font class="keyword">struct</font>
01937 <font class="keyword"></font>{
01938   Check1Func func;
01939   BusContext *context;
01940 } Check1Data;
01941 
01942 <font class="keyword">static</font> dbus_bool_t
01943 check_oom_check1_func (<font class="keywordtype">void</font> *data)
01944 {
01945   Check1Data *d = data;
01946 
01947   <font class="keywordflow">if</font> (! (* d-&gt;func) (d-&gt;context))
01948     <font class="keywordflow">return</font> FALSE;
01949   
01950   <font class="keywordflow">if</font> (!check_no_leftovers (d-&gt;context))
01951     {
01952       _dbus_warn (<font class="stringliteral">"Messages were left over, should be covered by test suite\n"</font>);
01953       <font class="keywordflow">return</font> FALSE;
01954     }
01955 
01956   <font class="keywordflow">return</font> TRUE;
01957 }
01958 
01959 <font class="keyword">static</font> <font class="keywordtype">void</font>
01960 check1_try_iterations (BusContext *context,
01961                        <font class="keyword">const</font> <font class="keywordtype">char</font> *description,
01962                        Check1Func  func)
01963 {
01964   Check1Data d;
01965 
01966   d.func = func;
01967   d.context = context;
01968 
01969   <font class="keywordflow">if</font> (!_dbus_test_oom_handling (description, check_oom_check1_func,
01970                                 &amp;d))
01971     _dbus_assert_not_reached (<font class="stringliteral">"test failed"</font>);
01972 }
01973 
01974 <font class="keyword">typedef</font> <font class="keyword">struct</font>
01975 <font class="keyword"></font>{
01976   Check2Func func;
01977   BusContext *context;
01978   <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection;
01979 } Check2Data;
01980 
01981 <font class="keyword">static</font> dbus_bool_t
01982 check_oom_check2_func (<font class="keywordtype">void</font> *data)
01983 {
01984   Check2Data *d = data;
01985 
01986   <font class="keywordflow">if</font> (! (* d-&gt;func) (d-&gt;context, d-&gt;connection))
01987     <font class="keywordflow">return</font> FALSE;
01988   
01989   <font class="keywordflow">if</font> (!check_no_leftovers (d-&gt;context))
01990     {
01991       _dbus_warn (<font class="stringliteral">"Messages were left over, should be covered by test suite"</font>);
01992       <font class="keywordflow">return</font> FALSE;
01993     }
01994 
01995   <font class="keywordflow">return</font> TRUE;
01996 }
01997 
01998 <font class="keyword">static</font> <font class="keywordtype">void</font>
01999 check2_try_iterations (BusContext     *context,
02000                        <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
02001                        <font class="keyword">const</font> <font class="keywordtype">char</font>     *description,
02002                        Check2Func      func)
02003 {
02004   Check2Data d;
02005 
02006   d.func = func;
02007   d.context = context;
02008   d.connection = connection;
02009   
02010   <font class="keywordflow">if</font> (!_dbus_test_oom_handling (description, check_oom_check2_func,
02011                                 &amp;d))
02012     _dbus_assert_not_reached (<font class="stringliteral">"test failed"</font>);
02013 }
02014 
02015 dbus_bool_t
02016 bus_dispatch_test (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *test_data_dir)
02017 {
02018   BusContext *context;
02019   <a class="code" href="structDBusConnection.html">DBusConnection</a> *foo;
02020   <a class="code" href="structDBusConnection.html">DBusConnection</a> *bar;
02021   <a class="code" href="structDBusConnection.html">DBusConnection</a> *baz;
02022   <a class="code" href="structDBusError.html">DBusError</a> error;
02023 
02024   dbus_error_init (&amp;error);
02025   
02026   context = bus_context_new_test (test_data_dir,
02027                                   <font class="stringliteral">"valid-config-files/debug-allow-all.conf"</font>);
02028   <font class="keywordflow">if</font> (context == NULL)
02029     <font class="keywordflow">return</font> FALSE;
02030   
02031   foo = dbus_connection_open (<font class="stringliteral">"debug-pipe:name=test-server"</font>, &amp;error);
02032   <font class="keywordflow">if</font> (foo == NULL)
02033     _dbus_assert_not_reached (<font class="stringliteral">"could not alloc connection"</font>);
02034 
02035   <font class="keywordflow">if</font> (!bus_setup_debug_client (foo))
02036     _dbus_assert_not_reached (<font class="stringliteral">"could not set up connection"</font>);
02037 
02038   <font class="keywordflow">if</font> (!check_hello_message (context, foo))
02039     _dbus_assert_not_reached (<font class="stringliteral">"hello message failed"</font>);
02040 
02041   <font class="keywordflow">if</font> (!check_add_match_all (context, foo))
02042     _dbus_assert_not_reached (<font class="stringliteral">"AddMatch message failed"</font>);
02043   
02044   bar = dbus_connection_open (<font class="stringliteral">"debug-pipe:name=test-server"</font>, &amp;error);
02045   <font class="keywordflow">if</font> (bar == NULL)
02046     _dbus_assert_not_reached (<font class="stringliteral">"could not alloc connection"</font>);
02047 
02048   <font class="keywordflow">if</font> (!bus_setup_debug_client (bar))
02049     _dbus_assert_not_reached (<font class="stringliteral">"could not set up connection"</font>);
02050 
02051   <font class="keywordflow">if</font> (!check_hello_message (context, bar))
02052     _dbus_assert_not_reached (<font class="stringliteral">"hello message failed"</font>);
02053 
02054   <font class="keywordflow">if</font> (!check_add_match_all (context, bar))
02055     _dbus_assert_not_reached (<font class="stringliteral">"AddMatch message failed"</font>);
02056   
02057   baz = dbus_connection_open (<font class="stringliteral">"debug-pipe:name=test-server"</font>, &amp;error);
02058   <font class="keywordflow">if</font> (baz == NULL)
02059     _dbus_assert_not_reached (<font class="stringliteral">"could not alloc connection"</font>);
02060 
02061   <font class="keywordflow">if</font> (!bus_setup_debug_client (baz))
02062     _dbus_assert_not_reached (<font class="stringliteral">"could not set up connection"</font>);
02063 
02064   <font class="keywordflow">if</font> (!check_hello_message (context, baz))
02065     _dbus_assert_not_reached (<font class="stringliteral">"hello message failed"</font>);
02066 
02067   <font class="keywordflow">if</font> (!check_add_match_all (context, baz))
02068     _dbus_assert_not_reached (<font class="stringliteral">"AddMatch message failed"</font>);
02069   
02070   <font class="keywordflow">if</font> (!check_no_leftovers (context))
02071     {
02072       _dbus_warn (<font class="stringliteral">"Messages were left over after setting up initial connections"</font>);
02073       _dbus_assert_not_reached (<font class="stringliteral">"initial connection setup failed"</font>);
02074     }
02075   
02076   check1_try_iterations (context, <font class="stringliteral">"create_and_hello"</font>,
02077                          check_hello_connection);
02078   
02079   check2_try_iterations (context, foo, <font class="stringliteral">"nonexistent_service_activation"</font>,
02080                          check_nonexistent_service_activation);
02081 
02082   check2_try_iterations (context, foo, <font class="stringliteral">"segfault_service_activation"</font>,
02083                          check_segfault_service_activation);
02084   
02085   check2_try_iterations (context, foo, <font class="stringliteral">"existent_service_activation"</font>,
02086                          check_existent_service_activation);
02087   
02088   _dbus_verbose (<font class="stringliteral">"Disconnecting foo, bar, and baz\n"</font>);
02089 
02090   kill_client_connection_unchecked (foo);
02091   kill_client_connection_unchecked (bar);
02092   kill_client_connection_unchecked (baz);
02093 
02094   bus_context_unref (context);
02095   
02096   <font class="keywordflow">return</font> TRUE;
02097 }
02098 
02099 dbus_bool_t
02100 bus_dispatch_sha1_test (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *test_data_dir)
02101 {
02102   BusContext *context;
02103   <a class="code" href="structDBusConnection.html">DBusConnection</a> *foo;
02104   <a class="code" href="structDBusError.html">DBusError</a> error;
02105 
02106   dbus_error_init (&amp;error);
02107   
02108   <font class="comment">/* Test SHA1 authentication */</font>
02109   _dbus_verbose (<font class="stringliteral">"Testing SHA1 context\n"</font>);
02110   
02111   context = bus_context_new_test (test_data_dir,
02112                                   <font class="stringliteral">"valid-config-files/debug-allow-all-sha1.conf"</font>);
02113   <font class="keywordflow">if</font> (context == NULL)
02114     <font class="keywordflow">return</font> FALSE;
02115 
02116   foo = dbus_connection_open (<font class="stringliteral">"debug-pipe:name=test-server"</font>, &amp;error);
02117   <font class="keywordflow">if</font> (foo == NULL)
02118     _dbus_assert_not_reached (<font class="stringliteral">"could not alloc connection"</font>);
02119 
02120   <font class="keywordflow">if</font> (!bus_setup_debug_client (foo))
02121     _dbus_assert_not_reached (<font class="stringliteral">"could not set up connection"</font>);
02122 
02123   <font class="keywordflow">if</font> (!check_hello_message (context, foo))
02124     _dbus_assert_not_reached (<font class="stringliteral">"hello message failed"</font>);
02125 
02126   <font class="keywordflow">if</font> (!check_add_match_all (context, foo))
02127     _dbus_assert_not_reached (<font class="stringliteral">"addmatch message failed"</font>);
02128   
02129   <font class="keywordflow">if</font> (!check_no_leftovers (context))
02130     {
02131       _dbus_warn (<font class="stringliteral">"Messages were left over after setting up initial SHA-1 connection\n"</font>);
02132       _dbus_assert_not_reached (<font class="stringliteral">"initial connection setup failed"</font>);
02133     }
02134   
02135   check1_try_iterations (context, <font class="stringliteral">"create_and_hello_sha1"</font>,
02136                          check_hello_connection);
02137 
02138   kill_client_connection_unchecked (foo);
02139 
02140   bus_context_unref (context);
02141 
02142   <font class="keywordflow">return</font> TRUE;
02143 }
02144 
02145 <font class="preprocessor">#endif </font><font class="comment">/* DBUS_BUILD_TESTS */</font>
</pre></div><hr><address align="right"><small>Generated on Mon Sep 29 21:31:02 2003 for D-BUS by
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border=0 
width=110 height=53></a>1.2.15 </small></address>
</body>
</html>