driver.c revision 75742242000e782719bc1656f0a7da72b059e88e
1/* -*- mode: C; c-file-style: "gnu" -*- */
2/* driver.c  Bus client (driver)
3 *
4 * Copyright (C) 2003 CodeFactory AB
5 * Copyright (C) 2003 Red Hat, Inc.
6 *
7 * Licensed under the Academic Free License version 1.2
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22 *
23 */
24
25#include "activation.h"
26#include "connection.h"
27#include "driver.h"
28#include "dispatch.h"
29#include "services.h"
30#include "signals.h"
31#include "utils.h"
32#include <dbus/dbus-string.h>
33#include <dbus/dbus-internals.h>
34#include <string.h>
35
36static dbus_bool_t bus_driver_send_welcome_message (DBusConnection *connection,
37                                                    DBusMessage    *hello_message,
38                                                    BusTransaction *transaction,
39                                                    DBusError      *error);
40
41dbus_bool_t
42bus_driver_send_service_deleted (const char     *service_name,
43                                 BusTransaction *transaction,
44                                 DBusError      *error)
45{
46  DBusMessage *message;
47  dbus_bool_t retval;
48
49  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
50
51  _dbus_verbose ("sending service deleted: %s\n", service_name);
52
53  message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_DBUS,
54                                     DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
55                                     "ServiceDeleted");
56
57  if (message == NULL)
58    {
59      BUS_SET_OOM (error);
60      return FALSE;
61    }
62
63  if (!dbus_message_set_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS) ||
64      !dbus_message_append_args (message,
65                                 DBUS_TYPE_STRING, service_name,
66                                 DBUS_TYPE_INVALID))
67    {
68      dbus_message_unref (message);
69      BUS_SET_OOM (error);
70      return FALSE;
71    }
72
73  retval = bus_dispatch_matches (transaction, NULL, NULL, message, error);
74  dbus_message_unref (message);
75
76  return retval;
77}
78
79dbus_bool_t
80bus_driver_send_service_created (const char     *service_name,
81                                 BusTransaction *transaction,
82                                 DBusError      *error)
83{
84  DBusMessage *message;
85  dbus_bool_t retval;
86
87  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
88
89  message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_DBUS,
90                                     DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
91                                     "ServiceCreated");
92
93  if (message == NULL)
94    {
95      BUS_SET_OOM (error);
96      return FALSE;
97    }
98
99  if (!dbus_message_set_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
100    {
101      dbus_message_unref (message);
102      BUS_SET_OOM (error);
103      return FALSE;
104    }
105
106  if (!dbus_message_append_args (message,
107                                 DBUS_TYPE_STRING, service_name,
108                                 DBUS_TYPE_INVALID))
109    {
110      dbus_message_unref (message);
111      BUS_SET_OOM (error);
112      return FALSE;
113    }
114
115  retval = bus_dispatch_matches (transaction, NULL, NULL, message, error);
116  dbus_message_unref (message);
117
118  return retval;
119}
120
121dbus_bool_t
122bus_driver_send_service_lost (DBusConnection *connection,
123			      const char     *service_name,
124                              BusTransaction *transaction,
125                              DBusError      *error)
126{
127  DBusMessage *message;
128
129  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
130
131  message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_DBUS,
132                                     DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
133                                     "ServiceLost");
134
135  if (message == NULL)
136    {
137      BUS_SET_OOM (error);
138      return FALSE;
139    }
140
141  if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) ||
142      !dbus_message_append_args (message,
143                                 DBUS_TYPE_STRING, service_name,
144                                 DBUS_TYPE_INVALID))
145    {
146      dbus_message_unref (message);
147      BUS_SET_OOM (error);
148      return FALSE;
149    }
150
151  if (!bus_transaction_send_from_driver (transaction, connection, message))
152    {
153      dbus_message_unref (message);
154      BUS_SET_OOM (error);
155      return FALSE;
156    }
157  else
158    {
159      dbus_message_unref (message);
160      return TRUE;
161    }
162}
163
164dbus_bool_t
165bus_driver_send_service_acquired (DBusConnection *connection,
166                                  const char     *service_name,
167                                  BusTransaction *transaction,
168                                  DBusError      *error)
169{
170  DBusMessage *message;
171
172  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
173
174  message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_DBUS,
175                                     DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
176                                     "ServiceAcquired");
177
178  if (message == NULL)
179    {
180      BUS_SET_OOM (error);
181      return FALSE;
182    }
183
184  if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) ||
185      !dbus_message_append_args (message,
186                                 DBUS_TYPE_STRING, service_name,
187                                 DBUS_TYPE_INVALID))
188    {
189      dbus_message_unref (message);
190      BUS_SET_OOM (error);
191      return FALSE;
192    }
193
194  if (!bus_transaction_send_from_driver (transaction, connection, message))
195    {
196      dbus_message_unref (message);
197      BUS_SET_OOM (error);
198      return FALSE;
199    }
200  else
201    {
202      dbus_message_unref (message);
203      return TRUE;
204    }
205}
206
207static dbus_bool_t
208create_unique_client_name (BusRegistry *registry,
209                           DBusString  *str)
210{
211  /* We never want to use the same unique client name twice, because
212   * we want to guarantee that if you send a message to a given unique
213   * name, you always get the same application. So we use two numbers
214   * for INT_MAX * INT_MAX combinations, should be pretty safe against
215   * wraparound.
216   */
217  /* FIXME these should be in BusRegistry rather than static vars */
218  static int next_major_number = 0;
219  static int next_minor_number = 0;
220  int len;
221
222  len = _dbus_string_get_length (str);
223
224  while (TRUE)
225    {
226      /* start out with 1-0, go to 1-1, 1-2, 1-3,
227       * up to 1-MAXINT, then 2-0, 2-1, etc.
228       */
229      if (next_minor_number <= 0)
230        {
231          next_major_number += 1;
232          next_minor_number = 0;
233          if (next_major_number <= 0)
234            _dbus_assert_not_reached ("INT_MAX * INT_MAX clients were added");
235        }
236
237      _dbus_assert (next_major_number > 0);
238      _dbus_assert (next_minor_number >= 0);
239
240      /* appname:MAJOR-MINOR */
241
242      if (!_dbus_string_append (str, ":"))
243        return FALSE;
244
245      if (!_dbus_string_append_int (str, next_major_number))
246        return FALSE;
247
248      if (!_dbus_string_append (str, "."))
249        return FALSE;
250
251      if (!_dbus_string_append_int (str, next_minor_number))
252        return FALSE;
253
254      next_minor_number += 1;
255
256      /* Check if a client with the name exists */
257      if (bus_registry_lookup (registry, str) == NULL)
258	break;
259
260      /* drop the number again, try the next one. */
261      _dbus_string_set_length (str, len);
262    }
263
264  return TRUE;
265}
266
267static dbus_bool_t
268bus_driver_handle_hello (DBusConnection *connection,
269                         BusTransaction *transaction,
270                         DBusMessage    *message,
271                         DBusError      *error)
272{
273  DBusString unique_name;
274  BusService *service;
275  dbus_bool_t retval;
276  BusRegistry *registry;
277  BusConnections *connections;
278
279  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
280
281  /* Note that when these limits are exceeded we don't disconnect the
282   * connection; we just sort of leave it hanging there until it times
283   * out or disconnects itself or is dropped due to the max number of
284   * incomplete connections. It's even OK if the connection wants to
285   * retry the hello message, we support that.
286   */
287  connections = bus_connection_get_connections (connection);
288  if (!bus_connections_check_limits (connections, connection,
289                                     error))
290    {
291      _DBUS_ASSERT_ERROR_IS_SET (error);
292      return FALSE;
293    }
294
295  if (!_dbus_string_init (&unique_name))
296    {
297      BUS_SET_OOM (error);
298      return FALSE;
299    }
300
301  retval = FALSE;
302
303  registry = bus_connection_get_registry (connection);
304
305  if (!create_unique_client_name (registry, &unique_name))
306    {
307      BUS_SET_OOM (error);
308      goto out_0;
309    }
310
311  if (!bus_connection_complete (connection, &unique_name, error))
312    {
313      _DBUS_ASSERT_ERROR_IS_SET (error);
314      goto out_0;
315    }
316
317  if (!dbus_message_set_sender (message,
318                                bus_connection_get_name (connection)))
319    {
320      BUS_SET_OOM (error);
321      goto out_0;
322    }
323
324  if (!bus_driver_send_welcome_message (connection, message, transaction, error))
325    goto out_0;
326
327  /* Create the service */
328  service = bus_registry_ensure (registry,
329                                 &unique_name, connection, transaction, error);
330  if (service == NULL)
331    goto out_0;
332
333  bus_service_set_prohibit_replacement (service, TRUE);
334
335  _dbus_assert (bus_connection_is_active (connection));
336  retval = TRUE;
337
338 out_0:
339  _dbus_string_free (&unique_name);
340  return retval;
341}
342
343static dbus_bool_t
344bus_driver_send_welcome_message (DBusConnection *connection,
345                                 DBusMessage    *hello_message,
346                                 BusTransaction *transaction,
347                                 DBusError      *error)
348{
349  DBusMessage *welcome;
350  const char *name;
351
352  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
353
354  name = bus_connection_get_name (connection);
355  _dbus_assert (name != NULL);
356
357  welcome = dbus_message_new_method_return (hello_message);
358  if (welcome == NULL)
359    {
360      BUS_SET_OOM (error);
361      return FALSE;
362    }
363
364  if (!dbus_message_append_args (welcome,
365                                 DBUS_TYPE_STRING, name,
366                                 DBUS_TYPE_INVALID))
367    {
368      dbus_message_unref (welcome);
369      BUS_SET_OOM (error);
370      return FALSE;
371    }
372
373  if (!bus_transaction_send_from_driver (transaction, connection, welcome))
374    {
375      dbus_message_unref (welcome);
376      BUS_SET_OOM (error);
377      return FALSE;
378    }
379  else
380    {
381      dbus_message_unref (welcome);
382      return TRUE;
383    }
384}
385
386static dbus_bool_t
387bus_driver_handle_list_services (DBusConnection *connection,
388                                 BusTransaction *transaction,
389                                 DBusMessage    *message,
390                                 DBusError      *error)
391{
392  DBusMessage *reply;
393  int len;
394  char **services;
395  BusRegistry *registry;
396
397  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
398
399  registry = bus_connection_get_registry (connection);
400
401  reply = dbus_message_new_method_return (message);
402  if (reply == NULL)
403    {
404      BUS_SET_OOM (error);
405      return FALSE;
406    }
407
408  if (!bus_registry_list_services (registry, &services, &len))
409    {
410      dbus_message_unref (reply);
411      BUS_SET_OOM (error);
412      return FALSE;
413    }
414
415  if (!dbus_message_append_args (reply,
416                                 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, services, len,
417                                 DBUS_TYPE_INVALID))
418    {
419      dbus_free_string_array (services);
420      dbus_message_unref (reply);
421      BUS_SET_OOM (error);
422      return FALSE;
423    }
424
425  dbus_free_string_array (services);
426
427  if (!bus_transaction_send_from_driver (transaction, connection, reply))
428    {
429      dbus_message_unref (reply);
430      BUS_SET_OOM (error);
431      return FALSE;
432    }
433  else
434    {
435      dbus_message_unref (reply);
436      return TRUE;
437    }
438}
439
440static dbus_bool_t
441bus_driver_handle_acquire_service (DBusConnection *connection,
442                                   BusTransaction *transaction,
443                                   DBusMessage    *message,
444                                   DBusError      *error)
445{
446  DBusMessage *reply;
447  DBusString service_name;
448  char *name;
449  int service_reply;
450  int flags;
451  dbus_bool_t retval;
452  BusRegistry *registry;
453
454  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
455
456  registry = bus_connection_get_registry (connection);
457
458  if (!dbus_message_get_args (message, error,
459                              DBUS_TYPE_STRING, &name,
460                              DBUS_TYPE_UINT32, &flags,
461                              DBUS_TYPE_INVALID))
462    return FALSE;
463
464  _dbus_verbose ("Trying to own service %s with flags 0x%x\n", name, flags);
465
466  retval = FALSE;
467  reply = NULL;
468
469  _dbus_string_init_const (&service_name, name);
470
471  if (!bus_registry_acquire_service (registry, connection,
472                                     &service_name, flags,
473                                     &service_reply, transaction,
474                                     error))
475    goto out;
476
477  reply = dbus_message_new_method_return (message);
478  if (reply == NULL)
479    {
480      BUS_SET_OOM (error);
481      goto out;
482    }
483
484  if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, service_reply, DBUS_TYPE_INVALID))
485    {
486      BUS_SET_OOM (error);
487      goto out;
488    }
489
490  if (!bus_transaction_send_from_driver (transaction, connection, reply))
491    {
492      BUS_SET_OOM (error);
493      goto out;
494    }
495
496  retval = TRUE;
497
498 out:
499  dbus_free (name);
500  if (reply)
501    dbus_message_unref (reply);
502  return retval;
503}
504
505static dbus_bool_t
506bus_driver_handle_service_exists (DBusConnection *connection,
507                                  BusTransaction *transaction,
508                                  DBusMessage    *message,
509                                  DBusError      *error)
510{
511  DBusMessage *reply;
512  DBusString service_name;
513  BusService *service;
514  char *name;
515  dbus_bool_t retval;
516  BusRegistry *registry;
517
518  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
519
520  registry = bus_connection_get_registry (connection);
521
522  if (!dbus_message_get_args (message, error,
523                              DBUS_TYPE_STRING, &name,
524                              DBUS_TYPE_INVALID))
525    return FALSE;
526
527  retval = FALSE;
528
529  _dbus_string_init_const (&service_name, name);
530  service = bus_registry_lookup (registry, &service_name);
531
532  reply = dbus_message_new_method_return (message);
533  if (reply == NULL)
534    {
535      BUS_SET_OOM (error);
536      goto out;
537    }
538
539  if (!dbus_message_append_args (reply,
540                                 DBUS_TYPE_UINT32, service != NULL,
541                                 0))
542    {
543      BUS_SET_OOM (error);
544      goto out;
545    }
546
547  if (!bus_transaction_send_from_driver (transaction, connection, reply))
548    {
549      BUS_SET_OOM (error);
550      goto out;
551    }
552
553  retval = TRUE;
554
555 out:
556  if (reply)
557    dbus_message_unref (reply);
558  dbus_free (name);
559
560  return retval;
561}
562
563static dbus_bool_t
564bus_driver_handle_activate_service (DBusConnection *connection,
565                                    BusTransaction *transaction,
566                                    DBusMessage    *message,
567                                    DBusError      *error)
568{
569  dbus_uint32_t flags;
570  char *name;
571  dbus_bool_t retval;
572  BusActivation *activation;
573
574  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
575
576  activation = bus_connection_get_activation (connection);
577
578  if (!dbus_message_get_args (message, error,
579                              DBUS_TYPE_STRING, &name,
580                              DBUS_TYPE_UINT32, &flags,
581                              DBUS_TYPE_INVALID))
582    {
583      _DBUS_ASSERT_ERROR_IS_SET (error);
584      _dbus_verbose ("No memory to get arguments to ActivateService\n");
585      return FALSE;
586    }
587
588  retval = FALSE;
589
590  if (!bus_activation_activate_service (activation, connection, transaction,
591                                        message, name, error))
592    {
593      _DBUS_ASSERT_ERROR_IS_SET (error);
594      _dbus_verbose ("bus_activation_activate_service() failed\n");
595      goto out;
596    }
597
598  retval = TRUE;
599
600 out:
601  dbus_free (name);
602  return retval;
603}
604
605static dbus_bool_t
606send_ack_reply (DBusConnection *connection,
607                BusTransaction *transaction,
608                DBusMessage    *message,
609                DBusError      *error)
610{
611  DBusMessage *reply;
612
613  reply = dbus_message_new_method_return (message);
614  if (reply == NULL)
615    {
616      BUS_SET_OOM (error);
617      return FALSE;
618    }
619
620  if (!bus_transaction_send_from_driver (transaction, connection, reply))
621    {
622      BUS_SET_OOM (error);
623      dbus_message_unref (reply);
624      return FALSE;
625    }
626
627  dbus_message_unref (reply);
628
629  return TRUE;
630}
631
632static dbus_bool_t
633bus_driver_handle_add_match (DBusConnection *connection,
634                             BusTransaction *transaction,
635                             DBusMessage    *message,
636                             DBusError      *error)
637{
638  BusMatchRule *rule;
639  char *text;
640  DBusString str;
641  BusMatchmaker *matchmaker;
642
643  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
644
645  text = NULL;
646  rule = NULL;
647
648  if (bus_connection_get_n_match_rules (connection) >=
649      bus_context_get_max_match_rules_per_connection (bus_transaction_get_context (transaction)))
650    {
651      dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
652                      "Connection \"%s\" is not allowed to add more match rules "
653                      "(increase limits in configuration file if required)",
654                      bus_connection_is_active (connection) ?
655                      bus_connection_get_name (connection) :
656                      "(inactive)");
657      goto failed;
658    }
659
660  if (!dbus_message_get_args (message, error,
661                              DBUS_TYPE_STRING, &text,
662                              DBUS_TYPE_INVALID))
663    {
664      _dbus_verbose ("No memory to get arguments to AddMatch\n");
665      goto failed;
666    }
667
668  _dbus_string_init_const (&str, text);
669
670  rule = bus_match_rule_parse (connection, &str, error);
671  if (rule == NULL)
672    goto failed;
673
674  matchmaker = bus_connection_get_matchmaker (connection);
675
676  if (!bus_matchmaker_add_rule (matchmaker, rule))
677    {
678      BUS_SET_OOM (error);
679      goto failed;
680    }
681
682  if (!send_ack_reply (connection, transaction,
683                       message, error))
684    {
685      bus_matchmaker_remove_rule (matchmaker, rule);
686      goto failed;
687    }
688
689  bus_match_rule_unref (rule);
690  dbus_free (text);
691
692  return TRUE;
693
694 failed:
695  _DBUS_ASSERT_ERROR_IS_SET (error);
696  if (rule)
697    bus_match_rule_unref (rule);
698  if (text)
699    dbus_free (text);
700  return FALSE;
701}
702
703static dbus_bool_t
704bus_driver_handle_remove_match (DBusConnection *connection,
705                                BusTransaction *transaction,
706                                DBusMessage    *message,
707                                DBusError      *error)
708{
709  BusMatchRule *rule;
710  char *text;
711  DBusString str;
712  BusMatchmaker *matchmaker;
713
714  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
715
716  text = NULL;
717  rule = NULL;
718
719  if (!dbus_message_get_args (message, error,
720                              DBUS_TYPE_STRING, &text,
721                              DBUS_TYPE_INVALID))
722    {
723      _dbus_verbose ("No memory to get arguments to RemoveMatch\n");
724      goto failed;
725    }
726
727  _dbus_string_init_const (&str, text);
728
729  rule = bus_match_rule_parse (connection, &str, error);
730  if (rule == NULL)
731    goto failed;
732
733  /* Send the ack before we remove the rule, since the ack is undone
734   * on transaction cancel, but rule removal isn't.
735   */
736  if (!send_ack_reply (connection, transaction,
737                       message, error))
738    goto failed;
739
740  matchmaker = bus_connection_get_matchmaker (connection);
741
742  if (!bus_matchmaker_remove_rule_by_value (matchmaker, rule, error))
743    goto failed;
744
745  bus_match_rule_unref (rule);
746  dbus_free (text);
747
748  return TRUE;
749
750 failed:
751  _DBUS_ASSERT_ERROR_IS_SET (error);
752  if (rule)
753    bus_match_rule_unref (rule);
754  if (text)
755    dbus_free (text);
756  return FALSE;
757}
758
759/* For speed it might be useful to sort this in order of
760 * frequency of use (but doesn't matter with only a few items
761 * anyhow)
762 */
763struct
764{
765  const char *name;
766  dbus_bool_t (* handler) (DBusConnection *connection,
767                           BusTransaction *transaction,
768                           DBusMessage    *message,
769                           DBusError      *error);
770} message_handlers[] = {
771  { "AcquireService", bus_driver_handle_acquire_service },
772  { "ActivateService", bus_driver_handle_activate_service },
773  { "Hello", bus_driver_handle_hello },
774  { "ServiceExists", bus_driver_handle_service_exists },
775  { "ListServices", bus_driver_handle_list_services },
776  { "AddMatch", bus_driver_handle_add_match },
777  { "RemoveMatch", bus_driver_handle_remove_match }
778};
779
780dbus_bool_t
781bus_driver_handle_message (DBusConnection *connection,
782                           BusTransaction *transaction,
783			   DBusMessage    *message,
784                           DBusError      *error)
785{
786  const char *name, *sender;
787  int i;
788
789  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
790
791  if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
792    {
793      _dbus_verbose ("Driver got a non-method-call message, ignoring\n");
794      return TRUE; /* we just ignore this */
795    }
796
797  _dbus_assert (dbus_message_get_interface (message) != NULL);
798  _dbus_assert (dbus_message_get_member (message) != NULL);
799
800  name = dbus_message_get_member (message);
801  sender = dbus_message_get_sender (message);
802
803  if (strcmp (dbus_message_get_interface (message),
804              DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS) != 0)
805    {
806      _dbus_verbose ("Driver got message to unknown interface \"%s\"\n",
807                     dbus_message_get_interface (message));
808      goto unknown;
809    }
810
811  _dbus_verbose ("Driver got a method call: %s\n",
812		 dbus_message_get_member (message));
813
814  /* security checks should have kept this from getting here */
815  _dbus_assert (sender != NULL || strcmp (name, "Hello") == 0);
816
817  if (dbus_message_get_reply_serial (message) != 0)
818    {
819      _dbus_verbose ("Client sent a reply to the bus driver, ignoring it\n");
820      return TRUE;
821    }
822
823  i = 0;
824  while (i < _DBUS_N_ELEMENTS (message_handlers))
825    {
826      if (strcmp (message_handlers[i].name, name) == 0)
827        {
828          _dbus_verbose ("Running driver handler for %s\n", name);
829          if ((* message_handlers[i].handler) (connection, transaction, message, error))
830            {
831              _DBUS_ASSERT_ERROR_IS_CLEAR (error);
832              _dbus_verbose ("Driver handler succeeded\n");
833              return TRUE;
834            }
835          else
836            {
837              _DBUS_ASSERT_ERROR_IS_SET (error);
838              _dbus_verbose ("Driver handler returned failure\n");
839              return FALSE;
840            }
841        }
842
843      ++i;
844    }
845
846 unknown:
847  _dbus_verbose ("No driver handler for message \"%s\"\n",
848                 name);
849
850  dbus_set_error (error, DBUS_ERROR_UNKNOWN_METHOD,
851                  "%s does not understand message %s",
852                  DBUS_SERVICE_ORG_FREEDESKTOP_DBUS, name);
853
854  return FALSE;
855}
856
857void
858bus_driver_remove_connection (DBusConnection *connection)
859{
860  /* FIXME Does nothing for now, should unregister the connection
861   * with the bus driver.
862   */
863}
864