Home | History | Annotate | Download | only in bus
      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 /* For speed it might be useful to sort this in order of
   1386  * frequency of use (but doesn't matter with only a few items
   1387  * anyhow)
   1388  */
   1389 struct
   1390 {
   1391   const char *name;
   1392   const char *in_args;
   1393   const char *out_args;
   1394   dbus_bool_t (* handler) (DBusConnection *connection,
   1395                            BusTransaction *transaction,
   1396                            DBusMessage    *message,
   1397                            DBusError      *error);
   1398 } message_handlers[] = {
   1399   { "RequestName",
   1400     DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
   1401     DBUS_TYPE_UINT32_AS_STRING,
   1402     bus_driver_handle_acquire_service },
   1403   { "ReleaseName",
   1404     DBUS_TYPE_STRING_AS_STRING,
   1405     DBUS_TYPE_UINT32_AS_STRING,
   1406     bus_driver_handle_release_service },
   1407   { "StartServiceByName",
   1408     DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
   1409     DBUS_TYPE_UINT32_AS_STRING,
   1410     bus_driver_handle_activate_service },
   1411   { "Hello",
   1412     "",
   1413     DBUS_TYPE_STRING_AS_STRING,
   1414     bus_driver_handle_hello },
   1415   { "NameHasOwner",
   1416     DBUS_TYPE_STRING_AS_STRING,
   1417     DBUS_TYPE_BOOLEAN_AS_STRING,
   1418     bus_driver_handle_service_exists },
   1419   { "ListNames",
   1420     "",
   1421     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
   1422     bus_driver_handle_list_services },
   1423   { "ListActivatableNames",
   1424     "",
   1425     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
   1426     bus_driver_handle_list_activatable_services },
   1427   { "AddMatch",
   1428     DBUS_TYPE_STRING_AS_STRING,
   1429     "",
   1430     bus_driver_handle_add_match },
   1431   { "RemoveMatch",
   1432     DBUS_TYPE_STRING_AS_STRING,
   1433     "",
   1434     bus_driver_handle_remove_match },
   1435   { "GetNameOwner",
   1436     DBUS_TYPE_STRING_AS_STRING,
   1437     DBUS_TYPE_STRING_AS_STRING,
   1438     bus_driver_handle_get_service_owner },
   1439   { "ListQueuedOwners",
   1440     DBUS_TYPE_STRING_AS_STRING,
   1441     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
   1442     bus_driver_handle_list_queued_owners },
   1443   { "GetConnectionUnixUser",
   1444     DBUS_TYPE_STRING_AS_STRING,
   1445     DBUS_TYPE_UINT32_AS_STRING,
   1446     bus_driver_handle_get_connection_unix_user },
   1447   { "GetConnectionUnixProcessID",
   1448     DBUS_TYPE_STRING_AS_STRING,
   1449     DBUS_TYPE_UINT32_AS_STRING,
   1450     bus_driver_handle_get_connection_unix_process_id },
   1451   { "GetConnectionSELinuxSecurityContext",
   1452     DBUS_TYPE_STRING_AS_STRING,
   1453     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
   1454     bus_driver_handle_get_connection_selinux_security_context },
   1455   { "ReloadConfig",
   1456     "",
   1457     "",
   1458     bus_driver_handle_reload_config }
   1459 };
   1460 
   1461 static dbus_bool_t
   1462 write_args_for_direction (DBusString *xml,
   1463 			  const char *signature,
   1464 			  dbus_bool_t in)
   1465 {
   1466   DBusTypeReader typereader;
   1467   DBusString sigstr;
   1468   int current_type;
   1469 
   1470   _dbus_string_init_const (&sigstr, signature);
   1471   _dbus_type_reader_init_types_only (&typereader, &sigstr, 0);
   1472 
   1473   while ((current_type = _dbus_type_reader_get_current_type (&typereader)) != DBUS_TYPE_INVALID)
   1474     {
   1475       const DBusString *subsig;
   1476       int start, len;
   1477 
   1478       _dbus_type_reader_get_signature (&typereader, &subsig, &start, &len);
   1479       if (!_dbus_string_append_printf (xml, "      <arg direction=\"%s\" type=\"",
   1480 				       in ? "in" : "out"))
   1481 	goto oom;
   1482       if (!_dbus_string_append_len (xml,
   1483 				    _dbus_string_get_const_data (subsig) + start,
   1484 				    len))
   1485 	goto oom;
   1486       if (!_dbus_string_append (xml, "\"/>\n"))
   1487 	goto oom;
   1488 
   1489       _dbus_type_reader_next (&typereader);
   1490     }
   1491   return TRUE;
   1492  oom:
   1493   return FALSE;
   1494 }
   1495 
   1496 dbus_bool_t
   1497 bus_driver_generate_introspect_string (DBusString *xml)
   1498 {
   1499   int i;
   1500 
   1501   if (!_dbus_string_append (xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE))
   1502     return FALSE;
   1503   if (!_dbus_string_append (xml, "<node>\n"))
   1504     return FALSE;
   1505   if (!_dbus_string_append_printf (xml, "  <interface name=\"%s\">\n", DBUS_INTERFACE_INTROSPECTABLE))
   1506     return FALSE;
   1507   if (!_dbus_string_append (xml, "    <method name=\"Introspect\">\n"))
   1508     return FALSE;
   1509   if (!_dbus_string_append_printf (xml, "      <arg name=\"data\" direction=\"out\" type=\"%s\"/>\n", DBUS_TYPE_STRING_AS_STRING))
   1510     return FALSE;
   1511   if (!_dbus_string_append (xml, "    </method>\n"))
   1512     return FALSE;
   1513   if (!_dbus_string_append (xml, "  </interface>\n"))
   1514     return FALSE;
   1515 
   1516   if (!_dbus_string_append_printf (xml, "  <interface name=\"%s\">\n",
   1517                                    DBUS_INTERFACE_DBUS))
   1518     return FALSE;
   1519 
   1520   i = 0;
   1521   while (i < _DBUS_N_ELEMENTS (message_handlers))
   1522     {
   1523 
   1524       if (!_dbus_string_append_printf (xml, "    <method name=\"%s\">\n",
   1525                                        message_handlers[i].name))
   1526         return FALSE;
   1527 
   1528       if (!write_args_for_direction (xml, message_handlers[i].in_args, TRUE))
   1529 	return FALSE;
   1530 
   1531       if (!write_args_for_direction (xml, message_handlers[i].out_args, FALSE))
   1532 	return FALSE;
   1533 
   1534       if (!_dbus_string_append (xml, "    </method>\n"))
   1535 	return FALSE;
   1536 
   1537       ++i;
   1538     }
   1539 
   1540   if (!_dbus_string_append_printf (xml, "    <signal name=\"NameOwnerChanged\">\n"))
   1541     return FALSE;
   1542 
   1543   if (!_dbus_string_append_printf (xml, "      <arg type=\"s\"/>\n"))
   1544     return FALSE;
   1545 
   1546   if (!_dbus_string_append_printf (xml, "      <arg type=\"s\"/>\n"))
   1547     return FALSE;
   1548 
   1549   if (!_dbus_string_append_printf (xml, "      <arg type=\"s\"/>\n"))
   1550     return FALSE;
   1551 
   1552   if (!_dbus_string_append_printf (xml, "    </signal>\n"))
   1553     return FALSE;
   1554 
   1555 
   1556 
   1557   if (!_dbus_string_append_printf (xml, "    <signal name=\"NameLost\">\n"))
   1558     return FALSE;
   1559 
   1560   if (!_dbus_string_append_printf (xml, "      <arg type=\"s\"/>\n"))
   1561     return FALSE;
   1562 
   1563   if (!_dbus_string_append_printf (xml, "    </signal>\n"))
   1564     return FALSE;
   1565 
   1566 
   1567 
   1568   if (!_dbus_string_append_printf (xml, "    <signal name=\"NameAcquired\">\n"))
   1569     return FALSE;
   1570 
   1571   if (!_dbus_string_append_printf (xml, "      <arg type=\"s\"/>\n"))
   1572     return FALSE;
   1573 
   1574   if (!_dbus_string_append_printf (xml, "    </signal>\n"))
   1575     return FALSE;
   1576 
   1577   if (!_dbus_string_append (xml, "  </interface>\n"))
   1578     return FALSE;
   1579 
   1580   if (!_dbus_string_append (xml, "</node>\n"))
   1581     return FALSE;
   1582 
   1583   return TRUE;
   1584 }
   1585 
   1586 static dbus_bool_t
   1587 bus_driver_handle_introspect (DBusConnection *connection,
   1588                               BusTransaction *transaction,
   1589                               DBusMessage    *message,
   1590                               DBusError      *error)
   1591 {
   1592   DBusString xml;
   1593   DBusMessage *reply;
   1594   const char *v_STRING;
   1595 
   1596   _dbus_verbose ("Introspect() on bus driver\n");
   1597 
   1598   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
   1599 
   1600   reply = NULL;
   1601 
   1602   if (! dbus_message_get_args (message, error,
   1603 			       DBUS_TYPE_INVALID))
   1604     {
   1605       _DBUS_ASSERT_ERROR_IS_SET (error);
   1606       return FALSE;
   1607     }
   1608 
   1609   if (!_dbus_string_init (&xml))
   1610     {
   1611       BUS_SET_OOM (error);
   1612       return FALSE;
   1613     }
   1614 
   1615   if (!bus_driver_generate_introspect_string (&xml))
   1616     goto oom;
   1617 
   1618   v_STRING = _dbus_string_get_const_data (&xml);
   1619 
   1620   reply = dbus_message_new_method_return (message);
   1621   if (reply == NULL)
   1622     goto oom;
   1623 
   1624   if (! dbus_message_append_args (reply,
   1625                                   DBUS_TYPE_STRING, &v_STRING,
   1626                                   DBUS_TYPE_INVALID))
   1627     goto oom;
   1628 
   1629   if (! bus_transaction_send_from_driver (transaction, connection, reply))
   1630     goto oom;
   1631 
   1632   dbus_message_unref (reply);
   1633   _dbus_string_free (&xml);
   1634 
   1635   return TRUE;
   1636 
   1637  oom:
   1638   BUS_SET_OOM (error);
   1639 
   1640   if (reply)
   1641     dbus_message_unref (reply);
   1642 
   1643   _dbus_string_free (&xml);
   1644 
   1645   return FALSE;
   1646 }
   1647 
   1648 dbus_bool_t
   1649 bus_driver_handle_message (DBusConnection *connection,
   1650                            BusTransaction *transaction,
   1651 			   DBusMessage    *message,
   1652                            DBusError      *error)
   1653 {
   1654   const char *name, *sender, *interface;
   1655   int i;
   1656 
   1657   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
   1658 
   1659   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
   1660     {
   1661       _dbus_verbose ("Driver got a non-method-call message, ignoring\n");
   1662       return TRUE; /* we just ignore this */
   1663     }
   1664 
   1665   if (dbus_message_is_method_call (message,
   1666                                    DBUS_INTERFACE_INTROSPECTABLE,
   1667                                    "Introspect"))
   1668     return bus_driver_handle_introspect (connection, transaction, message, error);
   1669 
   1670   interface = dbus_message_get_interface (message);
   1671   if (interface == NULL)
   1672     interface = DBUS_INTERFACE_DBUS;
   1673 
   1674   _dbus_assert (dbus_message_get_member (message) != NULL);
   1675 
   1676   name = dbus_message_get_member (message);
   1677   sender = dbus_message_get_sender (message);
   1678 
   1679   if (strcmp (interface,
   1680               DBUS_INTERFACE_DBUS) != 0)
   1681     {
   1682       _dbus_verbose ("Driver got message to unknown interface \"%s\"\n",
   1683                      interface);
   1684       goto unknown;
   1685     }
   1686 
   1687   _dbus_verbose ("Driver got a method call: %s\n",
   1688 		 dbus_message_get_member (message));
   1689 
   1690   /* security checks should have kept this from getting here */
   1691   _dbus_assert (sender != NULL || strcmp (name, "Hello") == 0);
   1692 
   1693   i = 0;
   1694   while (i < _DBUS_N_ELEMENTS (message_handlers))
   1695     {
   1696       if (strcmp (message_handlers[i].name, name) == 0)
   1697         {
   1698           _dbus_verbose ("Found driver handler for %s\n", name);
   1699 
   1700           if (!dbus_message_has_signature (message, message_handlers[i].in_args))
   1701             {
   1702               _DBUS_ASSERT_ERROR_IS_CLEAR (error);
   1703               _dbus_verbose ("Call to %s has wrong args (%s, expected %s)\n",
   1704                              name, dbus_message_get_signature (message),
   1705                              message_handlers[i].in_args);
   1706 
   1707               dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
   1708                               "Call to %s has wrong args (%s, expected %s)\n",
   1709                               name, dbus_message_get_signature (message),
   1710                               message_handlers[i].in_args);
   1711               _DBUS_ASSERT_ERROR_IS_SET (error);
   1712               return FALSE;
   1713             }
   1714 
   1715           if ((* message_handlers[i].handler) (connection, transaction, message, error))
   1716             {
   1717               _DBUS_ASSERT_ERROR_IS_CLEAR (error);
   1718               _dbus_verbose ("Driver handler succeeded\n");
   1719               return TRUE;
   1720             }
   1721           else
   1722             {
   1723               _DBUS_ASSERT_ERROR_IS_SET (error);
   1724               _dbus_verbose ("Driver handler returned failure\n");
   1725               return FALSE;
   1726             }
   1727         }
   1728 
   1729       ++i;
   1730     }
   1731 
   1732  unknown:
   1733   _dbus_verbose ("No driver handler for message \"%s\"\n",
   1734                  name);
   1735 
   1736   dbus_set_error (error, DBUS_ERROR_UNKNOWN_METHOD,
   1737                   "%s does not understand message %s",
   1738                   DBUS_SERVICE_DBUS, name);
   1739 
   1740   return FALSE;
   1741 }
   1742 
   1743 void
   1744 bus_driver_remove_connection (DBusConnection *connection)
   1745 {
   1746   /* FIXME 1.0 Does nothing for now, should unregister the connection
   1747    * with the bus driver.
   1748    */
   1749 }
   1750