<!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> <a class="qindex" href="modules.html">Modules</a> <a class="qindex" href="annotated.html">Data Structures</a> <a class="qindex" href="files.html">File List</a> <a class="qindex" href="functions.html">Data Fields</a> <a class="qindex" href="pages.html">Related Pages</a> </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 <dbus/dbus-string.h></font> 00033 <font class="preprocessor">#include <dbus/dbus-internals.h></font> 00034 <font class="preprocessor">#include <string.h></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 <= 0) 00230 { 00231 next_major_number += 1; 00232 next_minor_number = 0; 00233 <font class="keywordflow">if</font> (next_major_number <= 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 > 0); 00238 _dbus_assert (next_minor_number >= 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 (&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, &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, &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 &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 (&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, &services, &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, &name, 00460 DBUS_TYPE_UINT32, &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 (&service_name, name); 00470 00471 <font class="keywordflow">if</font> (!bus_registry_acquire_service (registry, connection, 00472 &service_name, flags, 00473 &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, &name, 00524 DBUS_TYPE_INVALID)) 00525 <font class="keywordflow">return</font> 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 <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, &name, 00580 DBUS_TYPE_UINT32, &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) >= 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, &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 (&str, text); 00669 00670 rule = bus_match_rule_parse (connection, &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, &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 (&str, text); 00728 00729 rule = bus_match_rule_parse (connection, &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 < _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>