<!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> <a class="qindex" href="modules.html">Modules</a> <a class="qindex" href="annotated.html">Data Structures</a> <a class="qindex" href="files.html">File List</a> <a class="qindex" href="functions.html">Data Fields</a> <a class="qindex" href="pages.html">Related Pages</a> </center> <hr><h1>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 <sys/types.h></font> 00030 <font class="preprocessor">#include <stdlib.h></font> 00031 <font class="preprocessor">#include <string.h></font> 00032 <font class="preprocessor">#include <signal.h></font> 00033 <font class="preprocessor">#include <unistd.h></font> 00034 <font class="preprocessor">#include <stdio.h></font> 00035 <font class="preprocessor">#include <errno.h></font> 00036 <font class="preprocessor">#include <fcntl.h></font> 00037 <font class="preprocessor">#include <sys/socket.h></font> 00038 <font class="preprocessor">#include <dirent.h></font> 00039 <font class="preprocessor">#include <sys/un.h></font> 00040 <font class="preprocessor">#include <pwd.h></font> 00041 <font class="preprocessor">#include <time.h></font> 00042 <font class="preprocessor">#include <locale.h></font> 00043 <font class="preprocessor">#include <sys/time.h></font> 00044 <font class="preprocessor">#include <sys/stat.h></font> 00045 <font class="preprocessor">#include <sys/wait.h></font> 00046 <font class="preprocessor">#include <netinet/in.h></font> 00047 <font class="preprocessor">#include <netdb.h></font> 00048 <font class="preprocessor">#include <grp.h></font> 00049 00050 <font class="preprocessor">#ifdef HAVE_WRITEV</font> 00051 <font class="preprocessor"></font><font class="preprocessor">#include <sys/uio.h></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 <sys/poll.h></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 <execinfo.h></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 && *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 >= 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 < 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 > 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 < 0 && 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 > 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 >= 0); 00304 _dbus_assert (start2 >= 0); 00305 _dbus_assert (len1 >= 0); 00306 _dbus_assert (len2 >= 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 < 0 && 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 && buffer2 != NULL) 00348 { 00349 ret2 = _dbus_write (fd, buffer2, start2, len2); 00350 <font class="keywordflow">if</font> (ret2 < 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 < 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 (&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*) &addr, <font class="keyword">sizeof</font> (addr)) < 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 < 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 (&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, &sb) == 0 && 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*) &addr, <font class="keyword">sizeof</font> (addr)) < 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>) < 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> && chmod (path, 0777) < 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 < 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->h_addr_list)[0]); 00628 00629 _DBUS_ZERO (addr); 00630 memcpy (&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*) &addr, <font class="keyword">sizeof</font> (addr)) < 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 < 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->h_addr_list)[0]); 00701 00702 _DBUS_ZERO (addr); 00703 memcpy (&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*) &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>) < 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 < 0 && errno == EINTR) 00748 <font class="keywordflow">goto</font> again; 00749 00750 <font class="keywordflow">if</font> (bytes_written < 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) <= <font class="keyword">sizeof</font> (credentials-><a class="code" href="structDBusCredentials.html#m0">pid</a>)); 00810 _dbus_assert (<font class="keyword">sizeof</font> (uid_t) <= <font class="keyword">sizeof</font> (credentials-><a class="code" href="structDBusCredentials.html#m1">uid</a>)); 00811 _dbus_assert (<font class="keyword">sizeof</font> (gid_t) <= <font class="keyword">sizeof</font> (credentials-><a class="code" href="structDBusCredentials.html#m2">gid</a>)); 00812 00813 _dbus_credentials_clear (credentials); 00814 00815 <font class="preprocessor">#if defined(LOCAL_CREDS) && 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, &on, <font class="keyword">sizeof</font> (on)) < 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 = &buf; 00828 iov.iov_len = 1; 00829 00830 memset (&msg, 0, <font class="keyword">sizeof</font> (msg)); 00831 msg.msg_iov = &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, &msg, 0) < 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->cmsg_len < <font class="keyword">sizeof</font> (cmsgmem) || cmsg->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, &cr, &cr_len) == 0 && 00876 cr_len == <font class="keyword">sizeof</font> (cr)) 00877 { 00878 credentials-><a class="code" href="structDBusCredentials.html#m0">pid</a> = cr.pid; 00879 credentials-><a class="code" href="structDBusCredentials.html#m1">uid</a> = cr.uid; 00880 credentials-><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-><a class="code" href="structDBusCredentials.html#m0">pid</a> = cred->cmcred_pid; 00893 credentials-><a class="code" href="structDBusCredentials.html#m1">uid</a> = cred->cmcred_euid; 00894 credentials-><a class="code" href="structDBusCredentials.html#m2">gid</a> = cred->cmcred_groups[0]; 00895 <font class="preprocessor">#else </font><font class="comment">/* !SO_PEERCRED && !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-><a class="code" href="structDBusCredentials.html#m0">pid</a>, 00905 credentials-><a class="code" href="structDBusCredentials.html#m1">uid</a>, 00906 credentials-><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, &addr, &addrlen); 00958 00959 <font class="keywordflow">if</font> (client_fd < 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, &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, &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 >= <font class="charliteral">'0'</font> && c <= <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 >= <font class="charliteral">'a'</font> && c <= <font class="charliteral">'f'</font>) || 01191 (c >= <font class="charliteral">'A'</font> && c <= <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->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> && 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, &fail_pos); 01303 01304 <font class="keywordflow">if</font> (fail_pos) 01305 { 01306 <font class="keywordflow">if</font> (fail_pos > 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, &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, &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->pw_name != NULL); 01376 _dbus_assert (p->pw_dir != NULL); 01377 01378 info-><a class="code" href="structDBusUserInfo.html#m0">uid</a> = p->pw_uid; 01379 info-><a class="code" href="structDBusUserInfo.html#m1">primary_gid</a> = p->pw_gid; 01380 info-><a class="code" href="structDBusUserInfo.html#m4">username</a> = _dbus_strdup (p->pw_name); 01381 info-><a class="code" href="structDBusUserInfo.html#m5">homedir</a> = _dbus_strdup (p->pw_dir); 01382 01383 <font class="keywordflow">if</font> (info-><a class="code" href="structDBusUserInfo.html#m4">username</a> == NULL || 01384 info-><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-><a class="code" href="structDBusUserInfo.html#m0">uid</a> = DBUS_UID_UNSET; 01406 info-><a class="code" href="structDBusUserInfo.html#m1">primary_gid</a> = DBUS_GID_UNSET; 01407 info-><a class="code" href="structDBusUserInfo.html#m2">group_ids</a> = NULL; 01408 info-><a class="code" href="structDBusUserInfo.html#m3">n_group_ids</a> = 0; 01409 info-><a class="code" href="structDBusUserInfo.html#m4">username</a> = NULL; 01410 info-><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 >= 0) 01432 result = getpwuid_r (uid, &p_str, buf, <font class="keyword">sizeof</font> (buf), 01433 &p); 01434 <font class="keywordflow">else</font> 01435 result = getpwnam_r (username_c, &p_str, buf, <font class="keyword">sizeof</font> (buf), 01436 &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, &p_str, buf, <font class="keyword">sizeof</font> (buf)); 01440 <font class="keywordflow">else</font> 01441 p = getpwnam_r (username_c, &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 && p == &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-><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-><a class="code" href="structDBusUserInfo.html#m1">primary_gid</a>, 01503 buf, &buf_count) < 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-><a class="code" href="structDBusUserInfo.html#m1">primary_gid</a>, buf, &buf_count) < 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-><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-><a class="code" href="structDBusUserInfo.html#m2">group_ids</a> = dbus_new (dbus_gid_t, buf_count); 01530 <font class="keywordflow">if</font> (info-><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 < buf_count; ++i) 01538 info-><a class="code" href="structDBusUserInfo.html#m2">group_ids</a>[i] = buf[i]; 01539 01540 info-><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-><a class="code" href="structDBusUserInfo.html#m2">group_ids</a> = dbus_new (dbus_gid_t, 1); 01548 <font class="keywordflow">if</font> (info-><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-><a class="code" href="structDBusUserInfo.html#m3">n_group_ids</a> = 1; 01555 01556 (info-><a class="code" href="structDBusUserInfo.html#m2">group_ids</a>)[0] = info-><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-><a class="code" href="structDBusUserInfo.html#m2">group_ids</a>); 01613 dbus_free (info-><a class="code" href="structDBusUserInfo.html#m4">username</a>); 01614 dbus_free (info-><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->gr_name != NULL); 01623 01624 info-><a class="code" href="structDBusGroupInfo.html#m0">gid</a> = g->gr_gid; 01625 info-><a class="code" href="structDBusGroupInfo.html#m1">groupname</a> = _dbus_strdup (g->gr_name); 01626 01627 <font class="comment">/* info->members = dbus_strdupv (g->gr_mem) */</font> 01628 01629 <font class="keywordflow">if</font> (info-><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, &g_str, buf, <font class="keyword">sizeof</font> (buf), 01671 &g); 01672 <font class="keywordflow">else</font> 01673 result = getgrgid_r (gid, &g_str, buf, <font class="keyword">sizeof</font> (buf), 01674 &g); 01675 <font class="preprocessor">#else</font> 01676 <font class="preprocessor"></font> p = getgrnam_r (group_c_str, &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 && g == &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-><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-><a class="code" href="structDBusCredentials.html#m0">pid</a> = DBUS_PID_UNSET; 01770 credentials-><a class="code" href="structDBusCredentials.html#m1">uid</a> = DBUS_UID_UNSET; 01771 credentials-><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) <= <font class="keyword">sizeof</font> (credentials-><a class="code" href="structDBusCredentials.html#m0">pid</a>)); 01787 _dbus_assert (<font class="keyword">sizeof</font> (uid_t) <= <font class="keyword">sizeof</font> (credentials-><a class="code" href="structDBusCredentials.html#m1">uid</a>)); 01788 _dbus_assert (<font class="keyword">sizeof</font> (gid_t) <= <font class="keyword">sizeof</font> (credentials-><a class="code" href="structDBusCredentials.html#m2">gid</a>)); 01789 01790 credentials-><a class="code" href="structDBusCredentials.html#m0">pid</a> = getpid (); 01791 credentials-><a class="code" href="structDBusCredentials.html#m1">uid</a> = getuid (); 01792 credentials-><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-><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-><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-><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-><a class="code" href="structDBusCredentials.html#m1">uid</a> == expected_credentials-><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-><a class="code" href="structDBusAtomic.html#m0">value</a>) 01860 : "0" (val), "m" (atomic->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-><a class="code" href="structDBusAtomic.html#m0">value</a>; 01882 atomic-><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-><a class="code" href="structDBusAtomic.html#m0">value</a>; 01906 atomic-><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 && 01931 _DBUS_POLLPRI == POLLPRI && 01932 _DBUS_POLLOUT == POLLOUT && 01933 _DBUS_POLLERR == POLLERR && 01934 _DBUS_POLLHUP == POLLHUP && 01935 _DBUS_POLLNVAL == POLLNVAL && 01936 <font class="keyword">sizeof</font> (DBusPollFD) == <font class="keyword">sizeof</font> (<font class="keyword">struct </font>pollfd) && 01937 _DBUS_STRUCT_OFFSET (<a class="code" href="structDBusPollFD.html">DBusPollFD</a>, fd) == 01938 _DBUS_STRUCT_OFFSET (<font class="keyword">struct</font> pollfd, fd) && 01939 _DBUS_STRUCT_OFFSET (<a class="code" href="structDBusPollFD.html">DBusPollFD</a>, events) == 01940 _DBUS_STRUCT_OFFSET (<font class="keyword">struct</font> pollfd, events) && 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 (&read_set); 01965 FD_ZERO (&write_set); 01966 FD_ZERO (&err_set); 01967 01968 <font class="keywordflow">for</font> (i = 0; i < 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> & _DBUS_POLLIN) 01973 FD_SET (f.<a class="code" href="structDBusPollFD.html#m0">fd</a>, &read_set); 01974 01975 <font class="keywordflow">if</font> (f.<a class="code" href="structDBusPollFD.html#m1">events</a> & _DBUS_POLLOUT) 01976 FD_SET (f.<a class="code" href="structDBusPollFD.html#m0">fd</a>, &write_set); 01977 01978 FD_SET (f.<a class="code" href="structDBusPollFD.html#m0">fd</a>, &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, &read_set, &write_set, &err_set, &tv); 01987 01988 <font class="keywordflow">if</font> (ready > 0) 01989 { 01990 <font class="keywordflow">for</font> (i = 0; i < 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>, &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>, &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>, &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 (&req, &rem) < 0 && 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 (&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 < 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, &sb) < 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 > _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 > 0 && S_ISREG (sb.st_mode)) 02130 { 02131 <font class="keywordtype">int</font> bytes_read; 02132 02133 <font class="keywordflow">while</font> (total < (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 <= 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 (&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, &tmp_filename, 0)) 02210 { 02211 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02212 _dbus_string_free (&tmp_filename); 02213 <font class="keywordflow">return</font> FALSE; 02214 } 02215 02216 <font class="keywordflow">if</font> (!_dbus_string_append (&tmp_filename, <font class="stringliteral">"."</font>)) 02217 { 02218 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02219 _dbus_string_free (&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 (&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES)) 02225 { 02226 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02227 _dbus_string_free (&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 (&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 < 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 < 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 <= 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) < 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) < 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 >= 0) 02299 close (fd); 02300 02301 <font class="keywordflow">if</font> (need_unlink && unlink (tmp_filename_c) < 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 (&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 < 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) < 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) < 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) < 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 && 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 > 0 && _dbus_string_get_byte (filename, sep - 1) == <font class="charliteral">'/'</font>) 02506 --sep; 02507 02508 _dbus_assert (sep >= 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>, &sep); 02515 <font class="keywordflow">if</font> (sep < 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 > 0 && _dbus_string_get_byte (filename, sep - 1) == <font class="charliteral">'/'</font>) 02520 --sep; 02521 02522 _dbus_assert (sep >= 0); 02523 02524 <font class="keywordflow">if</font> (sep == 0 && 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) > 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-><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-><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->d_name[0] == <font class="charliteral">'.'</font> && 02632 (ent->d_name[1] == <font class="charliteral">'\0'</font> || 02633 (ent->d_name[1] == <font class="charliteral">'.'</font> && ent->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->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-><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, &tv_usec); 02674 srand (tv_usec); 02675 02676 i = 0; 02677 <font class="keywordflow">while</font> (i < 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 < 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 < 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 < 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, &sb) < 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-><a class="code" href="structDBusStat.html#m0">mode</a> = sb.st_mode; 02966 statbuf-><a class="code" href="structDBusStat.html#m1">nlink</a> = sb.st_nlink; 02967 statbuf-><a class="code" href="structDBusStat.html#m2">uid</a> = sb.st_uid; 02968 statbuf-><a class="code" href="structDBusStat.html#m3">gid</a> = sb.st_gid; 02969 statbuf-><a class="code" href="structDBusStat.html#m4">size</a> = sb.st_size; 02970 statbuf-><a class="code" href="structDBusStat.html#m5">atime</a> = sb.st_atime; 02971 statbuf-><a class="code" href="structDBusStat.html#m6">mtime</a> = sb.st_mtime; 02972 statbuf-><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) < 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 && 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) < 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 < 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) < 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) && 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 < 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>) < 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 >= 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 < 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) < 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) < 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) < 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 (&empty_mask); 03318 act.sa_handler = handler; 03319 act.sa_mask = empty_mask; 03320 act.sa_flags = 0; 03321 sigaction (sig, &act, 0); 03322 } 03323 03324 03325 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font> 03326 <font class="preprocessor"></font><font class="preprocessor">#include <stdlib.h></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 (&f, filename); 03334 03335 <font class="keywordflow">if</font> (!_dbus_string_init (&d)) 03336 _dbus_assert_not_reached (<font class="stringliteral">"no memory"</font>); 03337 03338 <font class="keywordflow">if</font> (!_dbus_string_get_dirname (&f, &d)) 03339 _dbus_assert_not_reached (<font class="stringliteral">"no memory"</font>); 03340 03341 <font class="keywordflow">if</font> (!_dbus_string_equal_c_str (&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 (&d), 03346 dirname); 03347 exit (1); 03348 } 03349 03350 _dbus_string_free (&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 (&p, path); 03360 03361 <font class="keywordflow">if</font> (_dbus_path_is_absolute (&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 (&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 (&str, "</font>3.5<font class="stringliteral">");</font> 03402 <font class="stringliteral"> if (!_dbus_string_parse_double (&str,</font> 03403 <font class="stringliteral"> 0, &val, &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 (&str, <font class="stringliteral">"0xff"</font>); 03420 <font class="keywordflow">if</font> (!_dbus_string_parse_double (&str, 03421 0, &val, &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>