Sophie

Sophie

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

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>connection.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>connection.c</h1><div class="fragment"><pre>00001 <font class="comment">/* -*- mode: C; c-file-style: "gnu" -*- */</font>
00002 <font class="comment">/* connection.c  Client connections</font>
00003 <font class="comment"> *</font>
00004 <font class="comment"> * Copyright (C) 2003  Red Hat, Inc.</font>
00005 <font class="comment"> *</font>
00006 <font class="comment"> * Licensed under the Academic Free License version 1.2</font>
00007 <font class="comment"> * </font>
00008 <font class="comment"> * This program is free software; you can redistribute it and/or modify</font>
00009 <font class="comment"> * it under the terms of the GNU General Public License as published by</font>
00010 <font class="comment"> * the Free Software Foundation; either version 2 of the License, or</font>
00011 <font class="comment"> * (at your option) any later version.</font>
00012 <font class="comment"> *</font>
00013 <font class="comment"> * This program is distributed in the hope that it will be useful,</font>
00014 <font class="comment"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</font>
00015 <font class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</font>
00016 <font class="comment"> * GNU General Public License for more details.</font>
00017 <font class="comment"> * </font>
00018 <font class="comment"> * You should have received a copy of the GNU General Public License</font>
00019 <font class="comment"> * along with this program; if not, write to the Free Software</font>
00020 <font class="comment"> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA</font>
00021 <font class="comment"> *</font>
00022 <font class="comment"> */</font>
00023 <font class="preprocessor">#include "connection.h"</font>
00024 <font class="preprocessor">#include "dispatch.h"</font>
00025 <font class="preprocessor">#include "policy.h"</font>
00026 <font class="preprocessor">#include "services.h"</font>
00027 <font class="preprocessor">#include "utils.h"</font>
00028 <font class="preprocessor">#include "signals.h"</font>
00029 <font class="preprocessor">#include &lt;dbus/dbus-list.h&gt;</font>
00030 <font class="preprocessor">#include &lt;dbus/dbus-hash.h&gt;</font>
00031 <font class="preprocessor">#include &lt;dbus/dbus-timeout.h&gt;</font>
00032 
00033 <font class="keyword">static</font> <font class="keywordtype">void</font> bus_connection_remove_transactions (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection);
00034 
00035 <font class="keyword">struct </font>BusConnections
00036 {
00037   <font class="keywordtype">int</font> refcount;
00038   <a class="code" href="structDBusList.html">DBusList</a> *completed;  
00039   <font class="keywordtype">int</font> n_completed;      
00040   <a class="code" href="structDBusList.html">DBusList</a> *incomplete; 
00041   <font class="keywordtype">int</font> n_incomplete;     
00042   BusContext *context;
00043   <a class="code" href="structDBusHashTable.html">DBusHashTable</a> *completed_by_user; 
00044   <a class="code" href="structDBusTimeout.html">DBusTimeout</a> *expire_timeout; 
00045   <font class="keywordtype">int</font> stamp;            
00046 };
00047 
00048 <font class="keyword">static</font> dbus_int32_t connection_data_slot = -1;
00049 
00050 <font class="keyword">typedef</font> <font class="keyword">struct</font>
00051 <font class="keyword"></font>{
00052   BusConnections *connections;
00053   <a class="code" href="structDBusList.html">DBusList</a> *link_in_connection_list;
00054   <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection;
00055   <a class="code" href="structDBusList.html">DBusList</a> *services_owned;
00056   <font class="keywordtype">int</font> n_services_owned;
00057   <a class="code" href="structDBusList.html">DBusList</a> *match_rules;
00058   <font class="keywordtype">int</font> n_match_rules;
00059   <font class="keywordtype">char</font> *name;
00060   <a class="code" href="structDBusList.html">DBusList</a> *transaction_messages; 
00061   <a class="code" href="structDBusMessage.html">DBusMessage</a> *oom_message;
00062   <a class="code" href="structDBusPreallocatedSend.html">DBusPreallocatedSend</a> *oom_preallocated;
00063   BusClientPolicy *policy;
00064 
00065   <font class="keywordtype">long</font> connection_tv_sec;  
00066   <font class="keywordtype">long</font> connection_tv_usec; 
00067   <font class="keywordtype">int</font> stamp;               
00068 } BusConnectionData;
00069 
00070 <font class="keyword">static</font> dbus_bool_t expire_incomplete_timeout (<font class="keywordtype">void</font> *data);
00071 
00072 <font class="preprocessor">#define BUS_CONNECTION_DATA(connection) (dbus_connection_get_data ((connection), connection_data_slot))</font>
00073 <font class="preprocessor"></font>
00074 <font class="keyword">static</font> DBusLoop*
00075 connection_get_loop (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
00076 {
00077   BusConnectionData *d;
00078 
00079   d = BUS_CONNECTION_DATA (connection);
00080 
00081   <font class="keywordflow">return</font> bus_context_get_loop (d-&gt;connections-&gt;context);
00082 }
00083 
00084 
00085 <font class="keyword">static</font> <font class="keywordtype">int</font>
00086 get_connections_for_uid (BusConnections *connections,
00087                          dbus_uid_t      uid)
00088 {
00089   <font class="keywordtype">void</font> *val;
00090   <font class="keywordtype">int</font> current_count;
00091 
00092   <font class="comment">/* val is NULL is 0 when it isn't in the hash yet */</font>
00093   
00094   val = _dbus_hash_table_lookup_ulong (connections-&gt;completed_by_user,
00095                                        uid);
00096 
00097   current_count = _DBUS_POINTER_TO_INT (val);
00098 
00099   <font class="keywordflow">return</font> current_count;
00100 }
00101 
00102 <font class="keyword">static</font> dbus_bool_t
00103 adjust_connections_for_uid (BusConnections *connections,
00104                             dbus_uid_t      uid,
00105                             <font class="keywordtype">int</font>             adjustment)
00106 {
00107   <font class="keywordtype">int</font> current_count;
00108 
00109   current_count = get_connections_for_uid (connections, uid);
00110 
00111   _dbus_verbose (<font class="stringliteral">"Adjusting connection count for UID "</font> DBUS_UID_FORMAT
00112                  <font class="stringliteral">": was %d adjustment %d making %d\n"</font>,
00113                  uid, current_count, adjustment, current_count + adjustment);
00114   
00115   _dbus_assert (current_count &gt;= 0);
00116   
00117   current_count += adjustment;
00118 
00119   _dbus_assert (current_count &gt;= 0);
00120 
00121   <font class="keywordflow">if</font> (current_count == 0)
00122     {
00123       _dbus_hash_table_remove_ulong (connections-&gt;completed_by_user, uid);
00124       <font class="keywordflow">return</font> TRUE;
00125     }
00126   <font class="keywordflow">else</font>
00127     {
00128       dbus_bool_t retval;
00129       
00130       retval = _dbus_hash_table_insert_ulong (connections-&gt;completed_by_user,
00131                                               uid, _DBUS_INT_TO_POINTER (current_count));
00132 
00133       <font class="comment">/* only positive adjustment can fail as otherwise</font>
00134 <font class="comment">       * a hash entry should already exist</font>
00135 <font class="comment">       */</font>
00136       _dbus_assert (adjustment &gt; 0 ||
00137                     (adjustment &lt;= 0 &amp;&amp; retval));
00138 
00139       <font class="keywordflow">return</font> retval;
00140     }
00141 }
00142 
00143 <font class="keywordtype">void</font>
00144 bus_connection_disconnected (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
00145 {
00146   BusConnectionData *d;
00147   BusService *service;
00148   BusMatchmaker *matchmaker;
00149   
00150   d = BUS_CONNECTION_DATA (connection);
00151   _dbus_assert (d != NULL);
00152 
00153   _dbus_verbose (<font class="stringliteral">"%s disconnected, dropping all service ownership and releasing\n"</font>,
00154                  d-&gt;name ? d-&gt;name : <font class="stringliteral">"(inactive)"</font>);
00155 
00156   <font class="comment">/* Delete our match rules */</font>
00157   <font class="keywordflow">if</font> (d-&gt;n_match_rules &gt; 0)
00158     {
00159       matchmaker = bus_context_get_matchmaker (d-&gt;connections-&gt;context);
00160       bus_matchmaker_disconnected (matchmaker, connection);
00161     }
00162   
00163   <font class="comment">/* Drop any service ownership. FIXME Unfortunately, this requires</font>
00164 <font class="comment">   * memory allocation and there doesn't seem to be a good way to</font>
00165 <font class="comment">   * handle it other than sleeping; we can't "fail" the operation of</font>
00166 <font class="comment">   * disconnecting a client, and preallocating a broadcast "service is</font>
00167 <font class="comment">   * now gone" message for every client-service pair seems kind of</font>
00168 <font class="comment">   * involved. Probably we need to do that though.</font>
00169 <font class="comment">   */</font>
00170   <font class="keywordflow">while</font> ((service = _dbus_list_get_last (&amp;d-&gt;services_owned)))
00171     {
00172       BusTransaction *transaction;
00173       <a class="code" href="structDBusError.html">DBusError</a> error;
00174 
00175     retry:
00176       
00177       dbus_error_init (&amp;error);
00178         
00179       transaction = NULL;
00180       <font class="keywordflow">while</font> (transaction == NULL)
00181         {
00182           transaction = bus_transaction_new (d-&gt;connections-&gt;context);
00183           _dbus_wait_for_memory ();
00184         }
00185         
00186       <font class="keywordflow">if</font> (!bus_service_remove_owner (service, connection,
00187                                      transaction, &amp;error))
00188         {
00189           _DBUS_ASSERT_ERROR_IS_SET (&amp;error);
00190           
00191           <font class="keywordflow">if</font> (dbus_error_has_name (&amp;error, DBUS_ERROR_NO_MEMORY))
00192             {
00193               dbus_error_free (&amp;error);
00194               bus_transaction_cancel_and_free (transaction);
00195               _dbus_wait_for_memory ();
00196               <font class="keywordflow">goto</font> retry;
00197             }
00198           <font class="keywordflow">else</font>
00199             {
00200               _dbus_verbose (<font class="stringliteral">"Failed to remove service owner: %s %s\n"</font>,
00201                              error.<a class="code" href="structDBusError.html#m0">name</a>, error.<a class="code" href="structDBusError.html#m1">message</a>);
00202               _dbus_assert_not_reached (<font class="stringliteral">"Removing service owner failed for non-memory-related reason"</font>);
00203             }
00204         }
00205         
00206       bus_transaction_execute_and_free (transaction);
00207     }
00208 
00209   bus_dispatch_remove_connection (connection);
00210   
00211   <font class="comment">/* no more watching */</font>
00212   <font class="keywordflow">if</font> (!dbus_connection_set_watch_functions (connection,
00213                                             NULL, NULL, NULL,
00214                                             connection,
00215                                             NULL))
00216     _dbus_assert_not_reached (<font class="stringliteral">"setting watch functions to NULL failed"</font>);
00217 
00218   <font class="keywordflow">if</font> (!dbus_connection_set_timeout_functions (connection,
00219                                               NULL, NULL, NULL,
00220                                               connection,
00221                                               NULL))
00222     _dbus_assert_not_reached (<font class="stringliteral">"setting timeout functions to NULL failed"</font>);
00223   
00224   dbus_connection_set_unix_user_function (connection,
00225                                           NULL, NULL, NULL);
00226 
00227   dbus_connection_set_dispatch_status_function (connection,
00228                                                 NULL, NULL, NULL);
00229   
00230   bus_connection_remove_transactions (connection);
00231 
00232   <font class="keywordflow">if</font> (d-&gt;link_in_connection_list != NULL)
00233     {
00234       <font class="keywordflow">if</font> (d-&gt;name != NULL)
00235         {
00236           <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> uid;
00237           
00238           _dbus_list_remove_link (&amp;d-&gt;connections-&gt;completed, d-&gt;link_in_connection_list);
00239           d-&gt;link_in_connection_list = NULL;
00240           d-&gt;connections-&gt;n_completed -= 1;
00241 
00242           <font class="keywordflow">if</font> (dbus_connection_get_unix_user (connection, &amp;uid))
00243             {
00244               <font class="keywordflow">if</font> (!adjust_connections_for_uid (d-&gt;connections,
00245                                                uid, -1))
00246                 _dbus_assert_not_reached (<font class="stringliteral">"adjusting downward should never fail"</font>);
00247             }
00248         }
00249       <font class="keywordflow">else</font>
00250         {
00251           _dbus_list_remove_link (&amp;d-&gt;connections-&gt;incomplete, d-&gt;link_in_connection_list);
00252           d-&gt;link_in_connection_list = NULL;
00253           d-&gt;connections-&gt;n_incomplete -= 1;
00254         }
00255       
00256       _dbus_assert (d-&gt;connections-&gt;n_incomplete &gt;= 0);
00257       _dbus_assert (d-&gt;connections-&gt;n_completed &gt;= 0);
00258     }
00259   
00260   <font class="comment">/* frees "d" as side effect */</font>
00261   dbus_connection_set_data (connection,
00262                             connection_data_slot,
00263                             NULL, NULL);
00264 
00265   dbus_connection_unref (connection);
00266 }
00267 
00268 <font class="keyword">static</font> dbus_bool_t
00269 connection_watch_callback (<a class="code" href="structDBusWatch.html">DBusWatch</a>     *watch,
00270                            <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font>   condition,
00271                            <font class="keywordtype">void</font>          *data)
00272 {
00273  <font class="comment">/* FIXME this can be done in dbus-mainloop.c</font>
00274 <font class="comment">  * if the code in activation.c for the babysitter</font>
00275 <font class="comment">  * watch handler is fixed.</font>
00276 <font class="comment">  */</font>
00277   
00278 <font class="preprocessor">#if 0</font>
00279 <font class="preprocessor"></font>  _dbus_verbose (<font class="stringliteral">"Calling handle_watch\n"</font>);
00280 <font class="preprocessor">#endif</font>
00281 <font class="preprocessor"></font>  <font class="keywordflow">return</font> dbus_watch_handle (watch, condition);
00282 }
00283 
00284 <font class="keyword">static</font> dbus_bool_t
00285 add_connection_watch (<a class="code" href="structDBusWatch.html">DBusWatch</a>      *watch,
00286                       <font class="keywordtype">void</font>           *data)
00287 {
00288   <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection = data;
00289 
00290   <font class="keywordflow">return</font> _dbus_loop_add_watch (connection_get_loop (connection),
00291                                watch, connection_watch_callback, connection,
00292                                NULL);
00293 }
00294 
00295 <font class="keyword">static</font> <font class="keywordtype">void</font>
00296 remove_connection_watch (<a class="code" href="structDBusWatch.html">DBusWatch</a>      *watch,
00297                          <font class="keywordtype">void</font>           *data)
00298 {
00299   <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection = data;
00300   
00301   _dbus_loop_remove_watch (connection_get_loop (connection),
00302                            watch, connection_watch_callback, connection);
00303 }
00304 
00305 <font class="keyword">static</font> <font class="keywordtype">void</font>
00306 connection_timeout_callback (<a class="code" href="structDBusTimeout.html">DBusTimeout</a>   *timeout,
00307                              <font class="keywordtype">void</font>          *data)
00308 {
00309   <font class="comment">/* DBusConnection *connection = data; */</font>
00310 
00311   <font class="comment">/* can return FALSE on OOM but we just let it fire again later */</font>
00312   dbus_timeout_handle (timeout);
00313 }
00314 
00315 <font class="keyword">static</font> dbus_bool_t
00316 add_connection_timeout (<a class="code" href="structDBusTimeout.html">DBusTimeout</a>    *timeout,
00317                         <font class="keywordtype">void</font>           *data)
00318 {
00319   <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection = data;
00320   
00321   <font class="keywordflow">return</font> _dbus_loop_add_timeout (connection_get_loop (connection),
00322                                  timeout, connection_timeout_callback, connection, NULL);
00323 }
00324 
00325 <font class="keyword">static</font> <font class="keywordtype">void</font>
00326 remove_connection_timeout (<a class="code" href="structDBusTimeout.html">DBusTimeout</a>    *timeout,
00327                            <font class="keywordtype">void</font>           *data)
00328 {
00329   <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection = data;
00330   
00331   _dbus_loop_remove_timeout (connection_get_loop (connection),
00332                              timeout, connection_timeout_callback, connection);
00333 }
00334 
00335 <font class="keyword">static</font> <font class="keywordtype">void</font>
00336 dispatch_status_function (<a class="code" href="structDBusConnection.html">DBusConnection</a>    *connection,
00337                           DBusDispatchStatus new_status,
00338                           <font class="keywordtype">void</font>              *data)
00339 {
00340   DBusLoop *loop = data;
00341   
00342   <font class="keywordflow">if</font> (new_status != DBUS_DISPATCH_COMPLETE)
00343     {
00344       <font class="keywordflow">while</font> (!_dbus_loop_queue_dispatch (loop, connection))
00345         _dbus_wait_for_memory ();
00346     }
00347 }
00348 
00349 <font class="keyword">static</font> dbus_bool_t
00350 allow_user_function (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
00351                      <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font>   uid,
00352                      <font class="keywordtype">void</font>           *data)
00353 {
00354   BusConnectionData *d;
00355     
00356   d = BUS_CONNECTION_DATA (connection);
00357 
00358   _dbus_assert (d != NULL);
00359   
00360   <font class="keywordflow">return</font> bus_context_allow_user (d-&gt;connections-&gt;context, uid);
00361 }
00362 
00363 <font class="keyword">static</font> <font class="keywordtype">void</font>
00364 free_connection_data (<font class="keywordtype">void</font> *data)
00365 {
00366   BusConnectionData *d = data;
00367 
00368   <font class="comment">/* services_owned should be NULL since we should be disconnected */</font>
00369   _dbus_assert (d-&gt;services_owned == NULL);
00370   _dbus_assert (d-&gt;n_services_owned == 0);
00371   <font class="comment">/* similarly */</font>
00372   _dbus_assert (d-&gt;transaction_messages == NULL);
00373 
00374   <font class="keywordflow">if</font> (d-&gt;oom_preallocated)
00375     dbus_connection_free_preallocated_send (d-&gt;connection, d-&gt;oom_preallocated);
00376 
00377   <font class="keywordflow">if</font> (d-&gt;oom_message)
00378     dbus_message_unref (d-&gt;oom_message);
00379 
00380   <font class="keywordflow">if</font> (d-&gt;policy)
00381     bus_client_policy_unref (d-&gt;policy);
00382   
00383   dbus_free (d-&gt;name);
00384   
00385   dbus_free (d);
00386 }
00387 
00388 <font class="keyword">static</font> <font class="keywordtype">void</font>
00389 call_timeout_callback (<a class="code" href="structDBusTimeout.html">DBusTimeout</a>   *timeout,
00390                        <font class="keywordtype">void</font>          *data)
00391 {
00392   <font class="comment">/* can return FALSE on OOM but we just let it fire again later */</font>
00393   dbus_timeout_handle (timeout);
00394 }
00395 
00396 BusConnections*
00397 bus_connections_new (BusContext *context)
00398 {
00399   BusConnections *connections;
00400 
00401   <font class="keywordflow">if</font> (!dbus_connection_allocate_data_slot (&amp;connection_data_slot))
00402     <font class="keywordflow">goto</font> failed_0;
00403 
00404   connections = dbus_new0 (BusConnections, 1);
00405   <font class="keywordflow">if</font> (connections == NULL)
00406     <font class="keywordflow">goto</font> failed_1;
00407 
00408   connections-&gt;completed_by_user = _dbus_hash_table_new (DBUS_HASH_ULONG,
00409                                                          NULL, NULL);
00410   <font class="keywordflow">if</font> (connections-&gt;completed_by_user == NULL)
00411     <font class="keywordflow">goto</font> failed_2;
00412 
00413   connections-&gt;expire_timeout = _dbus_timeout_new (100, <font class="comment">/* irrelevant */</font>
00414                                                    expire_incomplete_timeout,
00415                                                    connections, NULL);
00416   <font class="keywordflow">if</font> (connections-&gt;expire_timeout == NULL)
00417     <font class="keywordflow">goto</font> failed_3;
00418 
00419   _dbus_timeout_set_enabled (connections-&gt;expire_timeout, FALSE);
00420 
00421   <font class="keywordflow">if</font> (!_dbus_loop_add_timeout (bus_context_get_loop (context),
00422                                connections-&gt;expire_timeout,
00423                                call_timeout_callback, NULL, NULL))
00424     <font class="keywordflow">goto</font> failed_4;
00425   
00426   connections-&gt;refcount = 1;
00427   connections-&gt;context = context;
00428   
00429   <font class="keywordflow">return</font> connections;
00430 
00431  failed_4:
00432   _dbus_timeout_unref (connections-&gt;expire_timeout);
00433  failed_3:
00434   _dbus_hash_table_unref (connections-&gt;completed_by_user);
00435  failed_2:
00436   dbus_free (connections);
00437  failed_1:
00438   dbus_connection_free_data_slot (&amp;connection_data_slot);
00439  failed_0:
00440   <font class="keywordflow">return</font> NULL;
00441 }
00442 
00443 <font class="keywordtype">void</font>
00444 bus_connections_ref (BusConnections *connections)
00445 {
00446   _dbus_assert (connections-&gt;refcount &gt; 0);
00447   connections-&gt;refcount += 1;
00448 }
00449 
00450 <font class="keywordtype">void</font>
00451 bus_connections_unref (BusConnections *connections)
00452 {
00453   _dbus_assert (connections-&gt;refcount &gt; 0);
00454   connections-&gt;refcount -= 1;
00455   <font class="keywordflow">if</font> (connections-&gt;refcount == 0)
00456     {
00457       <font class="comment">/* drop all incomplete */</font>
00458       <font class="keywordflow">while</font> (connections-&gt;incomplete != NULL)
00459         {
00460           <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection;
00461 
00462           connection = connections-&gt;incomplete-&gt;data;
00463 
00464           dbus_connection_ref (connection);
00465           dbus_connection_disconnect (connection);
00466           bus_connection_disconnected (connection);
00467           dbus_connection_unref (connection);
00468         }
00469 
00470       _dbus_assert (connections-&gt;n_incomplete == 0);
00471       
00472       <font class="comment">/* drop all real connections */</font>
00473       <font class="keywordflow">while</font> (connections-&gt;completed != NULL)
00474         {
00475           <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection;
00476 
00477           connection = connections-&gt;completed-&gt;data;
00478 
00479           dbus_connection_ref (connection);
00480           dbus_connection_disconnect (connection);
00481           bus_connection_disconnected (connection);
00482           dbus_connection_unref (connection);          
00483         }
00484 
00485       _dbus_assert (connections-&gt;n_completed == 0);
00486 
00487       _dbus_loop_remove_timeout (bus_context_get_loop (connections-&gt;context),
00488                                  connections-&gt;expire_timeout,
00489                                  call_timeout_callback, NULL);
00490       
00491       _dbus_timeout_unref (connections-&gt;expire_timeout);
00492       
00493       _dbus_hash_table_unref (connections-&gt;completed_by_user);
00494       
00495       dbus_free (connections);
00496 
00497       dbus_connection_free_data_slot (&amp;connection_data_slot);
00498     }
00499 }
00500 
00501 dbus_bool_t
00502 bus_connections_setup_connection (BusConnections *connections,
00503                                   <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
00504 {
00505   BusConnectionData *d;
00506   dbus_bool_t retval;
00507   
00508   d = dbus_new0 (BusConnectionData, 1);
00509   
00510   <font class="keywordflow">if</font> (d == NULL)
00511     <font class="keywordflow">return</font> FALSE;
00512 
00513   d-&gt;connections = connections;
00514   d-&gt;connection = connection;
00515   
00516   _dbus_get_current_time (&amp;d-&gt;connection_tv_sec,
00517                           &amp;d-&gt;connection_tv_usec);
00518   
00519   _dbus_assert (connection_data_slot &gt;= 0);
00520   
00521   <font class="keywordflow">if</font> (!dbus_connection_set_data (connection,
00522                                  connection_data_slot,
00523                                  d, free_connection_data))
00524     {
00525       dbus_free (d);
00526       <font class="keywordflow">return</font> FALSE;
00527     }
00528 
00529   retval = FALSE;
00530   
00531   <font class="keywordflow">if</font> (!dbus_connection_set_watch_functions (connection,
00532                                             add_connection_watch,
00533                                             remove_connection_watch,
00534                                             NULL,
00535                                             connection,
00536                                             NULL))
00537     <font class="keywordflow">goto</font> out;
00538   
00539   <font class="keywordflow">if</font> (!dbus_connection_set_timeout_functions (connection,
00540                                               add_connection_timeout,
00541                                               remove_connection_timeout,
00542                                               NULL,
00543                                               connection, NULL))
00544     <font class="keywordflow">goto</font> out;
00545   
00546   dbus_connection_set_unix_user_function (connection,
00547                                           allow_user_function,
00548                                           NULL, NULL);
00549 
00550   dbus_connection_set_dispatch_status_function (connection,
00551                                                 dispatch_status_function,
00552                                                 bus_context_get_loop (connections-&gt;context),
00553                                                 NULL);
00554 
00555   d-&gt;link_in_connection_list = _dbus_list_alloc_link (connection);
00556   <font class="keywordflow">if</font> (d-&gt;link_in_connection_list == NULL)
00557     <font class="keywordflow">goto</font> out;
00558   
00559   <font class="comment">/* Setup the connection with the dispatcher */</font>
00560   <font class="keywordflow">if</font> (!bus_dispatch_add_connection (connection))
00561     <font class="keywordflow">goto</font> out;
00562 
00563   <font class="keywordflow">if</font> (dbus_connection_get_dispatch_status (connection) != DBUS_DISPATCH_COMPLETE)
00564     {
00565       <font class="keywordflow">if</font> (!_dbus_loop_queue_dispatch (bus_context_get_loop (connections-&gt;context), connection))
00566         {
00567           bus_dispatch_remove_connection (connection);
00568           <font class="keywordflow">goto</font> out;
00569         }
00570     }
00571 
00572   _dbus_list_append_link (&amp;connections-&gt;incomplete, d-&gt;link_in_connection_list);
00573   connections-&gt;n_incomplete += 1;
00574   
00575   dbus_connection_ref (connection);
00576 
00577   <font class="comment">/* Note that we might disconnect ourselves here, but it only takes</font>
00578 <font class="comment">   * effect on return to the main loop. We call this to free up</font>
00579 <font class="comment">   * expired connections if possible, and to queue the timeout for our</font>
00580 <font class="comment">   * own expiration.</font>
00581 <font class="comment">   */</font>
00582   bus_connections_expire_incomplete (connections);
00583   
00584   <font class="comment">/* And we might also disconnect ourselves here, but again it</font>
00585 <font class="comment">   * only takes effect on return to main loop.</font>
00586 <font class="comment">   */</font>
00587   <font class="keywordflow">if</font> (connections-&gt;n_incomplete &gt;
00588       bus_context_get_max_incomplete_connections (connections-&gt;context))
00589     {
00590       _dbus_verbose (<font class="stringliteral">"Number of incomplete connections exceeds max, dropping oldest one\n"</font>);
00591       
00592       _dbus_assert (connections-&gt;incomplete != NULL);
00593       <font class="comment">/* Disconnect the oldest unauthenticated connection.  FIXME</font>
00594 <font class="comment">       * would it be more secure to drop a *random* connection?  This</font>
00595 <font class="comment">       * algorithm seems to mean that if someone can create new</font>
00596 <font class="comment">       * connections quickly enough, they can keep anyone else from</font>
00597 <font class="comment">       * completing authentication. But random may or may not really</font>
00598 <font class="comment">       * help with that, a more elaborate solution might be required.</font>
00599 <font class="comment">       */</font>
00600       dbus_connection_disconnect (connections-&gt;incomplete-&gt;data);
00601     }
00602   
00603   retval = TRUE;
00604 
00605  out:
00606   <font class="keywordflow">if</font> (!retval)
00607     {      
00608       <font class="keywordflow">if</font> (!dbus_connection_set_watch_functions (connection,
00609                                                 NULL, NULL, NULL,
00610                                                 connection,
00611                                                 NULL))
00612         _dbus_assert_not_reached (<font class="stringliteral">"setting watch functions to NULL failed"</font>);
00613       
00614       <font class="keywordflow">if</font> (!dbus_connection_set_timeout_functions (connection,
00615                                                   NULL, NULL, NULL,
00616                                                   connection,
00617                                                   NULL))
00618         _dbus_assert_not_reached (<font class="stringliteral">"setting timeout functions to NULL failed"</font>);
00619 
00620       dbus_connection_set_unix_user_function (connection,
00621                                               NULL, NULL, NULL);
00622 
00623       dbus_connection_set_dispatch_status_function (connection,
00624                                                     NULL, NULL, NULL);
00625 
00626       <font class="keywordflow">if</font> (d-&gt;link_in_connection_list != NULL)
00627         {
00628           _dbus_assert (d-&gt;link_in_connection_list-&gt;next == NULL);
00629           _dbus_assert (d-&gt;link_in_connection_list-&gt;prev == NULL);
00630           _dbus_list_free_link (d-&gt;link_in_connection_list);
00631           d-&gt;link_in_connection_list = NULL;
00632         }
00633       
00634       <font class="keywordflow">if</font> (!dbus_connection_set_data (connection,
00635                                      connection_data_slot,
00636                                      NULL, NULL))
00637         _dbus_assert_not_reached (<font class="stringliteral">"failed to set connection data to null"</font>);
00638 
00639       <font class="comment">/* "d" has now been freed */</font>
00640     }
00641   
00642   <font class="keywordflow">return</font> retval;
00643 }
00644 
00645 <font class="keywordtype">void</font>
00646 bus_connections_expire_incomplete (BusConnections *connections)
00647 {    
00648   <font class="keywordtype">int</font> next_interval;
00649 
00650   next_interval = -1;
00651   
00652   <font class="keywordflow">if</font> (connections-&gt;incomplete != NULL)
00653     {
00654       <font class="keywordtype">long</font> tv_sec, tv_usec;
00655       <a class="code" href="structDBusList.html">DBusList</a> *link;
00656       <font class="keywordtype">int</font> auth_timeout;
00657       
00658       _dbus_get_current_time (&amp;tv_sec, &amp;tv_usec);
00659       auth_timeout = bus_context_get_auth_timeout (connections-&gt;context);
00660   
00661       link = _dbus_list_get_first_link (&amp;connections-&gt;incomplete);
00662       <font class="keywordflow">while</font> (link != NULL)
00663         {
00664           <a class="code" href="structDBusList.html">DBusList</a> *next = _dbus_list_get_next_link (&amp;connections-&gt;incomplete, link);
00665           <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection;
00666           BusConnectionData *d;
00667           <font class="keywordtype">double</font> elapsed;
00668       
00669           connection = link-&gt;<a class="code" href="structDBusList.html#m2">data</a>;
00670       
00671           d = BUS_CONNECTION_DATA (connection);
00672       
00673           _dbus_assert (d != NULL);
00674       
00675           elapsed = ((double) tv_sec - (double) d-&gt;connection_tv_sec) * 1000.0 +
00676             ((double) tv_usec - (double) d-&gt;connection_tv_usec) / 1000.0;
00677 
00678           <font class="keywordflow">if</font> (elapsed &gt;= (double) auth_timeout)
00679             {
00680               _dbus_verbose (<font class="stringliteral">"Timing out authentication for connection %p\n"</font>, connection);
00681               dbus_connection_disconnect (connection);
00682             }
00683           <font class="keywordflow">else</font>
00684             {
00685               <font class="comment">/* We can end the loop, since the connections are in oldest-first order */</font>
00686               next_interval = ((double)auth_timeout) - elapsed;
00687               _dbus_verbose (<font class="stringliteral">"Connection %p authentication expires in %d milliseconds\n"</font>,
00688                              connection, next_interval);
00689           
00690               <font class="keywordflow">break</font>;
00691             }
00692       
00693           link = next;
00694         }
00695     }
00696   
00697   <font class="keywordflow">if</font> (next_interval &gt;= 0)
00698     {
00699       _dbus_timeout_set_interval (connections-&gt;expire_timeout,
00700                                   next_interval);
00701       _dbus_timeout_set_enabled (connections-&gt;expire_timeout, TRUE);
00702 
00703       _dbus_verbose (<font class="stringliteral">"Enabled incomplete connections timeout with interval %d, %d incomplete connections\n"</font>,
00704                      next_interval, connections-&gt;n_incomplete);
00705     }
00706   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (dbus_timeout_get_enabled (connections-&gt;expire_timeout))
00707     {
00708       _dbus_timeout_set_enabled (connections-&gt;expire_timeout, FALSE);
00709 
00710       _dbus_verbose (<font class="stringliteral">"Disabled incomplete connections timeout, %d incomplete connections\n"</font>,
00711                      connections-&gt;n_incomplete);
00712     }
00713   <font class="keywordflow">else</font>
00714     _dbus_verbose (<font class="stringliteral">"No need to disable incomplete connections timeout\n"</font>);
00715 }
00716 
00717 <font class="keyword">static</font> dbus_bool_t
00718 expire_incomplete_timeout (<font class="keywordtype">void</font> *data)
00719 {
00720   BusConnections *connections = data;
00721 
00722   _dbus_verbose (<font class="stringliteral">"Running %s\n"</font>, _DBUS_FUNCTION_NAME);
00723   
00724   <font class="comment">/* note that this may remove the timeout */</font>
00725   bus_connections_expire_incomplete (connections);
00726 
00727   <font class="keywordflow">return</font> TRUE;
00728 }
00729 
00730 dbus_bool_t
00731 bus_connection_get_groups  (<a class="code" href="structDBusConnection.html">DBusConnection</a>   *connection,
00732                             <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font>   **groups,
00733                             <font class="keywordtype">int</font>              *n_groups,
00734                             <a class="code" href="structDBusError.html">DBusError</a>        *error)
00735 {
00736   BusConnectionData *d;
00737   <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> uid;
00738   <a class="code" href="structDBusUserDatabase.html">DBusUserDatabase</a> *user_database;
00739   
00740   d = BUS_CONNECTION_DATA (connection);
00741 
00742   _dbus_assert (d != NULL);
00743 
00744   user_database = bus_context_get_user_database (d-&gt;connections-&gt;context);
00745   
00746   *groups = NULL;
00747   *n_groups = 0;
00748 
00749   <font class="keywordflow">if</font> (dbus_connection_get_unix_user (connection, &amp;uid))
00750     {
00751       <font class="keywordflow">if</font> (!_dbus_user_database_get_groups (user_database,
00752                                            uid, groups, n_groups,
00753                                            error))
00754         {
00755           _DBUS_ASSERT_ERROR_IS_SET (error);
00756           _dbus_verbose (<font class="stringliteral">"Did not get any groups for UID %lu\n"</font>,
00757                          uid);
00758           <font class="keywordflow">return</font> FALSE;
00759         }
00760       <font class="keywordflow">else</font>
00761         {
00762           _dbus_verbose (<font class="stringliteral">"Got %d groups for UID %lu\n"</font>,
00763                          *n_groups, uid);
00764           <font class="keywordflow">return</font> TRUE;
00765         }
00766     }
00767   <font class="keywordflow">else</font>
00768     <font class="keywordflow">return</font> TRUE; <font class="comment">/* successfully got 0 groups */</font>
00769 }
00770 
00771 dbus_bool_t
00772 bus_connection_is_in_group (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
00773                             <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font>   gid)
00774 {
00775   <font class="keywordtype">int</font> i;
00776   <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> *group_ids;
00777   <font class="keywordtype">int</font> n_group_ids;
00778 
00779   <font class="keywordflow">if</font> (!bus_connection_get_groups (connection, &amp;group_ids, &amp;n_group_ids,
00780                                   NULL))
00781     <font class="keywordflow">return</font> FALSE;
00782 
00783   i = 0;
00784   <font class="keywordflow">while</font> (i &lt; n_group_ids)
00785     {
00786       <font class="keywordflow">if</font> (group_ids[i] == gid)
00787         {
00788           dbus_free (group_ids);
00789           <font class="keywordflow">return</font> TRUE;
00790         }
00791       ++i;
00792     }
00793 
00794   dbus_free (group_ids);
00795   <font class="keywordflow">return</font> FALSE;
00796 }
00797 
00798 BusClientPolicy*
00799 bus_connection_get_policy (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
00800 {
00801   BusConnectionData *d;
00802     
00803   d = BUS_CONNECTION_DATA (connection);
00804 
00805   _dbus_assert (d != NULL);
00806   _dbus_assert (d-&gt;policy != NULL);
00807   
00808   <font class="keywordflow">return</font> d-&gt;policy;
00809 }
00810 
00811 <font class="keyword">static</font> dbus_bool_t
00812 foreach_active (BusConnections               *connections,
00813                 BusConnectionForeachFunction  function,
00814                 <font class="keywordtype">void</font>                         *data)
00815 {
00816   <a class="code" href="structDBusList.html">DBusList</a> *link;
00817   
00818   link = _dbus_list_get_first_link (&amp;connections-&gt;completed);
00819   <font class="keywordflow">while</font> (link != NULL)
00820     {
00821       <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection = link-&gt;<a class="code" href="structDBusList.html#m2">data</a>;
00822       <a class="code" href="structDBusList.html">DBusList</a> *next = _dbus_list_get_next_link (&amp;connections-&gt;completed, link);
00823 
00824       <font class="keywordflow">if</font> (!(* function) (connection, data))
00825         <font class="keywordflow">return</font> FALSE;
00826       
00827       link = next;
00828     }
00829 
00830   <font class="keywordflow">return</font> TRUE;
00831 }
00832 
00833 <font class="keyword">static</font> dbus_bool_t
00834 foreach_inactive (BusConnections               *connections,
00835                   BusConnectionForeachFunction  function,
00836                   <font class="keywordtype">void</font>                         *data)
00837 {
00838   <a class="code" href="structDBusList.html">DBusList</a> *link;
00839   
00840   link = _dbus_list_get_first_link (&amp;connections-&gt;incomplete);
00841   <font class="keywordflow">while</font> (link != NULL)
00842     {
00843       <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection = link-&gt;<a class="code" href="structDBusList.html#m2">data</a>;
00844       <a class="code" href="structDBusList.html">DBusList</a> *next = _dbus_list_get_next_link (&amp;connections-&gt;incomplete, link);
00845 
00846       <font class="keywordflow">if</font> (!(* function) (connection, data))
00847         <font class="keywordflow">return</font> FALSE;
00848       
00849       link = next;
00850     }
00851 
00852   <font class="keywordflow">return</font> TRUE;
00853 }
00854 
00864 <font class="keywordtype">void</font>
00865 bus_connections_foreach_active (BusConnections               *connections,
00866                                 BusConnectionForeachFunction  function,
00867                                 <font class="keywordtype">void</font>                         *data)
00868 {
00869   foreach_active (connections, function, data);
00870 }
00871 
00880 <font class="keywordtype">void</font>
00881 bus_connections_foreach (BusConnections               *connections,
00882                          BusConnectionForeachFunction  function,
00883                          <font class="keywordtype">void</font>                         *data)
00884 {
00885   <font class="keywordflow">if</font> (!foreach_active (connections, function, data))
00886     <font class="keywordflow">return</font>;
00887 
00888   foreach_inactive (connections, function, data);
00889 }
00890 
00891 BusContext*
00892 bus_connections_get_context (BusConnections *connections)
00893 {
00894   <font class="keywordflow">return</font> connections-&gt;context;
00895 }
00896 
00897 <font class="comment">/*</font>
00898 <font class="comment"> * This is used to avoid covering the same connection twice when</font>
00899 <font class="comment"> * traversing connections. Note that it assumes we will</font>
00900 <font class="comment"> * bus_connection_mark_stamp() each connection at least once per</font>
00901 <font class="comment"> * INT_MAX increments of the global stamp, or wraparound would break</font>
00902 <font class="comment"> * things.</font>
00903 <font class="comment"> */</font>
00904 <font class="keywordtype">void</font>
00905 bus_connections_increment_stamp (BusConnections *connections)
00906 {
00907   connections-&gt;stamp += 1;
00908 }
00909 
00910 <font class="comment">/* Mark connection with current stamp, return TRUE if it</font>
00911 <font class="comment"> * didn't already have that stamp</font>
00912 <font class="comment"> */</font>
00913 dbus_bool_t
00914 bus_connection_mark_stamp (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
00915 {
00916   BusConnectionData *d;
00917   
00918   d = BUS_CONNECTION_DATA (connection);
00919   
00920   _dbus_assert (d != NULL);
00921 
00922   <font class="keywordflow">if</font> (d-&gt;stamp == d-&gt;connections-&gt;stamp)
00923     <font class="keywordflow">return</font> FALSE;
00924   <font class="keywordflow">else</font>
00925     {
00926       d-&gt;stamp = d-&gt;connections-&gt;stamp;
00927       <font class="keywordflow">return</font> TRUE;
00928     }
00929 }
00930 
00931 BusContext*
00932 bus_connection_get_context (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
00933 {
00934   BusConnectionData *d;
00935 
00936   d = BUS_CONNECTION_DATA (connection);
00937 
00938   _dbus_assert (d != NULL);
00939 
00940   <font class="keywordflow">return</font> d-&gt;connections-&gt;context;
00941 }
00942 
00943 BusConnections*
00944 bus_connection_get_connections (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
00945 {
00946   BusConnectionData *d;
00947     
00948   d = BUS_CONNECTION_DATA (connection);
00949 
00950   _dbus_assert (d != NULL);
00951 
00952   <font class="keywordflow">return</font> d-&gt;connections;
00953 }
00954 
00955 BusRegistry*
00956 bus_connection_get_registry (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
00957 {
00958   BusConnectionData *d;
00959 
00960   d = BUS_CONNECTION_DATA (connection);
00961 
00962   _dbus_assert (d != NULL);
00963 
00964   <font class="keywordflow">return</font> bus_context_get_registry (d-&gt;connections-&gt;context);
00965 }
00966 
00967 BusActivation*
00968 bus_connection_get_activation (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
00969 {
00970   BusConnectionData *d;
00971 
00972   d = BUS_CONNECTION_DATA (connection);
00973 
00974   _dbus_assert (d != NULL);
00975 
00976   <font class="keywordflow">return</font> bus_context_get_activation (d-&gt;connections-&gt;context);
00977 }
00978 
00979 BusMatchmaker*
00980 bus_connection_get_matchmaker (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
00981 {
00982   BusConnectionData *d;
00983 
00984   d = BUS_CONNECTION_DATA (connection);
00985 
00986   _dbus_assert (d != NULL);
00987 
00988   <font class="keywordflow">return</font> bus_context_get_matchmaker (d-&gt;connections-&gt;context);
00989 }
00990 
00997 dbus_bool_t
00998 bus_connection_is_active (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
00999 {
01000   BusConnectionData *d;
01001 
01002   d = BUS_CONNECTION_DATA (connection);
01003   
01004   <font class="keywordflow">return</font> d != NULL &amp;&amp; d-&gt;name != NULL;
01005 }
01006 
01007 dbus_bool_t
01008 bus_connection_preallocate_oom_error (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
01009 {
01010   <a class="code" href="structDBusMessage.html">DBusMessage</a> *message;
01011   <a class="code" href="structDBusPreallocatedSend.html">DBusPreallocatedSend</a> *preallocated;
01012   BusConnectionData *d;
01013 
01014   d = BUS_CONNECTION_DATA (connection);  
01015 
01016   _dbus_assert (d != NULL);
01017 
01018   <font class="keywordflow">if</font> (d-&gt;oom_preallocated != NULL)
01019     <font class="keywordflow">return</font> TRUE;
01020   
01021   preallocated = dbus_connection_preallocate_send (connection);
01022   <font class="keywordflow">if</font> (preallocated == NULL)
01023     <font class="keywordflow">return</font> FALSE;
01024 
01025   message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
01026 
01027   <font class="keywordflow">if</font> (message == NULL)
01028     {
01029       dbus_connection_free_preallocated_send (connection, preallocated);
01030       <font class="keywordflow">return</font> FALSE;
01031     }
01032 
01033   <font class="comment">/* d-&gt;name may be NULL, but that is OK */</font>
01034   <font class="keywordflow">if</font> (!dbus_message_set_error_name (message, DBUS_ERROR_NO_MEMORY) ||
01035       !dbus_message_set_destination (message, d-&gt;name) ||
01036       !dbus_message_set_sender (message,
01037                                 DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
01038     {
01039       dbus_connection_free_preallocated_send (connection, preallocated);
01040       dbus_message_unref (message);
01041       <font class="keywordflow">return</font> FALSE;
01042     }
01043   
01044   <font class="comment">/* set reply serial to placeholder value just so space is already allocated</font>
01045 <font class="comment">   * for it.</font>
01046 <font class="comment">   */</font>
01047   <font class="keywordflow">if</font> (!dbus_message_set_reply_serial (message, 14))
01048     {
01049       dbus_connection_free_preallocated_send (connection, preallocated);
01050       dbus_message_unref (message);
01051       <font class="keywordflow">return</font> FALSE;
01052     }
01053 
01054   d-&gt;oom_message = message;
01055   d-&gt;oom_preallocated = preallocated;
01056   
01057   <font class="keywordflow">return</font> TRUE;
01058 }
01059 
01060 <font class="keywordtype">void</font>
01061 bus_connection_send_oom_error (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
01062                                <a class="code" href="structDBusMessage.html">DBusMessage</a>    *in_reply_to)
01063 {
01064   BusConnectionData *d;
01065 
01066   d = BUS_CONNECTION_DATA (connection);  
01067 
01068   _dbus_assert (d != NULL);  
01069   _dbus_assert (d-&gt;oom_message != NULL);
01070 
01071   <font class="comment">/* should always succeed since we set it to a placeholder earlier */</font>
01072   <font class="keywordflow">if</font> (!dbus_message_set_reply_serial (d-&gt;oom_message,
01073                                       dbus_message_get_serial (in_reply_to)))
01074     _dbus_assert_not_reached (<font class="stringliteral">"Failed to set reply serial for preallocated oom message"</font>);
01075 
01076   _dbus_assert (dbus_message_get_sender (d-&gt;oom_message) != NULL);
01077   
01078   dbus_connection_send_preallocated (connection, d-&gt;oom_preallocated,
01079                                      d-&gt;oom_message, NULL);
01080 
01081   dbus_message_unref (d-&gt;oom_message);
01082   d-&gt;oom_message = NULL;
01083   d-&gt;oom_preallocated = NULL;
01084 }
01085 
01086 <font class="keywordtype">void</font>
01087 bus_connection_add_match_rule_link (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
01088                                     <a class="code" href="structDBusList.html">DBusList</a>       *link)
01089 {
01090   BusConnectionData *d;
01091 
01092   d = BUS_CONNECTION_DATA (connection);
01093   _dbus_assert (d != NULL);
01094 
01095   _dbus_list_append_link (&amp;d-&gt;match_rules, link);
01096 
01097   d-&gt;n_match_rules += 1;
01098 }
01099 
01100 dbus_bool_t
01101 bus_connection_add_match_rule (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
01102                                BusMatchRule   *rule)
01103 {
01104     <a class="code" href="structDBusList.html">DBusList</a> *link;
01105 
01106   link = _dbus_list_alloc_link (rule);
01107 
01108   <font class="keywordflow">if</font> (link == NULL)
01109     <font class="keywordflow">return</font> FALSE;
01110 
01111   bus_connection_add_match_rule_link (connection, link);
01112 
01113   <font class="keywordflow">return</font> TRUE;
01114 }
01115 
01116 <font class="keywordtype">void</font>
01117 bus_connection_remove_match_rule (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
01118                                   BusMatchRule   *rule)
01119 {
01120   BusConnectionData *d;
01121 
01122   d = BUS_CONNECTION_DATA (connection);
01123   _dbus_assert (d != NULL);
01124 
01125   _dbus_list_remove_last (&amp;d-&gt;match_rules, rule);
01126 
01127   d-&gt;n_match_rules -= 1;
01128   _dbus_assert (d-&gt;n_match_rules &gt;= 0);
01129 }
01130 
01131 <font class="keywordtype">int</font>
01132 bus_connection_get_n_match_rules (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
01133 {
01134   BusConnectionData *d;
01135 
01136   d = BUS_CONNECTION_DATA (connection);
01137   _dbus_assert (d != NULL);
01138   
01139   <font class="keywordflow">return</font> d-&gt;n_match_rules;
01140 }
01141 
01142 <font class="keywordtype">void</font>
01143 bus_connection_add_owned_service_link (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
01144                                        <a class="code" href="structDBusList.html">DBusList</a>       *link)
01145 {
01146   BusConnectionData *d;
01147 
01148   d = BUS_CONNECTION_DATA (connection);
01149   _dbus_assert (d != NULL);
01150 
01151   _dbus_list_append_link (&amp;d-&gt;services_owned, link);
01152 
01153   d-&gt;n_services_owned += 1;
01154 }
01155 
01156 dbus_bool_t
01157 bus_connection_add_owned_service (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
01158                                   BusService     *service)
01159 {
01160   <a class="code" href="structDBusList.html">DBusList</a> *link;
01161 
01162   link = _dbus_list_alloc_link (service);
01163 
01164   <font class="keywordflow">if</font> (link == NULL)
01165     <font class="keywordflow">return</font> FALSE;
01166 
01167   bus_connection_add_owned_service_link (connection, link);
01168 
01169   <font class="keywordflow">return</font> TRUE;
01170 }
01171 
01172 <font class="keywordtype">void</font>
01173 bus_connection_remove_owned_service (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
01174                                      BusService     *service)
01175 {
01176   BusConnectionData *d;
01177 
01178   d = BUS_CONNECTION_DATA (connection);
01179   _dbus_assert (d != NULL);
01180 
01181   _dbus_list_remove_last (&amp;d-&gt;services_owned, service);
01182 
01183   d-&gt;n_services_owned -= 1;
01184   _dbus_assert (d-&gt;n_services_owned &gt;= 0);
01185 }
01186 
01187 <font class="keywordtype">int</font>
01188 bus_connection_get_n_services_owned (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
01189 {
01190   BusConnectionData *d;
01191 
01192   d = BUS_CONNECTION_DATA (connection);
01193   _dbus_assert (d != NULL);
01194   
01195   <font class="keywordflow">return</font> d-&gt;n_services_owned;
01196 }
01197 
01198 dbus_bool_t
01199 bus_connection_complete (<a class="code" href="structDBusConnection.html">DBusConnection</a>   *connection,
01200                          <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *name,
01201                          <a class="code" href="structDBusError.html">DBusError</a>        *error)
01202 {
01203   BusConnectionData *d;
01204   <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> uid;
01205   
01206   d = BUS_CONNECTION_DATA (connection);
01207   _dbus_assert (d != NULL);
01208   _dbus_assert (d-&gt;name == NULL);
01209   _dbus_assert (d-&gt;policy == NULL);
01210 
01211   _dbus_assert (!bus_connection_is_active (connection));
01212   
01213   <font class="keywordflow">if</font> (!_dbus_string_copy_data (name, &amp;d-&gt;name))
01214     {
01215       BUS_SET_OOM (error);
01216       <font class="keywordflow">return</font> FALSE;
01217     }
01218 
01219   _dbus_assert (d-&gt;name != NULL);
01220   
01221   _dbus_verbose (<font class="stringliteral">"Name %s assigned to %p\n"</font>, d-&gt;name, connection);
01222 
01223   d-&gt;policy = bus_context_create_client_policy (d-&gt;connections-&gt;context,
01224                                                 connection,
01225                                                 error);
01226 
01227   <font class="comment">/* we may have a NULL policy on OOM or error getting list of</font>
01228 <font class="comment">   * groups for a user. In the latter case we don't handle it so</font>
01229 <font class="comment">   * well currently, as it will just keep failing over and over.</font>
01230 <font class="comment">   */</font>
01231 
01232   <font class="keywordflow">if</font> (d-&gt;policy == NULL)
01233     {
01234       _dbus_verbose (<font class="stringliteral">"Failed to create security policy for connection %p\n"</font>,
01235                      connection);
01236       _DBUS_ASSERT_ERROR_IS_SET (error);
01237       dbus_free (d-&gt;name);
01238       d-&gt;name = NULL;
01239       <font class="keywordflow">return</font> FALSE;
01240     }
01241   
01242   <font class="keywordflow">if</font> (dbus_connection_get_unix_user (connection, &amp;uid))
01243     {
01244       <font class="keywordflow">if</font> (!adjust_connections_for_uid (d-&gt;connections,
01245                                        uid, 1))
01246         {
01247           BUS_SET_OOM (error);
01248           dbus_free (d-&gt;name);
01249           d-&gt;name = NULL;
01250           <font class="keywordflow">return</font> FALSE;
01251         }
01252     }
01253   
01254   <font class="comment">/* Now the connection is active, move it between lists */</font>
01255   _dbus_list_unlink (&amp;d-&gt;connections-&gt;incomplete,
01256                      d-&gt;link_in_connection_list);
01257   d-&gt;connections-&gt;n_incomplete -= 1;
01258   _dbus_list_append_link (&amp;d-&gt;connections-&gt;completed,
01259                           d-&gt;link_in_connection_list);
01260   d-&gt;connections-&gt;n_completed += 1;
01261 
01262   _dbus_assert (d-&gt;connections-&gt;n_incomplete &gt;= 0);
01263   _dbus_assert (d-&gt;connections-&gt;n_completed &gt; 0);
01264 
01265   <font class="comment">/* See if we can remove the timeout */</font>
01266   bus_connections_expire_incomplete (d-&gt;connections);
01267 
01268   _dbus_assert (bus_connection_is_active (connection));
01269   
01270   <font class="keywordflow">return</font> TRUE;
01271 }
01272 
01273 <font class="keyword">const</font> <font class="keywordtype">char</font> *
01274 bus_connection_get_name (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
01275 {
01276   BusConnectionData *d;
01277   
01278   d = BUS_CONNECTION_DATA (connection);
01279   _dbus_assert (d != NULL);
01280   
01281   <font class="keywordflow">return</font> d-&gt;name;
01282 }
01283 
01288 dbus_bool_t
01289 bus_connections_check_limits (BusConnections  *connections,
01290                               <a class="code" href="structDBusConnection.html">DBusConnection</a>  *requesting_completion,
01291                               <a class="code" href="structDBusError.html">DBusError</a>       *error)
01292 {
01293   BusConnectionData *d;
01294   <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> uid;
01295   
01296   d = BUS_CONNECTION_DATA (requesting_completion);
01297   _dbus_assert (d != NULL);
01298 
01299   _dbus_assert (d-&gt;name == NULL);
01300 
01301   <font class="keywordflow">if</font> (connections-&gt;n_completed &gt;=
01302       bus_context_get_max_completed_connections (connections-&gt;context))
01303     {
01304       dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
01305                       <font class="stringliteral">"The maximum number of active connections has been reached"</font>);
01306       <font class="keywordflow">return</font> FALSE;
01307     }
01308   
01309   <font class="keywordflow">if</font> (dbus_connection_get_unix_user (requesting_completion, &amp;uid))
01310     {
01311       <font class="keywordflow">if</font> (get_connections_for_uid (connections, uid) &gt;=
01312           bus_context_get_max_connections_per_user (connections-&gt;context))
01313         {
01314           dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
01315                           <font class="stringliteral">"The maximum number of active connections for UID %lu has been reached"</font>,
01316                           uid);
01317           <font class="keywordflow">return</font> FALSE;
01318         }
01319     }
01320   
01321   <font class="keywordflow">return</font> TRUE;
01322 }
01323 
01324 
01325 <font class="comment">/*</font>
01326 <font class="comment"> * Transactions</font>
01327 <font class="comment"> *</font>
01328 <font class="comment"> * Note that this is fairly fragile; in particular, don't try to use</font>
01329 <font class="comment"> * one transaction across any main loop iterations.</font>
01330 <font class="comment"> */</font>
01331 
01332 <font class="keyword">typedef</font> <font class="keyword">struct</font>
01333 <font class="keyword"></font>{
01334   BusTransaction *transaction;
01335   <a class="code" href="structDBusMessage.html">DBusMessage</a>    *message;
01336   <a class="code" href="structDBusPreallocatedSend.html">DBusPreallocatedSend</a> *preallocated;
01337 } MessageToSend;
01338 
01339 <font class="keyword">typedef</font> <font class="keyword">struct</font>
01340 <font class="keyword"></font>{
01341   BusTransactionCancelFunction cancel_function;
01342   DBusFreeFunction free_data_function;
01343   <font class="keywordtype">void</font> *data;
01344 } CancelHook;
01345 
01346 <font class="keyword">struct </font>BusTransaction
01347 {
01348   <a class="code" href="structDBusList.html">DBusList</a> *connections;
01349   BusContext *context;
01350   <a class="code" href="structDBusList.html">DBusList</a> *cancel_hooks;
01351 };
01352 
01353 <font class="keyword">static</font> <font class="keywordtype">void</font>
01354 message_to_send_free (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
01355                       MessageToSend  *to_send)
01356 {
01357   <font class="keywordflow">if</font> (to_send-&gt;message)
01358     dbus_message_unref (to_send-&gt;message);
01359 
01360   <font class="keywordflow">if</font> (to_send-&gt;preallocated)
01361     dbus_connection_free_preallocated_send (connection, to_send-&gt;preallocated);
01362 
01363   dbus_free (to_send);
01364 }
01365 
01366 <font class="keyword">static</font> <font class="keywordtype">void</font>
01367 cancel_hook_cancel (<font class="keywordtype">void</font> *element,
01368                     <font class="keywordtype">void</font> *data)
01369 {
01370   CancelHook *ch = element;
01371 
01372   _dbus_verbose (<font class="stringliteral">"Running transaction cancel hook\n"</font>);
01373   
01374   <font class="keywordflow">if</font> (ch-&gt;cancel_function)
01375     (* ch-&gt;cancel_function) (ch-&gt;data);  
01376 }
01377 
01378 <font class="keyword">static</font> <font class="keywordtype">void</font>
01379 cancel_hook_free (<font class="keywordtype">void</font> *element,
01380                   <font class="keywordtype">void</font> *data)
01381 {
01382   CancelHook *ch = element;
01383 
01384   <font class="keywordflow">if</font> (ch-&gt;free_data_function)
01385     (* ch-&gt;free_data_function) (ch-&gt;data);
01386 
01387   dbus_free (ch);
01388 }
01389 
01390 <font class="keyword">static</font> <font class="keywordtype">void</font>
01391 free_cancel_hooks (BusTransaction *transaction)
01392 {
01393   _dbus_list_foreach (&amp;transaction-&gt;cancel_hooks,
01394                       cancel_hook_free, NULL);
01395   
01396   _dbus_list_clear (&amp;transaction-&gt;cancel_hooks);
01397 }
01398 
01399 BusTransaction*
01400 bus_transaction_new (BusContext *context)
01401 {
01402   BusTransaction *transaction;
01403 
01404   transaction = dbus_new0 (BusTransaction, 1);
01405   <font class="keywordflow">if</font> (transaction == NULL)
01406     <font class="keywordflow">return</font> NULL;
01407 
01408   transaction-&gt;context = context;
01409   
01410   <font class="keywordflow">return</font> transaction;
01411 }
01412 
01413 BusContext*
01414 bus_transaction_get_context (BusTransaction  *transaction)
01415 {
01416   <font class="keywordflow">return</font> transaction-&gt;context;
01417 }
01418 
01419 BusConnections*
01420 bus_transaction_get_connections (BusTransaction  *transaction)
01421 {
01422   <font class="keywordflow">return</font> bus_context_get_connections (transaction-&gt;context);
01423 }
01424 
01425 dbus_bool_t
01426 bus_transaction_send_from_driver (BusTransaction *transaction,
01427                                   <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
01428                                   <a class="code" href="structDBusMessage.html">DBusMessage</a>    *message)
01429 {
01430   <font class="comment">/* We have to set the sender to the driver, and have</font>
01431 <font class="comment">   * to check security policy since it was not done in</font>
01432 <font class="comment">   * dispatch.c</font>
01433 <font class="comment">   */</font>
01434   _dbus_verbose (<font class="stringliteral">"Sending %s %s %s from driver\n"</font>,
01435                  dbus_message_get_interface (message) ?
01436                  dbus_message_get_interface (message) : "(no interface)",
01437                  dbus_message_get_member (message) ?
01438                  dbus_message_get_member (message) : "(no member)",
01439                  dbus_message_get_error_name (message) ?
01440                  dbus_message_get_error_name (message) : "(no error name)");
01441                  
01442   <font class="keywordflow">if</font> (!dbus_message_set_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
01443     <font class="keywordflow">return</font> FALSE;
01444 
01445   <font class="comment">/* If security policy doesn't allow the message, we silently</font>
01446 <font class="comment">   * eat it; the driver doesn't care about getting a reply.</font>
01447 <font class="comment">   */</font>
01448   <font class="keywordflow">if</font> (!bus_context_check_security_policy (bus_transaction_get_context (transaction),
01449                                           NULL, connection, connection, message, NULL))
01450     <font class="keywordflow">return</font> TRUE;
01451 
01452   <font class="keywordflow">return</font> bus_transaction_send (transaction, connection, message);
01453 }
01454 
01455 dbus_bool_t
01456 bus_transaction_send (BusTransaction *transaction,
01457                       <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
01458                       <a class="code" href="structDBusMessage.html">DBusMessage</a>    *message)
01459 {
01460   MessageToSend *to_send;
01461   BusConnectionData *d;
01462   <a class="code" href="structDBusList.html">DBusList</a> *link;
01463 
01464   _dbus_verbose (<font class="stringliteral">"  trying to add %s interface=%s member=%s error=%s to transaction%s\n"</font>,
01465                  dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR ? <font class="stringliteral">"error"</font> :
01466                  dbus_message_get_reply_serial (message) != 0 ? <font class="stringliteral">"reply"</font> :
01467                  <font class="stringliteral">"message"</font>,
01468                  dbus_message_get_interface (message) ?
01469                  dbus_message_get_interface (message) : "(unset)",
01470                  dbus_message_get_member (message) ?
01471                  dbus_message_get_member (message) : "(unset)",
01472                  dbus_message_get_error_name (message) ?
01473                  dbus_message_get_error_name (message) : "(unset)",
01474                  dbus_connection_get_is_connected (connection) ?
01475                  "" : " (disconnected)");
01476 
01477   _dbus_assert (dbus_message_get_sender (message) != NULL);
01478   
01479   <font class="keywordflow">if</font> (!dbus_connection_get_is_connected (connection))
01480     <font class="keywordflow">return</font> TRUE; <font class="comment">/* silently ignore disconnected connections */</font>
01481   
01482   d = BUS_CONNECTION_DATA (connection);
01483   _dbus_assert (d != NULL);
01484   
01485   to_send = dbus_new (MessageToSend, 1);
01486   <font class="keywordflow">if</font> (to_send == NULL)
01487     {
01488       <font class="keywordflow">return</font> FALSE;
01489     }
01490 
01491   to_send-&gt;preallocated = dbus_connection_preallocate_send (connection);
01492   <font class="keywordflow">if</font> (to_send-&gt;preallocated == NULL)
01493     {
01494       dbus_free (to_send);
01495       <font class="keywordflow">return</font> FALSE;
01496     }  
01497   
01498   dbus_message_ref (message);
01499   to_send-&gt;message = message;
01500   to_send-&gt;transaction = transaction;
01501 
01502   _dbus_verbose (<font class="stringliteral">"about to prepend message\n"</font>);
01503   
01504   <font class="keywordflow">if</font> (!_dbus_list_prepend (&amp;d-&gt;transaction_messages, to_send))
01505     {
01506       message_to_send_free (connection, to_send);
01507       <font class="keywordflow">return</font> FALSE;
01508     }
01509 
01510   _dbus_verbose (<font class="stringliteral">"prepended message\n"</font>);
01511   
01512   <font class="comment">/* See if we already had this connection in the list</font>
01513 <font class="comment">   * for this transaction. If we have a pending message,</font>
01514 <font class="comment">   * then we should already be in transaction-&gt;connections</font>
01515 <font class="comment">   */</font>
01516   link = _dbus_list_get_first_link (&amp;d-&gt;transaction_messages);
01517   _dbus_assert (link-&gt;<a class="code" href="structDBusList.html#m2">data</a> == to_send);
01518   link = _dbus_list_get_next_link (&amp;d-&gt;transaction_messages, link);
01519   <font class="keywordflow">while</font> (link != NULL)
01520     {
01521       MessageToSend *m = link-&gt;<a class="code" href="structDBusList.html#m2">data</a>;
01522       <a class="code" href="structDBusList.html">DBusList</a> *next = _dbus_list_get_next_link (&amp;d-&gt;transaction_messages, link);
01523       
01524       <font class="keywordflow">if</font> (m-&gt;transaction == transaction)
01525         <font class="keywordflow">break</font>;
01526         
01527       link = next;
01528     }
01529 
01530   <font class="keywordflow">if</font> (link == NULL)
01531     {
01532       <font class="keywordflow">if</font> (!_dbus_list_prepend (&amp;transaction-&gt;connections, connection))
01533         {
01534           _dbus_list_remove (&amp;d-&gt;transaction_messages, to_send);
01535           message_to_send_free (connection, to_send);
01536           <font class="keywordflow">return</font> FALSE;
01537         }
01538     }
01539 
01540   <font class="keywordflow">return</font> TRUE;
01541 }
01542 
01543 <font class="keyword">static</font> <font class="keywordtype">void</font>
01544 connection_cancel_transaction (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
01545                                BusTransaction *transaction)
01546 {
01547   <a class="code" href="structDBusList.html">DBusList</a> *link;
01548   BusConnectionData *d;
01549   
01550   d = BUS_CONNECTION_DATA (connection);
01551   _dbus_assert (d != NULL);
01552   
01553   link = _dbus_list_get_first_link (&amp;d-&gt;transaction_messages);
01554   <font class="keywordflow">while</font> (link != NULL)
01555     {
01556       MessageToSend *m = link-&gt;<a class="code" href="structDBusList.html#m2">data</a>;
01557       <a class="code" href="structDBusList.html">DBusList</a> *next = _dbus_list_get_next_link (&amp;d-&gt;transaction_messages, link);
01558       
01559       <font class="keywordflow">if</font> (m-&gt;transaction == transaction)
01560         {
01561           _dbus_list_remove_link (&amp;d-&gt;transaction_messages,
01562                                   link);
01563           
01564           message_to_send_free (connection, m);
01565         }
01566         
01567       link = next;
01568     }
01569 }
01570 
01571 <font class="keywordtype">void</font>
01572 bus_transaction_cancel_and_free (BusTransaction *transaction)
01573 {
01574   <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection;
01575 
01576   _dbus_verbose (<font class="stringliteral">"TRANSACTION: cancelled\n"</font>);
01577   
01578   <font class="keywordflow">while</font> ((connection = _dbus_list_pop_first (&amp;transaction-&gt;connections)))
01579     connection_cancel_transaction (connection, transaction);
01580 
01581   _dbus_assert (transaction-&gt;connections == NULL);
01582 
01583   _dbus_list_foreach (&amp;transaction-&gt;cancel_hooks,
01584                       cancel_hook_cancel, NULL);
01585 
01586   free_cancel_hooks (transaction);
01587   
01588   dbus_free (transaction);
01589 }
01590 
01591 <font class="keyword">static</font> <font class="keywordtype">void</font>
01592 connection_execute_transaction (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
01593                                 BusTransaction *transaction)
01594 {
01595   <a class="code" href="structDBusList.html">DBusList</a> *link;
01596   BusConnectionData *d;
01597   
01598   d = BUS_CONNECTION_DATA (connection);
01599   _dbus_assert (d != NULL);
01600 
01601   <font class="comment">/* Send the queue in order (FIFO) */</font>
01602   link = _dbus_list_get_last_link (&amp;d-&gt;transaction_messages);
01603   <font class="keywordflow">while</font> (link != NULL)
01604     {
01605       MessageToSend *m = link-&gt;<a class="code" href="structDBusList.html#m2">data</a>;
01606       <a class="code" href="structDBusList.html">DBusList</a> *prev = _dbus_list_get_prev_link (&amp;d-&gt;transaction_messages, link);
01607       
01608       <font class="keywordflow">if</font> (m-&gt;transaction == transaction)
01609         {
01610           _dbus_list_remove_link (&amp;d-&gt;transaction_messages,
01611                                   link);
01612 
01613           _dbus_assert (dbus_message_get_sender (m-&gt;message) != NULL);
01614           
01615           dbus_connection_send_preallocated (connection,
01616                                              m-&gt;preallocated,
01617                                              m-&gt;message,
01618                                              NULL);
01619 
01620           m-&gt;preallocated = NULL; <font class="comment">/* so we don't double-free it */</font>
01621           
01622           message_to_send_free (connection, m);
01623         }
01624         
01625       link = prev;
01626     }
01627 }
01628 
01629 <font class="keywordtype">void</font>
01630 bus_transaction_execute_and_free (BusTransaction *transaction)
01631 {
01632   <font class="comment">/* For each connection in transaction-&gt;connections</font>
01633 <font class="comment">   * send the messages</font>
01634 <font class="comment">   */</font>
01635   <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection;
01636 
01637   _dbus_verbose (<font class="stringliteral">"TRANSACTION: executing\n"</font>);
01638   
01639   <font class="keywordflow">while</font> ((connection = _dbus_list_pop_first (&amp;transaction-&gt;connections)))
01640     connection_execute_transaction (connection, transaction);
01641 
01642   _dbus_assert (transaction-&gt;connections == NULL);
01643 
01644   free_cancel_hooks (transaction);
01645   
01646   dbus_free (transaction);
01647 }
01648 
01649 <font class="keyword">static</font> <font class="keywordtype">void</font>
01650 bus_connection_remove_transactions (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection)
01651 {
01652   MessageToSend *to_send;
01653   BusConnectionData *d;
01654   
01655   d = BUS_CONNECTION_DATA (connection);
01656   _dbus_assert (d != NULL);
01657   
01658   <font class="keywordflow">while</font> ((to_send = _dbus_list_get_first (&amp;d-&gt;transaction_messages)))
01659     {
01660       <font class="comment">/* only has an effect for the first MessageToSend listing this transaction */</font>
01661       _dbus_list_remove (&amp;to_send-&gt;transaction-&gt;connections,
01662                          connection);
01663 
01664       _dbus_list_remove (&amp;d-&gt;transaction_messages, to_send);
01665       message_to_send_free (connection, to_send);
01666     }
01667 }
01668 
01672 dbus_bool_t
01673 bus_transaction_send_error_reply (BusTransaction  *transaction,
01674                                   <a class="code" href="structDBusConnection.html">DBusConnection</a>  *connection,
01675                                   <font class="keyword">const</font> <a class="code" href="structDBusError.html">DBusError</a> *error,
01676                                   <a class="code" href="structDBusMessage.html">DBusMessage</a>     *in_reply_to)
01677 {
01678   <a class="code" href="structDBusMessage.html">DBusMessage</a> *reply;
01679   
01680   _dbus_assert (error != NULL);
01681   _DBUS_ASSERT_ERROR_IS_SET (error);
01682   
01683   _dbus_verbose (<font class="stringliteral">"Sending error reply %s \"%s\"\n"</font>,
01684                  error-&gt;<a class="code" href="structDBusError.html#m0">name</a>, error-&gt;<a class="code" href="structDBusError.html#m1">message</a>);
01685 
01686   reply = dbus_message_new_error (in_reply_to,
01687                                   error-&gt;<a class="code" href="structDBusError.html#m0">name</a>,
01688                                   error-&gt;<a class="code" href="structDBusError.html#m1">message</a>);
01689   <font class="keywordflow">if</font> (reply == NULL)
01690     <font class="keywordflow">return</font> FALSE;
01691 
01692   <font class="keywordflow">if</font> (!bus_transaction_send_from_driver (transaction, connection, reply))
01693     {
01694       dbus_message_unref (reply);
01695       <font class="keywordflow">return</font> FALSE;
01696     }
01697 
01698   dbus_message_unref (reply);
01699   
01700   <font class="keywordflow">return</font> TRUE;
01701 }
01702 
01703 dbus_bool_t
01704 bus_transaction_add_cancel_hook (BusTransaction               *transaction,
01705                                  BusTransactionCancelFunction  cancel_function,
01706                                  <font class="keywordtype">void</font>                         *data,
01707                                  DBusFreeFunction              free_data_function)
01708 {
01709   CancelHook *ch;
01710 
01711   ch = dbus_new (CancelHook, 1);
01712   <font class="keywordflow">if</font> (ch == NULL)
01713     <font class="keywordflow">return</font> FALSE;
01714   
01715   ch-&gt;cancel_function = cancel_function;
01716   ch-&gt;data = data;
01717   ch-&gt;free_data_function = free_data_function;
01718 
01719   <font class="comment">/* It's important that the hooks get run in reverse order that they</font>
01720 <font class="comment">   * were added</font>
01721 <font class="comment">   */</font>
01722   <font class="keywordflow">if</font> (!_dbus_list_prepend (&amp;transaction-&gt;cancel_hooks, ch))
01723     {
01724       dbus_free (ch);
01725       <font class="keywordflow">return</font> FALSE;
01726     }
01727 
01728   <font class="keywordflow">return</font> TRUE;
01729 }
</pre></div><hr><address align="right"><small>Generated on Mon Sep 29 21:30:59 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>