2007-06-18 Havoc Pennington <hp@redhat.com>
[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   dbus_free_string_array (services);
440
441   if (!dbus_message_iter_close_container (&iter, &sub))
442     {
443       dbus_message_unref (reply);
444       BUS_SET_OOM (error);
445       return FALSE;
446     }
447   
448   if (!bus_transaction_send_from_driver (transaction, connection, reply))
449     {
450       dbus_message_unref (reply);
451       BUS_SET_OOM (error);
452       return FALSE;
453     }
454   else
455     {
456       dbus_message_unref (reply);
457       return TRUE;
458     }
459 }
460
461 static dbus_bool_t
462 bus_driver_handle_list_activatable_services (DBusConnection *connection,
463                                              BusTransaction *transaction,
464                                              DBusMessage    *message,
465                                              DBusError      *error)
466 {
467   DBusMessage *reply;
468   int len;
469   char **services;
470   BusActivation *activation;
471   int i;
472   DBusMessageIter iter;
473   DBusMessageIter sub;
474
475   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
476
477   activation = bus_connection_get_activation (connection);
478
479   reply = dbus_message_new_method_return (message);
480   if (reply == NULL)
481     {
482       BUS_SET_OOM (error);
483       return FALSE;
484     }
485
486   if (!bus_activation_list_services (activation, &services, &len))
487     {
488       dbus_message_unref (reply);
489       BUS_SET_OOM (error);
490       return FALSE;
491     }
492
493   dbus_message_iter_init_append (reply, &iter);
494
495   if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
496                                          DBUS_TYPE_STRING_AS_STRING,
497                                          &sub))
498     {
499       dbus_free_string_array (services);
500       dbus_message_unref (reply);
501       BUS_SET_OOM (error);
502       return FALSE;
503     }
504
505   {
506     /* Include the bus driver in the list */
507     const char *v_STRING = DBUS_SERVICE_DBUS;
508     if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
509                                          &v_STRING))
510       {
511         dbus_free_string_array (services);
512         dbus_message_unref (reply);
513         BUS_SET_OOM (error);
514         return FALSE;
515       }
516   }
517
518   i = 0;
519   while (i < len)
520     {
521       if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
522                                            &services[i]))
523         {
524           dbus_free_string_array (services);
525           dbus_message_unref (reply);
526           BUS_SET_OOM (error);
527           return FALSE;
528         }
529       ++i;
530     }
531
532   dbus_free_string_array (services);
533
534   if (!dbus_message_iter_close_container (&iter, &sub))
535     {
536       dbus_message_unref (reply);
537       BUS_SET_OOM (error);
538       return FALSE;
539     }
540
541   if (!bus_transaction_send_from_driver (transaction, connection, reply))
542     {
543       dbus_message_unref (reply);
544       BUS_SET_OOM (error);
545       return FALSE;
546     }
547   else
548     {
549       dbus_message_unref (reply);
550       return TRUE;
551     }
552 }
553
554 static dbus_bool_t
555 bus_driver_handle_acquire_service (DBusConnection *connection,
556                                    BusTransaction *transaction,
557                                    DBusMessage    *message,
558                                    DBusError      *error)
559 {
560   DBusMessage *reply;
561   DBusString service_name;
562   const char *name;
563   dbus_uint32_t service_reply;
564   dbus_uint32_t flags;
565   dbus_bool_t retval;
566   BusRegistry *registry;
567
568   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
569   
570   registry = bus_connection_get_registry (connection);
571   
572   if (!dbus_message_get_args (message, error,
573                               DBUS_TYPE_STRING, &name,
574                               DBUS_TYPE_UINT32, &flags,
575                               DBUS_TYPE_INVALID))
576     return FALSE;
577   
578   _dbus_verbose ("Trying to own name %s with flags 0x%x\n", name, flags);
579   
580   retval = FALSE;
581   reply = NULL;
582
583   _dbus_string_init_const (&service_name, name);
584
585   if (!bus_registry_acquire_service (registry, connection,
586                                      &service_name, flags,
587                                      &service_reply, transaction,
588                                      error))
589     goto out;
590   
591   reply = dbus_message_new_method_return (message);
592   if (reply == NULL)
593     {
594       BUS_SET_OOM (error);
595       goto out;
596     }
597
598   if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, &service_reply, DBUS_TYPE_INVALID))
599     {
600       BUS_SET_OOM (error);
601       goto out;
602     }
603
604   if (!bus_transaction_send_from_driver (transaction, connection, reply))
605     {
606       BUS_SET_OOM (error);
607       goto out;
608     }
609
610   retval = TRUE;
611   
612  out:
613   if (reply)
614     dbus_message_unref (reply);
615   return retval;
616
617
618 static dbus_bool_t
619 bus_driver_handle_release_service (DBusConnection *connection,
620                                    BusTransaction *transaction,
621                                    DBusMessage    *message,
622                                    DBusError      *error)
623 {
624   DBusMessage *reply;
625   DBusString service_name;
626   const char *name;
627   dbus_uint32_t service_reply;
628   dbus_bool_t retval;
629   BusRegistry *registry;
630
631   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
632
633   registry = bus_connection_get_registry (connection);
634
635   if (!dbus_message_get_args (message, error,
636                               DBUS_TYPE_STRING, &name,
637                               DBUS_TYPE_INVALID))
638     return FALSE;
639
640   _dbus_verbose ("Trying to release name %s\n", name);
641
642   retval = FALSE;
643   reply = NULL;
644
645   _dbus_string_init_const (&service_name, name);
646
647   if (!bus_registry_release_service (registry, connection,
648                                      &service_name, &service_reply,
649                                      transaction, error))
650     goto out;
651
652   reply = dbus_message_new_method_return (message);
653   if (reply == NULL)
654     {
655       BUS_SET_OOM (error);
656       goto out;
657     }
658
659   if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, &service_reply, DBUS_TYPE_INVALID))
660     {
661       BUS_SET_OOM (error);
662       goto out;
663     }
664
665   if (!bus_transaction_send_from_driver (transaction, connection, reply))
666     {
667       BUS_SET_OOM (error);
668       goto out;
669     }
670
671   retval = TRUE;
672
673  out:
674   if (reply)
675     dbus_message_unref (reply);
676   return retval;
677 }
678
679 static dbus_bool_t
680 bus_driver_handle_service_exists (DBusConnection *connection,
681                                   BusTransaction *transaction,
682                                   DBusMessage    *message,
683                                   DBusError      *error)
684 {
685   DBusMessage *reply;
686   DBusString service_name;
687   BusService *service;
688   dbus_bool_t service_exists;
689   const char *name;
690   dbus_bool_t retval;
691   BusRegistry *registry;
692
693   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
694   
695   registry = bus_connection_get_registry (connection);
696   
697   if (!dbus_message_get_args (message, error,
698                               DBUS_TYPE_STRING, &name,
699                               DBUS_TYPE_INVALID))
700     return FALSE;
701
702   retval = FALSE;
703
704   if (strcmp (name, DBUS_SERVICE_DBUS) == 0)
705     {
706       service_exists = TRUE;
707     }
708   else
709     {
710       _dbus_string_init_const (&service_name, name);
711       service = bus_registry_lookup (registry, &service_name);
712       service_exists = service != NULL;
713     }
714   
715   reply = dbus_message_new_method_return (message);
716   if (reply == NULL)
717     {
718       BUS_SET_OOM (error);
719       goto out;
720     }
721
722   if (!dbus_message_append_args (reply,
723                                  DBUS_TYPE_BOOLEAN, &service_exists,
724                                  0))
725     {
726       BUS_SET_OOM (error);
727       goto out;
728     }
729
730   if (!bus_transaction_send_from_driver (transaction, connection, reply))
731     {
732       BUS_SET_OOM (error);
733       goto out;
734     }
735
736   retval = TRUE;
737   
738  out:
739   if (reply)
740     dbus_message_unref (reply);
741
742   return retval;
743 }
744
745 static dbus_bool_t
746 bus_driver_handle_activate_service (DBusConnection *connection,
747                                     BusTransaction *transaction,
748                                     DBusMessage    *message,
749                                     DBusError      *error)
750 {
751   dbus_uint32_t flags;
752   const char *name;
753   dbus_bool_t retval;
754   BusActivation *activation;
755
756   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
757   
758   activation = bus_connection_get_activation (connection);
759   
760   if (!dbus_message_get_args (message, error,
761                               DBUS_TYPE_STRING, &name,
762                               DBUS_TYPE_UINT32, &flags,
763                               DBUS_TYPE_INVALID))
764     {
765       _DBUS_ASSERT_ERROR_IS_SET (error);
766       _dbus_verbose ("No memory to get arguments to StartServiceByName\n");
767       return FALSE;
768     }
769
770   retval = FALSE;
771
772   if (!bus_activation_activate_service (activation, connection, transaction, FALSE,
773                                         message, name, error))
774     {
775       _DBUS_ASSERT_ERROR_IS_SET (error);
776       _dbus_verbose ("bus_activation_activate_service() failed\n");
777       goto out;
778     }
779
780   retval = TRUE;
781   
782  out:
783   return retval;
784 }
785
786 static dbus_bool_t
787 send_ack_reply (DBusConnection *connection,
788                 BusTransaction *transaction,
789                 DBusMessage    *message,
790                 DBusError      *error)
791 {
792   DBusMessage *reply;
793
794   reply = dbus_message_new_method_return (message);
795   if (reply == NULL)
796     {
797       BUS_SET_OOM (error);
798       return FALSE;
799     }
800
801   if (!bus_transaction_send_from_driver (transaction, connection, reply))
802     {
803       BUS_SET_OOM (error);
804       dbus_message_unref (reply);
805       return FALSE;
806     }
807
808   dbus_message_unref (reply);
809   
810   return TRUE;
811 }
812
813 static dbus_bool_t
814 bus_driver_handle_add_match (DBusConnection *connection,
815                              BusTransaction *transaction,
816                              DBusMessage    *message,
817                              DBusError      *error)
818 {
819   BusMatchRule *rule;
820   const char *text;
821   DBusString str;
822   BusMatchmaker *matchmaker;
823   
824   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
825
826   text = NULL;
827   rule = NULL;
828
829   if (bus_connection_get_n_match_rules (connection) >=
830       bus_context_get_max_match_rules_per_connection (bus_transaction_get_context (transaction)))
831     {
832       dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
833                       "Connection \"%s\" is not allowed to add more match rules "
834                       "(increase limits in configuration file if required)",
835                       bus_connection_is_active (connection) ?
836                       bus_connection_get_name (connection) :
837                       "(inactive)");
838       goto failed;
839     }
840   
841   if (!dbus_message_get_args (message, error,
842                               DBUS_TYPE_STRING, &text,
843                               DBUS_TYPE_INVALID))
844     {
845       _dbus_verbose ("No memory to get arguments to AddMatch\n");
846       goto failed;
847     }
848
849   _dbus_string_init_const (&str, text);
850
851   rule = bus_match_rule_parse (connection, &str, error);
852   if (rule == NULL)
853     goto failed;
854
855   matchmaker = bus_connection_get_matchmaker (connection);
856
857   if (!bus_matchmaker_add_rule (matchmaker, rule))
858     {
859       BUS_SET_OOM (error);
860       goto failed;
861     }
862
863   if (!send_ack_reply (connection, transaction,
864                        message, error))
865     {
866       bus_matchmaker_remove_rule (matchmaker, rule);
867       goto failed;
868     }
869   
870   bus_match_rule_unref (rule);
871   
872   return TRUE;
873
874  failed:
875   _DBUS_ASSERT_ERROR_IS_SET (error);
876   if (rule)
877     bus_match_rule_unref (rule);
878   return FALSE;
879 }
880
881 static dbus_bool_t
882 bus_driver_handle_remove_match (DBusConnection *connection,
883                                 BusTransaction *transaction,
884                                 DBusMessage    *message,
885                                 DBusError      *error)
886 {
887   BusMatchRule *rule;
888   const char *text;
889   DBusString str;
890   BusMatchmaker *matchmaker;
891   
892   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
893
894   text = NULL;
895   rule = NULL;
896   
897   if (!dbus_message_get_args (message, error,
898                               DBUS_TYPE_STRING, &text,
899                               DBUS_TYPE_INVALID))
900     {
901       _dbus_verbose ("No memory to get arguments to RemoveMatch\n");
902       goto failed;
903     }
904
905   _dbus_string_init_const (&str, text);
906
907   rule = bus_match_rule_parse (connection, &str, error);
908   if (rule == NULL)
909     goto failed;
910
911   /* Send the ack before we remove the rule, since the ack is undone
912    * on transaction cancel, but rule removal isn't.
913    */
914   if (!send_ack_reply (connection, transaction,
915                        message, error))
916     goto failed;
917   
918   matchmaker = bus_connection_get_matchmaker (connection);
919
920   if (!bus_matchmaker_remove_rule_by_value (matchmaker, rule, error))
921     goto failed;
922
923   bus_match_rule_unref (rule);
924   
925   return TRUE;
926
927  failed:
928   _DBUS_ASSERT_ERROR_IS_SET (error);
929   if (rule)
930     bus_match_rule_unref (rule);
931   return FALSE;
932 }
933
934 static dbus_bool_t
935 bus_driver_handle_get_service_owner (DBusConnection *connection,
936                                      BusTransaction *transaction,
937                                      DBusMessage    *message,
938                                      DBusError      *error)
939 {
940   const char *text;
941   const char *base_name;
942   DBusString str;
943   BusRegistry *registry;
944   BusService *service;
945   DBusMessage *reply;
946   
947   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
948
949   registry = bus_connection_get_registry (connection);
950
951   text = NULL;
952   reply = NULL;
953
954   if (! dbus_message_get_args (message, error,
955                                DBUS_TYPE_STRING, &text,
956                                DBUS_TYPE_INVALID))
957       goto failed;
958
959   _dbus_string_init_const (&str, text);
960   service = bus_registry_lookup (registry, &str);
961   if (service == NULL &&
962       _dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS))
963     {
964       /* ORG_FREEDESKTOP_DBUS owns itself */
965       base_name = DBUS_SERVICE_DBUS;
966     }
967   else if (service == NULL)
968     {
969       dbus_set_error (error, 
970                       DBUS_ERROR_NAME_HAS_NO_OWNER,
971                       "Could not get owner of name '%s': no such name", text);
972       goto failed;
973     }
974   else
975     {
976       base_name = bus_connection_get_name (bus_service_get_primary_owners_connection (service));
977       if (base_name == NULL)
978         {
979           /* FIXME - how is this error possible? */
980           dbus_set_error (error,
981                           DBUS_ERROR_FAILED,
982                           "Could not determine unique name for '%s'", text);
983           goto failed;
984         }
985       _dbus_assert (*base_name == ':');      
986     }
987
988   _dbus_assert (base_name != NULL);
989
990   reply = dbus_message_new_method_return (message);
991   if (reply == NULL)
992     goto oom;
993
994   if (! dbus_message_append_args (reply, 
995                                   DBUS_TYPE_STRING, &base_name,
996                                   DBUS_TYPE_INVALID))
997     goto oom;
998   
999   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1000     goto oom;
1001
1002   dbus_message_unref (reply);
1003
1004   return TRUE;
1005
1006  oom:
1007   BUS_SET_OOM (error);
1008
1009  failed:
1010   _DBUS_ASSERT_ERROR_IS_SET (error);
1011   if (reply)
1012     dbus_message_unref (reply);
1013   return FALSE;
1014 }
1015
1016 static dbus_bool_t
1017 bus_driver_handle_list_queued_owners (DBusConnection *connection,
1018                                       BusTransaction *transaction,
1019                                       DBusMessage    *message,
1020                                       DBusError      *error)
1021 {
1022   const char *text;
1023   DBusList *base_names;
1024   DBusList *link;
1025   DBusString str;
1026   BusRegistry *registry;
1027   BusService *service;
1028   DBusMessage *reply;
1029   DBusMessageIter iter, array_iter;
1030   char *dbus_service_name = DBUS_SERVICE_DBUS;
1031   
1032   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1033
1034   registry = bus_connection_get_registry (connection);
1035
1036   base_names = NULL;
1037   text = NULL;
1038   reply = NULL;
1039
1040   if (! dbus_message_get_args (message, error,
1041                                DBUS_TYPE_STRING, &text,
1042                                DBUS_TYPE_INVALID))
1043       goto failed;
1044
1045   _dbus_string_init_const (&str, text);
1046   service = bus_registry_lookup (registry, &str);
1047   if (service == NULL &&
1048       _dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS))
1049     {
1050       /* ORG_FREEDESKTOP_DBUS owns itself */
1051       if (! _dbus_list_append (&base_names, dbus_service_name))
1052         goto oom;
1053     }
1054   else if (service == NULL)
1055     {
1056       dbus_set_error (error, 
1057                       DBUS_ERROR_NAME_HAS_NO_OWNER,
1058                       "Could not get owners of name '%s': no such name", text);
1059       goto failed;
1060     }
1061   else
1062     {
1063       if (!bus_service_list_queued_owners (service, 
1064                                            &base_names,
1065                                            error))
1066         goto failed;
1067     }
1068
1069   _dbus_assert (base_names != NULL);
1070
1071   reply = dbus_message_new_method_return (message);
1072   if (reply == NULL)
1073     goto oom;
1074
1075   dbus_message_iter_init_append (reply, &iter);
1076   if (!dbus_message_iter_open_container (&iter,
1077                                          DBUS_TYPE_ARRAY,
1078                                          DBUS_TYPE_STRING_AS_STRING,
1079                                          &array_iter))
1080     goto oom;
1081   
1082   link = _dbus_list_get_first_link (&base_names);
1083   while (link != NULL)
1084     {
1085       char *uname;
1086
1087       _dbus_assert (link->data != NULL);
1088       uname = (char *)link->data;
1089     
1090       if (!dbus_message_iter_append_basic (&array_iter, 
1091                                            DBUS_TYPE_STRING,
1092                                            &uname))
1093         goto oom;
1094
1095       link = _dbus_list_get_next_link (&base_names, link);
1096     }
1097
1098   if (! dbus_message_iter_close_container (&iter, &array_iter))
1099     goto oom;
1100                                     
1101  
1102   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1103     goto oom;
1104
1105   dbus_message_unref (reply);
1106
1107   return TRUE;
1108
1109  oom:
1110   BUS_SET_OOM (error);
1111
1112  failed:
1113   _DBUS_ASSERT_ERROR_IS_SET (error);
1114   if (reply)
1115     dbus_message_unref (reply);
1116
1117   if (base_names)
1118     _dbus_list_clear (&base_names);
1119
1120   return FALSE;
1121 }
1122
1123 static dbus_bool_t
1124 bus_driver_handle_get_connection_unix_user (DBusConnection *connection,
1125                                             BusTransaction *transaction,
1126                                             DBusMessage    *message,
1127                                             DBusError      *error)
1128 {
1129   const char *service;
1130   DBusString str;
1131   BusRegistry *registry;
1132   BusService *serv;
1133   DBusConnection *conn;
1134   DBusMessage *reply;
1135   unsigned long uid;
1136   dbus_uint32_t uid32;
1137
1138   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1139
1140   registry = bus_connection_get_registry (connection);
1141
1142   service = NULL;
1143   reply = NULL;
1144
1145   if (! dbus_message_get_args (message, error,
1146                                DBUS_TYPE_STRING, &service,
1147                                DBUS_TYPE_INVALID))
1148       goto failed;
1149
1150   _dbus_verbose ("asked for UID of connection %s\n", service);
1151
1152   _dbus_string_init_const (&str, service);
1153   serv = bus_registry_lookup (registry, &str);
1154   if (serv == NULL)
1155     {
1156       dbus_set_error (error, 
1157                       DBUS_ERROR_NAME_HAS_NO_OWNER,
1158                       "Could not get UID of name '%s': no such name", service);
1159       goto failed;
1160     }
1161
1162   conn = bus_service_get_primary_owners_connection (serv);
1163
1164   reply = dbus_message_new_method_return (message);
1165   if (reply == NULL)
1166     goto oom;
1167
1168   if (!dbus_connection_get_unix_user (conn, &uid))
1169     {
1170       dbus_set_error (error,
1171                       DBUS_ERROR_FAILED,
1172                       "Could not determine UID for '%s'", service);
1173       goto failed;
1174     }
1175
1176   uid32 = uid;
1177   if (! dbus_message_append_args (reply,
1178                                   DBUS_TYPE_UINT32, &uid32,
1179                                   DBUS_TYPE_INVALID))
1180     goto oom;
1181
1182   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1183     goto oom;
1184
1185   dbus_message_unref (reply);
1186
1187   return TRUE;
1188
1189  oom:
1190   BUS_SET_OOM (error);
1191
1192  failed:
1193   _DBUS_ASSERT_ERROR_IS_SET (error);
1194   if (reply)
1195     dbus_message_unref (reply);
1196   return FALSE;
1197 }
1198
1199 static dbus_bool_t
1200 bus_driver_handle_get_connection_unix_process_id (DBusConnection *connection,
1201                                                   BusTransaction *transaction,
1202                                                   DBusMessage    *message,
1203                                                   DBusError      *error)
1204 {
1205   const char *service;
1206   DBusString str;
1207   BusRegistry *registry;
1208   BusService *serv;
1209   DBusConnection *conn;
1210   DBusMessage *reply;
1211   unsigned long pid;
1212   dbus_uint32_t pid32;
1213
1214   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1215
1216   registry = bus_connection_get_registry (connection);
1217
1218   service = NULL;
1219   reply = NULL;
1220
1221   if (! dbus_message_get_args (message, error,
1222                                DBUS_TYPE_STRING, &service,
1223                                DBUS_TYPE_INVALID))
1224       goto failed;
1225
1226   _dbus_verbose ("asked for PID of connection %s\n", service);
1227
1228   _dbus_string_init_const (&str, service);
1229   serv = bus_registry_lookup (registry, &str);
1230   if (serv == NULL)
1231     {
1232       dbus_set_error (error, 
1233                       DBUS_ERROR_NAME_HAS_NO_OWNER,
1234                       "Could not get PID of name '%s': no such name", service);
1235       goto failed;
1236     }
1237
1238   conn = bus_service_get_primary_owners_connection (serv);
1239
1240   reply = dbus_message_new_method_return (message);
1241   if (reply == NULL)
1242     goto oom;
1243
1244   if (!dbus_connection_get_unix_process_id (conn, &pid))
1245     {
1246       dbus_set_error (error,
1247                       DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN,
1248                       "Could not determine PID for '%s'", service);
1249       goto failed;
1250     }
1251
1252   pid32 = pid;
1253   if (! dbus_message_append_args (reply,
1254                                   DBUS_TYPE_UINT32, &pid32,
1255                                   DBUS_TYPE_INVALID))
1256     goto oom;
1257
1258   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1259     goto oom;
1260
1261   dbus_message_unref (reply);
1262
1263   return TRUE;
1264
1265  oom:
1266   BUS_SET_OOM (error);
1267
1268  failed:
1269   _DBUS_ASSERT_ERROR_IS_SET (error);
1270   if (reply)
1271     dbus_message_unref (reply);
1272   return FALSE;
1273 }
1274
1275 static dbus_bool_t
1276 bus_driver_handle_get_connection_selinux_security_context (DBusConnection *connection,
1277                                                            BusTransaction *transaction,
1278                                                            DBusMessage    *message,
1279                                                            DBusError      *error)
1280 {
1281   const char *service;
1282   DBusString str;
1283   BusRegistry *registry;
1284   BusService *serv;
1285   DBusConnection *conn;
1286   DBusMessage *reply;
1287   BusSELinuxID *context;
1288
1289   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1290
1291   registry = bus_connection_get_registry (connection);
1292
1293   service = NULL;
1294   reply = NULL;
1295
1296   if (! dbus_message_get_args (message, error,
1297                                DBUS_TYPE_STRING, &service,
1298                                DBUS_TYPE_INVALID))
1299       goto failed;
1300
1301   _dbus_verbose ("asked for security context of connection %s\n", service);
1302
1303   _dbus_string_init_const (&str, service);
1304   serv = bus_registry_lookup (registry, &str);
1305   if (serv == NULL)
1306     {
1307       dbus_set_error (error, 
1308                       DBUS_ERROR_NAME_HAS_NO_OWNER,
1309                       "Could not get security context of name '%s': no such name", service);
1310       goto failed;
1311     }
1312
1313   conn = bus_service_get_primary_owners_connection (serv);
1314
1315   reply = dbus_message_new_method_return (message);
1316   if (reply == NULL)
1317     goto oom;
1318
1319   context = bus_connection_get_selinux_id (conn);
1320   if (!context)
1321     {
1322       dbus_set_error (error,
1323                       DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN,
1324                       "Could not determine security context for '%s'", service);
1325       goto failed;
1326     }
1327
1328   if (! bus_selinux_append_context (reply, context, error))
1329     goto failed;
1330
1331   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1332     goto oom;
1333
1334   dbus_message_unref (reply);
1335
1336   return TRUE;
1337
1338  oom:
1339   BUS_SET_OOM (error);
1340
1341  failed:
1342   _DBUS_ASSERT_ERROR_IS_SET (error);
1343   if (reply)
1344     dbus_message_unref (reply);
1345   return FALSE;
1346 }
1347
1348 static dbus_bool_t
1349 bus_driver_handle_reload_config (DBusConnection *connection,
1350                                  BusTransaction *transaction,
1351                                  DBusMessage    *message,
1352                                  DBusError      *error)
1353 {
1354   BusContext *context;
1355   DBusMessage *reply;
1356
1357   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1358
1359   reply = NULL;
1360   
1361   context = bus_connection_get_context (connection);
1362   if (!bus_context_reload_config (context, error))
1363     goto failed;
1364
1365   reply = dbus_message_new_method_return (message);
1366   if (reply == NULL)
1367     goto oom;
1368
1369   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1370     goto oom;
1371
1372   dbus_message_unref (reply);
1373   return TRUE;
1374
1375  oom:
1376   BUS_SET_OOM (error);
1377
1378  failed:
1379   _DBUS_ASSERT_ERROR_IS_SET (error);
1380   if (reply)
1381     dbus_message_unref (reply);
1382   return FALSE;
1383 }
1384
1385 static dbus_bool_t
1386 bus_driver_handle_get_id (DBusConnection *connection,
1387                           BusTransaction *transaction,
1388                           DBusMessage    *message,
1389                           DBusError      *error)
1390 {
1391   BusContext *context;
1392   DBusMessage *reply;
1393   DBusString uuid;
1394   const char *v_STRING;
1395
1396   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1397
1398   if (!_dbus_string_init (&uuid))
1399     {
1400       BUS_SET_OOM (error);
1401       return FALSE;
1402     }
1403
1404   reply = NULL;
1405   
1406   context = bus_connection_get_context (connection);
1407   if (!bus_context_get_id (context, &uuid))
1408     goto oom;
1409
1410   reply = dbus_message_new_method_return (message);
1411   if (reply == NULL)
1412     goto oom;
1413
1414   v_STRING = _dbus_string_get_const_data (&uuid);
1415   if (!dbus_message_append_args (reply,
1416                                  DBUS_TYPE_STRING, &v_STRING,
1417                                  DBUS_TYPE_INVALID))
1418     goto oom;
1419   
1420   _dbus_assert (dbus_message_has_signature (reply, "s"));
1421   
1422   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1423     goto oom;
1424
1425   _dbus_string_free (&uuid);  
1426   dbus_message_unref (reply);
1427   return TRUE;
1428
1429  oom:
1430   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1431   
1432   BUS_SET_OOM (error);
1433
1434   if (reply)
1435     dbus_message_unref (reply);
1436   _dbus_string_free (&uuid);  
1437   return FALSE;
1438 }
1439
1440 /* For speed it might be useful to sort this in order of
1441  * frequency of use (but doesn't matter with only a few items
1442  * anyhow)
1443  */
1444 struct
1445 {
1446   const char *name;
1447   const char *in_args;
1448   const char *out_args;
1449   dbus_bool_t (* handler) (DBusConnection *connection,
1450                            BusTransaction *transaction,
1451                            DBusMessage    *message,
1452                            DBusError      *error);
1453 } message_handlers[] = {
1454   { "Hello",
1455     "",
1456     DBUS_TYPE_STRING_AS_STRING,
1457     bus_driver_handle_hello },  
1458   { "RequestName",
1459     DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
1460     DBUS_TYPE_UINT32_AS_STRING,
1461     bus_driver_handle_acquire_service },
1462   { "ReleaseName",
1463     DBUS_TYPE_STRING_AS_STRING,
1464     DBUS_TYPE_UINT32_AS_STRING,
1465     bus_driver_handle_release_service },
1466   { "StartServiceByName",
1467     DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
1468     DBUS_TYPE_UINT32_AS_STRING,
1469     bus_driver_handle_activate_service },
1470   { "NameHasOwner",
1471     DBUS_TYPE_STRING_AS_STRING,
1472     DBUS_TYPE_BOOLEAN_AS_STRING,
1473     bus_driver_handle_service_exists },
1474   { "ListNames",
1475     "",
1476     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
1477     bus_driver_handle_list_services },
1478   { "ListActivatableNames",
1479     "",
1480     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
1481     bus_driver_handle_list_activatable_services },
1482   { "AddMatch",
1483     DBUS_TYPE_STRING_AS_STRING,
1484     "",
1485     bus_driver_handle_add_match },
1486   { "RemoveMatch",
1487     DBUS_TYPE_STRING_AS_STRING,
1488     "",
1489     bus_driver_handle_remove_match },
1490   { "GetNameOwner",
1491     DBUS_TYPE_STRING_AS_STRING,
1492     DBUS_TYPE_STRING_AS_STRING,
1493     bus_driver_handle_get_service_owner },
1494   { "ListQueuedOwners",
1495     DBUS_TYPE_STRING_AS_STRING,
1496     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
1497     bus_driver_handle_list_queued_owners },
1498   { "GetConnectionUnixUser",
1499     DBUS_TYPE_STRING_AS_STRING,
1500     DBUS_TYPE_UINT32_AS_STRING,
1501     bus_driver_handle_get_connection_unix_user },
1502   { "GetConnectionUnixProcessID",
1503     DBUS_TYPE_STRING_AS_STRING,
1504     DBUS_TYPE_UINT32_AS_STRING,
1505     bus_driver_handle_get_connection_unix_process_id },
1506   { "GetConnectionSELinuxSecurityContext",
1507     DBUS_TYPE_STRING_AS_STRING,
1508     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
1509     bus_driver_handle_get_connection_selinux_security_context },
1510   { "ReloadConfig",
1511     "",
1512     "",
1513     bus_driver_handle_reload_config },
1514   { "GetId",
1515     "",
1516     DBUS_TYPE_STRING_AS_STRING,
1517     bus_driver_handle_get_id }
1518 };
1519
1520 static dbus_bool_t
1521 write_args_for_direction (DBusString *xml,
1522                           const char *signature,
1523                           dbus_bool_t in)
1524 {
1525   DBusTypeReader typereader;
1526   DBusString sigstr;
1527   int current_type;
1528   
1529   _dbus_string_init_const (&sigstr, signature);
1530   _dbus_type_reader_init_types_only (&typereader, &sigstr, 0);
1531       
1532   while ((current_type = _dbus_type_reader_get_current_type (&typereader)) != DBUS_TYPE_INVALID)
1533     {
1534       const DBusString *subsig;
1535       int start, len;
1536
1537       _dbus_type_reader_get_signature (&typereader, &subsig, &start, &len);
1538       if (!_dbus_string_append_printf (xml, "      <arg direction=\"%s\" type=\"",
1539                                        in ? "in" : "out"))
1540         goto oom;
1541       if (!_dbus_string_append_len (xml,
1542                                     _dbus_string_get_const_data (subsig) + start,
1543                                     len))
1544         goto oom;
1545       if (!_dbus_string_append (xml, "\"/>\n"))
1546         goto oom;
1547
1548       _dbus_type_reader_next (&typereader);
1549     }
1550   return TRUE;
1551  oom:
1552   return FALSE;
1553 }
1554
1555 dbus_bool_t
1556 bus_driver_generate_introspect_string (DBusString *xml)
1557 {
1558   int i;
1559
1560   if (!_dbus_string_append (xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE))
1561     return FALSE;
1562   if (!_dbus_string_append (xml, "<node>\n"))
1563     return FALSE;
1564   if (!_dbus_string_append_printf (xml, "  <interface name=\"%s\">\n", DBUS_INTERFACE_INTROSPECTABLE))
1565     return FALSE;
1566   if (!_dbus_string_append (xml, "    <method name=\"Introspect\">\n"))
1567     return FALSE;
1568   if (!_dbus_string_append_printf (xml, "      <arg name=\"data\" direction=\"out\" type=\"%s\"/>\n", DBUS_TYPE_STRING_AS_STRING))
1569     return FALSE;
1570   if (!_dbus_string_append (xml, "    </method>\n"))
1571     return FALSE;
1572   if (!_dbus_string_append (xml, "  </interface>\n"))
1573     return FALSE;
1574
1575   if (!_dbus_string_append_printf (xml, "  <interface name=\"%s\">\n",
1576                                    DBUS_INTERFACE_DBUS))
1577     return FALSE;
1578
1579   i = 0;
1580   while (i < _DBUS_N_ELEMENTS (message_handlers))
1581     {
1582           
1583       if (!_dbus_string_append_printf (xml, "    <method name=\"%s\">\n",
1584                                        message_handlers[i].name))
1585         return FALSE;
1586
1587       if (!write_args_for_direction (xml, message_handlers[i].in_args, TRUE))
1588         return FALSE;
1589
1590       if (!write_args_for_direction (xml, message_handlers[i].out_args, FALSE))
1591         return FALSE;
1592
1593       if (!_dbus_string_append (xml, "    </method>\n"))
1594         return FALSE;
1595       
1596       ++i;
1597     }
1598
1599   if (!_dbus_string_append_printf (xml, "    <signal name=\"NameOwnerChanged\">\n"))
1600     return FALSE;
1601   
1602   if (!_dbus_string_append_printf (xml, "      <arg type=\"s\"/>\n"))
1603     return FALSE;
1604   
1605   if (!_dbus_string_append_printf (xml, "      <arg type=\"s\"/>\n"))
1606     return FALSE;
1607   
1608   if (!_dbus_string_append_printf (xml, "      <arg type=\"s\"/>\n"))
1609     return FALSE;
1610   
1611   if (!_dbus_string_append_printf (xml, "    </signal>\n"))
1612     return FALSE;
1613
1614
1615
1616   if (!_dbus_string_append_printf (xml, "    <signal name=\"NameLost\">\n"))
1617     return FALSE;
1618   
1619   if (!_dbus_string_append_printf (xml, "      <arg type=\"s\"/>\n"))
1620     return FALSE;
1621   
1622   if (!_dbus_string_append_printf (xml, "    </signal>\n"))
1623     return FALSE;
1624
1625
1626
1627   if (!_dbus_string_append_printf (xml, "    <signal name=\"NameAcquired\">\n"))
1628     return FALSE;
1629   
1630   if (!_dbus_string_append_printf (xml, "      <arg type=\"s\"/>\n"))
1631     return FALSE;
1632   
1633   if (!_dbus_string_append_printf (xml, "    </signal>\n"))
1634     return FALSE;
1635
1636   if (!_dbus_string_append (xml, "  </interface>\n"))
1637     return FALSE;
1638   
1639   if (!_dbus_string_append (xml, "</node>\n"))
1640     return FALSE;
1641
1642   return TRUE;
1643 }
1644
1645 static dbus_bool_t
1646 bus_driver_handle_introspect (DBusConnection *connection,
1647                               BusTransaction *transaction,
1648                               DBusMessage    *message,
1649                               DBusError      *error)
1650 {
1651   DBusString xml;
1652   DBusMessage *reply;
1653   const char *v_STRING;
1654
1655   _dbus_verbose ("Introspect() on bus driver\n");
1656   
1657   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1658
1659   reply = NULL;
1660
1661   if (! dbus_message_get_args (message, error,
1662                                DBUS_TYPE_INVALID))
1663     {
1664       _DBUS_ASSERT_ERROR_IS_SET (error);
1665       return FALSE;
1666     }
1667
1668   if (!_dbus_string_init (&xml))
1669     {
1670       BUS_SET_OOM (error);
1671       return FALSE;
1672     }
1673
1674   if (!bus_driver_generate_introspect_string (&xml))
1675     goto oom;
1676
1677   v_STRING = _dbus_string_get_const_data (&xml);
1678
1679   reply = dbus_message_new_method_return (message);
1680   if (reply == NULL)
1681     goto oom;
1682
1683   if (! dbus_message_append_args (reply,
1684                                   DBUS_TYPE_STRING, &v_STRING,
1685                                   DBUS_TYPE_INVALID))
1686     goto oom;
1687
1688   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1689     goto oom;
1690
1691   dbus_message_unref (reply);
1692   _dbus_string_free (&xml);
1693
1694   return TRUE;
1695
1696  oom:
1697   BUS_SET_OOM (error);
1698
1699   if (reply)
1700     dbus_message_unref (reply);
1701
1702   _dbus_string_free (&xml);
1703   
1704   return FALSE;
1705 }
1706
1707 dbus_bool_t
1708 bus_driver_handle_message (DBusConnection *connection,
1709                            BusTransaction *transaction,
1710                            DBusMessage    *message,
1711                            DBusError      *error)
1712 {
1713   const char *name, *sender, *interface;
1714   int i;
1715
1716   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1717
1718   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
1719     {
1720       _dbus_verbose ("Driver got a non-method-call message, ignoring\n");
1721       return TRUE; /* we just ignore this */
1722     }
1723
1724   if (dbus_message_is_method_call (message,
1725                                    DBUS_INTERFACE_INTROSPECTABLE,
1726                                    "Introspect"))
1727     return bus_driver_handle_introspect (connection, transaction, message, error);
1728   
1729   interface = dbus_message_get_interface (message);
1730   if (interface == NULL)
1731     interface = DBUS_INTERFACE_DBUS;
1732   
1733   _dbus_assert (dbus_message_get_member (message) != NULL);
1734   
1735   name = dbus_message_get_member (message);
1736   sender = dbus_message_get_sender (message);
1737   
1738   if (strcmp (interface,
1739               DBUS_INTERFACE_DBUS) != 0)
1740     {
1741       _dbus_verbose ("Driver got message to unknown interface \"%s\"\n",
1742                      interface);
1743       goto unknown;
1744     }
1745   
1746   _dbus_verbose ("Driver got a method call: %s\n",
1747                  dbus_message_get_member (message));
1748   
1749   /* security checks should have kept this from getting here */
1750   _dbus_assert (sender != NULL || strcmp (name, "Hello") == 0);
1751   
1752   i = 0;
1753   while (i < _DBUS_N_ELEMENTS (message_handlers))
1754     {
1755       if (strcmp (message_handlers[i].name, name) == 0)
1756         {
1757           _dbus_verbose ("Found driver handler for %s\n", name);
1758
1759           if (!dbus_message_has_signature (message, message_handlers[i].in_args))
1760             {
1761               _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1762               _dbus_verbose ("Call to %s has wrong args (%s, expected %s)\n",
1763                              name, dbus_message_get_signature (message),
1764                              message_handlers[i].in_args);
1765               
1766               dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1767                               "Call to %s has wrong args (%s, expected %s)\n",
1768                               name, dbus_message_get_signature (message),
1769                               message_handlers[i].in_args);
1770               _DBUS_ASSERT_ERROR_IS_SET (error);
1771               return FALSE;
1772             }
1773           
1774           if ((* message_handlers[i].handler) (connection, transaction, message, error))
1775             {
1776               _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1777               _dbus_verbose ("Driver handler succeeded\n");
1778               return TRUE;
1779             }
1780           else
1781             {
1782               _DBUS_ASSERT_ERROR_IS_SET (error);
1783               _dbus_verbose ("Driver handler returned failure\n");
1784               return FALSE;
1785             }
1786         }
1787       
1788       ++i;
1789     }
1790
1791  unknown:
1792   _dbus_verbose ("No driver handler for message \"%s\"\n",
1793                  name);
1794
1795   dbus_set_error (error, DBUS_ERROR_UNKNOWN_METHOD,
1796                   "%s does not understand message %s",
1797                   DBUS_SERVICE_DBUS, name);
1798   
1799   return FALSE;
1800 }
1801
1802 void
1803 bus_driver_remove_connection (DBusConnection *connection)
1804 {
1805   /* FIXME 1.0 Does nothing for now, should unregister the connection
1806    * with the bus driver.
1807    */
1808 }