Main Page   Modules   Data Structures   File List   Data Fields   Related Pages  

driver.c

00001 /* -*- mode: C; c-file-style: "gnu" -*- */
00002 /* driver.c  Bus client (driver)
00003  *
00004  * Copyright (C) 2003 CodeFactory AB
00005  * Copyright (C) 2003 Red Hat, Inc.
00006  *
00007  * Licensed under the Academic Free License version 1.2
00008  * 
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  * 
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022  *
00023  */
00024 
00025 #include "activation.h"
00026 #include "connection.h"
00027 #include "driver.h"
00028 #include "dispatch.h"
00029 #include "services.h"
00030 #include "signals.h"
00031 #include "utils.h"
00032 #include <dbus/dbus-string.h>
00033 #include <dbus/dbus-internals.h>
00034 #include <string.h>
00035 
00036 static dbus_bool_t bus_driver_send_welcome_message (DBusConnection *connection,
00037                                                     DBusMessage    *hello_message,
00038                                                     BusTransaction *transaction,
00039                                                     DBusError      *error);
00040 
00041 dbus_bool_t
00042 bus_driver_send_service_deleted (const char     *service_name,
00043                                  BusTransaction *transaction,
00044                                  DBusError      *error)
00045 {
00046   DBusMessage *message;
00047   dbus_bool_t retval;
00048 
00049   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00050   
00051   _dbus_verbose ("sending service deleted: %s\n", service_name);
00052 
00053   message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_DBUS,
00054                                      DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
00055                                      "ServiceDeleted");
00056   
00057   if (message == NULL)
00058     {
00059       BUS_SET_OOM (error);
00060       return FALSE;
00061     }
00062   
00063   if (!dbus_message_set_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS) ||
00064       !dbus_message_append_args (message,
00065                                  DBUS_TYPE_STRING, service_name,
00066                                  DBUS_TYPE_INVALID))
00067     {
00068       dbus_message_unref (message);
00069       BUS_SET_OOM (error);
00070       return FALSE;
00071     }
00072 
00073   retval = bus_dispatch_matches (transaction, NULL, NULL, message, error);
00074   dbus_message_unref (message);
00075 
00076   return retval;
00077 }
00078 
00079 dbus_bool_t
00080 bus_driver_send_service_created (const char     *service_name,
00081                                  BusTransaction *transaction,
00082                                  DBusError      *error)
00083 {
00084   DBusMessage *message;
00085   dbus_bool_t retval;
00086 
00087   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00088   
00089   message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_DBUS,
00090                                      DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
00091                                      "ServiceCreated");
00092   
00093   if (message == NULL)
00094     {
00095       BUS_SET_OOM (error);
00096       return FALSE;
00097     }
00098   
00099   if (!dbus_message_set_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
00100     {
00101       dbus_message_unref (message);
00102       BUS_SET_OOM (error);
00103       return FALSE;
00104     }
00105   
00106   if (!dbus_message_append_args (message,
00107                                  DBUS_TYPE_STRING, service_name,
00108                                  DBUS_TYPE_INVALID))
00109     {
00110       dbus_message_unref (message);
00111       BUS_SET_OOM (error);
00112       return FALSE;
00113     }
00114   
00115   retval = bus_dispatch_matches (transaction, NULL, NULL, message, error);
00116   dbus_message_unref (message);
00117 
00118   return retval;
00119 }
00120 
00121 dbus_bool_t
00122 bus_driver_send_service_lost (DBusConnection *connection,
00123                               const char     *service_name,
00124                               BusTransaction *transaction,
00125                               DBusError      *error)
00126 {
00127   DBusMessage *message;
00128 
00129   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00130   
00131   message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_DBUS,
00132                                      DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
00133                                      "ServiceLost");
00134   
00135   if (message == NULL)
00136     {
00137       BUS_SET_OOM (error);
00138       return FALSE;
00139     }
00140   
00141   if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) ||
00142       !dbus_message_append_args (message,
00143                                  DBUS_TYPE_STRING, service_name,
00144                                  DBUS_TYPE_INVALID))
00145     {
00146       dbus_message_unref (message);
00147       BUS_SET_OOM (error);
00148       return FALSE;
00149     }
00150 
00151   if (!bus_transaction_send_from_driver (transaction, connection, message))
00152     {
00153       dbus_message_unref (message);
00154       BUS_SET_OOM (error);
00155       return FALSE;
00156     }
00157   else
00158     {
00159       dbus_message_unref (message);
00160       return TRUE;
00161     }
00162 }
00163 
00164 dbus_bool_t
00165 bus_driver_send_service_acquired (DBusConnection *connection,
00166                                   const char     *service_name,
00167                                   BusTransaction *transaction,
00168                                   DBusError      *error)
00169 {
00170   DBusMessage *message;
00171 
00172   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00173   
00174   message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_DBUS,
00175                                      DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
00176                                      "ServiceAcquired");
00177 
00178   if (message == NULL)
00179     {
00180       BUS_SET_OOM (error);
00181       return FALSE;
00182     }
00183   
00184   if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) ||
00185       !dbus_message_append_args (message,
00186                                  DBUS_TYPE_STRING, service_name,
00187                                  DBUS_TYPE_INVALID))
00188     {
00189       dbus_message_unref (message);
00190       BUS_SET_OOM (error);
00191       return FALSE;
00192     }
00193 
00194   if (!bus_transaction_send_from_driver (transaction, connection, message))
00195     {
00196       dbus_message_unref (message);
00197       BUS_SET_OOM (error);
00198       return FALSE;
00199     }
00200   else
00201     {
00202       dbus_message_unref (message);
00203       return TRUE;
00204     }
00205 }
00206 
00207 static dbus_bool_t
00208 create_unique_client_name (BusRegistry *registry,
00209                            DBusString  *str)
00210 {
00211   /* We never want to use the same unique client name twice, because
00212    * we want to guarantee that if you send a message to a given unique
00213    * name, you always get the same application. So we use two numbers
00214    * for INT_MAX * INT_MAX combinations, should be pretty safe against
00215    * wraparound.
00216    */
00217   /* FIXME these should be in BusRegistry rather than static vars */
00218   static int next_major_number = 0;
00219   static int next_minor_number = 0;
00220   int len;
00221   
00222   len = _dbus_string_get_length (str);
00223   
00224   while (TRUE)
00225     {
00226       /* start out with 1-0, go to 1-1, 1-2, 1-3,
00227        * up to 1-MAXINT, then 2-0, 2-1, etc.
00228        */
00229       if (next_minor_number <= 0)
00230         {
00231           next_major_number += 1;
00232           next_minor_number = 0;
00233           if (next_major_number <= 0)
00234             _dbus_assert_not_reached ("INT_MAX * INT_MAX clients were added");
00235         }
00236 
00237       _dbus_assert (next_major_number > 0);
00238       _dbus_assert (next_minor_number >= 0);
00239 
00240       /* appname:MAJOR-MINOR */
00241       
00242       if (!_dbus_string_append (str, ":"))
00243         return FALSE;
00244       
00245       if (!_dbus_string_append_int (str, next_major_number))
00246         return FALSE;
00247 
00248       if (!_dbus_string_append (str, "-"))
00249         return FALSE;
00250       
00251       if (!_dbus_string_append_int (str, next_minor_number))
00252         return FALSE;
00253 
00254       next_minor_number += 1;
00255       
00256       /* Check if a client with the name exists */
00257       if (bus_registry_lookup (registry, str) == NULL)
00258         break;
00259 
00260       /* drop the number again, try the next one. */
00261       _dbus_string_set_length (str, len);
00262     }
00263 
00264   return TRUE;
00265 }
00266 
00267 static dbus_bool_t
00268 bus_driver_handle_hello (DBusConnection *connection,
00269                          BusTransaction *transaction,
00270                          DBusMessage    *message,
00271                          DBusError      *error)
00272 {
00273   DBusString unique_name;
00274   BusService *service;
00275   dbus_bool_t retval;
00276   BusRegistry *registry;
00277   BusConnections *connections;
00278 
00279   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00280 
00281   /* Note that when these limits are exceeded we don't disconnect the
00282    * connection; we just sort of leave it hanging there until it times
00283    * out or disconnects itself or is dropped due to the max number of
00284    * incomplete connections. It's even OK if the connection wants to
00285    * retry the hello message, we support that.
00286    */
00287   connections = bus_connection_get_connections (connection);
00288   if (!bus_connections_check_limits (connections, connection,
00289                                      error))
00290     {
00291       _DBUS_ASSERT_ERROR_IS_SET (error);
00292       return FALSE;
00293     }
00294   
00295   if (!_dbus_string_init (&unique_name))
00296     {
00297       BUS_SET_OOM (error);
00298       return FALSE;
00299     }
00300 
00301   retval = FALSE;
00302 
00303   registry = bus_connection_get_registry (connection);
00304   
00305   if (!create_unique_client_name (registry, &unique_name))
00306     {
00307       BUS_SET_OOM (error);
00308       goto out_0;
00309     }
00310 
00311   if (!bus_connection_complete (connection, &unique_name, error))
00312     {
00313       _DBUS_ASSERT_ERROR_IS_SET (error);
00314       goto out_0;
00315     }
00316   
00317   if (!dbus_message_set_sender (message,
00318                                 bus_connection_get_name (connection)))
00319     {
00320       BUS_SET_OOM (error);
00321       goto out_0;
00322     }
00323   
00324   if (!bus_driver_send_welcome_message (connection, message, transaction, error))
00325     goto out_0;
00326 
00327   /* Create the service */
00328   service = bus_registry_ensure (registry,
00329                                  &unique_name, connection, transaction, error);
00330   if (service == NULL)
00331     goto out_0;
00332   
00333   bus_service_set_prohibit_replacement (service, TRUE);
00334 
00335   _dbus_assert (bus_connection_is_active (connection));
00336   retval = TRUE;
00337   
00338  out_0:
00339   _dbus_string_free (&unique_name);
00340   return retval;
00341 }
00342 
00343 static dbus_bool_t
00344 bus_driver_send_welcome_message (DBusConnection *connection,
00345                                  DBusMessage    *hello_message,
00346                                  BusTransaction *transaction,
00347                                  DBusError      *error)
00348 {
00349   DBusMessage *welcome;
00350   const char *name;
00351 
00352   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00353   
00354   name = bus_connection_get_name (connection);
00355   _dbus_assert (name != NULL);
00356   
00357   welcome = dbus_message_new_method_return (hello_message);
00358   if (welcome == NULL)
00359     {
00360       BUS_SET_OOM (error);
00361       return FALSE;
00362     }
00363   
00364   if (!dbus_message_append_args (welcome,
00365                                  DBUS_TYPE_STRING, name,
00366                                  DBUS_TYPE_INVALID))
00367     {
00368       dbus_message_unref (welcome);
00369       BUS_SET_OOM (error);
00370       return FALSE;
00371     }
00372 
00373   if (!bus_transaction_send_from_driver (transaction, connection, welcome))
00374     {
00375       dbus_message_unref (welcome);
00376       BUS_SET_OOM (error);
00377       return FALSE;
00378     }
00379   else
00380     {
00381       dbus_message_unref (welcome);
00382       return TRUE;
00383     }
00384 }
00385 
00386 static dbus_bool_t
00387 bus_driver_handle_list_services (DBusConnection *connection,
00388                                  BusTransaction *transaction,
00389                                  DBusMessage    *message,
00390                                  DBusError      *error)
00391 {
00392   DBusMessage *reply;
00393   int len;
00394   char **services;
00395   BusRegistry *registry;
00396 
00397   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00398   
00399   registry = bus_connection_get_registry (connection);
00400   
00401   reply = dbus_message_new_method_return (message);
00402   if (reply == NULL)
00403     {
00404       BUS_SET_OOM (error);
00405       return FALSE;
00406     }
00407 
00408   if (!bus_registry_list_services (registry, &services, &len))
00409     {
00410       dbus_message_unref (reply);
00411       BUS_SET_OOM (error);
00412       return FALSE;
00413     }
00414   
00415   if (!dbus_message_append_args (reply,
00416                                  DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, services, len,
00417                                  DBUS_TYPE_INVALID))
00418     {
00419       dbus_free_string_array (services);
00420       dbus_message_unref (reply);
00421       BUS_SET_OOM (error);
00422       return FALSE;
00423     }
00424 
00425   dbus_free_string_array (services);
00426   
00427   if (!bus_transaction_send_from_driver (transaction, connection, reply))
00428     {
00429       dbus_message_unref (reply);
00430       BUS_SET_OOM (error);
00431       return FALSE;
00432     }
00433   else
00434     {
00435       dbus_message_unref (reply);
00436       return TRUE;
00437     }
00438 }
00439 
00440 static dbus_bool_t
00441 bus_driver_handle_acquire_service (DBusConnection *connection,
00442                                    BusTransaction *transaction,
00443                                    DBusMessage    *message,
00444                                    DBusError      *error)
00445 {
00446   DBusMessage *reply;
00447   DBusString service_name;
00448   char *name;
00449   int service_reply;
00450   int flags;
00451   dbus_bool_t retval;
00452   BusRegistry *registry;
00453 
00454   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00455   
00456   registry = bus_connection_get_registry (connection);
00457   
00458   if (!dbus_message_get_args (message, error,
00459                               DBUS_TYPE_STRING, &name,
00460                               DBUS_TYPE_UINT32, &flags,
00461                               DBUS_TYPE_INVALID))
00462     return FALSE;
00463   
00464   _dbus_verbose ("Trying to own service %s with flags 0x%x\n", name, flags);
00465   
00466   retval = FALSE;
00467   reply = NULL;
00468 
00469   _dbus_string_init_const (&service_name, name);
00470 
00471   if (!bus_registry_acquire_service (registry, connection,
00472                                      &service_name, flags,
00473                                      &service_reply, transaction,
00474                                      error))
00475     goto out;
00476   
00477   reply = dbus_message_new_method_return (message);
00478   if (reply == NULL)
00479     {
00480       BUS_SET_OOM (error);
00481       goto out;
00482     }
00483 
00484   if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, service_reply, DBUS_TYPE_INVALID))
00485     {
00486       BUS_SET_OOM (error);
00487       goto out;
00488     }
00489 
00490   if (!bus_transaction_send_from_driver (transaction, connection, reply))
00491     {
00492       BUS_SET_OOM (error);
00493       goto out;
00494     }
00495 
00496   retval = TRUE;
00497   
00498  out:
00499   dbus_free (name);
00500   if (reply)
00501     dbus_message_unref (reply);
00502   return retval;
00503 } 
00504 
00505 static dbus_bool_t
00506 bus_driver_handle_service_exists (DBusConnection *connection,
00507                                   BusTransaction *transaction,
00508                                   DBusMessage    *message,
00509                                   DBusError      *error)
00510 {
00511   DBusMessage *reply;
00512   DBusString service_name;
00513   BusService *service;
00514   char *name;
00515   dbus_bool_t retval;
00516   BusRegistry *registry;
00517 
00518   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00519   
00520   registry = bus_connection_get_registry (connection);
00521   
00522   if (!dbus_message_get_args (message, error,
00523                               DBUS_TYPE_STRING, &name,
00524                               DBUS_TYPE_INVALID))
00525     return FALSE;
00526 
00527   retval = FALSE;
00528   
00529   _dbus_string_init_const (&service_name, name);
00530   service = bus_registry_lookup (registry, &service_name);
00531  
00532   reply = dbus_message_new_method_return (message);
00533   if (reply == NULL)
00534     {
00535       BUS_SET_OOM (error);
00536       goto out;
00537     }
00538 
00539   if (!dbus_message_append_args (reply,
00540                                  DBUS_TYPE_UINT32, service != NULL,
00541                                  0))
00542     {
00543       BUS_SET_OOM (error);
00544       goto out;
00545     }
00546 
00547   if (!bus_transaction_send_from_driver (transaction, connection, reply))
00548     {
00549       BUS_SET_OOM (error);
00550       goto out;
00551     }
00552 
00553   retval = TRUE;
00554   
00555  out:
00556   if (reply)
00557     dbus_message_unref (reply);
00558   dbus_free (name);
00559 
00560   return retval;
00561 }
00562 
00563 static dbus_bool_t
00564 bus_driver_handle_activate_service (DBusConnection *connection,
00565                                     BusTransaction *transaction,
00566                                     DBusMessage    *message,
00567                                     DBusError      *error)
00568 {
00569   dbus_uint32_t flags;
00570   char *name;
00571   dbus_bool_t retval;
00572   BusActivation *activation;
00573 
00574   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00575   
00576   activation = bus_connection_get_activation (connection);
00577   
00578   if (!dbus_message_get_args (message, error,
00579                               DBUS_TYPE_STRING, &name,
00580                               DBUS_TYPE_UINT32, &flags,
00581                               DBUS_TYPE_INVALID))
00582     {
00583       _DBUS_ASSERT_ERROR_IS_SET (error);
00584       _dbus_verbose ("No memory to get arguments to ActivateService\n");
00585       return FALSE;
00586     }
00587 
00588   retval = FALSE;
00589 
00590   if (!bus_activation_activate_service (activation, connection, transaction,
00591                                         message, name, error))
00592     {
00593       _DBUS_ASSERT_ERROR_IS_SET (error);
00594       _dbus_verbose ("bus_activation_activate_service() failed\n");
00595       goto out;
00596     }
00597 
00598   retval = TRUE;
00599   
00600  out:
00601   dbus_free (name);
00602   return retval;
00603 }
00604 
00605 static dbus_bool_t
00606 send_ack_reply (DBusConnection *connection,
00607                 BusTransaction *transaction,
00608                 DBusMessage    *message,
00609                 DBusError      *error)
00610 {
00611   DBusMessage *reply;
00612 
00613   reply = dbus_message_new_method_return (message);
00614   if (reply == NULL)
00615     {
00616       BUS_SET_OOM (error);
00617       return FALSE;
00618     }
00619 
00620   if (!bus_transaction_send_from_driver (transaction, connection, reply))
00621     {
00622       BUS_SET_OOM (error);
00623       dbus_message_unref (reply);
00624       return FALSE;
00625     }
00626 
00627   dbus_message_unref (reply);
00628   
00629   return TRUE;
00630 }
00631 
00632 static dbus_bool_t
00633 bus_driver_handle_add_match (DBusConnection *connection,
00634                              BusTransaction *transaction,
00635                              DBusMessage    *message,
00636                              DBusError      *error)
00637 {
00638   BusMatchRule *rule;
00639   char *text;
00640   DBusString str;
00641   BusMatchmaker *matchmaker;
00642   
00643   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00644 
00645   text = NULL;
00646   rule = NULL;
00647 
00648   if (bus_connection_get_n_match_rules (connection) >=
00649       bus_context_get_max_match_rules_per_connection (bus_transaction_get_context (transaction)))
00650     {
00651       dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
00652                       "Connection \"%s\" is not allowed to add more match rules "
00653                       "(increase limits in configuration file if required)",
00654                       bus_connection_is_active (connection) ?
00655                       bus_connection_get_name (connection) :
00656                       "(inactive)");
00657       goto failed;
00658     }
00659   
00660   if (!dbus_message_get_args (message, error,
00661                               DBUS_TYPE_STRING, &text,
00662                               DBUS_TYPE_INVALID))
00663     {
00664       _dbus_verbose ("No memory to get arguments to AddMatch\n");
00665       goto failed;
00666     }
00667 
00668   _dbus_string_init_const (&str, text);
00669 
00670   rule = bus_match_rule_parse (connection, &str, error);
00671   if (rule == NULL)
00672     goto failed;
00673 
00674   matchmaker = bus_connection_get_matchmaker (connection);
00675 
00676   if (!bus_matchmaker_add_rule (matchmaker, rule))
00677     {
00678       BUS_SET_OOM (error);
00679       goto failed;
00680     }
00681 
00682   if (!send_ack_reply (connection, transaction,
00683                        message, error))
00684     {
00685       bus_matchmaker_remove_rule (matchmaker, rule);
00686       goto failed;
00687     }
00688   
00689   bus_match_rule_unref (rule);
00690   dbus_free (text);
00691   
00692   return TRUE;
00693 
00694  failed:
00695   _DBUS_ASSERT_ERROR_IS_SET (error);
00696   if (rule)
00697     bus_match_rule_unref (rule);
00698   if (text)
00699     dbus_free (text);
00700   return FALSE;
00701 }
00702 
00703 static dbus_bool_t
00704 bus_driver_handle_remove_match (DBusConnection *connection,
00705                                 BusTransaction *transaction,
00706                                 DBusMessage    *message,
00707                                 DBusError      *error)
00708 {
00709   BusMatchRule *rule;
00710   char *text;
00711   DBusString str;
00712   BusMatchmaker *matchmaker;
00713   
00714   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00715 
00716   text = NULL;
00717   rule = NULL;
00718   
00719   if (!dbus_message_get_args (message, error,
00720                               DBUS_TYPE_STRING, &text,
00721                               DBUS_TYPE_INVALID))
00722     {
00723       _dbus_verbose ("No memory to get arguments to RemoveMatch\n");
00724       goto failed;
00725     }
00726 
00727   _dbus_string_init_const (&str, text);
00728 
00729   rule = bus_match_rule_parse (connection, &str, error);
00730   if (rule == NULL)
00731     goto failed;
00732 
00733   /* Send the ack before we remove the rule, since the ack is undone
00734    * on transaction cancel, but rule removal isn't.
00735    */
00736   if (!send_ack_reply (connection, transaction,
00737                        message, error))
00738     goto failed;
00739   
00740   matchmaker = bus_connection_get_matchmaker (connection);
00741 
00742   if (!bus_matchmaker_remove_rule_by_value (matchmaker, rule, error))
00743     goto failed;
00744 
00745   bus_match_rule_unref (rule);
00746   dbus_free (text);
00747   
00748   return TRUE;
00749 
00750  failed:
00751   _DBUS_ASSERT_ERROR_IS_SET (error);
00752   if (rule)
00753     bus_match_rule_unref (rule);
00754   if (text)
00755     dbus_free (text);
00756   return FALSE;
00757 }
00758 
00759 /* For speed it might be useful to sort this in order of
00760  * frequency of use (but doesn't matter with only a few items
00761  * anyhow)
00762  */
00763 struct
00764 {
00765   const char *name;
00766   dbus_bool_t (* handler) (DBusConnection *connection,
00767                            BusTransaction *transaction,
00768                            DBusMessage    *message,
00769                            DBusError      *error);
00770 } message_handlers[] = {
00771   { "AcquireService", bus_driver_handle_acquire_service },
00772   { "ActivateService", bus_driver_handle_activate_service },
00773   { "Hello", bus_driver_handle_hello },
00774   { "ServiceExists", bus_driver_handle_service_exists },
00775   { "ListServices", bus_driver_handle_list_services },
00776   { "AddMatch", bus_driver_handle_add_match },
00777   { "RemoveMatch", bus_driver_handle_remove_match }
00778 };
00779 
00780 dbus_bool_t
00781 bus_driver_handle_message (DBusConnection *connection,
00782                            BusTransaction *transaction,
00783                            DBusMessage    *message,
00784                            DBusError      *error)
00785 {
00786   const char *name, *sender;
00787   int i;
00788 
00789   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00790 
00791   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
00792     {
00793       _dbus_verbose ("Driver got a non-method-call message, ignoring\n");
00794       return TRUE; /* we just ignore this */
00795     }
00796 
00797   _dbus_assert (dbus_message_get_interface (message) != NULL);
00798   _dbus_assert (dbus_message_get_member (message) != NULL);
00799 
00800   name = dbus_message_get_member (message);
00801   sender = dbus_message_get_sender (message);
00802   
00803   if (strcmp (dbus_message_get_interface (message),
00804               DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS) != 0)
00805     {
00806       _dbus_verbose ("Driver got message to unknown interface \"%s\"\n",
00807                      dbus_message_get_interface (message));
00808       goto unknown;
00809     }
00810   
00811   _dbus_verbose ("Driver got a method call: %s\n",
00812                  dbus_message_get_member (message));
00813   
00814   /* security checks should have kept this from getting here */
00815   _dbus_assert (sender != NULL || strcmp (name, "Hello") == 0);
00816 
00817   if (dbus_message_get_reply_serial (message) == 0)
00818     {
00819       _dbus_verbose ("Client sent a reply to the bus driver, ignoring it\n");
00820       return TRUE;
00821     }
00822   
00823   i = 0;
00824   while (i < _DBUS_N_ELEMENTS (message_handlers))
00825     {
00826       if (strcmp (message_handlers[i].name, name) == 0)
00827         {
00828           _dbus_verbose ("Running driver handler for %s\n", name);
00829           if ((* message_handlers[i].handler) (connection, transaction, message, error))
00830             {
00831               _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00832               _dbus_verbose ("Driver handler succeeded\n");
00833               return TRUE;
00834             }
00835           else
00836             {
00837               _DBUS_ASSERT_ERROR_IS_SET (error);
00838               _dbus_verbose ("Driver handler returned failure\n");
00839               return FALSE;
00840             }
00841         }
00842       
00843       ++i;
00844     }
00845 
00846  unknown:
00847   _dbus_verbose ("No driver handler for message \"%s\"\n",
00848                  name);
00849 
00850   dbus_set_error (error, DBUS_ERROR_UNKNOWN_METHOD,
00851                   "%s does not understand message %s",
00852                   DBUS_SERVICE_ORG_FREEDESKTOP_DBUS, name);
00853   
00854   return FALSE;
00855 }
00856 
00857 void
00858 bus_driver_remove_connection (DBusConnection *connection)
00859 {
00860   /* FIXME Does nothing for now, should unregister the connection
00861    * with the bus driver.
00862    */
00863 }

Generated on Mon Sep 29 21:31:02 2003 for D-BUS by doxygen1.2.15