Sophie

Sophie

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

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>bus.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>bus.c</h1><div class="fragment"><pre>00001 <font class="comment">/* -*- mode: C; c-file-style: "gnu" -*- */</font>
00002 <font class="comment">/* bus.c  message bus context object</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 
00024 <font class="preprocessor">#include "bus.h"</font>
00025 <font class="preprocessor">#include "activation.h"</font>
00026 <font class="preprocessor">#include "connection.h"</font>
00027 <font class="preprocessor">#include "services.h"</font>
00028 <font class="preprocessor">#include "utils.h"</font>
00029 <font class="preprocessor">#include "policy.h"</font>
00030 <font class="preprocessor">#include "config-parser.h"</font>
00031 <font class="preprocessor">#include "signals.h"</font>
00032 <font class="preprocessor">#include &lt;dbus/dbus-list.h&gt;</font>
00033 <font class="preprocessor">#include &lt;dbus/dbus-hash.h&gt;</font>
00034 <font class="preprocessor">#include &lt;dbus/dbus-internals.h&gt;</font>
00035 
00036 <font class="keyword">struct </font>BusContext
00037 {
00038   <font class="keywordtype">int</font> refcount;
00039   <font class="keywordtype">char</font> *type;
00040   <font class="keywordtype">char</font> *address;
00041   <font class="keywordtype">char</font> *pidfile;
00042   DBusLoop *loop;
00043   <a class="code" href="structDBusList.html">DBusList</a> *servers;
00044   BusConnections *connections;
00045   BusActivation *activation;
00046   BusRegistry *registry;
00047   BusPolicy *policy;
00048   BusMatchmaker *matchmaker;
00049   <a class="code" href="structDBusUserDatabase.html">DBusUserDatabase</a> *user_database;
00050   BusLimits limits;
00051 };
00052 
00053 <font class="keyword">static</font> dbus_int32_t server_data_slot = -1;
00054 
00055 <font class="keyword">typedef</font> <font class="keyword">struct</font>
00056 <font class="keyword"></font>{
00057   BusContext *context;
00058 } BusServerData;
00059 
00060 <font class="preprocessor">#define BUS_SERVER_DATA(server) (dbus_server_get_data ((server), server_data_slot))</font>
00061 <font class="preprocessor"></font>
00062 <font class="keyword">static</font> BusContext*
00063 server_get_context (<a class="code" href="structDBusServer.html">DBusServer</a> *server)
00064 {
00065   BusContext *context;
00066   BusServerData *bd;
00067   
00068   <font class="keywordflow">if</font> (!dbus_server_allocate_data_slot (&amp;server_data_slot))
00069     <font class="keywordflow">return</font> NULL;
00070 
00071   bd = BUS_SERVER_DATA (server);
00072   <font class="keywordflow">if</font> (bd == NULL)
00073     {
00074       dbus_server_free_data_slot (&amp;server_data_slot);
00075       <font class="keywordflow">return</font> NULL;
00076     }
00077 
00078   context = bd-&gt;context;
00079 
00080   dbus_server_free_data_slot (&amp;server_data_slot);
00081 
00082   <font class="keywordflow">return</font> context;
00083 }
00084 
00085 <font class="keyword">static</font> dbus_bool_t
00086 server_watch_callback (<a class="code" href="structDBusWatch.html">DBusWatch</a>     *watch,
00087                        <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font>   condition,
00088                        <font class="keywordtype">void</font>          *data)
00089 {
00090   <font class="comment">/* FIXME this can be done in dbus-mainloop.c</font>
00091 <font class="comment">   * if the code in activation.c for the babysitter</font>
00092 <font class="comment">   * watch handler is fixed.</font>
00093 <font class="comment">   */</font>
00094   
00095   <font class="keywordflow">return</font> dbus_watch_handle (watch, condition);
00096 }
00097 
00098 <font class="keyword">static</font> dbus_bool_t
00099 add_server_watch (<a class="code" href="structDBusWatch.html">DBusWatch</a>  *watch,
00100                   <font class="keywordtype">void</font>       *data)
00101 {
00102   <a class="code" href="structDBusServer.html">DBusServer</a> *server = data;
00103   BusContext *context;
00104   
00105   context = server_get_context (server);
00106   
00107   <font class="keywordflow">return</font> _dbus_loop_add_watch (context-&gt;loop,
00108                                watch, server_watch_callback, server,
00109                                NULL);
00110 }
00111 
00112 <font class="keyword">static</font> <font class="keywordtype">void</font>
00113 remove_server_watch (<a class="code" href="structDBusWatch.html">DBusWatch</a>  *watch,
00114                      <font class="keywordtype">void</font>       *data)
00115 {
00116   <a class="code" href="structDBusServer.html">DBusServer</a> *server = data;
00117   BusContext *context;
00118   
00119   context = server_get_context (server);
00120   
00121   _dbus_loop_remove_watch (context-&gt;loop,
00122                            watch, server_watch_callback, server);
00123 }
00124 
00125 
00126 <font class="keyword">static</font> <font class="keywordtype">void</font>
00127 server_timeout_callback (<a class="code" href="structDBusTimeout.html">DBusTimeout</a>   *timeout,
00128                          <font class="keywordtype">void</font>          *data)
00129 {
00130   <font class="comment">/* can return FALSE on OOM but we just let it fire again later */</font>
00131   dbus_timeout_handle (timeout);
00132 }
00133 
00134 <font class="keyword">static</font> dbus_bool_t
00135 add_server_timeout (<a class="code" href="structDBusTimeout.html">DBusTimeout</a> *timeout,
00136                     <font class="keywordtype">void</font>        *data)
00137 {
00138   <a class="code" href="structDBusServer.html">DBusServer</a> *server = data;
00139   BusContext *context;
00140   
00141   context = server_get_context (server);
00142 
00143   <font class="keywordflow">return</font> _dbus_loop_add_timeout (context-&gt;loop,
00144                                  timeout, server_timeout_callback, server, NULL);
00145 }
00146 
00147 <font class="keyword">static</font> <font class="keywordtype">void</font>
00148 remove_server_timeout (<a class="code" href="structDBusTimeout.html">DBusTimeout</a> *timeout,
00149                        <font class="keywordtype">void</font>        *data)
00150 {
00151   <a class="code" href="structDBusServer.html">DBusServer</a> *server = data;
00152   BusContext *context;
00153   
00154   context = server_get_context (server);
00155   
00156   _dbus_loop_remove_timeout (context-&gt;loop,
00157                              timeout, server_timeout_callback, server);
00158 }
00159 
00160 <font class="keyword">static</font> <font class="keywordtype">void</font>
00161 new_connection_callback (<a class="code" href="structDBusServer.html">DBusServer</a>     *server,
00162                          <a class="code" href="structDBusConnection.html">DBusConnection</a> *new_connection,
00163                          <font class="keywordtype">void</font>           *data)
00164 {
00165   BusContext *context = data;
00166   
00167   <font class="keywordflow">if</font> (!bus_connections_setup_connection (context-&gt;connections, new_connection))
00168     {
00169       _dbus_verbose (<font class="stringliteral">"No memory to setup new connection\n"</font>);
00170 
00171       <font class="comment">/* if we don't do this, it will get unref'd without</font>
00172 <font class="comment">       * being disconnected... kind of strange really</font>
00173 <font class="comment">       * that we have to do this, people won't get it right</font>
00174 <font class="comment">       * in general.</font>
00175 <font class="comment">       */</font>
00176       dbus_connection_disconnect (new_connection);
00177     }
00178 
00179   dbus_connection_set_max_received_size (new_connection,
00180                                          context-&gt;limits.max_incoming_bytes);
00181 
00182   dbus_connection_set_max_message_size (new_connection,
00183                                         context-&gt;limits.max_message_size);
00184   
00185   <font class="comment">/* on OOM, we won't have ref'd the connection so it will die. */</font>
00186 }
00187 
00188 <font class="keyword">static</font> <font class="keywordtype">void</font>
00189 free_server_data (<font class="keywordtype">void</font> *data)
00190 {
00191   BusServerData *bd = data;  
00192   
00193   dbus_free (bd);
00194 }
00195 
00196 <font class="keyword">static</font> dbus_bool_t
00197 setup_server (BusContext *context,
00198               <a class="code" href="structDBusServer.html">DBusServer</a> *server,
00199               <font class="keywordtype">char</font>      **auth_mechanisms,
00200               <a class="code" href="structDBusError.html">DBusError</a>  *error)
00201 {
00202   BusServerData *bd;
00203 
00204   bd = dbus_new0 (BusServerData, 1);
00205   <font class="keywordflow">if</font> (!dbus_server_set_data (server,
00206                              server_data_slot,
00207                              bd, free_server_data))
00208     {
00209       dbus_free (bd);
00210       BUS_SET_OOM (error);
00211       <font class="keywordflow">return</font> FALSE;
00212     }
00213 
00214   bd-&gt;context = context;
00215   
00216   <font class="keywordflow">if</font> (!dbus_server_set_auth_mechanisms (server, (<font class="keyword">const</font> <font class="keywordtype">char</font>**) auth_mechanisms))
00217     {
00218       BUS_SET_OOM (error);
00219       <font class="keywordflow">return</font> FALSE;
00220     }
00221   
00222   dbus_server_set_new_connection_function (server,
00223                                            new_connection_callback,
00224                                            context, NULL);
00225   
00226   <font class="keywordflow">if</font> (!dbus_server_set_watch_functions (server,
00227                                         add_server_watch,
00228                                         remove_server_watch,
00229                                         NULL,
00230                                         server,
00231                                         NULL))
00232     {
00233       BUS_SET_OOM (error);
00234       <font class="keywordflow">return</font> FALSE;
00235     }
00236 
00237   <font class="keywordflow">if</font> (!dbus_server_set_timeout_functions (server,
00238                                           add_server_timeout,
00239                                           remove_server_timeout,
00240                                           NULL,
00241                                           server, NULL))
00242     {
00243       BUS_SET_OOM (error);
00244       <font class="keywordflow">return</font> FALSE;
00245     }
00246   
00247   <font class="keywordflow">return</font> TRUE;
00248 }
00249 
00250 BusContext*
00251 bus_context_new (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *config_file,
00252                  dbus_bool_t       force_fork,
00253                  <font class="keywordtype">int</font>               print_addr_fd,
00254                  <font class="keywordtype">int</font>               print_pid_fd,
00255                  <a class="code" href="structDBusError.html">DBusError</a>        *error)
00256 {
00257   BusContext *context;
00258   <a class="code" href="structDBusList.html">DBusList</a> *link;
00259   <a class="code" href="structDBusList.html">DBusList</a> **addresses;
00260   <a class="code" href="structBusConfigParser.html">BusConfigParser</a> *parser;
00261   <a class="code" href="structDBusString.html">DBusString</a> full_address;
00262   <font class="keyword">const</font> <font class="keywordtype">char</font> *user, *pidfile;
00263   <font class="keywordtype">char</font> **auth_mechanisms;
00264   <a class="code" href="structDBusList.html">DBusList</a> **auth_mechanisms_list;
00265   <font class="keywordtype">int</font> len;
00266   
00267   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00268 
00269   <font class="keywordflow">if</font> (!_dbus_string_init (&amp;full_address))
00270     {
00271       BUS_SET_OOM (error);
00272       <font class="keywordflow">return</font> NULL;
00273     }
00274 
00275   <font class="keywordflow">if</font> (!dbus_server_allocate_data_slot (&amp;server_data_slot))
00276     {
00277       BUS_SET_OOM (error);
00278       _dbus_string_free (&amp;full_address);
00279       <font class="keywordflow">return</font> NULL;
00280     }
00281   
00282   parser = NULL;
00283   context = NULL;
00284   auth_mechanisms = NULL;
00285   
00286   parser = bus_config_load (config_file, TRUE, error);
00287   <font class="keywordflow">if</font> (parser == NULL)
00288     <font class="keywordflow">goto</font> failed;
00289 
00290   <font class="comment">/* Check for an existing pid file. Of course this is a race;</font>
00291 <font class="comment">   * we'd have to use fcntl() locks on the pid file to</font>
00292 <font class="comment">   * avoid that. But we want to check for the pid file</font>
00293 <font class="comment">   * before overwriting any existing sockets, etc.</font>
00294 <font class="comment">   */</font>
00295   pidfile = bus_config_parser_get_pidfile (parser);
00296   <font class="keywordflow">if</font> (pidfile != NULL)
00297     {
00298       <a class="code" href="structDBusString.html">DBusString</a> u;
00299       <a class="code" href="structDBusStat.html">DBusStat</a> stbuf;
00300       <a class="code" href="structDBusError.html">DBusError</a> tmp_error;
00301       
00302       dbus_error_init (&amp;tmp_error);
00303       _dbus_string_init_const (&amp;u, pidfile);
00304       
00305       <font class="keywordflow">if</font> (_dbus_stat (&amp;u, &amp;stbuf, &amp;tmp_error))
00306         {
00307           dbus_set_error (error, DBUS_ERROR_FAILED,
00308                           <font class="stringliteral">"The pid file \"%s\" exists, if the message bus is not running, remove this file"</font>,
00309                           pidfile);
00310           dbus_error_free (&amp;tmp_error);
00311           <font class="keywordflow">goto</font> failed;
00312         }
00313     }
00314   
00315   context = dbus_new0 (BusContext, 1);
00316   <font class="keywordflow">if</font> (context == NULL)
00317     {
00318       BUS_SET_OOM (error);
00319       <font class="keywordflow">goto</font> failed;
00320     }
00321   
00322   context-&gt;refcount = 1;
00323 
00324   <font class="comment">/* get our limits and timeout lengths */</font>
00325   bus_config_parser_get_limits (parser, &amp;context-&gt;limits);
00326   
00327   <font class="comment">/* we need another ref of the server data slot for the context</font>
00328 <font class="comment">   * to own</font>
00329 <font class="comment">   */</font>
00330   <font class="keywordflow">if</font> (!dbus_server_allocate_data_slot (&amp;server_data_slot))
00331     _dbus_assert_not_reached (<font class="stringliteral">"second ref of server data slot failed"</font>);
00332   
00333   context-&gt;user_database = _dbus_user_database_new ();
00334   <font class="keywordflow">if</font> (context-&gt;user_database == NULL)
00335     {
00336       BUS_SET_OOM (error);
00337       <font class="keywordflow">goto</font> failed;
00338     }
00339   
00340   context-&gt;loop = _dbus_loop_new ();
00341   <font class="keywordflow">if</font> (context-&gt;loop == NULL)
00342     {
00343       BUS_SET_OOM (error);
00344       <font class="keywordflow">goto</font> failed;
00345     }
00346   
00347   <font class="comment">/* Build an array of auth mechanisms */</font>
00348   
00349   auth_mechanisms_list = bus_config_parser_get_mechanisms (parser);
00350   len = _dbus_list_get_length (auth_mechanisms_list);
00351 
00352   <font class="keywordflow">if</font> (len &gt; 0)
00353     {
00354       <font class="keywordtype">int</font> i;
00355 
00356       auth_mechanisms = dbus_new0 (<font class="keywordtype">char</font>*, len + 1);
00357       <font class="keywordflow">if</font> (auth_mechanisms == NULL)
00358         <font class="keywordflow">goto</font> failed;
00359       
00360       i = 0;
00361       link = _dbus_list_get_first_link (auth_mechanisms_list);
00362       <font class="keywordflow">while</font> (link != NULL)
00363         {
00364           auth_mechanisms[i] = _dbus_strdup (link-&gt;<a class="code" href="structDBusList.html#m2">data</a>);
00365           <font class="keywordflow">if</font> (auth_mechanisms[i] == NULL)
00366             <font class="keywordflow">goto</font> failed;
00367           link = _dbus_list_get_next_link (auth_mechanisms_list, link);
00368         }
00369     }
00370   <font class="keywordflow">else</font>
00371     {
00372       auth_mechanisms = NULL;
00373     }
00374 
00375   <font class="comment">/* Listen on our addresses */</font>
00376   
00377   addresses = bus_config_parser_get_addresses (parser);  
00378   
00379   link = _dbus_list_get_first_link (addresses);
00380   <font class="keywordflow">while</font> (link != NULL)
00381     {
00382       <a class="code" href="structDBusServer.html">DBusServer</a> *server;
00383       
00384       server = dbus_server_listen (link-&gt;<a class="code" href="structDBusList.html#m2">data</a>, error);
00385       <font class="keywordflow">if</font> (server == NULL)
00386         <font class="keywordflow">goto</font> failed;
00387       <font class="keywordflow">else</font> <font class="keywordflow">if</font> (!setup_server (context, server, auth_mechanisms, error))
00388         <font class="keywordflow">goto</font> failed;
00389 
00390       <font class="keywordflow">if</font> (!_dbus_list_append (&amp;context-&gt;servers, server))
00391         {
00392           BUS_SET_OOM (error);
00393           <font class="keywordflow">goto</font> failed;
00394         }          
00395       
00396       link = _dbus_list_get_next_link (addresses, link);
00397     }
00398 
00399   <font class="comment">/* note that type may be NULL */</font>
00400   context-&gt;type = _dbus_strdup (bus_config_parser_get_type (parser));
00401   
00402   <font class="comment">/* We have to build the address backward, so that</font>
00403 <font class="comment">   * &lt;listen&gt; later in the config file have priority</font>
00404 <font class="comment">   */</font>
00405   link = _dbus_list_get_last_link (&amp;context-&gt;servers);
00406   <font class="keywordflow">while</font> (link != NULL)
00407     {
00408       <font class="keywordtype">char</font> *addr;
00409       
00410       addr = dbus_server_get_address (link-&gt;<a class="code" href="structDBusList.html#m2">data</a>);
00411       <font class="keywordflow">if</font> (addr == NULL)
00412         {
00413           BUS_SET_OOM (error);
00414           <font class="keywordflow">goto</font> failed;
00415         }
00416 
00417       <font class="keywordflow">if</font> (_dbus_string_get_length (&amp;full_address) &gt; 0)
00418         {
00419           <font class="keywordflow">if</font> (!_dbus_string_append (&amp;full_address, <font class="stringliteral">";"</font>))
00420             {
00421               BUS_SET_OOM (error);
00422               <font class="keywordflow">goto</font> failed;
00423             }
00424         }
00425 
00426       <font class="keywordflow">if</font> (!_dbus_string_append (&amp;full_address, addr))
00427         {
00428           BUS_SET_OOM (error);
00429           <font class="keywordflow">goto</font> failed;
00430         }
00431 
00432       dbus_free (addr);
00433 
00434       link = _dbus_list_get_prev_link (&amp;context-&gt;servers, link);
00435     }
00436 
00437   <font class="keywordflow">if</font> (!_dbus_string_copy_data (&amp;full_address, &amp;context-&gt;address))
00438     {
00439       BUS_SET_OOM (error);
00440       <font class="keywordflow">goto</font> failed;
00441     }
00442 
00443   <font class="comment">/* Note that we don't know whether the print_addr_fd is</font>
00444 <font class="comment">   * one of the sockets we're using to listen on, or some</font>
00445 <font class="comment">   * other random thing. But I think the answer is "don't do</font>
00446 <font class="comment">   * that then"</font>
00447 <font class="comment">   */</font>
00448   <font class="keywordflow">if</font> (print_addr_fd &gt;= 0)
00449     {
00450       <a class="code" href="structDBusString.html">DBusString</a> addr;
00451       <font class="keyword">const</font> <font class="keywordtype">char</font> *a = bus_context_get_address (context);
00452       <font class="keywordtype">int</font> bytes;
00453       
00454       _dbus_assert (a != NULL);
00455       <font class="keywordflow">if</font> (!_dbus_string_init (&amp;addr))
00456         {
00457           BUS_SET_OOM (error);
00458           <font class="keywordflow">goto</font> failed;
00459         }
00460       
00461       <font class="keywordflow">if</font> (!_dbus_string_append (&amp;addr, a) ||
00462           !_dbus_string_append (&amp;addr, <font class="stringliteral">"\n"</font>))
00463         {
00464           _dbus_string_free (&amp;addr);
00465           BUS_SET_OOM (error);
00466           <font class="keywordflow">goto</font> failed;
00467         }
00468 
00469       bytes = _dbus_string_get_length (&amp;addr);
00470       <font class="keywordflow">if</font> (_dbus_write (print_addr_fd, &amp;addr, 0, bytes) != bytes)
00471         {
00472           dbus_set_error (error, DBUS_ERROR_FAILED,
00473                           <font class="stringliteral">"Printing message bus address: %s\n"</font>,
00474                           _dbus_strerror (errno));
00475           _dbus_string_free (&amp;addr);
00476           <font class="keywordflow">goto</font> failed;
00477         }
00478 
00479       <font class="keywordflow">if</font> (print_addr_fd &gt; 2)
00480         _dbus_close (print_addr_fd, NULL);
00481 
00482       _dbus_string_free (&amp;addr);
00483     }
00484   
00485   <font class="comment">/* Create activation subsystem */</font>
00486   
00487   context-&gt;activation = bus_activation_new (context, &amp;full_address,
00488                                             bus_config_parser_get_service_dirs (parser),
00489                                             error);
00490   <font class="keywordflow">if</font> (context-&gt;activation == NULL)
00491     {
00492       _DBUS_ASSERT_ERROR_IS_SET (error);
00493       <font class="keywordflow">goto</font> failed;
00494     }
00495 
00496   context-&gt;connections = bus_connections_new (context);
00497   <font class="keywordflow">if</font> (context-&gt;connections == NULL)
00498     {
00499       BUS_SET_OOM (error);
00500       <font class="keywordflow">goto</font> failed;
00501     }
00502 
00503   context-&gt;registry = bus_registry_new (context);
00504   <font class="keywordflow">if</font> (context-&gt;registry == NULL)
00505     {
00506       BUS_SET_OOM (error);
00507       <font class="keywordflow">goto</font> failed;
00508     }
00509 
00510   context-&gt;matchmaker = bus_matchmaker_new ();
00511   <font class="keywordflow">if</font> (context-&gt;matchmaker == NULL)
00512     {
00513       BUS_SET_OOM (error);
00514       <font class="keywordflow">goto</font> failed;
00515     }
00516   
00517   context-&gt;policy = bus_config_parser_steal_policy (parser);
00518   _dbus_assert (context-&gt;policy != NULL);
00519   
00520   <font class="comment">/* Now become a daemon if appropriate */</font>
00521   <font class="keywordflow">if</font> (force_fork || bus_config_parser_get_fork (parser))
00522     {
00523       <a class="code" href="structDBusString.html">DBusString</a> u;
00524 
00525       <font class="keywordflow">if</font> (pidfile)
00526         _dbus_string_init_const (&amp;u, pidfile);
00527       
00528       <font class="keywordflow">if</font> (!_dbus_become_daemon (pidfile ? &amp;u : NULL, error))
00529         <font class="keywordflow">goto</font> failed;
00530     }
00531   <font class="keywordflow">else</font>
00532     {
00533       <font class="comment">/* Need to write PID file for ourselves, not for the child process */</font>
00534       <font class="keywordflow">if</font> (pidfile != NULL)
00535         {
00536           <a class="code" href="structDBusString.html">DBusString</a> u;
00537 
00538           _dbus_string_init_const (&amp;u, pidfile);
00539           
00540           <font class="keywordflow">if</font> (!_dbus_write_pid_file (&amp;u, _dbus_getpid (), error))
00541             <font class="keywordflow">goto</font> failed;
00542         }
00543     }
00544 
00545   <font class="comment">/* keep around the pid filename so we can delete it later */</font>
00546   context-&gt;pidfile = _dbus_strdup (pidfile);
00547 
00548   <font class="comment">/* Write PID if requested */</font>
00549   <font class="keywordflow">if</font> (print_pid_fd &gt;= 0)
00550     {
00551       <a class="code" href="structDBusString.html">DBusString</a> pid;
00552       <font class="keywordtype">int</font> bytes;
00553 
00554       <font class="keywordflow">if</font> (!_dbus_string_init (&amp;pid))
00555         {
00556           BUS_SET_OOM (error);
00557           <font class="keywordflow">goto</font> failed;
00558         }
00559       
00560       <font class="keywordflow">if</font> (!_dbus_string_append_int (&amp;pid, _dbus_getpid ()) ||
00561           !_dbus_string_append (&amp;pid, <font class="stringliteral">"\n"</font>))
00562         {
00563           _dbus_string_free (&amp;pid);
00564           BUS_SET_OOM (error);
00565           <font class="keywordflow">goto</font> failed;
00566         }
00567 
00568       bytes = _dbus_string_get_length (&amp;pid);
00569       <font class="keywordflow">if</font> (_dbus_write (print_pid_fd, &amp;pid, 0, bytes) != bytes)
00570         {
00571           dbus_set_error (error, DBUS_ERROR_FAILED,
00572                           <font class="stringliteral">"Printing message bus PID: %s\n"</font>,
00573                           _dbus_strerror (errno));
00574           _dbus_string_free (&amp;pid);
00575           <font class="keywordflow">goto</font> failed;
00576         }
00577 
00578       <font class="keywordflow">if</font> (print_pid_fd &gt; 2)
00579         _dbus_close (print_pid_fd, NULL);
00580       
00581       _dbus_string_free (&amp;pid);
00582     }
00583   
00584   <font class="comment">/* Here we change our credentials if required,</font>
00585 <font class="comment">   * as soon as we've set up our sockets and pidfile</font>
00586 <font class="comment">   */</font>
00587   user = bus_config_parser_get_user (parser);
00588   <font class="keywordflow">if</font> (user != NULL)
00589     {
00590       <a class="code" href="structDBusCredentials.html">DBusCredentials</a> creds;
00591       <a class="code" href="structDBusString.html">DBusString</a> u;
00592 
00593       _dbus_string_init_const (&amp;u, user);
00594 
00595       <font class="keywordflow">if</font> (!_dbus_credentials_from_username (&amp;u, &amp;creds) ||
00596           creds.<a class="code" href="structDBusCredentials.html#m1">uid</a> &lt; 0 ||
00597           creds.<a class="code" href="structDBusCredentials.html#m2">gid</a> &lt; 0)
00598         {
00599           dbus_set_error (error, DBUS_ERROR_FAILED,
00600                           <font class="stringliteral">"Could not get UID and GID for username \"%s\""</font>,
00601                           user);
00602           <font class="keywordflow">goto</font> failed;
00603         }
00604       
00605       <font class="keywordflow">if</font> (!_dbus_change_identity (creds.<a class="code" href="structDBusCredentials.html#m1">uid</a>, creds.<a class="code" href="structDBusCredentials.html#m2">gid</a>, error))
00606         <font class="keywordflow">goto</font> failed;
00607     }
00608   
00609   bus_config_parser_unref (parser);
00610   _dbus_string_free (&amp;full_address);
00611   dbus_free_string_array (auth_mechanisms);
00612   dbus_server_free_data_slot (&amp;server_data_slot);
00613   
00614   <font class="keywordflow">return</font> context;
00615   
00616  failed:  
00617   <font class="keywordflow">if</font> (parser != NULL)
00618     bus_config_parser_unref (parser);
00619 
00620   <font class="keywordflow">if</font> (context != NULL)
00621     bus_context_unref (context);
00622 
00623   _dbus_string_free (&amp;full_address);
00624   dbus_free_string_array (auth_mechanisms);
00625 
00626   dbus_server_free_data_slot (&amp;server_data_slot);
00627   
00628   <font class="keywordflow">return</font> NULL;
00629 }
00630 
00631 <font class="keyword">static</font> <font class="keywordtype">void</font>
00632 shutdown_server (BusContext *context,
00633                  <a class="code" href="structDBusServer.html">DBusServer</a> *server)
00634 {
00635   <font class="keywordflow">if</font> (server == NULL ||
00636       !dbus_server_get_is_connected (server))
00637     <font class="keywordflow">return</font>;
00638   
00639   <font class="keywordflow">if</font> (!dbus_server_set_watch_functions (server,
00640                                         NULL, NULL, NULL,
00641                                         context,
00642                                         NULL))
00643     _dbus_assert_not_reached (<font class="stringliteral">"setting watch functions to NULL failed"</font>);
00644   
00645   <font class="keywordflow">if</font> (!dbus_server_set_timeout_functions (server,
00646                                           NULL, NULL, NULL,
00647                                           context,
00648                                           NULL))
00649     _dbus_assert_not_reached (<font class="stringliteral">"setting timeout functions to NULL failed"</font>);
00650   
00651   dbus_server_disconnect (server);
00652 }
00653 
00654 <font class="keywordtype">void</font>
00655 bus_context_shutdown (BusContext  *context)
00656 {
00657   <a class="code" href="structDBusList.html">DBusList</a> *link;
00658 
00659   link = _dbus_list_get_first_link (&amp;context-&gt;servers);
00660   <font class="keywordflow">while</font> (link != NULL)
00661     {
00662       shutdown_server (context, link-&gt;<a class="code" href="structDBusList.html#m2">data</a>);
00663 
00664       link = _dbus_list_get_next_link (&amp;context-&gt;servers, link);
00665     }
00666 }
00667 
00668 <font class="keywordtype">void</font>
00669 bus_context_ref (BusContext *context)
00670 {
00671   _dbus_assert (context-&gt;refcount &gt; 0);
00672   context-&gt;refcount += 1;
00673 }
00674 
00675 <font class="keywordtype">void</font>
00676 bus_context_unref (BusContext *context)
00677 {
00678   _dbus_assert (context-&gt;refcount &gt; 0);
00679   context-&gt;refcount -= 1;
00680 
00681   <font class="keywordflow">if</font> (context-&gt;refcount == 0)
00682     {
00683       <a class="code" href="structDBusList.html">DBusList</a> *link;
00684       
00685       _dbus_verbose (<font class="stringliteral">"Finalizing bus context %p\n"</font>, context);
00686       
00687       bus_context_shutdown (context);
00688 
00689       <font class="keywordflow">if</font> (context-&gt;connections)
00690         {
00691           bus_connections_unref (context-&gt;connections);
00692           context-&gt;connections = NULL;
00693         }
00694       
00695       <font class="keywordflow">if</font> (context-&gt;registry)
00696         {
00697           bus_registry_unref (context-&gt;registry);
00698           context-&gt;registry = NULL;
00699         }
00700       
00701       <font class="keywordflow">if</font> (context-&gt;activation)
00702         {
00703           bus_activation_unref (context-&gt;activation);
00704           context-&gt;activation = NULL;
00705         }
00706 
00707       link = _dbus_list_get_first_link (&amp;context-&gt;servers);
00708       <font class="keywordflow">while</font> (link != NULL)
00709         {
00710           dbus_server_unref (link-&gt;<a class="code" href="structDBusList.html#m2">data</a>);
00711           
00712           link = _dbus_list_get_next_link (&amp;context-&gt;servers, link);
00713         }
00714       _dbus_list_clear (&amp;context-&gt;servers);
00715 
00716       <font class="keywordflow">if</font> (context-&gt;policy)
00717         {
00718           bus_policy_unref (context-&gt;policy);
00719           context-&gt;policy = NULL;
00720         }
00721       
00722       <font class="keywordflow">if</font> (context-&gt;loop)
00723         {
00724           _dbus_loop_unref (context-&gt;loop);
00725           context-&gt;loop = NULL;
00726         }
00727 
00728       <font class="keywordflow">if</font> (context-&gt;matchmaker)
00729         {
00730           bus_matchmaker_unref (context-&gt;matchmaker);
00731           context-&gt;matchmaker = NULL;
00732         }
00733       
00734       dbus_free (context-&gt;type);
00735       dbus_free (context-&gt;address);
00736 
00737       <font class="keywordflow">if</font> (context-&gt;pidfile)
00738         {
00739           <a class="code" href="structDBusString.html">DBusString</a> u;
00740           _dbus_string_init_const (&amp;u, context-&gt;pidfile);
00741 
00742           <font class="comment">/* Deliberately ignore errors here, since there's not much</font>
00743 <font class="comment">           * we can do about it, and we're exiting anyways.</font>
00744 <font class="comment">           */</font>
00745           _dbus_delete_file (&amp;u, NULL);
00746 
00747           dbus_free (context-&gt;pidfile); 
00748         }
00749 
00750       _dbus_user_database_unref (context-&gt;user_database);
00751       
00752       dbus_free (context);
00753 
00754       dbus_server_free_data_slot (&amp;server_data_slot);
00755     }
00756 }
00757 
00758 <font class="comment">/* type may be NULL */</font>
00759 <font class="keyword">const</font> <font class="keywordtype">char</font>*
00760 bus_context_get_type (BusContext *context)
00761 {
00762   <font class="keywordflow">return</font> context-&gt;type;
00763 }
00764 
00765 <font class="keyword">const</font> <font class="keywordtype">char</font>*
00766 bus_context_get_address (BusContext *context)
00767 {
00768   <font class="keywordflow">return</font> context-&gt;address;
00769 }
00770 
00771 BusRegistry*
00772 bus_context_get_registry (BusContext  *context)
00773 {
00774   <font class="keywordflow">return</font> context-&gt;registry;
00775 }
00776 
00777 BusConnections*
00778 bus_context_get_connections (BusContext  *context)
00779 {
00780   <font class="keywordflow">return</font> context-&gt;connections;
00781 }
00782 
00783 BusActivation*
00784 bus_context_get_activation (BusContext  *context)
00785 {
00786   <font class="keywordflow">return</font> context-&gt;activation;
00787 }
00788 
00789 BusMatchmaker*
00790 bus_context_get_matchmaker (BusContext  *context)
00791 {
00792   <font class="keywordflow">return</font> context-&gt;matchmaker;
00793 }
00794 
00795 DBusLoop*
00796 bus_context_get_loop (BusContext *context)
00797 {
00798   <font class="keywordflow">return</font> context-&gt;loop;
00799 }
00800 
00801 <a class="code" href="structDBusUserDatabase.html">DBusUserDatabase</a>*
00802 bus_context_get_user_database (BusContext *context)
00803 {
00804   <font class="keywordflow">return</font> context-&gt;user_database;
00805 }
00806 
00807 dbus_bool_t
00808 bus_context_allow_user (BusContext   *context,
00809                         <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> uid)
00810 {
00811   <font class="keywordflow">return</font> bus_policy_allow_user (context-&gt;policy,
00812                                 context-&gt;user_database,
00813                                 uid);
00814 }
00815 
00816 BusClientPolicy*
00817 bus_context_create_client_policy (BusContext      *context,
00818                                   <a class="code" href="structDBusConnection.html">DBusConnection</a>  *connection,
00819                                   <a class="code" href="structDBusError.html">DBusError</a>       *error)
00820 {
00821   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00822   <font class="keywordflow">return</font> bus_policy_create_client_policy (context-&gt;policy, connection,
00823                                           error);
00824 }
00825 
00826 <font class="keywordtype">int</font>
00827 bus_context_get_activation_timeout (BusContext *context)
00828 {
00829   
00830   <font class="keywordflow">return</font> context-&gt;limits.activation_timeout;
00831 }
00832 
00833 <font class="keywordtype">int</font>
00834 bus_context_get_auth_timeout (BusContext *context)
00835 {
00836   <font class="keywordflow">return</font> context-&gt;limits.auth_timeout;
00837 }
00838 
00839 <font class="keywordtype">int</font>
00840 bus_context_get_max_completed_connections (BusContext *context)
00841 {
00842   <font class="keywordflow">return</font> context-&gt;limits.max_completed_connections;
00843 }
00844 
00845 <font class="keywordtype">int</font>
00846 bus_context_get_max_incomplete_connections (BusContext *context)
00847 {
00848   <font class="keywordflow">return</font> context-&gt;limits.max_incomplete_connections;
00849 }
00850 
00851 <font class="keywordtype">int</font>
00852 bus_context_get_max_connections_per_user (BusContext *context)
00853 {
00854   <font class="keywordflow">return</font> context-&gt;limits.max_connections_per_user;
00855 }
00856 
00857 <font class="keywordtype">int</font>
00858 bus_context_get_max_pending_activations (BusContext *context)
00859 {
00860   <font class="keywordflow">return</font> context-&gt;limits.max_pending_activations;
00861 }
00862 
00863 <font class="keywordtype">int</font>
00864 bus_context_get_max_services_per_connection (BusContext *context)
00865 {
00866   <font class="keywordflow">return</font> context-&gt;limits.max_services_per_connection;
00867 }
00868 
00869 <font class="keywordtype">int</font>
00870 bus_context_get_max_match_rules_per_connection (BusContext *context)
00871 {
00872   <font class="keywordflow">return</font> context-&gt;limits.max_match_rules_per_connection;
00873 }
00874 
00875 dbus_bool_t
00876 bus_context_check_security_policy (BusContext     *context,
00877                                    <a class="code" href="structDBusConnection.html">DBusConnection</a> *sender,
00878                                    <a class="code" href="structDBusConnection.html">DBusConnection</a> *addressed_recipient,
00879                                    <a class="code" href="structDBusConnection.html">DBusConnection</a> *proposed_recipient,
00880                                    <a class="code" href="structDBusMessage.html">DBusMessage</a>    *message,
00881                                    <a class="code" href="structDBusError.html">DBusError</a>      *error)
00882 {
00883   BusClientPolicy *sender_policy;
00884   BusClientPolicy *recipient_policy;
00885 
00886   <font class="comment">/* NULL sender, proposed_recipient means the bus driver.  NULL</font>
00887 <font class="comment">   * addressed_recipient means the message didn't specify an explicit</font>
00888 <font class="comment">   * target. If proposed_recipient is NULL, then addressed_recipient</font>
00889 <font class="comment">   * is also NULL but is implicitly the bus driver.</font>
00890 <font class="comment">   */</font>
00891 
00892   _dbus_assert (proposed_recipient == NULL ||
00893                 (dbus_message_get_destination (message) == NULL ||
00894                  addressed_recipient != NULL));
00895   
00896   <font class="keywordflow">if</font> (sender != NULL)
00897     {
00898       <font class="keywordflow">if</font> (bus_connection_is_active (sender))
00899         {
00900           sender_policy = bus_connection_get_policy (sender);
00901           _dbus_assert (sender_policy != NULL);
00902         }
00903       <font class="keywordflow">else</font>
00904         {
00905           <font class="comment">/* Policy for inactive connections is that they can only send</font>
00906 <font class="comment">           * the hello message to the bus driver</font>
00907 <font class="comment">           */</font>
00908           <font class="keywordflow">if</font> (proposed_recipient == NULL &amp;&amp;
00909               dbus_message_is_method_call (message,
00910                                            DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
00911                                            <font class="stringliteral">"Hello"</font>))
00912             {
00913               _dbus_verbose (<font class="stringliteral">"security check allowing %s message\n"</font>,
00914                              <font class="stringliteral">"Hello"</font>);
00915               <font class="keywordflow">return</font> TRUE;
00916             }
00917           <font class="keywordflow">else</font>
00918             {
00919               _dbus_verbose (<font class="stringliteral">"security check disallowing non-%s message\n"</font>,
00920                              <font class="stringliteral">"Hello"</font>);
00921 
00922               dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
00923                               <font class="stringliteral">"Client tried to send a message other than %s without being registered"</font>,
00924                               <font class="stringliteral">"Hello"</font>);
00925               
00926               <font class="keywordflow">return</font> FALSE;
00927             }
00928         }
00929     }
00930   <font class="keywordflow">else</font>
00931     sender_policy = NULL;
00932 
00933   _dbus_assert ((sender != NULL &amp;&amp; sender_policy != NULL) ||
00934                 (sender == NULL &amp;&amp; sender_policy == NULL));
00935   
00936   <font class="keywordflow">if</font> (proposed_recipient != NULL)
00937     {
00938       <font class="comment">/* only the bus driver can send to an inactive recipient (as it</font>
00939 <font class="comment">       * owns no services, so other apps can't address it). Inactive</font>
00940 <font class="comment">       * recipients can receive any message.</font>
00941 <font class="comment">       */</font>
00942       <font class="keywordflow">if</font> (bus_connection_is_active (proposed_recipient))
00943         {
00944           recipient_policy = bus_connection_get_policy (proposed_recipient);
00945           _dbus_assert (recipient_policy != NULL);
00946         }
00947       <font class="keywordflow">else</font> <font class="keywordflow">if</font> (sender == NULL)
00948         {
00949           _dbus_verbose (<font class="stringliteral">"security check using NULL recipient policy for message from bus\n"</font>);
00950           recipient_policy = NULL;
00951         }
00952       <font class="keywordflow">else</font>
00953         {
00954           _dbus_assert_not_reached (<font class="stringliteral">"a message was somehow sent to an inactive recipient from a source other than the message bus\n"</font>);
00955           recipient_policy = NULL;
00956         }
00957     }
00958   <font class="keywordflow">else</font>
00959     recipient_policy = NULL;
00960   
00961   _dbus_assert ((proposed_recipient != NULL &amp;&amp; recipient_policy != NULL) ||
00962                 (proposed_recipient != NULL &amp;&amp; sender == NULL &amp;&amp; recipient_policy == NULL) ||
00963                 (proposed_recipient == NULL &amp;&amp; recipient_policy == NULL));
00964   
00965   <font class="keywordflow">if</font> (sender_policy &amp;&amp;
00966       !bus_client_policy_check_can_send (sender_policy,
00967                                          context-&gt;registry, proposed_recipient,
00968                                          message))
00969     {
00970       <font class="keyword">const</font> <font class="keywordtype">char</font> *dest = dbus_message_get_destination (message);
00971       dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
00972                       <font class="stringliteral">"A security policy in place prevents this sender "</font>
00973                       <font class="stringliteral">"from sending this message to this recipient, "</font>
00974                       <font class="stringliteral">"see message bus configuration file (rejected message "</font>
00975                       <font class="stringliteral">"had interface \"%s\" member \"%s\" error name \"%s\" destination \"%s\")"</font>,
00976                       dbus_message_get_interface (message) ?
00977                       dbus_message_get_interface (message) : "(unset)",
00978                       dbus_message_get_member (message) ?
00979                       dbus_message_get_member (message) : "(unset)",
00980                       dbus_message_get_error_name (message) ?
00981                       dbus_message_get_error_name (message) : "(unset)",
00982                       dest ? dest : DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
00983       _dbus_verbose (<font class="stringliteral">"security policy disallowing message due to sender policy\n"</font>);
00984       <font class="keywordflow">return</font> FALSE;
00985     }
00986 
00987   <font class="keywordflow">if</font> (recipient_policy &amp;&amp;
00988       !bus_client_policy_check_can_receive (recipient_policy,
00989                                             context-&gt;registry, sender,
00990                                             addressed_recipient, proposed_recipient,
00991                                             message))
00992     {
00993       <font class="keyword">const</font> <font class="keywordtype">char</font> *dest = dbus_message_get_destination (message);
00994       dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
00995                       <font class="stringliteral">"A security policy in place prevents this recipient "</font>
00996                       <font class="stringliteral">"from receiving this message from this sender, "</font>
00997                       <font class="stringliteral">"see message bus configuration file (rejected message "</font>
00998                       <font class="stringliteral">"had interface \"%s\" member \"%s\" error name \"%s\" destination \"%s\")"</font>,
00999                       dbus_message_get_interface (message) ?
01000                       dbus_message_get_interface (message) : "(unset)",
01001                       dbus_message_get_member (message) ?
01002                       dbus_message_get_member (message) : "(unset)",
01003                       dbus_message_get_error_name (message) ?
01004                       dbus_message_get_error_name (message) : "(unset)",
01005                       dest ? dest : DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
01006       _dbus_verbose (<font class="stringliteral">"security policy disallowing message due to recipient policy\n"</font>);
01007       <font class="keywordflow">return</font> FALSE;
01008     }
01009 
01010   <font class="comment">/* See if limits on size have been exceeded */</font>
01011   <font class="keywordflow">if</font> (proposed_recipient &amp;&amp;
01012       dbus_connection_get_outgoing_size (proposed_recipient) &gt;
01013       context-&gt;limits.max_outgoing_bytes)
01014     {
01015       <font class="keyword">const</font> <font class="keywordtype">char</font> *dest = dbus_message_get_destination (message);
01016       dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
01017                       <font class="stringliteral">"The destination service \"%s\" has a full message queue"</font>,
01018                       dest ? dest : (proposed_recipient ?
01019                                      bus_connection_get_name (proposed_recipient) : 
01020                                      DBUS_SERVICE_ORG_FREEDESKTOP_DBUS));
01021       _dbus_verbose (<font class="stringliteral">"security policy disallowing message due to full message queue\n"</font>);
01022       <font class="keywordflow">return</font> FALSE;
01023     }
01024 
01025   _dbus_verbose (<font class="stringliteral">"security policy allowing message\n"</font>);
01026   <font class="keywordflow">return</font> TRUE;
01027 }
</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>