* configure.in: Add test/name-test/Makefile to the generated
[platform/upstream/dbus.git] / bus / driver.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* driver.c  Bus client (driver)
3  *
4  * Copyright (C) 2003 CodeFactory AB
5  * Copyright (C) 2003, 2004, 2005 Red Hat, Inc.
6  *
7  * Licensed under the Academic Free License version 2.1
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 "selinux.h"
31 #include "signals.h"
32 #include "utils.h"
33 #include <dbus/dbus-string.h>
34 #include <dbus/dbus-internals.h>
35 #include <dbus/dbus-marshal-recursive.h>
36 #include <string.h>
37
38 static dbus_bool_t bus_driver_send_welcome_message (DBusConnection *connection,
39                                                     DBusMessage    *hello_message,
40                                                     BusTransaction *transaction,
41                                                     DBusError      *error);
42
43 dbus_bool_t
44 bus_driver_send_service_owner_changed (const char     *service_name,
45                                        const char     *old_owner,
46                                        const char     *new_owner,
47                                        BusTransaction *transaction,
48                                        DBusError      *error)
49 {
50   DBusMessage *message;
51   dbus_bool_t retval;
52   const char *null_service;
53
54   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
55
56   null_service = "";
57   _dbus_verbose ("sending name owner changed: %s [%s -> %s]\n",
58                  service_name, 
59                  old_owner ? old_owner : null_service, 
60                  new_owner ? new_owner : null_service);
61
62   message = dbus_message_new_signal (DBUS_PATH_DBUS,
63                                      DBUS_INTERFACE_DBUS,
64                                      "NameOwnerChanged");
65   
66   if (message == NULL)
67     {
68       BUS_SET_OOM (error);
69       return FALSE;
70     }
71   
72   if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS))
73     goto oom;
74
75   if (!dbus_message_append_args (message,
76                                  DBUS_TYPE_STRING, &service_name,
77                                  DBUS_TYPE_STRING, old_owner ? &old_owner : &null_service,
78                                  DBUS_TYPE_STRING, new_owner ? &new_owner : &null_service,
79                                  DBUS_TYPE_INVALID))
80     goto oom;
81
82   _dbus_assert (dbus_message_has_signature (message, "sss"));
83   
84   retval = bus_dispatch_matches (transaction, NULL, NULL, message, error);
85   dbus_message_unref (message);
86
87   return retval;
88
89  oom:
90   dbus_message_unref (message);
91   BUS_SET_OOM (error);
92   return FALSE;
93 }
94
95 dbus_bool_t
96 bus_driver_send_service_lost (DBusConnection *connection,
97                               const char     *service_name,
98                               BusTransaction *transaction,
99                               DBusError      *error)
100 {
101   DBusMessage *message;
102
103   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
104   
105   message = dbus_message_new_signal (DBUS_PATH_DBUS,
106                                      DBUS_INTERFACE_DBUS,
107                                      "NameLost");
108   
109   if (message == NULL)
110     {
111       BUS_SET_OOM (error);
112       return FALSE;
113     }
114   
115   if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) ||
116       !dbus_message_append_args (message,
117                                  DBUS_TYPE_STRING, &service_name,
118                                  DBUS_TYPE_INVALID))
119     {
120       dbus_message_unref (message);
121       BUS_SET_OOM (error);
122       return FALSE;
123     }
124
125   if (!bus_transaction_send_from_driver (transaction, connection, message))
126     {
127       dbus_message_unref (message);
128       BUS_SET_OOM (error);
129       return FALSE;
130     }
131   else
132     {
133       dbus_message_unref (message);
134       return TRUE;
135     }
136 }
137
138 dbus_bool_t
139 bus_driver_send_service_acquired (DBusConnection *connection,
140                                   const char     *service_name,
141                                   BusTransaction *transaction,
142                                   DBusError      *error)
143 {
144   DBusMessage *message;
145
146   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
147   
148   message = dbus_message_new_signal (DBUS_PATH_DBUS,
149                                      DBUS_INTERFACE_DBUS,
150                                      "NameAcquired");
151
152   if (message == NULL)
153     {
154       BUS_SET_OOM (error);
155       return FALSE;
156     }
157   
158   if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) ||
159       !dbus_message_append_args (message,
160                                  DBUS_TYPE_STRING, &service_name,
161                                  DBUS_TYPE_INVALID))
162     {
163       dbus_message_unref (message);
164       BUS_SET_OOM (error);
165       return FALSE;
166     }
167
168   if (!bus_transaction_send_from_driver (transaction, connection, message))
169     {
170       dbus_message_unref (message);
171       BUS_SET_OOM (error);
172       return FALSE;
173     }
174   else
175     {
176       dbus_message_unref (message);
177       return TRUE;
178     }
179 }
180
181 static dbus_bool_t
182 create_unique_client_name (BusRegistry *registry,
183                            DBusString  *str)
184 {
185   /* We never want to use the same unique client name twice, because
186    * we want to guarantee that if you send a message to a given unique
187    * name, you always get the same application. So we use two numbers
188    * for INT_MAX * INT_MAX combinations, should be pretty safe against
189    * wraparound.
190    */
191   /* FIXME these should be in BusRegistry rather than static vars */
192   static int next_major_number = 0;
193   static int next_minor_number = 0;
194   int len;
195   
196   len = _dbus_string_get_length (str);
197   
198   while (TRUE)
199     {
200       /* start out with 1-0, go to 1-1, 1-2, 1-3,
201        * up to 1-MAXINT, then 2-0, 2-1, etc.
202        */
203       if (next_minor_number <= 0)
204         {
205           next_major_number += 1;
206           next_minor_number = 0;
207           if (next_major_number <= 0)
208             _dbus_assert_not_reached ("INT_MAX * INT_MAX clients were added");
209         }
210
211       _dbus_assert (next_major_number > 0);
212       _dbus_assert (next_minor_number >= 0);
213
214       /* appname:MAJOR-MINOR */
215       
216       if (!_dbus_string_append (str, ":"))
217         return FALSE;
218       
219       if (!_dbus_string_append_int (str, next_major_number))
220         return FALSE;
221
222       if (!_dbus_string_append (str, "."))
223         return FALSE;
224       
225       if (!_dbus_string_append_int (str, next_minor_number))
226         return FALSE;
227
228       next_minor_number += 1;
229       
230       /* Check if a client with the name exists */
231       if (bus_registry_lookup (registry, str) == NULL)
232         break;
233
234       /* drop the number again, try the next one. */
235       _dbus_string_set_length (str, len);
236     }
237
238   return TRUE;
239 }
240
241 static dbus_bool_t
242 bus_driver_handle_hello (DBusConnection *connection,
243                          BusTransaction *transaction,
244                          DBusMessage    *message,
245                          DBusError      *error)
246 {
247   DBusString unique_name;
248   BusService *service;
249   dbus_bool_t retval;
250   BusRegistry *registry;
251   BusConnections *connections;
252
253   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
254
255   if (bus_connection_is_active (connection))
256     {
257       /* We already handled an Hello message for this connection. */
258       dbus_set_error (error, DBUS_ERROR_FAILED,
259                       "Already handled an Hello message");
260       return FALSE;
261     }
262
263   /* Note that when these limits are exceeded we don't disconnect the
264    * connection; we just sort of leave it hanging there until it times
265    * out or disconnects itself or is dropped due to the max number of
266    * incomplete connections. It's even OK if the connection wants to
267    * retry the hello message, we support that.
268    */
269   connections = bus_connection_get_connections (connection);
270   if (!bus_connections_check_limits (connections, connection,
271                                      error))
272     {
273       _DBUS_ASSERT_ERROR_IS_SET (error);
274       return FALSE;
275     }
276   
277   if (!_dbus_string_init (&unique_name))
278     {
279       BUS_SET_OOM (error);
280       return FALSE;
281     }
282
283   retval = FALSE;
284
285   registry = bus_connection_get_registry (connection);
286   
287   if (!create_unique_client_name (registry, &unique_name))
288     {
289       BUS_SET_OOM (error);
290       goto out_0;
291     }
292
293   if (!bus_connection_complete (connection, &unique_name, error))
294     {
295       _DBUS_ASSERT_ERROR_IS_SET (error);
296       goto out_0;
297     }
298   
299   if (!dbus_message_set_sender (message,
300                                 bus_connection_get_name (connection)))
301     {
302       BUS_SET_OOM (error);
303       goto out_0;
304     }
305   
306   if (!bus_driver_send_welcome_message (connection, message, transaction, error))
307     goto out_0;
308
309   /* Create the service */
310   service = bus_registry_ensure (registry,
311                                  &unique_name, connection, 0, transaction, error);
312   if (service == NULL)
313     goto out_0;
314   
315   _dbus_assert (bus_connection_is_active (connection));
316   retval = TRUE;
317   
318  out_0:
319   _dbus_string_free (&unique_name);
320   return retval;
321 }
322
323 static dbus_bool_t
324 bus_driver_send_welcome_message (DBusConnection *connection,
325                                  DBusMessage    *hello_message,
326                                  BusTransaction *transaction,
327                                  DBusError      *error)
328 {
329   DBusMessage *welcome;
330   const char *name;
331
332   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
333   
334   name = bus_connection_get_name (connection);
335   _dbus_assert (name != NULL);
336   
337   welcome = dbus_message_new_method_return (hello_message);
338   if (welcome == NULL)
339     {
340       BUS_SET_OOM (error);
341       return FALSE;
342     }
343   
344   if (!dbus_message_append_args (welcome,
345                                  DBUS_TYPE_STRING, &name,
346                                  DBUS_TYPE_INVALID))
347     {
348       dbus_message_unref (welcome);
349       BUS_SET_OOM (error);
350       return FALSE;
351     }
352
353   _dbus_assert (dbus_message_has_signature (welcome, DBUS_TYPE_STRING_AS_STRING));
354   
355   if (!bus_transaction_send_from_driver (transaction, connection, welcome))
356     {
357       dbus_message_unref (welcome);
358       BUS_SET_OOM (error);
359       return FALSE;
360     }
361   else
362     {
363       dbus_message_unref (welcome);
364       return TRUE;
365     }
366 }
367
368 static dbus_bool_t
369 bus_driver_handle_list_services (DBusConnection *connection,
370                                  BusTransaction *transaction,
371                                  DBusMessage    *message,
372                                  DBusError      *error)
373 {
374   DBusMessage *reply;
375   int len;
376   char **services;
377   BusRegistry *registry;
378   int i;
379   DBusMessageIter iter;
380   DBusMessageIter sub;
381
382   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
383   
384   registry = bus_connection_get_registry (connection);
385   
386   reply = dbus_message_new_method_return (message);
387   if (reply == NULL)
388     {
389       BUS_SET_OOM (error);
390       return FALSE;
391     }
392
393   if (!bus_registry_list_services (registry, &services, &len))
394     {
395       dbus_message_unref (reply);
396       BUS_SET_OOM (error);
397       return FALSE;
398     }
399
400   dbus_message_iter_init_append (reply, &iter);
401   
402   if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
403                                          DBUS_TYPE_STRING_AS_STRING,
404                                          &sub))
405     {
406       dbus_free_string_array (services);
407       dbus_message_unref (reply);
408       BUS_SET_OOM (error);
409       return FALSE;
410     }
411
412   {
413     /* Include the bus driver in the list */
414     const char *v_STRING = DBUS_SERVICE_DBUS;
415     if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
416                                          &v_STRING))
417       {
418         dbus_free_string_array (services);
419         dbus_message_unref (reply);
420         BUS_SET_OOM (error);
421         return FALSE;
422       }
423   }
424   
425   i = 0;
426   while (i < len)
427     {
428       if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
429                                            &services[i]))
430         {
431           dbus_free_string_array (services);
432           dbus_message_unref (reply);
433           BUS_SET_OOM (error);
434           return FALSE;
435         }
436       ++i;
437     }
438
439   if (!dbus_message_iter_close_container (&iter, &sub))
440     {
441       dbus_free_string_array (services);
442       dbus_message_unref (reply);
443       BUS_SET_OOM (error);
444       return FALSE;
445     }
446   
447   dbus_free_string_array (services);
448   
449   if (!bus_transaction_send_from_driver (transaction, connection, reply))
450     {
451       dbus_message_unref (reply);
452       BUS_SET_OOM (error);
453       return FALSE;
454     }
455   else
456     {
457       dbus_message_unref (reply);
458       return TRUE;
459     }
460 }
461
462 static dbus_bool_t
463 bus_driver_handle_acquire_service (DBusConnection *connection,
464                                    BusTransaction *transaction,
465                                    DBusMessage    *message,
466                                    DBusError      *error)
467 {
468   DBusMessage *reply;
469   DBusString service_name;
470   const char *name;
471   dbus_uint32_t service_reply;
472   dbus_uint32_t flags;
473   dbus_bool_t retval;
474   BusRegistry *registry;
475
476   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
477   
478   registry = bus_connection_get_registry (connection);
479   
480   if (!dbus_message_get_args (message, error,
481                               DBUS_TYPE_STRING, &name,
482                               DBUS_TYPE_UINT32, &flags,
483                               DBUS_TYPE_INVALID))
484     return FALSE;
485   
486   _dbus_verbose ("Trying to own name %s with flags 0x%x\n", name, flags);
487   
488   retval = FALSE;
489   reply = NULL;
490
491   _dbus_string_init_const (&service_name, name);
492
493   if (!bus_registry_acquire_service (registry, connection,
494                                      &service_name, flags,
495                                      &service_reply, transaction,
496                                      error))
497     goto out;
498   
499   reply = dbus_message_new_method_return (message);
500   if (reply == NULL)
501     {
502       BUS_SET_OOM (error);
503       goto out;
504     }
505
506   if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, &service_reply, DBUS_TYPE_INVALID))
507     {
508       BUS_SET_OOM (error);
509       goto out;
510     }
511
512   if (!bus_transaction_send_from_driver (transaction, connection, reply))
513     {
514       BUS_SET_OOM (error);
515       goto out;
516     }
517
518   retval = TRUE;
519   
520  out:
521   if (reply)
522     dbus_message_unref (reply);
523   return retval;
524
525
526 static dbus_bool_t
527 bus_driver_handle_release_service (DBusConnection *connection,
528                                    BusTransaction *transaction,
529                                    DBusMessage    *message,
530                                    DBusError      *error)
531 {
532   DBusMessage *reply;
533   DBusString service_name;
534   const char *name;
535   dbus_uint32_t service_reply;
536   dbus_bool_t retval;
537   BusRegistry *registry;
538
539   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
540
541   registry = bus_connection_get_registry (connection);
542
543   if (!dbus_message_get_args (message, error,
544                               DBUS_TYPE_STRING, &name,
545                               DBUS_TYPE_INVALID))
546     return FALSE;
547
548   _dbus_verbose ("Trying to release name %s\n", name);
549
550   retval = FALSE;
551   reply = NULL;
552
553   _dbus_string_init_const (&service_name, name);
554
555   if (!bus_registry_release_service (registry, connection,
556                                      &service_name, &service_reply,
557                                      transaction, error))
558     goto out;
559
560   reply = dbus_message_new_method_return (message);
561   if (reply == NULL)
562     {
563       BUS_SET_OOM (error);
564       goto out;
565     }
566
567   if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, &service_reply, DBUS_TYPE_INVALID))
568     {
569       BUS_SET_OOM (error);
570       goto out;
571     }
572
573   if (!bus_transaction_send_from_driver (transaction, connection, reply))
574     {
575       BUS_SET_OOM (error);
576       goto out;
577     }
578
579   retval = TRUE;
580
581  out:
582   if (reply)
583     dbus_message_unref (reply);
584   return retval;
585 }
586
587 static dbus_bool_t
588 bus_driver_handle_service_exists (DBusConnection *connection,
589                                   BusTransaction *transaction,
590                                   DBusMessage    *message,
591                                   DBusError      *error)
592 {
593   DBusMessage *reply;
594   DBusString service_name;
595   BusService *service;
596   dbus_bool_t service_exists;
597   const char *name;
598   dbus_bool_t retval;
599   BusRegistry *registry;
600
601   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
602   
603   registry = bus_connection_get_registry (connection);
604   
605   if (!dbus_message_get_args (message, error,
606                               DBUS_TYPE_STRING, &name,
607                               DBUS_TYPE_INVALID))
608     return FALSE;
609
610   retval = FALSE;
611
612   if (strcmp (name, DBUS_SERVICE_DBUS) == 0)
613     {
614       service_exists = TRUE;
615     }
616   else
617     {
618       _dbus_string_init_const (&service_name, name);
619       service = bus_registry_lookup (registry, &service_name);
620       service_exists = service != NULL;
621     }
622   
623   reply = dbus_message_new_method_return (message);
624   if (reply == NULL)
625     {
626       BUS_SET_OOM (error);
627       goto out;
628     }
629
630   if (!dbus_message_append_args (reply,
631                                  DBUS_TYPE_BOOLEAN, &service_exists,
632                                  0))
633     {
634       BUS_SET_OOM (error);
635       goto out;
636     }
637
638   if (!bus_transaction_send_from_driver (transaction, connection, reply))
639     {
640       BUS_SET_OOM (error);
641       goto out;
642     }
643
644   retval = TRUE;
645   
646  out:
647   if (reply)
648     dbus_message_unref (reply);
649
650   return retval;
651 }
652
653 static dbus_bool_t
654 bus_driver_handle_activate_service (DBusConnection *connection,
655                                     BusTransaction *transaction,
656                                     DBusMessage    *message,
657                                     DBusError      *error)
658 {
659   dbus_uint32_t flags;
660   const char *name;
661   dbus_bool_t retval;
662   BusActivation *activation;
663
664   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
665   
666   activation = bus_connection_get_activation (connection);
667   
668   if (!dbus_message_get_args (message, error,
669                               DBUS_TYPE_STRING, &name,
670                               DBUS_TYPE_UINT32, &flags,
671                               DBUS_TYPE_INVALID))
672     {
673       _DBUS_ASSERT_ERROR_IS_SET (error);
674       _dbus_verbose ("No memory to get arguments to StartServiceByName\n");
675       return FALSE;
676     }
677
678   retval = FALSE;
679
680   if (!bus_activation_activate_service (activation, connection, transaction, FALSE,
681                                         message, name, error))
682     {
683       _DBUS_ASSERT_ERROR_IS_SET (error);
684       _dbus_verbose ("bus_activation_activate_service() failed\n");
685       goto out;
686     }
687
688   retval = TRUE;
689   
690  out:
691   return retval;
692 }
693
694 static dbus_bool_t
695 send_ack_reply (DBusConnection *connection,
696                 BusTransaction *transaction,
697                 DBusMessage    *message,
698                 DBusError      *error)
699 {
700   DBusMessage *reply;
701
702   reply = dbus_message_new_method_return (message);
703   if (reply == NULL)
704     {
705       BUS_SET_OOM (error);
706       return FALSE;
707     }
708
709   if (!bus_transaction_send_from_driver (transaction, connection, reply))
710     {
711       BUS_SET_OOM (error);
712       dbus_message_unref (reply);
713       return FALSE;
714     }
715
716   dbus_message_unref (reply);
717   
718   return TRUE;
719 }
720
721 static dbus_bool_t
722 bus_driver_handle_add_match (DBusConnection *connection,
723                              BusTransaction *transaction,
724                              DBusMessage    *message,
725                              DBusError      *error)
726 {
727   BusMatchRule *rule;
728   const char *text;
729   DBusString str;
730   BusMatchmaker *matchmaker;
731   
732   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
733
734   text = NULL;
735   rule = NULL;
736
737   if (bus_connection_get_n_match_rules (connection) >=
738       bus_context_get_max_match_rules_per_connection (bus_transaction_get_context (transaction)))
739     {
740       dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
741                       "Connection \"%s\" is not allowed to add more match rules "
742                       "(increase limits in configuration file if required)",
743                       bus_connection_is_active (connection) ?
744                       bus_connection_get_name (connection) :
745                       "(inactive)");
746       goto failed;
747     }
748   
749   if (!dbus_message_get_args (message, error,
750                               DBUS_TYPE_STRING, &text,
751                               DBUS_TYPE_INVALID))
752     {
753       _dbus_verbose ("No memory to get arguments to AddMatch\n");
754       goto failed;
755     }
756
757   _dbus_string_init_const (&str, text);
758
759   rule = bus_match_rule_parse (connection, &str, error);
760   if (rule == NULL)
761     goto failed;
762
763   matchmaker = bus_connection_get_matchmaker (connection);
764
765   if (!bus_matchmaker_add_rule (matchmaker, rule))
766     {
767       BUS_SET_OOM (error);
768       goto failed;
769     }
770
771   if (!send_ack_reply (connection, transaction,
772                        message, error))
773     {
774       bus_matchmaker_remove_rule (matchmaker, rule);
775       goto failed;
776     }
777   
778   bus_match_rule_unref (rule);
779   
780   return TRUE;
781
782  failed:
783   _DBUS_ASSERT_ERROR_IS_SET (error);
784   if (rule)
785     bus_match_rule_unref (rule);
786   return FALSE;
787 }
788
789 static dbus_bool_t
790 bus_driver_handle_remove_match (DBusConnection *connection,
791                                 BusTransaction *transaction,
792                                 DBusMessage    *message,
793                                 DBusError      *error)
794 {
795   BusMatchRule *rule;
796   const char *text;
797   DBusString str;
798   BusMatchmaker *matchmaker;
799   
800   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
801
802   text = NULL;
803   rule = NULL;
804   
805   if (!dbus_message_get_args (message, error,
806                               DBUS_TYPE_STRING, &text,
807                               DBUS_TYPE_INVALID))
808     {
809       _dbus_verbose ("No memory to get arguments to RemoveMatch\n");
810       goto failed;
811     }
812
813   _dbus_string_init_const (&str, text);
814
815   rule = bus_match_rule_parse (connection, &str, error);
816   if (rule == NULL)
817     goto failed;
818
819   /* Send the ack before we remove the rule, since the ack is undone
820    * on transaction cancel, but rule removal isn't.
821    */
822   if (!send_ack_reply (connection, transaction,
823                        message, error))
824     goto failed;
825   
826   matchmaker = bus_connection_get_matchmaker (connection);
827
828   if (!bus_matchmaker_remove_rule_by_value (matchmaker, rule, error))
829     goto failed;
830
831   bus_match_rule_unref (rule);
832   
833   return TRUE;
834
835  failed:
836   _DBUS_ASSERT_ERROR_IS_SET (error);
837   if (rule)
838     bus_match_rule_unref (rule);
839   return FALSE;
840 }
841
842 static dbus_bool_t
843 bus_driver_handle_get_service_owner (DBusConnection *connection,
844                                      BusTransaction *transaction,
845                                      DBusMessage    *message,
846                                      DBusError      *error)
847 {
848   const char *text;
849   const char *base_name;
850   DBusString str;
851   BusRegistry *registry;
852   BusService *service;
853   DBusMessage *reply;
854   
855   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
856
857   registry = bus_connection_get_registry (connection);
858
859   text = NULL;
860   reply = NULL;
861
862   if (! dbus_message_get_args (message, error,
863                                DBUS_TYPE_STRING, &text,
864                                DBUS_TYPE_INVALID))
865       goto failed;
866
867   _dbus_string_init_const (&str, text);
868   service = bus_registry_lookup (registry, &str);
869   if (service == NULL &&
870       _dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS))
871     {
872       /* ORG_FREEDESKTOP_DBUS owns itself */
873       base_name = DBUS_SERVICE_DBUS;
874     }
875   else if (service == NULL)
876     {
877       dbus_set_error (error, 
878                       DBUS_ERROR_NAME_HAS_NO_OWNER,
879                       "Could not get owner of name '%s': no such name", text);
880       goto failed;
881     }
882   else
883     {
884       base_name = bus_connection_get_name (bus_service_get_primary_owners_connection (service));
885       if (base_name == NULL)
886         {
887           /* FIXME - how is this error possible? */
888           dbus_set_error (error,
889                           DBUS_ERROR_FAILED,
890                           "Could not determine unique name for '%s'", text);
891           goto failed;
892         }
893       _dbus_assert (*base_name == ':');      
894     }
895
896   _dbus_assert (base_name != NULL);
897
898   reply = dbus_message_new_method_return (message);
899   if (reply == NULL)
900     goto oom;
901
902   if (! dbus_message_append_args (reply, 
903                                   DBUS_TYPE_STRING, &base_name,
904                                   DBUS_TYPE_INVALID))
905     goto oom;
906   
907   if (! bus_transaction_send_from_driver (transaction, connection, reply))
908     goto oom;
909
910   dbus_message_unref (reply);
911
912   return TRUE;
913
914  oom:
915   BUS_SET_OOM (error);
916
917  failed:
918   _DBUS_ASSERT_ERROR_IS_SET (error);
919   if (reply)
920     dbus_message_unref (reply);
921   return FALSE;
922 }
923
924 static dbus_bool_t
925 bus_driver_handle_list_queued_owners (DBusConnection *connection,
926                                       BusTransaction *transaction,
927                                       DBusMessage    *message,
928                                       DBusError      *error)
929 {
930   const char *text;
931   DBusList *base_names;
932   DBusList *link;
933   DBusString str;
934   BusRegistry *registry;
935   BusService *service;
936   DBusMessage *reply;
937   DBusMessageIter iter, array_iter;
938   char *dbus_service_name = DBUS_SERVICE_DBUS;
939   
940   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
941
942   registry = bus_connection_get_registry (connection);
943
944   base_names = NULL;
945   text = NULL;
946   reply = NULL;
947
948   if (! dbus_message_get_args (message, error,
949                                DBUS_TYPE_STRING, &text,
950                                DBUS_TYPE_INVALID))
951       goto failed;
952
953   _dbus_string_init_const (&str, text);
954   service = bus_registry_lookup (registry, &str);
955   if (service == NULL &&
956       _dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS))
957     {
958       /* ORG_FREEDESKTOP_DBUS owns itself */
959       if (! _dbus_list_append (&base_names, dbus_service_name))
960         goto oom;
961     }
962   else if (service == NULL)
963     {
964       dbus_set_error (error, 
965                       DBUS_ERROR_NAME_HAS_NO_OWNER,
966                       "Could not get owners of name '%s': no such name", text);
967       goto failed;
968     }
969   else
970     {
971       if (!bus_service_list_queued_owners (service, 
972                                            &base_names,
973                                            error))
974         goto failed;
975     }
976
977   _dbus_assert (base_names != NULL);
978
979   reply = dbus_message_new_method_return (message);
980   if (reply == NULL)
981     goto oom;
982
983   dbus_message_iter_init_append (reply, &iter);
984   if (!dbus_message_iter_open_container (&iter,
985                                          DBUS_TYPE_ARRAY,
986                                          DBUS_TYPE_STRING_AS_STRING,
987                                          &array_iter))
988     goto oom;
989   
990   link = _dbus_list_get_first_link (&base_names);
991   while (link != NULL)
992     {
993       char *uname;
994
995       _dbus_assert (link->data != NULL);
996       uname = (char *)link->data;
997     
998       if (!dbus_message_iter_append_basic (&array_iter, 
999                                            DBUS_TYPE_STRING,
1000                                            &uname))
1001         goto oom;
1002
1003       link = _dbus_list_get_next_link (&base_names, link);
1004     }
1005
1006   if (! dbus_message_iter_close_container (&iter, &array_iter))
1007     goto oom;
1008                                     
1009  
1010   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1011     goto oom;
1012
1013   dbus_message_unref (reply);
1014
1015   return TRUE;
1016
1017  oom:
1018   BUS_SET_OOM (error);
1019
1020  failed:
1021   _DBUS_ASSERT_ERROR_IS_SET (error);
1022   if (reply)
1023     dbus_message_unref (reply);
1024
1025   if (base_names)
1026     _dbus_list_clear (&base_names);
1027
1028   return FALSE;
1029 }
1030
1031 static dbus_bool_t
1032 bus_driver_handle_get_connection_unix_user (DBusConnection *connection,
1033                                             BusTransaction *transaction,
1034                                             DBusMessage    *message,
1035                                             DBusError      *error)
1036 {
1037   const char *service;
1038   DBusString str;
1039   BusRegistry *registry;
1040   BusService *serv;
1041   DBusConnection *conn;
1042   DBusMessage *reply;
1043   unsigned long uid;
1044   dbus_uint32_t uid32;
1045
1046   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1047
1048   registry = bus_connection_get_registry (connection);
1049
1050   service = NULL;
1051   reply = NULL;
1052
1053   if (! dbus_message_get_args (message, error,
1054                                DBUS_TYPE_STRING, &service,
1055                                DBUS_TYPE_INVALID))
1056       goto failed;
1057
1058   _dbus_verbose ("asked for UID of connection %s\n", service);
1059
1060   _dbus_string_init_const (&str, service);
1061   serv = bus_registry_lookup (registry, &str);
1062   if (serv == NULL)
1063     {
1064       dbus_set_error (error, 
1065                       DBUS_ERROR_NAME_HAS_NO_OWNER,
1066                       "Could not get UID of name '%s': no such name", service);
1067       goto failed;
1068     }
1069
1070   conn = bus_service_get_primary_owners_connection (serv);
1071
1072   reply = dbus_message_new_method_return (message);
1073   if (reply == NULL)
1074     goto oom;
1075
1076   if (!dbus_connection_get_unix_user (conn, &uid))
1077     {
1078       dbus_set_error (error,
1079                       DBUS_ERROR_FAILED,
1080                       "Could not determine UID for '%s'", service);
1081       goto failed;
1082     }
1083
1084   uid32 = uid;
1085   if (! dbus_message_append_args (reply,
1086                                   DBUS_TYPE_UINT32, &uid32,
1087                                   DBUS_TYPE_INVALID))
1088     goto oom;
1089
1090   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1091     goto oom;
1092
1093   dbus_message_unref (reply);
1094
1095   return TRUE;
1096
1097  oom:
1098   BUS_SET_OOM (error);
1099
1100  failed:
1101   _DBUS_ASSERT_ERROR_IS_SET (error);
1102   if (reply)
1103     dbus_message_unref (reply);
1104   return FALSE;
1105 }
1106
1107 static dbus_bool_t
1108 bus_driver_handle_get_connection_unix_process_id (DBusConnection *connection,
1109                                                   BusTransaction *transaction,
1110                                                   DBusMessage    *message,
1111                                                   DBusError      *error)
1112 {
1113   const char *service;
1114   DBusString str;
1115   BusRegistry *registry;
1116   BusService *serv;
1117   DBusConnection *conn;
1118   DBusMessage *reply;
1119   unsigned long pid;
1120   dbus_uint32_t pid32;
1121
1122   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1123
1124   registry = bus_connection_get_registry (connection);
1125
1126   service = NULL;
1127   reply = NULL;
1128
1129   if (! dbus_message_get_args (message, error,
1130                                DBUS_TYPE_STRING, &service,
1131                                DBUS_TYPE_INVALID))
1132       goto failed;
1133
1134   _dbus_verbose ("asked for PID of connection %s\n", service);
1135
1136   _dbus_string_init_const (&str, service);
1137   serv = bus_registry_lookup (registry, &str);
1138   if (serv == NULL)
1139     {
1140       dbus_set_error (error, 
1141                       DBUS_ERROR_NAME_HAS_NO_OWNER,
1142                       "Could not get PID of name '%s': no such name", service);
1143       goto failed;
1144     }
1145
1146   conn = bus_service_get_primary_owners_connection (serv);
1147
1148   reply = dbus_message_new_method_return (message);
1149   if (reply == NULL)
1150     goto oom;
1151
1152   if (!dbus_connection_get_unix_process_id (conn, &pid))
1153     {
1154       dbus_set_error (error,
1155                       DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN,
1156                       "Could not determine PID for '%s'", service);
1157       goto failed;
1158     }
1159
1160   pid32 = pid;
1161   if (! dbus_message_append_args (reply,
1162                                   DBUS_TYPE_UINT32, &pid32,
1163                                   DBUS_TYPE_INVALID))
1164     goto oom;
1165
1166   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1167     goto oom;
1168
1169   dbus_message_unref (reply);
1170
1171   return TRUE;
1172
1173  oom:
1174   BUS_SET_OOM (error);
1175
1176  failed:
1177   _DBUS_ASSERT_ERROR_IS_SET (error);
1178   if (reply)
1179     dbus_message_unref (reply);
1180   return FALSE;
1181 }
1182
1183 static dbus_bool_t
1184 bus_driver_handle_get_connection_selinux_security_context (DBusConnection *connection,
1185                                                            BusTransaction *transaction,
1186                                                            DBusMessage    *message,
1187                                                            DBusError      *error)
1188 {
1189   const char *service;
1190   DBusString str;
1191   BusRegistry *registry;
1192   BusService *serv;
1193   DBusConnection *conn;
1194   DBusMessage *reply;
1195   BusSELinuxID *context;
1196
1197   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1198
1199   registry = bus_connection_get_registry (connection);
1200
1201   service = NULL;
1202   reply = NULL;
1203
1204   if (! dbus_message_get_args (message, error,
1205                                DBUS_TYPE_STRING, &service,
1206                                DBUS_TYPE_INVALID))
1207       goto failed;
1208
1209   _dbus_verbose ("asked for security context of connection %s\n", service);
1210
1211   _dbus_string_init_const (&str, service);
1212   serv = bus_registry_lookup (registry, &str);
1213   if (serv == NULL)
1214     {
1215       dbus_set_error (error, 
1216                       DBUS_ERROR_NAME_HAS_NO_OWNER,
1217                       "Could not get security context of name '%s': no such name", service);
1218       goto failed;
1219     }
1220
1221   conn = bus_service_get_primary_owners_connection (serv);
1222
1223   reply = dbus_message_new_method_return (message);
1224   if (reply == NULL)
1225     goto oom;
1226
1227   context = bus_connection_get_selinux_id (conn);
1228   if (!context)
1229     {
1230       dbus_set_error (error,
1231                       DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN,
1232                       "Could not determine security context for '%s'", service);
1233       goto failed;
1234     }
1235
1236   if (! bus_selinux_append_context (reply, context, error))
1237     goto failed;
1238
1239   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1240     goto oom;
1241
1242   dbus_message_unref (reply);
1243
1244   return TRUE;
1245
1246  oom:
1247   BUS_SET_OOM (error);
1248
1249  failed:
1250   _DBUS_ASSERT_ERROR_IS_SET (error);
1251   if (reply)
1252     dbus_message_unref (reply);
1253   return FALSE;
1254 }
1255
1256 static dbus_bool_t
1257 bus_driver_handle_reload_config (DBusConnection *connection,
1258                                  BusTransaction *transaction,
1259                                  DBusMessage    *message,
1260                                  DBusError      *error)
1261 {
1262   BusContext *context;
1263   DBusMessage *reply;
1264
1265   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1266
1267   reply = NULL;
1268   
1269   context = bus_connection_get_context (connection);
1270   if (!bus_context_reload_config (context, error))
1271     goto failed;
1272
1273   reply = dbus_message_new_method_return (message);
1274   if (reply == NULL)
1275     goto oom;
1276
1277   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1278     goto oom;
1279
1280   dbus_message_unref (reply);
1281   return TRUE;
1282
1283  oom:
1284   BUS_SET_OOM (error);
1285
1286  failed:
1287   _DBUS_ASSERT_ERROR_IS_SET (error);
1288   if (reply)
1289     dbus_message_unref (reply);
1290   return FALSE;
1291 }
1292
1293 /* For speed it might be useful to sort this in order of
1294  * frequency of use (but doesn't matter with only a few items
1295  * anyhow)
1296  */
1297 struct
1298 {
1299   const char *name;
1300   const char *in_args;
1301   const char *out_args;
1302   dbus_bool_t (* handler) (DBusConnection *connection,
1303                            BusTransaction *transaction,
1304                            DBusMessage    *message,
1305                            DBusError      *error);
1306 } message_handlers[] = {
1307   { "RequestName",
1308     DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
1309     DBUS_TYPE_UINT32_AS_STRING,
1310     bus_driver_handle_acquire_service },
1311   { "ReleaseName",
1312     DBUS_TYPE_STRING_AS_STRING,
1313     DBUS_TYPE_UINT32_AS_STRING,
1314     bus_driver_handle_release_service },
1315   { "StartServiceByName",
1316     DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
1317     DBUS_TYPE_UINT32_AS_STRING,
1318     bus_driver_handle_activate_service },
1319   { "Hello",
1320     "",
1321     DBUS_TYPE_STRING_AS_STRING,
1322     bus_driver_handle_hello },
1323   { "NameHasOwner",
1324     DBUS_TYPE_STRING_AS_STRING,
1325     DBUS_TYPE_BOOLEAN_AS_STRING,
1326     bus_driver_handle_service_exists },
1327   { "ListNames",
1328     "",
1329     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
1330     bus_driver_handle_list_services },
1331   { "AddMatch",
1332     DBUS_TYPE_STRING_AS_STRING,
1333     "",
1334     bus_driver_handle_add_match },
1335   { "RemoveMatch",
1336     DBUS_TYPE_STRING_AS_STRING,
1337     "",
1338     bus_driver_handle_remove_match },
1339   { "GetNameOwner",
1340     DBUS_TYPE_STRING_AS_STRING,
1341     DBUS_TYPE_STRING_AS_STRING,
1342     bus_driver_handle_get_service_owner },
1343   { "ListQueuedOwners",
1344     DBUS_TYPE_STRING_AS_STRING,
1345     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
1346     bus_driver_handle_list_queued_owners },
1347   { "GetConnectionUnixUser",
1348     DBUS_TYPE_STRING_AS_STRING,
1349     DBUS_TYPE_UINT32_AS_STRING,
1350     bus_driver_handle_get_connection_unix_user },
1351   { "GetConnectionUnixProcessID",
1352     DBUS_TYPE_STRING_AS_STRING,
1353     DBUS_TYPE_UINT32_AS_STRING,
1354     bus_driver_handle_get_connection_unix_process_id },
1355   { "GetConnectionSELinuxSecurityContext",
1356     DBUS_TYPE_STRING_AS_STRING,
1357     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
1358     bus_driver_handle_get_connection_selinux_security_context },
1359   { "ReloadConfig",
1360     "",
1361     "",
1362     bus_driver_handle_reload_config }
1363 };
1364
1365 static dbus_bool_t
1366 write_args_for_direction (DBusString *xml,
1367                           const char *signature,
1368                           dbus_bool_t in)
1369 {
1370   DBusTypeReader typereader;
1371   DBusString sigstr;
1372   int current_type;
1373   
1374   _dbus_string_init_const (&sigstr, signature);
1375   _dbus_type_reader_init_types_only (&typereader, &sigstr, 0);
1376       
1377   while ((current_type = _dbus_type_reader_get_current_type (&typereader)) != DBUS_TYPE_INVALID)
1378     {
1379       const DBusString *subsig;
1380       int start, len;
1381
1382       _dbus_type_reader_get_signature (&typereader, &subsig, &start, &len);
1383       if (!_dbus_string_append_printf (xml, "      <arg direction=\"%s\" type=\"",
1384                                        in ? "in" : "out"))
1385         goto oom;
1386       if (!_dbus_string_append_len (xml,
1387                                     _dbus_string_get_const_data (subsig) + start,
1388                                     len))
1389         goto oom;
1390       if (!_dbus_string_append (xml, "\"/>\n"))
1391         goto oom;
1392
1393       _dbus_type_reader_next (&typereader);
1394     }
1395   return TRUE;
1396  oom:
1397   return FALSE;
1398 }
1399
1400 static dbus_bool_t
1401 bus_driver_handle_introspect (DBusConnection *connection,
1402                               BusTransaction *transaction,
1403                               DBusMessage    *message,
1404                               DBusError      *error)
1405 {
1406   DBusString xml;
1407   DBusMessage *reply;
1408   const char *v_STRING;
1409   int i;
1410
1411   _dbus_verbose ("Introspect() on bus driver\n");
1412   
1413   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1414
1415   reply = NULL;
1416
1417   if (! dbus_message_get_args (message, error,
1418                                DBUS_TYPE_INVALID))
1419     {
1420       _DBUS_ASSERT_ERROR_IS_SET (error);
1421       return FALSE;
1422     }
1423
1424   if (!_dbus_string_init (&xml))
1425     {
1426       BUS_SET_OOM (error);
1427       return FALSE;
1428     }
1429
1430   if (!_dbus_string_append (&xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE))
1431     goto oom;
1432   if (!_dbus_string_append (&xml, "<node>\n"))
1433     goto oom;
1434   if (!_dbus_string_append_printf (&xml, "  <interface name=\"%s\">\n", DBUS_INTERFACE_INTROSPECTABLE))
1435     goto oom;
1436   if (!_dbus_string_append (&xml, "    <method name=\"Introspect\">\n"))
1437     goto oom;
1438   if (!_dbus_string_append_printf (&xml, "      <arg name=\"data\" direction=\"out\" type=\"%s\"/>\n", DBUS_TYPE_STRING_AS_STRING))
1439     goto oom;
1440   if (!_dbus_string_append (&xml, "    </method>\n"))
1441     goto oom;
1442   if (!_dbus_string_append (&xml, "  </interface>\n"))
1443     goto oom;
1444
1445   if (!_dbus_string_append_printf (&xml, "  <interface name=\"%s\">\n",
1446                                    DBUS_INTERFACE_DBUS))
1447     goto oom;
1448
1449   i = 0;
1450   while (i < _DBUS_N_ELEMENTS (message_handlers))
1451     {
1452           
1453       if (!_dbus_string_append_printf (&xml, "    <method name=\"%s\">\n",
1454                                        message_handlers[i].name))
1455         goto oom;
1456
1457       if (!write_args_for_direction (&xml, message_handlers[i].in_args, TRUE))
1458         goto oom;
1459
1460       if (!write_args_for_direction (&xml, message_handlers[i].out_args, FALSE))
1461         goto oom;
1462
1463       if (!_dbus_string_append (&xml, "    </method>\n"))
1464         goto oom;
1465       
1466       ++i;
1467     }
1468
1469   if (!_dbus_string_append_printf (&xml, "    <signal name=\"NameOwnerChanged\">\n"))
1470     goto oom;
1471   
1472   if (!_dbus_string_append_printf (&xml, "      <arg type=\"s\"/>\n"))
1473     goto oom;
1474   
1475   if (!_dbus_string_append_printf (&xml, "      <arg type=\"s\"/>\n"))
1476     goto oom;
1477   
1478   if (!_dbus_string_append_printf (&xml, "      <arg type=\"s\"/>\n"))
1479     goto oom;
1480   
1481   if (!_dbus_string_append_printf (&xml, "    </signal>\n"))
1482     goto oom;
1483
1484
1485
1486   if (!_dbus_string_append_printf (&xml, "    <signal name=\"NameLost\">\n"))
1487     goto oom;
1488   
1489   if (!_dbus_string_append_printf (&xml, "      <arg type=\"s\"/>\n"))
1490     goto oom;
1491   
1492   if (!_dbus_string_append_printf (&xml, "    </signal>\n"))
1493     goto oom;
1494
1495
1496
1497   if (!_dbus_string_append_printf (&xml, "    <signal name=\"NameAcquired\">\n"))
1498     goto oom;
1499   
1500   if (!_dbus_string_append_printf (&xml, "      <arg type=\"s\"/>\n"))
1501     goto oom;
1502   
1503   if (!_dbus_string_append_printf (&xml, "    </signal>\n"))
1504     goto oom;
1505
1506
1507   
1508   if (!_dbus_string_append (&xml, "  </interface>\n"))
1509     goto oom;
1510   
1511   if (!_dbus_string_append (&xml, "</node>\n"))
1512     goto oom;
1513
1514   reply = dbus_message_new_method_return (message);
1515   if (reply == NULL)
1516     goto oom;
1517
1518   v_STRING = _dbus_string_get_const_data (&xml);
1519   if (! dbus_message_append_args (reply,
1520                                   DBUS_TYPE_STRING, &v_STRING,
1521                                   DBUS_TYPE_INVALID))
1522     goto oom;
1523
1524   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1525     goto oom;
1526
1527   dbus_message_unref (reply);
1528   _dbus_string_free (&xml);
1529
1530   return TRUE;
1531
1532  oom:
1533   BUS_SET_OOM (error);
1534
1535   if (reply)
1536     dbus_message_unref (reply);
1537
1538   _dbus_string_free (&xml);
1539   
1540   return FALSE;
1541 }
1542
1543 dbus_bool_t
1544 bus_driver_handle_message (DBusConnection *connection,
1545                            BusTransaction *transaction,
1546                            DBusMessage    *message,
1547                            DBusError      *error)
1548 {
1549   const char *name, *sender, *interface;
1550   int i;
1551
1552   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1553
1554   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
1555     {
1556       _dbus_verbose ("Driver got a non-method-call message, ignoring\n");
1557       return TRUE; /* we just ignore this */
1558     }
1559
1560   if (dbus_message_is_method_call (message,
1561                                    DBUS_INTERFACE_INTROSPECTABLE,
1562                                    "Introspect"))
1563     return bus_driver_handle_introspect (connection, transaction, message, error);
1564   
1565   interface = dbus_message_get_interface (message);
1566   if (interface == NULL)
1567     interface = DBUS_INTERFACE_DBUS;
1568   
1569   _dbus_assert (dbus_message_get_member (message) != NULL);
1570   
1571   name = dbus_message_get_member (message);
1572   sender = dbus_message_get_sender (message);
1573   
1574   if (strcmp (interface,
1575               DBUS_INTERFACE_DBUS) != 0)
1576     {
1577       _dbus_verbose ("Driver got message to unknown interface \"%s\"\n",
1578                      interface);
1579       goto unknown;
1580     }
1581   
1582   _dbus_verbose ("Driver got a method call: %s\n",
1583                  dbus_message_get_member (message));
1584   
1585   /* security checks should have kept this from getting here */
1586   _dbus_assert (sender != NULL || strcmp (name, "Hello") == 0);
1587   
1588   i = 0;
1589   while (i < _DBUS_N_ELEMENTS (message_handlers))
1590     {
1591       if (strcmp (message_handlers[i].name, name) == 0)
1592         {
1593           _dbus_verbose ("Found driver handler for %s\n", name);
1594
1595           if (!dbus_message_has_signature (message, message_handlers[i].in_args))
1596             {
1597               _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1598               _dbus_verbose ("Call to %s has wrong args (%s, expected %s)\n",
1599                              name, dbus_message_get_signature (message),
1600                              message_handlers[i].in_args);
1601               
1602               dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1603                               "Call to %s has wrong args (%s, expected %s)\n",
1604                               name, dbus_message_get_signature (message),
1605                               message_handlers[i].in_args);
1606               _DBUS_ASSERT_ERROR_IS_SET (error);
1607               return FALSE;
1608             }
1609           
1610           if ((* message_handlers[i].handler) (connection, transaction, message, error))
1611             {
1612               _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1613               _dbus_verbose ("Driver handler succeeded\n");
1614               return TRUE;
1615             }
1616           else
1617             {
1618               _DBUS_ASSERT_ERROR_IS_SET (error);
1619               _dbus_verbose ("Driver handler returned failure\n");
1620               return FALSE;
1621             }
1622         }
1623       
1624       ++i;
1625     }
1626
1627  unknown:
1628   _dbus_verbose ("No driver handler for message \"%s\"\n",
1629                  name);
1630
1631   dbus_set_error (error, DBUS_ERROR_UNKNOWN_METHOD,
1632                   "%s does not understand message %s",
1633                   DBUS_SERVICE_DBUS, name);
1634   
1635   return FALSE;
1636 }
1637
1638 void
1639 bus_driver_remove_connection (DBusConnection *connection)
1640 {
1641   /* FIXME Does nothing for now, should unregister the connection
1642    * with the bus driver.
1643    */
1644 }