Sophie

Sophie

distrib > Mandriva > 2007.0 > x86_64 > media > main-release > by-pkgid > 926d2d1e3111287cee1b0a4fad4fb4f6 > files > 155

lib64dbus-1_3-devel-0.92-6mdv2007.0.x86_64.rpm

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