Sophie

Sophie

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

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>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> &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>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-&gt;refcount = 1;
00053   rule-&gt;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-&gt;refcount &gt; 0);
00062 
00063   rule-&gt;refcount += 1;
00064 }
00065 
00066 <font class="keywordtype">void</font>
00067 bus_match_rule_unref (BusMatchRule *rule)
00068 {
00069   _dbus_assert (rule-&gt;refcount &gt; 0);
00070 
00071   rule-&gt;refcount -= 1;
00072   <font class="keywordflow">if</font> (rule-&gt;refcount == 0)
00073     {
00074       dbus_free (rule-&gt;interface);
00075       dbus_free (rule-&gt;member);
00076       dbus_free (rule-&gt;sender);
00077       dbus_free (rule-&gt;destination);
00078       dbus_free (rule-&gt;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 (&amp;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-&gt;flags &amp; BUS_MATCH_MESSAGE_TYPE)
00099     {
00100       <font class="comment">/* FIXME make type readable */</font>
00101       <font class="keywordflow">if</font> (!_dbus_string_append_printf (&amp;str, <font class="stringliteral">"type='%d'"</font>, rule-&gt;message_type))
00102         <font class="keywordflow">goto</font> nomem;
00103     }
00104 
00105   <font class="keywordflow">if</font> (rule-&gt;flags &amp; BUS_MATCH_INTERFACE)
00106     {
00107       <font class="keywordflow">if</font> (_dbus_string_get_length (&amp;str) &gt; 0)
00108         {
00109           <font class="keywordflow">if</font> (!_dbus_string_append (&amp;str, <font class="stringliteral">","</font>))
00110             <font class="keywordflow">goto</font> nomem;
00111         }
00112       
00113       <font class="keywordflow">if</font> (!_dbus_string_append_printf (&amp;str, <font class="stringliteral">"interface='%s'"</font>, rule-&gt;interface))
00114         <font class="keywordflow">goto</font> nomem;
00115     }
00116 
00117   <font class="keywordflow">if</font> (rule-&gt;flags &amp; BUS_MATCH_MEMBER)
00118     {
00119       <font class="keywordflow">if</font> (_dbus_string_get_length (&amp;str) &gt; 0)
00120         {
00121           <font class="keywordflow">if</font> (!_dbus_string_append (&amp;str, <font class="stringliteral">","</font>))
00122             <font class="keywordflow">goto</font> nomem;
00123         }
00124       
00125       <font class="keywordflow">if</font> (!_dbus_string_append_printf (&amp;str, <font class="stringliteral">"member='%s'"</font>, rule-&gt;member))
00126         <font class="keywordflow">goto</font> nomem;
00127     }
00128 
00129   <font class="keywordflow">if</font> (rule-&gt;flags &amp; BUS_MATCH_PATH)
00130     {
00131       <font class="keywordflow">if</font> (_dbus_string_get_length (&amp;str) &gt; 0)
00132         {
00133           <font class="keywordflow">if</font> (!_dbus_string_append (&amp;str, <font class="stringliteral">","</font>))
00134             <font class="keywordflow">goto</font> nomem;
00135         }
00136       
00137       <font class="keywordflow">if</font> (!_dbus_string_append_printf (&amp;str, <font class="stringliteral">"path='%s'"</font>, rule-&gt;path))
00138         <font class="keywordflow">goto</font> nomem;
00139     }
00140 
00141   <font class="keywordflow">if</font> (rule-&gt;flags &amp; BUS_MATCH_SENDER)
00142     {
00143       <font class="keywordflow">if</font> (_dbus_string_get_length (&amp;str) &gt; 0)
00144         {
00145           <font class="keywordflow">if</font> (!_dbus_string_append (&amp;str, <font class="stringliteral">","</font>))
00146             <font class="keywordflow">goto</font> nomem;
00147         }
00148       
00149       <font class="keywordflow">if</font> (!_dbus_string_append_printf (&amp;str, <font class="stringliteral">"sender='%s'"</font>, rule-&gt;sender))
00150         <font class="keywordflow">goto</font> nomem;
00151     }
00152 
00153   <font class="keywordflow">if</font> (rule-&gt;flags &amp; BUS_MATCH_DESTINATION)
00154     {
00155       <font class="keywordflow">if</font> (_dbus_string_get_length (&amp;str) &gt; 0)
00156         {
00157           <font class="keywordflow">if</font> (!_dbus_string_append (&amp;str, <font class="stringliteral">","</font>))
00158             <font class="keywordflow">goto</font> nomem;
00159         }
00160       
00161       <font class="keywordflow">if</font> (!_dbus_string_append_printf (&amp;str, <font class="stringliteral">"destination='%s'"</font>, rule-&gt;destination))
00162         <font class="keywordflow">goto</font> nomem;
00163     }
00164   
00165   <font class="keywordflow">if</font> (!_dbus_string_steal_data (&amp;str, &amp;ret))
00166     <font class="keywordflow">goto</font> nomem;
00167 
00168   _dbus_string_free (&amp;str);
00169   <font class="keywordflow">return</font> ret;
00170   
00171  nomem:
00172   _dbus_string_free (&amp;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-&gt;flags |= BUS_MATCH_MESSAGE_TYPE;
00187 
00188   rule-&gt;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-&gt;flags |= BUS_MATCH_INTERFACE;
00206   dbus_free (rule-&gt;interface);
00207   rule-&gt;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-&gt;flags |= BUS_MATCH_MEMBER;
00225   dbus_free (rule-&gt;member);
00226   rule-&gt;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-&gt;flags |= BUS_MATCH_SENDER;
00244   dbus_free (rule-&gt;sender);
00245   rule-&gt;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-&gt;flags |= BUS_MATCH_DESTINATION;
00263   dbus_free (rule-&gt;destination);
00264   rule-&gt;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-&gt;flags |= BUS_MATCH_PATH;
00282   dbus_free (rule-&gt;path);
00283   rule-&gt;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-&gt;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-&gt;refcount &gt; 0);
00347 
00348   matchmaker-&gt;refcount += 1;
00349 }
00350 
00351 <font class="keywordtype">void</font>
00352 bus_matchmaker_unref (BusMatchmaker *matchmaker)
00353 {
00354   _dbus_assert (matchmaker-&gt;refcount &gt; 0);
00355 
00356   matchmaker-&gt;refcount -= 1;
00357   <font class="keywordflow">if</font> (matchmaker-&gt;refcount == 0)
00358     {
00359       <font class="keywordflow">while</font> (matchmaker-&gt;all_rules != NULL)
00360         {
00361           BusMatchRule *rule;
00362 
00363           rule = matchmaker-&gt;all_rules-&gt;data;
00364           bus_match_rule_unref (rule);
00365           _dbus_list_remove_link (&amp;matchmaker-&gt;all_rules,
00366                                   matchmaker-&gt;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-&gt;matches_go_to));
00379 
00380   <font class="keywordflow">if</font> (!_dbus_list_append (&amp;matchmaker-&gt;all_rules, rule))
00381     <font class="keywordflow">return</font> FALSE;
00382 
00383   <font class="keywordflow">if</font> (!bus_connection_add_match_rule (rule-&gt;matches_go_to, rule))
00384     {
00385       _dbus_list_remove_last (&amp;matchmaker-&gt;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-&gt;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-&gt;flags != b-&gt;flags)
00409     <font class="keywordflow">return</font> FALSE;
00410 
00411   <font class="keywordflow">if</font> ((a-&gt;flags &amp; BUS_MATCH_MESSAGE_TYPE) &amp;&amp;
00412       a-&gt;message_type != b-&gt;message_type)
00413     <font class="keywordflow">return</font> FALSE;
00414 
00415   <font class="keywordflow">if</font> ((a-&gt;flags &amp; BUS_MATCH_MEMBER) &amp;&amp;
00416       strcmp (a-&gt;member, b-&gt;member) != 0)
00417     <font class="keywordflow">return</font> FALSE;
00418 
00419   <font class="keywordflow">if</font> ((a-&gt;flags &amp; BUS_MATCH_PATH) &amp;&amp;
00420       strcmp (a-&gt;path, b-&gt;path) != 0)
00421     <font class="keywordflow">return</font> FALSE;
00422   
00423   <font class="keywordflow">if</font> ((a-&gt;flags &amp; BUS_MATCH_INTERFACE) &amp;&amp;
00424       strcmp (a-&gt;interface, b-&gt;interface) != 0)
00425     <font class="keywordflow">return</font> FALSE;
00426 
00427   <font class="keywordflow">if</font> ((a-&gt;flags &amp; BUS_MATCH_SENDER) &amp;&amp;
00428       strcmp (a-&gt;sender, b-&gt;sender) != 0)
00429     <font class="keywordflow">return</font> FALSE;
00430 
00431   <font class="keywordflow">if</font> ((a-&gt;flags &amp; BUS_MATCH_DESTINATION) &amp;&amp;
00432       strcmp (a-&gt;destination, b-&gt;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-&gt;<a class="code" href="structDBusList.html#m2">data</a>;
00443   
00444   bus_connection_remove_match_rule (rule-&gt;matches_go_to, rule);
00445   _dbus_list_remove_link (&amp;matchmaker-&gt;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-&gt;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-&gt;matches_go_to, rule);
00465   _dbus_list_remove (&amp;matchmaker-&gt;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-&gt;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 (&amp;matchmaker-&gt;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-&gt;<a class="code" href="structDBusList.html#m2">data</a>;
00500       prev = _dbus_list_get_prev_link (&amp;matchmaker-&gt;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 (&amp;matchmaker-&gt;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-&gt;<a class="code" href="structDBusList.html#m2">data</a>;
00545       next = _dbus_list_get_next_link (&amp;matchmaker-&gt;all_rules, link);
00546 
00547       <font class="keywordflow">if</font> (rule-&gt;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-&gt;flags &amp; BUS_MATCH_SENDER) &amp;&amp; *rule-&gt;sender == <font class="charliteral">':'</font>) ||
00552                ((rule-&gt;flags &amp; BUS_MATCH_DESTINATION) &amp;&amp; *rule-&gt;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-&gt;flags &amp; BUS_MATCH_SENDER) &amp;&amp;
00564                strcmp (rule-&gt;sender, name) == 0) ||
00565               ((rule-&gt;flags &amp; BUS_MATCH_DESTINATION) &amp;&amp;
00566                strcmp (rule-&gt;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 (&amp;str, service_name);
00587   service = bus_registry_lookup (registry, &amp;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-&gt;flags &amp; BUS_MATCH_MESSAGE_TYPE)
00607     {
00608       _dbus_assert (rule-&gt;message_type != DBUS_MESSAGE_TYPE_INVALID);
00609 
00610       <font class="keywordflow">if</font> (rule-&gt;message_type != dbus_message_get_type (message))
00611         <font class="keywordflow">return</font> FALSE;
00612     }
00613 
00614   <font class="keywordflow">if</font> (rule-&gt;flags &amp; BUS_MATCH_INTERFACE)
00615     {
00616       <font class="keyword">const</font> <font class="keywordtype">char</font> *iface;
00617 
00618       _dbus_assert (rule-&gt;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-&gt;interface) != 0)
00625         <font class="keywordflow">return</font> FALSE;
00626     }
00627 
00628   <font class="keywordflow">if</font> (rule-&gt;flags &amp; BUS_MATCH_MEMBER)
00629     {
00630       <font class="keyword">const</font> <font class="keywordtype">char</font> *member;
00631 
00632       _dbus_assert (rule-&gt;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-&gt;member) != 0)
00639         <font class="keywordflow">return</font> FALSE;
00640     }
00641 
00642   <font class="keywordflow">if</font> (rule-&gt;flags &amp; BUS_MATCH_SENDER)
00643     {
00644       _dbus_assert (rule-&gt;sender != NULL);
00645 
00646       <font class="keywordflow">if</font> (!connection_is_primary_owner (sender, rule-&gt;sender))
00647         <font class="keywordflow">return</font> FALSE;
00648     }
00649 
00650   <font class="keywordflow">if</font> (rule-&gt;flags &amp; BUS_MATCH_DESTINATION)
00651     {
00652       <font class="keyword">const</font> <font class="keywordtype">char</font> *destination;
00653 
00654       _dbus_assert (rule-&gt;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-&gt;destination))
00664         <font class="keywordflow">return</font> FALSE;
00665     }
00666 
00667   <font class="keywordflow">if</font> (rule-&gt;flags &amp; BUS_MATCH_PATH)
00668     {
00669       <font class="keyword">const</font> <font class="keywordtype">char</font> *path;
00670 
00671       _dbus_assert (rule-&gt;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-&gt;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 (&amp;matchmaker-&gt;all_rules);
00716   <font class="keywordflow">while</font> (link != NULL)
00717     {
00718       BusMatchRule *rule;
00719 
00720       rule = link-&gt;<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-&gt;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-&gt;matches_go_to))
00739             {
00740               <font class="keywordflow">if</font> (!_dbus_list_append (recipients_p, rule-&gt;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 (&amp;matchmaker-&gt;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>