Sophie

Sophie

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

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>dbus-sysdeps.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>dbus-sysdeps.c</h1><div class="fragment"><pre>00001 <font class="comment">/* -*- mode: C; c-file-style: "gnu" -*- */</font>
00002 <font class="comment">/* dbus-sysdeps.c Wrappers around system/libc features (internal to D-BUS implementation)</font>
00003 <font class="comment"> * </font>
00004 <font class="comment"> * Copyright (C) 2002, 2003  Red Hat, Inc.</font>
00005 <font class="comment"> * Copyright (C) 2003 CodeFactory AB</font>
00006 <font class="comment"> *</font>
00007 <font class="comment"> * Licensed under the Academic Free License version 2.0</font>
00008 <font class="comment"> * </font>
00009 <font class="comment"> * This program is free software; you can redistribute it and/or modify</font>
00010 <font class="comment"> * it under the terms of the GNU General Public License as published by</font>
00011 <font class="comment"> * the Free Software Foundation; either version 2 of the License, or</font>
00012 <font class="comment"> * (at your option) any later version.</font>
00013 <font class="comment"> *</font>
00014 <font class="comment"> * This program is distributed in the hope that it will be useful,</font>
00015 <font class="comment"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</font>
00016 <font class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</font>
00017 <font class="comment"> * GNU General Public License for more details.</font>
00018 <font class="comment"> * </font>
00019 <font class="comment"> * You should have received a copy of the GNU General Public License</font>
00020 <font class="comment"> * along with this program; if not, write to the Free Software</font>
00021 <font class="comment"> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA</font>
00022 <font class="comment"> *</font>
00023 <font class="comment"> */</font>
00024 
00025 <font class="preprocessor">#include "dbus-internals.h"</font>
00026 <font class="preprocessor">#include "dbus-sysdeps.h"</font>
00027 <font class="preprocessor">#include "dbus-threads.h"</font>
00028 <font class="preprocessor">#include "dbus-test.h"</font>
00029 <font class="preprocessor">#include &lt;sys/types.h&gt;</font>
00030 <font class="preprocessor">#include &lt;stdlib.h&gt;</font>
00031 <font class="preprocessor">#include &lt;string.h&gt;</font>
00032 <font class="preprocessor">#include &lt;signal.h&gt;</font>
00033 <font class="preprocessor">#include &lt;unistd.h&gt;</font>
00034 <font class="preprocessor">#include &lt;stdio.h&gt;</font>
00035 <font class="preprocessor">#include &lt;errno.h&gt;</font>
00036 <font class="preprocessor">#include &lt;fcntl.h&gt;</font>
00037 <font class="preprocessor">#include &lt;sys/socket.h&gt;</font>
00038 <font class="preprocessor">#include &lt;dirent.h&gt;</font>
00039 <font class="preprocessor">#include &lt;sys/un.h&gt;</font>
00040 <font class="preprocessor">#include &lt;pwd.h&gt;</font>
00041 <font class="preprocessor">#include &lt;time.h&gt;</font>
00042 <font class="preprocessor">#include &lt;locale.h&gt;</font>
00043 <font class="preprocessor">#include &lt;sys/time.h&gt;</font>
00044 <font class="preprocessor">#include &lt;sys/stat.h&gt;</font>
00045 <font class="preprocessor">#include &lt;sys/wait.h&gt;</font>
00046 <font class="preprocessor">#include &lt;netinet/in.h&gt;</font>
00047 <font class="preprocessor">#include &lt;netdb.h&gt;</font>
00048 <font class="preprocessor">#include &lt;grp.h&gt;</font>
00049 
00050 <font class="preprocessor">#ifdef HAVE_WRITEV</font>
00051 <font class="preprocessor"></font><font class="preprocessor">#include &lt;sys/uio.h&gt;</font>
00052 <font class="preprocessor">#endif</font>
00053 <font class="preprocessor"></font><font class="preprocessor">#ifdef HAVE_POLL</font>
00054 <font class="preprocessor"></font><font class="preprocessor">#include &lt;sys/poll.h&gt;</font>
00055 <font class="preprocessor">#endif</font>
00056 <font class="preprocessor"></font><font class="preprocessor">#ifdef HAVE_BACKTRACE</font>
00057 <font class="preprocessor"></font><font class="preprocessor">#include &lt;execinfo.h&gt;</font>
00058 <font class="preprocessor">#endif</font>
00059 <font class="preprocessor"></font>
00060 
00061 <font class="preprocessor">#ifndef O_BINARY</font>
00062 <font class="preprocessor"></font><font class="preprocessor">#define O_BINARY 0</font>
00063 <font class="preprocessor"></font><font class="preprocessor">#endif</font>
00064 <font class="preprocessor"></font>
00065 <font class="preprocessor">#ifndef HAVE_SOCKLEN_T</font>
00066 <font class="preprocessor"></font><font class="preprocessor">#define socklen_t int</font>
00067 <font class="preprocessor"></font><font class="preprocessor">#endif</font>
00068 <font class="preprocessor"></font>
00076 <font class="keywordtype">void</font>
<a name="l00077"></a><a class="code" href="group__DBusInternalsUtils.html#a44">00077</a> _dbus_abort (<font class="keywordtype">void</font>)
00078 {
00079 <font class="preprocessor">#ifdef DBUS_ENABLE_VERBOSE_MODE</font>
00080 <font class="preprocessor"></font>  <font class="keyword">const</font> <font class="keywordtype">char</font> *s;
00081   s = _dbus_getenv (<font class="stringliteral">"DBUS_PRINT_BACKTRACE"</font>);
00082   <font class="keywordflow">if</font> (s &amp;&amp; *s)
00083     _dbus_print_backtrace ();
00084 <font class="preprocessor">#endif</font>
00085 <font class="preprocessor"></font>  abort ();
00086   _exit (1); <font class="comment">/* in case someone manages to ignore SIGABRT */</font>
00087 }
00088 
00100 dbus_bool_t
<a name="l00101"></a><a class="code" href="group__DBusInternalsUtils.html#a45">00101</a> _dbus_setenv (<font class="keyword">const</font> <font class="keywordtype">char</font> *varname,
00102               <font class="keyword">const</font> <font class="keywordtype">char</font> *value)
00103 {
00104   _dbus_assert (varname != NULL);
00105   
00106   <font class="keywordflow">if</font> (value == NULL)
00107     {
00108 <font class="preprocessor">#ifdef HAVE_UNSETENV</font>
00109 <font class="preprocessor"></font>      unsetenv (varname);
00110       <font class="keywordflow">return</font> TRUE;
00111 <font class="preprocessor">#else</font>
00112 <font class="preprocessor"></font>      <font class="keywordtype">char</font> *putenv_value;
00113       size_t len;
00114 
00115       len = strlen (varname);
00116 
00117       <font class="comment">/* Use system malloc to avoid memleaks that dbus_malloc</font>
00118 <font class="comment">       * will get upset about.</font>
00119 <font class="comment">       */</font>
00120       
00121       putenv_value = malloc (len + 1);
00122       <font class="keywordflow">if</font> (putenv_value == NULL)
00123         <font class="keywordflow">return</font> FALSE;
00124 
00125       strcpy (putenv_value, varname);
00126       
00127       <font class="keywordflow">return</font> (putenv (putenv_value) == 0);
00128 <font class="preprocessor">#endif</font>
00129 <font class="preprocessor"></font>    }
00130   <font class="keywordflow">else</font>
00131     {
00132 <font class="preprocessor">#ifdef HAVE_SETENV</font>
00133 <font class="preprocessor"></font>      <font class="keywordflow">return</font> (setenv (varname, value, TRUE) == 0);
00134 <font class="preprocessor">#else</font>
00135 <font class="preprocessor"></font>      <font class="keywordtype">char</font> *putenv_value;
00136       size_t len;
00137       size_t varname_len;
00138       size_t value_len;
00139 
00140       varname_len = strlen (varname);
00141       value_len = strlen (value);
00142       
00143       len = varname_len + value_len + 1 <font class="comment">/* '=' */</font> ;
00144 
00145       <font class="comment">/* Use system malloc to avoid memleaks that dbus_malloc</font>
00146 <font class="comment">       * will get upset about.</font>
00147 <font class="comment">       */</font>
00148       
00149       putenv_value = malloc (len + 1);
00150       <font class="keywordflow">if</font> (putenv_value == NULL)
00151         <font class="keywordflow">return</font> FALSE;
00152 
00153       strcpy (putenv_value, varname);
00154       strcpy (putenv_value + varname_len, <font class="stringliteral">"="</font>);
00155       strcpy (putenv_value + varname_len + 1, value);
00156       
00157       <font class="keywordflow">return</font> (putenv (putenv_value) == 0);
00158 <font class="preprocessor">#endif</font>
00159 <font class="preprocessor"></font>    }
00160 }
00161 
00168 <font class="keyword">const</font> <font class="keywordtype">char</font>*
<a name="l00169"></a><a class="code" href="group__DBusInternalsUtils.html#a46">00169</a> _dbus_getenv (<font class="keyword">const</font> <font class="keywordtype">char</font> *varname)
00170 {  
00171   <font class="keywordflow">return</font> getenv (varname);
00172 }
00173 
00187 <font class="keywordtype">int</font>
<a name="l00188"></a><a class="code" href="group__DBusInternalsUtils.html#a47">00188</a> _dbus_read (<font class="keywordtype">int</font>               fd,
00189             <a class="code" href="structDBusString.html">DBusString</a>       *buffer,
00190             <font class="keywordtype">int</font>               count)
00191 {
00192   <font class="keywordtype">int</font> bytes_read;
00193   <font class="keywordtype">int</font> start;
00194   <font class="keywordtype">char</font> *data;
00195 
00196   _dbus_assert (count &gt;= 0);
00197   
00198   start = _dbus_string_get_length (buffer);
00199 
00200   <font class="keywordflow">if</font> (!_dbus_string_lengthen (buffer, count))
00201     {
00202       errno = ENOMEM;
00203       <font class="keywordflow">return</font> -1;
00204     }
00205 
00206   data = _dbus_string_get_data_len (buffer, start, count);
00207 
00208  again:
00209   
00210   bytes_read = read (fd, data, count);
00211 
00212   <font class="keywordflow">if</font> (bytes_read &lt; 0)
00213     {
00214       <font class="keywordflow">if</font> (errno == EINTR)
00215         <font class="keywordflow">goto</font> again;
00216       <font class="keywordflow">else</font>
00217         {
00218           <font class="comment">/* put length back (note that this doesn't actually realloc anything) */</font>
00219           _dbus_string_set_length (buffer, start);
00220           <font class="keywordflow">return</font> -1;
00221         }
00222     }
00223   <font class="keywordflow">else</font>
00224     {
00225       <font class="comment">/* put length back (doesn't actually realloc) */</font>
00226       _dbus_string_set_length (buffer, start + bytes_read);
00227 
00228 <font class="preprocessor">#if 0</font>
00229 <font class="preprocessor"></font>      <font class="keywordflow">if</font> (bytes_read &gt; 0)
00230         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00231 <font class="preprocessor">#endif</font>
00232 <font class="preprocessor"></font>      
00233       <font class="keywordflow">return</font> bytes_read;
00234     }
00235 }
00236 
00247 <font class="keywordtype">int</font>
<a name="l00248"></a><a class="code" href="group__DBusInternalsUtils.html#a48">00248</a> _dbus_write (<font class="keywordtype">int</font>               fd,
00249              <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *buffer,
00250              <font class="keywordtype">int</font>               start,
00251              <font class="keywordtype">int</font>               len)
00252 {
00253   <font class="keyword">const</font> <font class="keywordtype">char</font> *data;
00254   <font class="keywordtype">int</font> bytes_written;
00255   
00256   data = _dbus_string_get_const_data_len (buffer, start, len);
00257   
00258  again:
00259 
00260   bytes_written = write (fd, data, len);
00261 
00262   <font class="keywordflow">if</font> (bytes_written &lt; 0 &amp;&amp; errno == EINTR)
00263     <font class="keywordflow">goto</font> again;
00264 
00265 <font class="preprocessor">#if 0</font>
00266 <font class="preprocessor"></font>  <font class="keywordflow">if</font> (bytes_written &gt; 0)
00267     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00268 <font class="preprocessor">#endif</font>
00269 <font class="preprocessor"></font>  
00270   <font class="keywordflow">return</font> bytes_written;
00271 }
00272 
00293 <font class="keywordtype">int</font>
<a name="l00294"></a><a class="code" href="group__DBusInternalsUtils.html#a49">00294</a> _dbus_write_two (<font class="keywordtype">int</font>               fd,
00295                  <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *buffer1,
00296                  <font class="keywordtype">int</font>               start1,
00297                  <font class="keywordtype">int</font>               len1,
00298                  <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *buffer2,
00299                  <font class="keywordtype">int</font>               start2,
00300                  <font class="keywordtype">int</font>               len2)
00301 {
00302   _dbus_assert (buffer1 != NULL);
00303   _dbus_assert (start1 &gt;= 0);
00304   _dbus_assert (start2 &gt;= 0);
00305   _dbus_assert (len1 &gt;= 0);
00306   _dbus_assert (len2 &gt;= 0);
00307   
00308 <font class="preprocessor">#ifdef HAVE_WRITEV</font>
00309 <font class="preprocessor"></font>  {
00310     <font class="keyword">struct </font>iovec vectors[2];
00311     <font class="keyword">const</font> <font class="keywordtype">char</font> *data1;
00312     <font class="keyword">const</font> <font class="keywordtype">char</font> *data2;
00313     <font class="keywordtype">int</font> bytes_written;
00314 
00315     data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00316 
00317     <font class="keywordflow">if</font> (buffer2 != NULL)
00318       data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00319     <font class="keywordflow">else</font>
00320       {
00321         data2 = NULL;
00322         start2 = 0;
00323         len2 = 0;
00324       }
00325    
00326     vectors[0].iov_base = (<font class="keywordtype">char</font>*) data1;
00327     vectors[0].iov_len = len1;
00328     vectors[1].iov_base = (<font class="keywordtype">char</font>*) data2;
00329     vectors[1].iov_len = len2;
00330 
00331   again:
00332    
00333     bytes_written = writev (fd,
00334                             vectors,
00335                             data2 ? 2 : 1);
00336 
00337     <font class="keywordflow">if</font> (bytes_written &lt; 0 &amp;&amp; errno == EINTR)
00338       <font class="keywordflow">goto</font> again;
00339    
00340     <font class="keywordflow">return</font> bytes_written;
00341   }
00342 <font class="preprocessor">#else </font><font class="comment">/* HAVE_WRITEV */</font>
00343   {
00344     <font class="keywordtype">int</font> ret1;
00345     
00346     ret1 = _dbus_write (fd, buffer1, start1, len1);
00347     <font class="keywordflow">if</font> (ret1 == len1 &amp;&amp; buffer2 != NULL)
00348       {
00349         ret2 = _dbus_write (fd, buffer2, start2, len2);
00350         <font class="keywordflow">if</font> (ret2 &lt; 0)
00351           ret2 = 0; <font class="comment">/* we can't report an error as the first write was OK */</font>
00352        
00353         <font class="keywordflow">return</font> ret1 + ret2;
00354       }
00355     <font class="keywordflow">else</font>
00356       <font class="keywordflow">return</font> ret1;
00357   }
00358 <font class="preprocessor">#endif </font><font class="comment">/* !HAVE_WRITEV */</font>   
00359 }
00360 
00361 <font class="preprocessor">#define _DBUS_MAX_SUN_PATH_LENGTH 99</font>
00362 <font class="preprocessor"></font>
00390 <font class="keywordtype">int</font>
<a name="l00391"></a><a class="code" href="group__DBusInternalsUtils.html#a50">00391</a> _dbus_connect_unix_socket (<font class="keyword">const</font> <font class="keywordtype">char</font>     *path,
00392                            dbus_bool_t     <font class="keyword">abstract</font>,
00393                            <a class="code" href="structDBusError.html">DBusError</a>      *error)
00394 {
00395   <font class="keywordtype">int</font> fd;
00396   <font class="keyword">struct </font>sockaddr_un addr;  
00397 
00398   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00399 
00400   _dbus_verbose (<font class="stringliteral">"connecting to unix socket %s abstract=%d\n"</font>,
00401                  path, <font class="keyword">abstract</font>);
00402   
00403   fd = socket (PF_UNIX, SOCK_STREAM, 0);
00404   
00405   <font class="keywordflow">if</font> (fd &lt; 0)
00406     {
00407       dbus_set_error (error,
00408                       _dbus_error_from_errno (errno),
00409                       <font class="stringliteral">"Failed to create socket: %s"</font>,
00410                       _dbus_strerror (errno)); 
00411       
00412       <font class="keywordflow">return</font> -1;
00413     }
00414 
00415   _DBUS_ZERO (addr);
00416   addr.sun_family = AF_UNIX;
00417 
00418   <font class="keywordflow">if</font> (abstract)
00419     {
00420 <font class="preprocessor">#ifdef HAVE_ABSTRACT_SOCKETS</font>
00421 <font class="preprocessor"></font>      <font class="comment">/* remember that abstract names aren't nul-terminated so we rely</font>
00422 <font class="comment">       * on sun_path being filled in with zeroes above.</font>
00423 <font class="comment">       */</font>
00424       addr.sun_path[0] = <font class="charliteral">'\0'</font>; <font class="comment">/* this is what says "use abstract" */</font>
00425       strncpy (&amp;addr.sun_path[1], path, _DBUS_MAX_SUN_PATH_LENGTH - 2);
00426       <font class="comment">/* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */</font>
00427 <font class="preprocessor">#else </font><font class="comment">/* HAVE_ABSTRACT_SOCKETS */</font>
00428       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00429                       <font class="stringliteral">"Operating system does not support abstract socket namespace\n"</font>);
00430       close (fd);
00431       <font class="keywordflow">return</font> -1;
00432 <font class="preprocessor">#endif </font><font class="comment">/* ! HAVE_ABSTRACT_SOCKETS */</font>
00433     }
00434   <font class="keywordflow">else</font>
00435     {
00436       strncpy (addr.sun_path, path, _DBUS_MAX_SUN_PATH_LENGTH - 1);
00437     }
00438   
00439   <font class="keywordflow">if</font> (connect (fd, (<font class="keyword">struct</font> sockaddr*) &amp;addr, <font class="keyword">sizeof</font> (addr)) &lt; 0)
00440     {      
00441       dbus_set_error (error,
00442                       _dbus_error_from_errno (errno),
00443                       <font class="stringliteral">"Failed to connect to socket %s: %s"</font>,
00444                       path, _dbus_strerror (errno));
00445 
00446       close (fd);
00447       fd = -1;
00448       
00449       <font class="keywordflow">return</font> -1;
00450     }
00451 
00452   <font class="keywordflow">if</font> (!_dbus_set_fd_nonblocking (fd, error))
00453     {
00454       _DBUS_ASSERT_ERROR_IS_SET (error);
00455       
00456       close (fd);
00457       fd = -1;
00458 
00459       <font class="keywordflow">return</font> -1;
00460     }
00461 
00462   <font class="keywordflow">return</font> fd;
00463 }
00464 
00480 <font class="keywordtype">int</font>
<a name="l00481"></a><a class="code" href="group__DBusInternalsUtils.html#a51">00481</a> _dbus_listen_unix_socket (<font class="keyword">const</font> <font class="keywordtype">char</font>     *path,
00482                           dbus_bool_t     <font class="keyword">abstract</font>,
00483                           <a class="code" href="structDBusError.html">DBusError</a>      *error)
00484 {
00485   <font class="keywordtype">int</font> listen_fd;
00486   <font class="keyword">struct </font>sockaddr_un addr;
00487 
00488   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00489 
00490   _dbus_verbose (<font class="stringliteral">"listening on unix socket %s abstract=%d\n"</font>,
00491                  path, <font class="keyword">abstract</font>);
00492   
00493   listen_fd = socket (PF_UNIX, SOCK_STREAM, 0);
00494   
00495   <font class="keywordflow">if</font> (listen_fd &lt; 0)
00496     {
00497       dbus_set_error (error, _dbus_error_from_errno (errno),
00498                       <font class="stringliteral">"Failed to create socket \"%s\": %s"</font>,
00499                       path, _dbus_strerror (errno));
00500       <font class="keywordflow">return</font> -1;
00501     }
00502 
00503   _DBUS_ZERO (addr);
00504   addr.sun_family = AF_UNIX;
00505   
00506   <font class="keywordflow">if</font> (abstract)
00507     {
00508 <font class="preprocessor">#ifdef HAVE_ABSTRACT_SOCKETS</font>
00509 <font class="preprocessor"></font>      <font class="comment">/* remember that abstract names aren't nul-terminated so we rely</font>
00510 <font class="comment">       * on sun_path being filled in with zeroes above.</font>
00511 <font class="comment">       */</font>
00512       addr.sun_path[0] = <font class="charliteral">'\0'</font>; <font class="comment">/* this is what says "use abstract" */</font>
00513       strncpy (&amp;addr.sun_path[1], path, _DBUS_MAX_SUN_PATH_LENGTH - 2);
00514       <font class="comment">/* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */</font>
00515 <font class="preprocessor">#else </font><font class="comment">/* HAVE_ABSTRACT_SOCKETS */</font>
00516       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00517                       <font class="stringliteral">"Operating system does not support abstract socket namespace\n"</font>);
00518       close (listen_fd);
00519       <font class="keywordflow">return</font> -1;
00520 <font class="preprocessor">#endif </font><font class="comment">/* ! HAVE_ABSTRACT_SOCKETS */</font>
00521     }
00522   <font class="keywordflow">else</font>
00523     {
00524       <font class="comment">/* FIXME discussed security implications of this with Nalin,</font>
00525 <font class="comment">       * and we couldn't think of where it would kick our ass, but</font>
00526 <font class="comment">       * it still seems a bit sucky. It also has non-security suckage;</font>
00527 <font class="comment">       * really we'd prefer to exit if the socket is already in use.</font>
00528 <font class="comment">       * But there doesn't seem to be a good way to do this.</font>
00529 <font class="comment">       *</font>
00530 <font class="comment">       * Just to be extra careful, I threw in the stat() - clearly</font>
00531 <font class="comment">       * the stat() can't *fix* any security issue, but it at least</font>
00532 <font class="comment">       * avoids inadvertent/accidental data loss.</font>
00533 <font class="comment">       */</font>
00534       {
00535         <font class="keyword">struct </font>stat sb;
00536 
00537         <font class="keywordflow">if</font> (stat (path, &amp;sb) == 0 &amp;&amp;
00538             S_ISSOCK (sb.st_mode))
00539           unlink (path);
00540       }
00541 
00542       strncpy (addr.sun_path, path, _DBUS_MAX_SUN_PATH_LENGTH - 1);
00543     }
00544   
00545   <font class="keywordflow">if</font> (bind (listen_fd, (<font class="keyword">struct</font> sockaddr*) &amp;addr, <font class="keyword">sizeof</font> (addr)) &lt; 0)
00546     {
00547       dbus_set_error (error, _dbus_error_from_errno (errno),
00548                       <font class="stringliteral">"Failed to bind socket \"%s\": %s"</font>,
00549                       path, _dbus_strerror (errno));
00550       close (listen_fd);
00551       <font class="keywordflow">return</font> -1;
00552     }
00553 
00554   <font class="keywordflow">if</font> (listen (listen_fd, 30 <font class="comment">/* backlog */</font>) &lt; 0)
00555     {
00556       dbus_set_error (error, _dbus_error_from_errno (errno),
00557                       <font class="stringliteral">"Failed to listen on socket \"%s\": %s"</font>,
00558                       path, _dbus_strerror (errno));
00559       close (listen_fd);
00560       <font class="keywordflow">return</font> -1;
00561     }
00562 
00563   <font class="keywordflow">if</font> (!_dbus_set_fd_nonblocking (listen_fd, error))
00564     {
00565       _DBUS_ASSERT_ERROR_IS_SET (error);
00566       close (listen_fd);
00567       <font class="keywordflow">return</font> -1;
00568     }
00569   
00570   <font class="comment">/* Try opening up the permissions, but if we can't, just go ahead</font>
00571 <font class="comment">   * and continue, maybe it will be good enough.</font>
00572 <font class="comment">   */</font>
00573   <font class="keywordflow">if</font> (!<font class="keyword">abstract</font> &amp;&amp; chmod (path, 0777) &lt; 0)
00574     _dbus_warn (<font class="stringliteral">"Could not set mode 0777 on socket %s\n"</font>,
00575                 path);
00576   
00577   <font class="keywordflow">return</font> listen_fd;
00578 }
00579 
00590 <font class="keywordtype">int</font>
<a name="l00591"></a><a class="code" href="group__DBusInternalsUtils.html#a52">00591</a> _dbus_connect_tcp_socket (<font class="keyword">const</font> <font class="keywordtype">char</font>     *host,
00592                           dbus_uint32_t   port,
00593                           <a class="code" href="structDBusError.html">DBusError</a>      *error)
00594 {
00595   <font class="keywordtype">int</font> fd;
00596   <font class="keyword">struct </font>sockaddr_in addr;
00597   <font class="keyword">struct </font>hostent *he;
00598   <font class="keyword">struct </font>in_addr *haddr;
00599 
00600   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00601   
00602   fd = socket (AF_INET, SOCK_STREAM, 0);
00603   
00604   <font class="keywordflow">if</font> (fd &lt; 0)
00605     {
00606       dbus_set_error (error,
00607                       _dbus_error_from_errno (errno),
00608                       <font class="stringliteral">"Failed to create socket: %s"</font>,
00609                       _dbus_strerror (errno)); 
00610       
00611       <font class="keywordflow">return</font> -1;
00612     }
00613 
00614   <font class="keywordflow">if</font> (host == NULL)
00615     host = <font class="stringliteral">"localhost"</font>;
00616 
00617   he = gethostbyname (host);
00618   <font class="keywordflow">if</font> (he == NULL) 
00619     {
00620       dbus_set_error (error,
00621                       _dbus_error_from_errno (errno),
00622                       <font class="stringliteral">"Failed to lookup hostname: %s"</font>,
00623                       host);
00624       <font class="keywordflow">return</font> -1;
00625     }
00626   
00627   haddr = ((<font class="keyword">struct </font>in_addr *) (he-&gt;h_addr_list)[0]);
00628 
00629   _DBUS_ZERO (addr);
00630   memcpy (&amp;addr.sin_addr, haddr, <font class="keyword">sizeof</font>(<font class="keyword">struct</font> in_addr));
00631   addr.sin_family = AF_INET;
00632   addr.sin_port = htons (port);
00633   
00634   <font class="keywordflow">if</font> (connect (fd, (<font class="keyword">struct</font> sockaddr*) &amp;addr, <font class="keyword">sizeof</font> (addr)) &lt; 0)
00635     {      
00636       dbus_set_error (error,
00637                        _dbus_error_from_errno (errno),
00638                       <font class="stringliteral">"Failed to connect to socket %s: %s:%d"</font>,
00639                       host, _dbus_strerror (errno), port);
00640 
00641       close (fd);
00642       fd = -1;
00643       
00644       <font class="keywordflow">return</font> -1;
00645     }
00646 
00647   <font class="keywordflow">if</font> (!_dbus_set_fd_nonblocking (fd, error))
00648     {
00649       close (fd);
00650       fd = -1;
00651 
00652       <font class="keywordflow">return</font> -1;
00653     }
00654 
00655   <font class="keywordflow">return</font> fd;
00656 }
00657 
00668 <font class="keywordtype">int</font>
<a name="l00669"></a><a class="code" href="group__DBusInternalsUtils.html#a53">00669</a> _dbus_listen_tcp_socket (<font class="keyword">const</font> <font class="keywordtype">char</font>     *host,
00670                          dbus_uint32_t   port,
00671                          <a class="code" href="structDBusError.html">DBusError</a>      *error)
00672 {
00673   <font class="keywordtype">int</font> listen_fd;
00674   <font class="keyword">struct </font>sockaddr_in addr;
00675   <font class="keyword">struct </font>hostent *he;
00676   <font class="keyword">struct </font>in_addr *haddr;
00677 
00678   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00679   
00680   listen_fd = socket (AF_INET, SOCK_STREAM, 0);
00681   
00682   <font class="keywordflow">if</font> (listen_fd &lt; 0)
00683     {
00684       dbus_set_error (error, _dbus_error_from_errno (errno),
00685                       <font class="stringliteral">"Failed to create socket \"%s:%d\": %s"</font>,
00686                       host, port, _dbus_strerror (errno));
00687       <font class="keywordflow">return</font> -1;
00688     }
00689 
00690   he = gethostbyname (host);
00691   <font class="keywordflow">if</font> (he == NULL) 
00692     {
00693       dbus_set_error (error,
00694                       _dbus_error_from_errno (errno),
00695                       <font class="stringliteral">"Failed to lookup hostname: %s"</font>,
00696                       host);
00697       <font class="keywordflow">return</font> -1;
00698     }
00699   
00700   haddr = ((<font class="keyword">struct </font>in_addr *) (he-&gt;h_addr_list)[0]);
00701 
00702   _DBUS_ZERO (addr);
00703   memcpy (&amp;addr.sin_addr, haddr, sizeof (<font class="keyword">struct</font> in_addr));
00704   addr.sin_family = AF_INET;
00705   addr.sin_port = htons (port);
00706 
00707   <font class="keywordflow">if</font> (bind (listen_fd, (<font class="keyword">struct</font> sockaddr*) &amp;addr, <font class="keyword">sizeof</font> (<font class="keyword">struct</font> sockaddr)))
00708     {
00709       dbus_set_error (error, _dbus_error_from_errno (errno),
00710                       <font class="stringliteral">"Failed to bind socket \"%s:%d\": %s"</font>,
00711                       host, port, _dbus_strerror (errno));
00712       close (listen_fd);
00713       <font class="keywordflow">return</font> -1;
00714     }
00715 
00716   <font class="keywordflow">if</font> (listen (listen_fd, 30 <font class="comment">/* backlog */</font>) &lt; 0)
00717     {
00718       dbus_set_error (error, _dbus_error_from_errno (errno),  
00719                       <font class="stringliteral">"Failed to listen on socket \"%s:%d\": %s"</font>,
00720                       host, port, _dbus_strerror (errno));
00721       close (listen_fd);
00722       <font class="keywordflow">return</font> -1;
00723     }
00724 
00725   <font class="keywordflow">if</font> (!_dbus_set_fd_nonblocking (listen_fd, error))
00726     {
00727       close (listen_fd);
00728       <font class="keywordflow">return</font> -1;
00729     }
00730   
00731   <font class="keywordflow">return</font> listen_fd;
00732 }
00733 
00734 <font class="keyword">static</font> dbus_bool_t
00735 write_credentials_byte (<font class="keywordtype">int</font>             server_fd,
00736                         <a class="code" href="structDBusError.html">DBusError</a>      *error)
00737 {
00738   <font class="keywordtype">int</font> bytes_written;
00739   <font class="keywordtype">char</font> buf[1] = { <font class="charliteral">'\0'</font> };
00740 
00741   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00742   
00743  again:
00744 
00745   bytes_written = write (server_fd, buf, 1);
00746 
00747   <font class="keywordflow">if</font> (bytes_written &lt; 0 &amp;&amp; errno == EINTR)
00748     <font class="keywordflow">goto</font> again;
00749 
00750   <font class="keywordflow">if</font> (bytes_written &lt; 0)
00751     {
00752       dbus_set_error (error, _dbus_error_from_errno (errno),
00753                       <font class="stringliteral">"Failed to write credentials byte: %s"</font>,
00754                      _dbus_strerror (errno));
00755       <font class="keywordflow">return</font> FALSE;
00756     }
00757   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (bytes_written == 0)
00758     {
00759       dbus_set_error (error, DBUS_ERROR_IO_ERROR,
00760                       <font class="stringliteral">"wrote zero bytes writing credentials byte"</font>);
00761       <font class="keywordflow">return</font> FALSE;
00762     }
00763   <font class="keywordflow">else</font>
00764     {
00765       _dbus_assert (bytes_written == 1);
00766       _dbus_verbose (<font class="stringliteral">"wrote credentials byte\n"</font>);
00767       <font class="keywordflow">return</font> TRUE;
00768     }
00769 }
00770 
00789 dbus_bool_t
<a name="l00790"></a><a class="code" href="group__DBusInternalsUtils.html#a55">00790</a> _dbus_read_credentials_unix_socket  (<font class="keywordtype">int</font>              client_fd,
00791                                      <a class="code" href="structDBusCredentials.html">DBusCredentials</a> *credentials,
00792                                      <a class="code" href="structDBusError.html">DBusError</a>       *error)
00793 {
00794   <font class="keyword">struct </font>msghdr msg;
00795   <font class="keyword">struct </font>iovec iov;
00796   <font class="keywordtype">char</font> buf;
00797 
00798 <font class="preprocessor">#ifdef HAVE_CMSGCRED </font>
00799 <font class="preprocessor"></font>  <font class="keywordtype">char</font> cmsgmem[CMSG_SPACE (<font class="keyword">sizeof</font> (<font class="keyword">struct</font> cmsgcred))];
00800   <font class="keyword">struct </font>cmsghdr *cmsg = (<font class="keyword">struct </font>cmsghdr *) cmsgmem;
00801 <font class="preprocessor">#endif</font>
00802 <font class="preprocessor"></font>
00803   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00804   
00805   <font class="comment">/* The POSIX spec certainly doesn't promise this, but</font>
00806 <font class="comment">   * we need these assertions to fail as soon as we're wrong about</font>
00807 <font class="comment">   * it so we can do the porting fixups</font>
00808 <font class="comment">   */</font>
00809   _dbus_assert (<font class="keyword">sizeof</font> (pid_t) &lt;= <font class="keyword">sizeof</font> (credentials-&gt;<a class="code" href="structDBusCredentials.html#m0">pid</a>));
00810   _dbus_assert (<font class="keyword">sizeof</font> (uid_t) &lt;= <font class="keyword">sizeof</font> (credentials-&gt;<a class="code" href="structDBusCredentials.html#m1">uid</a>));
00811   _dbus_assert (<font class="keyword">sizeof</font> (gid_t) &lt;= <font class="keyword">sizeof</font> (credentials-&gt;<a class="code" href="structDBusCredentials.html#m2">gid</a>));
00812 
00813   _dbus_credentials_clear (credentials);
00814 
00815 <font class="preprocessor">#if defined(LOCAL_CREDS) &amp;&amp; defined(HAVE_CMSGCRED)</font>
00816 <font class="preprocessor"></font>  <font class="comment">/* Set the socket to receive credentials on the next message */</font>
00817   {
00818     <font class="keywordtype">int</font> on = 1;
00819     <font class="keywordflow">if</font> (setsockopt (client_fd, 0, LOCAL_CREDS, &amp;on, <font class="keyword">sizeof</font> (on)) &lt; 0)
00820       {
00821         _dbus_verbose (<font class="stringliteral">"Unable to set LOCAL_CREDS socket option\n"</font>);
00822         <font class="keywordflow">return</font> FALSE;
00823       }
00824   }
00825 <font class="preprocessor">#endif</font>
00826 <font class="preprocessor"></font>
00827   iov.iov_base = &amp;buf;
00828   iov.iov_len = 1;
00829 
00830   memset (&amp;msg, 0, <font class="keyword">sizeof</font> (msg));
00831   msg.msg_iov = &amp;iov;
00832   msg.msg_iovlen = 1;
00833 
00834 <font class="preprocessor">#ifdef HAVE_CMSGCRED</font>
00835 <font class="preprocessor"></font>  memset (cmsgmem, 0, <font class="keyword">sizeof</font> (cmsgmem));
00836   msg.msg_control = cmsgmem;
00837   msg.msg_controllen = <font class="keyword">sizeof</font> (cmsgmem);
00838 <font class="preprocessor">#endif</font>
00839 <font class="preprocessor"></font>
00840  again:
00841   <font class="keywordflow">if</font> (recvmsg (client_fd, &amp;msg, 0) &lt; 0)
00842     {
00843       <font class="keywordflow">if</font> (errno == EINTR)
00844         <font class="keywordflow">goto</font> again;
00845 
00846       dbus_set_error (error, _dbus_error_from_errno (errno),
00847                       <font class="stringliteral">"Failed to read credentials byte: %s"</font>,
00848                       _dbus_strerror (errno));
00849       <font class="keywordflow">return</font> FALSE;
00850     }
00851 
00852   <font class="keywordflow">if</font> (buf != <font class="charliteral">'\0'</font>)
00853     {
00854       dbus_set_error (error, DBUS_ERROR_FAILED,
00855                       <font class="stringliteral">"Credentials byte was not nul"</font>);
00856       <font class="keywordflow">return</font> FALSE;
00857     }
00858 
00859 <font class="preprocessor">#ifdef HAVE_CMSGCRED</font>
00860 <font class="preprocessor"></font>  <font class="keywordflow">if</font> (cmsg-&gt;cmsg_len &lt; <font class="keyword">sizeof</font> (cmsgmem) || cmsg-&gt;cmsg_type != SCM_CREDS)
00861     {
00862       dbus_set_error (error, DBUS_ERROR_FAILED);
00863       _dbus_verbose (<font class="stringliteral">"Message from recvmsg() was not SCM_CREDS\n"</font>);
00864       <font class="keywordflow">return</font> FALSE;
00865     }
00866 <font class="preprocessor">#endif</font>
00867 <font class="preprocessor"></font>
00868   _dbus_verbose (<font class="stringliteral">"read credentials byte\n"</font>);
00869 
00870   {
00871 <font class="preprocessor">#ifdef SO_PEERCRED</font>
00872 <font class="preprocessor"></font>    <font class="keyword">struct </font>ucred cr;   
00873     <font class="keywordtype">int</font> cr_len = <font class="keyword">sizeof</font> (cr);
00874    
00875     <font class="keywordflow">if</font> (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &amp;cr, &amp;cr_len) == 0 &amp;&amp;
00876         cr_len == <font class="keyword">sizeof</font> (cr))
00877       {
00878         credentials-&gt;<a class="code" href="structDBusCredentials.html#m0">pid</a> = cr.pid;
00879         credentials-&gt;<a class="code" href="structDBusCredentials.html#m1">uid</a> = cr.uid;
00880         credentials-&gt;<a class="code" href="structDBusCredentials.html#m2">gid</a> = cr.gid;
00881       }
00882     <font class="keywordflow">else</font>
00883       {
00884         _dbus_verbose (<font class="stringliteral">"Failed to getsockopt() credentials, returned len %d/%d: %s\n"</font>,
00885                        cr_len, (<font class="keywordtype">int</font>) <font class="keyword">sizeof</font> (cr), _dbus_strerror (errno));
00886       }
00887 <font class="preprocessor">#elif defined(HAVE_CMSGCRED)</font>
00888 <font class="preprocessor"></font>    <font class="keyword">struct </font>cmsgcred *cred;
00889 
00890     cred = (<font class="keyword">struct </font>cmsgcred *) CMSG_DATA (cmsg);
00891 
00892     credentials-&gt;<a class="code" href="structDBusCredentials.html#m0">pid</a> = cred-&gt;cmcred_pid;
00893     credentials-&gt;<a class="code" href="structDBusCredentials.html#m1">uid</a> = cred-&gt;cmcred_euid;
00894     credentials-&gt;<a class="code" href="structDBusCredentials.html#m2">gid</a> = cred-&gt;cmcred_groups[0];
00895 <font class="preprocessor">#else </font><font class="comment">/* !SO_PEERCRED &amp;&amp; !HAVE_CMSGCRED */</font>
00896     _dbus_verbose (<font class="stringliteral">"Socket credentials not supported on this OS\n"</font>);
00897 <font class="preprocessor">#endif</font>
00898 <font class="preprocessor"></font>  }
00899 
00900   _dbus_verbose (<font class="stringliteral">"Credentials:"</font>
00901                  <font class="stringliteral">"  pid "</font>DBUS_PID_FORMAT
00902                  <font class="stringliteral">"  uid "</font>DBUS_UID_FORMAT
00903                  <font class="stringliteral">"  gid "</font>DBUS_GID_FORMAT<font class="stringliteral">"\n"</font>,
00904                  credentials-&gt;<a class="code" href="structDBusCredentials.html#m0">pid</a>,
00905                  credentials-&gt;<a class="code" href="structDBusCredentials.html#m1">uid</a>,
00906                  credentials-&gt;<a class="code" href="structDBusCredentials.html#m2">gid</a>);
00907     
00908   <font class="keywordflow">return</font> TRUE;
00909 }
00910 
00928 dbus_bool_t
<a name="l00929"></a><a class="code" href="group__DBusInternalsUtils.html#a56">00929</a> _dbus_send_credentials_unix_socket  (<font class="keywordtype">int</font>              server_fd,
00930                                      <a class="code" href="structDBusError.html">DBusError</a>       *error)
00931 {
00932   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00933   
00934   <font class="keywordflow">if</font> (write_credentials_byte (server_fd, error))
00935     <font class="keywordflow">return</font> TRUE;
00936   <font class="keywordflow">else</font>
00937     <font class="keywordflow">return</font> FALSE;
00938 }
00939 
00947 <font class="keywordtype">int</font>
<a name="l00948"></a><a class="code" href="group__DBusInternalsUtils.html#a57">00948</a> _dbus_accept  (<font class="keywordtype">int</font> listen_fd)
00949 {
00950   <font class="keywordtype">int</font> client_fd;
00951   <font class="keyword">struct </font>sockaddr addr;
00952   socklen_t addrlen;
00953 
00954   addrlen = <font class="keyword">sizeof</font> (addr);
00955   
00956  retry:
00957   client_fd = accept (listen_fd, &amp;addr, &amp;addrlen);
00958   
00959   <font class="keywordflow">if</font> (client_fd &lt; 0)
00960     {
00961       <font class="keywordflow">if</font> (errno == EINTR)
00962         <font class="keywordflow">goto</font> retry;
00963     }
00964   
00965   <font class="keywordflow">return</font> client_fd;
00966 }
00967 
00982 dbus_bool_t
<a name="l00983"></a><a class="code" href="group__DBusString.html#a25">00983</a> _dbus_string_append_int (<a class="code" href="structDBusString.html">DBusString</a> *str,
00984                          <font class="keywordtype">long</font>        value)
00985 {
00986   <font class="comment">/* this calculation is from comp.lang.c faq */</font>
00987 <font class="preprocessor">#define MAX_LONG_LEN ((sizeof (long) * 8 + 2) / 3 + 1)  </font><font class="comment">/* +1 for '-' */</font>
00988   <font class="keywordtype">int</font> orig_len;
00989   <font class="keywordtype">int</font> i;
00990   <font class="keywordtype">char</font> *buf;
00991   
00992   orig_len = _dbus_string_get_length (str);
00993 
00994   <font class="keywordflow">if</font> (!_dbus_string_lengthen (str, MAX_LONG_LEN))
00995     <font class="keywordflow">return</font> FALSE;
00996 
00997   buf = _dbus_string_get_data_len (str, orig_len, MAX_LONG_LEN);
00998 
00999   snprintf (buf, MAX_LONG_LEN, <font class="stringliteral">"%ld"</font>, value);
01000 
01001   i = 0;
01002   <font class="keywordflow">while</font> (*buf)
01003     {
01004       ++buf;
01005       ++i;
01006     }
01007   
01008   _dbus_string_shorten (str, MAX_LONG_LEN - i);
01009   
01010   <font class="keywordflow">return</font> TRUE;
01011 }
01012 
01020 dbus_bool_t
<a name="l01021"></a><a class="code" href="group__DBusString.html#a26">01021</a> _dbus_string_append_uint (<a class="code" href="structDBusString.html">DBusString</a>    *str,
01022                           <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font>  value)
01023 {
01024   <font class="comment">/* this is wrong, but definitely on the high side. */</font>
01025 <font class="preprocessor">#define MAX_ULONG_LEN (MAX_LONG_LEN * 2)</font>
01026 <font class="preprocessor"></font>  <font class="keywordtype">int</font> orig_len;
01027   <font class="keywordtype">int</font> i;
01028   <font class="keywordtype">char</font> *buf;
01029   
01030   orig_len = _dbus_string_get_length (str);
01031 
01032   <font class="keywordflow">if</font> (!_dbus_string_lengthen (str, MAX_ULONG_LEN))
01033     <font class="keywordflow">return</font> FALSE;
01034 
01035   buf = _dbus_string_get_data_len (str, orig_len, MAX_ULONG_LEN);
01036 
01037   snprintf (buf, MAX_ULONG_LEN, <font class="stringliteral">"%lu"</font>, value);
01038 
01039   i = 0;
01040   <font class="keywordflow">while</font> (*buf)
01041     {
01042       ++buf;
01043       ++i;
01044     }
01045   
01046   _dbus_string_shorten (str, MAX_ULONG_LEN - i);
01047   
01048   <font class="keywordflow">return</font> TRUE;
01049 }
01050 
01058 dbus_bool_t
<a name="l01059"></a><a class="code" href="group__DBusString.html#a27">01059</a> _dbus_string_append_double (<a class="code" href="structDBusString.html">DBusString</a> *str,
01060                             <font class="keywordtype">double</font>      value)
01061 {
01062 <font class="preprocessor">#define MAX_DOUBLE_LEN 64 </font><font class="comment">/* this is completely made up :-/ */</font>
01063   <font class="keywordtype">int</font> orig_len;
01064   <font class="keywordtype">char</font> *buf;
01065   <font class="keywordtype">int</font> i;
01066   
01067   orig_len = _dbus_string_get_length (str);
01068 
01069   <font class="keywordflow">if</font> (!_dbus_string_lengthen (str, MAX_DOUBLE_LEN))
01070     <font class="keywordflow">return</font> FALSE;
01071 
01072   buf = _dbus_string_get_data_len (str, orig_len, MAX_DOUBLE_LEN);
01073 
01074   snprintf (buf, MAX_LONG_LEN, <font class="stringliteral">"%g"</font>, value);
01075 
01076   i = 0;
01077   <font class="keywordflow">while</font> (*buf)
01078     {
01079       ++buf;
01080       ++i;
01081     }
01082   
01083   _dbus_string_shorten (str, MAX_DOUBLE_LEN - i);
01084   
01085   <font class="keywordflow">return</font> TRUE;
01086 }
01087 
01100 dbus_bool_t
<a name="l01101"></a><a class="code" href="group__DBusString.html#a28">01101</a> _dbus_string_parse_int (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *str,
01102                         <font class="keywordtype">int</font>               start,
01103                         <font class="keywordtype">long</font>             *value_return,
01104                         <font class="keywordtype">int</font>              *end_return)
01105 {
01106   <font class="keywordtype">long</font> v;
01107   <font class="keyword">const</font> <font class="keywordtype">char</font> *p;
01108   <font class="keywordtype">char</font> *end;
01109 
01110   p = _dbus_string_get_const_data_len (str, start,
01111                                        _dbus_string_get_length (str) - start);
01112 
01113   end = NULL;
01114   errno = 0;
01115   v = strtol (p, &amp;end, 0);
01116   <font class="keywordflow">if</font> (end == NULL || end == p || errno != 0)
01117     <font class="keywordflow">return</font> FALSE;
01118 
01119   <font class="keywordflow">if</font> (value_return)
01120     *value_return = v;
01121   <font class="keywordflow">if</font> (end_return)
01122     *end_return = start + (end - p);
01123 
01124   <font class="keywordflow">return</font> TRUE;
01125 }
01126 
01127 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font>
01128 <font class="preprocessor"></font><font class="comment">/* Not currently used, so only built when tests are enabled */</font>
01141 dbus_bool_t
<a name="l01142"></a><a class="code" href="group__DBusString.html#a29">01142</a> _dbus_string_parse_uint (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *str,
01143                          <font class="keywordtype">int</font>               start,
01144                          <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font>    *value_return,
01145                          <font class="keywordtype">int</font>              *end_return)
01146 {
01147   <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> v;
01148   <font class="keyword">const</font> <font class="keywordtype">char</font> *p;
01149   <font class="keywordtype">char</font> *end;
01150 
01151   p = _dbus_string_get_const_data_len (str, start,
01152                                        _dbus_string_get_length (str) - start);
01153 
01154   end = NULL;
01155   errno = 0;
01156   v = strtoul (p, &amp;end, 0);
01157   <font class="keywordflow">if</font> (end == NULL || end == p || errno != 0)
01158     <font class="keywordflow">return</font> FALSE;
01159 
01160   <font class="keywordflow">if</font> (value_return)
01161     *value_return = v;
01162   <font class="keywordflow">if</font> (end_return)
01163     *end_return = start + (end - p);
01164 
01165   <font class="keywordflow">return</font> TRUE;
01166 }
01167 <font class="preprocessor">#endif </font><font class="comment">/* DBUS_BUILD_TESTS */</font>
01168 
01169 <font class="keyword">static</font> dbus_bool_t
01170 ascii_isspace (<font class="keywordtype">char</font> c)
01171 {
01172   <font class="keywordflow">return</font> (c == <font class="charliteral">' '</font> ||
01173           c == <font class="charliteral">'\f'</font> ||
01174           c == <font class="charliteral">'\n'</font> ||
01175           c == <font class="charliteral">'\r'</font> ||
01176           c == <font class="charliteral">'\t'</font> ||
01177           c == <font class="charliteral">'\v'</font>);
01178 }
01179 
01180 <font class="keyword">static</font> dbus_bool_t
01181 ascii_isdigit (<font class="keywordtype">char</font> c)
01182 {
01183   <font class="keywordflow">return</font> c &gt;= <font class="charliteral">'0'</font> &amp;&amp; c &lt;= <font class="charliteral">'9'</font>;
01184 }
01185 
01186 <font class="keyword">static</font> dbus_bool_t
01187 ascii_isxdigit (<font class="keywordtype">char</font> c)
01188 {
01189   <font class="keywordflow">return</font> (ascii_isdigit (c) ||
01190           (c &gt;= <font class="charliteral">'a'</font> &amp;&amp; c &lt;= <font class="charliteral">'f'</font>) ||
01191           (c &gt;= <font class="charliteral">'A'</font> &amp;&amp; c &lt;= <font class="charliteral">'F'</font>));
01192 }
01193 
01194 
01195 <font class="comment">/* Calls strtod in a locale-independent fashion, by looking at</font>
01196 <font class="comment"> * the locale data and patching the decimal comma to a point.</font>
01197 <font class="comment"> *</font>
01198 <font class="comment"> * Relicensed from glib.</font>
01199 <font class="comment"> */</font>
01200 <font class="keyword">static</font> <font class="keywordtype">double</font>
01201 ascii_strtod (<font class="keyword">const</font> <font class="keywordtype">char</font> *nptr,
01202               <font class="keywordtype">char</font>      **endptr)
01203 {
01204   <font class="keywordtype">char</font> *fail_pos;
01205   <font class="keywordtype">double</font> val;
01206   <font class="keyword">struct </font>lconv *locale_data;
01207   <font class="keyword">const</font> <font class="keywordtype">char</font> *decimal_point;
01208   <font class="keywordtype">int</font> decimal_point_len;
01209   <font class="keyword">const</font> <font class="keywordtype">char</font> *p, *decimal_point_pos;
01210   <font class="keyword">const</font> <font class="keywordtype">char</font> *end = NULL; <font class="comment">/* Silence gcc */</font>
01211 
01212   fail_pos = NULL;
01213 
01214   locale_data = localeconv ();
01215   decimal_point = locale_data-&gt;decimal_point;
01216   decimal_point_len = strlen (decimal_point);
01217 
01218   _dbus_assert (decimal_point_len != 0);
01219   
01220   decimal_point_pos = NULL;
01221   <font class="keywordflow">if</font> (decimal_point[0] != <font class="charliteral">'.'</font> ||
01222       decimal_point[1] != 0)
01223     {
01224       p = nptr;
01225       <font class="comment">/* Skip leading space */</font>
01226       <font class="keywordflow">while</font> (ascii_isspace (*p))
01227         p++;
01228       
01229       <font class="comment">/* Skip leading optional sign */</font>
01230       <font class="keywordflow">if</font> (*p == <font class="charliteral">'+'</font> || *p == <font class="charliteral">'-'</font>)
01231         p++;
01232       
01233       <font class="keywordflow">if</font> (p[0] == <font class="charliteral">'0'</font> &amp;&amp;
01234           (p[1] == <font class="charliteral">'x'</font> || p[1] == <font class="charliteral">'X'</font>))
01235         {
01236           p += 2;
01237           <font class="comment">/* HEX - find the (optional) decimal point */</font>
01238           
01239           <font class="keywordflow">while</font> (ascii_isxdigit (*p))
01240             p++;
01241           
01242           <font class="keywordflow">if</font> (*p == <font class="charliteral">'.'</font>)
01243             {
01244               decimal_point_pos = p++;
01245               
01246               <font class="keywordflow">while</font> (ascii_isxdigit (*p))
01247                 p++;
01248               
01249               <font class="keywordflow">if</font> (*p == <font class="charliteral">'p'</font> || *p == <font class="charliteral">'P'</font>)
01250                 p++;
01251               <font class="keywordflow">if</font> (*p == <font class="charliteral">'+'</font> || *p == <font class="charliteral">'-'</font>)
01252                 p++;
01253               <font class="keywordflow">while</font> (ascii_isdigit (*p))
01254                 p++;
01255               end = p;
01256             }
01257         }
01258       <font class="keywordflow">else</font>
01259         {
01260           <font class="keywordflow">while</font> (ascii_isdigit (*p))
01261             p++;
01262           
01263           <font class="keywordflow">if</font> (*p == <font class="charliteral">'.'</font>)
01264             {
01265               decimal_point_pos = p++;
01266               
01267               <font class="keywordflow">while</font> (ascii_isdigit (*p))
01268                 p++;
01269               
01270               <font class="keywordflow">if</font> (*p == <font class="charliteral">'e'</font> || *p == <font class="charliteral">'E'</font>)
01271                 p++;
01272               <font class="keywordflow">if</font> (*p == <font class="charliteral">'+'</font> || *p == <font class="charliteral">'-'</font>)
01273                 p++;
01274               <font class="keywordflow">while</font> (ascii_isdigit (*p))
01275                 p++;
01276               end = p;
01277             }
01278         }
01279       <font class="comment">/* For the other cases, we need not convert the decimal point */</font>
01280     }
01281 
01282   <font class="comment">/* Set errno to zero, so that we can distinguish zero results</font>
01283 <font class="comment">     and underflows */</font>
01284   errno = 0;
01285   
01286   <font class="keywordflow">if</font> (decimal_point_pos)
01287     {
01288       <font class="keywordtype">char</font> *copy, *c;
01289 
01290       <font class="comment">/* We need to convert the '.' to the locale specific decimal point */</font>
01291       copy = dbus_malloc (end - nptr + 1 + decimal_point_len);
01292       
01293       c = copy;
01294       memcpy (c, nptr, decimal_point_pos - nptr);
01295       c += decimal_point_pos - nptr;
01296       memcpy (c, decimal_point, decimal_point_len);
01297       c += decimal_point_len;
01298       memcpy (c, decimal_point_pos + 1, end - (decimal_point_pos + 1));
01299       c += end - (decimal_point_pos + 1);
01300       *c = 0;
01301 
01302       val = strtod (copy, &amp;fail_pos);
01303 
01304       <font class="keywordflow">if</font> (fail_pos)
01305         {
01306           <font class="keywordflow">if</font> (fail_pos &gt; decimal_point_pos)
01307             fail_pos = (<font class="keywordtype">char</font> *)nptr + (fail_pos - copy) - (decimal_point_len - 1);
01308           <font class="keywordflow">else</font>
01309             fail_pos = (<font class="keywordtype">char</font> *)nptr + (fail_pos - copy);
01310         }
01311       
01312       dbus_free (copy);
01313           
01314     }
01315   <font class="keywordflow">else</font>
01316     val = strtod (nptr, &amp;fail_pos);
01317 
01318   <font class="keywordflow">if</font> (endptr)
01319     *endptr = fail_pos;
01320   
01321   <font class="keywordflow">return</font> val;
01322 }
01323 
01324 
01337 dbus_bool_t
<a name="l01338"></a><a class="code" href="group__DBusString.html#a34">01338</a> _dbus_string_parse_double (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *str,
01339                            <font class="keywordtype">int</font>               start,
01340                            <font class="keywordtype">double</font>           *value_return,
01341                            <font class="keywordtype">int</font>              *end_return)
01342 {
01343   <font class="keywordtype">double</font> v;
01344   <font class="keyword">const</font> <font class="keywordtype">char</font> *p;
01345   <font class="keywordtype">char</font> *end;
01346 
01347   p = _dbus_string_get_const_data_len (str, start,
01348                                        _dbus_string_get_length (str) - start);
01349 
01350   end = NULL;
01351   errno = 0;
01352   v = ascii_strtod (p, &amp;end);
01353   <font class="keywordflow">if</font> (end == NULL || end == p || errno != 0)
01354     <font class="keywordflow">return</font> FALSE;
01355 
01356   <font class="keywordflow">if</font> (value_return)
01357     *value_return = v;
01358   <font class="keywordflow">if</font> (end_return)
01359     *end_return = start + (end - p);
01360 
01361   <font class="keywordflow">return</font> TRUE;
01362 }
01363  <font class="comment">/* DBusString group */</font>
01365 
01370 <font class="keyword">static</font> dbus_bool_t
01371 fill_user_info_from_passwd (<font class="keyword">struct</font> passwd *p,
01372                             <a class="code" href="structDBusUserInfo.html">DBusUserInfo</a>  *info,
01373                             <a class="code" href="structDBusError.html">DBusError</a>     *error)
01374 {
01375   _dbus_assert (p-&gt;pw_name != NULL);
01376   _dbus_assert (p-&gt;pw_dir != NULL);
01377   
01378   info-&gt;<a class="code" href="structDBusUserInfo.html#m0">uid</a> = p-&gt;pw_uid;
01379   info-&gt;<a class="code" href="structDBusUserInfo.html#m1">primary_gid</a> = p-&gt;pw_gid;
01380   info-&gt;<a class="code" href="structDBusUserInfo.html#m4">username</a> = _dbus_strdup (p-&gt;pw_name);
01381   info-&gt;<a class="code" href="structDBusUserInfo.html#m5">homedir</a> = _dbus_strdup (p-&gt;pw_dir);
01382   
01383   <font class="keywordflow">if</font> (info-&gt;<a class="code" href="structDBusUserInfo.html#m4">username</a> == NULL ||
01384       info-&gt;<a class="code" href="structDBusUserInfo.html#m5">homedir</a> == NULL)
01385     {
01386       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01387       <font class="keywordflow">return</font> FALSE;
01388     }
01389 
01390   <font class="keywordflow">return</font> TRUE;
01391 }
01392 
01393 <font class="keyword">static</font> dbus_bool_t
01394 fill_user_info (<a class="code" href="structDBusUserInfo.html">DBusUserInfo</a>       *info,
01395                 dbus_uid_t          uid,
01396                 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a>   *username,
01397                 <a class="code" href="structDBusError.html">DBusError</a>          *error)
01398 {
01399   <font class="keyword">const</font> <font class="keywordtype">char</font> *username_c;
01400   
01401   <font class="comment">/* exactly one of username/uid provided */</font>
01402   _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
01403   _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
01404 
01405   info-&gt;<a class="code" href="structDBusUserInfo.html#m0">uid</a> = DBUS_UID_UNSET;
01406   info-&gt;<a class="code" href="structDBusUserInfo.html#m1">primary_gid</a> = DBUS_GID_UNSET;
01407   info-&gt;<a class="code" href="structDBusUserInfo.html#m2">group_ids</a> = NULL;
01408   info-&gt;<a class="code" href="structDBusUserInfo.html#m3">n_group_ids</a> = 0;
01409   info-&gt;<a class="code" href="structDBusUserInfo.html#m4">username</a> = NULL;
01410   info-&gt;<a class="code" href="structDBusUserInfo.html#m5">homedir</a> = NULL;
01411   
01412   <font class="keywordflow">if</font> (username != NULL)
01413     username_c = _dbus_string_get_const_data (username);
01414   <font class="keywordflow">else</font>
01415     username_c = NULL;
01416 
01417   <font class="comment">/* For now assuming that the getpwnam() and getpwuid() flavors</font>
01418 <font class="comment">   * are always symmetrical, if not we have to add more configure</font>
01419 <font class="comment">   * checks</font>
01420 <font class="comment">   */</font>
01421   
01422 <font class="preprocessor">#if defined (HAVE_POSIX_GETPWNAME_R) || defined (HAVE_NONPOSIX_GETPWNAME_R)</font>
01423 <font class="preprocessor"></font>  {
01424     <font class="keyword">struct </font>passwd *p;
01425     <font class="keywordtype">int</font> result;
01426     <font class="keywordtype">char</font> buf[1024];
01427     <font class="keyword">struct </font>passwd p_str;
01428 
01429     p = NULL;
01430 <font class="preprocessor">#ifdef HAVE_POSIX_GETPWNAME_R</font>
01431 <font class="preprocessor"></font>    <font class="keywordflow">if</font> (uid &gt;= 0)
01432       result = getpwuid_r (uid, &amp;p_str, buf, <font class="keyword">sizeof</font> (buf),
01433                            &amp;p);
01434     <font class="keywordflow">else</font>
01435       result = getpwnam_r (username_c, &amp;p_str, buf, <font class="keyword">sizeof</font> (buf),
01436                            &amp;p);
01437 <font class="preprocessor">#else</font>
01438 <font class="preprocessor"></font>    <font class="keywordflow">if</font> (uid != DBUS_UID_UNSET)
01439       p = getpwuid_r (uid, &amp;p_str, buf, <font class="keyword">sizeof</font> (buf));
01440     <font class="keywordflow">else</font>
01441       p = getpwnam_r (username_c, &amp;p_str, buf, <font class="keyword">sizeof</font> (buf));
01442     result = 0;
01443 <font class="preprocessor">#endif </font><font class="comment">/* !HAVE_POSIX_GETPWNAME_R */</font>
01444     <font class="keywordflow">if</font> (result == 0 &amp;&amp; p == &amp;p_str)
01445       {
01446         <font class="keywordflow">if</font> (!fill_user_info_from_passwd (p, info, error))
01447           <font class="keywordflow">return</font> FALSE;
01448       }
01449     <font class="keywordflow">else</font>
01450       {
01451         dbus_set_error (error, _dbus_error_from_errno (errno),
01452                         <font class="stringliteral">"User \"%s\" unknown or no memory to allocate password entry\n"</font>,
01453                         username_c ? username_c : <font class="stringliteral">"???"</font>);
01454         _dbus_verbose (<font class="stringliteral">"User %s unknown\n"</font>, username_c ? username_c : <font class="stringliteral">"???"</font>);
01455         <font class="keywordflow">return</font> FALSE;
01456       }
01457   }
01458 <font class="preprocessor">#else </font><font class="comment">/* ! HAVE_GETPWNAM_R */</font>
01459   {
01460     <font class="comment">/* I guess we're screwed on thread safety here */</font>
01461     <font class="keyword">struct </font>passwd *p;
01462 
01463     <font class="keywordflow">if</font> (uid != DBUS_UID_UNSET)
01464       p = getpwuid (uid);
01465     <font class="keywordflow">else</font>
01466       p = getpwnam (username_c);
01467 
01468     <font class="keywordflow">if</font> (p != NULL)
01469       {
01470         <font class="keywordflow">if</font> (!fill_user_info_from_passwd (p, info, error))
01471           <font class="keywordflow">return</font> FALSE;
01472       }
01473     <font class="keywordflow">else</font>
01474       {
01475         dbus_set_error (error, _dbus_error_from_errno (errno),
01476                         <font class="stringliteral">"User \"%s\" unknown or no memory to allocate password entry\n"</font>,
01477                         username_c ? username_c : <font class="stringliteral">"???"</font>);
01478         _dbus_verbose (<font class="stringliteral">"User %s unknown\n"</font>, username_c ? username_c : <font class="stringliteral">"???"</font>);
01479         <font class="keywordflow">return</font> FALSE;
01480       }
01481   }
01482 <font class="preprocessor">#endif  </font><font class="comment">/* ! HAVE_GETPWNAM_R */</font>
01483 
01484   <font class="comment">/* Fill this in so we can use it to get groups */</font>
01485   username_c = info-&gt;<a class="code" href="structDBusUserInfo.html#m4">username</a>;
01486   
01487 <font class="preprocessor">#ifdef HAVE_GETGROUPLIST</font>
01488 <font class="preprocessor"></font>  {
01489     gid_t *buf;
01490     <font class="keywordtype">int</font> buf_count;
01491     <font class="keywordtype">int</font> i;
01492     
01493     buf_count = 17;
01494     buf = dbus_new (gid_t, buf_count);
01495     <font class="keywordflow">if</font> (buf == NULL)
01496       {
01497         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01498         <font class="keywordflow">goto</font> failed;
01499       }
01500     
01501     <font class="keywordflow">if</font> (getgrouplist (username_c,
01502                       info-&gt;<a class="code" href="structDBusUserInfo.html#m1">primary_gid</a>,
01503                       buf, &amp;buf_count) &lt; 0)
01504       {
01505         gid_t *<font class="keyword">new</font> = dbus_realloc (buf, buf_count * <font class="keyword">sizeof</font> (buf[0]));
01506         <font class="keywordflow">if</font> (<font class="keyword">new</font> == NULL)
01507           {
01508             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01509             dbus_free (buf);
01510             <font class="keywordflow">goto</font> failed;
01511           }
01512         
01513         buf = <font class="keyword">new</font>;
01514 
01515         errno = 0;
01516         <font class="keywordflow">if</font> (getgrouplist (username_c, info-&gt;<a class="code" href="structDBusUserInfo.html#m1">primary_gid</a>, buf, &amp;buf_count) &lt; 0)
01517           {
01518             dbus_set_error (error,
01519                             _dbus_error_from_errno (errno),
01520                             <font class="stringliteral">"Failed to get groups for username \"%s\" primary GID "</font>
01521                             DBUS_GID_FORMAT <font class="stringliteral">": %s\n"</font>,
01522                             username_c, info-&gt;<a class="code" href="structDBusUserInfo.html#m1">primary_gid</a>,
01523                             _dbus_strerror (errno));
01524             dbus_free (buf);
01525             <font class="keywordflow">goto</font> failed;
01526           }
01527       }
01528 
01529     info-&gt;<a class="code" href="structDBusUserInfo.html#m2">group_ids</a> = dbus_new (dbus_gid_t, buf_count);
01530     <font class="keywordflow">if</font> (info-&gt;<a class="code" href="structDBusUserInfo.html#m2">group_ids</a> == NULL)
01531       {
01532         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01533         dbus_free (buf);
01534         <font class="keywordflow">goto</font> failed;
01535       }
01536     
01537     <font class="keywordflow">for</font> (i = 0; i &lt; buf_count; ++i)
01538       info-&gt;<a class="code" href="structDBusUserInfo.html#m2">group_ids</a>[i] = buf[i];
01539 
01540     info-&gt;<a class="code" href="structDBusUserInfo.html#m3">n_group_ids</a> = buf_count;
01541     
01542     dbus_free (buf);
01543   }
01544 <font class="preprocessor">#else  </font><font class="comment">/* HAVE_GETGROUPLIST */</font>
01545   {
01546     <font class="comment">/* We just get the one group ID */</font>
01547     info-&gt;<a class="code" href="structDBusUserInfo.html#m2">group_ids</a> = dbus_new (dbus_gid_t, 1);
01548     <font class="keywordflow">if</font> (info-&gt;<a class="code" href="structDBusUserInfo.html#m2">group_ids</a> == NULL)
01549       {
01550         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01551         <font class="keywordflow">goto</font> out;
01552       }
01553 
01554     info-&gt;<a class="code" href="structDBusUserInfo.html#m3">n_group_ids</a> = 1;
01555 
01556     (info-&gt;<a class="code" href="structDBusUserInfo.html#m2">group_ids</a>)[0] = info-&gt;<a class="code" href="structDBusUserInfo.html#m1">primary_gid</a>;
01557   }
01558 <font class="preprocessor">#endif </font><font class="comment">/* HAVE_GETGROUPLIST */</font>
01559 
01560   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01561   
01562   <font class="keywordflow">return</font> TRUE;
01563   
01564  failed:
01565   _DBUS_ASSERT_ERROR_IS_SET (error);
01566   _dbus_user_info_free (info);
01567   <font class="keywordflow">return</font> FALSE;
01568 }
01569 
01578 dbus_bool_t
<a name="l01579"></a><a class="code" href="group__DBusInternalsUtils.html#a60">01579</a> _dbus_user_info_fill (<a class="code" href="structDBusUserInfo.html">DBusUserInfo</a>     *info,
01580                       <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *username,
01581                       <a class="code" href="structDBusError.html">DBusError</a>        *error)
01582 {
01583   <font class="keywordflow">return</font> fill_user_info (info, DBUS_UID_UNSET,
01584                          username, error);
01585 }
01586 
01595 dbus_bool_t
<a name="l01596"></a><a class="code" href="group__DBusInternalsUtils.html#a61">01596</a> _dbus_user_info_fill_uid (<a class="code" href="structDBusUserInfo.html">DBusUserInfo</a> *info,
01597                           dbus_uid_t    uid,
01598                           <a class="code" href="structDBusError.html">DBusError</a>    *error)
01599 {
01600   <font class="keywordflow">return</font> fill_user_info (info, uid,
01601                          NULL, error);
01602 }
01603 
01609 <font class="keywordtype">void</font>
<a name="l01610"></a><a class="code" href="group__DBusInternalsUtils.html#a62">01610</a> _dbus_user_info_free (<a class="code" href="structDBusUserInfo.html">DBusUserInfo</a> *info)
01611 {
01612   dbus_free (info-&gt;<a class="code" href="structDBusUserInfo.html#m2">group_ids</a>);
01613   dbus_free (info-&gt;<a class="code" href="structDBusUserInfo.html#m4">username</a>);
01614   dbus_free (info-&gt;<a class="code" href="structDBusUserInfo.html#m5">homedir</a>);
01615 }
01616 
01617 <font class="keyword">static</font> dbus_bool_t
01618 fill_user_info_from_group (<font class="keyword">struct</font> group  *g,
01619                            <a class="code" href="structDBusGroupInfo.html">DBusGroupInfo</a> *info,
01620                            <a class="code" href="structDBusError.html">DBusError</a>     *error)
01621 {
01622   _dbus_assert (g-&gt;gr_name != NULL);
01623   
01624   info-&gt;<a class="code" href="structDBusGroupInfo.html#m0">gid</a> = g-&gt;gr_gid;
01625   info-&gt;<a class="code" href="structDBusGroupInfo.html#m1">groupname</a> = _dbus_strdup (g-&gt;gr_name);
01626 
01627   <font class="comment">/* info-&gt;members = dbus_strdupv (g-&gt;gr_mem) */</font>
01628   
01629   <font class="keywordflow">if</font> (info-&gt;<a class="code" href="structDBusGroupInfo.html#m1">groupname</a> == NULL)
01630     {
01631       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01632       <font class="keywordflow">return</font> FALSE;
01633     }
01634 
01635   <font class="keywordflow">return</font> TRUE;
01636 }
01637 
01638 <font class="keyword">static</font> dbus_bool_t
01639 fill_group_info (<a class="code" href="structDBusGroupInfo.html">DBusGroupInfo</a>    *info,
01640                  dbus_gid_t        gid,
01641                  <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *groupname,
01642                  <a class="code" href="structDBusError.html">DBusError</a>        *error)
01643 {
01644   <font class="keyword">const</font> <font class="keywordtype">char</font> *group_c_str;
01645 
01646   _dbus_assert (groupname != NULL || gid != DBUS_GID_UNSET);
01647   _dbus_assert (groupname == NULL || gid == DBUS_GID_UNSET);
01648 
01649   <font class="keywordflow">if</font> (groupname)
01650     group_c_str = _dbus_string_get_const_data (groupname);
01651   <font class="keywordflow">else</font>
01652     group_c_str = NULL;
01653   
01654   <font class="comment">/* For now assuming that the getgrnam() and getgrgid() flavors</font>
01655 <font class="comment">   * always correspond to the pwnam flavors, if not we have</font>
01656 <font class="comment">   * to add more configure checks.</font>
01657 <font class="comment">   */</font>
01658   
01659 <font class="preprocessor">#if defined (HAVE_POSIX_GETPWNAME_R) || defined (HAVE_NONPOSIX_GETPWNAME_R)</font>
01660 <font class="preprocessor"></font>  {
01661     <font class="keyword">struct </font>group *g;
01662     <font class="keywordtype">int</font> result;
01663     <font class="keywordtype">char</font> buf[1024];
01664     <font class="keyword">struct </font>group g_str;
01665 
01666     g = NULL;
01667 <font class="preprocessor">#ifdef HAVE_POSIX_GETPWNAME_R</font>
01668 <font class="preprocessor"></font>
01669     <font class="keywordflow">if</font> (group_c_str)
01670       result = getgrnam_r (group_c_str, &amp;g_str, buf, <font class="keyword">sizeof</font> (buf),
01671                            &amp;g);
01672     <font class="keywordflow">else</font>
01673       result = getgrgid_r (gid, &amp;g_str, buf, <font class="keyword">sizeof</font> (buf),
01674                            &amp;g);
01675 <font class="preprocessor">#else</font>
01676 <font class="preprocessor"></font>    p = getgrnam_r (group_c_str, &amp;g_str, buf, <font class="keyword">sizeof</font> (buf));
01677     result = 0;
01678 <font class="preprocessor">#endif </font><font class="comment">/* !HAVE_POSIX_GETPWNAME_R */</font>
01679     <font class="keywordflow">if</font> (result == 0 &amp;&amp; g == &amp;g_str)
01680       {
01681         <font class="keywordflow">return</font> fill_user_info_from_group (g, info, error);
01682       }
01683     <font class="keywordflow">else</font>
01684       {
01685         dbus_set_error (error, _dbus_error_from_errno (errno),
01686                         <font class="stringliteral">"Group %s unknown or failed to look it up\n"</font>,
01687                         group_c_str ? group_c_str : <font class="stringliteral">"???"</font>);
01688         <font class="keywordflow">return</font> FALSE;
01689       }
01690   }
01691 <font class="preprocessor">#else </font><font class="comment">/* ! HAVE_GETPWNAM_R */</font>
01692   {
01693     <font class="comment">/* I guess we're screwed on thread safety here */</font>
01694     <font class="keyword">struct </font>group *g;
01695 
01696     g = getgrnam (group_c_str);
01697 
01698     <font class="keywordflow">if</font> (g != NULL)
01699       {
01700         <font class="keywordflow">return</font> fill_user_info_from_group (g, info, error);
01701       }
01702     <font class="keywordflow">else</font>
01703       {
01704         dbus_set_error (error, _dbus_error_from_errno (errno),
01705                         <font class="stringliteral">"Group %s unknown or failed to look it up\n"</font>,
01706                         group_c_str ? group_c_str : <font class="stringliteral">"???"</font>);
01707         <font class="keywordflow">return</font> FALSE;
01708       }
01709   }
01710 <font class="preprocessor">#endif  </font><font class="comment">/* ! HAVE_GETPWNAM_R */</font>
01711 }
01712 
01722 dbus_bool_t
<a name="l01723"></a><a class="code" href="group__DBusInternalsUtils.html#a65">01723</a> _dbus_group_info_fill (<a class="code" href="structDBusGroupInfo.html">DBusGroupInfo</a>    *info,
01724                        <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *groupname,
01725                        <a class="code" href="structDBusError.html">DBusError</a>        *error)
01726 {
01727   <font class="keywordflow">return</font> fill_group_info (info, DBUS_GID_UNSET,
01728                           groupname, error);
01729 
01730 }
01731 
01741 dbus_bool_t
<a name="l01742"></a><a class="code" href="group__DBusInternalsUtils.html#a66">01742</a> _dbus_group_info_fill_gid (<a class="code" href="structDBusGroupInfo.html">DBusGroupInfo</a> *info,
01743                            dbus_gid_t     gid,
01744                            <a class="code" href="structDBusError.html">DBusError</a>     *error)
01745 {
01746   <font class="keywordflow">return</font> fill_group_info (info, gid, NULL, error);
01747 }
01748 
01754 <font class="keywordtype">void</font>
<a name="l01755"></a><a class="code" href="group__DBusInternalsUtils.html#a67">01755</a> _dbus_group_info_free (<a class="code" href="structDBusGroupInfo.html">DBusGroupInfo</a>    *info)
01756 {
01757   dbus_free (info-&gt;<a class="code" href="structDBusGroupInfo.html#m1">groupname</a>);
01758 }
01759 
01766 <font class="keywordtype">void</font>
<a name="l01767"></a><a class="code" href="group__DBusInternalsUtils.html#a68">01767</a> _dbus_credentials_clear (<a class="code" href="structDBusCredentials.html">DBusCredentials</a> *credentials)
01768 {
01769   credentials-&gt;<a class="code" href="structDBusCredentials.html#m0">pid</a> = DBUS_PID_UNSET;
01770   credentials-&gt;<a class="code" href="structDBusCredentials.html#m1">uid</a> = DBUS_UID_UNSET;
01771   credentials-&gt;<a class="code" href="structDBusCredentials.html#m2">gid</a> = DBUS_GID_UNSET;
01772 }
01773 
01779 <font class="keywordtype">void</font>
<a name="l01780"></a><a class="code" href="group__DBusInternalsUtils.html#a69">01780</a> _dbus_credentials_from_current_process (<a class="code" href="structDBusCredentials.html">DBusCredentials</a> *credentials)
01781 {
01782   <font class="comment">/* The POSIX spec certainly doesn't promise this, but</font>
01783 <font class="comment">   * we need these assertions to fail as soon as we're wrong about</font>
01784 <font class="comment">   * it so we can do the porting fixups</font>
01785 <font class="comment">   */</font>
01786   _dbus_assert (<font class="keyword">sizeof</font> (pid_t) &lt;= <font class="keyword">sizeof</font> (credentials-&gt;<a class="code" href="structDBusCredentials.html#m0">pid</a>));
01787   _dbus_assert (<font class="keyword">sizeof</font> (uid_t) &lt;= <font class="keyword">sizeof</font> (credentials-&gt;<a class="code" href="structDBusCredentials.html#m1">uid</a>));
01788   _dbus_assert (<font class="keyword">sizeof</font> (gid_t) &lt;= <font class="keyword">sizeof</font> (credentials-&gt;<a class="code" href="structDBusCredentials.html#m2">gid</a>));
01789   
01790   credentials-&gt;<a class="code" href="structDBusCredentials.html#m0">pid</a> = getpid ();
01791   credentials-&gt;<a class="code" href="structDBusCredentials.html#m1">uid</a> = getuid ();
01792   credentials-&gt;<a class="code" href="structDBusCredentials.html#m2">gid</a> = getgid ();
01793 }
01794 
01803 dbus_bool_t
<a name="l01804"></a><a class="code" href="group__DBusInternalsUtils.html#a70">01804</a> _dbus_credentials_match (<font class="keyword">const</font> <a class="code" href="structDBusCredentials.html">DBusCredentials</a> *expected_credentials,
01805                          <font class="keyword">const</font> <a class="code" href="structDBusCredentials.html">DBusCredentials</a> *provided_credentials)
01806 {
01807   <font class="keywordflow">if</font> (provided_credentials-&gt;<a class="code" href="structDBusCredentials.html#m1">uid</a> == DBUS_UID_UNSET)
01808     <font class="keywordflow">return</font> FALSE;
01809   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (expected_credentials-&gt;<a class="code" href="structDBusCredentials.html#m1">uid</a> == DBUS_UID_UNSET)
01810     <font class="keywordflow">return</font> FALSE;
01811   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (provided_credentials-&gt;<a class="code" href="structDBusCredentials.html#m1">uid</a> == 0)
01812     <font class="keywordflow">return</font> TRUE;
01813   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (provided_credentials-&gt;<a class="code" href="structDBusCredentials.html#m1">uid</a> == expected_credentials-&gt;<a class="code" href="structDBusCredentials.html#m1">uid</a>)
01814     <font class="keywordflow">return</font> TRUE;
01815   <font class="keywordflow">else</font>
01816     <font class="keywordflow">return</font> FALSE;
01817 }
01818 
01823 <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font>
<a name="l01824"></a><a class="code" href="group__DBusInternalsUtils.html#a71">01824</a> _dbus_getpid (<font class="keywordtype">void</font>)
01825 {
01826   <font class="keywordflow">return</font> getpid ();
01827 }
01828 
01832 dbus_uid_t
<a name="l01833"></a><a class="code" href="group__DBusInternalsUtils.html#a72">01833</a> _dbus_getuid (<font class="keywordtype">void</font>)
01834 {
01835   <font class="keywordflow">return</font> getuid ();
01836 }
01837 
01841 dbus_gid_t
<a name="l01842"></a><a class="code" href="group__DBusInternalsUtils.html#a73">01842</a> _dbus_getgid (<font class="keywordtype">void</font>)
01843 {
01844   <font class="keywordflow">return</font> getgid ();
01845 }
01846 
01847 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
01848 
01849 <font class="preprocessor">#ifdef DBUS_USE_ATOMIC_INT_486</font>
01850 <font class="preprocessor"></font><font class="comment">/* Taken from CVS version 1.7 of glibc's sysdeps/i386/i486/atomicity.h */</font>
01851 <font class="comment">/* Since the asm stuff here is gcc-specific we go ahead and use "inline" also */</font>
01852 <font class="keyword">static</font> <font class="keyword">inline</font> dbus_int32_t
01853 atomic_exchange_and_add (<a class="code" href="structDBusAtomic.html">DBusAtomic</a>            *atomic,
01854                          <font class="keyword">volatile</font> dbus_int32_t  val)
01855 {
01856   <font class="keyword">register</font> dbus_int32_t result;
01857 
01858   __asm__ __volatile__ (<font class="stringliteral">"lock; xaddl %0,%1"</font>
01859                         : <font class="stringliteral">"=r"</font> (result), <font class="stringliteral">"=m"</font> (atomic-&gt;<a class="code" href="structDBusAtomic.html#m0">value</a>)
01860                         : "0" (val), "m" (atomic-&gt;value));
01861   <font class="keywordflow">return</font> result;
01862 }
01863 <font class="preprocessor">#endif</font>
01864 <font class="preprocessor"></font>
01873 dbus_int32_t
<a name="l01874"></a><a class="code" href="group__DBusInternalsUtils.html#a75">01874</a> _dbus_atomic_inc (<a class="code" href="structDBusAtomic.html">DBusAtomic</a> *atomic)
01875 {
01876 <font class="preprocessor">#ifdef DBUS_USE_ATOMIC_INT_486</font>
01877 <font class="preprocessor"></font>  <font class="keywordflow">return</font> atomic_exchange_and_add (atomic, 1);
01878 <font class="preprocessor">#else</font>
01879 <font class="preprocessor"></font>  dbus_int32_t res;
01880   _DBUS_LOCK (atomic);
01881   res = atomic-&gt;<a class="code" href="structDBusAtomic.html#m0">value</a>;
01882   atomic-&gt;<a class="code" href="structDBusAtomic.html#m0">value</a> += 1;
01883   _DBUS_UNLOCK (atomic);
01884   <font class="keywordflow">return</font> res;
01885 <font class="preprocessor">#endif</font>
01886 <font class="preprocessor"></font>}
01887 
01896 dbus_int32_t
<a name="l01897"></a><a class="code" href="group__DBusInternalsUtils.html#a76">01897</a> _dbus_atomic_dec (<a class="code" href="structDBusAtomic.html">DBusAtomic</a> *atomic)
01898 {
01899 <font class="preprocessor">#ifdef DBUS_USE_ATOMIC_INT_486</font>
01900 <font class="preprocessor"></font>  <font class="keywordflow">return</font> atomic_exchange_and_add (atomic, -1);
01901 <font class="preprocessor">#else</font>
01902 <font class="preprocessor"></font>  dbus_int32_t res;
01903   
01904   _DBUS_LOCK (atomic);
01905   res = atomic-&gt;<a class="code" href="structDBusAtomic.html#m0">value</a>;
01906   atomic-&gt;<a class="code" href="structDBusAtomic.html#m0">value</a> -= 1;
01907   _DBUS_UNLOCK (atomic);
01908   <font class="keywordflow">return</font> res;
01909 <font class="preprocessor">#endif</font>
01910 <font class="preprocessor"></font>}
01911 
01920 <font class="keywordtype">int</font>
<a name="l01921"></a><a class="code" href="group__DBusInternalsUtils.html#a77">01921</a> _dbus_poll (<a class="code" href="structDBusPollFD.html">DBusPollFD</a> *fds,
01922             <font class="keywordtype">int</font>         n_fds,
01923             <font class="keywordtype">int</font>         timeout_milliseconds)
01924 {
01925 <font class="preprocessor">#ifdef HAVE_POLL</font>
01926 <font class="preprocessor"></font>  <font class="comment">/* This big thing is a constant expression and should get optimized</font>
01927 <font class="comment">   * out of existence. So it's more robust than a configure check at</font>
01928 <font class="comment">   * no cost.</font>
01929 <font class="comment">   */</font>
01930   <font class="keywordflow">if</font> (_DBUS_POLLIN == POLLIN &amp;&amp;
01931       _DBUS_POLLPRI == POLLPRI &amp;&amp;
01932       _DBUS_POLLOUT == POLLOUT &amp;&amp;
01933       _DBUS_POLLERR == POLLERR &amp;&amp;
01934       _DBUS_POLLHUP == POLLHUP &amp;&amp;
01935       _DBUS_POLLNVAL == POLLNVAL &amp;&amp;
01936       <font class="keyword">sizeof</font> (DBusPollFD) == <font class="keyword">sizeof</font> (<font class="keyword">struct </font>pollfd) &amp;&amp;
01937       _DBUS_STRUCT_OFFSET (<a class="code" href="structDBusPollFD.html">DBusPollFD</a>, fd) ==
01938       _DBUS_STRUCT_OFFSET (<font class="keyword">struct</font> pollfd, fd) &amp;&amp;
01939       _DBUS_STRUCT_OFFSET (<a class="code" href="structDBusPollFD.html">DBusPollFD</a>, events) ==
01940       _DBUS_STRUCT_OFFSET (<font class="keyword">struct</font> pollfd, events) &amp;&amp;
01941       _DBUS_STRUCT_OFFSET (<a class="code" href="structDBusPollFD.html">DBusPollFD</a>, revents) ==
01942       _DBUS_STRUCT_OFFSET (<font class="keyword">struct</font> pollfd, revents))
01943     {
01944       <font class="keywordflow">return</font> poll ((<font class="keyword">struct</font> pollfd*) fds,
01945                    n_fds, 
01946                    timeout_milliseconds);
01947     }
01948   <font class="keywordflow">else</font>
01949     {
01950       <font class="comment">/* We have to convert the DBusPollFD to an array of</font>
01951 <font class="comment">       * struct pollfd, poll, and convert back.</font>
01952 <font class="comment">       */</font>
01953       _dbus_warn (<font class="stringliteral">"didn't implement poll() properly for this system yet\n"</font>);
01954       <font class="keywordflow">return</font> -1;
01955     }
01956 <font class="preprocessor">#else </font><font class="comment">/* ! HAVE_POLL */</font>
01957 
01958   fd_set read_set, write_set, err_set;
01959   <font class="keywordtype">int</font> max_fd = 0;
01960   <font class="keywordtype">int</font> i;
01961   <font class="keyword">struct </font>timeval tv;
01962   <font class="keywordtype">int</font> ready;
01963   
01964   FD_ZERO (&amp;read_set);
01965   FD_ZERO (&amp;write_set);
01966   FD_ZERO (&amp;err_set);
01967 
01968   <font class="keywordflow">for</font> (i = 0; i &lt; n_fds; i++)
01969     {
01970       <a class="code" href="structDBusPollFD.html">DBusPollFD</a> f = fds[i];
01971 
01972       <font class="keywordflow">if</font> (f.<a class="code" href="structDBusPollFD.html#m1">events</a> &amp; _DBUS_POLLIN)
01973         FD_SET (f.<a class="code" href="structDBusPollFD.html#m0">fd</a>, &amp;read_set);
01974 
01975       <font class="keywordflow">if</font> (f.<a class="code" href="structDBusPollFD.html#m1">events</a> &amp; _DBUS_POLLOUT)
01976         FD_SET (f.<a class="code" href="structDBusPollFD.html#m0">fd</a>, &amp;write_set);
01977 
01978       FD_SET (f.<a class="code" href="structDBusPollFD.html#m0">fd</a>, &amp;err_set);
01979 
01980       max_fd = MAX (max_fd, f.<a class="code" href="structDBusPollFD.html#m0">fd</a>);
01981     }
01982     
01983   tv.tv_sec = timeout_milliseconds / 1000;
01984   tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
01985 
01986   ready = select (max_fd + 1, &amp;read_set, &amp;write_set, &amp;err_set, &amp;tv);
01987 
01988   <font class="keywordflow">if</font> (ready &gt; 0)
01989     {
01990       <font class="keywordflow">for</font> (i = 0; i &lt; n_fds; i++)
01991         {
01992           <a class="code" href="structDBusPollFD.html">DBusPollFD</a> f = fds[i];
01993 
01994           f.<a class="code" href="structDBusPollFD.html#m2">revents</a> = 0;
01995 
01996           <font class="keywordflow">if</font> (FD_ISSET (f.<a class="code" href="structDBusPollFD.html#m0">fd</a>, &amp;read_set))
01997             f.<a class="code" href="structDBusPollFD.html#m2">revents</a> |= _DBUS_POLLIN;
01998 
01999           <font class="keywordflow">if</font> (FD_ISSET (f.<a class="code" href="structDBusPollFD.html#m0">fd</a>, &amp;write_set))
02000             f.<a class="code" href="structDBusPollFD.html#m2">revents</a> |= _DBUS_POLLOUT;
02001 
02002           <font class="keywordflow">if</font> (FD_ISSET (f.<a class="code" href="structDBusPollFD.html#m0">fd</a>, &amp;err_set))
02003             f.<a class="code" href="structDBusPollFD.html#m2">revents</a> |= _DBUS_POLLERR;
02004         }
02005     }
02006 
02007   <font class="keywordflow">return</font> ready;
02008 <font class="preprocessor">#endif</font>
02009 <font class="preprocessor"></font>}
02010 
<a name="l02012"></a><a class="code" href="group__DBusInternalsUtils.html#a148">02012</a> <font class="preprocessor">#define NANOSECONDS_PER_SECOND       1000000000</font>
02013 <font class="preprocessor"></font>
<a name="l02014"></a><a class="code" href="group__DBusInternalsUtils.html#a149">02014</a> <font class="preprocessor">#define MICROSECONDS_PER_SECOND      1000000</font>
02015 <font class="preprocessor"></font>
<a name="l02016"></a><a class="code" href="group__DBusInternalsUtils.html#a150">02016</a> <font class="preprocessor">#define MILLISECONDS_PER_SECOND      1000</font>
02017 <font class="preprocessor"></font>
<a name="l02018"></a><a class="code" href="group__DBusInternalsUtils.html#a151">02018</a> <font class="preprocessor">#define NANOSECONDS_PER_MILLISECOND  1000000</font>
02019 <font class="preprocessor"></font>
<a name="l02020"></a><a class="code" href="group__DBusInternalsUtils.html#a152">02020</a> <font class="preprocessor">#define MICROSECONDS_PER_MILLISECOND 1000</font>
02021 <font class="preprocessor"></font>
02026 <font class="keywordtype">void</font>
<a name="l02027"></a><a class="code" href="group__DBusInternalsUtils.html#a78">02027</a> _dbus_sleep_milliseconds (<font class="keywordtype">int</font> milliseconds)
02028 {
02029 <font class="preprocessor">#ifdef HAVE_NANOSLEEP</font>
02030 <font class="preprocessor"></font>  <font class="keyword">struct </font>timespec req;
02031   <font class="keyword">struct </font>timespec rem;
02032 
02033   req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
02034   req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
02035   rem.tv_sec = 0;
02036   rem.tv_nsec = 0;
02037 
02038   <font class="keywordflow">while</font> (nanosleep (&amp;req, &amp;rem) &lt; 0 &amp;&amp; errno == EINTR)
02039     req = rem;
02040 <font class="preprocessor">#elif defined (HAVE_USLEEP)</font>
02041 <font class="preprocessor"></font>  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
02042 <font class="preprocessor">#else </font><font class="comment">/* ! HAVE_USLEEP */</font>
02043   sleep (MAX (milliseconds / 1000, 1));
02044 <font class="preprocessor">#endif</font>
02045 <font class="preprocessor"></font>}
02046 
02053 <font class="keywordtype">void</font>
<a name="l02054"></a><a class="code" href="group__DBusInternalsUtils.html#a79">02054</a> _dbus_get_current_time (<font class="keywordtype">long</font> *tv_sec,
02055                         <font class="keywordtype">long</font> *tv_usec)
02056 {
02057   <font class="keyword">struct </font>timeval t;
02058 
02059   gettimeofday (&amp;t, NULL);
02060 
02061   <font class="keywordflow">if</font> (tv_sec)
02062     *tv_sec = t.tv_sec;
02063   <font class="keywordflow">if</font> (tv_usec)
02064     *tv_usec = t.tv_usec;
02065 }
02066 
02077 dbus_bool_t
<a name="l02078"></a><a class="code" href="group__DBusInternalsUtils.html#a80">02078</a> _dbus_file_get_contents (<a class="code" href="structDBusString.html">DBusString</a>       *str,
02079                          <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *filename,
02080                          <a class="code" href="structDBusError.html">DBusError</a>        *error)
02081 {
02082   <font class="keywordtype">int</font> fd;
02083   <font class="keyword">struct </font>stat sb;
02084   <font class="keywordtype">int</font> orig_len;
02085   <font class="keywordtype">int</font> total;
02086   <font class="keyword">const</font> <font class="keywordtype">char</font> *filename_c;
02087 
02088   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02089   
02090   filename_c = _dbus_string_get_const_data (filename);
02091   
02092   <font class="comment">/* O_BINARY useful on Cygwin */</font>
02093   fd = open (filename_c, O_RDONLY | O_BINARY);
02094   <font class="keywordflow">if</font> (fd &lt; 0)
02095     {
02096       dbus_set_error (error, _dbus_error_from_errno (errno),
02097                       <font class="stringliteral">"Failed to open \"%s\": %s"</font>,
02098                       filename_c,
02099                       _dbus_strerror (errno));
02100       <font class="keywordflow">return</font> FALSE;
02101     }
02102 
02103   <font class="keywordflow">if</font> (fstat (fd, &amp;sb) &lt; 0)
02104     {
02105       dbus_set_error (error, _dbus_error_from_errno (errno),
02106                       <font class="stringliteral">"Failed to stat \"%s\": %s"</font>,
02107                       filename_c,
02108                       _dbus_strerror (errno));
02109 
02110       _dbus_verbose (<font class="stringliteral">"fstat() failed: %s"</font>,
02111                      _dbus_strerror (errno));
02112       
02113       close (fd);
02114       
02115       <font class="keywordflow">return</font> FALSE;
02116     }
02117 
02118   <font class="keywordflow">if</font> (sb.st_size &gt; _DBUS_ONE_MEGABYTE)
02119     {
02120       dbus_set_error (error, DBUS_ERROR_FAILED,
02121                       <font class="stringliteral">"File size %lu of \"%s\" is too large."</font>,
02122                       filename_c, (<font class="keywordtype">unsigned</font> <font class="keywordtype">long</font>) sb.st_size);
02123       close (fd);
02124       <font class="keywordflow">return</font> FALSE;
02125     }
02126   
02127   total = 0;
02128   orig_len = _dbus_string_get_length (str);
02129   <font class="keywordflow">if</font> (sb.st_size &gt; 0 &amp;&amp; S_ISREG (sb.st_mode))
02130     {
02131       <font class="keywordtype">int</font> bytes_read;
02132 
02133       <font class="keywordflow">while</font> (total &lt; (int) sb.st_size)
02134         {
02135           bytes_read = _dbus_read (fd, str,
02136                                    sb.st_size - total);
02137           <font class="keywordflow">if</font> (bytes_read &lt;= 0)
02138             {
02139               dbus_set_error (error, _dbus_error_from_errno (errno),
02140                               <font class="stringliteral">"Error reading \"%s\": %s"</font>,
02141                               filename_c,
02142                               _dbus_strerror (errno));
02143 
02144               _dbus_verbose (<font class="stringliteral">"read() failed: %s"</font>,
02145                              _dbus_strerror (errno));
02146               
02147               close (fd);
02148               _dbus_string_set_length (str, orig_len);
02149               <font class="keywordflow">return</font> FALSE;
02150             }
02151           <font class="keywordflow">else</font>
02152             total += bytes_read;
02153         }
02154 
02155       close (fd);
02156       <font class="keywordflow">return</font> TRUE;
02157     }
02158   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (sb.st_size != 0)
02159     {
02160       _dbus_verbose (<font class="stringliteral">"Can only open regular files at the moment.\n"</font>);
02161       dbus_set_error (error, DBUS_ERROR_FAILED,
02162                       <font class="stringliteral">"\"%s\" is not a regular file"</font>,
02163                       filename_c);
02164       close (fd);
02165       <font class="keywordflow">return</font> FALSE;
02166     }
02167   <font class="keywordflow">else</font>
02168     {
02169       close (fd);
02170       <font class="keywordflow">return</font> TRUE;
02171     }
02172 }
02173 
02183 dbus_bool_t
<a name="l02184"></a><a class="code" href="group__DBusInternalsUtils.html#a81">02184</a> _dbus_string_save_to_file (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *str,
02185                            <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *filename,
02186                            <a class="code" href="structDBusError.html">DBusError</a>        *error)
02187 {
02188   <font class="keywordtype">int</font> fd;
02189   <font class="keywordtype">int</font> bytes_to_write;
02190   <font class="keyword">const</font> <font class="keywordtype">char</font> *filename_c;
02191   <a class="code" href="structDBusString.html">DBusString</a> tmp_filename;
02192   <font class="keyword">const</font> <font class="keywordtype">char</font> *tmp_filename_c;
02193   <font class="keywordtype">int</font> total;
02194   dbus_bool_t need_unlink;
02195   dbus_bool_t retval;
02196 
02197   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02198   
02199   fd = -1;
02200   retval = FALSE;
02201   need_unlink = FALSE;
02202   
02203   <font class="keywordflow">if</font> (!_dbus_string_init (&amp;tmp_filename))
02204     {
02205       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02206       <font class="keywordflow">return</font> FALSE;
02207     }
02208 
02209   <font class="keywordflow">if</font> (!_dbus_string_copy (filename, 0, &amp;tmp_filename, 0))
02210     {
02211       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02212       _dbus_string_free (&amp;tmp_filename);
02213       <font class="keywordflow">return</font> FALSE;
02214     }
02215   
02216   <font class="keywordflow">if</font> (!_dbus_string_append (&amp;tmp_filename, <font class="stringliteral">"."</font>))
02217     {
02218       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02219       _dbus_string_free (&amp;tmp_filename);
02220       <font class="keywordflow">return</font> FALSE;
02221     }
02222 
02223 <font class="preprocessor">#define N_TMP_FILENAME_RANDOM_BYTES 8</font>
02224 <font class="preprocessor"></font>  <font class="keywordflow">if</font> (!_dbus_generate_random_ascii (&amp;tmp_filename, N_TMP_FILENAME_RANDOM_BYTES))
02225     {
02226       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02227       _dbus_string_free (&amp;tmp_filename);
02228       <font class="keywordflow">return</font> FALSE;
02229     }
02230     
02231   filename_c = _dbus_string_get_const_data (filename);
02232   tmp_filename_c = _dbus_string_get_const_data (&amp;tmp_filename);
02233 
02234   fd = open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
02235              0600);
02236   <font class="keywordflow">if</font> (fd &lt; 0)
02237     {
02238       dbus_set_error (error, _dbus_error_from_errno (errno),
02239                       <font class="stringliteral">"Could not create %s: %s"</font>, tmp_filename_c,
02240                       _dbus_strerror (errno));
02241       <font class="keywordflow">goto</font> out;
02242     }
02243 
02244   need_unlink = TRUE;
02245   
02246   total = 0;
02247   bytes_to_write = _dbus_string_get_length (str);
02248 
02249   <font class="keywordflow">while</font> (total &lt; bytes_to_write)
02250     {
02251       <font class="keywordtype">int</font> bytes_written;
02252 
02253       bytes_written = _dbus_write (fd, str, total,
02254                                    bytes_to_write - total);
02255 
02256       <font class="keywordflow">if</font> (bytes_written &lt;= 0)
02257         {
02258           dbus_set_error (error, _dbus_error_from_errno (errno),
02259                           <font class="stringliteral">"Could not write to %s: %s"</font>, tmp_filename_c,
02260                           _dbus_strerror (errno));
02261           
02262           <font class="keywordflow">goto</font> out;
02263         }
02264 
02265       total += bytes_written;
02266     }
02267 
02268   <font class="keywordflow">if</font> (close (fd) &lt; 0)
02269     {
02270       dbus_set_error (error, _dbus_error_from_errno (errno),
02271                       <font class="stringliteral">"Could not close file %s: %s"</font>,
02272                       tmp_filename_c, _dbus_strerror (errno));
02273 
02274       <font class="keywordflow">goto</font> out;
02275     }
02276 
02277   fd = -1;
02278   
02279   <font class="keywordflow">if</font> (rename (tmp_filename_c, filename_c) &lt; 0)
02280     {
02281       dbus_set_error (error, _dbus_error_from_errno (errno),
02282                       <font class="stringliteral">"Could not rename %s to %s: %s"</font>,
02283                       tmp_filename_c, filename_c,
02284                       _dbus_strerror (errno));
02285 
02286       <font class="keywordflow">goto</font> out;
02287     }
02288 
02289   need_unlink = FALSE;
02290   
02291   retval = TRUE;
02292   
02293  out:
02294   <font class="comment">/* close first, then unlink, to prevent ".nfs34234235" garbage</font>
02295 <font class="comment">   * files</font>
02296 <font class="comment">   */</font>
02297 
02298   <font class="keywordflow">if</font> (fd &gt;= 0)
02299     close (fd);
02300         
02301   <font class="keywordflow">if</font> (need_unlink &amp;&amp; unlink (tmp_filename_c) &lt; 0)
02302     _dbus_verbose (<font class="stringliteral">"Failed to unlink temp file %s: %s\n"</font>,
02303                    tmp_filename_c, _dbus_strerror (errno));
02304 
02305   _dbus_string_free (&amp;tmp_filename);
02306 
02307   <font class="keywordflow">if</font> (!retval)
02308     _DBUS_ASSERT_ERROR_IS_SET (error);
02309   
02310   <font class="keywordflow">return</font> retval;
02311 }
02312 
02319 dbus_bool_t
<a name="l02320"></a><a class="code" href="group__DBusInternalsUtils.html#a82">02320</a> _dbus_create_file_exclusively (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *filename,
02321                                <a class="code" href="structDBusError.html">DBusError</a>        *error)
02322 {
02323   <font class="keywordtype">int</font> fd;
02324   <font class="keyword">const</font> <font class="keywordtype">char</font> *filename_c;
02325 
02326   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02327   
02328   filename_c = _dbus_string_get_const_data (filename);
02329   
02330   fd = open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
02331              0600);
02332   <font class="keywordflow">if</font> (fd &lt; 0)
02333     {
02334       dbus_set_error (error,
02335                       DBUS_ERROR_FAILED,
02336                       <font class="stringliteral">"Could not create file %s: %s\n"</font>,
02337                       filename_c,
02338                       _dbus_strerror (errno));
02339       <font class="keywordflow">return</font> FALSE;
02340     }
02341 
02342   <font class="keywordflow">if</font> (close (fd) &lt; 0)
02343     {
02344       dbus_set_error (error,
02345                       DBUS_ERROR_FAILED,
02346                       <font class="stringliteral">"Could not close file %s: %s\n"</font>,
02347                       filename_c,
02348                       _dbus_strerror (errno));
02349       <font class="keywordflow">return</font> FALSE;
02350     }
02351   
02352   <font class="keywordflow">return</font> TRUE;
02353 }
02354 
02363 dbus_bool_t
<a name="l02364"></a><a class="code" href="group__DBusInternalsUtils.html#a83">02364</a> _dbus_delete_file (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *filename,
02365                    <a class="code" href="structDBusError.html">DBusError</a>        *error)
02366 {
02367   <font class="keyword">const</font> <font class="keywordtype">char</font> *filename_c;
02368 
02369   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02370   
02371   filename_c = _dbus_string_get_const_data (filename);
02372 
02373   <font class="keywordflow">if</font> (unlink (filename_c) &lt; 0)
02374     {
02375       dbus_set_error (error, DBUS_ERROR_FAILED,
02376                       <font class="stringliteral">"Failed to delete file %s: %s\n"</font>,
02377                       filename_c, _dbus_strerror (errno));
02378       <font class="keywordflow">return</font> FALSE;
02379     }
02380   <font class="keywordflow">else</font>
02381     <font class="keywordflow">return</font> TRUE;
02382 }
02383 
02392 dbus_bool_t
<a name="l02393"></a><a class="code" href="group__DBusInternalsUtils.html#a84">02393</a> _dbus_create_directory (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *filename,
02394                         <a class="code" href="structDBusError.html">DBusError</a>        *error)
02395 {
02396   <font class="keyword">const</font> <font class="keywordtype">char</font> *filename_c;
02397 
02398   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02399   
02400   filename_c = _dbus_string_get_const_data (filename);
02401 
02402   <font class="keywordflow">if</font> (mkdir (filename_c, 0700) &lt; 0)
02403     {
02404       <font class="keywordflow">if</font> (errno == EEXIST)
02405         <font class="keywordflow">return</font> TRUE;
02406       
02407       dbus_set_error (error, DBUS_ERROR_FAILED,
02408                       <font class="stringliteral">"Failed to create directory %s: %s\n"</font>,
02409                       filename_c, _dbus_strerror (errno));
02410       <font class="keywordflow">return</font> FALSE;
02411     }
02412   <font class="keywordflow">else</font>
02413     <font class="keywordflow">return</font> TRUE;
02414 }
02415 
02423 dbus_bool_t
<a name="l02424"></a><a class="code" href="group__DBusInternalsUtils.html#a85">02424</a> _dbus_delete_directory (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *filename,
02425                         <a class="code" href="structDBusError.html">DBusError</a>        *error)
02426 {
02427   <font class="keyword">const</font> <font class="keywordtype">char</font> *filename_c;
02428   
02429   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02430 
02431   filename_c = _dbus_string_get_const_data (filename);
02432 
02433   <font class="keywordflow">if</font> (rmdir (filename_c) != 0)
02434     {
02435       dbus_set_error (error, DBUS_ERROR_FAILED,
02436                       <font class="stringliteral">"Failed to remove directory %s: %s\n"</font>,
02437                       filename_c, _dbus_strerror (errno));
02438       <font class="keywordflow">return</font> FALSE;
02439     }
02440   
02441   <font class="keywordflow">return</font> TRUE;
02442 }
02443 
02454 dbus_bool_t
<a name="l02455"></a><a class="code" href="group__DBusInternalsUtils.html#a86">02455</a> _dbus_concat_dir_and_file (<a class="code" href="structDBusString.html">DBusString</a>       *dir,
02456                            <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *next_component)
02457 {
02458   dbus_bool_t dir_ends_in_slash;
02459   dbus_bool_t file_starts_with_slash;
02460 
02461   <font class="keywordflow">if</font> (_dbus_string_get_length (dir) == 0 ||
02462       _dbus_string_get_length (next_component) == 0)
02463     <font class="keywordflow">return</font> TRUE;
02464   
02465   dir_ends_in_slash = <font class="charliteral">'/'</font> == _dbus_string_get_byte (dir,
02466                                                     _dbus_string_get_length (dir) - 1);
02467 
02468   file_starts_with_slash = <font class="charliteral">'/'</font> == _dbus_string_get_byte (next_component, 0);
02469 
02470   <font class="keywordflow">if</font> (dir_ends_in_slash &amp;&amp; file_starts_with_slash)
02471     {
02472       _dbus_string_shorten (dir, 1);
02473     }
02474   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (!(dir_ends_in_slash || file_starts_with_slash))
02475     {
02476       <font class="keywordflow">if</font> (!_dbus_string_append_byte (dir, <font class="charliteral">'/'</font>))
02477         <font class="keywordflow">return</font> FALSE;
02478     }
02479 
02480   <font class="keywordflow">return</font> _dbus_string_copy (next_component, 0, dir,
02481                             _dbus_string_get_length (dir));
02482 }
02483 
02490 dbus_bool_t
<a name="l02491"></a><a class="code" href="group__DBusInternalsUtils.html#a87">02491</a> _dbus_string_get_dirname  (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *filename,
02492                            <a class="code" href="structDBusString.html">DBusString</a>       *dirname)
02493 {
02494   <font class="keywordtype">int</font> sep;
02495   
02496   _dbus_assert (filename != dirname);
02497   _dbus_assert (filename != NULL);
02498   _dbus_assert (dirname != NULL);
02499 
02500   <font class="comment">/* Ignore any separators on the end */</font>
02501   sep = _dbus_string_get_length (filename);
02502   <font class="keywordflow">if</font> (sep == 0)
02503     <font class="keywordflow">return</font> _dbus_string_append (dirname, <font class="stringliteral">"."</font>); <font class="comment">/* empty string passed in */</font>
02504     
02505   <font class="keywordflow">while</font> (sep &gt; 0 &amp;&amp; _dbus_string_get_byte (filename, sep - 1) == <font class="charliteral">'/'</font>)
02506     --sep;
02507 
02508   _dbus_assert (sep &gt;= 0);
02509   
02510   <font class="keywordflow">if</font> (sep == 0)
02511     <font class="keywordflow">return</font> _dbus_string_append (dirname, <font class="stringliteral">"/"</font>);
02512   
02513   <font class="comment">/* Now find the previous separator */</font>
02514   _dbus_string_find_byte_backward (filename, sep, <font class="charliteral">'/'</font>, &amp;sep);
02515   <font class="keywordflow">if</font> (sep &lt; 0)
02516     <font class="keywordflow">return</font> _dbus_string_append (dirname, <font class="stringliteral">"."</font>);
02517   
02518   <font class="comment">/* skip multiple separators */</font>
02519   <font class="keywordflow">while</font> (sep &gt; 0 &amp;&amp; _dbus_string_get_byte (filename, sep - 1) == <font class="charliteral">'/'</font>)
02520     --sep;
02521 
02522   _dbus_assert (sep &gt;= 0);
02523   
02524   <font class="keywordflow">if</font> (sep == 0 &amp;&amp;
02525       _dbus_string_get_byte (filename, 0) == <font class="charliteral">'/'</font>)
02526     <font class="keywordflow">return</font> _dbus_string_append (dirname, <font class="stringliteral">"/"</font>);
02527   <font class="keywordflow">else</font>
02528     <font class="keywordflow">return</font> _dbus_string_copy_len (filename, 0, sep - 0,
02529                                   dirname, _dbus_string_get_length (dirname));
02530 }
02531 
02538 dbus_bool_t
<a name="l02539"></a><a class="code" href="group__DBusInternalsUtils.html#a88">02539</a> _dbus_path_is_absolute (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *filename)
02540 {
02541   <font class="keywordflow">if</font> (_dbus_string_get_length (filename) &gt; 0)
02542     <font class="keywordflow">return</font> _dbus_string_get_byte (filename, 0) == <font class="charliteral">'/'</font>;
02543   <font class="keywordflow">else</font>
02544     <font class="keywordflow">return</font> FALSE;
02545 }
02546 
<a name="l02550"></a><a class="code" href="structDBusDirIter.html">02550</a> <font class="keyword">struct </font><a class="code" href="structDBusDirIter.html">DBusDirIter</a>
02551 {
<a name="l02552"></a><a class="code" href="structDBusDirIter.html#m0">02552</a>   DIR *<a class="code" href="structDBusDirIter.html#m0">d</a>; 
02554 };
02555 
02563 <a class="code" href="structDBusDirIter.html">DBusDirIter</a>*
<a name="l02564"></a><a class="code" href="group__DBusInternalsUtils.html#a89">02564</a> _dbus_directory_open (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *filename,
02565                       <a class="code" href="structDBusError.html">DBusError</a>        *error)
02566 {
02567   DIR *d;
02568   <a class="code" href="structDBusDirIter.html">DBusDirIter</a> *iter;
02569   <font class="keyword">const</font> <font class="keywordtype">char</font> *filename_c;
02570 
02571   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02572   
02573   filename_c = _dbus_string_get_const_data (filename);
02574 
02575   d = opendir (filename_c);
02576   <font class="keywordflow">if</font> (d == NULL)
02577     {
02578       dbus_set_error (error, _dbus_error_from_errno (errno),
02579                       <font class="stringliteral">"Failed to read directory \"%s\": %s"</font>,
02580                       filename_c,
02581                       _dbus_strerror (errno));
02582       <font class="keywordflow">return</font> NULL;
02583     }
02584   iter = dbus_new0 (<a class="code" href="structDBusDirIter.html">DBusDirIter</a>, 1);
02585   <font class="keywordflow">if</font> (iter == NULL)
02586     {
02587       closedir (d);
02588       dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
02589                       <font class="stringliteral">"Could not allocate memory for directory iterator"</font>);
02590       <font class="keywordflow">return</font> NULL;
02591     }
02592 
02593   iter-&gt;<a class="code" href="structDBusDirIter.html#m0">d</a> = d;
02594 
02595   <font class="keywordflow">return</font> iter;
02596 }
02597 
02611 dbus_bool_t
<a name="l02612"></a><a class="code" href="group__DBusInternalsUtils.html#a90">02612</a> _dbus_directory_get_next_file (<a class="code" href="structDBusDirIter.html">DBusDirIter</a>      *iter,
02613                                <a class="code" href="structDBusString.html">DBusString</a>       *filename,
02614                                <a class="code" href="structDBusError.html">DBusError</a>        *error)
02615 {
02616   <font class="keyword">struct </font>dirent *ent;
02617 
02618   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02619   
02620  again:
02621   errno = 0;
02622   ent = readdir (iter-&gt;<a class="code" href="structDBusDirIter.html#m0">d</a>);
02623   <font class="keywordflow">if</font> (ent == NULL)
02624     {
02625       <font class="keywordflow">if</font> (errno != 0)
02626         dbus_set_error (error,
02627                         _dbus_error_from_errno (errno),
02628                         <font class="stringliteral">"%s"</font>, _dbus_strerror (errno));
02629       <font class="keywordflow">return</font> FALSE;
02630     }
02631   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (ent-&gt;d_name[0] == <font class="charliteral">'.'</font> &amp;&amp;
02632            (ent-&gt;d_name[1] == <font class="charliteral">'\0'</font> ||
02633             (ent-&gt;d_name[1] == <font class="charliteral">'.'</font> &amp;&amp; ent-&gt;d_name[2] == <font class="charliteral">'\0'</font>)))
02634     <font class="keywordflow">goto</font> again;
02635   <font class="keywordflow">else</font>
02636     {
02637       _dbus_string_set_length (filename, 0);
02638       <font class="keywordflow">if</font> (!_dbus_string_append (filename, ent-&gt;d_name))
02639         {
02640           dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
02641                           <font class="stringliteral">"No memory to read directory entry"</font>);
02642           <font class="keywordflow">return</font> FALSE;
02643         }
02644       <font class="keywordflow">else</font>
02645         <font class="keywordflow">return</font> TRUE;
02646     }
02647 }
02648 
02652 <font class="keywordtype">void</font>
<a name="l02653"></a><a class="code" href="group__DBusInternalsUtils.html#a91">02653</a> _dbus_directory_close (<a class="code" href="structDBusDirIter.html">DBusDirIter</a> *iter)
02654 {
02655   closedir (iter-&gt;<a class="code" href="structDBusDirIter.html#m0">d</a>);
02656   dbus_free (iter);
02657 }
02658 
02659 <font class="keyword">static</font> dbus_bool_t
02660 pseudorandom_generate_random_bytes (<a class="code" href="structDBusString.html">DBusString</a> *str,
02661                                     <font class="keywordtype">int</font>         n_bytes)
02662 {
02663   <font class="keywordtype">int</font> old_len;
02664   <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> tv_usec;
02665   <font class="keywordtype">int</font> i;
02666   
02667   old_len = _dbus_string_get_length (str);
02668 
02669   <font class="comment">/* fall back to pseudorandom */</font>
02670   _dbus_verbose (<font class="stringliteral">"Falling back to pseudorandom for %d bytes\n"</font>,
02671                  n_bytes);
02672   
02673   _dbus_get_current_time (NULL, &amp;tv_usec);
02674   srand (tv_usec);
02675   
02676   i = 0;
02677   <font class="keywordflow">while</font> (i &lt; n_bytes)
02678     {
02679       <font class="keywordtype">double</font> r;
02680       <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> b;
02681           
02682       r = rand ();
02683       b = (r / (double) RAND_MAX) * 255.0;
02684           
02685       <font class="keywordflow">if</font> (!_dbus_string_append_byte (str, b))
02686         <font class="keywordflow">goto</font> failed;
02687           
02688       ++i;
02689     }
02690 
02691   <font class="keywordflow">return</font> TRUE;
02692 
02693  failed:
02694   _dbus_string_set_length (str, old_len);
02695   <font class="keywordflow">return</font> FALSE;
02696 }
02697 
02706 dbus_bool_t
<a name="l02707"></a><a class="code" href="group__DBusInternalsUtils.html#a93">02707</a> _dbus_generate_random_bytes (<a class="code" href="structDBusString.html">DBusString</a> *str,
02708                              <font class="keywordtype">int</font>         n_bytes)
02709 {
02710   <font class="keywordtype">int</font> old_len;
02711   <font class="keywordtype">int</font> fd;
02712 
02713   <font class="comment">/* FALSE return means "no memory", if it could</font>
02714 <font class="comment">   * mean something else then we'd need to return</font>
02715 <font class="comment">   * a DBusError. So we always fall back to pseudorandom</font>
02716 <font class="comment">   * if the I/O fails.</font>
02717 <font class="comment">   */</font>
02718   
02719   old_len = _dbus_string_get_length (str);
02720   fd = -1;
02721 
02722   <font class="comment">/* note, urandom on linux will fall back to pseudorandom */</font>
02723   fd = open (<font class="stringliteral">"/dev/urandom"</font>, O_RDONLY);
02724   <font class="keywordflow">if</font> (fd &lt; 0)
02725     <font class="keywordflow">return</font> pseudorandom_generate_random_bytes (str, n_bytes);
02726 
02727   <font class="keywordflow">if</font> (_dbus_read (fd, str, n_bytes) != n_bytes)
02728     {
02729       close (fd);
02730       _dbus_string_set_length (str, old_len);
02731       <font class="keywordflow">return</font> pseudorandom_generate_random_bytes (str, n_bytes);
02732     }
02733 
02734   _dbus_verbose (<font class="stringliteral">"Read %d bytes from /dev/urandom\n"</font>,
02735                  n_bytes);
02736   
02737   close (fd);
02738   
02739   <font class="keywordflow">return</font> TRUE;
02740 }
02741 
02750 dbus_bool_t
<a name="l02751"></a><a class="code" href="group__DBusInternalsUtils.html#a94">02751</a> _dbus_generate_random_ascii (<a class="code" href="structDBusString.html">DBusString</a> *str,
02752                              <font class="keywordtype">int</font>         n_bytes)
02753 {
02754   <font class="keyword">static</font> <font class="keyword">const</font> <font class="keywordtype">char</font> letters[] =
02755     <font class="stringliteral">"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"</font>;
02756   <font class="keywordtype">int</font> i;
02757   <font class="keywordtype">int</font> len;
02758   
02759   <font class="keywordflow">if</font> (!_dbus_generate_random_bytes (str, n_bytes))
02760     <font class="keywordflow">return</font> FALSE;
02761   
02762   len = _dbus_string_get_length (str);
02763   i = len - n_bytes;
02764   <font class="keywordflow">while</font> (i &lt; len)
02765     {
02766       _dbus_string_set_byte (str, i,
02767                              letters[_dbus_string_get_byte (str, i) %
02768                                      (<font class="keyword">sizeof</font> (letters) - 1)]);
02769 
02770       ++i;
02771     }
02772 
02773   _dbus_assert (_dbus_string_validate_ascii (str, len - n_bytes,
02774                                              n_bytes));
02775 
02776   <font class="keywordflow">return</font> TRUE;
02777 }
02778 
02786 <font class="keyword">const</font> <font class="keywordtype">char</font>*
<a name="l02787"></a><a class="code" href="group__DBusInternalsUtils.html#a72">02787</a> _dbus_strerror (<font class="keywordtype">int</font> error_number)
02788 {
02789   <font class="keyword">const</font> <font class="keywordtype">char</font> *msg;
02790   
02791   msg = strerror (error_number);
02792   <font class="keywordflow">if</font> (msg == NULL)
02793     msg = <font class="stringliteral">"unknown"</font>;
02794 
02795   <font class="keywordflow">return</font> msg;
02796 }
02797 
02801 <font class="keywordtype">void</font>
<a name="l02802"></a><a class="code" href="group__DBusInternalsUtils.html#a96">02802</a> _dbus_disable_sigpipe (<font class="keywordtype">void</font>)
02803 {
02804   signal (SIGPIPE, SIG_IGN);
02805 }
02806 
02814 <font class="keywordtype">void</font>
<a name="l02815"></a><a class="code" href="group__DBusInternalsUtils.html#a97">02815</a> _dbus_fd_set_close_on_exec (<font class="keywordtype">int</font> fd)
02816 {
02817   <font class="keywordtype">int</font> val;
02818   
02819   val = fcntl (fd, F_GETFD, 0);
02820   
02821   <font class="keywordflow">if</font> (val &lt; 0)
02822     <font class="keywordflow">return</font>;
02823 
02824   val |= FD_CLOEXEC;
02825   
02826   fcntl (fd, F_SETFD, val);
02827 }
02828 
02838 <font class="keyword">const</font> <font class="keywordtype">char</font>*
<a name="l02839"></a><a class="code" href="group__DBusInternalsUtils.html#a98">02839</a> _dbus_error_from_errno (<font class="keywordtype">int</font> error_number)
02840 {
02841   <font class="keywordflow">switch</font> (error_number)
02842     {
02843     <font class="keywordflow">case</font> 0:
02844       <font class="keywordflow">return</font> DBUS_ERROR_FAILED;
02845       
02846 <font class="preprocessor">#ifdef EPROTONOSUPPORT</font>
02847 <font class="preprocessor"></font>    <font class="keywordflow">case</font> EPROTONOSUPPORT:
02848       <font class="keywordflow">return</font> DBUS_ERROR_NOT_SUPPORTED;
02849 <font class="preprocessor">#endif</font>
02850 <font class="preprocessor"></font><font class="preprocessor">#ifdef EAFNOSUPPORT</font>
02851 <font class="preprocessor"></font>    <font class="keywordflow">case</font> EAFNOSUPPORT:
02852       <font class="keywordflow">return</font> DBUS_ERROR_NOT_SUPPORTED;
02853 <font class="preprocessor">#endif</font>
02854 <font class="preprocessor"></font><font class="preprocessor">#ifdef ENFILE</font>
02855 <font class="preprocessor"></font>    <font class="keywordflow">case</font> ENFILE:
02856       <font class="keywordflow">return</font> DBUS_ERROR_LIMITS_EXCEEDED; <font class="comment">/* kernel out of memory */</font>
02857 <font class="preprocessor">#endif</font>
02858 <font class="preprocessor"></font><font class="preprocessor">#ifdef EMFILE</font>
02859 <font class="preprocessor"></font>    <font class="keywordflow">case</font> EMFILE:
02860       <font class="keywordflow">return</font> DBUS_ERROR_LIMITS_EXCEEDED;
02861 <font class="preprocessor">#endif</font>
02862 <font class="preprocessor"></font><font class="preprocessor">#ifdef EACCES</font>
02863 <font class="preprocessor"></font>    <font class="keywordflow">case</font> EACCES:
02864       <font class="keywordflow">return</font> DBUS_ERROR_ACCESS_DENIED;
02865 <font class="preprocessor">#endif</font>
02866 <font class="preprocessor"></font><font class="preprocessor">#ifdef EPERM</font>
02867 <font class="preprocessor"></font>    <font class="keywordflow">case</font> EPERM:
02868       <font class="keywordflow">return</font> DBUS_ERROR_ACCESS_DENIED;
02869 <font class="preprocessor">#endif</font>
02870 <font class="preprocessor"></font><font class="preprocessor">#ifdef ENOBUFS</font>
02871 <font class="preprocessor"></font>    <font class="keywordflow">case</font> ENOBUFS:
02872       <font class="keywordflow">return</font> DBUS_ERROR_NO_MEMORY;
02873 <font class="preprocessor">#endif</font>
02874 <font class="preprocessor"></font><font class="preprocessor">#ifdef ENOMEM</font>
02875 <font class="preprocessor"></font>    <font class="keywordflow">case</font> ENOMEM:
02876       <font class="keywordflow">return</font> DBUS_ERROR_NO_MEMORY;
02877 <font class="preprocessor">#endif</font>
02878 <font class="preprocessor"></font><font class="preprocessor">#ifdef EINVAL</font>
02879 <font class="preprocessor"></font>    <font class="keywordflow">case</font> EINVAL:
02880       <font class="keywordflow">return</font> DBUS_ERROR_FAILED;
02881 <font class="preprocessor">#endif</font>
02882 <font class="preprocessor"></font><font class="preprocessor">#ifdef EBADF</font>
02883 <font class="preprocessor"></font>    <font class="keywordflow">case</font> EBADF:
02884       <font class="keywordflow">return</font> DBUS_ERROR_FAILED;
02885 <font class="preprocessor">#endif</font>
02886 <font class="preprocessor"></font><font class="preprocessor">#ifdef EFAULT</font>
02887 <font class="preprocessor"></font>    <font class="keywordflow">case</font> EFAULT:
02888       <font class="keywordflow">return</font> DBUS_ERROR_FAILED;
02889 <font class="preprocessor">#endif</font>
02890 <font class="preprocessor"></font><font class="preprocessor">#ifdef ENOTSOCK</font>
02891 <font class="preprocessor"></font>    <font class="keywordflow">case</font> ENOTSOCK:
02892       <font class="keywordflow">return</font> DBUS_ERROR_FAILED;
02893 <font class="preprocessor">#endif</font>
02894 <font class="preprocessor"></font><font class="preprocessor">#ifdef EISCONN</font>
02895 <font class="preprocessor"></font>    <font class="keywordflow">case</font> EISCONN:
02896       <font class="keywordflow">return</font> DBUS_ERROR_FAILED;
02897 <font class="preprocessor">#endif</font>
02898 <font class="preprocessor"></font><font class="preprocessor">#ifdef ECONNREFUSED</font>
02899 <font class="preprocessor"></font>    <font class="keywordflow">case</font> ECONNREFUSED:
02900       <font class="keywordflow">return</font> DBUS_ERROR_NO_SERVER;
02901 <font class="preprocessor">#endif</font>
02902 <font class="preprocessor"></font><font class="preprocessor">#ifdef ETIMEDOUT</font>
02903 <font class="preprocessor"></font>    <font class="keywordflow">case</font> ETIMEDOUT:
02904       <font class="keywordflow">return</font> DBUS_ERROR_TIMEOUT;
02905 <font class="preprocessor">#endif</font>
02906 <font class="preprocessor"></font><font class="preprocessor">#ifdef ENETUNREACH</font>
02907 <font class="preprocessor"></font>    <font class="keywordflow">case</font> ENETUNREACH:
02908       <font class="keywordflow">return</font> DBUS_ERROR_NO_NETWORK;
02909 <font class="preprocessor">#endif</font>
02910 <font class="preprocessor"></font><font class="preprocessor">#ifdef EADDRINUSE</font>
02911 <font class="preprocessor"></font>    <font class="keywordflow">case</font> EADDRINUSE:
02912       <font class="keywordflow">return</font> DBUS_ERROR_ADDRESS_IN_USE;
02913 <font class="preprocessor">#endif</font>
02914 <font class="preprocessor"></font><font class="preprocessor">#ifdef EEXIST</font>
02915 <font class="preprocessor"></font>    <font class="keywordflow">case</font> EEXIST:
02916       <font class="keywordflow">return</font> DBUS_ERROR_FILE_NOT_FOUND;
02917 <font class="preprocessor">#endif</font>
02918 <font class="preprocessor"></font><font class="preprocessor">#ifdef ENOENT</font>
02919 <font class="preprocessor"></font>    <font class="keywordflow">case</font> ENOENT:
02920       <font class="keywordflow">return</font> DBUS_ERROR_FILE_NOT_FOUND;
02921 <font class="preprocessor">#endif</font>
02922 <font class="preprocessor"></font>    }
02923 
02924   <font class="keywordflow">return</font> DBUS_ERROR_FAILED;
02925 }
02926 
02932 <font class="keywordtype">void</font>
<a name="l02933"></a><a class="code" href="group__DBusInternalsUtils.html#a99">02933</a> _dbus_exit (<font class="keywordtype">int</font> code)
02934 {
02935   _exit (code);
02936 }
02937 
02946 dbus_bool_t
<a name="l02947"></a><a class="code" href="group__DBusInternalsUtils.html#a100">02947</a> _dbus_stat (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *filename,
02948             <a class="code" href="structDBusStat.html">DBusStat</a>         *statbuf,
02949             <a class="code" href="structDBusError.html">DBusError</a>        *error)
02950 {
02951   <font class="keyword">const</font> <font class="keywordtype">char</font> *filename_c;
02952   <font class="keyword">struct </font>stat sb;
02953 
02954   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02955   
02956   filename_c = _dbus_string_get_const_data (filename);
02957 
02958   <font class="keywordflow">if</font> (stat (filename_c, &amp;sb) &lt; 0)
02959     {
02960       dbus_set_error (error, _dbus_error_from_errno (errno),
02961                       <font class="stringliteral">"%s"</font>, _dbus_strerror (errno));
02962       <font class="keywordflow">return</font> FALSE;
02963     }
02964 
02965   statbuf-&gt;<a class="code" href="structDBusStat.html#m0">mode</a> = sb.st_mode;
02966   statbuf-&gt;<a class="code" href="structDBusStat.html#m1">nlink</a> = sb.st_nlink;
02967   statbuf-&gt;<a class="code" href="structDBusStat.html#m2">uid</a> = sb.st_uid;
02968   statbuf-&gt;<a class="code" href="structDBusStat.html#m3">gid</a> = sb.st_gid;
02969   statbuf-&gt;<a class="code" href="structDBusStat.html#m4">size</a> = sb.st_size;
02970   statbuf-&gt;<a class="code" href="structDBusStat.html#m5">atime</a> = sb.st_atime;
02971   statbuf-&gt;<a class="code" href="structDBusStat.html#m6">mtime</a> = sb.st_mtime;
02972   statbuf-&gt;<a class="code" href="structDBusStat.html#m7">ctime</a> = sb.st_ctime;
02973 
02974   <font class="keywordflow">return</font> TRUE;
02975 }
02976 
02987 dbus_bool_t
<a name="l02988"></a><a class="code" href="group__DBusInternalsUtils.html#a101">02988</a> _dbus_full_duplex_pipe (<font class="keywordtype">int</font>        *fd1,
02989                         <font class="keywordtype">int</font>        *fd2,
02990                         dbus_bool_t blocking,
02991                         <a class="code" href="structDBusError.html">DBusError</a>  *error)
02992 {
02993 <font class="preprocessor">#ifdef HAVE_SOCKETPAIR</font>
02994 <font class="preprocessor"></font>  <font class="keywordtype">int</font> fds[2];
02995 
02996   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02997   
02998   <font class="keywordflow">if</font> (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) &lt; 0)
02999     {
03000       dbus_set_error (error, _dbus_error_from_errno (errno),
03001                       <font class="stringliteral">"Could not create full-duplex pipe"</font>);
03002       <font class="keywordflow">return</font> FALSE;
03003     }
03004 
03005   <font class="keywordflow">if</font> (!blocking &amp;&amp;
03006       (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
03007        !_dbus_set_fd_nonblocking (fds[1], NULL)))
03008     {
03009       dbus_set_error (error, _dbus_error_from_errno (errno),
03010                       <font class="stringliteral">"Could not set full-duplex pipe nonblocking"</font>);
03011       
03012       close (fds[0]);
03013       close (fds[1]);
03014       
03015       <font class="keywordflow">return</font> FALSE;
03016     }
03017   
03018   *fd1 = fds[0];
03019   *fd2 = fds[1];
03020   
03021   <font class="keywordflow">return</font> TRUE;  
03022 <font class="preprocessor">#else</font>
03023 <font class="preprocessor"></font>  _dbus_warn (<font class="stringliteral">"_dbus_full_duplex_pipe() not implemented on this OS\n"</font>);
03024   dbus_set_error (error, DBUS_ERROR_FAILED,
03025                   <font class="stringliteral">"_dbus_full_duplex_pipe() not implemented on this OS"</font>);
03026   <font class="keywordflow">return</font> FALSE;
03027 <font class="preprocessor">#endif</font>
03028 <font class="preprocessor"></font>}
03029 
03037 dbus_bool_t
<a name="l03038"></a><a class="code" href="group__DBusInternalsUtils.html#a102">03038</a> _dbus_close (<font class="keywordtype">int</font>        fd,
03039              <a class="code" href="structDBusError.html">DBusError</a> *error)
03040 {
03041   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03042   
03043  again:
03044   <font class="keywordflow">if</font> (close (fd) &lt; 0)
03045     {
03046       <font class="keywordflow">if</font> (errno == EINTR)
03047         <font class="keywordflow">goto</font> again;
03048 
03049       dbus_set_error (error, _dbus_error_from_errno (errno),
03050                       <font class="stringliteral">"Could not close fd %d"</font>, fd);
03051       <font class="keywordflow">return</font> FALSE;
03052     }
03053 
03054   <font class="keywordflow">return</font> TRUE;
03055 }
03056 
03064 dbus_bool_t
<a name="l03065"></a><a class="code" href="group__DBusInternalsUtils.html#a80">03065</a> _dbus_set_fd_nonblocking (<font class="keywordtype">int</font>             fd,
03066                           <a class="code" href="structDBusError.html">DBusError</a>      *error)
03067 {
03068   <font class="keywordtype">int</font> val;
03069 
03070   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03071   
03072   val = fcntl (fd, F_GETFL, 0);
03073   <font class="keywordflow">if</font> (val &lt; 0)
03074     {
03075       dbus_set_error (error, _dbus_error_from_errno (errno),
03076                       <font class="stringliteral">"Failed to get flags from file descriptor %d: %s"</font>,
03077                       fd, _dbus_strerror (errno));
03078       _dbus_verbose (<font class="stringliteral">"Failed to get flags for fd %d: %s\n"</font>, fd,
03079                      _dbus_strerror (errno));
03080       <font class="keywordflow">return</font> FALSE;
03081     }
03082 
03083   <font class="keywordflow">if</font> (fcntl (fd, F_SETFL, val | O_NONBLOCK) &lt; 0)
03084     {
03085       dbus_set_error (error, _dbus_error_from_errno (errno),
03086                       <font class="stringliteral">"Failed to set nonblocking flag of file descriptor %d: %s"</font>,
03087                       fd, _dbus_strerror (errno));
03088       _dbus_verbose (<font class="stringliteral">"Failed to set fd %d nonblocking: %s\n"</font>,
03089                      fd, _dbus_strerror (errno));
03090 
03091       <font class="keywordflow">return</font> FALSE;
03092     }
03093 
03094   <font class="keywordflow">return</font> TRUE;
03095 }
03096 
03102 <font class="keywordtype">void</font>
<a name="l03103"></a><a class="code" href="group__DBusInternalsUtils.html#a104">03103</a> _dbus_print_backtrace (<font class="keywordtype">void</font>)
03104 {
03105 <font class="preprocessor">#if defined (HAVE_BACKTRACE) &amp;&amp; defined (DBUS_ENABLE_VERBOSE_MODE)</font>
03106 <font class="preprocessor"></font>  <font class="keywordtype">void</font> *bt[500];
03107   <font class="keywordtype">int</font> bt_size;
03108   <font class="keywordtype">int</font> i;
03109   <font class="keywordtype">char</font> **syms;
03110   
03111   bt_size = backtrace (bt, 500);
03112 
03113   syms = backtrace_symbols (bt, bt_size);
03114   
03115   i = 0;
03116   <font class="keywordflow">while</font> (i &lt; bt_size)
03117     {
03118       _dbus_verbose (<font class="stringliteral">"  %s\n"</font>, syms[i]);
03119       ++i;
03120     }
03121 
03122   free (syms);
03123 <font class="preprocessor">#else</font>
03124 <font class="preprocessor"></font>  _dbus_verbose (<font class="stringliteral">"  D-BUS not compiled with backtrace support\n"</font>);
03125 <font class="preprocessor">#endif</font>
03126 <font class="preprocessor"></font>}
03127 
03135 dbus_bool_t
<a name="l03136"></a><a class="code" href="group__DBusInternalsUtils.html#a105">03136</a> _dbus_become_daemon (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *pidfile,
03137                      <a class="code" href="structDBusError.html">DBusError</a>        *error)
03138 {
03139   <font class="keyword">const</font> <font class="keywordtype">char</font> *s;
03140   pid_t child_pid;
03141   <font class="keywordtype">int</font> dev_null_fd;
03142 
03143   _dbus_verbose (<font class="stringliteral">"Becoming a daemon...\n"</font>);
03144 
03145   _dbus_verbose (<font class="stringliteral">"chdir to /\n"</font>);
03146   <font class="keywordflow">if</font> (chdir (<font class="stringliteral">"/"</font>) &lt; 0)
03147     {
03148       dbus_set_error (error, DBUS_ERROR_FAILED,
03149                       <font class="stringliteral">"Could not chdir() to root directory"</font>);
03150       <font class="keywordflow">return</font> FALSE;
03151     }
03152 
03153   _dbus_verbose (<font class="stringliteral">"forking...\n"</font>);
03154   <font class="keywordflow">switch</font> ((child_pid = fork ()))
03155     {
03156     <font class="keywordflow">case</font> -1:
03157       _dbus_verbose (<font class="stringliteral">"fork failed\n"</font>);
03158       dbus_set_error (error, _dbus_error_from_errno (errno),
03159                       <font class="stringliteral">"Failed to fork daemon: %s"</font>, _dbus_strerror (errno));
03160       <font class="keywordflow">return</font> FALSE;
03161       <font class="keywordflow">break</font>;
03162 
03163     <font class="keywordflow">case</font> 0:
03164       _dbus_verbose (<font class="stringliteral">"in child, closing std file descriptors\n"</font>);
03165 
03166       <font class="comment">/* silently ignore failures here, if someone</font>
03167 <font class="comment">       * doesn't have /dev/null we may as well try</font>
03168 <font class="comment">       * to continue anyhow</font>
03169 <font class="comment">       */</font>
03170       
03171       dev_null_fd = open (<font class="stringliteral">"/dev/null"</font>, O_RDWR);
03172       <font class="keywordflow">if</font> (dev_null_fd &gt;= 0)
03173         {
03174           dup2 (dev_null_fd, 0);
03175           dup2 (dev_null_fd, 1);
03176           
03177           s = _dbus_getenv (<font class="stringliteral">"DBUS_DEBUG_OUTPUT"</font>);
03178           <font class="keywordflow">if</font> (s == NULL || *s == <font class="charliteral">'\0'</font>)
03179             dup2 (dev_null_fd, 2);
03180           <font class="keywordflow">else</font>
03181             _dbus_verbose (<font class="stringliteral">"keeping stderr open due to DBUS_DEBUG_OUTPUT\n"</font>);
03182         }
03183 
03184       <font class="comment">/* Get a predictable umask */</font>
03185       _dbus_verbose (<font class="stringliteral">"setting umask\n"</font>);
03186       umask (022);
03187       <font class="keywordflow">break</font>;
03188 
03189     <font class="keywordflow">default</font>:
03190       <font class="keywordflow">if</font> (pidfile)
03191         {
03192           _dbus_verbose (<font class="stringliteral">"parent writing pid file\n"</font>);
03193           <font class="keywordflow">if</font> (!_dbus_write_pid_file (pidfile,
03194                                      child_pid,
03195                                      error))
03196             {
03197               _dbus_verbose (<font class="stringliteral">"pid file write failed, killing child\n"</font>);
03198               kill (child_pid, SIGTERM);
03199               <font class="keywordflow">return</font> FALSE;
03200             }
03201         }
03202       _dbus_verbose (<font class="stringliteral">"parent exiting\n"</font>);
03203       _exit (0);
03204       <font class="keywordflow">break</font>;
03205     }
03206 
03207   _dbus_verbose (<font class="stringliteral">"calling setsid()\n"</font>);
03208   <font class="keywordflow">if</font> (setsid () == -1)
03209     _dbus_assert_not_reached (<font class="stringliteral">"setsid() failed"</font>);
03210   
03211   <font class="keywordflow">return</font> TRUE;
03212 }
03213 
03222 dbus_bool_t
<a name="l03223"></a><a class="code" href="group__DBusInternalsUtils.html#a106">03223</a> _dbus_write_pid_file (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *filename,
03224                       <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font>     pid,
03225                       <a class="code" href="structDBusError.html">DBusError</a>        *error)
03226 {
03227   <font class="keyword">const</font> <font class="keywordtype">char</font> *cfilename;
03228   <font class="keywordtype">int</font> fd;
03229   FILE *f;
03230 
03231   cfilename = _dbus_string_get_const_data (filename);
03232   
03233   fd = open (cfilename, O_WRONLY|O_CREAT|O_EXCL|O_BINARY, 0644);
03234   
03235   <font class="keywordflow">if</font> (fd &lt; 0)
03236     {
03237       dbus_set_error (error, _dbus_error_from_errno (errno),
03238                       <font class="stringliteral">"Failed to open \"%s\": %s"</font>, cfilename,
03239                       _dbus_strerror (errno));
03240       <font class="keywordflow">return</font> FALSE;
03241     }
03242 
03243   <font class="keywordflow">if</font> ((f = fdopen (fd, <font class="stringliteral">"w"</font>)) == NULL)
03244     {
03245       dbus_set_error (error, _dbus_error_from_errno (errno),
03246                       <font class="stringliteral">"Failed to fdopen fd %d: %s"</font>, fd, _dbus_strerror (errno));
03247       close (fd);
03248       <font class="keywordflow">return</font> FALSE;
03249     }
03250   
03251   <font class="keywordflow">if</font> (fprintf (f, <font class="stringliteral">"%lu\n"</font>, pid) &lt; 0)
03252     {
03253       dbus_set_error (error, _dbus_error_from_errno (errno),
03254                       <font class="stringliteral">"Failed to write to \"%s\": %s"</font>, cfilename,
03255                       _dbus_strerror (errno));
03256       <font class="keywordflow">return</font> FALSE;
03257     }
03258 
03259   <font class="keywordflow">if</font> (fclose (f) == EOF)
03260     {
03261       dbus_set_error (error, _dbus_error_from_errno (errno),
03262                       <font class="stringliteral">"Failed to close \"%s\": %s"</font>, cfilename,
03263                       _dbus_strerror (errno));
03264       <font class="keywordflow">return</font> FALSE;
03265     }
03266   
03267   <font class="keywordflow">return</font> TRUE;
03268 }
03269 
03278 dbus_bool_t
<a name="l03279"></a><a class="code" href="group__DBusInternalsUtils.html#a107">03279</a> _dbus_change_identity  (dbus_uid_t     uid,
03280                         dbus_gid_t     gid,
03281                         <a class="code" href="structDBusError.html">DBusError</a>     *error)
03282 {
03283   <font class="comment">/* Set GID first, or the setuid may remove our permission</font>
03284 <font class="comment">   * to change the GID</font>
03285 <font class="comment">   */</font>
03286   <font class="keywordflow">if</font> (setgid (gid) &lt; 0)
03287     {
03288       dbus_set_error (error, _dbus_error_from_errno (errno),
03289                       <font class="stringliteral">"Failed to set GID to %lu: %s"</font>, gid,
03290                       _dbus_strerror (errno));
03291       <font class="keywordflow">return</font> FALSE;
03292     }
03293   
03294   <font class="keywordflow">if</font> (setuid (uid) &lt; 0)
03295     {
03296       dbus_set_error (error, _dbus_error_from_errno (errno),
03297                       <font class="stringliteral">"Failed to set UID to %lu: %s"</font>, uid,
03298                       _dbus_strerror (errno));
03299       <font class="keywordflow">return</font> FALSE;
03300     }
03301   
03302   <font class="keywordflow">return</font> TRUE;
03303 }
03304 
03310 <font class="keywordtype">void</font>
<a name="l03311"></a><a class="code" href="group__DBusInternalsUtils.html#a108">03311</a> _dbus_set_signal_handler (<font class="keywordtype">int</font>               sig,
03312                           DBusSignalHandler handler)
03313 {
03314   <font class="keyword">struct </font>sigaction act;
03315   sigset_t empty_mask;
03316   
03317   sigemptyset (&amp;empty_mask);
03318   act.sa_handler = handler;
03319   act.sa_mask    = empty_mask;
03320   act.sa_flags   = 0;
03321   sigaction (sig,  &amp;act, 0);
03322 }
03323 
03324 
03325 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font>
03326 <font class="preprocessor"></font><font class="preprocessor">#include &lt;stdlib.h&gt;</font>
03327 <font class="keyword">static</font> <font class="keywordtype">void</font>
03328 check_dirname (<font class="keyword">const</font> <font class="keywordtype">char</font> *filename,
03329                <font class="keyword">const</font> <font class="keywordtype">char</font> *dirname)
03330 {
03331   <a class="code" href="structDBusString.html">DBusString</a> f, d;
03332   
03333   _dbus_string_init_const (&amp;f, filename);
03334 
03335   <font class="keywordflow">if</font> (!_dbus_string_init (&amp;d))
03336     _dbus_assert_not_reached (<font class="stringliteral">"no memory"</font>);
03337 
03338   <font class="keywordflow">if</font> (!_dbus_string_get_dirname (&amp;f, &amp;d))
03339     _dbus_assert_not_reached (<font class="stringliteral">"no memory"</font>);
03340 
03341   <font class="keywordflow">if</font> (!_dbus_string_equal_c_str (&amp;d, dirname))
03342     {
03343       _dbus_warn (<font class="stringliteral">"For filename \"%s\" got dirname \"%s\" and expected \"%s\"\n"</font>,
03344                   filename,
03345                   _dbus_string_get_const_data (&amp;d),
03346                   dirname);
03347       exit (1);
03348     }
03349 
03350   _dbus_string_free (&amp;d);
03351 }
03352 
03353 <font class="keyword">static</font> <font class="keywordtype">void</font>
03354 check_path_absolute (<font class="keyword">const</font> <font class="keywordtype">char</font> *path,
03355                      dbus_bool_t expected)
03356 {
03357   <a class="code" href="structDBusString.html">DBusString</a> p;
03358 
03359   _dbus_string_init_const (&amp;p, path);
03360 
03361   <font class="keywordflow">if</font> (_dbus_path_is_absolute (&amp;p) != expected)
03362     {
03363       _dbus_warn (<font class="stringliteral">"For path \"%s\" expected absolute = %d got %d\n"</font>,
03364                   path, expected, _dbus_path_is_absolute (&amp;p));
03365       exit (1);
03366     }
03367 }
03368 
03374 dbus_bool_t
<a name="l03375"></a><a class="code" href="group__DBusInternalsUtils.html#a111">03375</a> _dbus_sysdeps_test (<font class="keywordtype">void</font>)
03376 {
03377   <a class="code" href="structDBusString.html">DBusString</a> str;
03378   <font class="keywordtype">double</font> val;
03379   <font class="keywordtype">int</font> pos;
03380   
03381   check_dirname (<font class="stringliteral">"foo"</font>, <font class="stringliteral">"."</font>);
03382   check_dirname (<font class="stringliteral">"foo/bar"</font>, <font class="stringliteral">"foo"</font>);
03383   check_dirname (<font class="stringliteral">"foo//bar"</font>, <font class="stringliteral">"foo"</font>);
03384   check_dirname (<font class="stringliteral">"foo///bar"</font>, <font class="stringliteral">"foo"</font>);
03385   check_dirname (<font class="stringliteral">"foo/bar/"</font>, <font class="stringliteral">"foo"</font>);
03386   check_dirname (<font class="stringliteral">"foo//bar/"</font>, <font class="stringliteral">"foo"</font>);
03387   check_dirname (<font class="stringliteral">"foo///bar/"</font>, <font class="stringliteral">"foo"</font>);
03388   check_dirname (<font class="stringliteral">"foo/bar//"</font>, <font class="stringliteral">"foo"</font>);
03389   check_dirname (<font class="stringliteral">"foo//bar////"</font>, <font class="stringliteral">"foo"</font>);
03390   check_dirname (<font class="stringliteral">"foo///bar///////"</font>, <font class="stringliteral">"foo"</font>);
03391   check_dirname (<font class="stringliteral">"/foo"</font>, <font class="stringliteral">"/"</font>);
03392   check_dirname (<font class="stringliteral">"</font>
03393 <font class="stringliteral">  check_dirname ("</font>/foo/bar<font class="stringliteral">", "</font>/foo<font class="stringliteral">");</font>
03394 <font class="stringliteral">  check_dirname ("</font>/foo<font class="comment">//bar", "/foo");</font>
03395   check_dirname (<font class="stringliteral">"/foo///bar"</font>, <font class="stringliteral">"/foo"</font>);
03396   check_dirname (<font class="stringliteral">"/"</font>, <font class="stringliteral">"/"</font>);
03397   check_dirname (<font class="stringliteral">"</font>
03398 <font class="stringliteral">  check_dirname ("</font><font class="stringliteral">", "</font>.<font class="stringliteral">");  </font>
03399 <font class="stringliteral"></font>
03400 <font class="stringliteral"></font>
03401 <font class="stringliteral">  _dbus_string_init_const (&amp;str, "</font>3.5<font class="stringliteral">");</font>
03402 <font class="stringliteral">  if (!_dbus_string_parse_double (&amp;str,</font>
03403 <font class="stringliteral">                                  0, &amp;val, &amp;pos))</font>
03404 <font class="stringliteral">    {</font>
03405 <font class="stringliteral">      _dbus_warn ("</font>Failed to parse <font class="keywordtype">double</font><font class="stringliteral">");</font>
03406 <font class="stringliteral">      exit (1);</font>
03407 <font class="stringliteral">    }</font>
03408 <font class="stringliteral">  if (val != 3.5)</font>
03409 <font class="stringliteral">    {</font>
03410 <font class="stringliteral">      _dbus_warn ("</font>Failed to parse 3.5 correctly, got: %f<font class="stringliteral">", val);</font>
03411 <font class="stringliteral">      exit (1);</font>
03412 <font class="stringliteral">    }</font>
03413 <font class="stringliteral">  if (pos != 3)</font>
03414 <font class="stringliteral">    {</font>
03415 <font class="stringliteral">      _dbus_warn ("</font>_dbus_string_parse_double of \<font class="stringliteral">"3.5\" returned wrong position %d"</font>, pos);
03416       exit (1);
03417     }
03418 
03419   _dbus_string_init_const (&amp;str, <font class="stringliteral">"0xff"</font>);
03420   <font class="keywordflow">if</font> (!_dbus_string_parse_double (&amp;str,
03421                                   0, &amp;val, &amp;pos))
03422     {
03423       _dbus_warn (<font class="stringliteral">"Failed to parse double"</font>);
03424       exit (1);
03425     }
03426   <font class="keywordflow">if</font> (val != 0xff)
03427     {
03428       _dbus_warn (<font class="stringliteral">"Failed to parse 0xff correctly, got: %f"</font>, val);
03429       exit (1);
03430     }
03431   <font class="keywordflow">if</font> (pos != 4)
03432     {
03433       _dbus_warn (<font class="stringliteral">"_dbus_string_parse_double of \"0xff\" returned wrong position %d"</font>, pos);
03434       exit (1);
03435     }
03436   
03437   check_path_absolute (<font class="stringliteral">"/"</font>, TRUE);
03438   check_path_absolute (<font class="stringliteral">"/foo"</font>, TRUE);
03439   check_path_absolute (<font class="stringliteral">""</font>, FALSE);
03440   check_path_absolute (<font class="stringliteral">"foo"</font>, FALSE);
03441   check_path_absolute (<font class="stringliteral">"foo/bar"</font>, FALSE);
03442   
03443   <font class="keywordflow">return</font> TRUE;
03444 }
03445 <font class="preprocessor">#endif </font><font class="comment">/* DBUS_BUILD_TESTS */</font>
03446 
</pre></div><hr><address align="right"><small>Generated on Wed Jun 9 05:01:27 2004 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>