<!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>signals.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>signals.c</h1><div class="fragment"><pre>00001 <font class="comment">/* -*- mode: C; c-file-style: "gnu" -*- */</font> 00002 <font class="comment">/* signals.c Bus signal connection implementation</font> 00003 <font class="comment"> *</font> 00004 <font class="comment"> * Copyright (C) 2003 Red Hat, Inc.</font> 00005 <font class="comment"> *</font> 00006 <font class="comment"> * Licensed under the Academic Free License version 1.2</font> 00007 <font class="comment"> *</font> 00008 <font class="comment"> * This program is free software; you can redistribute it and/or modify</font> 00009 <font class="comment"> * it under the terms of the GNU General Public License as published by</font> 00010 <font class="comment"> * the Free Software Foundation; either version 2 of the License, or</font> 00011 <font class="comment"> * (at your option) any later version.</font> 00012 <font class="comment"> *</font> 00013 <font class="comment"> * This program is distributed in the hope that it will be useful,</font> 00014 <font class="comment"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</font> 00015 <font class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</font> 00016 <font class="comment"> * GNU General Public License for more details.</font> 00017 <font class="comment"> *</font> 00018 <font class="comment"> * You should have received a copy of the GNU General Public License</font> 00019 <font class="comment"> * along with this program; if not, write to the Free Software</font> 00020 <font class="comment"> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA</font> 00021 <font class="comment"> *</font> 00022 <font class="comment"> */</font> 00023 <font class="preprocessor">#include "signals.h"</font> 00024 <font class="preprocessor">#include "services.h"</font> 00025 <font class="preprocessor">#include "utils.h"</font> 00026 00027 <font class="keyword">struct </font>BusMatchRule 00028 { 00029 <font class="keywordtype">int</font> refcount; 00031 <a class="code" href="structDBusConnection.html">DBusConnection</a> *matches_go_to; 00033 <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> flags; 00035 <font class="keywordtype">int</font> message_type; 00036 <font class="keywordtype">char</font> *interface; 00037 <font class="keywordtype">char</font> *member; 00038 <font class="keywordtype">char</font> *sender; 00039 <font class="keywordtype">char</font> *destination; 00040 <font class="keywordtype">char</font> *path; 00041 }; 00042 00043 BusMatchRule* 00044 bus_match_rule_new (<a class="code" href="structDBusConnection.html">DBusConnection</a> *matches_go_to) 00045 { 00046 BusMatchRule *rule; 00047 00048 rule = dbus_new0 (BusMatchRule, 1); 00049 <font class="keywordflow">if</font> (rule == NULL) 00050 <font class="keywordflow">return</font> NULL; 00051 00052 rule->refcount = 1; 00053 rule->matches_go_to = matches_go_to; 00054 00055 <font class="keywordflow">return</font> rule; 00056 } 00057 00058 <font class="keywordtype">void</font> 00059 bus_match_rule_ref (BusMatchRule *rule) 00060 { 00061 _dbus_assert (rule->refcount > 0); 00062 00063 rule->refcount += 1; 00064 } 00065 00066 <font class="keywordtype">void</font> 00067 bus_match_rule_unref (BusMatchRule *rule) 00068 { 00069 _dbus_assert (rule->refcount > 0); 00070 00071 rule->refcount -= 1; 00072 <font class="keywordflow">if</font> (rule->refcount == 0) 00073 { 00074 dbus_free (rule->interface); 00075 dbus_free (rule->member); 00076 dbus_free (rule->sender); 00077 dbus_free (rule->destination); 00078 dbus_free (rule->path); 00079 dbus_free (rule); 00080 } 00081 } 00082 00083 <font class="preprocessor">#ifdef DBUS_ENABLE_VERBOSE_MODE</font> 00084 <font class="preprocessor"></font><font class="keyword">static</font> <font class="keywordtype">char</font>* 00085 match_rule_to_string (BusMatchRule *rule) 00086 { 00087 <a class="code" href="structDBusString.html">DBusString</a> str; 00088 <font class="keywordtype">char</font> *ret; 00089 00090 <font class="keywordflow">if</font> (!_dbus_string_init (&str)) 00091 { 00092 <font class="keywordtype">char</font> *s; 00093 <font class="keywordflow">while</font> ((s = _dbus_strdup (<font class="stringliteral">"nomem"</font>)) == NULL) 00094 ; <font class="comment">/* only OK for debug spew... */</font> 00095 <font class="keywordflow">return</font> s; 00096 } 00097 00098 <font class="keywordflow">if</font> (rule->flags & BUS_MATCH_MESSAGE_TYPE) 00099 { 00100 <font class="comment">/* FIXME make type readable */</font> 00101 <font class="keywordflow">if</font> (!_dbus_string_append_printf (&str, <font class="stringliteral">"type='%d'"</font>, rule->message_type)) 00102 <font class="keywordflow">goto</font> nomem; 00103 } 00104 00105 <font class="keywordflow">if</font> (rule->flags & BUS_MATCH_INTERFACE) 00106 { 00107 <font class="keywordflow">if</font> (_dbus_string_get_length (&str) > 0) 00108 { 00109 <font class="keywordflow">if</font> (!_dbus_string_append (&str, <font class="stringliteral">","</font>)) 00110 <font class="keywordflow">goto</font> nomem; 00111 } 00112 00113 <font class="keywordflow">if</font> (!_dbus_string_append_printf (&str, <font class="stringliteral">"interface='%s'"</font>, rule->interface)) 00114 <font class="keywordflow">goto</font> nomem; 00115 } 00116 00117 <font class="keywordflow">if</font> (rule->flags & BUS_MATCH_MEMBER) 00118 { 00119 <font class="keywordflow">if</font> (_dbus_string_get_length (&str) > 0) 00120 { 00121 <font class="keywordflow">if</font> (!_dbus_string_append (&str, <font class="stringliteral">","</font>)) 00122 <font class="keywordflow">goto</font> nomem; 00123 } 00124 00125 <font class="keywordflow">if</font> (!_dbus_string_append_printf (&str, <font class="stringliteral">"member='%s'"</font>, rule->member)) 00126 <font class="keywordflow">goto</font> nomem; 00127 } 00128 00129 <font class="keywordflow">if</font> (rule->flags & BUS_MATCH_PATH) 00130 { 00131 <font class="keywordflow">if</font> (_dbus_string_get_length (&str) > 0) 00132 { 00133 <font class="keywordflow">if</font> (!_dbus_string_append (&str, <font class="stringliteral">","</font>)) 00134 <font class="keywordflow">goto</font> nomem; 00135 } 00136 00137 <font class="keywordflow">if</font> (!_dbus_string_append_printf (&str, <font class="stringliteral">"path='%s'"</font>, rule->path)) 00138 <font class="keywordflow">goto</font> nomem; 00139 } 00140 00141 <font class="keywordflow">if</font> (rule->flags & BUS_MATCH_SENDER) 00142 { 00143 <font class="keywordflow">if</font> (_dbus_string_get_length (&str) > 0) 00144 { 00145 <font class="keywordflow">if</font> (!_dbus_string_append (&str, <font class="stringliteral">","</font>)) 00146 <font class="keywordflow">goto</font> nomem; 00147 } 00148 00149 <font class="keywordflow">if</font> (!_dbus_string_append_printf (&str, <font class="stringliteral">"sender='%s'"</font>, rule->sender)) 00150 <font class="keywordflow">goto</font> nomem; 00151 } 00152 00153 <font class="keywordflow">if</font> (rule->flags & BUS_MATCH_DESTINATION) 00154 { 00155 <font class="keywordflow">if</font> (_dbus_string_get_length (&str) > 0) 00156 { 00157 <font class="keywordflow">if</font> (!_dbus_string_append (&str, <font class="stringliteral">","</font>)) 00158 <font class="keywordflow">goto</font> nomem; 00159 } 00160 00161 <font class="keywordflow">if</font> (!_dbus_string_append_printf (&str, <font class="stringliteral">"destination='%s'"</font>, rule->destination)) 00162 <font class="keywordflow">goto</font> nomem; 00163 } 00164 00165 <font class="keywordflow">if</font> (!_dbus_string_steal_data (&str, &ret)) 00166 <font class="keywordflow">goto</font> nomem; 00167 00168 _dbus_string_free (&str); 00169 <font class="keywordflow">return</font> ret; 00170 00171 nomem: 00172 _dbus_string_free (&str); 00173 { 00174 <font class="keywordtype">char</font> *s; 00175 <font class="keywordflow">while</font> ((s = _dbus_strdup (<font class="stringliteral">"nomem"</font>)) == NULL) 00176 ; <font class="comment">/* only OK for debug spew... */</font> 00177 <font class="keywordflow">return</font> s; 00178 } 00179 } 00180 <font class="preprocessor">#endif </font><font class="comment">/* DBUS_ENABLE_VERBOSE_MODE */</font> 00181 00182 dbus_bool_t 00183 bus_match_rule_set_message_type (BusMatchRule *rule, 00184 <font class="keywordtype">int</font> type) 00185 { 00186 rule->flags |= BUS_MATCH_MESSAGE_TYPE; 00187 00188 rule->message_type = type; 00189 00190 <font class="keywordflow">return</font> TRUE; 00191 } 00192 00193 dbus_bool_t 00194 bus_match_rule_set_interface (BusMatchRule *rule, 00195 <font class="keyword">const</font> <font class="keywordtype">char</font> *interface) 00196 { 00197 <font class="keywordtype">char</font> *<font class="keyword">new</font>; 00198 00199 _dbus_assert (interface != NULL); 00200 00201 <font class="keyword">new</font> = _dbus_strdup (interface); 00202 <font class="keywordflow">if</font> (<font class="keyword">new</font> == NULL) 00203 <font class="keywordflow">return</font> FALSE; 00204 00205 rule->flags |= BUS_MATCH_INTERFACE; 00206 dbus_free (rule->interface); 00207 rule->interface = <font class="keyword">new</font>; 00208 00209 <font class="keywordflow">return</font> TRUE; 00210 } 00211 00212 dbus_bool_t 00213 bus_match_rule_set_member (BusMatchRule *rule, 00214 <font class="keyword">const</font> <font class="keywordtype">char</font> *member) 00215 { 00216 <font class="keywordtype">char</font> *<font class="keyword">new</font>; 00217 00218 _dbus_assert (member != NULL); 00219 00220 <font class="keyword">new</font> = _dbus_strdup (member); 00221 <font class="keywordflow">if</font> (<font class="keyword">new</font> == NULL) 00222 <font class="keywordflow">return</font> FALSE; 00223 00224 rule->flags |= BUS_MATCH_MEMBER; 00225 dbus_free (rule->member); 00226 rule->member = <font class="keyword">new</font>; 00227 00228 <font class="keywordflow">return</font> TRUE; 00229 } 00230 00231 dbus_bool_t 00232 bus_match_rule_set_sender (BusMatchRule *rule, 00233 <font class="keyword">const</font> <font class="keywordtype">char</font> *sender) 00234 { 00235 <font class="keywordtype">char</font> *<font class="keyword">new</font>; 00236 00237 _dbus_assert (sender != NULL); 00238 00239 <font class="keyword">new</font> = _dbus_strdup (sender); 00240 <font class="keywordflow">if</font> (<font class="keyword">new</font> == NULL) 00241 <font class="keywordflow">return</font> FALSE; 00242 00243 rule->flags |= BUS_MATCH_SENDER; 00244 dbus_free (rule->sender); 00245 rule->sender = <font class="keyword">new</font>; 00246 00247 <font class="keywordflow">return</font> TRUE; 00248 } 00249 00250 dbus_bool_t 00251 bus_match_rule_set_destination (BusMatchRule *rule, 00252 <font class="keyword">const</font> <font class="keywordtype">char</font> *destination) 00253 { 00254 <font class="keywordtype">char</font> *<font class="keyword">new</font>; 00255 00256 _dbus_assert (destination != NULL); 00257 00258 <font class="keyword">new</font> = _dbus_strdup (destination); 00259 <font class="keywordflow">if</font> (<font class="keyword">new</font> == NULL) 00260 <font class="keywordflow">return</font> FALSE; 00261 00262 rule->flags |= BUS_MATCH_DESTINATION; 00263 dbus_free (rule->destination); 00264 rule->destination = <font class="keyword">new</font>; 00265 00266 <font class="keywordflow">return</font> TRUE; 00267 } 00268 00269 dbus_bool_t 00270 bus_match_rule_set_path (BusMatchRule *rule, 00271 <font class="keyword">const</font> <font class="keywordtype">char</font> *path) 00272 { 00273 <font class="keywordtype">char</font> *<font class="keyword">new</font>; 00274 00275 _dbus_assert (path != NULL); 00276 00277 <font class="keyword">new</font> = _dbus_strdup (path); 00278 <font class="keywordflow">if</font> (<font class="keyword">new</font> == NULL) 00279 <font class="keywordflow">return</font> FALSE; 00280 00281 rule->flags |= BUS_MATCH_PATH; 00282 dbus_free (rule->path); 00283 rule->path = <font class="keyword">new</font>; 00284 00285 <font class="keywordflow">return</font> TRUE; 00286 } 00287 00288 <font class="comment">/*</font> 00289 <font class="comment"> * The format is comma-separated with strings quoted with single quotes</font> 00290 <font class="comment"> * as for the shell (to escape a literal single quote, use '\'').</font> 00291 <font class="comment"> *</font> 00292 <font class="comment"> * type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='Foo',</font> 00293 <font class="comment"> * path='/bar/foo',destination=':452345-34'</font> 00294 <font class="comment"> *</font> 00295 <font class="comment"> */</font> 00296 BusMatchRule* 00297 bus_match_rule_parse (<a class="code" href="structDBusConnection.html">DBusConnection</a> *matches_go_to, 00298 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *rule_text, 00299 <a class="code" href="structDBusError.html">DBusError</a> *error) 00300 { 00301 BusMatchRule *rule; 00302 00303 rule = bus_match_rule_new (matches_go_to); 00304 <font class="keywordflow">if</font> (rule == NULL) 00305 <font class="keywordflow">goto</font> oom; 00306 00307 <font class="comment">/* FIXME implement for real */</font> 00308 00309 <font class="keywordflow">if</font> (!bus_match_rule_set_message_type (rule, 00310 DBUS_MESSAGE_TYPE_SIGNAL)) 00311 <font class="keywordflow">goto</font> oom; 00312 00313 <font class="keywordflow">return</font> rule; 00314 00315 oom: 00316 <font class="keywordflow">if</font> (rule) 00317 bus_match_rule_unref (rule); 00318 BUS_SET_OOM (error); 00319 <font class="keywordflow">return</font> NULL; 00320 } 00321 00322 <font class="keyword">struct </font>BusMatchmaker 00323 { 00324 <font class="keywordtype">int</font> refcount; 00325 00326 <a class="code" href="structDBusList.html">DBusList</a> *all_rules; 00327 }; 00328 00329 BusMatchmaker* 00330 bus_matchmaker_new (<font class="keywordtype">void</font>) 00331 { 00332 BusMatchmaker *matchmaker; 00333 00334 matchmaker = dbus_new0 (BusMatchmaker, 1); 00335 <font class="keywordflow">if</font> (matchmaker == NULL) 00336 <font class="keywordflow">return</font> NULL; 00337 00338 matchmaker->refcount = 1; 00339 00340 <font class="keywordflow">return</font> matchmaker; 00341 } 00342 00343 <font class="keywordtype">void</font> 00344 bus_matchmaker_ref (BusMatchmaker *matchmaker) 00345 { 00346 _dbus_assert (matchmaker->refcount > 0); 00347 00348 matchmaker->refcount += 1; 00349 } 00350 00351 <font class="keywordtype">void</font> 00352 bus_matchmaker_unref (BusMatchmaker *matchmaker) 00353 { 00354 _dbus_assert (matchmaker->refcount > 0); 00355 00356 matchmaker->refcount -= 1; 00357 <font class="keywordflow">if</font> (matchmaker->refcount == 0) 00358 { 00359 <font class="keywordflow">while</font> (matchmaker->all_rules != NULL) 00360 { 00361 BusMatchRule *rule; 00362 00363 rule = matchmaker->all_rules->data; 00364 bus_match_rule_unref (rule); 00365 _dbus_list_remove_link (&matchmaker->all_rules, 00366 matchmaker->all_rules); 00367 } 00368 00369 dbus_free (matchmaker); 00370 } 00371 } 00372 00373 <font class="comment">/* The rule can't be modified after it's added. */</font> 00374 dbus_bool_t 00375 bus_matchmaker_add_rule (BusMatchmaker *matchmaker, 00376 BusMatchRule *rule) 00377 { 00378 _dbus_assert (bus_connection_is_active (rule->matches_go_to)); 00379 00380 <font class="keywordflow">if</font> (!_dbus_list_append (&matchmaker->all_rules, rule)) 00381 <font class="keywordflow">return</font> FALSE; 00382 00383 <font class="keywordflow">if</font> (!bus_connection_add_match_rule (rule->matches_go_to, rule)) 00384 { 00385 _dbus_list_remove_last (&matchmaker->all_rules, rule); 00386 <font class="keywordflow">return</font> FALSE; 00387 } 00388 00389 bus_match_rule_ref (rule); 00390 00391 <font class="preprocessor">#ifdef DBUS_ENABLE_VERBOSE_MODE</font> 00392 <font class="preprocessor"></font> { 00393 <font class="keywordtype">char</font> *s = match_rule_to_string (rule); 00394 00395 _dbus_verbose (<font class="stringliteral">"Added match rule %s to connection %p\n"</font>, 00396 s, rule->matches_go_to); 00397 dbus_free (s); 00398 } 00399 <font class="preprocessor">#endif</font> 00400 <font class="preprocessor"></font> 00401 <font class="keywordflow">return</font> TRUE; 00402 } 00403 00404 <font class="keyword">static</font> dbus_bool_t 00405 match_rule_equal (BusMatchRule *a, 00406 BusMatchRule *b) 00407 { 00408 <font class="keywordflow">if</font> (a->flags != b->flags) 00409 <font class="keywordflow">return</font> FALSE; 00410 00411 <font class="keywordflow">if</font> ((a->flags & BUS_MATCH_MESSAGE_TYPE) && 00412 a->message_type != b->message_type) 00413 <font class="keywordflow">return</font> FALSE; 00414 00415 <font class="keywordflow">if</font> ((a->flags & BUS_MATCH_MEMBER) && 00416 strcmp (a->member, b->member) != 0) 00417 <font class="keywordflow">return</font> FALSE; 00418 00419 <font class="keywordflow">if</font> ((a->flags & BUS_MATCH_PATH) && 00420 strcmp (a->path, b->path) != 0) 00421 <font class="keywordflow">return</font> FALSE; 00422 00423 <font class="keywordflow">if</font> ((a->flags & BUS_MATCH_INTERFACE) && 00424 strcmp (a->interface, b->interface) != 0) 00425 <font class="keywordflow">return</font> FALSE; 00426 00427 <font class="keywordflow">if</font> ((a->flags & BUS_MATCH_SENDER) && 00428 strcmp (a->sender, b->sender) != 0) 00429 <font class="keywordflow">return</font> FALSE; 00430 00431 <font class="keywordflow">if</font> ((a->flags & BUS_MATCH_DESTINATION) && 00432 strcmp (a->destination, b->destination) != 0) 00433 <font class="keywordflow">return</font> FALSE; 00434 00435 <font class="keywordflow">return</font> TRUE; 00436 } 00437 00438 <font class="keyword">static</font> <font class="keywordtype">void</font> 00439 bus_matchmaker_remove_rule_link (BusMatchmaker *matchmaker, 00440 <a class="code" href="structDBusList.html">DBusList</a> *link) 00441 { 00442 BusMatchRule *rule = link-><a class="code" href="structDBusList.html#m2">data</a>; 00443 00444 bus_connection_remove_match_rule (rule->matches_go_to, rule); 00445 _dbus_list_remove_link (&matchmaker->all_rules, link); 00446 00447 <font class="preprocessor">#ifdef DBUS_ENABLE_VERBOSE_MODE</font> 00448 <font class="preprocessor"></font> { 00449 <font class="keywordtype">char</font> *s = match_rule_to_string (rule); 00450 00451 _dbus_verbose (<font class="stringliteral">"Removed match rule %s for connection %p\n"</font>, 00452 s, rule->matches_go_to); 00453 dbus_free (s); 00454 } 00455 <font class="preprocessor">#endif</font> 00456 <font class="preprocessor"></font> 00457 bus_match_rule_unref (rule); 00458 } 00459 00460 <font class="keywordtype">void</font> 00461 bus_matchmaker_remove_rule (BusMatchmaker *matchmaker, 00462 BusMatchRule *rule) 00463 { 00464 bus_connection_remove_match_rule (rule->matches_go_to, rule); 00465 _dbus_list_remove (&matchmaker->all_rules, rule); 00466 00467 <font class="preprocessor">#ifdef DBUS_ENABLE_VERBOSE_MODE</font> 00468 <font class="preprocessor"></font> { 00469 <font class="keywordtype">char</font> *s = match_rule_to_string (rule); 00470 00471 _dbus_verbose (<font class="stringliteral">"Removed match rule %s for connection %p\n"</font>, 00472 s, rule->matches_go_to); 00473 dbus_free (s); 00474 } 00475 <font class="preprocessor">#endif</font> 00476 <font class="preprocessor"></font> 00477 bus_match_rule_unref (rule); 00478 } 00479 00480 <font class="comment">/* Remove a single rule which is equal to the given rule by value */</font> 00481 dbus_bool_t 00482 bus_matchmaker_remove_rule_by_value (BusMatchmaker *matchmaker, 00483 BusMatchRule *value, 00484 <a class="code" href="structDBusError.html">DBusError</a> *error) 00485 { 00486 <font class="comment">/* FIXME this is an unoptimized linear scan */</font> 00487 00488 <a class="code" href="structDBusList.html">DBusList</a> *link; 00489 00490 <font class="comment">/* we traverse backward because bus_connection_remove_match_rule()</font> 00491 <font class="comment"> * removes the most-recently-added rule</font> 00492 <font class="comment"> */</font> 00493 link = _dbus_list_get_last_link (&matchmaker->all_rules); 00494 <font class="keywordflow">while</font> (link != NULL) 00495 { 00496 BusMatchRule *rule; 00497 <a class="code" href="structDBusList.html">DBusList</a> *prev; 00498 00499 rule = link-><a class="code" href="structDBusList.html#m2">data</a>; 00500 prev = _dbus_list_get_prev_link (&matchmaker->all_rules, link); 00501 00502 <font class="keywordflow">if</font> (match_rule_equal (rule, value)) 00503 { 00504 bus_matchmaker_remove_rule_link (matchmaker, link); 00505 <font class="keywordflow">break</font>; 00506 } 00507 00508 link = prev; 00509 } 00510 00511 <font class="keywordflow">if</font> (link == NULL) 00512 { 00513 dbus_set_error (error, DBUS_ERROR_MATCH_RULE_NOT_FOUND, 00514 <font class="stringliteral">"The given match rule wasn't found and can't be removed"</font>); 00515 <font class="keywordflow">return</font> FALSE; 00516 } 00517 00518 <font class="keywordflow">return</font> TRUE; 00519 } 00520 00521 <font class="keywordtype">void</font> 00522 bus_matchmaker_disconnected (BusMatchmaker *matchmaker, 00523 <a class="code" href="structDBusConnection.html">DBusConnection</a> *disconnected) 00524 { 00525 <a class="code" href="structDBusList.html">DBusList</a> *link; 00526 00527 <font class="comment">/* FIXME</font> 00528 <font class="comment"> *</font> 00529 <font class="comment"> * This scans all match rules on the bus. We could avoid that</font> 00530 <font class="comment"> * for the rules belonging to the connection, since we keep</font> 00531 <font class="comment"> * a list of those; but for the rules that just refer to</font> 00532 <font class="comment"> * the connection we'd need to do something more elaborate.</font> 00533 <font class="comment"> * </font> 00534 <font class="comment"> */</font> 00535 00536 _dbus_assert (bus_connection_is_active (disconnected)); 00537 00538 link = _dbus_list_get_first_link (&matchmaker->all_rules); 00539 <font class="keywordflow">while</font> (link != NULL) 00540 { 00541 BusMatchRule *rule; 00542 <a class="code" href="structDBusList.html">DBusList</a> *next; 00543 00544 rule = link-><a class="code" href="structDBusList.html#m2">data</a>; 00545 next = _dbus_list_get_next_link (&matchmaker->all_rules, link); 00546 00547 <font class="keywordflow">if</font> (rule->matches_go_to == disconnected) 00548 { 00549 bus_matchmaker_remove_rule_link (matchmaker, link); 00550 } 00551 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (((rule->flags & BUS_MATCH_SENDER) && *rule->sender == <font class="charliteral">':'</font>) || 00552 ((rule->flags & BUS_MATCH_DESTINATION) && *rule->destination == <font class="charliteral">':'</font>)) 00553 { 00554 <font class="comment">/* The rule matches to/from a base service, see if it's the</font> 00555 <font class="comment"> * one being disconnected, since we know this service name</font> 00556 <font class="comment"> * will never be recycled.</font> 00557 <font class="comment"> */</font> 00558 <font class="keyword">const</font> <font class="keywordtype">char</font> *name; 00559 00560 name = bus_connection_get_name (disconnected); 00561 _dbus_assert (name != NULL); <font class="comment">/* because we're an active connection */</font> 00562 00563 <font class="keywordflow">if</font> (((rule->flags & BUS_MATCH_SENDER) && 00564 strcmp (rule->sender, name) == 0) || 00565 ((rule->flags & BUS_MATCH_DESTINATION) && 00566 strcmp (rule->destination, name) == 0)) 00567 { 00568 bus_matchmaker_remove_rule_link (matchmaker, link); 00569 } 00570 } 00571 00572 link = next; 00573 } 00574 } 00575 00576 <font class="keyword">static</font> dbus_bool_t 00577 connection_is_primary_owner (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection, 00578 <font class="keyword">const</font> <font class="keywordtype">char</font> *service_name) 00579 { 00580 BusService *service; 00581 <a class="code" href="structDBusString.html">DBusString</a> str; 00582 BusRegistry *registry; 00583 00584 registry = bus_connection_get_registry (connection); 00585 00586 _dbus_string_init_const (&str, service_name); 00587 service = bus_registry_lookup (registry, &str); 00588 00589 <font class="keywordflow">if</font> (service == NULL) 00590 <font class="keywordflow">return</font> FALSE; <font class="comment">/* Service doesn't exist so connection can't own it. */</font> 00591 00592 <font class="keywordflow">return</font> bus_service_get_primary_owner (service) == connection; 00593 } 00594 00595 <font class="keyword">static</font> dbus_bool_t 00596 match_rule_matches (BusMatchRule *rule, 00597 BusConnections *connections, 00598 <a class="code" href="structDBusConnection.html">DBusConnection</a> *sender, 00599 <a class="code" href="structDBusConnection.html">DBusConnection</a> *addressed_recipient, 00600 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message) 00601 { 00602 <font class="comment">/* All features of the match rule are AND'd together,</font> 00603 <font class="comment"> * so FALSE if any of them don't match.</font> 00604 <font class="comment"> */</font> 00605 00606 <font class="keywordflow">if</font> (rule->flags & BUS_MATCH_MESSAGE_TYPE) 00607 { 00608 _dbus_assert (rule->message_type != DBUS_MESSAGE_TYPE_INVALID); 00609 00610 <font class="keywordflow">if</font> (rule->message_type != dbus_message_get_type (message)) 00611 <font class="keywordflow">return</font> FALSE; 00612 } 00613 00614 <font class="keywordflow">if</font> (rule->flags & BUS_MATCH_INTERFACE) 00615 { 00616 <font class="keyword">const</font> <font class="keywordtype">char</font> *iface; 00617 00618 _dbus_assert (rule->interface != NULL); 00619 00620 iface = dbus_message_get_interface (message); 00621 <font class="keywordflow">if</font> (iface == NULL) 00622 <font class="keywordflow">return</font> FALSE; 00623 00624 <font class="keywordflow">if</font> (strcmp (iface, rule->interface) != 0) 00625 <font class="keywordflow">return</font> FALSE; 00626 } 00627 00628 <font class="keywordflow">if</font> (rule->flags & BUS_MATCH_MEMBER) 00629 { 00630 <font class="keyword">const</font> <font class="keywordtype">char</font> *member; 00631 00632 _dbus_assert (rule->member != NULL); 00633 00634 member = dbus_message_get_member (message); 00635 <font class="keywordflow">if</font> (member == NULL) 00636 <font class="keywordflow">return</font> FALSE; 00637 00638 <font class="keywordflow">if</font> (strcmp (member, rule->member) != 0) 00639 <font class="keywordflow">return</font> FALSE; 00640 } 00641 00642 <font class="keywordflow">if</font> (rule->flags & BUS_MATCH_SENDER) 00643 { 00644 _dbus_assert (rule->sender != NULL); 00645 00646 <font class="keywordflow">if</font> (!connection_is_primary_owner (sender, rule->sender)) 00647 <font class="keywordflow">return</font> FALSE; 00648 } 00649 00650 <font class="keywordflow">if</font> (rule->flags & BUS_MATCH_DESTINATION) 00651 { 00652 <font class="keyword">const</font> <font class="keywordtype">char</font> *destination; 00653 00654 _dbus_assert (rule->destination != NULL); 00655 00656 <font class="keywordflow">if</font> (addressed_recipient == NULL) 00657 <font class="keywordflow">return</font> FALSE; 00658 00659 destination = dbus_message_get_destination (message); 00660 <font class="keywordflow">if</font> (destination == NULL) 00661 <font class="keywordflow">return</font> FALSE; 00662 00663 <font class="keywordflow">if</font> (!connection_is_primary_owner (addressed_recipient, rule->destination)) 00664 <font class="keywordflow">return</font> FALSE; 00665 } 00666 00667 <font class="keywordflow">if</font> (rule->flags & BUS_MATCH_PATH) 00668 { 00669 <font class="keyword">const</font> <font class="keywordtype">char</font> *path; 00670 00671 _dbus_assert (rule->path != NULL); 00672 00673 path = dbus_message_get_path (message); 00674 <font class="keywordflow">if</font> (path == NULL) 00675 <font class="keywordflow">return</font> FALSE; 00676 00677 <font class="keywordflow">if</font> (strcmp (path, rule->path) != 0) 00678 <font class="keywordflow">return</font> FALSE; 00679 } 00680 00681 <font class="keywordflow">return</font> TRUE; 00682 } 00683 00684 dbus_bool_t 00685 bus_matchmaker_get_recipients (BusMatchmaker *matchmaker, 00686 BusConnections *connections, 00687 <a class="code" href="structDBusConnection.html">DBusConnection</a> *sender, 00688 <a class="code" href="structDBusConnection.html">DBusConnection</a> *addressed_recipient, 00689 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message, 00690 <a class="code" href="structDBusList.html">DBusList</a> **recipients_p) 00691 { 00692 <font class="comment">/* FIXME for now this is a wholly unoptimized linear search */</font> 00693 <font class="comment">/* Guessing the important optimization is to skip the signal-related</font> 00694 <font class="comment"> * match lists when processing method call and exception messages.</font> 00695 <font class="comment"> * So separate match rule lists for signals?</font> 00696 <font class="comment"> */</font> 00697 00698 <a class="code" href="structDBusList.html">DBusList</a> *link; 00699 00700 _dbus_assert (*recipients_p == NULL); 00701 00702 <font class="comment">/* This avoids sending same message to the same connection twice.</font> 00703 <font class="comment"> * Purpose of the stamp instead of a bool is to avoid iterating over</font> 00704 <font class="comment"> * all connections resetting the bool each time.</font> 00705 <font class="comment"> */</font> 00706 bus_connections_increment_stamp (connections); 00707 00708 <font class="comment">/* addressed_recipient is already receiving the message, don't add to list.</font> 00709 <font class="comment"> * NULL addressed_recipient means either bus driver, or this is a signal</font> 00710 <font class="comment"> * and thus lacks a specific addressed_recipient.</font> 00711 <font class="comment"> */</font> 00712 <font class="keywordflow">if</font> (addressed_recipient != NULL) 00713 bus_connection_mark_stamp (addressed_recipient); 00714 00715 link = _dbus_list_get_first_link (&matchmaker->all_rules); 00716 <font class="keywordflow">while</font> (link != NULL) 00717 { 00718 BusMatchRule *rule; 00719 00720 rule = link-><a class="code" href="structDBusList.html#m2">data</a>; 00721 00722 <font class="preprocessor">#ifdef DBUS_ENABLE_VERBOSE_MODE</font> 00723 <font class="preprocessor"></font> { 00724 <font class="keywordtype">char</font> *s = match_rule_to_string (rule); 00725 00726 _dbus_verbose (<font class="stringliteral">"Checking whether message matches rule %s for connection %p\n"</font>, 00727 s, rule->matches_go_to); 00728 dbus_free (s); 00729 } 00730 <font class="preprocessor">#endif</font> 00731 <font class="preprocessor"></font> 00732 <font class="keywordflow">if</font> (match_rule_matches (rule, connections, 00733 sender, addressed_recipient, message)) 00734 { 00735 _dbus_verbose (<font class="stringliteral">"Rule matched\n"</font>); 00736 00737 <font class="comment">/* Append to the list if we haven't already */</font> 00738 <font class="keywordflow">if</font> (bus_connection_mark_stamp (rule->matches_go_to)) 00739 { 00740 <font class="keywordflow">if</font> (!_dbus_list_append (recipients_p, rule->matches_go_to)) 00741 <font class="keywordflow">goto</font> nomem; 00742 } 00743 <font class="preprocessor">#ifdef DBUS_ENABLE_VERBOSE_MODE</font> 00744 <font class="preprocessor"></font> <font class="keywordflow">else</font> 00745 { 00746 _dbus_verbose (<font class="stringliteral">"Connection already receiving this message, so not adding again\n"</font>); 00747 } 00748 <font class="preprocessor">#endif </font><font class="comment">/* DBUS_ENABLE_VERBOSE_MODE */</font> 00749 } 00750 00751 link = _dbus_list_get_next_link (&matchmaker->all_rules, link); 00752 } 00753 00754 <font class="keywordflow">return</font> TRUE; 00755 00756 nomem: 00757 _dbus_list_clear (recipients_p); 00758 <font class="keywordflow">return</font> FALSE; 00759 } 00760 00761 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font> 00762 <font class="preprocessor"></font><font class="preprocessor">#include "test.h"</font> 00763 00764 dbus_bool_t 00765 bus_signals_test (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *test_data_dir) 00766 { 00767 BusMatchmaker *matchmaker; 00768 00769 matchmaker = bus_matchmaker_new (); 00770 bus_matchmaker_ref (matchmaker); 00771 bus_matchmaker_unref (matchmaker); 00772 bus_matchmaker_unref (matchmaker); 00773 00774 <font class="keywordflow">return</font> TRUE; 00775 } 00776 00777 <font class="preprocessor">#endif </font><font class="comment">/* DBUS_BUILD_TESTS */</font> 00778 </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>