Sophie

Sophie

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

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>config-parser.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>config-parser.c</h1><div class="fragment"><pre>00001 <font class="comment">/* -*- mode: C; c-file-style: "gnu" -*- */</font>
00002 <font class="comment">/* config-parser.c  XML-library-agnostic configuration file parser</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 "config-parser.h"</font>
00024 <font class="preprocessor">#include "test.h"</font>
00025 <font class="preprocessor">#include "utils.h"</font>
00026 <font class="preprocessor">#include "policy.h"</font>
00027 <font class="preprocessor">#include &lt;dbus/dbus-list.h&gt;</font>
00028 <font class="preprocessor">#include &lt;dbus/dbus-internals.h&gt;</font>
00029 <font class="preprocessor">#include &lt;string.h&gt;</font>
00030 
00031 <font class="keyword">typedef</font> <font class="keyword">enum</font>
00032 {
00033   ELEMENT_NONE,
00034   ELEMENT_BUSCONFIG,
00035   ELEMENT_INCLUDE,
00036   ELEMENT_USER,
00037   ELEMENT_LISTEN,
00038   ELEMENT_AUTH,
00039   ELEMENT_POLICY,
00040   ELEMENT_LIMIT,
00041   ELEMENT_ALLOW,
00042   ELEMENT_DENY,
00043   ELEMENT_FORK,
00044   ELEMENT_PIDFILE,
00045   ELEMENT_SERVICEDIR,
00046   ELEMENT_INCLUDEDIR,
00047   ELEMENT_TYPE
00048 } ElementType;
00049 
00050 <font class="keyword">typedef</font> <font class="keyword">enum</font>
00051 {
00052   <font class="comment">/* we ignore policies for unknown groups/users */</font>
00053   POLICY_IGNORED,
00054 
00055   <font class="comment">/* non-ignored */</font>
00056   POLICY_DEFAULT,
00057   POLICY_MANDATORY,
00058   POLICY_USER,
00059   POLICY_GROUP
00060 } PolicyType;
00061 
00062 <font class="keyword">typedef</font> <font class="keyword">struct</font>
00063 <font class="keyword"></font>{
00064   ElementType type;
00065 
00066   <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> had_content : 1;
00067 
00068   <font class="keyword">union</font>
00069 <font class="keyword">  </font>{
00070     <font class="keyword">struct</font>
00071 <font class="keyword">    </font>{
00072       <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> ignore_missing : 1;
00073     } include;
00074 
00075     <font class="keyword">struct</font>
00076 <font class="keyword">    </font>{
00077       PolicyType type;
00078       <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> gid_or_uid;      
00079     } policy;
00080 
00081     <font class="keyword">struct</font>
00082 <font class="keyword">    </font>{
00083       <font class="keywordtype">char</font> *name;
00084       <font class="keywordtype">long</font> value;
00085     } limit;
00086     
00087   } d;
00088 
00089 } Element;
00090 
<a name="l00094"></a><a class="code" href="structBusConfigParser.html">00094</a> <font class="keyword">struct </font><a class="code" href="structBusConfigParser.html">BusConfigParser</a>
00095 {
<a name="l00096"></a><a class="code" href="structBusConfigParser.html#m0">00096</a>   <font class="keywordtype">int</font> <a class="code" href="structBusConfigParser.html#m0">refcount</a>;        
<a name="l00098"></a><a class="code" href="structBusConfigParser.html#m1">00098</a>   <a class="code" href="structDBusString.html">DBusString</a> <a class="code" href="structBusConfigParser.html#m1">basedir</a>;  
<a name="l00100"></a><a class="code" href="structBusConfigParser.html#m2">00100</a>   <a class="code" href="structDBusList.html">DBusList</a> *<a class="code" href="structBusConfigParser.html#m2">stack</a>;     
<a name="l00102"></a><a class="code" href="structBusConfigParser.html#m3">00102</a>   <font class="keywordtype">char</font> *<a class="code" href="structBusConfigParser.html#m3">user</a>;          
<a name="l00104"></a><a class="code" href="structBusConfigParser.html#m4">00104</a>   <font class="keywordtype">char</font> *<a class="code" href="structBusConfigParser.html#m4">bus_type</a>;          
<a name="l00106"></a><a class="code" href="structBusConfigParser.html#m5">00106</a>   <a class="code" href="structDBusList.html">DBusList</a> *<a class="code" href="structBusConfigParser.html#m5">listen_on</a>; 
<a name="l00108"></a><a class="code" href="structBusConfigParser.html#m6">00108</a>   <a class="code" href="structDBusList.html">DBusList</a> *<a class="code" href="structBusConfigParser.html#m6">mechanisms</a>; 
<a name="l00110"></a><a class="code" href="structBusConfigParser.html#m7">00110</a>   <a class="code" href="structDBusList.html">DBusList</a> *<a class="code" href="structBusConfigParser.html#m7">service_dirs</a>; 
<a name="l00112"></a><a class="code" href="structBusConfigParser.html#m8">00112</a>   BusPolicy *<a class="code" href="structBusConfigParser.html#m8">policy</a>;     
<a name="l00114"></a><a class="code" href="structBusConfigParser.html#m9">00114</a>   BusLimits <a class="code" href="structBusConfigParser.html#m9">limits</a>;      
<a name="l00116"></a><a class="code" href="structBusConfigParser.html#m10">00116</a>   <font class="keywordtype">char</font> *<a class="code" href="structBusConfigParser.html#m10">pidfile</a>;         
<a name="l00118"></a><a class="code" href="structBusConfigParser.html#m11">00118</a>   <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> <a class="code" href="structBusConfigParser.html#m11">fork</a> : 1; 
<a name="l00120"></a><a class="code" href="structBusConfigParser.html#m12">00120</a>   <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> <a class="code" href="structBusConfigParser.html#m12">is_toplevel</a> : 1; 
00121 };
00122 
00123 <font class="keyword">static</font> <font class="keyword">const</font> <font class="keywordtype">char</font>*
00124 element_type_to_name (ElementType type)
00125 {
00126   <font class="keywordflow">switch</font> (type)
00127     {
00128     <font class="keywordflow">case</font> ELEMENT_NONE:
00129       <font class="keywordflow">return</font> NULL;
00130     <font class="keywordflow">case</font> ELEMENT_BUSCONFIG:
00131       <font class="keywordflow">return</font> <font class="stringliteral">"busconfig"</font>;
00132     <font class="keywordflow">case</font> ELEMENT_INCLUDE:
00133       <font class="keywordflow">return</font> <font class="stringliteral">"include"</font>;
00134     <font class="keywordflow">case</font> ELEMENT_USER:
00135       <font class="keywordflow">return</font> <font class="stringliteral">"user"</font>;
00136     <font class="keywordflow">case</font> ELEMENT_LISTEN:
00137       <font class="keywordflow">return</font> <font class="stringliteral">"listen"</font>;
00138     <font class="keywordflow">case</font> ELEMENT_AUTH:
00139       <font class="keywordflow">return</font> <font class="stringliteral">"auth"</font>;
00140     <font class="keywordflow">case</font> ELEMENT_POLICY:
00141       <font class="keywordflow">return</font> <font class="stringliteral">"policy"</font>;
00142     <font class="keywordflow">case</font> ELEMENT_LIMIT:
00143       <font class="keywordflow">return</font> <font class="stringliteral">"limit"</font>;
00144     <font class="keywordflow">case</font> ELEMENT_ALLOW:
00145       <font class="keywordflow">return</font> <font class="stringliteral">"allow"</font>;
00146     <font class="keywordflow">case</font> ELEMENT_DENY:
00147       <font class="keywordflow">return</font> <font class="stringliteral">"deny"</font>;
00148     <font class="keywordflow">case</font> ELEMENT_FORK:
00149       <font class="keywordflow">return</font> <font class="stringliteral">"fork"</font>;
00150     <font class="keywordflow">case</font> ELEMENT_PIDFILE:
00151       <font class="keywordflow">return</font> <font class="stringliteral">"pidfile"</font>;
00152     <font class="keywordflow">case</font> ELEMENT_SERVICEDIR:
00153       <font class="keywordflow">return</font> <font class="stringliteral">"servicedir"</font>;
00154     <font class="keywordflow">case</font> ELEMENT_INCLUDEDIR:
00155       <font class="keywordflow">return</font> <font class="stringliteral">"includedir"</font>;
00156     <font class="keywordflow">case</font> ELEMENT_TYPE:
00157       <font class="keywordflow">return</font> <font class="stringliteral">"type"</font>;
00158     }
00159 
00160   _dbus_assert_not_reached (<font class="stringliteral">"bad element type"</font>);
00161 
00162   <font class="keywordflow">return</font> NULL;
00163 }
00164 
00165 <font class="keyword">static</font> Element*
00166 push_element (<a class="code" href="structBusConfigParser.html">BusConfigParser</a> *parser,
00167               ElementType      type)
00168 {
00169   Element *e;
00170 
00171   _dbus_assert (type != ELEMENT_NONE);
00172   
00173   e = dbus_new0 (Element, 1);
00174   <font class="keywordflow">if</font> (e == NULL)
00175     <font class="keywordflow">return</font> NULL;
00176 
00177   <font class="keywordflow">if</font> (!_dbus_list_append (&amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m2">stack</a>, e))
00178     {
00179       dbus_free (e);
00180       <font class="keywordflow">return</font> NULL;
00181     }
00182   
00183   e-&gt;type = type;
00184 
00185   <font class="keywordflow">return</font> e;
00186 }
00187 
00188 <font class="keyword">static</font> <font class="keywordtype">void</font>
00189 element_free (Element *e)
00190 {
00191   <font class="keywordflow">if</font> (e-&gt;type == ELEMENT_LIMIT)
00192     dbus_free (e-&gt;d.limit.name);
00193   
00194   dbus_free (e);
00195 }
00196 
00197 <font class="keyword">static</font> <font class="keywordtype">void</font>
00198 pop_element (<a class="code" href="structBusConfigParser.html">BusConfigParser</a> *parser)
00199 {
00200   Element *e;
00201 
00202   e = _dbus_list_pop_last (&amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m2">stack</a>);
00203   
00204   element_free (e);
00205 }
00206 
00207 <font class="keyword">static</font> Element*
00208 peek_element (<a class="code" href="structBusConfigParser.html">BusConfigParser</a> *parser)
00209 {
00210   Element *e;
00211 
00212   e = _dbus_list_get_last (&amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m2">stack</a>);
00213 
00214   <font class="keywordflow">return</font> e;
00215 }
00216 
00217 <font class="keyword">static</font> ElementType
00218 top_element_type (<a class="code" href="structBusConfigParser.html">BusConfigParser</a> *parser)
00219 {
00220   Element *e;
00221 
00222   e = _dbus_list_get_last (&amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m2">stack</a>);
00223 
00224   <font class="keywordflow">if</font> (e)
00225     <font class="keywordflow">return</font> e-&gt;type;
00226   <font class="keywordflow">else</font>
00227     <font class="keywordflow">return</font> ELEMENT_NONE;
00228 }
00229 
00230 <font class="keyword">static</font> dbus_bool_t
00231 merge_included (<a class="code" href="structBusConfigParser.html">BusConfigParser</a> *parser,
00232                 <a class="code" href="structBusConfigParser.html">BusConfigParser</a> *included,
00233                 <a class="code" href="structDBusError.html">DBusError</a>       *error)
00234 {
00235   <a class="code" href="structDBusList.html">DBusList</a> *link;
00236 
00237   <font class="keywordflow">if</font> (!bus_policy_merge (parser-&gt;<a class="code" href="structBusConfigParser.html#m8">policy</a>,
00238                          included-&gt;<a class="code" href="structBusConfigParser.html#m8">policy</a>))
00239     {
00240       BUS_SET_OOM (error);
00241       <font class="keywordflow">return</font> FALSE;
00242     }
00243   
00244   <font class="keywordflow">if</font> (included-&gt;<a class="code" href="structBusConfigParser.html#m3">user</a> != NULL)
00245     {
00246       dbus_free (parser-&gt;<a class="code" href="structBusConfigParser.html#m3">user</a>);
00247       parser-&gt;<a class="code" href="structBusConfigParser.html#m3">user</a> = included-&gt;<a class="code" href="structBusConfigParser.html#m3">user</a>;
00248       included-&gt;<a class="code" href="structBusConfigParser.html#m3">user</a> = NULL;
00249     }
00250 
00251   <font class="keywordflow">if</font> (included-&gt;<a class="code" href="structBusConfigParser.html#m4">bus_type</a> != NULL)
00252     {
00253       dbus_free (parser-&gt;<a class="code" href="structBusConfigParser.html#m4">bus_type</a>);
00254       parser-&gt;<a class="code" href="structBusConfigParser.html#m4">bus_type</a> = included-&gt;<a class="code" href="structBusConfigParser.html#m4">bus_type</a>;
00255       included-&gt;<a class="code" href="structBusConfigParser.html#m4">bus_type</a> = NULL;
00256     }
00257   
00258   <font class="keywordflow">if</font> (included-&gt;<a class="code" href="structBusConfigParser.html#m11">fork</a>)
00259     parser-&gt;<a class="code" href="structBusConfigParser.html#m11">fork</a> = TRUE;
00260 
00261   <font class="keywordflow">if</font> (included-&gt;<a class="code" href="structBusConfigParser.html#m10">pidfile</a> != NULL)
00262     {
00263       dbus_free (parser-&gt;<a class="code" href="structBusConfigParser.html#m10">pidfile</a>);
00264       parser-&gt;<a class="code" href="structBusConfigParser.html#m10">pidfile</a> = included-&gt;<a class="code" href="structBusConfigParser.html#m10">pidfile</a>;
00265       included-&gt;<a class="code" href="structBusConfigParser.html#m10">pidfile</a> = NULL;
00266     }
00267   
00268   <font class="keywordflow">while</font> ((link = _dbus_list_pop_first_link (&amp;included-&gt;<a class="code" href="structBusConfigParser.html#m5">listen_on</a>)))
00269     _dbus_list_append_link (&amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m5">listen_on</a>, link);
00270 
00271   <font class="keywordflow">while</font> ((link = _dbus_list_pop_first_link (&amp;included-&gt;<a class="code" href="structBusConfigParser.html#m6">mechanisms</a>)))
00272     _dbus_list_append_link (&amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m6">mechanisms</a>, link);
00273 
00274   <font class="keywordflow">while</font> ((link = _dbus_list_pop_first_link (&amp;included-&gt;<a class="code" href="structBusConfigParser.html#m7">service_dirs</a>)))
00275     _dbus_list_append_link (&amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m7">service_dirs</a>, link);
00276   
00277   <font class="keywordflow">return</font> TRUE;
00278 }
00279 
00280 <a class="code" href="structBusConfigParser.html">BusConfigParser</a>*
00281 bus_config_parser_new (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *basedir,
00282                        dbus_bool_t       is_toplevel)
00283 {
00284   <a class="code" href="structBusConfigParser.html">BusConfigParser</a> *parser;
00285 
00286   parser = dbus_new0 (<a class="code" href="structBusConfigParser.html">BusConfigParser</a>, 1);
00287   <font class="keywordflow">if</font> (parser == NULL)
00288     <font class="keywordflow">return</font> NULL;
00289 
00290   parser-&gt;<a class="code" href="structBusConfigParser.html#m12">is_toplevel</a> = !!is_toplevel;
00291   
00292   <font class="keywordflow">if</font> (!_dbus_string_init (&amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m1">basedir</a>))
00293     {
00294       dbus_free (parser);
00295       <font class="keywordflow">return</font> NULL;
00296     }
00297 
00298   <font class="keywordflow">if</font> (((parser-&gt;<a class="code" href="structBusConfigParser.html#m8">policy</a> = bus_policy_new ()) == NULL) ||
00299       !_dbus_string_copy (basedir, 0, &amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m1">basedir</a>, 0))
00300     {
00301       <font class="keywordflow">if</font> (parser-&gt;<a class="code" href="structBusConfigParser.html#m8">policy</a>)
00302         bus_policy_unref (parser-&gt;<a class="code" href="structBusConfigParser.html#m8">policy</a>);
00303       
00304       _dbus_string_free (&amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m1">basedir</a>);
00305       dbus_free (parser);
00306       <font class="keywordflow">return</font> NULL;
00307     }
00308 
00309   <font class="comment">/* Make up some numbers! woot! */</font>
00310   parser-&gt;<a class="code" href="structBusConfigParser.html#m9">limits</a>.max_incoming_bytes = _DBUS_ONE_MEGABYTE * 63;
00311   parser-&gt;<a class="code" href="structBusConfigParser.html#m9">limits</a>.max_outgoing_bytes = _DBUS_ONE_MEGABYTE * 63;
00312   parser-&gt;<a class="code" href="structBusConfigParser.html#m9">limits</a>.max_message_size = _DBUS_ONE_MEGABYTE * 32;
00313 
00314   <font class="comment">/* Making this long means the user has to wait longer for an error</font>
00315 <font class="comment">   * message if something screws up, but making it too short means</font>
00316 <font class="comment">   * they might see a false failure.</font>
00317 <font class="comment">   */</font>
00318   parser-&gt;<a class="code" href="structBusConfigParser.html#m9">limits</a>.activation_timeout = 25000; <font class="comment">/* 25 seconds */</font>
00319 
00320   <font class="comment">/* Making this long risks making a DOS attack easier, but too short</font>
00321 <font class="comment">   * and legitimate auth will fail.  If interactive auth (ask user for</font>
00322 <font class="comment">   * password) is allowed, then potentially it has to be quite long.</font>
00323 <font class="comment">   */</font>
00324   parser-&gt;<a class="code" href="structBusConfigParser.html#m9">limits</a>.auth_timeout = 30000; <font class="comment">/* 30 seconds */</font>
00325 
00326   parser-&gt;<a class="code" href="structBusConfigParser.html#m9">limits</a>.max_incomplete_connections = 32;
00327   parser-&gt;<a class="code" href="structBusConfigParser.html#m9">limits</a>.max_connections_per_user = 128;
00328 
00329   <font class="comment">/* Note that max_completed_connections / max_connections_per_user</font>
00330 <font class="comment">   * is the number of users that would have to work together to</font>
00331 <font class="comment">   * DOS all the other users.</font>
00332 <font class="comment">   */</font>
00333   parser-&gt;<a class="code" href="structBusConfigParser.html#m9">limits</a>.max_completed_connections = 1024;
00334 
00335   parser-&gt;<a class="code" href="structBusConfigParser.html#m9">limits</a>.max_pending_activations = 256;
00336   parser-&gt;<a class="code" href="structBusConfigParser.html#m9">limits</a>.max_services_per_connection = 256;
00337 
00338   parser-&gt;<a class="code" href="structBusConfigParser.html#m9">limits</a>.max_match_rules_per_connection = 128;
00339   
00340   parser-&gt;<a class="code" href="structBusConfigParser.html#m0">refcount</a> = 1;
00341 
00342   <font class="keywordflow">return</font> parser;
00343 }
00344 
00345 <font class="keywordtype">void</font>
00346 bus_config_parser_ref (<a class="code" href="structBusConfigParser.html">BusConfigParser</a> *parser)
00347 {
00348   _dbus_assert (parser-&gt;<a class="code" href="structBusConfigParser.html#m0">refcount</a> &gt; 0);
00349 
00350   parser-&gt;<a class="code" href="structBusConfigParser.html#m0">refcount</a> += 1;
00351 }
00352 
00353 <font class="keywordtype">void</font>
00354 bus_config_parser_unref (<a class="code" href="structBusConfigParser.html">BusConfigParser</a> *parser)
00355 {
00356   _dbus_assert (parser-&gt;<a class="code" href="structBusConfigParser.html#m0">refcount</a> &gt; 0);
00357 
00358   parser-&gt;<a class="code" href="structBusConfigParser.html#m0">refcount</a> -= 1;
00359 
00360   <font class="keywordflow">if</font> (parser-&gt;<a class="code" href="structBusConfigParser.html#m0">refcount</a> == 0)
00361     {
00362       <font class="keywordflow">while</font> (parser-&gt;<a class="code" href="structBusConfigParser.html#m2">stack</a> != NULL)
00363         pop_element (parser);
00364 
00365       dbus_free (parser-&gt;<a class="code" href="structBusConfigParser.html#m3">user</a>);
00366       dbus_free (parser-&gt;<a class="code" href="structBusConfigParser.html#m4">bus_type</a>);
00367       dbus_free (parser-&gt;<a class="code" href="structBusConfigParser.html#m10">pidfile</a>);
00368       
00369       _dbus_list_foreach (&amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m5">listen_on</a>,
00370                           (DBusForeachFunction) dbus_free,
00371                           NULL);
00372 
00373       _dbus_list_clear (&amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m5">listen_on</a>);
00374 
00375       _dbus_list_foreach (&amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m7">service_dirs</a>,
00376                           (DBusForeachFunction) dbus_free,
00377                           NULL);
00378 
00379       _dbus_list_clear (&amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m7">service_dirs</a>);
00380 
00381       _dbus_list_foreach (&amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m6">mechanisms</a>,
00382                           (DBusForeachFunction) dbus_free,
00383                           NULL);
00384 
00385       _dbus_list_clear (&amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m6">mechanisms</a>);
00386       
00387       _dbus_string_free (&amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m1">basedir</a>);
00388 
00389       <font class="keywordflow">if</font> (parser-&gt;<a class="code" href="structBusConfigParser.html#m8">policy</a>)
00390         bus_policy_unref (parser-&gt;<a class="code" href="structBusConfigParser.html#m8">policy</a>);
00391       
00392       dbus_free (parser);
00393     }
00394 }
00395 
00396 dbus_bool_t
00397 bus_config_parser_check_doctype (<a class="code" href="structBusConfigParser.html">BusConfigParser</a>   *parser,
00398                                  <font class="keyword">const</font> <font class="keywordtype">char</font>        *doctype,
00399                                  <a class="code" href="structDBusError.html">DBusError</a>         *error)
00400 {
00401   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00402 
00403   <font class="keywordflow">if</font> (strcmp (doctype, <font class="stringliteral">"busconfig"</font>) != 0)
00404     {
00405       dbus_set_error (error,
00406                       DBUS_ERROR_FAILED,
00407                       <font class="stringliteral">"Configuration file has the wrong document type %s"</font>,
00408                       doctype);
00409       <font class="keywordflow">return</font> FALSE;
00410     }
00411   <font class="keywordflow">else</font>
00412     <font class="keywordflow">return</font> TRUE;
00413 }
00414 
00415 <font class="keyword">typedef</font> <font class="keyword">struct</font>
00416 <font class="keyword"></font>{
00417   <font class="keyword">const</font> <font class="keywordtype">char</font>  *name;
00418   <font class="keyword">const</font> <font class="keywordtype">char</font> **retloc;
00419 } LocateAttr;
00420 
00421 <font class="keyword">static</font> dbus_bool_t
00422 locate_attributes (<a class="code" href="structBusConfigParser.html">BusConfigParser</a>  *parser,
00423                    <font class="keyword">const</font> <font class="keywordtype">char</font>       *element_name,
00424                    <font class="keyword">const</font> <font class="keywordtype">char</font>      **attribute_names,
00425                    <font class="keyword">const</font> <font class="keywordtype">char</font>      **attribute_values,
00426                    <a class="code" href="structDBusError.html">DBusError</a>        *error,
00427                    <font class="keyword">const</font> <font class="keywordtype">char</font>       *first_attribute_name,
00428                    <font class="keyword">const</font> <font class="keywordtype">char</font>      **first_attribute_retloc,
00429                    ...)
00430 {
00431   va_list args;
00432   <font class="keyword">const</font> <font class="keywordtype">char</font> *name;
00433   <font class="keyword">const</font> <font class="keywordtype">char</font> **retloc;
00434   <font class="keywordtype">int</font> n_attrs;
00435 <font class="preprocessor">#define MAX_ATTRS 24</font>
00436 <font class="preprocessor"></font>  LocateAttr attrs[MAX_ATTRS];
00437   dbus_bool_t retval;
00438   <font class="keywordtype">int</font> i;
00439 
00440   _dbus_assert (first_attribute_name != NULL);
00441   _dbus_assert (first_attribute_retloc != NULL);
00442 
00443   retval = TRUE;
00444 
00445   n_attrs = 1;
00446   attrs[0].name = first_attribute_name;
00447   attrs[0].retloc = first_attribute_retloc;
00448   *first_attribute_retloc = NULL;
00449 
00450   va_start (args, first_attribute_retloc);
00451 
00452   name = va_arg (args, <font class="keyword">const</font> <font class="keywordtype">char</font>*);
00453   retloc = va_arg (args, <font class="keyword">const</font> <font class="keywordtype">char</font>**);
00454 
00455   <font class="keywordflow">while</font> (name != NULL)
00456     {
00457       _dbus_assert (retloc != NULL);
00458       _dbus_assert (n_attrs &lt; MAX_ATTRS);
00459 
00460       attrs[n_attrs].name = name;
00461       attrs[n_attrs].retloc = retloc;
00462       n_attrs += 1;
00463       *retloc = NULL;
00464 
00465       name = va_arg (args, <font class="keyword">const</font> <font class="keywordtype">char</font>*);
00466       retloc = va_arg (args, <font class="keyword">const</font> <font class="keywordtype">char</font>**);
00467     }
00468 
00469   va_end (args);
00470 
00471   <font class="keywordflow">if</font> (!retval)
00472     <font class="keywordflow">return</font> retval;
00473 
00474   i = 0;
00475   <font class="keywordflow">while</font> (attribute_names[i])
00476     {
00477       <font class="keywordtype">int</font> j;
00478       dbus_bool_t found;
00479       
00480       found = FALSE;
00481       j = 0;
00482       <font class="keywordflow">while</font> (j &lt; n_attrs)
00483         {
00484           <font class="keywordflow">if</font> (strcmp (attrs[j].name, attribute_names[i]) == 0)
00485             {
00486               retloc = attrs[j].retloc;
00487 
00488               <font class="keywordflow">if</font> (*retloc != NULL)
00489                 {
00490                   dbus_set_error (error, DBUS_ERROR_FAILED,
00491                                   <font class="stringliteral">"Attribute \"%s\" repeated twice on the same &lt;%s&gt; element"</font>,
00492                                   attrs[j].name, element_name);
00493                   retval = FALSE;
00494                   <font class="keywordflow">goto</font> out;
00495                 }
00496 
00497               *retloc = attribute_values[i];
00498               found = TRUE;
00499             }
00500 
00501           ++j;
00502         }
00503 
00504       <font class="keywordflow">if</font> (!found)
00505         {
00506           dbus_set_error (error, DBUS_ERROR_FAILED,
00507                           <font class="stringliteral">"Attribute \"%s\" is invalid on &lt;%s&gt; element in this context"</font>,
00508                           attribute_names[i], element_name);
00509           retval = FALSE;
00510           <font class="keywordflow">goto</font> out;
00511         }
00512 
00513       ++i;
00514     }
00515 
00516  out:
00517   <font class="keywordflow">return</font> retval;
00518 }
00519 
00520 <font class="keyword">static</font> dbus_bool_t
00521 check_no_attributes (<a class="code" href="structBusConfigParser.html">BusConfigParser</a>  *parser,
00522                      <font class="keyword">const</font> <font class="keywordtype">char</font>       *element_name,
00523                      <font class="keyword">const</font> <font class="keywordtype">char</font>      **attribute_names,
00524                      <font class="keyword">const</font> <font class="keywordtype">char</font>      **attribute_values,
00525                      <a class="code" href="structDBusError.html">DBusError</a>        *error)
00526 {
00527   <font class="keywordflow">if</font> (attribute_names[0] != NULL)
00528     {
00529       dbus_set_error (error, DBUS_ERROR_FAILED,
00530                       <font class="stringliteral">"Attribute \"%s\" is invalid on &lt;%s&gt; element in this context"</font>,
00531                       attribute_names[0], element_name);
00532       <font class="keywordflow">return</font> FALSE;
00533     }
00534 
00535   <font class="keywordflow">return</font> TRUE;
00536 }
00537 
00538 <font class="keyword">static</font> dbus_bool_t
00539 start_busconfig_child (<a class="code" href="structBusConfigParser.html">BusConfigParser</a>   *parser,
00540                        <font class="keyword">const</font> <font class="keywordtype">char</font>        *element_name,
00541                        <font class="keyword">const</font> <font class="keywordtype">char</font>       **attribute_names,
00542                        <font class="keyword">const</font> <font class="keywordtype">char</font>       **attribute_values,
00543                        <a class="code" href="structDBusError.html">DBusError</a>         *error)
00544 {
00545   <font class="keywordflow">if</font> (strcmp (element_name, <font class="stringliteral">"user"</font>) == 0)
00546     {
00547       <font class="keywordflow">if</font> (!check_no_attributes (parser, <font class="stringliteral">"user"</font>, attribute_names, attribute_values, error))
00548         <font class="keywordflow">return</font> FALSE;
00549 
00550       <font class="keywordflow">if</font> (push_element (parser, ELEMENT_USER) == NULL)
00551         {
00552           BUS_SET_OOM (error);
00553           <font class="keywordflow">return</font> FALSE;
00554         }
00555 
00556       <font class="keywordflow">return</font> TRUE;
00557     }
00558   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (element_name, <font class="stringliteral">"type"</font>) == 0)
00559     {
00560       <font class="keywordflow">if</font> (!check_no_attributes (parser, <font class="stringliteral">"type"</font>, attribute_names, attribute_values, error))
00561         <font class="keywordflow">return</font> FALSE;
00562 
00563       <font class="keywordflow">if</font> (push_element (parser, ELEMENT_TYPE) == NULL)
00564         {
00565           BUS_SET_OOM (error);
00566           <font class="keywordflow">return</font> FALSE;
00567         }
00568 
00569       <font class="keywordflow">return</font> TRUE;
00570     }
00571   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (element_name, <font class="stringliteral">"fork"</font>) == 0)
00572     {
00573       <font class="keywordflow">if</font> (!check_no_attributes (parser, <font class="stringliteral">"fork"</font>, attribute_names, attribute_values, error))
00574         <font class="keywordflow">return</font> FALSE;
00575 
00576       <font class="keywordflow">if</font> (push_element (parser, ELEMENT_FORK) == NULL)
00577         {
00578           BUS_SET_OOM (error);
00579           <font class="keywordflow">return</font> FALSE;
00580         }
00581 
00582       parser-&gt;<a class="code" href="structBusConfigParser.html#m11">fork</a> = TRUE;
00583       
00584       <font class="keywordflow">return</font> TRUE;
00585     }
00586   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (element_name, <font class="stringliteral">"pidfile"</font>) == 0)
00587     {
00588       <font class="keywordflow">if</font> (!check_no_attributes (parser, <font class="stringliteral">"pidfile"</font>, attribute_names, attribute_values, error))
00589         <font class="keywordflow">return</font> FALSE;
00590 
00591       <font class="keywordflow">if</font> (push_element (parser, ELEMENT_PIDFILE) == NULL)
00592         {
00593           BUS_SET_OOM (error);
00594           <font class="keywordflow">return</font> FALSE;
00595         }
00596 
00597       <font class="keywordflow">return</font> TRUE;
00598     }
00599   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (element_name, <font class="stringliteral">"listen"</font>) == 0)
00600     {
00601       <font class="keywordflow">if</font> (!check_no_attributes (parser, <font class="stringliteral">"listen"</font>, attribute_names, attribute_values, error))
00602         <font class="keywordflow">return</font> FALSE;
00603 
00604       <font class="keywordflow">if</font> (push_element (parser, ELEMENT_LISTEN) == NULL)
00605         {
00606           BUS_SET_OOM (error);
00607           <font class="keywordflow">return</font> FALSE;
00608         }
00609 
00610       <font class="keywordflow">return</font> TRUE;
00611     }
00612   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (element_name, <font class="stringliteral">"auth"</font>) == 0)
00613     {
00614       <font class="keywordflow">if</font> (!check_no_attributes (parser, <font class="stringliteral">"auth"</font>, attribute_names, attribute_values, error))
00615         <font class="keywordflow">return</font> FALSE;
00616 
00617       <font class="keywordflow">if</font> (push_element (parser, ELEMENT_AUTH) == NULL)
00618         {
00619           BUS_SET_OOM (error);
00620           <font class="keywordflow">return</font> FALSE;
00621         }
00622 
00623       <font class="keywordflow">return</font> TRUE;
00624     }
00625   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (element_name, <font class="stringliteral">"includedir"</font>) == 0)
00626     {
00627       <font class="keywordflow">if</font> (!check_no_attributes (parser, <font class="stringliteral">"includedir"</font>, attribute_names, attribute_values, error))
00628         <font class="keywordflow">return</font> FALSE;
00629 
00630       <font class="keywordflow">if</font> (push_element (parser, ELEMENT_INCLUDEDIR) == NULL)
00631         {
00632           BUS_SET_OOM (error);
00633           <font class="keywordflow">return</font> FALSE;
00634         }
00635 
00636       <font class="keywordflow">return</font> TRUE;
00637     }
00638   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (element_name, <font class="stringliteral">"servicedir"</font>) == 0)
00639     {
00640       <font class="keywordflow">if</font> (!check_no_attributes (parser, <font class="stringliteral">"servicedir"</font>, attribute_names, attribute_values, error))
00641         <font class="keywordflow">return</font> FALSE;
00642 
00643       <font class="keywordflow">if</font> (push_element (parser, ELEMENT_SERVICEDIR) == NULL)
00644         {
00645           BUS_SET_OOM (error);
00646           <font class="keywordflow">return</font> FALSE;
00647         }
00648 
00649       <font class="keywordflow">return</font> TRUE;
00650     }
00651   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (element_name, <font class="stringliteral">"include"</font>) == 0)
00652     {
00653       Element *e;
00654       <font class="keyword">const</font> <font class="keywordtype">char</font> *ignore_missing;
00655 
00656       <font class="keywordflow">if</font> ((e = push_element (parser, ELEMENT_INCLUDE)) == NULL)
00657         {
00658           BUS_SET_OOM (error);
00659           <font class="keywordflow">return</font> FALSE;
00660         }
00661 
00662       e-&gt;d.include.ignore_missing = FALSE;
00663 
00664       <font class="keywordflow">if</font> (!locate_attributes (parser, <font class="stringliteral">"include"</font>,
00665                               attribute_names,
00666                               attribute_values,
00667                               error,
00668                               <font class="stringliteral">"ignore_missing"</font>, &amp;ignore_missing,
00669                               NULL))
00670         <font class="keywordflow">return</font> FALSE;
00671 
00672       <font class="keywordflow">if</font> (ignore_missing != NULL)
00673         {
00674           <font class="keywordflow">if</font> (strcmp (ignore_missing, <font class="stringliteral">"yes"</font>) == 0)
00675             e-&gt;d.include.ignore_missing = TRUE;
00676           <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (ignore_missing, <font class="stringliteral">"no"</font>) == 0)
00677             e-&gt;d.include.ignore_missing = FALSE;
00678           <font class="keywordflow">else</font>
00679             {
00680               dbus_set_error (error, DBUS_ERROR_FAILED,
00681                               <font class="stringliteral">"ignore_missing attribute must have value \"yes\" or \"no\""</font>);
00682               <font class="keywordflow">return</font> FALSE;
00683             }
00684         }
00685 
00686       <font class="keywordflow">return</font> TRUE;
00687     }
00688   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (element_name, <font class="stringliteral">"policy"</font>) == 0)
00689     {
00690       Element *e;
00691       <font class="keyword">const</font> <font class="keywordtype">char</font> *context;
00692       <font class="keyword">const</font> <font class="keywordtype">char</font> *user;
00693       <font class="keyword">const</font> <font class="keywordtype">char</font> *group;
00694 
00695       <font class="keywordflow">if</font> ((e = push_element (parser, ELEMENT_POLICY)) == NULL)
00696         {
00697           BUS_SET_OOM (error);
00698           <font class="keywordflow">return</font> FALSE;
00699         }
00700 
00701       e-&gt;d.policy.type = POLICY_IGNORED;
00702       
00703       <font class="keywordflow">if</font> (!locate_attributes (parser, <font class="stringliteral">"policy"</font>,
00704                               attribute_names,
00705                               attribute_values,
00706                               error,
00707                               <font class="stringliteral">"context"</font>, &amp;context,
00708                               <font class="stringliteral">"user"</font>, &amp;user,
00709                               <font class="stringliteral">"group"</font>, &amp;group,
00710                               NULL))
00711         <font class="keywordflow">return</font> FALSE;
00712 
00713       <font class="keywordflow">if</font> (((context &amp;&amp; user) ||
00714            (context &amp;&amp; group)) ||
00715           (user &amp;&amp; group) ||
00716           !(context || user || group))
00717         {
00718           dbus_set_error (error, DBUS_ERROR_FAILED,
00719                           <font class="stringliteral">"&lt;policy&gt; element must have exactly one of (context|user|group) attributes"</font>);
00720           <font class="keywordflow">return</font> FALSE;
00721         }
00722 
00723       <font class="keywordflow">if</font> (context != NULL)
00724         {
00725           <font class="keywordflow">if</font> (strcmp (context, <font class="stringliteral">"default"</font>) == 0)
00726             {
00727               e-&gt;d.policy.type = POLICY_DEFAULT;
00728             }
00729           <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (context, <font class="stringliteral">"mandatory"</font>) == 0)
00730             {
00731               e-&gt;d.policy.type = POLICY_MANDATORY;
00732             }
00733           <font class="keywordflow">else</font>
00734             {
00735               dbus_set_error (error, DBUS_ERROR_FAILED,
00736                               <font class="stringliteral">"context attribute on &lt;policy&gt; must have the value \"default\" or \"mandatory\", not \"%s\""</font>,
00737                               context);
00738               <font class="keywordflow">return</font> FALSE;
00739             }
00740         }
00741       <font class="keywordflow">else</font> <font class="keywordflow">if</font> (user != NULL)
00742         {
00743           <a class="code" href="structDBusString.html">DBusString</a> username;
00744           _dbus_string_init_const (&amp;username, user);
00745 
00746           <font class="keywordflow">if</font> (_dbus_get_user_id (&amp;username,
00747                                  &amp;e-&gt;d.policy.gid_or_uid))
00748             e-&gt;d.policy.type = POLICY_USER;
00749           <font class="keywordflow">else</font>
00750             _dbus_warn (<font class="stringliteral">"Unknown username \"%s\" in message bus configuration file\n"</font>,
00751                         user);
00752         }
00753       <font class="keywordflow">else</font> <font class="keywordflow">if</font> (group != NULL)
00754         {
00755           <a class="code" href="structDBusString.html">DBusString</a> group_name;
00756           _dbus_string_init_const (&amp;group_name, group);
00757 
00758           <font class="keywordflow">if</font> (_dbus_get_group_id (&amp;group_name,
00759                                   &amp;e-&gt;d.policy.gid_or_uid))
00760             e-&gt;d.policy.type = POLICY_GROUP;
00761           <font class="keywordflow">else</font>
00762             _dbus_warn (<font class="stringliteral">"Unknown group \"%s\" in message bus configuration file\n"</font>,
00763                         group);          
00764         }
00765       <font class="keywordflow">else</font>
00766         {
00767           _dbus_assert_not_reached (<font class="stringliteral">"all &lt;policy&gt; attributes null and we didn't set error"</font>);
00768         }
00769       
00770       <font class="keywordflow">return</font> TRUE;
00771     }
00772   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (element_name, <font class="stringliteral">"limit"</font>) == 0)
00773     {
00774       Element *e;
00775       <font class="keyword">const</font> <font class="keywordtype">char</font> *name;
00776 
00777       <font class="keywordflow">if</font> ((e = push_element (parser, ELEMENT_LIMIT)) == NULL)
00778         {
00779           BUS_SET_OOM (error);
00780           <font class="keywordflow">return</font> FALSE;
00781         }
00782       
00783       <font class="keywordflow">if</font> (!locate_attributes (parser, <font class="stringliteral">"limit"</font>,
00784                               attribute_names,
00785                               attribute_values,
00786                               error,
00787                               <font class="stringliteral">"name"</font>, &amp;name,
00788                               NULL))
00789         <font class="keywordflow">return</font> FALSE;
00790 
00791       <font class="keywordflow">if</font> (name == NULL)
00792         {
00793           dbus_set_error (error, DBUS_ERROR_FAILED,
00794                           <font class="stringliteral">"&lt;limit&gt; element must have a \"name\" attribute"</font>);
00795           <font class="keywordflow">return</font> FALSE;
00796         }
00797 
00798       e-&gt;d.limit.name = _dbus_strdup (name);
00799       <font class="keywordflow">if</font> (e-&gt;d.limit.name == NULL)
00800         {
00801           BUS_SET_OOM (error);
00802           <font class="keywordflow">return</font> FALSE;
00803         }
00804 
00805       <font class="keywordflow">return</font> TRUE;
00806     }
00807   <font class="keywordflow">else</font>
00808     {
00809       dbus_set_error (error, DBUS_ERROR_FAILED,
00810                       <font class="stringliteral">"Element &lt;%s&gt; not allowed inside &lt;%s&gt; in configuration file"</font>,
00811                       element_name, <font class="stringliteral">"busconfig"</font>);
00812       <font class="keywordflow">return</font> FALSE;
00813     }
00814 }
00815 
00816 <font class="keyword">static</font> <font class="keywordtype">int</font>
00817 message_type_from_string (<font class="keyword">const</font> <font class="keywordtype">char</font> *type_str)
00818 {
00819   <font class="keywordflow">if</font> (strcmp (type_str, <font class="stringliteral">"method_call"</font>) == 0)
00820     <font class="keywordflow">return</font> DBUS_MESSAGE_TYPE_METHOD_CALL;
00821   <font class="keywordflow">if</font> (strcmp (type_str, <font class="stringliteral">"method_return"</font>) == 0)
00822     <font class="keywordflow">return</font> DBUS_MESSAGE_TYPE_METHOD_RETURN;
00823   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (type_str, <font class="stringliteral">"signal"</font>) == 0)
00824     <font class="keywordflow">return</font> DBUS_MESSAGE_TYPE_SIGNAL;
00825   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (type_str, <font class="stringliteral">"error"</font>) == 0)
00826     <font class="keywordflow">return</font> DBUS_MESSAGE_TYPE_ERROR;
00827   <font class="keywordflow">else</font>
00828     <font class="keywordflow">return</font> DBUS_MESSAGE_TYPE_INVALID;
00829 }
00830 
00831 <font class="keyword">static</font> dbus_bool_t
00832 append_rule_from_element (<a class="code" href="structBusConfigParser.html">BusConfigParser</a>   *parser,
00833                           <font class="keyword">const</font> <font class="keywordtype">char</font>        *element_name,
00834                           <font class="keyword">const</font> <font class="keywordtype">char</font>       **attribute_names,
00835                           <font class="keyword">const</font> <font class="keywordtype">char</font>       **attribute_values,
00836                           dbus_bool_t        allow,
00837                           <a class="code" href="structDBusError.html">DBusError</a>         *error)
00838 {
00839   <font class="keyword">const</font> <font class="keywordtype">char</font> *send_interface;
00840   <font class="keyword">const</font> <font class="keywordtype">char</font> *send_member;
00841   <font class="keyword">const</font> <font class="keywordtype">char</font> *send_error;
00842   <font class="keyword">const</font> <font class="keywordtype">char</font> *send_destination;
00843   <font class="keyword">const</font> <font class="keywordtype">char</font> *send_path;
00844   <font class="keyword">const</font> <font class="keywordtype">char</font> *send_type;
00845   <font class="keyword">const</font> <font class="keywordtype">char</font> *receive_interface;
00846   <font class="keyword">const</font> <font class="keywordtype">char</font> *receive_member;
00847   <font class="keyword">const</font> <font class="keywordtype">char</font> *receive_error;
00848   <font class="keyword">const</font> <font class="keywordtype">char</font> *receive_sender;
00849   <font class="keyword">const</font> <font class="keywordtype">char</font> *receive_path;
00850   <font class="keyword">const</font> <font class="keywordtype">char</font> *receive_type;
00851   <font class="keyword">const</font> <font class="keywordtype">char</font> *eavesdrop;
00852   <font class="keyword">const</font> <font class="keywordtype">char</font> *own;
00853   <font class="keyword">const</font> <font class="keywordtype">char</font> *user;
00854   <font class="keyword">const</font> <font class="keywordtype">char</font> *group;
00855   BusPolicyRule *rule;
00856   
00857   <font class="keywordflow">if</font> (!locate_attributes (parser, element_name,
00858                           attribute_names,
00859                           attribute_values,
00860                           error,
00861                           <font class="stringliteral">"send_interface"</font>, &amp;send_interface,
00862                           <font class="stringliteral">"send_member"</font>, &amp;send_member,
00863                           <font class="stringliteral">"send_error"</font>, &amp;send_error,
00864                           <font class="stringliteral">"send_destination"</font>, &amp;send_destination,
00865                           <font class="stringliteral">"send_path"</font>, &amp;send_path,
00866                           <font class="stringliteral">"send_type"</font>, &amp;send_type,
00867                           <font class="stringliteral">"receive_interface"</font>, &amp;receive_interface,
00868                           <font class="stringliteral">"receive_member"</font>, &amp;receive_member,
00869                           <font class="stringliteral">"receive_error"</font>, &amp;receive_error,
00870                           <font class="stringliteral">"receive_sender"</font>, &amp;receive_sender,
00871                           <font class="stringliteral">"receive_path"</font>, &amp;receive_path,
00872                           <font class="stringliteral">"receive_type"</font>, &amp;receive_type,
00873                           <font class="stringliteral">"eavesdrop"</font>, &amp;eavesdrop,
00874                           <font class="stringliteral">"own"</font>, &amp;own,
00875                           <font class="stringliteral">"user"</font>, &amp;user,
00876                           <font class="stringliteral">"group"</font>, &amp;group,
00877                           NULL))
00878     <font class="keywordflow">return</font> FALSE;
00879 
00880   <font class="keywordflow">if</font> (!(send_interface || send_member || send_error || send_destination ||
00881         send_type || send_path ||
00882         receive_interface || receive_member || receive_error || receive_sender ||
00883         receive_type || receive_path || eavesdrop ||
00884         own || user || group))
00885     {
00886       dbus_set_error (error, DBUS_ERROR_FAILED,
00887                       <font class="stringliteral">"Element &lt;%s&gt; must have one or more attributes"</font>,
00888                       element_name);
00889       <font class="keywordflow">return</font> FALSE;
00890     }
00891 
00892   <font class="keywordflow">if</font> ((send_member &amp;&amp; (send_interface == NULL &amp;&amp; send_path == NULL)) ||
00893       (receive_member &amp;&amp; (receive_interface == NULL &amp;&amp; receive_path == NULL)))
00894     {
00895       dbus_set_error (error, DBUS_ERROR_FAILED,
00896                       <font class="stringliteral">"On element &lt;%s&gt;, if you specify a member you must specify an interface or a path. Keep in mind that not all messages have an interface field."</font>,
00897                       element_name);
00898       <font class="keywordflow">return</font> FALSE;
00899     }
00900   
00901   <font class="comment">/* Allowed combinations of elements are:</font>
00902 <font class="comment">   *</font>
00903 <font class="comment">   *   base, must be all send or all receive:</font>
00904 <font class="comment">   *     nothing</font>
00905 <font class="comment">   *     interface</font>
00906 <font class="comment">   *     interface + member</font>
00907 <font class="comment">   *     error</font>
00908 <font class="comment">   * </font>
00909 <font class="comment">   *   base send_ can combine with send_destination, send_path, send_type</font>
00910 <font class="comment">   *   base receive_ with receive_sender, receive_path, receive_type, eavesdrop</font>
00911 <font class="comment">   *</font>
00912 <font class="comment">   *   user, group, own must occur alone</font>
00913 <font class="comment">   *</font>
00914 <font class="comment">   * Pretty sure the below stuff is broken, FIXME think about it more.</font>
00915 <font class="comment">   */</font>
00916 
00917   <font class="keywordflow">if</font> (((send_interface &amp;&amp; send_error) ||
00918        (send_interface &amp;&amp; receive_interface) ||
00919        (send_interface &amp;&amp; receive_member) ||
00920        (send_interface &amp;&amp; receive_error) ||
00921        (send_interface &amp;&amp; receive_sender) ||
00922        (send_interface &amp;&amp; eavesdrop) ||
00923        (send_interface &amp;&amp; own) ||
00924        (send_interface &amp;&amp; user) ||
00925        (send_interface &amp;&amp; group)) ||
00926 
00927       ((send_member &amp;&amp; send_error) ||
00928        (send_member &amp;&amp; receive_interface) ||
00929        (send_member &amp;&amp; receive_member) ||
00930        (send_member &amp;&amp; receive_error) ||
00931        (send_member &amp;&amp; receive_sender) ||
00932        (send_member &amp;&amp; eavesdrop) ||
00933        (send_member &amp;&amp; own) ||
00934        (send_member &amp;&amp; user) ||
00935        (send_member &amp;&amp; group)) ||
00936       
00937       ((send_error &amp;&amp; receive_interface) ||
00938        (send_error &amp;&amp; receive_member) ||
00939        (send_error &amp;&amp; receive_error) ||
00940        (send_error &amp;&amp; receive_sender) ||
00941        (send_error &amp;&amp; eavesdrop) ||
00942        (send_error &amp;&amp; own) ||
00943        (send_error &amp;&amp; user) ||
00944        (send_error &amp;&amp; group)) ||
00945 
00946       ((send_destination &amp;&amp; receive_interface) ||
00947        (send_destination &amp;&amp; receive_member) ||
00948        (send_destination &amp;&amp; receive_error) ||
00949        (send_destination &amp;&amp; receive_sender) ||
00950        (send_destination &amp;&amp; eavesdrop) ||
00951        (send_destination &amp;&amp; own) ||
00952        (send_destination &amp;&amp; user) ||
00953        (send_destination &amp;&amp; group)) ||
00954 
00955       ((send_type &amp;&amp; receive_interface) ||
00956        (send_type &amp;&amp; receive_member) ||
00957        (send_type &amp;&amp; receive_error) ||
00958        (send_type &amp;&amp; receive_sender) ||
00959        (send_type &amp;&amp; eavesdrop) ||
00960        (send_type &amp;&amp; own) ||
00961        (send_type &amp;&amp; user) ||
00962        (send_type &amp;&amp; group)) ||
00963 
00964       ((send_path &amp;&amp; receive_interface) ||
00965        (send_path &amp;&amp; receive_member) ||
00966        (send_path &amp;&amp; receive_error) ||
00967        (send_path &amp;&amp; receive_sender) ||
00968        (send_path &amp;&amp; eavesdrop) ||
00969        (send_path &amp;&amp; own) ||
00970        (send_path &amp;&amp; user) ||
00971        (send_path &amp;&amp; group)) ||
00972       
00973       ((receive_interface &amp;&amp; receive_error) ||
00974        (receive_interface &amp;&amp; own) ||
00975        (receive_interface &amp;&amp; user) ||
00976        (receive_interface &amp;&amp; group)) ||
00977 
00978       ((receive_member &amp;&amp; receive_error) ||
00979        (receive_member &amp;&amp; own) ||
00980        (receive_member &amp;&amp; user) ||
00981        (receive_member &amp;&amp; group)) ||
00982       
00983       ((receive_error &amp;&amp; own) ||
00984        (receive_error &amp;&amp; user) ||
00985        (receive_error &amp;&amp; group)) ||
00986 
00987       ((eavesdrop &amp;&amp; own) ||
00988        (eavesdrop &amp;&amp; user) ||
00989        (eavesdrop &amp;&amp; group)) ||
00990       
00991       ((own &amp;&amp; user) ||
00992        (own &amp;&amp; group)) ||
00993 
00994       ((user &amp;&amp; group)))
00995     {
00996       dbus_set_error (error, DBUS_ERROR_FAILED,
00997                       <font class="stringliteral">"Invalid combination of attributes on element &lt;%s&gt;"</font>,
00998                       element_name);
00999       <font class="keywordflow">return</font> FALSE;
01000     }
01001   
01002   rule = NULL;
01003 
01004   <font class="comment">/* In BusPolicyRule, NULL represents wildcard.</font>
01005 <font class="comment">   * In the config file, '*' represents it.</font>
01006 <font class="comment">   */</font>
01007 <font class="preprocessor">#define IS_WILDCARD(str) ((str) &amp;&amp; ((str)[0]) == '*' &amp;&amp; ((str)[1]) == '\0')</font>
01008 <font class="preprocessor"></font>
01009   <font class="keywordflow">if</font> (send_interface || send_member || send_error || send_destination ||
01010       send_path || send_type)
01011     {
01012       <font class="keywordtype">int</font> message_type;
01013       
01014       <font class="keywordflow">if</font> (IS_WILDCARD (send_interface))
01015         send_interface = NULL;
01016       <font class="keywordflow">if</font> (IS_WILDCARD (send_member))
01017         send_member = NULL;
01018       <font class="keywordflow">if</font> (IS_WILDCARD (send_error))
01019         send_error = NULL;
01020       <font class="keywordflow">if</font> (IS_WILDCARD (send_destination))
01021         send_destination = NULL;
01022       <font class="keywordflow">if</font> (IS_WILDCARD (send_path))
01023         send_path = NULL;
01024       <font class="keywordflow">if</font> (IS_WILDCARD (send_type))
01025         send_type = NULL;
01026 
01027       message_type = DBUS_MESSAGE_TYPE_INVALID;
01028       <font class="keywordflow">if</font> (send_type != NULL)
01029         {
01030           message_type = message_type_from_string (send_type);
01031           <font class="keywordflow">if</font> (message_type == DBUS_MESSAGE_TYPE_INVALID)
01032             {
01033               dbus_set_error (error, DBUS_ERROR_FAILED,
01034                               <font class="stringliteral">"Bad message type \"%s\""</font>,
01035                               send_type);
01036               <font class="keywordflow">return</font> FALSE;
01037             }
01038         }
01039       
01040       rule = bus_policy_rule_new (BUS_POLICY_RULE_SEND, allow); 
01041       <font class="keywordflow">if</font> (rule == NULL)
01042         <font class="keywordflow">goto</font> nomem;
01043       
01044       rule-&gt;d.send.message_type = message_type;
01045       rule-&gt;d.send.path = _dbus_strdup (send_path);
01046       rule-&gt;d.send.interface = _dbus_strdup (send_interface);
01047       rule-&gt;d.send.member = _dbus_strdup (send_member);
01048       rule-&gt;d.send.error = _dbus_strdup (send_error);
01049       rule-&gt;d.send.destination = _dbus_strdup (send_destination);
01050       <font class="keywordflow">if</font> (send_path &amp;&amp; rule-&gt;d.send.path == NULL)
01051         <font class="keywordflow">goto</font> nomem;
01052       <font class="keywordflow">if</font> (send_interface &amp;&amp; rule-&gt;d.send.interface == NULL)
01053         <font class="keywordflow">goto</font> nomem;
01054       <font class="keywordflow">if</font> (send_member &amp;&amp; rule-&gt;d.send.member == NULL)
01055         <font class="keywordflow">goto</font> nomem;
01056       <font class="keywordflow">if</font> (send_error &amp;&amp; rule-&gt;d.send.error == NULL)
01057         <font class="keywordflow">goto</font> nomem;
01058       <font class="keywordflow">if</font> (send_destination &amp;&amp; rule-&gt;d.send.destination == NULL)
01059         <font class="keywordflow">goto</font> nomem;
01060     }
01061   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (receive_interface || receive_member || receive_error || receive_sender ||
01062            receive_path || receive_type || eavesdrop)
01063     {
01064       <font class="keywordtype">int</font> message_type;
01065       
01066       <font class="keywordflow">if</font> (IS_WILDCARD (receive_interface))
01067         receive_interface = NULL;
01068       <font class="keywordflow">if</font> (IS_WILDCARD (receive_member))
01069         receive_member = NULL;
01070       <font class="keywordflow">if</font> (IS_WILDCARD (receive_error))
01071         receive_error = NULL;
01072       <font class="keywordflow">if</font> (IS_WILDCARD (receive_sender))
01073         receive_sender = NULL;
01074       <font class="keywordflow">if</font> (IS_WILDCARD (receive_path))
01075         receive_path = NULL;
01076       <font class="keywordflow">if</font> (IS_WILDCARD (receive_type))
01077         receive_type = NULL;
01078 
01079       message_type = DBUS_MESSAGE_TYPE_INVALID;
01080       <font class="keywordflow">if</font> (receive_type != NULL)
01081         {
01082           message_type = message_type_from_string (receive_type);
01083           <font class="keywordflow">if</font> (message_type == DBUS_MESSAGE_TYPE_INVALID)
01084             {
01085               dbus_set_error (error, DBUS_ERROR_FAILED,
01086                               <font class="stringliteral">"Bad message type \"%s\""</font>,
01087                               receive_type);
01088               <font class="keywordflow">return</font> FALSE;
01089             }
01090         }
01091 
01092 
01093       <font class="keywordflow">if</font> (eavesdrop &amp;&amp;
01094           !(strcmp (eavesdrop, <font class="stringliteral">"true"</font>) == 0 ||
01095             strcmp (eavesdrop, <font class="stringliteral">"false"</font>) == 0))
01096         {
01097           dbus_set_error (error, DBUS_ERROR_FAILED,
01098                           <font class="stringliteral">"Bad value \"%s\" for eavesdrop attribute, must be true or false"</font>,
01099                           eavesdrop);
01100           <font class="keywordflow">return</font> FALSE;
01101         }
01102       
01103       rule = bus_policy_rule_new (BUS_POLICY_RULE_RECEIVE, allow); 
01104       <font class="keywordflow">if</font> (rule == NULL)
01105         <font class="keywordflow">goto</font> nomem;
01106 
01107       <font class="keywordflow">if</font> (eavesdrop)
01108         rule-&gt;d.receive.eavesdrop = (strcmp (eavesdrop, <font class="stringliteral">"true"</font>) == 0);
01109       
01110       rule-&gt;d.receive.message_type = message_type;
01111       rule-&gt;d.receive.path = _dbus_strdup (receive_path);
01112       rule-&gt;d.receive.interface = _dbus_strdup (receive_interface);
01113       rule-&gt;d.receive.member = _dbus_strdup (receive_member);
01114       rule-&gt;d.receive.error = _dbus_strdup (receive_error);
01115       rule-&gt;d.receive.origin = _dbus_strdup (receive_sender);
01116       <font class="keywordflow">if</font> (receive_path &amp;&amp; rule-&gt;d.receive.path == NULL)
01117         <font class="keywordflow">goto</font> nomem;
01118       <font class="keywordflow">if</font> (receive_interface &amp;&amp; rule-&gt;d.receive.interface == NULL)
01119         <font class="keywordflow">goto</font> nomem;
01120       <font class="keywordflow">if</font> (receive_member &amp;&amp; rule-&gt;d.receive.member == NULL)
01121         <font class="keywordflow">goto</font> nomem;
01122       <font class="keywordflow">if</font> (receive_error &amp;&amp; rule-&gt;d.receive.error == NULL)
01123         <font class="keywordflow">goto</font> nomem;
01124       <font class="keywordflow">if</font> (receive_sender &amp;&amp; rule-&gt;d.receive.origin == NULL)
01125         <font class="keywordflow">goto</font> nomem;
01126     }
01127   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (own)
01128     {
01129       rule = bus_policy_rule_new (BUS_POLICY_RULE_OWN, allow); 
01130       <font class="keywordflow">if</font> (rule == NULL)
01131         <font class="keywordflow">goto</font> nomem;
01132 
01133       <font class="keywordflow">if</font> (IS_WILDCARD (own))
01134         own = NULL;
01135       
01136       rule-&gt;d.own.service_name = _dbus_strdup (own);
01137       <font class="keywordflow">if</font> (own &amp;&amp; rule-&gt;d.own.service_name == NULL)
01138         <font class="keywordflow">goto</font> nomem;
01139     }
01140   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (user)
01141     {      
01142       <font class="keywordflow">if</font> (IS_WILDCARD (user))
01143         {
01144           rule = bus_policy_rule_new (BUS_POLICY_RULE_USER, allow); 
01145           <font class="keywordflow">if</font> (rule == NULL)
01146             <font class="keywordflow">goto</font> nomem;
01147 
01148           rule-&gt;d.user.uid = DBUS_UID_UNSET;
01149         }
01150       <font class="keywordflow">else</font>
01151         {
01152           <a class="code" href="structDBusString.html">DBusString</a> username;
01153           dbus_uid_t uid;
01154           
01155           _dbus_string_init_const (&amp;username, user);
01156       
01157           <font class="keywordflow">if</font> (_dbus_get_user_id (&amp;username, &amp;uid))
01158             {
01159               rule = bus_policy_rule_new (BUS_POLICY_RULE_USER, allow); 
01160               <font class="keywordflow">if</font> (rule == NULL)
01161                 <font class="keywordflow">goto</font> nomem;
01162 
01163               rule-&gt;d.user.uid = uid;
01164             }
01165           <font class="keywordflow">else</font>
01166             {
01167               _dbus_warn (<font class="stringliteral">"Unknown username \"%s\" on element &lt;%s&gt;\n"</font>,
01168                           user, element_name);
01169             }
01170         }
01171     }
01172   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (group)
01173     {
01174       <font class="keywordflow">if</font> (IS_WILDCARD (group))
01175         {
01176           rule = bus_policy_rule_new (BUS_POLICY_RULE_GROUP, allow); 
01177           <font class="keywordflow">if</font> (rule == NULL)
01178             <font class="keywordflow">goto</font> nomem;
01179 
01180           rule-&gt;d.group.gid = DBUS_GID_UNSET;
01181         }
01182       <font class="keywordflow">else</font>
01183         {
01184           <a class="code" href="structDBusString.html">DBusString</a> groupname;
01185           dbus_gid_t gid;
01186           
01187           _dbus_string_init_const (&amp;groupname, group);
01188           
01189           <font class="keywordflow">if</font> (_dbus_get_user_id (&amp;groupname, &amp;gid))
01190             {
01191               rule = bus_policy_rule_new (BUS_POLICY_RULE_GROUP, allow); 
01192               <font class="keywordflow">if</font> (rule == NULL)
01193                 <font class="keywordflow">goto</font> nomem;
01194 
01195               rule-&gt;d.group.gid = gid;
01196             }
01197           <font class="keywordflow">else</font>
01198             {
01199               _dbus_warn (<font class="stringliteral">"Unknown group \"%s\" on element &lt;%s&gt;\n"</font>,
01200                           group, element_name);
01201             }
01202         }
01203     }
01204   <font class="keywordflow">else</font>
01205     _dbus_assert_not_reached (<font class="stringliteral">"Did not handle some combination of attributes on &lt;allow&gt; or &lt;deny&gt;"</font>);
01206 
01207   <font class="keywordflow">if</font> (rule != NULL)
01208     {
01209       Element *pe;
01210       
01211       pe = peek_element (parser);      
01212       _dbus_assert (pe != NULL);
01213       _dbus_assert (pe-&gt;type == ELEMENT_POLICY);
01214 
01215       <font class="keywordflow">switch</font> (pe-&gt;d.policy.type)
01216         {
01217         <font class="keywordflow">case</font> POLICY_IGNORED:
01218           <font class="comment">/* drop the rule on the floor */</font>
01219           <font class="keywordflow">break</font>;
01220           
01221         <font class="keywordflow">case</font> POLICY_DEFAULT:
01222           <font class="keywordflow">if</font> (!bus_policy_append_default_rule (parser-&gt;<a class="code" href="structBusConfigParser.html#m8">policy</a>, rule))
01223             <font class="keywordflow">goto</font> nomem;
01224           <font class="keywordflow">break</font>;
01225         <font class="keywordflow">case</font> POLICY_MANDATORY:
01226           <font class="keywordflow">if</font> (!bus_policy_append_mandatory_rule (parser-&gt;<a class="code" href="structBusConfigParser.html#m8">policy</a>, rule))
01227             <font class="keywordflow">goto</font> nomem;
01228           <font class="keywordflow">break</font>;
01229         <font class="keywordflow">case</font> POLICY_USER:
01230           <font class="keywordflow">if</font> (!BUS_POLICY_RULE_IS_PER_CLIENT (rule))
01231             {
01232               dbus_set_error (error, DBUS_ERROR_FAILED,
01233                               <font class="stringliteral">"&lt;%s&gt; rule cannot be per-user because it has bus-global semantics"</font>,
01234                               element_name);
01235               <font class="keywordflow">goto</font> failed;
01236             }
01237           
01238           <font class="keywordflow">if</font> (!bus_policy_append_user_rule (parser-&gt;<a class="code" href="structBusConfigParser.html#m8">policy</a>, pe-&gt;d.policy.gid_or_uid,
01239                                             rule))
01240             <font class="keywordflow">goto</font> nomem;
01241           <font class="keywordflow">break</font>;
01242         <font class="keywordflow">case</font> POLICY_GROUP:
01243           <font class="keywordflow">if</font> (!BUS_POLICY_RULE_IS_PER_CLIENT (rule))
01244             {
01245               dbus_set_error (error, DBUS_ERROR_FAILED,
01246                               <font class="stringliteral">"&lt;%s&gt; rule cannot be per-group because it has bus-global semantics"</font>,
01247                               element_name);
01248               <font class="keywordflow">goto</font> failed;
01249             }
01250           
01251           <font class="keywordflow">if</font> (!bus_policy_append_group_rule (parser-&gt;<a class="code" href="structBusConfigParser.html#m8">policy</a>, pe-&gt;d.policy.gid_or_uid,
01252                                              rule))
01253             <font class="keywordflow">goto</font> nomem;
01254           <font class="keywordflow">break</font>;
01255         }
01256       
01257       bus_policy_rule_unref (rule);
01258       rule = NULL;
01259     }
01260   
01261   <font class="keywordflow">return</font> TRUE;
01262 
01263  nomem:
01264   BUS_SET_OOM (error);
01265  failed:
01266   <font class="keywordflow">if</font> (rule)
01267     bus_policy_rule_unref (rule);
01268   <font class="keywordflow">return</font> FALSE;
01269 }
01270 
01271 <font class="keyword">static</font> dbus_bool_t
01272 start_policy_child (<a class="code" href="structBusConfigParser.html">BusConfigParser</a>   *parser,
01273                     <font class="keyword">const</font> <font class="keywordtype">char</font>        *element_name,
01274                     <font class="keyword">const</font> <font class="keywordtype">char</font>       **attribute_names,
01275                     <font class="keyword">const</font> <font class="keywordtype">char</font>       **attribute_values,
01276                     <a class="code" href="structDBusError.html">DBusError</a>         *error)
01277 {
01278   <font class="keywordflow">if</font> (strcmp (element_name, <font class="stringliteral">"allow"</font>) == 0)
01279     {
01280       <font class="keywordflow">if</font> (!append_rule_from_element (parser, element_name,
01281                                      attribute_names, attribute_values,
01282                                      TRUE, error))
01283         <font class="keywordflow">return</font> FALSE;
01284       
01285       <font class="keywordflow">if</font> (push_element (parser, ELEMENT_ALLOW) == NULL)
01286         {
01287           BUS_SET_OOM (error);
01288           <font class="keywordflow">return</font> FALSE;
01289         }
01290       
01291       <font class="keywordflow">return</font> TRUE;
01292     }
01293   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (element_name, <font class="stringliteral">"deny"</font>) == 0)
01294     {
01295       <font class="keywordflow">if</font> (!append_rule_from_element (parser, element_name,
01296                                      attribute_names, attribute_values,
01297                                      FALSE, error))
01298         <font class="keywordflow">return</font> FALSE;
01299       
01300       <font class="keywordflow">if</font> (push_element (parser, ELEMENT_DENY) == NULL)
01301         {
01302           BUS_SET_OOM (error);
01303           <font class="keywordflow">return</font> FALSE;
01304         }
01305       
01306       <font class="keywordflow">return</font> TRUE;
01307     }
01308   <font class="keywordflow">else</font>
01309     {
01310       dbus_set_error (error, DBUS_ERROR_FAILED,
01311                       <font class="stringliteral">"Element &lt;%s&gt; not allowed inside &lt;%s&gt; in configuration file"</font>,
01312                       element_name, <font class="stringliteral">"policy"</font>);
01313       <font class="keywordflow">return</font> FALSE;
01314     }
01315 }
01316 
01317 dbus_bool_t
01318 bus_config_parser_start_element (<a class="code" href="structBusConfigParser.html">BusConfigParser</a>   *parser,
01319                                  <font class="keyword">const</font> <font class="keywordtype">char</font>        *element_name,
01320                                  <font class="keyword">const</font> <font class="keywordtype">char</font>       **attribute_names,
01321                                  <font class="keyword">const</font> <font class="keywordtype">char</font>       **attribute_values,
01322                                  <a class="code" href="structDBusError.html">DBusError</a>         *error)
01323 {
01324   ElementType t;
01325 
01326   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01327 
01328   <font class="comment">/* printf ("START: %s\n", element_name); */</font>
01329   
01330   t = top_element_type (parser);
01331 
01332   <font class="keywordflow">if</font> (t == ELEMENT_NONE)
01333     {
01334       <font class="keywordflow">if</font> (strcmp (element_name, <font class="stringliteral">"busconfig"</font>) == 0)
01335         {
01336           <font class="keywordflow">if</font> (!check_no_attributes (parser, <font class="stringliteral">"busconfig"</font>, attribute_names, attribute_values, error))
01337             <font class="keywordflow">return</font> FALSE;
01338           
01339           <font class="keywordflow">if</font> (push_element (parser, ELEMENT_BUSCONFIG) == NULL)
01340             {
01341               BUS_SET_OOM (error);
01342               <font class="keywordflow">return</font> FALSE;
01343             }
01344 
01345           <font class="keywordflow">return</font> TRUE;
01346         }
01347       <font class="keywordflow">else</font>
01348         {
01349           dbus_set_error (error, DBUS_ERROR_FAILED,
01350                           <font class="stringliteral">"Unknown element &lt;%s&gt; at root of configuration file"</font>,
01351                           element_name);
01352           <font class="keywordflow">return</font> FALSE;
01353         }
01354     }
01355   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (t == ELEMENT_BUSCONFIG)
01356     {
01357       <font class="keywordflow">return</font> start_busconfig_child (parser, element_name,
01358                                     attribute_names, attribute_values,
01359                                     error);
01360     }
01361   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (t == ELEMENT_POLICY)
01362     {
01363       <font class="keywordflow">return</font> start_policy_child (parser, element_name,
01364                                  attribute_names, attribute_values,
01365                                  error);
01366     }
01367   <font class="keywordflow">else</font>
01368     {
01369       dbus_set_error (error, DBUS_ERROR_FAILED,
01370                       <font class="stringliteral">"Element &lt;%s&gt; is not allowed in this context"</font>,
01371                       element_name);
01372       <font class="keywordflow">return</font> FALSE;
01373     }  
01374 }
01375 
01376 <font class="keyword">static</font> dbus_bool_t
01377 set_limit (<a class="code" href="structBusConfigParser.html">BusConfigParser</a> *parser,
01378            <font class="keyword">const</font> <font class="keywordtype">char</font>      *name,
01379            <font class="keywordtype">long</font>             value,
01380            <a class="code" href="structDBusError.html">DBusError</a>       *error)
01381 {
01382   dbus_bool_t must_be_positive;
01383   dbus_bool_t must_be_int;
01384 
01385   must_be_int = FALSE;
01386   must_be_positive = FALSE;
01387   
01388   <font class="keywordflow">if</font> (strcmp (name, <font class="stringliteral">"max_incoming_bytes"</font>) == 0)
01389     {
01390       must_be_positive = TRUE;
01391       parser-&gt;<a class="code" href="structBusConfigParser.html#m9">limits</a>.max_incoming_bytes = value;
01392     }
01393   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (name, <font class="stringliteral">"max_outgoing_bytes"</font>) == 0)
01394     {
01395       must_be_positive = TRUE;
01396       parser-&gt;<a class="code" href="structBusConfigParser.html#m9">limits</a>.max_outgoing_bytes = value;
01397     }
01398   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (name, <font class="stringliteral">"max_message_size"</font>) == 0)
01399     {
01400       must_be_positive = TRUE;
01401       parser-&gt;<a class="code" href="structBusConfigParser.html#m9">limits</a>.max_message_size = value;
01402     }
01403   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (name, <font class="stringliteral">"activation_timeout"</font>) == 0)
01404     {
01405       must_be_positive = TRUE;
01406       must_be_int = TRUE;
01407       parser-&gt;<a class="code" href="structBusConfigParser.html#m9">limits</a>.activation_timeout = value;
01408     }
01409   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (name, <font class="stringliteral">"auth_timeout"</font>) == 0)
01410     {
01411       must_be_positive = TRUE;
01412       must_be_int = TRUE;
01413       parser-&gt;<a class="code" href="structBusConfigParser.html#m9">limits</a>.auth_timeout = value;
01414     }
01415   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (name, <font class="stringliteral">"max_completed_connections"</font>) == 0)
01416     {
01417       must_be_positive = TRUE;
01418       must_be_int = TRUE;
01419       parser-&gt;<a class="code" href="structBusConfigParser.html#m9">limits</a>.max_completed_connections = value;
01420     }
01421   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (name, <font class="stringliteral">"max_incomplete_connections"</font>) == 0)
01422     {
01423       must_be_positive = TRUE;
01424       must_be_int = TRUE;
01425       parser-&gt;<a class="code" href="structBusConfigParser.html#m9">limits</a>.max_incomplete_connections = value;
01426     }
01427   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (name, <font class="stringliteral">"max_connections_per_user"</font>) == 0)
01428     {
01429       must_be_positive = TRUE;
01430       must_be_int = TRUE;
01431       parser-&gt;<a class="code" href="structBusConfigParser.html#m9">limits</a>.max_connections_per_user = value;
01432     }
01433   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (name, <font class="stringliteral">"max_pending_activations"</font>) == 0)
01434     {
01435       must_be_positive = TRUE;
01436       must_be_int = TRUE;
01437       parser-&gt;<a class="code" href="structBusConfigParser.html#m9">limits</a>.max_pending_activations = value;
01438     }
01439   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (name, <font class="stringliteral">"max_services_per_connection"</font>) == 0)
01440     {
01441       must_be_positive = TRUE;
01442       must_be_int = TRUE;
01443       parser-&gt;<a class="code" href="structBusConfigParser.html#m9">limits</a>.max_services_per_connection = value;
01444     }
01445   <font class="keywordflow">else</font>
01446     {
01447       dbus_set_error (error, DBUS_ERROR_FAILED,
01448                       <font class="stringliteral">"There is no limit called \"%s\"\n"</font>,
01449                       name);
01450       <font class="keywordflow">return</font> FALSE;
01451     }
01452   
01453   <font class="keywordflow">if</font> (must_be_positive &amp;&amp; value &lt; 0)
01454     {
01455       dbus_set_error (error, DBUS_ERROR_FAILED,
01456                       <font class="stringliteral">"&lt;limit name=\"%s\"&gt; must be a positive number\n"</font>,
01457                       name);
01458       <font class="keywordflow">return</font> FALSE;
01459     }
01460 
01461   <font class="keywordflow">if</font> (must_be_int &amp;&amp;
01462       (value &lt; _DBUS_INT_MIN || value &gt; _DBUS_INT_MAX))
01463     {
01464       dbus_set_error (error, DBUS_ERROR_FAILED,
01465                       <font class="stringliteral">"&lt;limit name=\"%s\"&gt; value is too large\n"</font>,
01466                       name);
01467       <font class="keywordflow">return</font> FALSE;
01468     }
01469 
01470   <font class="keywordflow">return</font> TRUE;  
01471 }
01472 
01473 dbus_bool_t
01474 bus_config_parser_end_element (<a class="code" href="structBusConfigParser.html">BusConfigParser</a>   *parser,
01475                                <font class="keyword">const</font> <font class="keywordtype">char</font>        *element_name,
01476                                <a class="code" href="structDBusError.html">DBusError</a>         *error)
01477 {
01478   ElementType t;
01479   <font class="keyword">const</font> <font class="keywordtype">char</font> *n;
01480   Element *e;
01481 
01482   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01483 
01484   <font class="comment">/* printf ("END: %s\n", element_name); */</font>
01485   
01486   t = top_element_type (parser);
01487 
01488   <font class="keywordflow">if</font> (t == ELEMENT_NONE)
01489     {
01490       <font class="comment">/* should probably be an assertion failure but</font>
01491 <font class="comment">       * being paranoid about XML parsers</font>
01492 <font class="comment">       */</font>
01493       dbus_set_error (error, DBUS_ERROR_FAILED,
01494                       <font class="stringliteral">"XML parser ended element with no element on the stack"</font>);
01495       <font class="keywordflow">return</font> FALSE;
01496     }
01497 
01498   n = element_type_to_name (t);
01499   _dbus_assert (n != NULL);
01500   <font class="keywordflow">if</font> (strcmp (n, element_name) != 0)
01501     {
01502       <font class="comment">/* should probably be an assertion failure but</font>
01503 <font class="comment">       * being paranoid about XML parsers</font>
01504 <font class="comment">       */</font>
01505       dbus_set_error (error, DBUS_ERROR_FAILED,
01506                       <font class="stringliteral">"XML element &lt;%s&gt; ended but topmost element on the stack was &lt;%s&gt;"</font>,
01507                       element_name, n);
01508       <font class="keywordflow">return</font> FALSE;
01509     }
01510 
01511   e = peek_element (parser);
01512   _dbus_assert (e != NULL);
01513 
01514   <font class="keywordflow">switch</font> (e-&gt;type)
01515     {
01516     <font class="keywordflow">case</font> ELEMENT_NONE:
01517       _dbus_assert_not_reached (<font class="stringliteral">"element in stack has no type"</font>);
01518       <font class="keywordflow">break</font>;
01519 
01520     <font class="keywordflow">case</font> ELEMENT_INCLUDE:
01521     <font class="keywordflow">case</font> ELEMENT_USER:
01522     <font class="keywordflow">case</font> ELEMENT_TYPE:
01523     <font class="keywordflow">case</font> ELEMENT_LISTEN:
01524     <font class="keywordflow">case</font> ELEMENT_PIDFILE:
01525     <font class="keywordflow">case</font> ELEMENT_AUTH:
01526     <font class="keywordflow">case</font> ELEMENT_SERVICEDIR:
01527     <font class="keywordflow">case</font> ELEMENT_INCLUDEDIR:
01528     <font class="keywordflow">case</font> ELEMENT_LIMIT:
01529       <font class="keywordflow">if</font> (!e-&gt;had_content)
01530         {
01531           dbus_set_error (error, DBUS_ERROR_FAILED,
01532                           <font class="stringliteral">"XML element &lt;%s&gt; was expected to have content inside it"</font>,
01533                           element_type_to_name (e-&gt;type));
01534           <font class="keywordflow">return</font> FALSE;
01535         }
01536 
01537       <font class="keywordflow">if</font> (e-&gt;type == ELEMENT_LIMIT)
01538         {
01539           <font class="keywordflow">if</font> (!set_limit (parser, e-&gt;d.limit.name, e-&gt;d.limit.value,
01540                           error))
01541             <font class="keywordflow">return</font> FALSE;
01542         }
01543       <font class="keywordflow">break</font>;
01544 
01545     <font class="keywordflow">case</font> ELEMENT_BUSCONFIG:
01546     <font class="keywordflow">case</font> ELEMENT_POLICY:
01547     <font class="keywordflow">case</font> ELEMENT_ALLOW:
01548     <font class="keywordflow">case</font> ELEMENT_DENY:
01549     <font class="keywordflow">case</font> ELEMENT_FORK:
01550       <font class="keywordflow">break</font>;
01551     }
01552 
01553   pop_element (parser);
01554 
01555   <font class="keywordflow">return</font> TRUE;
01556 }
01557 
01558 <font class="keyword">static</font> dbus_bool_t
01559 all_whitespace (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *str)
01560 {
01561   <font class="keywordtype">int</font> i;
01562 
01563   _dbus_string_skip_white (str, 0, &amp;i);
01564 
01565   <font class="keywordflow">return</font> i == _dbus_string_get_length (str);
01566 }
01567 
01568 <font class="keyword">static</font> dbus_bool_t
01569 make_full_path (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *basedir,
01570                 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *filename,
01571                 <a class="code" href="structDBusString.html">DBusString</a>       *full_path)
01572 {
01573   <font class="keywordflow">if</font> (_dbus_path_is_absolute (filename))
01574     {
01575       <font class="keywordflow">return</font> _dbus_string_copy (filename, 0, full_path, 0);
01576     }
01577   <font class="keywordflow">else</font>
01578     {
01579       <font class="keywordflow">if</font> (!_dbus_string_copy (basedir, 0, full_path, 0))
01580         <font class="keywordflow">return</font> FALSE;
01581       
01582       <font class="keywordflow">if</font> (!_dbus_concat_dir_and_file (full_path, filename))
01583         <font class="keywordflow">return</font> FALSE;
01584 
01585       <font class="keywordflow">return</font> TRUE;
01586     }
01587 }
01588 
01589 <font class="keyword">static</font> dbus_bool_t
01590 include_file (<a class="code" href="structBusConfigParser.html">BusConfigParser</a>   *parser,
01591               <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a>  *filename,
01592               dbus_bool_t        ignore_missing,
01593               <a class="code" href="structDBusError.html">DBusError</a>         *error)
01594 {
01595   <font class="comment">/* FIXME good test case for this would load each config file in the</font>
01596 <font class="comment">   * test suite both alone, and as an include, and check</font>
01597 <font class="comment">   * that the result is the same</font>
01598 <font class="comment">   */</font>
01599   <a class="code" href="structBusConfigParser.html">BusConfigParser</a> *included;
01600   <a class="code" href="structDBusError.html">DBusError</a> tmp_error;
01601         
01602   dbus_error_init (&amp;tmp_error);
01603   included = bus_config_load (filename, FALSE, &amp;tmp_error);
01604   <font class="keywordflow">if</font> (included == NULL)
01605     {
01606       _DBUS_ASSERT_ERROR_IS_SET (&amp;tmp_error);
01607 
01608       <font class="keywordflow">if</font> (dbus_error_has_name (&amp;tmp_error, DBUS_ERROR_FILE_NOT_FOUND) &amp;&amp;
01609           ignore_missing)
01610         {
01611           dbus_error_free (&amp;tmp_error);
01612           <font class="keywordflow">return</font> TRUE;
01613         }
01614       <font class="keywordflow">else</font>
01615         {
01616           dbus_move_error (&amp;tmp_error, error);
01617           <font class="keywordflow">return</font> FALSE;
01618         }
01619     }
01620   <font class="keywordflow">else</font>
01621     {
01622       _DBUS_ASSERT_ERROR_IS_CLEAR (&amp;tmp_error);
01623 
01624       <font class="keywordflow">if</font> (!merge_included (parser, included, error))
01625         {
01626           bus_config_parser_unref (included);
01627           <font class="keywordflow">return</font> FALSE;
01628         }
01629 
01630       bus_config_parser_unref (included);
01631       <font class="keywordflow">return</font> TRUE;
01632     }
01633 }
01634 
01635 <font class="keyword">static</font> dbus_bool_t
01636 include_dir (<a class="code" href="structBusConfigParser.html">BusConfigParser</a>   *parser,
01637              <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a>  *dirname,
01638              <a class="code" href="structDBusError.html">DBusError</a>         *error)
01639 {
01640   <a class="code" href="structDBusString.html">DBusString</a> filename;
01641   dbus_bool_t retval;
01642   <a class="code" href="structDBusError.html">DBusError</a> tmp_error;
01643   <a class="code" href="structDBusDirIter.html">DBusDirIter</a> *dir;
01644   
01645   <font class="keywordflow">if</font> (!_dbus_string_init (&amp;filename))
01646     {
01647       BUS_SET_OOM (error);
01648       <font class="keywordflow">return</font> FALSE;
01649     }
01650 
01651   retval = FALSE;
01652   
01653   dir = _dbus_directory_open (dirname, error);
01654 
01655   <font class="keywordflow">if</font> (dir == NULL)
01656     <font class="keywordflow">goto</font> failed;
01657 
01658   dbus_error_init (&amp;tmp_error);
01659   <font class="keywordflow">while</font> (_dbus_directory_get_next_file (dir, &amp;filename, &amp;tmp_error))
01660     {
01661       <a class="code" href="structDBusString.html">DBusString</a> full_path;
01662 
01663       <font class="keywordflow">if</font> (!_dbus_string_init (&amp;full_path))
01664         {
01665           BUS_SET_OOM (error);
01666           <font class="keywordflow">goto</font> failed;
01667         }
01668 
01669       <font class="keywordflow">if</font> (!_dbus_string_copy (dirname, 0, &amp;full_path, 0))
01670         {
01671           BUS_SET_OOM (error);
01672           _dbus_string_free (&amp;full_path);
01673           <font class="keywordflow">goto</font> failed;
01674         }      
01675 
01676       <font class="keywordflow">if</font> (!_dbus_concat_dir_and_file (&amp;full_path, &amp;filename))
01677         {
01678           BUS_SET_OOM (error);
01679           _dbus_string_free (&amp;full_path);
01680           <font class="keywordflow">goto</font> failed;
01681         }
01682       
01683       <font class="keywordflow">if</font> (_dbus_string_ends_with_c_str (&amp;full_path, <font class="stringliteral">".conf"</font>))
01684         {
01685           <font class="keywordflow">if</font> (!include_file (parser, &amp;full_path, TRUE, error))
01686             {
01687               _dbus_string_free (&amp;full_path);
01688               <font class="keywordflow">goto</font> failed;
01689             }
01690         }
01691 
01692       _dbus_string_free (&amp;full_path);
01693     }
01694 
01695   <font class="keywordflow">if</font> (dbus_error_is_set (&amp;tmp_error))
01696     {
01697       dbus_move_error (&amp;tmp_error, error);
01698       <font class="keywordflow">goto</font> failed;
01699     }
01700   
01701   retval = TRUE;
01702   
01703  failed:
01704   _dbus_string_free (&amp;filename);
01705   
01706   <font class="keywordflow">if</font> (dir)
01707     _dbus_directory_close (dir);
01708 
01709   <font class="keywordflow">return</font> retval;
01710 }
01711 
01712 dbus_bool_t
01713 bus_config_parser_content (<a class="code" href="structBusConfigParser.html">BusConfigParser</a>   *parser,
01714                            <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a>  *content,
01715                            <a class="code" href="structDBusError.html">DBusError</a>         *error)
01716 {
01717   Element *e;
01718 
01719   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01720 
01721 <font class="preprocessor">#if 0</font>
01722 <font class="preprocessor"></font>  {
01723     <font class="keyword">const</font> <font class="keywordtype">char</font> *c_str;
01724     
01725     _dbus_string_get_const_data (content, &amp;c_str);
01726 
01727     printf (<font class="stringliteral">"CONTENT %d bytes: %s\n"</font>, _dbus_string_get_length (content), c_str);
01728   }
01729 <font class="preprocessor">#endif</font>
01730 <font class="preprocessor"></font>  
01731   e = peek_element (parser);
01732   <font class="keywordflow">if</font> (e == NULL)
01733     {
01734       dbus_set_error (error, DBUS_ERROR_FAILED,
01735                       <font class="stringliteral">"Text content outside of any XML element in configuration file"</font>);
01736       <font class="keywordflow">return</font> FALSE;
01737     }
01738   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (e-&gt;had_content)
01739     {
01740       _dbus_assert_not_reached (<font class="stringliteral">"Element had multiple content blocks"</font>);
01741       <font class="keywordflow">return</font> FALSE;
01742     }
01743 
01744   <font class="keywordflow">switch</font> (top_element_type (parser))
01745     {
01746     <font class="keywordflow">case</font> ELEMENT_NONE:
01747       _dbus_assert_not_reached (<font class="stringliteral">"element at top of stack has no type"</font>);
01748       <font class="keywordflow">return</font> FALSE;
01749 
01750     <font class="keywordflow">case</font> ELEMENT_BUSCONFIG:
01751     <font class="keywordflow">case</font> ELEMENT_POLICY:
01752     <font class="keywordflow">case</font> ELEMENT_ALLOW:
01753     <font class="keywordflow">case</font> ELEMENT_DENY:
01754     <font class="keywordflow">case</font> ELEMENT_FORK:
01755       <font class="keywordflow">if</font> (all_whitespace (content))
01756         <font class="keywordflow">return</font> TRUE;
01757       <font class="keywordflow">else</font>
01758         {
01759           dbus_set_error (error, DBUS_ERROR_FAILED,
01760                           <font class="stringliteral">"No text content expected inside XML element %s in configuration file"</font>,
01761                           element_type_to_name (top_element_type (parser)));
01762           <font class="keywordflow">return</font> FALSE;
01763         }
01764 
01765     <font class="keywordflow">case</font> ELEMENT_PIDFILE:
01766       {
01767         <font class="keywordtype">char</font> *s;
01768 
01769         e-&gt;had_content = TRUE;
01770         
01771         <font class="keywordflow">if</font> (!_dbus_string_copy_data (content, &amp;s))
01772           <font class="keywordflow">goto</font> nomem;
01773           
01774         dbus_free (parser-&gt;<a class="code" href="structBusConfigParser.html#m10">pidfile</a>);
01775         parser-&gt;<a class="code" href="structBusConfigParser.html#m10">pidfile</a> = s;
01776       }
01777       <font class="keywordflow">break</font>;
01778 
01779     <font class="keywordflow">case</font> ELEMENT_INCLUDE:
01780       {
01781         <a class="code" href="structDBusString.html">DBusString</a> full_path;
01782         
01783         e-&gt;had_content = TRUE;
01784 
01785         <font class="keywordflow">if</font> (!_dbus_string_init (&amp;full_path))
01786           <font class="keywordflow">goto</font> nomem;
01787         
01788         <font class="keywordflow">if</font> (!make_full_path (&amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m1">basedir</a>, content, &amp;full_path))
01789           {
01790             _dbus_string_free (&amp;full_path);
01791             <font class="keywordflow">goto</font> nomem;
01792           }
01793         
01794         <font class="keywordflow">if</font> (!include_file (parser, &amp;full_path,
01795                            e-&gt;d.include.ignore_missing, error))
01796           {
01797             _dbus_string_free (&amp;full_path);
01798             <font class="keywordflow">return</font> FALSE;
01799           }
01800 
01801         _dbus_string_free (&amp;full_path);
01802       }
01803       <font class="keywordflow">break</font>;
01804 
01805     <font class="keywordflow">case</font> ELEMENT_INCLUDEDIR:
01806       {
01807         <a class="code" href="structDBusString.html">DBusString</a> full_path;
01808         
01809         e-&gt;had_content = TRUE;
01810 
01811         <font class="keywordflow">if</font> (!_dbus_string_init (&amp;full_path))
01812           <font class="keywordflow">goto</font> nomem;
01813         
01814         <font class="keywordflow">if</font> (!make_full_path (&amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m1">basedir</a>, content, &amp;full_path))
01815           {
01816             _dbus_string_free (&amp;full_path);
01817             <font class="keywordflow">goto</font> nomem;
01818           }
01819         
01820         <font class="keywordflow">if</font> (!include_dir (parser, &amp;full_path, error))
01821           {
01822             _dbus_string_free (&amp;full_path);
01823             <font class="keywordflow">return</font> FALSE;
01824           }
01825 
01826         _dbus_string_free (&amp;full_path);
01827       }
01828       <font class="keywordflow">break</font>;
01829       
01830     <font class="keywordflow">case</font> ELEMENT_USER:
01831       {
01832         <font class="keywordtype">char</font> *s;
01833 
01834         e-&gt;had_content = TRUE;
01835         
01836         <font class="keywordflow">if</font> (!_dbus_string_copy_data (content, &amp;s))
01837           <font class="keywordflow">goto</font> nomem;
01838           
01839         dbus_free (parser-&gt;<a class="code" href="structBusConfigParser.html#m3">user</a>);
01840         parser-&gt;<a class="code" href="structBusConfigParser.html#m3">user</a> = s;
01841       }
01842       <font class="keywordflow">break</font>;
01843 
01844     <font class="keywordflow">case</font> ELEMENT_TYPE:
01845       {
01846         <font class="keywordtype">char</font> *s;
01847 
01848         e-&gt;had_content = TRUE;
01849 
01850         <font class="keywordflow">if</font> (!_dbus_string_copy_data (content, &amp;s))
01851           <font class="keywordflow">goto</font> nomem;
01852         
01853         dbus_free (parser-&gt;<a class="code" href="structBusConfigParser.html#m4">bus_type</a>);
01854         parser-&gt;<a class="code" href="structBusConfigParser.html#m4">bus_type</a> = s;
01855       }
01856       <font class="keywordflow">break</font>;
01857       
01858     <font class="keywordflow">case</font> ELEMENT_LISTEN:
01859       {
01860         <font class="keywordtype">char</font> *s;
01861 
01862         e-&gt;had_content = TRUE;
01863         
01864         <font class="keywordflow">if</font> (!_dbus_string_copy_data (content, &amp;s))
01865           <font class="keywordflow">goto</font> nomem;
01866 
01867         <font class="keywordflow">if</font> (!_dbus_list_append (&amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m5">listen_on</a>,
01868                                 s))
01869           {
01870             dbus_free (s);
01871             <font class="keywordflow">goto</font> nomem;
01872           }
01873       }
01874       <font class="keywordflow">break</font>;
01875 
01876     <font class="keywordflow">case</font> ELEMENT_AUTH:
01877       {
01878         <font class="keywordtype">char</font> *s;
01879         
01880         e-&gt;had_content = TRUE;
01881 
01882         <font class="keywordflow">if</font> (!_dbus_string_copy_data (content, &amp;s))
01883           <font class="keywordflow">goto</font> nomem;
01884 
01885         <font class="keywordflow">if</font> (!_dbus_list_append (&amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m6">mechanisms</a>,
01886                                 s))
01887           {
01888             dbus_free (s);
01889             <font class="keywordflow">goto</font> nomem;
01890           }
01891       }
01892       <font class="keywordflow">break</font>;
01893 
01894     <font class="keywordflow">case</font> ELEMENT_SERVICEDIR:
01895       {
01896         <font class="keywordtype">char</font> *s;
01897         <a class="code" href="structDBusString.html">DBusString</a> full_path;
01898         
01899         e-&gt;had_content = TRUE;
01900 
01901         <font class="keywordflow">if</font> (!_dbus_string_init (&amp;full_path))
01902           <font class="keywordflow">goto</font> nomem;
01903         
01904         <font class="keywordflow">if</font> (!make_full_path (&amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m1">basedir</a>, content, &amp;full_path))
01905           {
01906             _dbus_string_free (&amp;full_path);
01907             <font class="keywordflow">goto</font> nomem;
01908           }
01909         
01910         <font class="keywordflow">if</font> (!_dbus_string_copy_data (&amp;full_path, &amp;s))
01911           {
01912             _dbus_string_free (&amp;full_path);
01913             <font class="keywordflow">goto</font> nomem;
01914           }
01915 
01916         <font class="keywordflow">if</font> (!_dbus_list_append (&amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m7">service_dirs</a>, s))
01917           {
01918             _dbus_string_free (&amp;full_path);
01919             dbus_free (s);
01920             <font class="keywordflow">goto</font> nomem;
01921           }
01922 
01923         _dbus_string_free (&amp;full_path);
01924       }
01925       <font class="keywordflow">break</font>;
01926 
01927     <font class="keywordflow">case</font> ELEMENT_LIMIT:
01928       {
01929         <font class="keywordtype">long</font> val;
01930 
01931         e-&gt;had_content = TRUE;
01932 
01933         val = 0;
01934         <font class="keywordflow">if</font> (!_dbus_string_parse_int (content, 0, &amp;val, NULL))
01935           {
01936             dbus_set_error (error, DBUS_ERROR_FAILED,
01937                             <font class="stringliteral">"&lt;limit name=\"%s\"&gt; element has invalid value (could not parse as integer)"</font>,
01938                             e-&gt;d.limit.name);
01939             <font class="keywordflow">return</font> FALSE;
01940           }
01941 
01942         e-&gt;d.limit.value = val;
01943 
01944         _dbus_verbose (<font class="stringliteral">"Loaded value %ld for limit %s\n"</font>,
01945                        e-&gt;d.limit.value,
01946                        e-&gt;d.limit.name);
01947       }
01948       <font class="keywordflow">break</font>;
01949     }
01950 
01951   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01952   <font class="keywordflow">return</font> TRUE;
01953 
01954  nomem:
01955   BUS_SET_OOM (error);
01956   <font class="keywordflow">return</font> FALSE;
01957 }
01958 
01959 dbus_bool_t
01960 bus_config_parser_finished (<a class="code" href="structBusConfigParser.html">BusConfigParser</a>   *parser,
01961                             <a class="code" href="structDBusError.html">DBusError</a>         *error)
01962 {
01963   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01964 
01965   <font class="keywordflow">if</font> (parser-&gt;<a class="code" href="structBusConfigParser.html#m2">stack</a> != NULL)
01966     {
01967       dbus_set_error (error, DBUS_ERROR_FAILED,
01968                       <font class="stringliteral">"Element &lt;%s&gt; was not closed in configuration file"</font>,
01969                       element_type_to_name (top_element_type (parser)));
01970 
01971       <font class="keywordflow">return</font> FALSE;
01972     }
01973 
01974   <font class="keywordflow">if</font> (parser-&gt;<a class="code" href="structBusConfigParser.html#m12">is_toplevel</a> &amp;&amp; parser-&gt;<a class="code" href="structBusConfigParser.html#m5">listen_on</a> == NULL)
01975     {
01976       dbus_set_error (error, DBUS_ERROR_FAILED,
01977                       <font class="stringliteral">"Configuration file needs one or more &lt;listen&gt; elements giving addresses"</font>); 
01978       <font class="keywordflow">return</font> FALSE;
01979     }
01980   
01981   <font class="keywordflow">return</font> TRUE;
01982 }
01983 
01984 <font class="keyword">const</font> <font class="keywordtype">char</font>*
01985 bus_config_parser_get_user (<a class="code" href="structBusConfigParser.html">BusConfigParser</a> *parser)
01986 {
01987   <font class="keywordflow">return</font> parser-&gt;<a class="code" href="structBusConfigParser.html#m3">user</a>;
01988 }
01989 
01990 <font class="keyword">const</font> <font class="keywordtype">char</font>*
01991 bus_config_parser_get_type (<a class="code" href="structBusConfigParser.html">BusConfigParser</a> *parser)
01992 {
01993   <font class="keywordflow">return</font> parser-&gt;<a class="code" href="structBusConfigParser.html#m4">bus_type</a>;
01994 }
01995 
01996 <a class="code" href="structDBusList.html">DBusList</a>**
01997 bus_config_parser_get_addresses (<a class="code" href="structBusConfigParser.html">BusConfigParser</a> *parser)
01998 {
01999   <font class="keywordflow">return</font> &amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m5">listen_on</a>;
02000 }
02001 
02002 <a class="code" href="structDBusList.html">DBusList</a>**
02003 bus_config_parser_get_mechanisms (<a class="code" href="structBusConfigParser.html">BusConfigParser</a> *parser)
02004 {
02005   <font class="keywordflow">return</font> &amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m6">mechanisms</a>;
02006 }
02007 
02008 <a class="code" href="structDBusList.html">DBusList</a>**
02009 bus_config_parser_get_service_dirs (<a class="code" href="structBusConfigParser.html">BusConfigParser</a> *parser)
02010 {
02011   <font class="keywordflow">return</font> &amp;parser-&gt;<a class="code" href="structBusConfigParser.html#m7">service_dirs</a>;
02012 }
02013 
02014 dbus_bool_t
02015 bus_config_parser_get_fork (<a class="code" href="structBusConfigParser.html">BusConfigParser</a>   *parser)
02016 {
02017   <font class="keywordflow">return</font> parser-&gt;<a class="code" href="structBusConfigParser.html#m11">fork</a>;
02018 }
02019 
02020 <font class="keyword">const</font> <font class="keywordtype">char</font> *
02021 bus_config_parser_get_pidfile (<a class="code" href="structBusConfigParser.html">BusConfigParser</a>   *parser)
02022 {
02023   <font class="keywordflow">return</font> parser-&gt;<a class="code" href="structBusConfigParser.html#m10">pidfile</a>;
02024 }
02025 
02026 BusPolicy*
02027 bus_config_parser_steal_policy (<a class="code" href="structBusConfigParser.html">BusConfigParser</a> *parser)
02028 {
02029   BusPolicy *policy;
02030 
02031   _dbus_assert (parser-&gt;<a class="code" href="structBusConfigParser.html#m8">policy</a> != NULL); <font class="comment">/* can only steal the policy 1 time */</font>
02032   
02033   policy = parser-&gt;<a class="code" href="structBusConfigParser.html#m8">policy</a>;
02034 
02035   parser-&gt;<a class="code" href="structBusConfigParser.html#m8">policy</a> = NULL;
02036 
02037   <font class="keywordflow">return</font> policy;
02038 }
02039 
02040 <font class="comment">/* Overwrite any limits that were set in the configuration file */</font>
02041 <font class="keywordtype">void</font>
02042 bus_config_parser_get_limits (<a class="code" href="structBusConfigParser.html">BusConfigParser</a> *parser,
02043                               BusLimits       *limits)
02044 {
02045   *limits = parser-&gt;<a class="code" href="structBusConfigParser.html#m9">limits</a>;
02046 }
02047 
02048 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font>
02049 <font class="preprocessor"></font><font class="preprocessor">#include &lt;stdio.h&gt;</font>
02050 
02051 <font class="keyword">typedef</font> <font class="keyword">enum</font>
02052 {
02053   VALID,
02054   INVALID,
02055   UNKNOWN
02056 } Validity;
02057 
02058 <font class="keyword">static</font> dbus_bool_t
02059 do_load (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *full_path,
02060          Validity          validity,
02061          dbus_bool_t       oom_possible)
02062 {
02063   <a class="code" href="structBusConfigParser.html">BusConfigParser</a> *parser;
02064   <a class="code" href="structDBusError.html">DBusError</a> error;
02065 
02066   dbus_error_init (&amp;error);
02067 
02068   parser = bus_config_load (full_path, TRUE, &amp;error);
02069   <font class="keywordflow">if</font> (parser == NULL)
02070     {
02071       _DBUS_ASSERT_ERROR_IS_SET (&amp;error);
02072 
02073       <font class="keywordflow">if</font> (oom_possible &amp;&amp;
02074           dbus_error_has_name (&amp;error, DBUS_ERROR_NO_MEMORY))
02075         {
02076           _dbus_verbose (<font class="stringliteral">"Failed to load valid file due to OOM\n"</font>);
02077           dbus_error_free (&amp;error);
02078           <font class="keywordflow">return</font> TRUE;
02079         }
02080       <font class="keywordflow">else</font> <font class="keywordflow">if</font> (validity == VALID)
02081         {
02082           _dbus_warn (<font class="stringliteral">"Failed to load valid file but still had memory: %s\n"</font>,
02083                       error.<a class="code" href="structDBusError.html#m1">message</a>);
02084 
02085           dbus_error_free (&amp;error);
02086           <font class="keywordflow">return</font> FALSE;
02087         }
02088       <font class="keywordflow">else</font>
02089         {
02090           dbus_error_free (&amp;error);
02091           <font class="keywordflow">return</font> TRUE;
02092         }
02093     }
02094   <font class="keywordflow">else</font>
02095     {
02096       _DBUS_ASSERT_ERROR_IS_CLEAR (&amp;error);
02097 
02098       bus_config_parser_unref (parser);
02099 
02100       <font class="keywordflow">if</font> (validity == INVALID)
02101         {
02102           _dbus_warn (<font class="stringliteral">"Accepted invalid file\n"</font>);
02103           <font class="keywordflow">return</font> FALSE;
02104         }
02105 
02106       <font class="keywordflow">return</font> TRUE;
02107     }
02108 }
02109 
02110 <font class="keyword">typedef</font> <font class="keyword">struct</font>
02111 <font class="keyword"></font>{
02112   <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *full_path;
02113   Validity          validity;
02114 } LoaderOomData;
02115 
02116 <font class="keyword">static</font> dbus_bool_t
02117 check_loader_oom_func (<font class="keywordtype">void</font> *data)
02118 {
02119   LoaderOomData *d = data;
02120 
02121   <font class="keywordflow">return</font> do_load (d-&gt;full_path, d-&gt;validity, TRUE);
02122 }
02123 
02124 <font class="keyword">static</font> dbus_bool_t
02125 process_test_subdir (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *test_base_dir,
02126                      <font class="keyword">const</font> <font class="keywordtype">char</font>       *subdir,
02127                      Validity          validity)
02128 {
02129   <a class="code" href="structDBusString.html">DBusString</a> test_directory;
02130   <a class="code" href="structDBusString.html">DBusString</a> filename;
02131   <a class="code" href="structDBusDirIter.html">DBusDirIter</a> *dir;
02132   dbus_bool_t retval;
02133   <a class="code" href="structDBusError.html">DBusError</a> error;
02134 
02135   retval = FALSE;
02136   dir = NULL;
02137 
02138   <font class="keywordflow">if</font> (!_dbus_string_init (&amp;test_directory))
02139     _dbus_assert_not_reached (<font class="stringliteral">"didn't allocate test_directory\n"</font>);
02140 
02141   _dbus_string_init_const (&amp;filename, subdir);
02142 
02143   <font class="keywordflow">if</font> (!_dbus_string_copy (test_base_dir, 0,
02144                           &amp;test_directory, 0))
02145     _dbus_assert_not_reached (<font class="stringliteral">"couldn't copy test_base_dir to test_directory"</font>);
02146 
02147   <font class="keywordflow">if</font> (!_dbus_concat_dir_and_file (&amp;test_directory, &amp;filename))
02148     _dbus_assert_not_reached (<font class="stringliteral">"couldn't allocate full path"</font>);
02149 
02150   _dbus_string_free (&amp;filename);
02151   <font class="keywordflow">if</font> (!_dbus_string_init (&amp;filename))
02152     _dbus_assert_not_reached (<font class="stringliteral">"didn't allocate filename string\n"</font>);
02153 
02154   dbus_error_init (&amp;error);
02155   dir = _dbus_directory_open (&amp;test_directory, &amp;error);
02156   <font class="keywordflow">if</font> (dir == NULL)
02157     {
02158       _dbus_warn (<font class="stringliteral">"Could not open %s: %s\n"</font>,
02159                   _dbus_string_get_const_data (&amp;test_directory),
02160                   error.<a class="code" href="structDBusError.html#m1">message</a>);
02161       dbus_error_free (&amp;error);
02162       <font class="keywordflow">goto</font> failed;
02163     }
02164 
02165   printf (<font class="stringliteral">"Testing:\n"</font>);
02166 
02167  next:
02168   <font class="keywordflow">while</font> (_dbus_directory_get_next_file (dir, &amp;filename, &amp;error))
02169     {
02170       <a class="code" href="structDBusString.html">DBusString</a> full_path;
02171       LoaderOomData d;
02172 
02173       <font class="keywordflow">if</font> (!_dbus_string_init (&amp;full_path))
02174         _dbus_assert_not_reached (<font class="stringliteral">"couldn't init string"</font>);
02175 
02176       <font class="keywordflow">if</font> (!_dbus_string_copy (&amp;test_directory, 0, &amp;full_path, 0))
02177         _dbus_assert_not_reached (<font class="stringliteral">"couldn't copy dir to full_path"</font>);
02178 
02179       <font class="keywordflow">if</font> (!_dbus_concat_dir_and_file (&amp;full_path, &amp;filename))
02180         _dbus_assert_not_reached (<font class="stringliteral">"couldn't concat file to dir"</font>);
02181 
02182       <font class="keywordflow">if</font> (!_dbus_string_ends_with_c_str (&amp;full_path, <font class="stringliteral">".conf"</font>))
02183         {
02184           _dbus_verbose (<font class="stringliteral">"Skipping non-.conf file %s\n"</font>,
02185                          _dbus_string_get_const_data (&amp;filename));
02186           _dbus_string_free (&amp;full_path);
02187           <font class="keywordflow">goto</font> next;
02188         }
02189 
02190       printf (<font class="stringliteral">"    %s\n"</font>, _dbus_string_get_const_data (&amp;filename));
02191 
02192       _dbus_verbose (<font class="stringliteral">" expecting %s\n"</font>,
02193                      validity == VALID ? <font class="stringliteral">"valid"</font> :
02194                      (validity == INVALID ? <font class="stringliteral">"invalid"</font> :
02195                       (validity == UNKNOWN ? <font class="stringliteral">"unknown"</font> : <font class="stringliteral">"???"</font>)));
02196 
02197       d.full_path = &amp;full_path;
02198       d.validity = validity;
02199       <font class="keywordflow">if</font> (!_dbus_test_oom_handling (<font class="stringliteral">"config-loader"</font>, check_loader_oom_func, &amp;d))
02200         _dbus_assert_not_reached (<font class="stringliteral">"test failed"</font>);
02201 
02202       _dbus_string_free (&amp;full_path);
02203     }
02204 
02205   <font class="keywordflow">if</font> (dbus_error_is_set (&amp;error))
02206     {
02207       _dbus_warn (<font class="stringliteral">"Could not get next file in %s: %s\n"</font>,
02208                   _dbus_string_get_const_data (&amp;test_directory),
02209                   error.<a class="code" href="structDBusError.html#m1">message</a>);
02210       dbus_error_free (&amp;error);
02211       <font class="keywordflow">goto</font> failed;
02212     }
02213 
02214   retval = TRUE;
02215 
02216  failed:
02217 
02218   <font class="keywordflow">if</font> (dir)
02219     _dbus_directory_close (dir);
02220   _dbus_string_free (&amp;test_directory);
02221   _dbus_string_free (&amp;filename);
02222 
02223   <font class="keywordflow">return</font> retval;
02224 }
02225 
02226 dbus_bool_t
02227 bus_config_parser_test (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *test_data_dir)
02228 {
02229   <font class="keywordflow">if</font> (test_data_dir == NULL ||
02230       _dbus_string_get_length (test_data_dir) == 0)
02231     {
02232       printf (<font class="stringliteral">"No test data\n"</font>);
02233       <font class="keywordflow">return</font> TRUE;
02234     }
02235 
02236   <font class="keywordflow">if</font> (!process_test_subdir (test_data_dir, <font class="stringliteral">"valid-config-files"</font>, VALID))
02237     <font class="keywordflow">return</font> FALSE;
02238 
02239   <font class="keywordflow">return</font> TRUE;
02240 }
02241 
02242 <font class="preprocessor">#endif </font><font class="comment">/* DBUS_BUILD_TESTS */</font>
02243 
</pre></div><hr><address align="right"><small>Generated on Mon Sep 29 21:30:59 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>