D-Bus  1.5.10
dbus-sysdeps-unix.c
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
00002 /* dbus-sysdeps-unix.c Wrappers around UNIX system/libc features (internal to D-Bus implementation)
00003  *
00004  * Copyright (C) 2002, 2003, 2006  Red Hat, Inc.
00005  * Copyright (C) 2003 CodeFactory AB
00006  *
00007  * Licensed under the Academic Free License version 2.1
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022  *
00023  */
00024 
00025 #include <config.h>
00026 
00027 #include "dbus-internals.h"
00028 #include "dbus-sysdeps.h"
00029 #include "dbus-sysdeps-unix.h"
00030 #include "dbus-threads.h"
00031 #include "dbus-protocol.h"
00032 #include "dbus-transport.h"
00033 #include "dbus-string.h"
00034 #include "dbus-userdb.h"
00035 #include "dbus-list.h"
00036 #include "dbus-credentials.h"
00037 #include "dbus-nonce.h"
00038 
00039 #include <sys/types.h>
00040 #include <stdlib.h>
00041 #include <string.h>
00042 #include <signal.h>
00043 #include <unistd.h>
00044 #include <stdio.h>
00045 #include <fcntl.h>
00046 #include <sys/socket.h>
00047 #include <dirent.h>
00048 #include <sys/un.h>
00049 #include <pwd.h>
00050 #include <time.h>
00051 #include <locale.h>
00052 #include <sys/time.h>
00053 #include <sys/stat.h>
00054 #include <sys/wait.h>
00055 #include <netinet/in.h>
00056 #include <netdb.h>
00057 #include <grp.h>
00058 
00059 #ifdef HAVE_ERRNO_H
00060 #include <errno.h>
00061 #endif
00062 #ifdef HAVE_WRITEV
00063 #include <sys/uio.h>
00064 #endif
00065 #ifdef HAVE_POLL
00066 #include <sys/poll.h>
00067 #endif
00068 #ifdef HAVE_BACKTRACE
00069 #include <execinfo.h>
00070 #endif
00071 #ifdef HAVE_GETPEERUCRED
00072 #include <ucred.h>
00073 #endif
00074 
00075 #ifdef HAVE_ADT
00076 #include <bsm/adt.h>
00077 #endif
00078 
00079 #include "sd-daemon.h"
00080 
00081 #ifndef O_BINARY
00082 #define O_BINARY 0
00083 #endif
00084 
00085 #ifndef AI_ADDRCONFIG
00086 #define AI_ADDRCONFIG 0
00087 #endif
00088 
00089 #ifndef HAVE_SOCKLEN_T
00090 #define socklen_t int
00091 #endif
00092 
00093 #if defined (__sun) || defined (__sun__)
00094 /*
00095  * CMS_SPACE etc. definitions for Solaris < 10, based on
00096  *   http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html
00097  * via
00098  *   http://wiki.opencsw.org/porting-faq#toc10
00099  *
00100  * These are only redefined for Solaris, for now: if your OS needs these too,
00101  * please file a bug. (Or preferably, improve your OS so they're not needed.)
00102  */
00103 
00104 # ifndef CMSG_ALIGN
00105 #   ifdef __sun__
00106 #     define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
00107 #   else
00108       /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
00109 #     define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
00110                               ~(sizeof (long) - 1))
00111 #   endif
00112 # endif
00113 
00114 # ifndef CMSG_SPACE
00115 #   define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
00116                             CMSG_ALIGN (len))
00117 # endif
00118 
00119 # ifndef CMSG_LEN
00120 #   define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
00121 # endif
00122 
00123 #endif /* Solaris */
00124 
00125 static dbus_bool_t
00126 _dbus_open_socket (int              *fd_p,
00127                    int               domain,
00128                    int               type,
00129                    int               protocol,
00130                    DBusError        *error)
00131 {
00132 #ifdef SOCK_CLOEXEC
00133   dbus_bool_t cloexec_done;
00134 
00135   *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
00136   cloexec_done = *fd_p >= 0;
00137 
00138   /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
00139   if (*fd_p < 0 && errno == EINVAL)
00140 #endif
00141     {
00142       *fd_p = socket (domain, type, protocol);
00143     }
00144 
00145   if (*fd_p >= 0)
00146     {
00147 #ifdef SOCK_CLOEXEC
00148       if (!cloexec_done)
00149 #endif
00150         {
00151           _dbus_fd_set_close_on_exec(*fd_p);
00152         }
00153 
00154       _dbus_verbose ("socket fd %d opened\n", *fd_p);
00155       return TRUE;
00156     }
00157   else
00158     {
00159       dbus_set_error(error,
00160                      _dbus_error_from_errno (errno),
00161                      "Failed to open socket: %s",
00162                      _dbus_strerror (errno));
00163       return FALSE;
00164     }
00165 }
00166 
00177 static dbus_bool_t
00178 _dbus_open_unix_socket (int              *fd,
00179                         DBusError        *error)
00180 {
00181   return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
00182 }
00183 
00192 dbus_bool_t
00193 _dbus_close_socket (int               fd,
00194                     DBusError        *error)
00195 {
00196   return _dbus_close (fd, error);
00197 }
00198 
00208 int
00209 _dbus_read_socket (int               fd,
00210                    DBusString       *buffer,
00211                    int               count)
00212 {
00213   return _dbus_read (fd, buffer, count);
00214 }
00215 
00226 int
00227 _dbus_write_socket (int               fd,
00228                     const DBusString *buffer,
00229                     int               start,
00230                     int               len)
00231 {
00232 #if HAVE_DECL_MSG_NOSIGNAL
00233   const char *data;
00234   int bytes_written;
00235 
00236   data = _dbus_string_get_const_data_len (buffer, start, len);
00237 
00238  again:
00239 
00240   bytes_written = send (fd, data, len, MSG_NOSIGNAL);
00241 
00242   if (bytes_written < 0 && errno == EINTR)
00243     goto again;
00244 
00245   return bytes_written;
00246 
00247 #else
00248   return _dbus_write (fd, buffer, start, len);
00249 #endif
00250 }
00251 
00264 int
00265 _dbus_read_socket_with_unix_fds (int               fd,
00266                                  DBusString       *buffer,
00267                                  int               count,
00268                                  int              *fds,
00269                                  int              *n_fds) {
00270 #ifndef HAVE_UNIX_FD_PASSING
00271   int r;
00272 
00273   if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
00274     return r;
00275 
00276   *n_fds = 0;
00277   return r;
00278 
00279 #else
00280   int bytes_read;
00281   int start;
00282   struct msghdr m;
00283   struct iovec iov;
00284 
00285   _dbus_assert (count >= 0);
00286   _dbus_assert (*n_fds >= 0);
00287 
00288   start = _dbus_string_get_length (buffer);
00289 
00290   if (!_dbus_string_lengthen (buffer, count))
00291     {
00292       errno = ENOMEM;
00293       return -1;
00294     }
00295 
00296   _DBUS_ZERO(iov);
00297   iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
00298   iov.iov_len = count;
00299 
00300   _DBUS_ZERO(m);
00301   m.msg_iov = &iov;
00302   m.msg_iovlen = 1;
00303 
00304   /* Hmm, we have no clue how long the control data will actually be
00305      that is queued for us. The least we can do is assume that the
00306      caller knows. Hence let's make space for the number of fds that
00307      we shall read at max plus the cmsg header. */
00308   m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
00309 
00310   /* It's probably safe to assume that systems with SCM_RIGHTS also
00311      know alloca() */
00312   m.msg_control = alloca(m.msg_controllen);
00313   memset(m.msg_control, 0, m.msg_controllen);
00314 
00315  again:
00316 
00317   bytes_read = recvmsg(fd, &m, 0
00318 #ifdef MSG_CMSG_CLOEXEC
00319                        |MSG_CMSG_CLOEXEC
00320 #endif
00321                        );
00322 
00323   if (bytes_read < 0)
00324     {
00325       if (errno == EINTR)
00326         goto again;
00327       else
00328         {
00329           /* put length back (note that this doesn't actually realloc anything) */
00330           _dbus_string_set_length (buffer, start);
00331           return -1;
00332         }
00333     }
00334   else
00335     {
00336       struct cmsghdr *cm;
00337       dbus_bool_t found = FALSE;
00338 
00339       if (m.msg_flags & MSG_CTRUNC)
00340         {
00341           /* Hmm, apparently the control data was truncated. The bad
00342              thing is that we might have completely lost a couple of fds
00343              without chance to recover them. Hence let's treat this as a
00344              serious error. */
00345 
00346           errno = ENOSPC;
00347           _dbus_string_set_length (buffer, start);
00348           return -1;
00349         }
00350 
00351       for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
00352         if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
00353           {
00354             unsigned i;
00355 
00356             _dbus_assert(cm->cmsg_len <= CMSG_LEN(*n_fds * sizeof(int)));
00357             *n_fds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(int);
00358 
00359             memcpy(fds, CMSG_DATA(cm), *n_fds * sizeof(int));
00360             found = TRUE;
00361 
00362             /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
00363                worked, hence we need to go through this list and set
00364                CLOEXEC everywhere in any case */
00365             for (i = 0; i < *n_fds; i++)
00366               _dbus_fd_set_close_on_exec(fds[i]);
00367 
00368             break;
00369           }
00370 
00371       if (!found)
00372         *n_fds = 0;
00373 
00374       /* put length back (doesn't actually realloc) */
00375       _dbus_string_set_length (buffer, start + bytes_read);
00376 
00377 #if 0
00378       if (bytes_read > 0)
00379         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00380 #endif
00381 
00382       return bytes_read;
00383     }
00384 #endif
00385 }
00386 
00387 int
00388 _dbus_write_socket_with_unix_fds(int               fd,
00389                                  const DBusString *buffer,
00390                                  int               start,
00391                                  int               len,
00392                                  const int        *fds,
00393                                  int               n_fds) {
00394 
00395 #ifndef HAVE_UNIX_FD_PASSING
00396 
00397   if (n_fds > 0) {
00398     errno = ENOTSUP;
00399     return -1;
00400   }
00401 
00402   return _dbus_write_socket(fd, buffer, start, len);
00403 #else
00404   return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
00405 #endif
00406 }
00407 
00408 int
00409 _dbus_write_socket_with_unix_fds_two(int               fd,
00410                                      const DBusString *buffer1,
00411                                      int               start1,
00412                                      int               len1,
00413                                      const DBusString *buffer2,
00414                                      int               start2,
00415                                      int               len2,
00416                                      const int        *fds,
00417                                      int               n_fds) {
00418 
00419 #ifndef HAVE_UNIX_FD_PASSING
00420 
00421   if (n_fds > 0) {
00422     errno = ENOTSUP;
00423     return -1;
00424   }
00425 
00426   return _dbus_write_socket_two(fd,
00427                                 buffer1, start1, len1,
00428                                 buffer2, start2, len2);
00429 #else
00430 
00431   struct msghdr m;
00432   struct cmsghdr *cm;
00433   struct iovec iov[2];
00434   int bytes_written;
00435 
00436   _dbus_assert (len1 >= 0);
00437   _dbus_assert (len2 >= 0);
00438   _dbus_assert (n_fds >= 0);
00439 
00440   _DBUS_ZERO(iov);
00441   iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
00442   iov[0].iov_len = len1;
00443 
00444   if (buffer2)
00445     {
00446       iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
00447       iov[1].iov_len = len2;
00448     }
00449 
00450   _DBUS_ZERO(m);
00451   m.msg_iov = iov;
00452   m.msg_iovlen = buffer2 ? 2 : 1;
00453 
00454   if (n_fds > 0)
00455     {
00456       m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
00457       m.msg_control = alloca(m.msg_controllen);
00458       memset(m.msg_control, 0, m.msg_controllen);
00459 
00460       cm = CMSG_FIRSTHDR(&m);
00461       cm->cmsg_level = SOL_SOCKET;
00462       cm->cmsg_type = SCM_RIGHTS;
00463       cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
00464       memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
00465     }
00466 
00467  again:
00468 
00469   bytes_written = sendmsg (fd, &m, 0
00470 #if HAVE_DECL_MSG_NOSIGNAL
00471                            |MSG_NOSIGNAL
00472 #endif
00473                            );
00474 
00475   if (bytes_written < 0 && errno == EINTR)
00476     goto again;
00477 
00478 #if 0
00479   if (bytes_written > 0)
00480     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00481 #endif
00482 
00483   return bytes_written;
00484 #endif
00485 }
00486 
00500 int
00501 _dbus_write_socket_two (int               fd,
00502                         const DBusString *buffer1,
00503                         int               start1,
00504                         int               len1,
00505                         const DBusString *buffer2,
00506                         int               start2,
00507                         int               len2)
00508 {
00509 #if HAVE_DECL_MSG_NOSIGNAL
00510   struct iovec vectors[2];
00511   const char *data1;
00512   const char *data2;
00513   int bytes_written;
00514   struct msghdr m;
00515 
00516   _dbus_assert (buffer1 != NULL);
00517   _dbus_assert (start1 >= 0);
00518   _dbus_assert (start2 >= 0);
00519   _dbus_assert (len1 >= 0);
00520   _dbus_assert (len2 >= 0);
00521 
00522   data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00523 
00524   if (buffer2 != NULL)
00525     data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00526   else
00527     {
00528       data2 = NULL;
00529       start2 = 0;
00530       len2 = 0;
00531     }
00532 
00533   vectors[0].iov_base = (char*) data1;
00534   vectors[0].iov_len = len1;
00535   vectors[1].iov_base = (char*) data2;
00536   vectors[1].iov_len = len2;
00537 
00538   _DBUS_ZERO(m);
00539   m.msg_iov = vectors;
00540   m.msg_iovlen = data2 ? 2 : 1;
00541 
00542  again:
00543 
00544   bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
00545 
00546   if (bytes_written < 0 && errno == EINTR)
00547     goto again;
00548 
00549   return bytes_written;
00550 
00551 #else
00552   return _dbus_write_two (fd, buffer1, start1, len1,
00553                           buffer2, start2, len2);
00554 #endif
00555 }
00556 
00557 dbus_bool_t
00558 _dbus_socket_is_invalid (int fd)
00559 {
00560     return fd < 0 ? TRUE : FALSE;
00561 }
00562 
00579 int
00580 _dbus_read (int               fd,
00581             DBusString       *buffer,
00582             int               count)
00583 {
00584   int bytes_read;
00585   int start;
00586   char *data;
00587 
00588   _dbus_assert (count >= 0);
00589 
00590   start = _dbus_string_get_length (buffer);
00591 
00592   if (!_dbus_string_lengthen (buffer, count))
00593     {
00594       errno = ENOMEM;
00595       return -1;
00596     }
00597 
00598   data = _dbus_string_get_data_len (buffer, start, count);
00599 
00600  again:
00601 
00602   bytes_read = read (fd, data, count);
00603 
00604   if (bytes_read < 0)
00605     {
00606       if (errno == EINTR)
00607         goto again;
00608       else
00609         {
00610           /* put length back (note that this doesn't actually realloc anything) */
00611           _dbus_string_set_length (buffer, start);
00612           return -1;
00613         }
00614     }
00615   else
00616     {
00617       /* put length back (doesn't actually realloc) */
00618       _dbus_string_set_length (buffer, start + bytes_read);
00619 
00620 #if 0
00621       if (bytes_read > 0)
00622         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00623 #endif
00624 
00625       return bytes_read;
00626     }
00627 }
00628 
00639 int
00640 _dbus_write (int               fd,
00641              const DBusString *buffer,
00642              int               start,
00643              int               len)
00644 {
00645   const char *data;
00646   int bytes_written;
00647 
00648   data = _dbus_string_get_const_data_len (buffer, start, len);
00649 
00650  again:
00651 
00652   bytes_written = write (fd, data, len);
00653 
00654   if (bytes_written < 0 && errno == EINTR)
00655     goto again;
00656 
00657 #if 0
00658   if (bytes_written > 0)
00659     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00660 #endif
00661 
00662   return bytes_written;
00663 }
00664 
00685 int
00686 _dbus_write_two (int               fd,
00687                  const DBusString *buffer1,
00688                  int               start1,
00689                  int               len1,
00690                  const DBusString *buffer2,
00691                  int               start2,
00692                  int               len2)
00693 {
00694   _dbus_assert (buffer1 != NULL);
00695   _dbus_assert (start1 >= 0);
00696   _dbus_assert (start2 >= 0);
00697   _dbus_assert (len1 >= 0);
00698   _dbus_assert (len2 >= 0);
00699 
00700 #ifdef HAVE_WRITEV
00701   {
00702     struct iovec vectors[2];
00703     const char *data1;
00704     const char *data2;
00705     int bytes_written;
00706 
00707     data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00708 
00709     if (buffer2 != NULL)
00710       data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00711     else
00712       {
00713         data2 = NULL;
00714         start2 = 0;
00715         len2 = 0;
00716       }
00717 
00718     vectors[0].iov_base = (char*) data1;
00719     vectors[0].iov_len = len1;
00720     vectors[1].iov_base = (char*) data2;
00721     vectors[1].iov_len = len2;
00722 
00723   again:
00724 
00725     bytes_written = writev (fd,
00726                             vectors,
00727                             data2 ? 2 : 1);
00728 
00729     if (bytes_written < 0 && errno == EINTR)
00730       goto again;
00731 
00732     return bytes_written;
00733   }
00734 #else /* HAVE_WRITEV */
00735   {
00736     int ret1;
00737 
00738     ret1 = _dbus_write (fd, buffer1, start1, len1);
00739     if (ret1 == len1 && buffer2 != NULL)
00740       {
00741         ret2 = _dbus_write (fd, buffer2, start2, len2);
00742         if (ret2 < 0)
00743           ret2 = 0; /* we can't report an error as the first write was OK */
00744 
00745         return ret1 + ret2;
00746       }
00747     else
00748       return ret1;
00749   }
00750 #endif /* !HAVE_WRITEV */
00751 }
00752 
00753 #define _DBUS_MAX_SUN_PATH_LENGTH 99
00754 
00784 int
00785 _dbus_connect_unix_socket (const char     *path,
00786                            dbus_bool_t     abstract,
00787                            DBusError      *error)
00788 {
00789   int fd;
00790   size_t path_len;
00791   struct sockaddr_un addr;
00792 
00793   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00794 
00795   _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
00796                  path, abstract);
00797 
00798 
00799   if (!_dbus_open_unix_socket (&fd, error))
00800     {
00801       _DBUS_ASSERT_ERROR_IS_SET(error);
00802       return -1;
00803     }
00804   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00805 
00806   _DBUS_ZERO (addr);
00807   addr.sun_family = AF_UNIX;
00808   path_len = strlen (path);
00809 
00810   if (abstract)
00811     {
00812 #ifdef HAVE_ABSTRACT_SOCKETS
00813       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
00814       path_len++; /* Account for the extra nul byte added to the start of sun_path */
00815 
00816       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00817         {
00818           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00819                       "Abstract socket name too long\n");
00820           _dbus_close (fd, NULL);
00821           return -1;
00822         }
00823 
00824       strncpy (&addr.sun_path[1], path, path_len);
00825       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
00826 #else /* HAVE_ABSTRACT_SOCKETS */
00827       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00828                       "Operating system does not support abstract socket namespace\n");
00829       _dbus_close (fd, NULL);
00830       return -1;
00831 #endif /* ! HAVE_ABSTRACT_SOCKETS */
00832     }
00833   else
00834     {
00835       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00836         {
00837           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00838                       "Socket name too long\n");
00839           _dbus_close (fd, NULL);
00840           return -1;
00841         }
00842 
00843       strncpy (addr.sun_path, path, path_len);
00844     }
00845 
00846   if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
00847     {
00848       dbus_set_error (error,
00849                       _dbus_error_from_errno (errno),
00850                       "Failed to connect to socket %s: %s",
00851                       path, _dbus_strerror (errno));
00852 
00853       _dbus_close (fd, NULL);
00854       return -1;
00855     }
00856 
00857   if (!_dbus_set_fd_nonblocking (fd, error))
00858     {
00859       _DBUS_ASSERT_ERROR_IS_SET (error);
00860 
00861       _dbus_close (fd, NULL);
00862       return -1;
00863     }
00864 
00865   return fd;
00866 }
00867 
00877 static dbus_bool_t
00878 _dbus_set_local_creds (int fd, dbus_bool_t on)
00879 {
00880   dbus_bool_t retval = TRUE;
00881 
00882 #if defined(HAVE_CMSGCRED)
00883   /* NOOP just to make sure only one codepath is used
00884    *      and to prefer CMSGCRED
00885    */
00886 #elif defined(LOCAL_CREDS)
00887   int val = on ? 1 : 0;
00888   if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
00889     {
00890       _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
00891       retval = FALSE;
00892     }
00893   else
00894     _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
00895                    on ? "enabled" : "disabled", fd);
00896 #endif
00897 
00898   return retval;
00899 }
00900 
00918 int
00919 _dbus_listen_unix_socket (const char     *path,
00920                           dbus_bool_t     abstract,
00921                           DBusError      *error)
00922 {
00923   int listen_fd;
00924   struct sockaddr_un addr;
00925   size_t path_len;
00926   unsigned int reuseaddr;
00927 
00928   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00929 
00930   _dbus_verbose ("listening on unix socket %s abstract=%d\n",
00931                  path, abstract);
00932 
00933   if (!_dbus_open_unix_socket (&listen_fd, error))
00934     {
00935       _DBUS_ASSERT_ERROR_IS_SET(error);
00936       return -1;
00937     }
00938   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00939 
00940   _DBUS_ZERO (addr);
00941   addr.sun_family = AF_UNIX;
00942   path_len = strlen (path);
00943 
00944   if (abstract)
00945     {
00946 #ifdef HAVE_ABSTRACT_SOCKETS
00947       /* remember that abstract names aren't nul-terminated so we rely
00948        * on sun_path being filled in with zeroes above.
00949        */
00950       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
00951       path_len++; /* Account for the extra nul byte added to the start of sun_path */
00952 
00953       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00954         {
00955           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00956                       "Abstract socket name too long\n");
00957           _dbus_close (listen_fd, NULL);
00958           return -1;
00959         }
00960 
00961       strncpy (&addr.sun_path[1], path, path_len);
00962       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
00963 #else /* HAVE_ABSTRACT_SOCKETS */
00964       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00965                       "Operating system does not support abstract socket namespace\n");
00966       _dbus_close (listen_fd, NULL);
00967       return -1;
00968 #endif /* ! HAVE_ABSTRACT_SOCKETS */
00969     }
00970   else
00971     {
00972       /* Discussed security implications of this with Nalin,
00973        * and we couldn't think of where it would kick our ass, but
00974        * it still seems a bit sucky. It also has non-security suckage;
00975        * really we'd prefer to exit if the socket is already in use.
00976        * But there doesn't seem to be a good way to do this.
00977        *
00978        * Just to be extra careful, I threw in the stat() - clearly
00979        * the stat() can't *fix* any security issue, but it at least
00980        * avoids inadvertent/accidental data loss.
00981        */
00982       {
00983         struct stat sb;
00984 
00985         if (stat (path, &sb) == 0 &&
00986             S_ISSOCK (sb.st_mode))
00987           unlink (path);
00988       }
00989 
00990       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00991         {
00992           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00993                       "Abstract socket name too long\n");
00994           _dbus_close (listen_fd, NULL);
00995           return -1;
00996         }
00997 
00998       strncpy (addr.sun_path, path, path_len);
00999     }
01000 
01001   reuseaddr = 1;
01002   if (setsockopt  (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
01003     {
01004       _dbus_warn ("Failed to set socket option\"%s\": %s",
01005                   path, _dbus_strerror (errno));
01006     }
01007 
01008   if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
01009     {
01010       dbus_set_error (error, _dbus_error_from_errno (errno),
01011                       "Failed to bind socket \"%s\": %s",
01012                       path, _dbus_strerror (errno));
01013       _dbus_close (listen_fd, NULL);
01014       return -1;
01015     }
01016 
01017   if (listen (listen_fd, 30 /* backlog */) < 0)
01018     {
01019       dbus_set_error (error, _dbus_error_from_errno (errno),
01020                       "Failed to listen on socket \"%s\": %s",
01021                       path, _dbus_strerror (errno));
01022       _dbus_close (listen_fd, NULL);
01023       return -1;
01024     }
01025 
01026   if (!_dbus_set_local_creds (listen_fd, TRUE))
01027     {
01028       dbus_set_error (error, _dbus_error_from_errno (errno),
01029                       "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
01030                       path, _dbus_strerror (errno));
01031       close (listen_fd);
01032       return -1;
01033     }
01034 
01035   if (!_dbus_set_fd_nonblocking (listen_fd, error))
01036     {
01037       _DBUS_ASSERT_ERROR_IS_SET (error);
01038       _dbus_close (listen_fd, NULL);
01039       return -1;
01040     }
01041 
01042   /* Try opening up the permissions, but if we can't, just go ahead
01043    * and continue, maybe it will be good enough.
01044    */
01045   if (!abstract && chmod (path, 0777) < 0)
01046     _dbus_warn ("Could not set mode 0777 on socket %s\n",
01047                 path);
01048 
01049   return listen_fd;
01050 }
01051 
01062 int
01063 _dbus_listen_systemd_sockets (int       **fds,
01064                               DBusError *error)
01065 {
01066   int r, n;
01067   unsigned fd;
01068   int *new_fds;
01069 
01070   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01071 
01072   n = sd_listen_fds (TRUE);
01073   if (n < 0)
01074     {
01075       dbus_set_error (error, _dbus_error_from_errno (-n),
01076                       "Failed to acquire systemd socket: %s",
01077                       _dbus_strerror (-n));
01078       return -1;
01079     }
01080 
01081   if (n <= 0)
01082     {
01083       dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01084                       "No socket received.");
01085       return -1;
01086     }
01087 
01088   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01089     {
01090       r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
01091       if (r < 0)
01092         {
01093           dbus_set_error (error, _dbus_error_from_errno (-r),
01094                           "Failed to verify systemd socket type: %s",
01095                           _dbus_strerror (-r));
01096           return -1;
01097         }
01098 
01099       if (!r)
01100         {
01101           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01102                           "Passed socket has wrong type.");
01103           return -1;
01104         }
01105     }
01106 
01107   /* OK, the file descriptors are all good, so let's take posession of
01108      them then. */
01109 
01110   new_fds = dbus_new (int, n);
01111   if (!new_fds)
01112     {
01113       dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
01114                       "Failed to allocate file handle array.");
01115       goto fail;
01116     }
01117 
01118   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01119     {
01120       if (!_dbus_set_local_creds (fd, TRUE))
01121         {
01122           dbus_set_error (error, _dbus_error_from_errno (errno),
01123                           "Failed to enable LOCAL_CREDS on systemd socket: %s",
01124                           _dbus_strerror (errno));
01125           goto fail;
01126         }
01127 
01128       if (!_dbus_set_fd_nonblocking (fd, error))
01129         {
01130           _DBUS_ASSERT_ERROR_IS_SET (error);
01131           goto fail;
01132         }
01133 
01134       new_fds[fd - SD_LISTEN_FDS_START] = fd;
01135     }
01136 
01137   *fds = new_fds;
01138   return n;
01139 
01140  fail:
01141 
01142   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01143     {
01144       _dbus_close (fd, NULL);
01145     }
01146 
01147   dbus_free (new_fds);
01148   return -1;
01149 }
01150 
01164 int
01165 _dbus_connect_tcp_socket (const char     *host,
01166                           const char     *port,
01167                           const char     *family,
01168                           DBusError      *error)
01169 {
01170     return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
01171 }
01172 
01173 int
01174 _dbus_connect_tcp_socket_with_nonce (const char     *host,
01175                                      const char     *port,
01176                                      const char     *family,
01177                                      const char     *noncefile,
01178                                      DBusError      *error)
01179 {
01180   int saved_errno = 0;
01181   int fd = -1, res;
01182   struct addrinfo hints;
01183   struct addrinfo *ai, *tmp;
01184 
01185   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01186 
01187   _DBUS_ZERO (hints);
01188 
01189   if (!family)
01190     hints.ai_family = AF_UNSPEC;
01191   else if (!strcmp(family, "ipv4"))
01192     hints.ai_family = AF_INET;
01193   else if (!strcmp(family, "ipv6"))
01194     hints.ai_family = AF_INET6;
01195   else
01196     {
01197       dbus_set_error (error,
01198                       DBUS_ERROR_BAD_ADDRESS,
01199                       "Unknown address family %s", family);
01200       return -1;
01201     }
01202   hints.ai_protocol = IPPROTO_TCP;
01203   hints.ai_socktype = SOCK_STREAM;
01204   hints.ai_flags = AI_ADDRCONFIG;
01205 
01206   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
01207     {
01208       dbus_set_error (error,
01209                       _dbus_error_from_errno (errno),
01210                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01211                       host, port, gai_strerror(res), res);
01212       return -1;
01213     }
01214 
01215   tmp = ai;
01216   while (tmp)
01217     {
01218       if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01219         {
01220           freeaddrinfo(ai);
01221           _DBUS_ASSERT_ERROR_IS_SET(error);
01222           return -1;
01223         }
01224       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01225 
01226       if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01227         {
01228           saved_errno = errno;
01229           _dbus_close(fd, NULL);
01230           fd = -1;
01231           tmp = tmp->ai_next;
01232           continue;
01233         }
01234 
01235       break;
01236     }
01237   freeaddrinfo(ai);
01238 
01239   if (fd == -1)
01240     {
01241       dbus_set_error (error,
01242                       _dbus_error_from_errno (saved_errno),
01243                       "Failed to connect to socket \"%s:%s\" %s",
01244                       host, port, _dbus_strerror(saved_errno));
01245       return -1;
01246     }
01247 
01248   if (noncefile != NULL)
01249     {
01250       DBusString noncefileStr;
01251       dbus_bool_t ret;
01252       _dbus_string_init_const (&noncefileStr, noncefile);
01253       ret = _dbus_send_nonce (fd, &noncefileStr, error);
01254       _dbus_string_free (&noncefileStr);
01255 
01256       if (!ret)
01257     {
01258       _dbus_close (fd, NULL);
01259           return -1;
01260         }
01261     }
01262 
01263   if (!_dbus_set_fd_nonblocking (fd, error))
01264     {
01265       _dbus_close (fd, NULL);
01266       return -1;
01267     }
01268 
01269   return fd;
01270 }
01271 
01288 int
01289 _dbus_listen_tcp_socket (const char     *host,
01290                          const char     *port,
01291                          const char     *family,
01292                          DBusString     *retport,
01293                          int           **fds_p,
01294                          DBusError      *error)
01295 {
01296   int saved_errno;
01297   int nlisten_fd = 0, *listen_fd = NULL, res, i;
01298   struct addrinfo hints;
01299   struct addrinfo *ai, *tmp;
01300   unsigned int reuseaddr;
01301 
01302   *fds_p = NULL;
01303   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01304 
01305   _DBUS_ZERO (hints);
01306 
01307   if (!family)
01308     hints.ai_family = AF_UNSPEC;
01309   else if (!strcmp(family, "ipv4"))
01310     hints.ai_family = AF_INET;
01311   else if (!strcmp(family, "ipv6"))
01312     hints.ai_family = AF_INET6;
01313   else
01314     {
01315       dbus_set_error (error,
01316                       DBUS_ERROR_BAD_ADDRESS,
01317                       "Unknown address family %s", family);
01318       return -1;
01319     }
01320 
01321   hints.ai_protocol = IPPROTO_TCP;
01322   hints.ai_socktype = SOCK_STREAM;
01323   hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
01324 
01325  redo_lookup_with_port:
01326   ai = NULL;
01327   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
01328     {
01329       dbus_set_error (error,
01330                       _dbus_error_from_errno (errno),
01331                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01332                       host ? host : "*", port, gai_strerror(res), res);
01333       goto failed;
01334     }
01335 
01336   tmp = ai;
01337   while (tmp)
01338     {
01339       int fd = -1, *newlisten_fd;
01340       if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01341         {
01342           _DBUS_ASSERT_ERROR_IS_SET(error);
01343           goto failed;
01344         }
01345       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01346 
01347       reuseaddr = 1;
01348       if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
01349         {
01350           _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
01351                       host ? host : "*", port, _dbus_strerror (errno));
01352         }
01353 
01354       if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01355         {
01356           saved_errno = errno;
01357           _dbus_close(fd, NULL);
01358           if (saved_errno == EADDRINUSE)
01359             {
01360               /* Depending on kernel policy, it may or may not
01361                  be neccessary to bind to both IPv4 & 6 addresses
01362                  so ignore EADDRINUSE here */
01363               tmp = tmp->ai_next;
01364               continue;
01365             }
01366           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01367                           "Failed to bind socket \"%s:%s\": %s",
01368                           host ? host : "*", port, _dbus_strerror (saved_errno));
01369           goto failed;
01370         }
01371 
01372       if (listen (fd, 30 /* backlog */) < 0)
01373         {
01374           saved_errno = errno;
01375           _dbus_close (fd, NULL);
01376           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01377                           "Failed to listen on socket \"%s:%s\": %s",
01378                           host ? host : "*", port, _dbus_strerror (saved_errno));
01379           goto failed;
01380         }
01381 
01382       newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
01383       if (!newlisten_fd)
01384         {
01385           saved_errno = errno;
01386           _dbus_close (fd, NULL);
01387           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01388                           "Failed to allocate file handle array: %s",
01389                           _dbus_strerror (saved_errno));
01390           goto failed;
01391         }
01392       listen_fd = newlisten_fd;
01393       listen_fd[nlisten_fd] = fd;
01394       nlisten_fd++;
01395 
01396       if (!_dbus_string_get_length(retport))
01397         {
01398           /* If the user didn't specify a port, or used 0, then
01399              the kernel chooses a port. After the first address
01400              is bound to, we need to force all remaining addresses
01401              to use the same port */
01402           if (!port || !strcmp(port, "0"))
01403             {
01404               int result;
01405               struct sockaddr_storage addr;
01406               socklen_t addrlen;
01407               char portbuf[50];
01408 
01409               addrlen = sizeof(addr);
01410               result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
01411 
01412               if (result == -1 ||
01413                   (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
01414                                       portbuf, sizeof(portbuf),
01415                                       NI_NUMERICHOST)) != 0)
01416                 {
01417                   dbus_set_error (error, _dbus_error_from_errno (errno),
01418                                   "Failed to resolve port \"%s:%s\": %s (%s)",
01419                                   host ? host : "*", port, gai_strerror(res), res);
01420                   goto failed;
01421                 }
01422               if (!_dbus_string_append(retport, portbuf))
01423                 {
01424                   dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01425                   goto failed;
01426                 }
01427 
01428               /* Release current address list & redo lookup */
01429               port = _dbus_string_get_const_data(retport);
01430               freeaddrinfo(ai);
01431               goto redo_lookup_with_port;
01432             }
01433           else
01434             {
01435               if (!_dbus_string_append(retport, port))
01436                 {
01437                     dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01438                     goto failed;
01439                 }
01440             }
01441         }
01442 
01443       tmp = tmp->ai_next;
01444     }
01445   freeaddrinfo(ai);
01446   ai = NULL;
01447 
01448   if (!nlisten_fd)
01449     {
01450       errno = EADDRINUSE;
01451       dbus_set_error (error, _dbus_error_from_errno (errno),
01452                       "Failed to bind socket \"%s:%s\": %s",
01453                       host ? host : "*", port, _dbus_strerror (errno));
01454       goto failed;
01455     }
01456 
01457   for (i = 0 ; i < nlisten_fd ; i++)
01458     {
01459       if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
01460         {
01461           goto failed;
01462         }
01463     }
01464 
01465   *fds_p = listen_fd;
01466 
01467   return nlisten_fd;
01468 
01469  failed:
01470   if (ai)
01471     freeaddrinfo(ai);
01472   for (i = 0 ; i < nlisten_fd ; i++)
01473     _dbus_close(listen_fd[i], NULL);
01474   dbus_free(listen_fd);
01475   return -1;
01476 }
01477 
01478 static dbus_bool_t
01479 write_credentials_byte (int             server_fd,
01480                         DBusError      *error)
01481 {
01482   int bytes_written;
01483   char buf[1] = { '\0' };
01484 #if defined(HAVE_CMSGCRED)
01485   union {
01486           struct cmsghdr hdr;
01487           char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01488   } cmsg;
01489   struct iovec iov;
01490   struct msghdr msg;
01491   iov.iov_base = buf;
01492   iov.iov_len = 1;
01493 
01494   _DBUS_ZERO(msg);
01495   msg.msg_iov = &iov;
01496   msg.msg_iovlen = 1;
01497 
01498   msg.msg_control = (caddr_t) &cmsg;
01499   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01500   _DBUS_ZERO(cmsg);
01501   cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
01502   cmsg.hdr.cmsg_level = SOL_SOCKET;
01503   cmsg.hdr.cmsg_type = SCM_CREDS;
01504 #endif
01505 
01506   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01507 
01508  again:
01509 
01510 #if defined(HAVE_CMSGCRED)
01511   bytes_written = sendmsg (server_fd, &msg, 0
01512 #if HAVE_DECL_MSG_NOSIGNAL
01513                            |MSG_NOSIGNAL
01514 #endif
01515                            );
01516 #else
01517   bytes_written = send (server_fd, buf, 1, 0
01518 #if HAVE_DECL_MSG_NOSIGNAL
01519                         |MSG_NOSIGNAL
01520 #endif
01521                         );
01522 #endif
01523 
01524   if (bytes_written < 0 && errno == EINTR)
01525     goto again;
01526 
01527   if (bytes_written < 0)
01528     {
01529       dbus_set_error (error, _dbus_error_from_errno (errno),
01530                       "Failed to write credentials byte: %s",
01531                      _dbus_strerror (errno));
01532       return FALSE;
01533     }
01534   else if (bytes_written == 0)
01535     {
01536       dbus_set_error (error, DBUS_ERROR_IO_ERROR,
01537                       "wrote zero bytes writing credentials byte");
01538       return FALSE;
01539     }
01540   else
01541     {
01542       _dbus_assert (bytes_written == 1);
01543       _dbus_verbose ("wrote credentials byte\n");
01544       return TRUE;
01545     }
01546 }
01547 
01569 dbus_bool_t
01570 _dbus_read_credentials_socket  (int              client_fd,
01571                                 DBusCredentials *credentials,
01572                                 DBusError       *error)
01573 {
01574   struct msghdr msg;
01575   struct iovec iov;
01576   char buf;
01577   dbus_uid_t uid_read;
01578   dbus_pid_t pid_read;
01579   int bytes_read;
01580 
01581 #ifdef HAVE_CMSGCRED
01582   union {
01583     struct cmsghdr hdr;
01584     char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01585   } cmsg;
01586 
01587 #elif defined(LOCAL_CREDS)
01588   struct {
01589     struct cmsghdr hdr;
01590     struct sockcred cred;
01591   } cmsg;
01592 #endif
01593 
01594   uid_read = DBUS_UID_UNSET;
01595   pid_read = DBUS_PID_UNSET;
01596 
01597   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01598 
01599   /* The POSIX spec certainly doesn't promise this, but
01600    * we need these assertions to fail as soon as we're wrong about
01601    * it so we can do the porting fixups
01602    */
01603   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
01604   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
01605   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
01606 
01607   _dbus_credentials_clear (credentials);
01608 
01609   /* Systems supporting LOCAL_CREDS are configured to have this feature
01610    * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
01611    * the connection.  Therefore, the received message must carry the
01612    * credentials information without doing anything special.
01613    */
01614 
01615   iov.iov_base = &buf;
01616   iov.iov_len = 1;
01617 
01618   _DBUS_ZERO(msg);
01619   msg.msg_iov = &iov;
01620   msg.msg_iovlen = 1;
01621 
01622 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01623   _DBUS_ZERO(cmsg);
01624   msg.msg_control = (caddr_t) &cmsg;
01625   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01626 #endif
01627 
01628  again:
01629   bytes_read = recvmsg (client_fd, &msg, 0);
01630 
01631   if (bytes_read < 0)
01632     {
01633       if (errno == EINTR)
01634         goto again;
01635 
01636       /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
01637        * normally only call read_credentials if the socket was ready
01638        * for reading
01639        */
01640 
01641       dbus_set_error (error, _dbus_error_from_errno (errno),
01642                       "Failed to read credentials byte: %s",
01643                       _dbus_strerror (errno));
01644       return FALSE;
01645     }
01646   else if (bytes_read == 0)
01647     {
01648       /* this should not happen unless we are using recvmsg wrong,
01649        * so is essentially here for paranoia
01650        */
01651       dbus_set_error (error, DBUS_ERROR_FAILED,
01652                       "Failed to read credentials byte (zero-length read)");
01653       return FALSE;
01654     }
01655   else if (buf != '\0')
01656     {
01657       dbus_set_error (error, DBUS_ERROR_FAILED,
01658                       "Credentials byte was not nul");
01659       return FALSE;
01660     }
01661 
01662 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01663   if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
01664                   || cmsg.hdr.cmsg_type != SCM_CREDS)
01665     {
01666       dbus_set_error (error, DBUS_ERROR_FAILED,
01667                       "Message from recvmsg() was not SCM_CREDS");
01668       return FALSE;
01669     }
01670 #endif
01671 
01672   _dbus_verbose ("read credentials byte\n");
01673 
01674   {
01675 #ifdef SO_PEERCRED
01676 #ifdef __OpenBSD__
01677     struct sockpeercred cr;
01678 #else
01679     struct ucred cr;
01680 #endif
01681     int cr_len = sizeof (cr);
01682 
01683     if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
01684         cr_len == sizeof (cr))
01685       {
01686         pid_read = cr.pid;
01687         uid_read = cr.uid;
01688       }
01689     else
01690       {
01691         _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
01692                        cr_len, (int) sizeof (cr), _dbus_strerror (errno));
01693       }
01694 #elif defined(HAVE_CMSGCRED)
01695     struct cmsgcred *cred;
01696 
01697     cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
01698     pid_read = cred->cmcred_pid;
01699     uid_read = cred->cmcred_euid;
01700 #elif defined(LOCAL_CREDS)
01701     pid_read = DBUS_PID_UNSET;
01702     uid_read = cmsg.cred.sc_uid;
01703     /* Since we have already got the credentials from this socket, we can
01704      * disable its LOCAL_CREDS flag if it was ever set. */
01705     _dbus_set_local_creds (client_fd, FALSE);
01706 #elif defined(HAVE_GETPEEREID)
01707     uid_t euid;
01708     gid_t egid;
01709     if (getpeereid (client_fd, &euid, &egid) == 0)
01710       {
01711         uid_read = euid;
01712       }
01713     else
01714       {
01715         _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
01716       }
01717 #elif defined(HAVE_GETPEERUCRED)
01718     ucred_t * ucred = NULL;
01719     if (getpeerucred (client_fd, &ucred) == 0)
01720       {
01721         pid_read = ucred_getpid (ucred);
01722         uid_read = ucred_geteuid (ucred);
01723 #ifdef HAVE_ADT
01724         /* generate audit session data based on socket ucred */
01725         adt_session_data_t *adth = NULL;
01726         adt_export_data_t *data = NULL;
01727         size_t size = 0;
01728         if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
01729           {
01730             _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
01731           }
01732         else
01733           {
01734             if (adt_set_from_ucred (adth, ucred, ADT_NEW))
01735               {
01736                 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
01737               }
01738             else
01739               {
01740                 size = adt_export_session_data (adth, &data);
01741                 if (size <= 0)
01742                   {
01743                     _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
01744                   }
01745                 else
01746                   {
01747                     _dbus_credentials_add_adt_audit_data (credentials, data, size);
01748                     free (data);
01749                   }
01750               }
01751             (void) adt_end_session (adth);
01752           }
01753 #endif /* HAVE_ADT */
01754       }
01755     else
01756       {
01757         _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
01758       }
01759     if (ucred != NULL)
01760       ucred_free (ucred);
01761 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
01762     _dbus_verbose ("Socket credentials not supported on this OS\n");
01763 #endif
01764   }
01765 
01766   _dbus_verbose ("Credentials:"
01767                  "  pid "DBUS_PID_FORMAT
01768                  "  uid "DBUS_UID_FORMAT
01769                  "\n",
01770                  pid_read,
01771                  uid_read);
01772 
01773   if (pid_read != DBUS_PID_UNSET)
01774     {
01775       if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
01776         {
01777           _DBUS_SET_OOM (error);
01778           return FALSE;
01779         }
01780     }
01781 
01782   if (uid_read != DBUS_UID_UNSET)
01783     {
01784       if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
01785         {
01786           _DBUS_SET_OOM (error);
01787           return FALSE;
01788         }
01789     }
01790 
01791   return TRUE;
01792 }
01793 
01811 dbus_bool_t
01812 _dbus_send_credentials_socket  (int              server_fd,
01813                                 DBusError       *error)
01814 {
01815   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01816 
01817   if (write_credentials_byte (server_fd, error))
01818     return TRUE;
01819   else
01820     return FALSE;
01821 }
01822 
01832 int
01833 _dbus_accept  (int listen_fd)
01834 {
01835   int client_fd;
01836   struct sockaddr addr;
01837   socklen_t addrlen;
01838 #ifdef HAVE_ACCEPT4
01839   dbus_bool_t cloexec_done;
01840 #endif
01841 
01842   addrlen = sizeof (addr);
01843 
01844  retry:
01845 
01846 #ifdef HAVE_ACCEPT4
01847   /* We assume that if accept4 is available SOCK_CLOEXEC is too */
01848   client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
01849   cloexec_done = client_fd >= 0;
01850 
01851   if (client_fd < 0 && errno == ENOSYS)
01852 #endif
01853     {
01854       client_fd = accept (listen_fd, &addr, &addrlen);
01855     }
01856 
01857   if (client_fd < 0)
01858     {
01859       if (errno == EINTR)
01860         goto retry;
01861     }
01862 
01863   _dbus_verbose ("client fd %d accepted\n", client_fd);
01864 
01865 #ifdef HAVE_ACCEPT4
01866   if (!cloexec_done)
01867 #endif
01868     {
01869       _dbus_fd_set_close_on_exec(client_fd);
01870     }
01871 
01872   return client_fd;
01873 }
01874 
01883 dbus_bool_t
01884 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
01885 {
01886   const char *directory;
01887   struct stat sb;
01888 
01889   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01890 
01891   directory = _dbus_string_get_const_data (dir);
01892 
01893   if (stat (directory, &sb) < 0)
01894     {
01895       dbus_set_error (error, _dbus_error_from_errno (errno),
01896                       "%s", _dbus_strerror (errno));
01897 
01898       return FALSE;
01899     }
01900 
01901   if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
01902       (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
01903     {
01904       dbus_set_error (error, DBUS_ERROR_FAILED,
01905                      "%s directory is not private to the user", directory);
01906       return FALSE;
01907     }
01908 
01909   return TRUE;
01910 }
01911 
01912 static dbus_bool_t
01913 fill_user_info_from_passwd (struct passwd *p,
01914                             DBusUserInfo  *info,
01915                             DBusError     *error)
01916 {
01917   _dbus_assert (p->pw_name != NULL);
01918   _dbus_assert (p->pw_dir != NULL);
01919 
01920   info->uid = p->pw_uid;
01921   info->primary_gid = p->pw_gid;
01922   info->username = _dbus_strdup (p->pw_name);
01923   info->homedir = _dbus_strdup (p->pw_dir);
01924 
01925   if (info->username == NULL ||
01926       info->homedir == NULL)
01927     {
01928       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01929       return FALSE;
01930     }
01931 
01932   return TRUE;
01933 }
01934 
01935 static dbus_bool_t
01936 fill_user_info (DBusUserInfo       *info,
01937                 dbus_uid_t          uid,
01938                 const DBusString   *username,
01939                 DBusError          *error)
01940 {
01941   const char *username_c;
01942 
01943   /* exactly one of username/uid provided */
01944   _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
01945   _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
01946 
01947   info->uid = DBUS_UID_UNSET;
01948   info->primary_gid = DBUS_GID_UNSET;
01949   info->group_ids = NULL;
01950   info->n_group_ids = 0;
01951   info->username = NULL;
01952   info->homedir = NULL;
01953 
01954   if (username != NULL)
01955     username_c = _dbus_string_get_const_data (username);
01956   else
01957     username_c = NULL;
01958 
01959   /* For now assuming that the getpwnam() and getpwuid() flavors
01960    * are always symmetrical, if not we have to add more configure
01961    * checks
01962    */
01963 
01964 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
01965   {
01966     struct passwd *p;
01967     int result;
01968     size_t buflen;
01969     char *buf;
01970     struct passwd p_str;
01971 
01972     /* retrieve maximum needed size for buf */
01973     buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
01974 
01975     /* sysconf actually returns a long, but everything else expects size_t,
01976      * so just recast here.
01977      * https://bugs.freedesktop.org/show_bug.cgi?id=17061
01978      */
01979     if ((long) buflen <= 0)
01980       buflen = 1024;
01981 
01982     result = -1;
01983     while (1)
01984       {
01985         buf = dbus_malloc (buflen);
01986         if (buf == NULL)
01987           {
01988             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01989             return FALSE;
01990           }
01991 
01992         p = NULL;
01993 #ifdef HAVE_POSIX_GETPWNAM_R
01994         if (uid != DBUS_UID_UNSET)
01995           result = getpwuid_r (uid, &p_str, buf, buflen,
01996                                &p);
01997         else
01998           result = getpwnam_r (username_c, &p_str, buf, buflen,
01999                                &p);
02000 #else
02001         if (uid != DBUS_UID_UNSET)
02002           p = getpwuid_r (uid, &p_str, buf, buflen);
02003         else
02004           p = getpwnam_r (username_c, &p_str, buf, buflen);
02005         result = 0;
02006 #endif /* !HAVE_POSIX_GETPWNAM_R */
02007         //Try a bigger buffer if ERANGE was returned
02008         if (result == ERANGE && buflen < 512 * 1024)
02009           {
02010             dbus_free (buf);
02011             buflen *= 2;
02012           }
02013         else
02014           {
02015             break;
02016           }
02017       }
02018     if (result == 0 && p == &p_str)
02019       {
02020         if (!fill_user_info_from_passwd (p, info, error))
02021           {
02022             dbus_free (buf);
02023             return FALSE;
02024           }
02025         dbus_free (buf);
02026       }
02027     else
02028       {
02029         dbus_set_error (error, _dbus_error_from_errno (errno),
02030                         "User \"%s\" unknown or no memory to allocate password entry\n",
02031                         username_c ? username_c : "???");
02032         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02033         dbus_free (buf);
02034         return FALSE;
02035       }
02036   }
02037 #else /* ! HAVE_GETPWNAM_R */
02038   {
02039     /* I guess we're screwed on thread safety here */
02040     struct passwd *p;
02041 
02042     if (uid != DBUS_UID_UNSET)
02043       p = getpwuid (uid);
02044     else
02045       p = getpwnam (username_c);
02046 
02047     if (p != NULL)
02048       {
02049         if (!fill_user_info_from_passwd (p, info, error))
02050           {
02051             return FALSE;
02052           }
02053       }
02054     else
02055       {
02056         dbus_set_error (error, _dbus_error_from_errno (errno),
02057                         "User \"%s\" unknown or no memory to allocate password entry\n",
02058                         username_c ? username_c : "???");
02059         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02060         return FALSE;
02061       }
02062   }
02063 #endif  /* ! HAVE_GETPWNAM_R */
02064 
02065   /* Fill this in so we can use it to get groups */
02066   username_c = info->username;
02067 
02068 #ifdef HAVE_GETGROUPLIST
02069   {
02070     gid_t *buf;
02071     int buf_count;
02072     int i;
02073     int initial_buf_count;
02074 
02075     initial_buf_count = 17;
02076     buf_count = initial_buf_count;
02077     buf = dbus_new (gid_t, buf_count);
02078     if (buf == NULL)
02079       {
02080         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02081         goto failed;
02082       }
02083 
02084     if (getgrouplist (username_c,
02085                       info->primary_gid,
02086                       buf, &buf_count) < 0)
02087       {
02088         gid_t *new;
02089         /* Presumed cause of negative return code: buf has insufficient
02090            entries to hold the entire group list. The Linux behavior in this
02091            case is to pass back the actual number of groups in buf_count, but
02092            on Mac OS X 10.5, buf_count is unhelpfully left alone.
02093            So as a hack, try to help out a bit by guessing a larger
02094            number of groups, within reason.. might still fail, of course,
02095            but we can at least print a more informative message.  I looked up
02096            the "right way" to do this by downloading Apple's own source code
02097            for the "id" command, and it turns out that they use an
02098            undocumented library function getgrouplist_2 (!) which is not
02099            declared in any header in /usr/include (!!). That did not seem
02100            like the way to go here.
02101         */
02102         if (buf_count == initial_buf_count)
02103           {
02104             buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
02105           }
02106         new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
02107         if (new == NULL)
02108           {
02109             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02110             dbus_free (buf);
02111             goto failed;
02112           }
02113 
02114         buf = new;
02115 
02116         errno = 0;
02117         if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
02118           {
02119             if (errno == 0)
02120               {
02121                 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
02122                             username_c, buf_count, buf_count);
02123               }
02124             else
02125               {
02126                 dbus_set_error (error,
02127                                 _dbus_error_from_errno (errno),
02128                                 "Failed to get groups for username \"%s\" primary GID "
02129                                 DBUS_GID_FORMAT ": %s\n",
02130                                 username_c, info->primary_gid,
02131                                 _dbus_strerror (errno));
02132                 dbus_free (buf);
02133                 goto failed;
02134               }
02135           }
02136       }
02137 
02138     info->group_ids = dbus_new (dbus_gid_t, buf_count);
02139     if (info->group_ids == NULL)
02140       {
02141         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02142         dbus_free (buf);
02143         goto failed;
02144       }
02145 
02146     for (i = 0; i < buf_count; ++i)
02147       info->group_ids[i] = buf[i];
02148 
02149     info->n_group_ids = buf_count;
02150 
02151     dbus_free (buf);
02152   }
02153 #else  /* HAVE_GETGROUPLIST */
02154   {
02155     /* We just get the one group ID */
02156     info->group_ids = dbus_new (dbus_gid_t, 1);
02157     if (info->group_ids == NULL)
02158       {
02159         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02160         goto failed;
02161       }
02162 
02163     info->n_group_ids = 1;
02164 
02165     (info->group_ids)[0] = info->primary_gid;
02166   }
02167 #endif /* HAVE_GETGROUPLIST */
02168 
02169   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02170 
02171   return TRUE;
02172 
02173  failed:
02174   _DBUS_ASSERT_ERROR_IS_SET (error);
02175   return FALSE;
02176 }
02177 
02186 dbus_bool_t
02187 _dbus_user_info_fill (DBusUserInfo     *info,
02188                       const DBusString *username,
02189                       DBusError        *error)
02190 {
02191   return fill_user_info (info, DBUS_UID_UNSET,
02192                          username, error);
02193 }
02194 
02203 dbus_bool_t
02204 _dbus_user_info_fill_uid (DBusUserInfo *info,
02205                           dbus_uid_t    uid,
02206                           DBusError    *error)
02207 {
02208   return fill_user_info (info, uid,
02209                          NULL, error);
02210 }
02211 
02219 dbus_bool_t
02220 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
02221 {
02222   /* The POSIX spec certainly doesn't promise this, but
02223    * we need these assertions to fail as soon as we're wrong about
02224    * it so we can do the porting fixups
02225    */
02226   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
02227   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
02228   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
02229 
02230   if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
02231     return FALSE;
02232   if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
02233     return FALSE;
02234 
02235   return TRUE;
02236 }
02237 
02249 dbus_bool_t
02250 _dbus_append_user_from_current_process (DBusString *str)
02251 {
02252   return _dbus_string_append_uint (str,
02253                                    _dbus_geteuid ());
02254 }
02255 
02260 dbus_pid_t
02261 _dbus_getpid (void)
02262 {
02263   return getpid ();
02264 }
02265 
02269 dbus_uid_t
02270 _dbus_getuid (void)
02271 {
02272   return getuid ();
02273 }
02274 
02278 dbus_uid_t
02279 _dbus_geteuid (void)
02280 {
02281   return geteuid ();
02282 }
02283 
02290 unsigned long
02291 _dbus_pid_for_log (void)
02292 {
02293   return getpid ();
02294 }
02295 
02303 dbus_bool_t
02304 _dbus_parse_uid (const DBusString      *uid_str,
02305                  dbus_uid_t            *uid)
02306 {
02307   int end;
02308   long val;
02309 
02310   if (_dbus_string_get_length (uid_str) == 0)
02311     {
02312       _dbus_verbose ("UID string was zero length\n");
02313       return FALSE;
02314     }
02315 
02316   val = -1;
02317   end = 0;
02318   if (!_dbus_string_parse_int (uid_str, 0, &val,
02319                                &end))
02320     {
02321       _dbus_verbose ("could not parse string as a UID\n");
02322       return FALSE;
02323     }
02324 
02325   if (end != _dbus_string_get_length (uid_str))
02326     {
02327       _dbus_verbose ("string contained trailing stuff after UID\n");
02328       return FALSE;
02329     }
02330 
02331   *uid = val;
02332 
02333   return TRUE;
02334 }
02335 
02336 #if !DBUS_USE_SYNC
02337 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
02338 #endif
02339 
02346 dbus_int32_t
02347 _dbus_atomic_inc (DBusAtomic *atomic)
02348 {
02349 #if DBUS_USE_SYNC
02350   return __sync_add_and_fetch(&atomic->value, 1)-1;
02351 #else
02352   dbus_int32_t res;
02353   _DBUS_LOCK (atomic);
02354   res = atomic->value;
02355   atomic->value += 1;
02356   _DBUS_UNLOCK (atomic);
02357   return res;
02358 #endif
02359 }
02360 
02367 dbus_int32_t
02368 _dbus_atomic_dec (DBusAtomic *atomic)
02369 {
02370 #if DBUS_USE_SYNC
02371   return __sync_sub_and_fetch(&atomic->value, 1)+1;
02372 #else
02373   dbus_int32_t res;
02374 
02375   _DBUS_LOCK (atomic);
02376   res = atomic->value;
02377   atomic->value -= 1;
02378   _DBUS_UNLOCK (atomic);
02379   return res;
02380 #endif
02381 }
02382 
02390 dbus_int32_t
02391 _dbus_atomic_get (DBusAtomic *atomic)
02392 {
02393 #if DBUS_USE_SYNC
02394   __sync_synchronize ();
02395   return atomic->value;
02396 #else
02397   dbus_int32_t res;
02398 
02399   _DBUS_LOCK (atomic);
02400   res = atomic->value;
02401   _DBUS_UNLOCK (atomic);
02402   return res;
02403 #endif
02404 }
02405 
02414 int
02415 _dbus_poll (DBusPollFD *fds,
02416             int         n_fds,
02417             int         timeout_milliseconds)
02418 {
02419 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
02420   /* This big thing is a constant expression and should get optimized
02421    * out of existence. So it's more robust than a configure check at
02422    * no cost.
02423    */
02424   if (_DBUS_POLLIN == POLLIN &&
02425       _DBUS_POLLPRI == POLLPRI &&
02426       _DBUS_POLLOUT == POLLOUT &&
02427       _DBUS_POLLERR == POLLERR &&
02428       _DBUS_POLLHUP == POLLHUP &&
02429       _DBUS_POLLNVAL == POLLNVAL &&
02430       sizeof (DBusPollFD) == sizeof (struct pollfd) &&
02431       _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
02432       _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
02433       _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
02434       _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
02435       _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
02436       _DBUS_STRUCT_OFFSET (struct pollfd, revents))
02437     {
02438       return poll ((struct pollfd*) fds,
02439                    n_fds,
02440                    timeout_milliseconds);
02441     }
02442   else
02443     {
02444       /* We have to convert the DBusPollFD to an array of
02445        * struct pollfd, poll, and convert back.
02446        */
02447       _dbus_warn ("didn't implement poll() properly for this system yet\n");
02448       return -1;
02449     }
02450 #else /* ! HAVE_POLL */
02451 
02452   fd_set read_set, write_set, err_set;
02453   int max_fd = 0;
02454   int i;
02455   struct timeval tv;
02456   int ready;
02457 
02458   FD_ZERO (&read_set);
02459   FD_ZERO (&write_set);
02460   FD_ZERO (&err_set);
02461 
02462   for (i = 0; i < n_fds; i++)
02463     {
02464       DBusPollFD *fdp = &fds[i];
02465 
02466       if (fdp->events & _DBUS_POLLIN)
02467         FD_SET (fdp->fd, &read_set);
02468 
02469       if (fdp->events & _DBUS_POLLOUT)
02470         FD_SET (fdp->fd, &write_set);
02471 
02472       FD_SET (fdp->fd, &err_set);
02473 
02474       max_fd = MAX (max_fd, fdp->fd);
02475     }
02476 
02477   tv.tv_sec = timeout_milliseconds / 1000;
02478   tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
02479 
02480   ready = select (max_fd + 1, &read_set, &write_set, &err_set,
02481                   timeout_milliseconds < 0 ? NULL : &tv);
02482 
02483   if (ready > 0)
02484     {
02485       for (i = 0; i < n_fds; i++)
02486         {
02487           DBusPollFD *fdp = &fds[i];
02488 
02489           fdp->revents = 0;
02490 
02491           if (FD_ISSET (fdp->fd, &read_set))
02492             fdp->revents |= _DBUS_POLLIN;
02493 
02494           if (FD_ISSET (fdp->fd, &write_set))
02495             fdp->revents |= _DBUS_POLLOUT;
02496 
02497           if (FD_ISSET (fdp->fd, &err_set))
02498             fdp->revents |= _DBUS_POLLERR;
02499         }
02500     }
02501 
02502   return ready;
02503 #endif
02504 }
02505 
02513 void
02514 _dbus_get_current_time (long *tv_sec,
02515                         long *tv_usec)
02516 {
02517 #ifdef HAVE_MONOTONIC_CLOCK
02518   struct timespec ts;
02519   clock_gettime (CLOCK_MONOTONIC, &ts);
02520 
02521   if (tv_sec)
02522     *tv_sec = ts.tv_sec;
02523   if (tv_usec)
02524     *tv_usec = ts.tv_nsec / 1000;
02525 #else
02526   struct timeval t;
02527 
02528   gettimeofday (&t, NULL);
02529 
02530   if (tv_sec)
02531     *tv_sec = t.tv_sec;
02532   if (tv_usec)
02533     *tv_usec = t.tv_usec;
02534 #endif
02535 }
02536 
02545 dbus_bool_t
02546 _dbus_create_directory (const DBusString *filename,
02547                         DBusError        *error)
02548 {
02549   const char *filename_c;
02550 
02551   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02552 
02553   filename_c = _dbus_string_get_const_data (filename);
02554 
02555   if (mkdir (filename_c, 0700) < 0)
02556     {
02557       if (errno == EEXIST)
02558         return TRUE;
02559 
02560       dbus_set_error (error, DBUS_ERROR_FAILED,
02561                       "Failed to create directory %s: %s\n",
02562                       filename_c, _dbus_strerror (errno));
02563       return FALSE;
02564     }
02565   else
02566     return TRUE;
02567 }
02568 
02579 dbus_bool_t
02580 _dbus_concat_dir_and_file (DBusString       *dir,
02581                            const DBusString *next_component)
02582 {
02583   dbus_bool_t dir_ends_in_slash;
02584   dbus_bool_t file_starts_with_slash;
02585 
02586   if (_dbus_string_get_length (dir) == 0 ||
02587       _dbus_string_get_length (next_component) == 0)
02588     return TRUE;
02589 
02590   dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
02591                                                     _dbus_string_get_length (dir) - 1);
02592 
02593   file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
02594 
02595   if (dir_ends_in_slash && file_starts_with_slash)
02596     {
02597       _dbus_string_shorten (dir, 1);
02598     }
02599   else if (!(dir_ends_in_slash || file_starts_with_slash))
02600     {
02601       if (!_dbus_string_append_byte (dir, '/'))
02602         return FALSE;
02603     }
02604 
02605   return _dbus_string_copy (next_component, 0, dir,
02606                             _dbus_string_get_length (dir));
02607 }
02608 
02610 #define NANOSECONDS_PER_SECOND       1000000000
02611 
02612 #define MICROSECONDS_PER_SECOND      1000000
02613 
02614 #define MILLISECONDS_PER_SECOND      1000
02615 
02616 #define NANOSECONDS_PER_MILLISECOND  1000000
02617 
02618 #define MICROSECONDS_PER_MILLISECOND 1000
02619 
02624 void
02625 _dbus_sleep_milliseconds (int milliseconds)
02626 {
02627 #ifdef HAVE_NANOSLEEP
02628   struct timespec req;
02629   struct timespec rem;
02630 
02631   req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
02632   req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
02633   rem.tv_sec = 0;
02634   rem.tv_nsec = 0;
02635 
02636   while (nanosleep (&req, &rem) < 0 && errno == EINTR)
02637     req = rem;
02638 #elif defined (HAVE_USLEEP)
02639   usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
02640 #else /* ! HAVE_USLEEP */
02641   sleep (MAX (milliseconds / 1000, 1));
02642 #endif
02643 }
02644 
02645 static dbus_bool_t
02646 _dbus_generate_pseudorandom_bytes (DBusString *str,
02647                                    int         n_bytes)
02648 {
02649   int old_len;
02650   char *p;
02651 
02652   old_len = _dbus_string_get_length (str);
02653 
02654   if (!_dbus_string_lengthen (str, n_bytes))
02655     return FALSE;
02656 
02657   p = _dbus_string_get_data_len (str, old_len, n_bytes);
02658 
02659   _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
02660 
02661   return TRUE;
02662 }
02663 
02672 dbus_bool_t
02673 _dbus_generate_random_bytes (DBusString *str,
02674                              int         n_bytes)
02675 {
02676   int old_len;
02677   int fd;
02678 
02679   /* FALSE return means "no memory", if it could
02680    * mean something else then we'd need to return
02681    * a DBusError. So we always fall back to pseudorandom
02682    * if the I/O fails.
02683    */
02684 
02685   old_len = _dbus_string_get_length (str);
02686   fd = -1;
02687 
02688   /* note, urandom on linux will fall back to pseudorandom */
02689   fd = open ("/dev/urandom", O_RDONLY);
02690   if (fd < 0)
02691     return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02692 
02693   _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
02694 
02695   if (_dbus_read (fd, str, n_bytes) != n_bytes)
02696     {
02697       _dbus_close (fd, NULL);
02698       _dbus_string_set_length (str, old_len);
02699       return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02700     }
02701 
02702   _dbus_verbose ("Read %d bytes from /dev/urandom\n",
02703                  n_bytes);
02704 
02705   _dbus_close (fd, NULL);
02706 
02707   return TRUE;
02708 }
02709 
02715 void
02716 _dbus_exit (int code)
02717 {
02718   _exit (code);
02719 }
02720 
02729 const char*
02730 _dbus_strerror (int error_number)
02731 {
02732   const char *msg;
02733 
02734   msg = strerror (error_number);
02735   if (msg == NULL)
02736     msg = "unknown";
02737 
02738   return msg;
02739 }
02740 
02744 void
02745 _dbus_disable_sigpipe (void)
02746 {
02747   signal (SIGPIPE, SIG_IGN);
02748 }
02749 
02757 void
02758 _dbus_fd_set_close_on_exec (intptr_t fd)
02759 {
02760   int val;
02761 
02762   val = fcntl (fd, F_GETFD, 0);
02763 
02764   if (val < 0)
02765     return;
02766 
02767   val |= FD_CLOEXEC;
02768 
02769   fcntl (fd, F_SETFD, val);
02770 }
02771 
02779 dbus_bool_t
02780 _dbus_close (int        fd,
02781              DBusError *error)
02782 {
02783   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02784 
02785  again:
02786   if (close (fd) < 0)
02787     {
02788       if (errno == EINTR)
02789         goto again;
02790 
02791       dbus_set_error (error, _dbus_error_from_errno (errno),
02792                       "Could not close fd %d", fd);
02793       return FALSE;
02794     }
02795 
02796   return TRUE;
02797 }
02798 
02806 int
02807 _dbus_dup(int        fd,
02808           DBusError *error)
02809 {
02810   int new_fd;
02811 
02812 #ifdef F_DUPFD_CLOEXEC
02813   dbus_bool_t cloexec_done;
02814 
02815   new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
02816   cloexec_done = new_fd >= 0;
02817 
02818   if (new_fd < 0 && errno == EINVAL)
02819 #endif
02820     {
02821       new_fd = fcntl(fd, F_DUPFD, 3);
02822     }
02823 
02824   if (new_fd < 0) {
02825 
02826     dbus_set_error (error, _dbus_error_from_errno (errno),
02827                     "Could not duplicate fd %d", fd);
02828     return -1;
02829   }
02830 
02831 #ifdef F_DUPFD_CLOEXEC
02832   if (!cloexec_done)
02833 #endif
02834     {
02835       _dbus_fd_set_close_on_exec(new_fd);
02836     }
02837 
02838   return new_fd;
02839 }
02840 
02848 dbus_bool_t
02849 _dbus_set_fd_nonblocking (int             fd,
02850                           DBusError      *error)
02851 {
02852   int val;
02853 
02854   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02855 
02856   val = fcntl (fd, F_GETFL, 0);
02857   if (val < 0)
02858     {
02859       dbus_set_error (error, _dbus_error_from_errno (errno),
02860                       "Failed to get flags from file descriptor %d: %s",
02861                       fd, _dbus_strerror (errno));
02862       _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
02863                      _dbus_strerror (errno));
02864       return FALSE;
02865     }
02866 
02867   if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
02868     {
02869       dbus_set_error (error, _dbus_error_from_errno (errno),
02870                       "Failed to set nonblocking flag of file descriptor %d: %s",
02871                       fd, _dbus_strerror (errno));
02872       _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
02873                      fd, _dbus_strerror (errno));
02874 
02875       return FALSE;
02876     }
02877 
02878   return TRUE;
02879 }
02880 
02886 void
02887 _dbus_print_backtrace (void)
02888 {
02889 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
02890   void *bt[500];
02891   int bt_size;
02892   int i;
02893   char **syms;
02894 
02895   bt_size = backtrace (bt, 500);
02896 
02897   syms = backtrace_symbols (bt, bt_size);
02898 
02899   i = 0;
02900   while (i < bt_size)
02901     {
02902       /* don't use dbus_warn since it can _dbus_abort() */
02903       fprintf (stderr, "  %s\n", syms[i]);
02904       ++i;
02905     }
02906   fflush (stderr);
02907 
02908   free (syms);
02909 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
02910   fprintf (stderr, "  D-Bus not built with -rdynamic so unable to print a backtrace\n");
02911 #else
02912   fprintf (stderr, "  D-Bus not compiled with backtrace support so unable to print a backtrace\n");
02913 #endif
02914 }
02915 
02928 dbus_bool_t
02929 _dbus_full_duplex_pipe (int        *fd1,
02930                         int        *fd2,
02931                         dbus_bool_t blocking,
02932                         DBusError  *error)
02933 {
02934 #ifdef HAVE_SOCKETPAIR
02935   int fds[2];
02936   int retval;
02937 
02938 #ifdef SOCK_CLOEXEC
02939   dbus_bool_t cloexec_done;
02940 
02941   retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
02942   cloexec_done = retval >= 0;
02943 
02944   if (retval < 0 && errno == EINVAL)
02945 #endif
02946     {
02947       retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
02948     }
02949 
02950   if (retval < 0)
02951     {
02952       dbus_set_error (error, _dbus_error_from_errno (errno),
02953                       "Could not create full-duplex pipe");
02954       return FALSE;
02955     }
02956 
02957   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02958 
02959 #ifdef SOCK_CLOEXEC
02960   if (!cloexec_done)
02961 #endif
02962     {
02963       _dbus_fd_set_close_on_exec (fds[0]);
02964       _dbus_fd_set_close_on_exec (fds[1]);
02965     }
02966 
02967   if (!blocking &&
02968       (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
02969        !_dbus_set_fd_nonblocking (fds[1], NULL)))
02970     {
02971       dbus_set_error (error, _dbus_error_from_errno (errno),
02972                       "Could not set full-duplex pipe nonblocking");
02973 
02974       _dbus_close (fds[0], NULL);
02975       _dbus_close (fds[1], NULL);
02976 
02977       return FALSE;
02978     }
02979 
02980   *fd1 = fds[0];
02981   *fd2 = fds[1];
02982 
02983   _dbus_verbose ("full-duplex pipe %d <-> %d\n",
02984                  *fd1, *fd2);
02985 
02986   return TRUE;
02987 #else
02988   _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
02989   dbus_set_error (error, DBUS_ERROR_FAILED,
02990                   "_dbus_full_duplex_pipe() not implemented on this OS");
02991   return FALSE;
02992 #endif
02993 }
02994 
03003 int
03004 _dbus_printf_string_upper_bound (const char *format,
03005                                  va_list     args)
03006 {
03007   char static_buf[1024];
03008   int bufsize = sizeof (static_buf);
03009   int len;
03010 
03011   len = vsnprintf (static_buf, bufsize, format, args);
03012 
03013   /* If vsnprintf() returned non-negative, then either the string fits in
03014    * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
03015    * returns the number of characters that were needed, or this OS returns the
03016    * truncated length.
03017    *
03018    * We ignore the possibility that snprintf might just ignore the length and
03019    * overrun the buffer (64-bit Solaris 7), because that's pathological.
03020    * If your libc is really that bad, come back when you have a better one. */
03021   if (len == bufsize)
03022     {
03023       /* This could be the truncated length (Tru64 and IRIX have this bug),
03024        * or the real length could be coincidentally the same. Which is it?
03025        * If vsnprintf returns the truncated length, we'll go to the slow
03026        * path. */
03027       if (vsnprintf (static_buf, 1, format, args) == 1)
03028         len = -1;
03029     }
03030 
03031   /* If vsnprintf() returned negative, we have to do more work.
03032    * HP-UX returns negative. */
03033   while (len < 0)
03034     {
03035       char *buf;
03036 
03037       bufsize *= 2;
03038 
03039       buf = dbus_malloc (bufsize);
03040 
03041       if (buf == NULL)
03042         return -1;
03043 
03044       len = vsnprintf (buf, bufsize, format, args);
03045       dbus_free (buf);
03046 
03047       /* If the reported length is exactly the buffer size, round up to the
03048        * next size, in case vsnprintf has been returning the truncated
03049        * length */
03050       if (len == bufsize)
03051         len = -1;
03052     }
03053 
03054   return len;
03055 }
03056 
03063 const char*
03064 _dbus_get_tmpdir(void)
03065 {
03066   static const char* tmpdir = NULL;
03067 
03068   if (tmpdir == NULL)
03069     {
03070       /* TMPDIR is what glibc uses, then
03071        * glibc falls back to the P_tmpdir macro which
03072        * just expands to "/tmp"
03073        */
03074       if (tmpdir == NULL)
03075         tmpdir = getenv("TMPDIR");
03076 
03077       /* These two env variables are probably
03078        * broken, but maybe some OS uses them?
03079        */
03080       if (tmpdir == NULL)
03081         tmpdir = getenv("TMP");
03082       if (tmpdir == NULL)
03083         tmpdir = getenv("TEMP");
03084 
03085       /* And this is the sane fallback. */
03086       if (tmpdir == NULL)
03087         tmpdir = "/tmp";
03088     }
03089 
03090   _dbus_assert(tmpdir != NULL);
03091 
03092   return tmpdir;
03093 }
03094 
03114 static dbus_bool_t
03115 _read_subprocess_line_argv (const char *progpath,
03116                             dbus_bool_t path_fallback,
03117                             char       * const *argv,
03118                             DBusString *result,
03119                             DBusError  *error)
03120 {
03121   int result_pipe[2] = { -1, -1 };
03122   int errors_pipe[2] = { -1, -1 };
03123   pid_t pid;
03124   int ret;
03125   int status;
03126   int orig_len;
03127   int i;
03128 
03129   dbus_bool_t retval;
03130   sigset_t new_set, old_set;
03131 
03132   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03133   retval = FALSE;
03134 
03135   /* We need to block any existing handlers for SIGCHLD temporarily; they
03136    * will cause waitpid() below to fail.
03137    * https://bugs.freedesktop.org/show_bug.cgi?id=21347
03138    */
03139   sigemptyset (&new_set);
03140   sigaddset (&new_set, SIGCHLD);
03141   sigprocmask (SIG_BLOCK, &new_set, &old_set);
03142 
03143   orig_len = _dbus_string_get_length (result);
03144 
03145 #define READ_END        0
03146 #define WRITE_END       1
03147   if (pipe (result_pipe) < 0)
03148     {
03149       dbus_set_error (error, _dbus_error_from_errno (errno),
03150                       "Failed to create a pipe to call %s: %s",
03151                       progpath, _dbus_strerror (errno));
03152       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03153                      progpath, _dbus_strerror (errno));
03154       goto out;
03155     }
03156   if (pipe (errors_pipe) < 0)
03157     {
03158       dbus_set_error (error, _dbus_error_from_errno (errno),
03159                       "Failed to create a pipe to call %s: %s",
03160                       progpath, _dbus_strerror (errno));
03161       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03162                      progpath, _dbus_strerror (errno));
03163       goto out;
03164     }
03165 
03166   pid = fork ();
03167   if (pid < 0)
03168     {
03169       dbus_set_error (error, _dbus_error_from_errno (errno),
03170                       "Failed to fork() to call %s: %s",
03171                       progpath, _dbus_strerror (errno));
03172       _dbus_verbose ("Failed to fork() to call %s: %s\n",
03173                      progpath, _dbus_strerror (errno));
03174       goto out;
03175     }
03176 
03177   if (pid == 0)
03178     {
03179       /* child process */
03180       int maxfds;
03181       int fd;
03182 
03183       fd = open ("/dev/null", O_RDWR);
03184       if (fd == -1)
03185         /* huh?! can't open /dev/null? */
03186         _exit (1);
03187 
03188       _dbus_verbose ("/dev/null fd %d opened\n", fd);
03189 
03190       /* set-up stdXXX */
03191       close (result_pipe[READ_END]);
03192       close (errors_pipe[READ_END]);
03193       close (0);                /* close stdin */
03194       close (1);                /* close stdout */
03195       close (2);                /* close stderr */
03196 
03197       if (dup2 (fd, 0) == -1)
03198         _exit (1);
03199       if (dup2 (result_pipe[WRITE_END], 1) == -1)
03200         _exit (1);
03201       if (dup2 (errors_pipe[WRITE_END], 2) == -1)
03202         _exit (1);
03203 
03204       maxfds = sysconf (_SC_OPEN_MAX);
03205       /* Pick something reasonable if for some reason sysconf
03206        * says unlimited.
03207        */
03208       if (maxfds < 0)
03209         maxfds = 1024;
03210       /* close all inherited fds */
03211       for (i = 3; i < maxfds; i++)
03212         close (i);
03213 
03214       sigprocmask (SIG_SETMASK, &old_set, NULL);
03215 
03216       /* If it looks fully-qualified, try execv first */
03217       if (progpath[0] == '/')
03218         {
03219           execv (progpath, argv);
03220           /* Ok, that failed.  Now if path_fallback is given, let's
03221            * try unqualified.  This is mostly a hack to work
03222            * around systems which ship dbus-launch in /usr/bin
03223            * but everything else in /bin (because dbus-launch
03224            * depends on X11).
03225            */
03226           if (path_fallback)
03227             /* We must have a slash, because we checked above */
03228             execvp (strrchr (progpath, '/')+1, argv);
03229         }
03230       else
03231         execvp (progpath, argv);
03232 
03233       /* still nothing, we failed */
03234       _exit (1);
03235     }
03236 
03237   /* parent process */
03238   close (result_pipe[WRITE_END]);
03239   close (errors_pipe[WRITE_END]);
03240   result_pipe[WRITE_END] = -1;
03241   errors_pipe[WRITE_END] = -1;
03242 
03243   ret = 0;
03244   do
03245     {
03246       ret = _dbus_read (result_pipe[READ_END], result, 1024);
03247     }
03248   while (ret > 0);
03249 
03250   /* reap the child process to avoid it lingering as zombie */
03251   do
03252     {
03253       ret = waitpid (pid, &status, 0);
03254     }
03255   while (ret == -1 && errno == EINTR);
03256 
03257   /* We succeeded if the process exited with status 0 and
03258      anything was read */
03259   if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
03260     {
03261       /* The process ended with error */
03262       DBusString error_message;
03263       if (!_dbus_string_init (&error_message))
03264         {
03265           _DBUS_SET_OOM (error);
03266           goto out;
03267         }
03268 
03269       ret = 0;
03270       do
03271         {
03272           ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
03273         }
03274       while (ret > 0);
03275 
03276       _dbus_string_set_length (result, orig_len);
03277       if (_dbus_string_get_length (&error_message) > 0)
03278         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03279                         "%s terminated abnormally with the following error: %s",
03280                         progpath, _dbus_string_get_data (&error_message));
03281       else
03282         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03283                         "%s terminated abnormally without any error message",
03284                         progpath);
03285       goto out;
03286     }
03287 
03288   retval = TRUE;
03289 
03290  out:
03291   sigprocmask (SIG_SETMASK, &old_set, NULL);
03292 
03293   if (retval)
03294     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03295   else
03296     _DBUS_ASSERT_ERROR_IS_SET (error);
03297 
03298   if (result_pipe[0] != -1)
03299     close (result_pipe[0]);
03300   if (result_pipe[1] != -1)
03301     close (result_pipe[1]);
03302   if (errors_pipe[0] != -1)
03303     close (errors_pipe[0]);
03304   if (errors_pipe[1] != -1)
03305     close (errors_pipe[1]);
03306 
03307   return retval;
03308 }
03309 
03321 dbus_bool_t
03322 _dbus_get_autolaunch_address (const char *scope,
03323                               DBusString *address,
03324                               DBusError  *error)
03325 {
03326 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
03327   /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
03328    * but that's done elsewhere, and if it worked, this function wouldn't
03329    * be called.) */
03330   const char *display;
03331   static char *argv[6];
03332   int i;
03333   DBusString uuid;
03334   dbus_bool_t retval;
03335 
03336   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03337   retval = FALSE;
03338 
03339   /* fd.o #19997: if $DISPLAY isn't set to something useful, then
03340    * dbus-launch-x11 is just going to fail. Rather than trying to
03341    * run it, we might as well bail out early with a nice error. */
03342   display = _dbus_getenv ("DISPLAY");
03343 
03344   if (display == NULL || display[0] == '\0')
03345     {
03346       dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03347           "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
03348       return FALSE;
03349     }
03350 
03351   if (!_dbus_string_init (&uuid))
03352     {
03353       _DBUS_SET_OOM (error);
03354       return FALSE;
03355     }
03356 
03357   if (!_dbus_get_local_machine_uuid_encoded (&uuid))
03358     {
03359       _DBUS_SET_OOM (error);
03360       goto out;
03361     }
03362 
03363   i = 0;
03364   argv[i] = "dbus-launch";
03365   ++i;
03366   argv[i] = "--autolaunch";
03367   ++i;
03368   argv[i] = _dbus_string_get_data (&uuid);
03369   ++i;
03370   argv[i] = "--binary-syntax";
03371   ++i;
03372   argv[i] = "--close-stderr";
03373   ++i;
03374   argv[i] = NULL;
03375   ++i;
03376 
03377   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03378 
03379   retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
03380                                        TRUE,
03381                                        argv, address, error);
03382 
03383  out:
03384   _dbus_string_free (&uuid);
03385   return retval;
03386 #else
03387   dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03388       "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
03389       "set your DBUS_SESSION_BUS_ADDRESS instead");
03390   return FALSE;
03391 #endif
03392 }
03393 
03412 dbus_bool_t
03413 _dbus_read_local_machine_uuid (DBusGUID   *machine_id,
03414                                dbus_bool_t create_if_not_found,
03415                                DBusError  *error)
03416 {
03417   DBusString filename;
03418   dbus_bool_t b;
03419 
03420   _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
03421 
03422   b = _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
03423   if (b)
03424     return TRUE;
03425 
03426   dbus_error_free (error);
03427 
03428   /* Fallback to the system machine ID */
03429   _dbus_string_init_const (&filename, "/etc/machine-id");
03430   return _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
03431 }
03432 
03433 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
03434 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
03435 
03442 dbus_bool_t
03443 _dbus_lookup_launchd_socket (DBusString *socket_path,
03444                              const char *launchd_env_var,
03445                              DBusError  *error)
03446 {
03447 #ifdef DBUS_ENABLE_LAUNCHD
03448   char *argv[4];
03449   int i;
03450 
03451   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03452 
03453   i = 0;
03454   argv[i] = "launchctl";
03455   ++i;
03456   argv[i] = "getenv";
03457   ++i;
03458   argv[i] = (char*)launchd_env_var;
03459   ++i;
03460   argv[i] = NULL;
03461   ++i;
03462 
03463   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03464 
03465   if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
03466     {
03467       return FALSE;
03468     }
03469 
03470   /* no error, but no result either */
03471   if (_dbus_string_get_length(socket_path) == 0)
03472     {
03473       return FALSE;
03474     }
03475 
03476   /* strip the carriage-return */
03477   _dbus_string_shorten(socket_path, 1);
03478   return TRUE;
03479 #else /* DBUS_ENABLE_LAUNCHD */
03480   dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
03481                 "can't lookup socket from launchd; launchd support not compiled in");
03482   return FALSE;
03483 #endif
03484 }
03485 
03486 #ifdef DBUS_ENABLE_LAUNCHD
03487 static dbus_bool_t
03488 _dbus_lookup_session_address_launchd (DBusString *address, DBusError  *error)
03489 {
03490   dbus_bool_t valid_socket;
03491   DBusString socket_path;
03492 
03493   if (!_dbus_string_init (&socket_path))
03494     {
03495       _DBUS_SET_OOM (error);
03496       return FALSE;
03497     }
03498 
03499   valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
03500 
03501   if (dbus_error_is_set(error))
03502     {
03503       _dbus_string_free(&socket_path);
03504       return FALSE;
03505     }
03506 
03507   if (!valid_socket)
03508     {
03509       dbus_set_error(error, "no socket path",
03510                 "launchd did not provide a socket path, "
03511                 "verify that org.freedesktop.dbus-session.plist is loaded!");
03512       _dbus_string_free(&socket_path);
03513       return FALSE;
03514     }
03515   if (!_dbus_string_append (address, "unix:path="))
03516     {
03517       _DBUS_SET_OOM (error);
03518       _dbus_string_free(&socket_path);
03519       return FALSE;
03520     }
03521   if (!_dbus_string_copy (&socket_path, 0, address,
03522                           _dbus_string_get_length (address)))
03523     {
03524       _DBUS_SET_OOM (error);
03525       _dbus_string_free(&socket_path);
03526       return FALSE;
03527     }
03528 
03529   _dbus_string_free(&socket_path);
03530   return TRUE;
03531 }
03532 #endif
03533 
03553 dbus_bool_t
03554 _dbus_lookup_session_address (dbus_bool_t *supported,
03555                               DBusString  *address,
03556                               DBusError   *error)
03557 {
03558 #ifdef DBUS_ENABLE_LAUNCHD
03559   *supported = TRUE;
03560   return _dbus_lookup_session_address_launchd (address, error);
03561 #else
03562   /* On non-Mac Unix platforms, if the session address isn't already
03563    * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
03564    * fall back to the autolaunch: global default; see
03565    * init_session_address in dbus/dbus-bus.c. */
03566   *supported = FALSE;
03567   return TRUE;
03568 #endif
03569 }
03570 
03588 dbus_bool_t
03589 _dbus_get_standard_session_servicedirs (DBusList **dirs)
03590 {
03591   const char *xdg_data_home;
03592   const char *xdg_data_dirs;
03593   DBusString servicedir_path;
03594 
03595   if (!_dbus_string_init (&servicedir_path))
03596     return FALSE;
03597 
03598   xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
03599   xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03600 
03601   if (xdg_data_home != NULL)
03602     {
03603       if (!_dbus_string_append (&servicedir_path, xdg_data_home))
03604         goto oom;
03605     }
03606   else
03607     {
03608       const DBusString *homedir;
03609       DBusString local_share;
03610 
03611       if (!_dbus_homedir_from_current_process (&homedir))
03612         goto oom;
03613 
03614       if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
03615         goto oom;
03616 
03617       _dbus_string_init_const (&local_share, "/.local/share");
03618       if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
03619         goto oom;
03620     }
03621 
03622   if (!_dbus_string_append (&servicedir_path, ":"))
03623     goto oom;
03624 
03625   if (xdg_data_dirs != NULL)
03626     {
03627       if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03628         goto oom;
03629 
03630       if (!_dbus_string_append (&servicedir_path, ":"))
03631         goto oom;
03632     }
03633   else
03634     {
03635       if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03636         goto oom;
03637     }
03638 
03639   /*
03640    * add configured datadir to defaults
03641    * this may be the same as an xdg dir
03642    * however the config parser should take
03643    * care of duplicates
03644    */
03645   if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
03646     goto oom;
03647 
03648   if (!_dbus_split_paths_and_append (&servicedir_path,
03649                                      DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
03650                                      dirs))
03651     goto oom;
03652 
03653   _dbus_string_free (&servicedir_path);
03654   return TRUE;
03655 
03656  oom:
03657   _dbus_string_free (&servicedir_path);
03658   return FALSE;
03659 }
03660 
03661 
03680 dbus_bool_t
03681 _dbus_get_standard_system_servicedirs (DBusList **dirs)
03682 {
03683   /*
03684    * DBUS_DATADIR may be the same as one of the standard directories. However,
03685    * the config parser should take care of the duplicates.
03686    *
03687    * Also, append /lib as counterpart of /usr/share on the root
03688    * directory (the root directory does not know /share), in order to
03689    * facilitate early boot system bus activation where /usr might not
03690    * be available.
03691    */
03692   static const char standard_search_path[] =
03693     "/usr/local/share:"
03694     "/usr/share:"
03695     DBUS_DATADIR ":"
03696     "/lib";
03697   DBusString servicedir_path;
03698 
03699   _dbus_string_init_const (&servicedir_path, standard_search_path);
03700 
03701   return _dbus_split_paths_and_append (&servicedir_path,
03702                                        DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
03703                                        dirs);
03704 }
03705 
03714 dbus_bool_t
03715 _dbus_append_system_config_file (DBusString *str)
03716 {
03717   return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
03718 }
03719 
03726 dbus_bool_t
03727 _dbus_append_session_config_file (DBusString *str)
03728 {
03729   return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
03730 }
03731 
03739 void
03740 _dbus_flush_caches (void)
03741 {
03742   _dbus_user_database_flush_system ();
03743 }
03744 
03758 dbus_bool_t
03759 _dbus_append_keyring_directory_for_credentials (DBusString      *directory,
03760                                                 DBusCredentials *credentials)
03761 {
03762   DBusString homedir;
03763   DBusString dotdir;
03764   dbus_uid_t uid;
03765 
03766   _dbus_assert (credentials != NULL);
03767   _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
03768 
03769   if (!_dbus_string_init (&homedir))
03770     return FALSE;
03771 
03772   uid = _dbus_credentials_get_unix_uid (credentials);
03773   _dbus_assert (uid != DBUS_UID_UNSET);
03774 
03775   if (!_dbus_homedir_from_uid (uid, &homedir))
03776     goto failed;
03777 
03778 #ifdef DBUS_BUILD_TESTS
03779   {
03780     const char *override;
03781 
03782     override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
03783     if (override != NULL && *override != '\0')
03784       {
03785         _dbus_string_set_length (&homedir, 0);
03786         if (!_dbus_string_append (&homedir, override))
03787           goto failed;
03788 
03789         _dbus_verbose ("Using fake homedir for testing: %s\n",
03790                        _dbus_string_get_const_data (&homedir));
03791       }
03792     else
03793       {
03794         static dbus_bool_t already_warned = FALSE;
03795         if (!already_warned)
03796           {
03797             _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
03798             already_warned = TRUE;
03799           }
03800       }
03801   }
03802 #endif
03803 
03804   _dbus_string_init_const (&dotdir, ".dbus-keyrings");
03805   if (!_dbus_concat_dir_and_file (&homedir,
03806                                   &dotdir))
03807     goto failed;
03808 
03809   if (!_dbus_string_copy (&homedir, 0,
03810                           directory, _dbus_string_get_length (directory))) {
03811     goto failed;
03812   }
03813 
03814   _dbus_string_free (&homedir);
03815   return TRUE;
03816 
03817  failed:
03818   _dbus_string_free (&homedir);
03819   return FALSE;
03820 }
03821 
03822 //PENDING(kdab) docs
03823 dbus_bool_t
03824 _dbus_daemon_publish_session_bus_address (const char* addr,
03825                                           const char *scope)
03826 {
03827   return TRUE;
03828 }
03829 
03830 //PENDING(kdab) docs
03831 void
03832 _dbus_daemon_unpublish_session_bus_address (void)
03833 {
03834 
03835 }
03836 
03843 dbus_bool_t
03844 _dbus_get_is_errno_eagain_or_ewouldblock (void)
03845 {
03846   return errno == EAGAIN || errno == EWOULDBLOCK;
03847 }
03848 
03856 dbus_bool_t
03857 _dbus_delete_directory (const DBusString *filename,
03858                         DBusError        *error)
03859 {
03860   const char *filename_c;
03861 
03862   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03863 
03864   filename_c = _dbus_string_get_const_data (filename);
03865 
03866   if (rmdir (filename_c) != 0)
03867     {
03868       dbus_set_error (error, DBUS_ERROR_FAILED,
03869                       "Failed to remove directory %s: %s\n",
03870                       filename_c, _dbus_strerror (errno));
03871       return FALSE;
03872     }
03873 
03874   return TRUE;
03875 }
03876 
03884 dbus_bool_t
03885 _dbus_socket_can_pass_unix_fd(int fd) {
03886 
03887 #ifdef SCM_RIGHTS
03888   union {
03889     struct sockaddr sa;
03890     struct sockaddr_storage storage;
03891     struct sockaddr_un un;
03892   } sa_buf;
03893 
03894   socklen_t sa_len = sizeof(sa_buf);
03895 
03896   _DBUS_ZERO(sa_buf);
03897 
03898   if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
03899     return FALSE;
03900 
03901   return sa_buf.sa.sa_family == AF_UNIX;
03902 
03903 #else
03904   return FALSE;
03905 
03906 #endif
03907 }
03908 
03909 
03910 /*
03911  * replaces the term DBUS_PREFIX in configure_time_path by the
03912  * current dbus installation directory. On unix this function is a noop
03913  *
03914  * @param configure_time_path
03915  * @return real path
03916  */
03917 const char *
03918 _dbus_replace_install_prefix (const char *configure_time_path)
03919 {
03920   return configure_time_path;
03921 }
03922 
03923 /* tests in dbus-sysdeps-util.c */