forgot to add files...
[platform/upstream/dbus.git] / bus / connection.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* connection.c  Client connections
3  *
4  * Copyright (C) 2003  Red Hat, Inc.
5  *
6  * Licensed under the Academic Free License version 1.2
7  * 
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  * 
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  */
23 #include "connection.h"
24 #include "dispatch.h"
25 #include "policy.h"
26 #include "services.h"
27 #include "utils.h"
28 #include "signals.h"
29 #include <dbus/dbus-list.h>
30 #include <dbus/dbus-hash.h>
31 #include <dbus/dbus-timeout.h>
32
33 static void bus_connection_remove_transactions (DBusConnection *connection);
34
35 struct BusConnections
36 {
37   int refcount;
38   DBusList *completed;  /**< List of all completed connections */
39   int n_completed;      /**< Length of completed list */
40   DBusList *incomplete; /**< List of all not-yet-active connections */
41   int n_incomplete;     /**< Length of incomplete list */
42   BusContext *context;
43   DBusHashTable *completed_by_user; /**< Number of completed connections for each UID */
44   DBusTimeout *expire_timeout; /**< Timeout for expiring incomplete connections. */
45   int stamp;            /**< Incrementing number */
46 };
47
48 static dbus_int32_t connection_data_slot = -1;
49
50 typedef struct
51 {
52   BusConnections *connections;
53   DBusList *link_in_connection_list;
54   DBusConnection *connection;
55   DBusList *services_owned;
56   int n_services_owned;
57   DBusList *match_rules;
58   int n_match_rules;
59   char *name;
60   DBusList *transaction_messages; /**< Stuff we need to send as part of a transaction */
61   DBusMessage *oom_message;
62   DBusPreallocatedSend *oom_preallocated;
63   BusClientPolicy *policy;
64
65   long connection_tv_sec;  /**< Time when we connected (seconds component) */
66   long connection_tv_usec; /**< Time when we connected (microsec component) */
67   int stamp;               /**< connections->stamp last time we were traversed */
68 } BusConnectionData;
69
70 static dbus_bool_t expire_incomplete_timeout (void *data);
71
72 #define BUS_CONNECTION_DATA(connection) (dbus_connection_get_data ((connection), connection_data_slot))
73
74 static DBusLoop*
75 connection_get_loop (DBusConnection *connection)
76 {
77   BusConnectionData *d;
78
79   d = BUS_CONNECTION_DATA (connection);
80
81   return bus_context_get_loop (d->connections->context);
82 }
83
84
85 static int
86 get_connections_for_uid (BusConnections *connections,
87                          dbus_uid_t      uid)
88 {
89   void *val;
90   int current_count;
91
92   /* val is NULL is 0 when it isn't in the hash yet */
93   
94   val = _dbus_hash_table_lookup_ulong (connections->completed_by_user,
95                                        uid);
96
97   current_count = _DBUS_POINTER_TO_INT (val);
98
99   return current_count;
100 }
101
102 static dbus_bool_t
103 adjust_connections_for_uid (BusConnections *connections,
104                             dbus_uid_t      uid,
105                             int             adjustment)
106 {
107   int current_count;
108
109   current_count = get_connections_for_uid (connections, uid);
110
111   _dbus_verbose ("Adjusting connection count for UID " DBUS_UID_FORMAT
112                  ": was %d adjustment %d making %d\n",
113                  uid, current_count, adjustment, current_count + adjustment);
114   
115   _dbus_assert (current_count >= 0);
116   
117   current_count += adjustment;
118
119   _dbus_assert (current_count >= 0);
120
121   if (current_count == 0)
122     {
123       _dbus_hash_table_remove_ulong (connections->completed_by_user, uid);
124       return TRUE;
125     }
126   else
127     {
128       dbus_bool_t retval;
129       
130       retval = _dbus_hash_table_insert_ulong (connections->completed_by_user,
131                                               uid, _DBUS_INT_TO_POINTER (current_count));
132
133       /* only positive adjustment can fail as otherwise
134        * a hash entry should already exist
135        */
136       _dbus_assert (adjustment > 0 ||
137                     (adjustment <= 0 && retval));
138
139       return retval;
140     }
141 }
142
143 void
144 bus_connection_disconnected (DBusConnection *connection)
145 {
146   BusConnectionData *d;
147   BusService *service;
148   BusMatchmaker *matchmaker;
149   
150   d = BUS_CONNECTION_DATA (connection);
151   _dbus_assert (d != NULL);
152
153   _dbus_verbose ("%s disconnected, dropping all service ownership and releasing\n",
154                  d->name ? d->name : "(inactive)");
155
156   /* Delete our match rules */
157   if (d->n_match_rules > 0)
158     {
159       matchmaker = bus_context_get_matchmaker (d->connections->context);
160       bus_matchmaker_disconnected (matchmaker, connection);
161     }
162   
163   /* Drop any service ownership. FIXME Unfortunately, this requires
164    * memory allocation and there doesn't seem to be a good way to
165    * handle it other than sleeping; we can't "fail" the operation of
166    * disconnecting a client, and preallocating a broadcast "service is
167    * now gone" message for every client-service pair seems kind of
168    * involved. Probably we need to do that though.
169    */
170   while ((service = _dbus_list_get_last (&d->services_owned)))
171     {
172       BusTransaction *transaction;
173       DBusError error;
174
175     retry:
176       
177       dbus_error_init (&error);
178         
179       transaction = NULL;
180       while (transaction == NULL)
181         {
182           transaction = bus_transaction_new (d->connections->context);
183           _dbus_wait_for_memory ();
184         }
185         
186       if (!bus_service_remove_owner (service, connection,
187                                      transaction, &error))
188         {
189           _DBUS_ASSERT_ERROR_IS_SET (&error);
190           
191           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
192             {
193               dbus_error_free (&error);
194               bus_transaction_cancel_and_free (transaction);
195               _dbus_wait_for_memory ();
196               goto retry;
197             }
198           else
199             {
200               _dbus_verbose ("Failed to remove service owner: %s %s\n",
201                              error.name, error.message);
202               _dbus_assert_not_reached ("Removing service owner failed for non-memory-related reason");
203             }
204         }
205         
206       bus_transaction_execute_and_free (transaction);
207     }
208
209   bus_dispatch_remove_connection (connection);
210   
211   /* no more watching */
212   if (!dbus_connection_set_watch_functions (connection,
213                                             NULL, NULL, NULL,
214                                             connection,
215                                             NULL))
216     _dbus_assert_not_reached ("setting watch functions to NULL failed");
217
218   if (!dbus_connection_set_timeout_functions (connection,
219                                               NULL, NULL, NULL,
220                                               connection,
221                                               NULL))
222     _dbus_assert_not_reached ("setting timeout functions to NULL failed");
223   
224   dbus_connection_set_unix_user_function (connection,
225                                           NULL, NULL, NULL);
226
227   dbus_connection_set_dispatch_status_function (connection,
228                                                 NULL, NULL, NULL);
229   
230   bus_connection_remove_transactions (connection);
231
232   if (d->link_in_connection_list != NULL)
233     {
234       if (d->name != NULL)
235         {
236           unsigned long uid;
237           
238           _dbus_list_remove_link (&d->connections->completed, d->link_in_connection_list);
239           d->link_in_connection_list = NULL;
240           d->connections->n_completed -= 1;
241
242           if (dbus_connection_get_unix_user (connection, &uid))
243             {
244               if (!adjust_connections_for_uid (d->connections,
245                                                uid, -1))
246                 _dbus_assert_not_reached ("adjusting downward should never fail");
247             }
248         }
249       else
250         {
251           _dbus_list_remove_link (&d->connections->incomplete, d->link_in_connection_list);
252           d->link_in_connection_list = NULL;
253           d->connections->n_incomplete -= 1;
254         }
255       
256       _dbus_assert (d->connections->n_incomplete >= 0);
257       _dbus_assert (d->connections->n_completed >= 0);
258     }
259   
260   /* frees "d" as side effect */
261   dbus_connection_set_data (connection,
262                             connection_data_slot,
263                             NULL, NULL);
264
265   dbus_connection_unref (connection);
266 }
267
268 static dbus_bool_t
269 connection_watch_callback (DBusWatch     *watch,
270                            unsigned int   condition,
271                            void          *data)
272 {
273  /* FIXME this can be done in dbus-mainloop.c
274   * if the code in activation.c for the babysitter
275   * watch handler is fixed.
276   */
277   
278 #if 0
279   _dbus_verbose ("Calling handle_watch\n");
280 #endif
281   return dbus_watch_handle (watch, condition);
282 }
283
284 static dbus_bool_t
285 add_connection_watch (DBusWatch      *watch,
286                       void           *data)
287 {
288   DBusConnection *connection = data;
289
290   return _dbus_loop_add_watch (connection_get_loop (connection),
291                                watch, connection_watch_callback, connection,
292                                NULL);
293 }
294
295 static void
296 remove_connection_watch (DBusWatch      *watch,
297                          void           *data)
298 {
299   DBusConnection *connection = data;
300   
301   _dbus_loop_remove_watch (connection_get_loop (connection),
302                            watch, connection_watch_callback, connection);
303 }
304
305 static void
306 connection_timeout_callback (DBusTimeout   *timeout,
307                              void          *data)
308 {
309   /* DBusConnection *connection = data; */
310
311   /* can return FALSE on OOM but we just let it fire again later */
312   dbus_timeout_handle (timeout);
313 }
314
315 static dbus_bool_t
316 add_connection_timeout (DBusTimeout    *timeout,
317                         void           *data)
318 {
319   DBusConnection *connection = data;
320   
321   return _dbus_loop_add_timeout (connection_get_loop (connection),
322                                  timeout, connection_timeout_callback, connection, NULL);
323 }
324
325 static void
326 remove_connection_timeout (DBusTimeout    *timeout,
327                            void           *data)
328 {
329   DBusConnection *connection = data;
330   
331   _dbus_loop_remove_timeout (connection_get_loop (connection),
332                              timeout, connection_timeout_callback, connection);
333 }
334
335 static void
336 dispatch_status_function (DBusConnection    *connection,
337                           DBusDispatchStatus new_status,
338                           void              *data)
339 {
340   DBusLoop *loop = data;
341   
342   if (new_status != DBUS_DISPATCH_COMPLETE)
343     {
344       while (!_dbus_loop_queue_dispatch (loop, connection))
345         _dbus_wait_for_memory ();
346     }
347 }
348
349 static dbus_bool_t
350 allow_user_function (DBusConnection *connection,
351                      unsigned long   uid,
352                      void           *data)
353 {
354   BusConnectionData *d;
355     
356   d = BUS_CONNECTION_DATA (connection);
357
358   _dbus_assert (d != NULL);
359   
360   return bus_context_allow_user (d->connections->context, uid);
361 }
362
363 static void
364 free_connection_data (void *data)
365 {
366   BusConnectionData *d = data;
367
368   /* services_owned should be NULL since we should be disconnected */
369   _dbus_assert (d->services_owned == NULL);
370   _dbus_assert (d->n_services_owned == 0);
371   /* similarly */
372   _dbus_assert (d->transaction_messages == NULL);
373
374   if (d->oom_preallocated)
375     dbus_connection_free_preallocated_send (d->connection, d->oom_preallocated);
376
377   if (d->oom_message)
378     dbus_message_unref (d->oom_message);
379
380   if (d->policy)
381     bus_client_policy_unref (d->policy);
382   
383   dbus_free (d->name);
384   
385   dbus_free (d);
386 }
387
388 static void
389 call_timeout_callback (DBusTimeout   *timeout,
390                        void          *data)
391 {
392   /* can return FALSE on OOM but we just let it fire again later */
393   dbus_timeout_handle (timeout);
394 }
395
396 BusConnections*
397 bus_connections_new (BusContext *context)
398 {
399   BusConnections *connections;
400
401   if (!dbus_connection_allocate_data_slot (&connection_data_slot))
402     goto failed_0;
403
404   connections = dbus_new0 (BusConnections, 1);
405   if (connections == NULL)
406     goto failed_1;
407
408   connections->completed_by_user = _dbus_hash_table_new (DBUS_HASH_ULONG,
409                                                          NULL, NULL);
410   if (connections->completed_by_user == NULL)
411     goto failed_2;
412
413   connections->expire_timeout = _dbus_timeout_new (100, /* irrelevant */
414                                                    expire_incomplete_timeout,
415                                                    connections, NULL);
416   if (connections->expire_timeout == NULL)
417     goto failed_3;
418
419   _dbus_timeout_set_enabled (connections->expire_timeout, FALSE);
420
421   if (!_dbus_loop_add_timeout (bus_context_get_loop (context),
422                                connections->expire_timeout,
423                                call_timeout_callback, NULL, NULL))
424     goto failed_4;
425   
426   connections->refcount = 1;
427   connections->context = context;
428   
429   return connections;
430
431  failed_4:
432   _dbus_timeout_unref (connections->expire_timeout);
433  failed_3:
434   _dbus_hash_table_unref (connections->completed_by_user);
435  failed_2:
436   dbus_free (connections);
437  failed_1:
438   dbus_connection_free_data_slot (&connection_data_slot);
439  failed_0:
440   return NULL;
441 }
442
443 void
444 bus_connections_ref (BusConnections *connections)
445 {
446   _dbus_assert (connections->refcount > 0);
447   connections->refcount += 1;
448 }
449
450 void
451 bus_connections_unref (BusConnections *connections)
452 {
453   _dbus_assert (connections->refcount > 0);
454   connections->refcount -= 1;
455   if (connections->refcount == 0)
456     {
457       /* drop all incomplete */
458       while (connections->incomplete != NULL)
459         {
460           DBusConnection *connection;
461
462           connection = connections->incomplete->data;
463
464           dbus_connection_ref (connection);
465           dbus_connection_disconnect (connection);
466           bus_connection_disconnected (connection);
467           dbus_connection_unref (connection);
468         }
469
470       _dbus_assert (connections->n_incomplete == 0);
471       
472       /* drop all real connections */
473       while (connections->completed != NULL)
474         {
475           DBusConnection *connection;
476
477           connection = connections->completed->data;
478
479           dbus_connection_ref (connection);
480           dbus_connection_disconnect (connection);
481           bus_connection_disconnected (connection);
482           dbus_connection_unref (connection);          
483         }
484
485       _dbus_assert (connections->n_completed == 0);
486
487       _dbus_loop_remove_timeout (bus_context_get_loop (connections->context),
488                                  connections->expire_timeout,
489                                  call_timeout_callback, NULL);
490       
491       _dbus_timeout_unref (connections->expire_timeout);
492       
493       _dbus_hash_table_unref (connections->completed_by_user);
494       
495       dbus_free (connections);
496
497       dbus_connection_free_data_slot (&connection_data_slot);
498     }
499 }
500
501 dbus_bool_t
502 bus_connections_setup_connection (BusConnections *connections,
503                                   DBusConnection *connection)
504 {
505   BusConnectionData *d;
506   dbus_bool_t retval;
507   
508   d = dbus_new0 (BusConnectionData, 1);
509   
510   if (d == NULL)
511     return FALSE;
512
513   d->connections = connections;
514   d->connection = connection;
515   
516   _dbus_get_current_time (&d->connection_tv_sec,
517                           &d->connection_tv_usec);
518   
519   _dbus_assert (connection_data_slot >= 0);
520   
521   if (!dbus_connection_set_data (connection,
522                                  connection_data_slot,
523                                  d, free_connection_data))
524     {
525       dbus_free (d);
526       return FALSE;
527     }
528
529   retval = FALSE;
530   
531   if (!dbus_connection_set_watch_functions (connection,
532                                             add_connection_watch,
533                                             remove_connection_watch,
534                                             NULL,
535                                             connection,
536                                             NULL))
537     goto out;
538   
539   if (!dbus_connection_set_timeout_functions (connection,
540                                               add_connection_timeout,
541                                               remove_connection_timeout,
542                                               NULL,
543                                               connection, NULL))
544     goto out;
545   
546   dbus_connection_set_unix_user_function (connection,
547                                           allow_user_function,
548                                           NULL, NULL);
549
550   dbus_connection_set_dispatch_status_function (connection,
551                                                 dispatch_status_function,
552                                                 bus_context_get_loop (connections->context),
553                                                 NULL);
554
555   d->link_in_connection_list = _dbus_list_alloc_link (connection);
556   if (d->link_in_connection_list == NULL)
557     goto out;
558   
559   /* Setup the connection with the dispatcher */
560   if (!bus_dispatch_add_connection (connection))
561     goto out;
562
563   if (dbus_connection_get_dispatch_status (connection) != DBUS_DISPATCH_COMPLETE)
564     {
565       if (!_dbus_loop_queue_dispatch (bus_context_get_loop (connections->context), connection))
566         {
567           bus_dispatch_remove_connection (connection);
568           goto out;
569         }
570     }
571
572   _dbus_list_append_link (&connections->incomplete, d->link_in_connection_list);
573   connections->n_incomplete += 1;
574   
575   dbus_connection_ref (connection);
576
577   /* Note that we might disconnect ourselves here, but it only takes
578    * effect on return to the main loop. We call this to free up
579    * expired connections if possible, and to queue the timeout for our
580    * own expiration.
581    */
582   bus_connections_expire_incomplete (connections);
583   
584   /* And we might also disconnect ourselves here, but again it
585    * only takes effect on return to main loop.
586    */
587   if (connections->n_incomplete >
588       bus_context_get_max_incomplete_connections (connections->context))
589     {
590       _dbus_verbose ("Number of incomplete connections exceeds max, dropping oldest one\n");
591       
592       _dbus_assert (connections->incomplete != NULL);
593       /* Disconnect the oldest unauthenticated connection.  FIXME
594        * would it be more secure to drop a *random* connection?  This
595        * algorithm seems to mean that if someone can create new
596        * connections quickly enough, they can keep anyone else from
597        * completing authentication. But random may or may not really
598        * help with that, a more elaborate solution might be required.
599        */
600       dbus_connection_disconnect (connections->incomplete->data);
601     }
602   
603   retval = TRUE;
604
605  out:
606   if (!retval)
607     {      
608       if (!dbus_connection_set_watch_functions (connection,
609                                                 NULL, NULL, NULL,
610                                                 connection,
611                                                 NULL))
612         _dbus_assert_not_reached ("setting watch functions to NULL failed");
613       
614       if (!dbus_connection_set_timeout_functions (connection,
615                                                   NULL, NULL, NULL,
616                                                   connection,
617                                                   NULL))
618         _dbus_assert_not_reached ("setting timeout functions to NULL failed");
619
620       dbus_connection_set_unix_user_function (connection,
621                                               NULL, NULL, NULL);
622
623       dbus_connection_set_dispatch_status_function (connection,
624                                                     NULL, NULL, NULL);
625
626       if (d->link_in_connection_list != NULL)
627         {
628           _dbus_assert (d->link_in_connection_list->next == NULL);
629           _dbus_assert (d->link_in_connection_list->prev == NULL);
630           _dbus_list_free_link (d->link_in_connection_list);
631           d->link_in_connection_list = NULL;
632         }
633       
634       if (!dbus_connection_set_data (connection,
635                                      connection_data_slot,
636                                      NULL, NULL))
637         _dbus_assert_not_reached ("failed to set connection data to null");
638
639       /* "d" has now been freed */
640     }
641   
642   return retval;
643 }
644
645 void
646 bus_connections_expire_incomplete (BusConnections *connections)
647 {    
648   int next_interval;
649
650   next_interval = -1;
651   
652   if (connections->incomplete != NULL)
653     {
654       long tv_sec, tv_usec;
655       DBusList *link;
656       int auth_timeout;
657       
658       _dbus_get_current_time (&tv_sec, &tv_usec);
659       auth_timeout = bus_context_get_auth_timeout (connections->context);
660   
661       link = _dbus_list_get_first_link (&connections->incomplete);
662       while (link != NULL)
663         {
664           DBusList *next = _dbus_list_get_next_link (&connections->incomplete, link);
665           DBusConnection *connection;
666           BusConnectionData *d;
667           double elapsed;
668       
669           connection = link->data;
670       
671           d = BUS_CONNECTION_DATA (connection);
672       
673           _dbus_assert (d != NULL);
674       
675           elapsed = ((double) tv_sec - (double) d->connection_tv_sec) * 1000.0 +
676             ((double) tv_usec - (double) d->connection_tv_usec) / 1000.0;
677
678           if (elapsed >= (double) auth_timeout)
679             {
680               _dbus_verbose ("Timing out authentication for connection %p\n", connection);
681               dbus_connection_disconnect (connection);
682             }
683           else
684             {
685               /* We can end the loop, since the connections are in oldest-first order */
686               next_interval = ((double)auth_timeout) - elapsed;
687               _dbus_verbose ("Connection %p authentication expires in %d milliseconds\n",
688                              connection, next_interval);
689           
690               break;
691             }
692       
693           link = next;
694         }
695     }
696   
697   if (next_interval >= 0)
698     {
699       _dbus_timeout_set_interval (connections->expire_timeout,
700                                   next_interval);
701       _dbus_timeout_set_enabled (connections->expire_timeout, TRUE);
702
703       _dbus_verbose ("Enabled incomplete connections timeout with interval %d, %d incomplete connections\n",
704                      next_interval, connections->n_incomplete);
705     }
706   else if (dbus_timeout_get_enabled (connections->expire_timeout))
707     {
708       _dbus_timeout_set_enabled (connections->expire_timeout, FALSE);
709
710       _dbus_verbose ("Disabled incomplete connections timeout, %d incomplete connections\n",
711                      connections->n_incomplete);
712     }
713   else
714     _dbus_verbose ("No need to disable incomplete connections timeout\n");
715 }
716
717 static dbus_bool_t
718 expire_incomplete_timeout (void *data)
719 {
720   BusConnections *connections = data;
721
722   _dbus_verbose ("Running %s\n", _DBUS_FUNCTION_NAME);
723   
724   /* note that this may remove the timeout */
725   bus_connections_expire_incomplete (connections);
726
727   return TRUE;
728 }
729
730 dbus_bool_t
731 bus_connection_get_groups  (DBusConnection   *connection,
732                             unsigned long   **groups,
733                             int              *n_groups,
734                             DBusError        *error)
735 {
736   BusConnectionData *d;
737   unsigned long uid;
738   DBusUserDatabase *user_database;
739   
740   d = BUS_CONNECTION_DATA (connection);
741
742   _dbus_assert (d != NULL);
743
744   user_database = bus_context_get_user_database (d->connections->context);
745   
746   *groups = NULL;
747   *n_groups = 0;
748
749   if (dbus_connection_get_unix_user (connection, &uid))
750     {
751       if (!_dbus_user_database_get_groups (user_database,
752                                            uid, groups, n_groups,
753                                            error))
754         {
755           _DBUS_ASSERT_ERROR_IS_SET (error);
756           _dbus_verbose ("Did not get any groups for UID %lu\n",
757                          uid);
758           return FALSE;
759         }
760       else
761         {
762           _dbus_verbose ("Got %d groups for UID %lu\n",
763                          *n_groups, uid);
764           return TRUE;
765         }
766     }
767   else
768     return TRUE; /* successfully got 0 groups */
769 }
770
771 dbus_bool_t
772 bus_connection_is_in_group (DBusConnection *connection,
773                             unsigned long   gid)
774 {
775   int i;
776   unsigned long *group_ids;
777   int n_group_ids;
778
779   if (!bus_connection_get_groups (connection, &group_ids, &n_group_ids,
780                                   NULL))
781     return FALSE;
782
783   i = 0;
784   while (i < n_group_ids)
785     {
786       if (group_ids[i] == gid)
787         {
788           dbus_free (group_ids);
789           return TRUE;
790         }
791       ++i;
792     }
793
794   dbus_free (group_ids);
795   return FALSE;
796 }
797
798 BusClientPolicy*
799 bus_connection_get_policy (DBusConnection *connection)
800 {
801   BusConnectionData *d;
802     
803   d = BUS_CONNECTION_DATA (connection);
804
805   _dbus_assert (d != NULL);
806   _dbus_assert (d->policy != NULL);
807   
808   return d->policy;
809 }
810
811 static dbus_bool_t
812 foreach_active (BusConnections               *connections,
813                 BusConnectionForeachFunction  function,
814                 void                         *data)
815 {
816   DBusList *link;
817   
818   link = _dbus_list_get_first_link (&connections->completed);
819   while (link != NULL)
820     {
821       DBusConnection *connection = link->data;
822       DBusList *next = _dbus_list_get_next_link (&connections->completed, link);
823
824       if (!(* function) (connection, data))
825         return FALSE;
826       
827       link = next;
828     }
829
830   return TRUE;
831 }
832
833 static dbus_bool_t
834 foreach_inactive (BusConnections               *connections,
835                   BusConnectionForeachFunction  function,
836                   void                         *data)
837 {
838   DBusList *link;
839   
840   link = _dbus_list_get_first_link (&connections->incomplete);
841   while (link != NULL)
842     {
843       DBusConnection *connection = link->data;
844       DBusList *next = _dbus_list_get_next_link (&connections->incomplete, link);
845
846       if (!(* function) (connection, data))
847         return FALSE;
848       
849       link = next;
850     }
851
852   return TRUE;
853 }
854
855 /**
856  * Calls function on each active connection; if the function returns
857  * #FALSE, stops iterating. Active connections are authenticated
858  * and have sent a Hello message.
859  *
860  * @param connections the connections object
861  * @param function the function
862  * @param data data to pass to it as a second arg
863  */
864 void
865 bus_connections_foreach_active (BusConnections               *connections,
866                                 BusConnectionForeachFunction  function,
867                                 void                         *data)
868 {
869   foreach_active (connections, function, data);
870 }
871
872 /**
873  * Calls function on each connection; if the function returns
874  * #FALSE, stops iterating.
875  *
876  * @param connections the connections object
877  * @param function the function
878  * @param data data to pass to it as a second arg
879  */
880 void
881 bus_connections_foreach (BusConnections               *connections,
882                          BusConnectionForeachFunction  function,
883                          void                         *data)
884 {
885   if (!foreach_active (connections, function, data))
886     return;
887
888   foreach_inactive (connections, function, data);
889 }
890
891 BusContext*
892 bus_connections_get_context (BusConnections *connections)
893 {
894   return connections->context;
895 }
896
897 /*
898  * This is used to avoid covering the same connection twice when
899  * traversing connections. Note that it assumes we will
900  * bus_connection_mark_stamp() each connection at least once per
901  * INT_MAX increments of the global stamp, or wraparound would break
902  * things.
903  */
904 void
905 bus_connections_increment_stamp (BusConnections *connections)
906 {
907   connections->stamp += 1;
908 }
909
910 /* Mark connection with current stamp, return TRUE if it
911  * didn't already have that stamp
912  */
913 dbus_bool_t
914 bus_connection_mark_stamp (DBusConnection *connection)
915 {
916   BusConnectionData *d;
917   
918   d = BUS_CONNECTION_DATA (connection);
919   
920   _dbus_assert (d != NULL);
921
922   if (d->stamp == d->connections->stamp)
923     return FALSE;
924   else
925     {
926       d->stamp = d->connections->stamp;
927       return TRUE;
928     }
929 }
930
931 BusContext*
932 bus_connection_get_context (DBusConnection *connection)
933 {
934   BusConnectionData *d;
935
936   d = BUS_CONNECTION_DATA (connection);
937
938   _dbus_assert (d != NULL);
939
940   return d->connections->context;
941 }
942
943 BusConnections*
944 bus_connection_get_connections (DBusConnection *connection)
945 {
946   BusConnectionData *d;
947     
948   d = BUS_CONNECTION_DATA (connection);
949
950   _dbus_assert (d != NULL);
951
952   return d->connections;
953 }
954
955 BusRegistry*
956 bus_connection_get_registry (DBusConnection *connection)
957 {
958   BusConnectionData *d;
959
960   d = BUS_CONNECTION_DATA (connection);
961
962   _dbus_assert (d != NULL);
963
964   return bus_context_get_registry (d->connections->context);
965 }
966
967 BusActivation*
968 bus_connection_get_activation (DBusConnection *connection)
969 {
970   BusConnectionData *d;
971
972   d = BUS_CONNECTION_DATA (connection);
973
974   _dbus_assert (d != NULL);
975
976   return bus_context_get_activation (d->connections->context);
977 }
978
979 BusMatchmaker*
980 bus_connection_get_matchmaker (DBusConnection *connection)
981 {
982   BusConnectionData *d;
983
984   d = BUS_CONNECTION_DATA (connection);
985
986   _dbus_assert (d != NULL);
987
988   return bus_context_get_matchmaker (d->connections->context);
989 }
990
991 /**
992  * Checks whether the connection is registered with the message bus.
993  *
994  * @param connection the connection
995  * @returns #TRUE if we're an active message bus participant
996  */
997 dbus_bool_t
998 bus_connection_is_active (DBusConnection *connection)
999 {
1000   BusConnectionData *d;
1001
1002   d = BUS_CONNECTION_DATA (connection);
1003   
1004   return d != NULL && d->name != NULL;
1005 }
1006
1007 dbus_bool_t
1008 bus_connection_preallocate_oom_error (DBusConnection *connection)
1009 {
1010   DBusMessage *message;
1011   DBusPreallocatedSend *preallocated;
1012   BusConnectionData *d;
1013
1014   d = BUS_CONNECTION_DATA (connection);  
1015
1016   _dbus_assert (d != NULL);
1017
1018   if (d->oom_preallocated != NULL)
1019     return TRUE;
1020   
1021   preallocated = dbus_connection_preallocate_send (connection);
1022   if (preallocated == NULL)
1023     return FALSE;
1024
1025   message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
1026
1027   if (message == NULL)
1028     {
1029       dbus_connection_free_preallocated_send (connection, preallocated);
1030       return FALSE;
1031     }
1032
1033   /* d->name may be NULL, but that is OK */
1034   if (!dbus_message_set_error_name (message, DBUS_ERROR_NO_MEMORY) ||
1035       !dbus_message_set_destination (message, d->name) ||
1036       !dbus_message_set_sender (message,
1037                                 DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
1038     {
1039       dbus_connection_free_preallocated_send (connection, preallocated);
1040       dbus_message_unref (message);
1041       return FALSE;
1042     }
1043   
1044   /* set reply serial to placeholder value just so space is already allocated
1045    * for it.
1046    */
1047   if (!dbus_message_set_reply_serial (message, 14))
1048     {
1049       dbus_connection_free_preallocated_send (connection, preallocated);
1050       dbus_message_unref (message);
1051       return FALSE;
1052     }
1053
1054   d->oom_message = message;
1055   d->oom_preallocated = preallocated;
1056   
1057   return TRUE;
1058 }
1059
1060 void
1061 bus_connection_send_oom_error (DBusConnection *connection,
1062                                DBusMessage    *in_reply_to)
1063 {
1064   BusConnectionData *d;
1065
1066   d = BUS_CONNECTION_DATA (connection);  
1067
1068   _dbus_assert (d != NULL);  
1069   _dbus_assert (d->oom_message != NULL);
1070
1071   /* should always succeed since we set it to a placeholder earlier */
1072   if (!dbus_message_set_reply_serial (d->oom_message,
1073                                       dbus_message_get_serial (in_reply_to)))
1074     _dbus_assert_not_reached ("Failed to set reply serial for preallocated oom message");
1075
1076   _dbus_assert (dbus_message_get_sender (d->oom_message) != NULL);
1077   
1078   dbus_connection_send_preallocated (connection, d->oom_preallocated,
1079                                      d->oom_message, NULL);
1080
1081   dbus_message_unref (d->oom_message);
1082   d->oom_message = NULL;
1083   d->oom_preallocated = NULL;
1084 }
1085
1086 void
1087 bus_connection_add_match_rule_link (DBusConnection *connection,
1088                                     DBusList       *link)
1089 {
1090   BusConnectionData *d;
1091
1092   d = BUS_CONNECTION_DATA (connection);
1093   _dbus_assert (d != NULL);
1094
1095   _dbus_list_append_link (&d->match_rules, link);
1096
1097   d->n_match_rules += 1;
1098 }
1099
1100 dbus_bool_t
1101 bus_connection_add_match_rule (DBusConnection *connection,
1102                                BusMatchRule   *rule)
1103 {
1104     DBusList *link;
1105
1106   link = _dbus_list_alloc_link (rule);
1107
1108   if (link == NULL)
1109     return FALSE;
1110
1111   bus_connection_add_match_rule_link (connection, link);
1112
1113   return TRUE;
1114 }
1115
1116 void
1117 bus_connection_remove_match_rule (DBusConnection *connection,
1118                                   BusMatchRule   *rule)
1119 {
1120   BusConnectionData *d;
1121
1122   d = BUS_CONNECTION_DATA (connection);
1123   _dbus_assert (d != NULL);
1124
1125   _dbus_list_remove_last (&d->match_rules, rule);
1126
1127   d->n_match_rules -= 1;
1128   _dbus_assert (d->n_match_rules >= 0);
1129 }
1130
1131 int
1132 bus_connection_get_n_match_rules (DBusConnection *connection)
1133 {
1134   BusConnectionData *d;
1135
1136   d = BUS_CONNECTION_DATA (connection);
1137   _dbus_assert (d != NULL);
1138   
1139   return d->n_match_rules;
1140 }
1141
1142 void
1143 bus_connection_add_owned_service_link (DBusConnection *connection,
1144                                        DBusList       *link)
1145 {
1146   BusConnectionData *d;
1147
1148   d = BUS_CONNECTION_DATA (connection);
1149   _dbus_assert (d != NULL);
1150
1151   _dbus_list_append_link (&d->services_owned, link);
1152
1153   d->n_services_owned += 1;
1154 }
1155
1156 dbus_bool_t
1157 bus_connection_add_owned_service (DBusConnection *connection,
1158                                   BusService     *service)
1159 {
1160   DBusList *link;
1161
1162   link = _dbus_list_alloc_link (service);
1163
1164   if (link == NULL)
1165     return FALSE;
1166
1167   bus_connection_add_owned_service_link (connection, link);
1168
1169   return TRUE;
1170 }
1171
1172 void
1173 bus_connection_remove_owned_service (DBusConnection *connection,
1174                                      BusService     *service)
1175 {
1176   BusConnectionData *d;
1177
1178   d = BUS_CONNECTION_DATA (connection);
1179   _dbus_assert (d != NULL);
1180
1181   _dbus_list_remove_last (&d->services_owned, service);
1182
1183   d->n_services_owned -= 1;
1184   _dbus_assert (d->n_services_owned >= 0);
1185 }
1186
1187 int
1188 bus_connection_get_n_services_owned (DBusConnection *connection)
1189 {
1190   BusConnectionData *d;
1191
1192   d = BUS_CONNECTION_DATA (connection);
1193   _dbus_assert (d != NULL);
1194   
1195   return d->n_services_owned;
1196 }
1197
1198 dbus_bool_t
1199 bus_connection_complete (DBusConnection   *connection,
1200                          const DBusString *name,
1201                          DBusError        *error)
1202 {
1203   BusConnectionData *d;
1204   unsigned long uid;
1205   
1206   d = BUS_CONNECTION_DATA (connection);
1207   _dbus_assert (d != NULL);
1208   _dbus_assert (d->name == NULL);
1209   _dbus_assert (d->policy == NULL);
1210
1211   _dbus_assert (!bus_connection_is_active (connection));
1212   
1213   if (!_dbus_string_copy_data (name, &d->name))
1214     {
1215       BUS_SET_OOM (error);
1216       return FALSE;
1217     }
1218
1219   _dbus_assert (d->name != NULL);
1220   
1221   _dbus_verbose ("Name %s assigned to %p\n", d->name, connection);
1222
1223   d->policy = bus_context_create_client_policy (d->connections->context,
1224                                                 connection,
1225                                                 error);
1226
1227   /* we may have a NULL policy on OOM or error getting list of
1228    * groups for a user. In the latter case we don't handle it so
1229    * well currently, as it will just keep failing over and over.
1230    */
1231
1232   if (d->policy == NULL)
1233     {
1234       _dbus_verbose ("Failed to create security policy for connection %p\n",
1235                      connection);
1236       _DBUS_ASSERT_ERROR_IS_SET (error);
1237       dbus_free (d->name);
1238       d->name = NULL;
1239       return FALSE;
1240     }
1241   
1242   if (dbus_connection_get_unix_user (connection, &uid))
1243     {
1244       if (!adjust_connections_for_uid (d->connections,
1245                                        uid, 1))
1246         {
1247           BUS_SET_OOM (error);
1248           dbus_free (d->name);
1249           d->name = NULL;
1250           return FALSE;
1251         }
1252     }
1253   
1254   /* Now the connection is active, move it between lists */
1255   _dbus_list_unlink (&d->connections->incomplete,
1256                      d->link_in_connection_list);
1257   d->connections->n_incomplete -= 1;
1258   _dbus_list_append_link (&d->connections->completed,
1259                           d->link_in_connection_list);
1260   d->connections->n_completed += 1;
1261
1262   _dbus_assert (d->connections->n_incomplete >= 0);
1263   _dbus_assert (d->connections->n_completed > 0);
1264
1265   /* See if we can remove the timeout */
1266   bus_connections_expire_incomplete (d->connections);
1267
1268   _dbus_assert (bus_connection_is_active (connection));
1269   
1270   return TRUE;
1271 }
1272
1273 const char *
1274 bus_connection_get_name (DBusConnection *connection)
1275 {
1276   BusConnectionData *d;
1277   
1278   d = BUS_CONNECTION_DATA (connection);
1279   _dbus_assert (d != NULL);
1280   
1281   return d->name;
1282 }
1283
1284 /**
1285  * Check whether completing the passed-in connection would
1286  * exceed limits, and if so set error and return #FALSE
1287  */
1288 dbus_bool_t
1289 bus_connections_check_limits (BusConnections  *connections,
1290                               DBusConnection  *requesting_completion,
1291                               DBusError       *error)
1292 {
1293   BusConnectionData *d;
1294   unsigned long uid;
1295   
1296   d = BUS_CONNECTION_DATA (requesting_completion);
1297   _dbus_assert (d != NULL);
1298
1299   _dbus_assert (d->name == NULL);
1300
1301   if (connections->n_completed >=
1302       bus_context_get_max_completed_connections (connections->context))
1303     {
1304       dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
1305                       "The maximum number of active connections has been reached");
1306       return FALSE;
1307     }
1308   
1309   if (dbus_connection_get_unix_user (requesting_completion, &uid))
1310     {
1311       if (get_connections_for_uid (connections, uid) >=
1312           bus_context_get_max_connections_per_user (connections->context))
1313         {
1314           dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
1315                           "The maximum number of active connections for UID %lu has been reached",
1316                           uid);
1317           return FALSE;
1318         }
1319     }
1320   
1321   return TRUE;
1322 }
1323
1324
1325 /*
1326  * Transactions
1327  *
1328  * Note that this is fairly fragile; in particular, don't try to use
1329  * one transaction across any main loop iterations.
1330  */
1331
1332 typedef struct
1333 {
1334   BusTransaction *transaction;
1335   DBusMessage    *message;
1336   DBusPreallocatedSend *preallocated;
1337 } MessageToSend;
1338
1339 typedef struct
1340 {
1341   BusTransactionCancelFunction cancel_function;
1342   DBusFreeFunction free_data_function;
1343   void *data;
1344 } CancelHook;
1345
1346 struct BusTransaction
1347 {
1348   DBusList *connections;
1349   BusContext *context;
1350   DBusList *cancel_hooks;
1351 };
1352
1353 static void
1354 message_to_send_free (DBusConnection *connection,
1355                       MessageToSend  *to_send)
1356 {
1357   if (to_send->message)
1358     dbus_message_unref (to_send->message);
1359
1360   if (to_send->preallocated)
1361     dbus_connection_free_preallocated_send (connection, to_send->preallocated);
1362
1363   dbus_free (to_send);
1364 }
1365
1366 static void
1367 cancel_hook_cancel (void *element,
1368                     void *data)
1369 {
1370   CancelHook *ch = element;
1371
1372   _dbus_verbose ("Running transaction cancel hook\n");
1373   
1374   if (ch->cancel_function)
1375     (* ch->cancel_function) (ch->data);  
1376 }
1377
1378 static void
1379 cancel_hook_free (void *element,
1380                   void *data)
1381 {
1382   CancelHook *ch = element;
1383
1384   if (ch->free_data_function)
1385     (* ch->free_data_function) (ch->data);
1386
1387   dbus_free (ch);
1388 }
1389
1390 static void
1391 free_cancel_hooks (BusTransaction *transaction)
1392 {
1393   _dbus_list_foreach (&transaction->cancel_hooks,
1394                       cancel_hook_free, NULL);
1395   
1396   _dbus_list_clear (&transaction->cancel_hooks);
1397 }
1398
1399 BusTransaction*
1400 bus_transaction_new (BusContext *context)
1401 {
1402   BusTransaction *transaction;
1403
1404   transaction = dbus_new0 (BusTransaction, 1);
1405   if (transaction == NULL)
1406     return NULL;
1407
1408   transaction->context = context;
1409   
1410   return transaction;
1411 }
1412
1413 BusContext*
1414 bus_transaction_get_context (BusTransaction  *transaction)
1415 {
1416   return transaction->context;
1417 }
1418
1419 BusConnections*
1420 bus_transaction_get_connections (BusTransaction  *transaction)
1421 {
1422   return bus_context_get_connections (transaction->context);
1423 }
1424
1425 dbus_bool_t
1426 bus_transaction_send_from_driver (BusTransaction *transaction,
1427                                   DBusConnection *connection,
1428                                   DBusMessage    *message)
1429 {
1430   /* We have to set the sender to the driver, and have
1431    * to check security policy since it was not done in
1432    * dispatch.c
1433    */
1434   _dbus_verbose ("Sending %s %s %s from driver\n",
1435                  dbus_message_get_interface (message) ?
1436                  dbus_message_get_interface (message) : "(no interface)",
1437                  dbus_message_get_member (message) ?
1438                  dbus_message_get_member (message) : "(no member)",
1439                  dbus_message_get_error_name (message) ?
1440                  dbus_message_get_error_name (message) : "(no error name)");
1441                  
1442   if (!dbus_message_set_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
1443     return FALSE;
1444
1445   /* If security policy doesn't allow the message, we silently
1446    * eat it; the driver doesn't care about getting a reply.
1447    */
1448   if (!bus_context_check_security_policy (bus_transaction_get_context (transaction),
1449                                           NULL, connection, connection, message, NULL))
1450     return TRUE;
1451
1452   return bus_transaction_send (transaction, connection, message);
1453 }
1454
1455 dbus_bool_t
1456 bus_transaction_send (BusTransaction *transaction,
1457                       DBusConnection *connection,
1458                       DBusMessage    *message)
1459 {
1460   MessageToSend *to_send;
1461   BusConnectionData *d;
1462   DBusList *link;
1463
1464   _dbus_verbose ("  trying to add %s interface=%s member=%s error=%s to transaction%s\n",
1465                  dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR ? "error" :
1466                  dbus_message_get_reply_serial (message) != 0 ? "reply" :
1467                  "message",
1468                  dbus_message_get_interface (message) ?
1469                  dbus_message_get_interface (message) : "(unset)",
1470                  dbus_message_get_member (message) ?
1471                  dbus_message_get_member (message) : "(unset)",
1472                  dbus_message_get_error_name (message) ?
1473                  dbus_message_get_error_name (message) : "(unset)",
1474                  dbus_connection_get_is_connected (connection) ?
1475                  "" : " (disconnected)");
1476
1477   _dbus_assert (dbus_message_get_sender (message) != NULL);
1478   
1479   if (!dbus_connection_get_is_connected (connection))
1480     return TRUE; /* silently ignore disconnected connections */
1481   
1482   d = BUS_CONNECTION_DATA (connection);
1483   _dbus_assert (d != NULL);
1484   
1485   to_send = dbus_new (MessageToSend, 1);
1486   if (to_send == NULL)
1487     {
1488       return FALSE;
1489     }
1490
1491   to_send->preallocated = dbus_connection_preallocate_send (connection);
1492   if (to_send->preallocated == NULL)
1493     {
1494       dbus_free (to_send);
1495       return FALSE;
1496     }  
1497   
1498   dbus_message_ref (message);
1499   to_send->message = message;
1500   to_send->transaction = transaction;
1501
1502   _dbus_verbose ("about to prepend message\n");
1503   
1504   if (!_dbus_list_prepend (&d->transaction_messages, to_send))
1505     {
1506       message_to_send_free (connection, to_send);
1507       return FALSE;
1508     }
1509
1510   _dbus_verbose ("prepended message\n");
1511   
1512   /* See if we already had this connection in the list
1513    * for this transaction. If we have a pending message,
1514    * then we should already be in transaction->connections
1515    */
1516   link = _dbus_list_get_first_link (&d->transaction_messages);
1517   _dbus_assert (link->data == to_send);
1518   link = _dbus_list_get_next_link (&d->transaction_messages, link);
1519   while (link != NULL)
1520     {
1521       MessageToSend *m = link->data;
1522       DBusList *next = _dbus_list_get_next_link (&d->transaction_messages, link);
1523       
1524       if (m->transaction == transaction)
1525         break;
1526         
1527       link = next;
1528     }
1529
1530   if (link == NULL)
1531     {
1532       if (!_dbus_list_prepend (&transaction->connections, connection))
1533         {
1534           _dbus_list_remove (&d->transaction_messages, to_send);
1535           message_to_send_free (connection, to_send);
1536           return FALSE;
1537         }
1538     }
1539
1540   return TRUE;
1541 }
1542
1543 static void
1544 connection_cancel_transaction (DBusConnection *connection,
1545                                BusTransaction *transaction)
1546 {
1547   DBusList *link;
1548   BusConnectionData *d;
1549   
1550   d = BUS_CONNECTION_DATA (connection);
1551   _dbus_assert (d != NULL);
1552   
1553   link = _dbus_list_get_first_link (&d->transaction_messages);
1554   while (link != NULL)
1555     {
1556       MessageToSend *m = link->data;
1557       DBusList *next = _dbus_list_get_next_link (&d->transaction_messages, link);
1558       
1559       if (m->transaction == transaction)
1560         {
1561           _dbus_list_remove_link (&d->transaction_messages,
1562                                   link);
1563           
1564           message_to_send_free (connection, m);
1565         }
1566         
1567       link = next;
1568     }
1569 }
1570
1571 void
1572 bus_transaction_cancel_and_free (BusTransaction *transaction)
1573 {
1574   DBusConnection *connection;
1575
1576   _dbus_verbose ("TRANSACTION: cancelled\n");
1577   
1578   while ((connection = _dbus_list_pop_first (&transaction->connections)))
1579     connection_cancel_transaction (connection, transaction);
1580
1581   _dbus_assert (transaction->connections == NULL);
1582
1583   _dbus_list_foreach (&transaction->cancel_hooks,
1584                       cancel_hook_cancel, NULL);
1585
1586   free_cancel_hooks (transaction);
1587   
1588   dbus_free (transaction);
1589 }
1590
1591 static void
1592 connection_execute_transaction (DBusConnection *connection,
1593                                 BusTransaction *transaction)
1594 {
1595   DBusList *link;
1596   BusConnectionData *d;
1597   
1598   d = BUS_CONNECTION_DATA (connection);
1599   _dbus_assert (d != NULL);
1600
1601   /* Send the queue in order (FIFO) */
1602   link = _dbus_list_get_last_link (&d->transaction_messages);
1603   while (link != NULL)
1604     {
1605       MessageToSend *m = link->data;
1606       DBusList *prev = _dbus_list_get_prev_link (&d->transaction_messages, link);
1607       
1608       if (m->transaction == transaction)
1609         {
1610           _dbus_list_remove_link (&d->transaction_messages,
1611                                   link);
1612
1613           _dbus_assert (dbus_message_get_sender (m->message) != NULL);
1614           
1615           dbus_connection_send_preallocated (connection,
1616                                              m->preallocated,
1617                                              m->message,
1618                                              NULL);
1619
1620           m->preallocated = NULL; /* so we don't double-free it */
1621           
1622           message_to_send_free (connection, m);
1623         }
1624         
1625       link = prev;
1626     }
1627 }
1628
1629 void
1630 bus_transaction_execute_and_free (BusTransaction *transaction)
1631 {
1632   /* For each connection in transaction->connections
1633    * send the messages
1634    */
1635   DBusConnection *connection;
1636
1637   _dbus_verbose ("TRANSACTION: executing\n");
1638   
1639   while ((connection = _dbus_list_pop_first (&transaction->connections)))
1640     connection_execute_transaction (connection, transaction);
1641
1642   _dbus_assert (transaction->connections == NULL);
1643
1644   free_cancel_hooks (transaction);
1645   
1646   dbus_free (transaction);
1647 }
1648
1649 static void
1650 bus_connection_remove_transactions (DBusConnection *connection)
1651 {
1652   MessageToSend *to_send;
1653   BusConnectionData *d;
1654   
1655   d = BUS_CONNECTION_DATA (connection);
1656   _dbus_assert (d != NULL);
1657   
1658   while ((to_send = _dbus_list_get_first (&d->transaction_messages)))
1659     {
1660       /* only has an effect for the first MessageToSend listing this transaction */
1661       _dbus_list_remove (&to_send->transaction->connections,
1662                          connection);
1663
1664       _dbus_list_remove (&d->transaction_messages, to_send);
1665       message_to_send_free (connection, to_send);
1666     }
1667 }
1668
1669 /**
1670  * Converts the DBusError to a message reply
1671  */
1672 dbus_bool_t
1673 bus_transaction_send_error_reply (BusTransaction  *transaction,
1674                                   DBusConnection  *connection,
1675                                   const DBusError *error,
1676                                   DBusMessage     *in_reply_to)
1677 {
1678   DBusMessage *reply;
1679   
1680   _dbus_assert (error != NULL);
1681   _DBUS_ASSERT_ERROR_IS_SET (error);
1682   
1683   _dbus_verbose ("Sending error reply %s \"%s\"\n",
1684                  error->name, error->message);
1685
1686   reply = dbus_message_new_error (in_reply_to,
1687                                   error->name,
1688                                   error->message);
1689   if (reply == NULL)
1690     return FALSE;
1691
1692   if (!bus_transaction_send_from_driver (transaction, connection, reply))
1693     {
1694       dbus_message_unref (reply);
1695       return FALSE;
1696     }
1697
1698   dbus_message_unref (reply);
1699   
1700   return TRUE;
1701 }
1702
1703 dbus_bool_t
1704 bus_transaction_add_cancel_hook (BusTransaction               *transaction,
1705                                  BusTransactionCancelFunction  cancel_function,
1706                                  void                         *data,
1707                                  DBusFreeFunction              free_data_function)
1708 {
1709   CancelHook *ch;
1710
1711   ch = dbus_new (CancelHook, 1);
1712   if (ch == NULL)
1713     return FALSE;
1714   
1715   ch->cancel_function = cancel_function;
1716   ch->data = data;
1717   ch->free_data_function = free_data_function;
1718
1719   /* It's important that the hooks get run in reverse order that they
1720    * were added
1721    */
1722   if (!_dbus_list_prepend (&transaction->cancel_hooks, ch))
1723     {
1724       dbus_free (ch);
1725       return FALSE;
1726     }
1727
1728   return TRUE;
1729 }