"Fossies" - the Fresh Open Source Software Archive

Member "dbus-1.12.20/dbus/dbus-sysdeps-unix.c" (2 Jul 2020, 131329 Bytes) of package /linux/misc/dbus-1.12.20.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "dbus-sysdeps-unix.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.12.18_vs_1.12.20.

    1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
    2 /* dbus-sysdeps-unix.c Wrappers around UNIX system/libc features (internal to D-Bus implementation)
    3  *
    4  * Copyright (C) 2002, 2003, 2006  Red Hat, Inc.
    5  * Copyright (C) 2003 CodeFactory AB
    6  *
    7  * Licensed under the Academic Free License version 2.1
    8  *
    9  * This program is free software; you can redistribute it and/or modify
   10  * it under the terms of the GNU General Public License as published by
   11  * the Free Software Foundation; either version 2 of the License, or
   12  * (at your option) any later version.
   13  *
   14  * This program is distributed in the hope that it will be useful,
   15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17  * GNU General Public License for more details.
   18  *
   19  * You should have received a copy of the GNU General Public License
   20  * along with this program; if not, write to the Free Software
   21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
   22  *
   23  */
   24 
   25 #include <config.h>
   26 
   27 #include "dbus-internals.h"
   28 #include "dbus-sysdeps.h"
   29 #include "dbus-sysdeps-unix.h"
   30 #include "dbus-threads.h"
   31 #include "dbus-protocol.h"
   32 #include "dbus-file.h"
   33 #include "dbus-transport.h"
   34 #include "dbus-string.h"
   35 #include "dbus-userdb.h"
   36 #include "dbus-list.h"
   37 #include "dbus-credentials.h"
   38 #include "dbus-nonce.h"
   39 
   40 #include <sys/types.h>
   41 #include <stdlib.h>
   42 #include <string.h>
   43 #include <signal.h>
   44 #include <unistd.h>
   45 #include <stdio.h>
   46 #include <fcntl.h>
   47 #include <sys/socket.h>
   48 #include <dirent.h>
   49 #include <sys/un.h>
   50 #include <pwd.h>
   51 #include <time.h>
   52 #include <locale.h>
   53 #include <sys/time.h>
   54 #include <sys/stat.h>
   55 #include <sys/wait.h>
   56 #include <netinet/in.h>
   57 #include <netinet/tcp.h>
   58 #include <netdb.h>
   59 #include <grp.h>
   60 #include <arpa/inet.h>
   61 
   62 #ifdef HAVE_ERRNO_H
   63 #include <errno.h>
   64 #endif
   65 #ifdef HAVE_SYSLOG_H
   66 #include <syslog.h>
   67 #endif
   68 #ifdef HAVE_WRITEV
   69 #include <sys/uio.h>
   70 #endif
   71 #ifdef HAVE_POLL
   72 #include <sys/poll.h>
   73 #endif
   74 #ifdef HAVE_BACKTRACE
   75 #include <execinfo.h>
   76 #endif
   77 #ifdef HAVE_GETPEERUCRED
   78 #include <ucred.h>
   79 #endif
   80 #ifdef HAVE_ALLOCA_H
   81 #include <alloca.h>
   82 #endif
   83 
   84 #ifdef HAVE_ADT
   85 #include <bsm/adt.h>
   86 #endif
   87 
   88 #ifdef HAVE_SYSTEMD
   89 #include <systemd/sd-daemon.h>
   90 #endif
   91 
   92 #if !DBUS_USE_SYNC
   93 #include <pthread.h>
   94 #endif
   95 
   96 #ifndef O_BINARY
   97 #define O_BINARY 0
   98 #endif
   99 
  100 #ifndef AI_ADDRCONFIG
  101 #define AI_ADDRCONFIG 0
  102 #endif
  103 
  104 #ifndef HAVE_SOCKLEN_T
  105 #define socklen_t int
  106 #endif
  107 
  108 #if defined (__sun) || defined (__sun__)
  109 /*
  110  * CMS_SPACE etc. definitions for Solaris < 10, based on
  111  *   http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html
  112  * via
  113  *   http://wiki.opencsw.org/porting-faq#toc10
  114  *
  115  * These are only redefined for Solaris, for now: if your OS needs these too,
  116  * please file a bug. (Or preferably, improve your OS so they're not needed.)
  117  */
  118 
  119 # ifndef CMSG_ALIGN
  120 #   ifdef __sun__
  121 #     define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
  122 #   else
  123       /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
  124 #     define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
  125                               ~(sizeof (long) - 1))
  126 #   endif
  127 # endif
  128 
  129 # ifndef CMSG_SPACE
  130 #   define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
  131                             CMSG_ALIGN (len))
  132 # endif
  133 
  134 # ifndef CMSG_LEN
  135 #   define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
  136 # endif
  137 
  138 #endif /* Solaris */
  139 
  140 /**
  141  * Ensure that the standard file descriptors stdin, stdout and stderr
  142  * are open, by opening /dev/null if necessary.
  143  *
  144  * This function does not use DBusError, to avoid calling malloc(), so
  145  * that it can be used in contexts where an async-signal-safe function
  146  * is required (for example after fork()). Instead, on failure it sets
  147  * errno and returns something like "Failed to open /dev/null" in
  148  * *error_str_p. Callers are expected to combine *error_str_p
  149  * with _dbus_strerror (errno) to get a full error report.
  150  *
  151  * This function can only be called while single-threaded: either during
  152  * startup of an executable, or after fork().
  153  */
  154 dbus_bool_t
  155 _dbus_ensure_standard_fds (DBusEnsureStandardFdsFlags   flags,
  156                            const char                 **error_str_p)
  157 {
  158   static int const relevant_flag[] = { DBUS_FORCE_STDIN_NULL,
  159       DBUS_FORCE_STDOUT_NULL,
  160       DBUS_FORCE_STDERR_NULL };
  161   /* Should always get replaced with the real error before use */
  162   const char *error_str = "Failed mysteriously";
  163   int devnull = -1;
  164   int saved_errno;
  165   /* This function relies on the standard fds having their POSIX values. */
  166   _DBUS_STATIC_ASSERT (STDIN_FILENO == 0);
  167   _DBUS_STATIC_ASSERT (STDOUT_FILENO == 1);
  168   _DBUS_STATIC_ASSERT (STDERR_FILENO == 2);
  169   int i;
  170 
  171   for (i = STDIN_FILENO; i <= STDERR_FILENO; i++)
  172     {
  173       /* Because we rely on being single-threaded, and we want the
  174        * standard fds to not be close-on-exec, we don't set it
  175        * close-on-exec. */
  176       if (devnull < i)
  177         devnull = open ("/dev/null", O_RDWR);
  178 
  179       if (devnull < 0)
  180         {
  181           error_str = "Failed to open /dev/null";
  182           goto out;
  183         }
  184 
  185       /* We already opened all fds < i, so the only way this assertion
  186        * could fail is if another thread closed one, and we document
  187        * this function as not safe for multi-threading. */
  188       _dbus_assert (devnull >= i);
  189 
  190       if (devnull != i && (flags & relevant_flag[i]) != 0)
  191         {
  192           if (dup2 (devnull, i) < 0)
  193             {
  194               error_str = "Failed to dup2 /dev/null onto a standard fd";
  195               goto out;
  196             }
  197         }
  198     }
  199 
  200   error_str = NULL;
  201 
  202 out:
  203   saved_errno = errno;
  204 
  205   if (devnull > STDERR_FILENO)
  206     close (devnull);
  207 
  208   if (error_str_p != NULL)
  209     *error_str_p = error_str;
  210 
  211   errno = saved_errno;
  212   return (error_str == NULL);
  213 }
  214 
  215 static dbus_bool_t _dbus_set_fd_nonblocking (int             fd,
  216                                              DBusError      *error);
  217 
  218 static dbus_bool_t
  219 _dbus_open_socket (int              *fd_p,
  220                    int               domain,
  221                    int               type,
  222                    int               protocol,
  223                    DBusError        *error)
  224 {
  225 #ifdef SOCK_CLOEXEC
  226   dbus_bool_t cloexec_done;
  227 
  228   *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
  229   cloexec_done = *fd_p >= 0;
  230 
  231   /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
  232   if (*fd_p < 0 && (errno == EINVAL || errno == EPROTOTYPE))
  233 #endif
  234     {
  235       *fd_p = socket (domain, type, protocol);
  236     }
  237 
  238   if (*fd_p >= 0)
  239     {
  240 #ifdef SOCK_CLOEXEC
  241       if (!cloexec_done)
  242 #endif
  243         {
  244           _dbus_fd_set_close_on_exec(*fd_p);
  245         }
  246 
  247       _dbus_verbose ("socket fd %d opened\n", *fd_p);
  248       return TRUE;
  249     }
  250   else
  251     {
  252       dbus_set_error(error,
  253                      _dbus_error_from_errno (errno),
  254                      "Failed to open socket: %s",
  255                      _dbus_strerror (errno));
  256       return FALSE;
  257     }
  258 }
  259 
  260 /**
  261  * Opens a UNIX domain socket (as in the socket() call).
  262  * Does not bind the socket.
  263  *
  264  * This will set FD_CLOEXEC for the socket returned
  265  *
  266  * @param fd return location for socket descriptor
  267  * @param error return location for an error
  268  * @returns #FALSE if error is set
  269  */
  270 static dbus_bool_t
  271 _dbus_open_unix_socket (int              *fd,
  272                         DBusError        *error)
  273 {
  274   return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
  275 }
  276 
  277 /**
  278  * Closes a socket. Should not be used on non-socket
  279  * file descriptors or handles.
  280  *
  281  * @param fd the socket
  282  * @param error return location for an error
  283  * @returns #FALSE if error is set
  284  */
  285 dbus_bool_t
  286 _dbus_close_socket (DBusSocket        fd,
  287                     DBusError        *error)
  288 {
  289   return _dbus_close (fd.fd, error);
  290 }
  291 
  292 /**
  293  * Like _dbus_read(), but only works on sockets so is
  294  * available on Windows.
  295  *
  296  * @param fd the socket
  297  * @param buffer string to append data to
  298  * @param count max amount of data to read
  299  * @returns number of bytes appended to the string
  300  */
  301 int
  302 _dbus_read_socket (DBusSocket        fd,
  303                    DBusString       *buffer,
  304                    int               count)
  305 {
  306   return _dbus_read (fd.fd, buffer, count);
  307 }
  308 
  309 /**
  310  * Like _dbus_write(), but only supports sockets
  311  * and is thus available on Windows.
  312  *
  313  * @param fd the file descriptor to write
  314  * @param buffer the buffer to write data from
  315  * @param start the first byte in the buffer to write
  316  * @param len the number of bytes to try to write
  317  * @returns the number of bytes written or -1 on error
  318  */
  319 int
  320 _dbus_write_socket (DBusSocket        fd,
  321                     const DBusString *buffer,
  322                     int               start,
  323                     int               len)
  324 {
  325 #if HAVE_DECL_MSG_NOSIGNAL
  326   const char *data;
  327   int bytes_written;
  328 
  329   data = _dbus_string_get_const_data_len (buffer, start, len);
  330 
  331  again:
  332 
  333   bytes_written = send (fd.fd, data, len, MSG_NOSIGNAL);
  334 
  335   if (bytes_written < 0 && errno == EINTR)
  336     goto again;
  337 
  338   return bytes_written;
  339 
  340 #else
  341   return _dbus_write (fd.fd, buffer, start, len);
  342 #endif
  343 }
  344 
  345 /**
  346  * Like _dbus_read_socket() but also tries to read unix fds from the
  347  * socket. When there are more fds to read than space in the array
  348  * passed this function will fail with ENOSPC.
  349  *
  350  * @param fd the socket
  351  * @param buffer string to append data to
  352  * @param count max amount of data to read
  353  * @param fds array to place read file descriptors in
  354  * @param n_fds on input space in fds array, on output how many fds actually got read
  355  * @returns number of bytes appended to string
  356  */
  357 int
  358 _dbus_read_socket_with_unix_fds (DBusSocket        fd,
  359                                  DBusString       *buffer,
  360                                  int               count,
  361                                  int              *fds,
  362                                  unsigned int     *n_fds) {
  363 #ifndef HAVE_UNIX_FD_PASSING
  364   int r;
  365 
  366   if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
  367     return r;
  368 
  369   *n_fds = 0;
  370   return r;
  371 
  372 #else
  373   int bytes_read;
  374   int start;
  375   struct msghdr m;
  376   struct iovec iov;
  377 
  378   _dbus_assert (count >= 0);
  379   _dbus_assert (*n_fds <= DBUS_MAXIMUM_MESSAGE_UNIX_FDS);
  380 
  381   start = _dbus_string_get_length (buffer);
  382 
  383   if (!_dbus_string_lengthen (buffer, count))
  384     {
  385       errno = ENOMEM;
  386       return -1;
  387     }
  388 
  389   _DBUS_ZERO(iov);
  390   iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
  391   iov.iov_len = count;
  392 
  393   _DBUS_ZERO(m);
  394   m.msg_iov = &iov;
  395   m.msg_iovlen = 1;
  396 
  397   /* Hmm, we have no clue how long the control data will actually be
  398      that is queued for us. The least we can do is assume that the
  399      caller knows. Hence let's make space for the number of fds that
  400      we shall read at max plus the cmsg header. */
  401   m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
  402 
  403   /* It's probably safe to assume that systems with SCM_RIGHTS also
  404      know alloca() */
  405   m.msg_control = alloca(m.msg_controllen);
  406   memset(m.msg_control, 0, m.msg_controllen);
  407 
  408   /* Do not include the padding at the end when we tell the kernel
  409    * how much we're willing to receive. This avoids getting
  410    * the padding filled with additional fds that we weren't expecting,
  411    * if a (potentially malicious) sender included them. (fd.o #83622) */
  412   m.msg_controllen = CMSG_LEN (*n_fds * sizeof(int));
  413 
  414  again:
  415 
  416   bytes_read = recvmsg (fd.fd, &m, 0
  417 #ifdef MSG_CMSG_CLOEXEC
  418                        |MSG_CMSG_CLOEXEC
  419 #endif
  420                        );
  421 
  422   if (bytes_read < 0)
  423     {
  424       if (errno == EINTR)
  425         goto again;
  426       else
  427         {
  428           /* put length back (note that this doesn't actually realloc anything) */
  429           _dbus_string_set_length (buffer, start);
  430           return -1;
  431         }
  432     }
  433   else
  434     {
  435       struct cmsghdr *cm;
  436       dbus_bool_t found = FALSE;
  437 
  438       for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
  439         if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
  440           {
  441             size_t i;
  442             int *payload = (int *) CMSG_DATA (cm);
  443             size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0));
  444             size_t payload_len_fds;
  445             size_t fds_to_use;
  446 
  447             /* Every unsigned int fits in a size_t without truncation, so
  448              * casting (size_t) *n_fds is OK */
  449             _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (unsigned int));
  450 
  451             if ((m.msg_flags & MSG_CTRUNC) && CMSG_NXTHDR(&m, cm) == NULL &&
  452               (char *) payload + payload_len_bytes >
  453               (char *) m.msg_control + m.msg_controllen)
  454               {
  455                 /* This is the last cmsg in a truncated message and using
  456                  * cmsg_len would apparently overrun the allocated buffer.
  457                  * Some operating systems (illumos and Solaris are known) do
  458                  * not adjust cmsg_len in the last cmsg when truncation occurs.
  459                  * Adjust the payload length here. The calculation for
  460                  * payload_len_fds below will discard any trailing bytes that
  461                  * belong to an incomplete file descriptor - the kernel will
  462                  * have already closed that (at least for illumos and Solaris)
  463                  */
  464                  payload_len_bytes = m.msg_controllen -
  465                    ((char *) payload - (char *) m.msg_control);
  466               }
  467 
  468             payload_len_fds = payload_len_bytes / sizeof (int);
  469 
  470             if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds))
  471               {
  472                 /* The fds in the payload will fit in our buffer */
  473                 fds_to_use = payload_len_fds;
  474               }
  475             else
  476               {
  477                 /* Too many fds in the payload. This shouldn't happen
  478                  * any more because we're setting m.msg_controllen to
  479                  * the exact number we can accept, but be safe and
  480                  * truncate. */
  481                 fds_to_use = (size_t) *n_fds;
  482 
  483                 /* Close the excess fds to avoid DoS: if they stayed open,
  484                  * someone could send us an extra fd per message
  485                  * and we'd eventually run out. */
  486                 for (i = fds_to_use; i < payload_len_fds; i++)
  487                   {
  488                     close (payload[i]);
  489                   }
  490               }
  491 
  492             memcpy (fds, payload, fds_to_use * sizeof (int));
  493             found = TRUE;
  494             /* This narrowing cast from size_t to unsigned int cannot
  495              * overflow because we have chosen fds_to_use
  496              * to be <= *n_fds */
  497             *n_fds = (unsigned int) fds_to_use;
  498 
  499             /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
  500                worked, hence we need to go through this list and set
  501                CLOEXEC everywhere in any case */
  502             for (i = 0; i < fds_to_use; i++)
  503               _dbus_fd_set_close_on_exec(fds[i]);
  504 
  505             break;
  506           }
  507 
  508       if (!found)
  509         *n_fds = 0;
  510 
  511       if (m.msg_flags & MSG_CTRUNC)
  512         {
  513           unsigned int i;
  514 
  515           /* Hmm, apparently the control data was truncated. The bad
  516              thing is that we might have completely lost a couple of fds
  517              without chance to recover them. Hence let's treat this as a
  518              serious error. */
  519 
  520           /* We still need to close whatever fds we *did* receive,
  521            * otherwise they'll never get closed. (CVE-2020-12049) */
  522           for (i = 0; i < *n_fds; i++)
  523             close (fds[i]);
  524 
  525           *n_fds = 0;
  526           errno = ENOSPC;
  527           _dbus_string_set_length (buffer, start);
  528           return -1;
  529         }
  530 
  531       /* put length back (doesn't actually realloc) */
  532       _dbus_string_set_length (buffer, start + bytes_read);
  533 
  534 #if 0
  535       if (bytes_read > 0)
  536         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
  537 #endif
  538 
  539       return bytes_read;
  540     }
  541 #endif
  542 }
  543 
  544 int
  545 _dbus_write_socket_with_unix_fds(DBusSocket        fd,
  546                                  const DBusString *buffer,
  547                                  int               start,
  548                                  int               len,
  549                                  const int        *fds,
  550                                  int               n_fds) {
  551 
  552 #ifndef HAVE_UNIX_FD_PASSING
  553 
  554   if (n_fds > 0) {
  555     errno = ENOTSUP;
  556     return -1;
  557   }
  558 
  559   return _dbus_write_socket(fd, buffer, start, len);
  560 #else
  561   return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
  562 #endif
  563 }
  564 
  565 int
  566 _dbus_write_socket_with_unix_fds_two(DBusSocket        fd,
  567                                      const DBusString *buffer1,
  568                                      int               start1,
  569                                      int               len1,
  570                                      const DBusString *buffer2,
  571                                      int               start2,
  572                                      int               len2,
  573                                      const int        *fds,
  574                                      int               n_fds) {
  575 
  576 #ifndef HAVE_UNIX_FD_PASSING
  577 
  578   if (n_fds > 0) {
  579     errno = ENOTSUP;
  580     return -1;
  581   }
  582 
  583   return _dbus_write_socket_two(fd,
  584                                 buffer1, start1, len1,
  585                                 buffer2, start2, len2);
  586 #else
  587 
  588   struct msghdr m;
  589   struct cmsghdr *cm;
  590   struct iovec iov[2];
  591   int bytes_written;
  592 
  593   _dbus_assert (len1 >= 0);
  594   _dbus_assert (len2 >= 0);
  595   _dbus_assert (n_fds >= 0);
  596 
  597   _DBUS_ZERO(iov);
  598   iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
  599   iov[0].iov_len = len1;
  600 
  601   if (buffer2)
  602     {
  603       iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
  604       iov[1].iov_len = len2;
  605     }
  606 
  607   _DBUS_ZERO(m);
  608   m.msg_iov = iov;
  609   m.msg_iovlen = buffer2 ? 2 : 1;
  610 
  611   if (n_fds > 0)
  612     {
  613       m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
  614       m.msg_control = alloca(m.msg_controllen);
  615       memset(m.msg_control, 0, m.msg_controllen);
  616 
  617       cm = CMSG_FIRSTHDR(&m);
  618       cm->cmsg_level = SOL_SOCKET;
  619       cm->cmsg_type = SCM_RIGHTS;
  620       cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
  621       memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
  622     }
  623 
  624  again:
  625 
  626   bytes_written = sendmsg (fd.fd, &m, 0
  627 #if HAVE_DECL_MSG_NOSIGNAL
  628                            |MSG_NOSIGNAL
  629 #endif
  630                            );
  631 
  632   if (bytes_written < 0 && errno == EINTR)
  633     goto again;
  634 
  635 #if 0
  636   if (bytes_written > 0)
  637     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
  638 #endif
  639 
  640   return bytes_written;
  641 #endif
  642 }
  643 
  644 /**
  645  * Like _dbus_write_two() but only works on sockets and is thus
  646  * available on Windows.
  647  *
  648  * @param fd the file descriptor
  649  * @param buffer1 first buffer
  650  * @param start1 first byte to write in first buffer
  651  * @param len1 number of bytes to write from first buffer
  652  * @param buffer2 second buffer, or #NULL
  653  * @param start2 first byte to write in second buffer
  654  * @param len2 number of bytes to write in second buffer
  655  * @returns total bytes written from both buffers, or -1 on error
  656  */
  657 int
  658 _dbus_write_socket_two (DBusSocket        fd,
  659                         const DBusString *buffer1,
  660                         int               start1,
  661                         int               len1,
  662                         const DBusString *buffer2,
  663                         int               start2,
  664                         int               len2)
  665 {
  666 #if HAVE_DECL_MSG_NOSIGNAL
  667   struct iovec vectors[2];
  668   const char *data1;
  669   const char *data2;
  670   int bytes_written;
  671   struct msghdr m;
  672 
  673   _dbus_assert (buffer1 != NULL);
  674   _dbus_assert (start1 >= 0);
  675   _dbus_assert (start2 >= 0);
  676   _dbus_assert (len1 >= 0);
  677   _dbus_assert (len2 >= 0);
  678 
  679   data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
  680 
  681   if (buffer2 != NULL)
  682     data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
  683   else
  684     {
  685       data2 = NULL;
  686       start2 = 0;
  687       len2 = 0;
  688     }
  689 
  690   vectors[0].iov_base = (char*) data1;
  691   vectors[0].iov_len = len1;
  692   vectors[1].iov_base = (char*) data2;
  693   vectors[1].iov_len = len2;
  694 
  695   _DBUS_ZERO(m);
  696   m.msg_iov = vectors;
  697   m.msg_iovlen = data2 ? 2 : 1;
  698 
  699  again:
  700 
  701   bytes_written = sendmsg (fd.fd, &m, MSG_NOSIGNAL);
  702 
  703   if (bytes_written < 0 && errno == EINTR)
  704     goto again;
  705 
  706   return bytes_written;
  707 
  708 #else
  709   return _dbus_write_two (fd.fd, buffer1, start1, len1,
  710                           buffer2, start2, len2);
  711 #endif
  712 }
  713 
  714 /**
  715  * Thin wrapper around the read() system call that appends
  716  * the data it reads to the DBusString buffer. It appends
  717  * up to the given count, and returns the same value
  718  * and same errno as read(). The only exception is that
  719  * _dbus_read() handles EINTR for you. Also, _dbus_read() can
  720  * return ENOMEM, even though regular UNIX read doesn't.
  721  *
  722  * Unlike _dbus_read_socket(), _dbus_read() is not available
  723  * on Windows.
  724  *
  725  * @param fd the file descriptor to read from
  726  * @param buffer the buffer to append data to
  727  * @param count the amount of data to read
  728  * @returns the number of bytes read or -1
  729  */
  730 int
  731 _dbus_read (int               fd,
  732             DBusString       *buffer,
  733             int               count)
  734 {
  735   int bytes_read;
  736   int start;
  737   char *data;
  738 
  739   _dbus_assert (count >= 0);
  740 
  741   start = _dbus_string_get_length (buffer);
  742 
  743   if (!_dbus_string_lengthen (buffer, count))
  744     {
  745       errno = ENOMEM;
  746       return -1;
  747     }
  748 
  749   data = _dbus_string_get_data_len (buffer, start, count);
  750 
  751  again:
  752 
  753   bytes_read = read (fd, data, count);
  754 
  755   if (bytes_read < 0)
  756     {
  757       if (errno == EINTR)
  758         goto again;
  759       else
  760         {
  761           /* put length back (note that this doesn't actually realloc anything) */
  762           _dbus_string_set_length (buffer, start);
  763           return -1;
  764         }
  765     }
  766   else
  767     {
  768       /* put length back (doesn't actually realloc) */
  769       _dbus_string_set_length (buffer, start + bytes_read);
  770 
  771 #if 0
  772       if (bytes_read > 0)
  773         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
  774 #endif
  775 
  776       return bytes_read;
  777     }
  778 }
  779 
  780 /**
  781  * Thin wrapper around the write() system call that writes a part of a
  782  * DBusString and handles EINTR for you.
  783  *
  784  * @param fd the file descriptor to write
  785  * @param buffer the buffer to write data from
  786  * @param start the first byte in the buffer to write
  787  * @param len the number of bytes to try to write
  788  * @returns the number of bytes written or -1 on error
  789  */
  790 int
  791 _dbus_write (int               fd,
  792              const DBusString *buffer,
  793              int               start,
  794              int               len)
  795 {
  796   const char *data;
  797   int bytes_written;
  798 
  799   data = _dbus_string_get_const_data_len (buffer, start, len);
  800 
  801  again:
  802 
  803   bytes_written = write (fd, data, len);
  804 
  805   if (bytes_written < 0 && errno == EINTR)
  806     goto again;
  807 
  808 #if 0
  809   if (bytes_written > 0)
  810     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
  811 #endif
  812 
  813   return bytes_written;
  814 }
  815 
  816 /**
  817  * Like _dbus_write() but will use writev() if possible
  818  * to write both buffers in sequence. The return value
  819  * is the number of bytes written in the first buffer,
  820  * plus the number written in the second. If the first
  821  * buffer is written successfully and an error occurs
  822  * writing the second, the number of bytes in the first
  823  * is returned (i.e. the error is ignored), on systems that
  824  * don't have writev. Handles EINTR for you.
  825  * The second buffer may be #NULL.
  826  *
  827  * @param fd the file descriptor
  828  * @param buffer1 first buffer
  829  * @param start1 first byte to write in first buffer
  830  * @param len1 number of bytes to write from first buffer
  831  * @param buffer2 second buffer, or #NULL
  832  * @param start2 first byte to write in second buffer
  833  * @param len2 number of bytes to write in second buffer
  834  * @returns total bytes written from both buffers, or -1 on error
  835  */
  836 int
  837 _dbus_write_two (int               fd,
  838                  const DBusString *buffer1,
  839                  int               start1,
  840                  int               len1,
  841                  const DBusString *buffer2,
  842                  int               start2,
  843                  int               len2)
  844 {
  845   _dbus_assert (buffer1 != NULL);
  846   _dbus_assert (start1 >= 0);
  847   _dbus_assert (start2 >= 0);
  848   _dbus_assert (len1 >= 0);
  849   _dbus_assert (len2 >= 0);
  850 
  851 #ifdef HAVE_WRITEV
  852   {
  853     struct iovec vectors[2];
  854     const char *data1;
  855     const char *data2;
  856     int bytes_written;
  857 
  858     data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
  859 
  860     if (buffer2 != NULL)
  861       data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
  862     else
  863       {
  864         data2 = NULL;
  865         start2 = 0;
  866         len2 = 0;
  867       }
  868 
  869     vectors[0].iov_base = (char*) data1;
  870     vectors[0].iov_len = len1;
  871     vectors[1].iov_base = (char*) data2;
  872     vectors[1].iov_len = len2;
  873 
  874   again:
  875 
  876     bytes_written = writev (fd,
  877                             vectors,
  878                             data2 ? 2 : 1);
  879 
  880     if (bytes_written < 0 && errno == EINTR)
  881       goto again;
  882 
  883     return bytes_written;
  884   }
  885 #else /* HAVE_WRITEV */
  886   {
  887     int ret1, ret2;
  888 
  889     ret1 = _dbus_write (fd, buffer1, start1, len1);
  890     if (ret1 == len1 && buffer2 != NULL)
  891       {
  892         ret2 = _dbus_write (fd, buffer2, start2, len2);
  893         if (ret2 < 0)
  894           ret2 = 0; /* we can't report an error as the first write was OK */
  895 
  896         return ret1 + ret2;
  897       }
  898     else
  899       return ret1;
  900   }
  901 #endif /* !HAVE_WRITEV */
  902 }
  903 
  904 #define _DBUS_MAX_SUN_PATH_LENGTH 99
  905 
  906 /**
  907  * @def _DBUS_MAX_SUN_PATH_LENGTH
  908  *
  909  * Maximum length of the path to a UNIX domain socket,
  910  * sockaddr_un::sun_path member. POSIX requires that all systems
  911  * support at least 100 bytes here, including the nul termination.
  912  * We use 99 for the max value to allow for the nul.
  913  *
  914  * We could probably also do sizeof (addr.sun_path)
  915  * but this way we are the same on all platforms
  916  * which is probably a good idea.
  917  */
  918 
  919 /**
  920  * Creates a socket and connects it to the UNIX domain socket at the
  921  * given path.  The connection fd is returned, and is set up as
  922  * nonblocking.
  923  *
  924  * Uses abstract sockets instead of filesystem-linked sockets if
  925  * requested (it's possible only on Linux; see "man 7 unix" on Linux).
  926  * On non-Linux abstract socket usage always fails.
  927  *
  928  * This will set FD_CLOEXEC for the socket returned.
  929  *
  930  * @param path the path to UNIX domain socket
  931  * @param abstract #TRUE to use abstract namespace
  932  * @param error return location for error code
  933  * @returns connection file descriptor or -1 on error
  934  */
  935 int
  936 _dbus_connect_unix_socket (const char     *path,
  937                            dbus_bool_t     abstract,
  938                            DBusError      *error)
  939 {
  940   int fd;
  941   size_t path_len;
  942   struct sockaddr_un addr;
  943   _DBUS_STATIC_ASSERT (sizeof (addr.sun_path) > _DBUS_MAX_SUN_PATH_LENGTH);
  944 
  945   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
  946 
  947   _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
  948                  path, abstract);
  949 
  950 
  951   if (!_dbus_open_unix_socket (&fd, error))
  952     {
  953       _DBUS_ASSERT_ERROR_IS_SET(error);
  954       return -1;
  955     }
  956   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
  957 
  958   _DBUS_ZERO (addr);
  959   addr.sun_family = AF_UNIX;
  960   path_len = strlen (path);
  961 
  962   if (abstract)
  963     {
  964 #ifdef __linux__
  965       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
  966       path_len++; /* Account for the extra nul byte added to the start of sun_path */
  967 
  968       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
  969         {
  970           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
  971                       "Abstract socket name too long\n");
  972           _dbus_close (fd, NULL);
  973           return -1;
  974     }
  975 
  976       strncpy (&addr.sun_path[1], path, sizeof (addr.sun_path) - 2);
  977       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
  978 #else /* !__linux__ */
  979       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
  980                       "Operating system does not support abstract socket namespace\n");
  981       _dbus_close (fd, NULL);
  982       return -1;
  983 #endif /* !__linux__ */
  984     }
  985   else
  986     {
  987       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
  988         {
  989           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
  990                       "Socket name too long\n");
  991           _dbus_close (fd, NULL);
  992           return -1;
  993     }
  994 
  995       strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
  996     }
  997 
  998   if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
  999     {
 1000       dbus_set_error (error,
 1001                       _dbus_error_from_errno (errno),
 1002                       "Failed to connect to socket %s: %s",
 1003                       path, _dbus_strerror (errno));
 1004 
 1005       _dbus_close (fd, NULL);
 1006       return -1;
 1007     }
 1008 
 1009   if (!_dbus_set_fd_nonblocking (fd, error))
 1010     {
 1011       _DBUS_ASSERT_ERROR_IS_SET (error);
 1012 
 1013       _dbus_close (fd, NULL);
 1014       return -1;
 1015     }
 1016 
 1017   return fd;
 1018 }
 1019 
 1020 /**
 1021  * Creates a UNIX domain socket and connects it to the specified
 1022  * process to execute.
 1023  *
 1024  * This will set FD_CLOEXEC for the socket returned.
 1025  *
 1026  * @param path the path to the executable
 1027  * @param argv the argument list for the process to execute.
 1028  * argv[0] typically is identical to the path of the executable
 1029  * @param error return location for error code
 1030  * @returns connection file descriptor or -1 on error
 1031  */
 1032 int
 1033 _dbus_connect_exec (const char     *path,
 1034                     char *const    argv[],
 1035                     DBusError      *error)
 1036 {
 1037   int fds[2];
 1038   pid_t pid;
 1039   int retval;
 1040   dbus_bool_t cloexec_done = 0;
 1041 
 1042   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 1043 
 1044   _dbus_verbose ("connecting to process %s\n", path);
 1045 
 1046 #ifdef SOCK_CLOEXEC
 1047   retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
 1048   cloexec_done = (retval >= 0);
 1049 
 1050   if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
 1051 #endif
 1052     {
 1053       retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
 1054     }
 1055 
 1056   if (retval < 0)
 1057     {
 1058       dbus_set_error (error,
 1059                       _dbus_error_from_errno (errno),
 1060                       "Failed to create socket pair: %s",
 1061                       _dbus_strerror (errno));
 1062       return -1;
 1063     }
 1064 
 1065   if (!cloexec_done)
 1066     {
 1067       _dbus_fd_set_close_on_exec (fds[0]);
 1068       _dbus_fd_set_close_on_exec (fds[1]);
 1069     }
 1070 
 1071   pid = fork ();
 1072   if (pid < 0)
 1073     {
 1074       dbus_set_error (error,
 1075                       _dbus_error_from_errno (errno),
 1076                       "Failed to fork() to call %s: %s",
 1077                       path, _dbus_strerror (errno));
 1078       close (fds[0]);
 1079       close (fds[1]);
 1080       return -1;
 1081     }
 1082 
 1083   if (pid == 0)
 1084     {
 1085       /* child */
 1086       close (fds[0]);
 1087 
 1088       dup2 (fds[1], STDIN_FILENO);
 1089       dup2 (fds[1], STDOUT_FILENO);
 1090 
 1091       if (fds[1] != STDIN_FILENO &&
 1092           fds[1] != STDOUT_FILENO)
 1093         close (fds[1]);
 1094 
 1095       /* Inherit STDERR and the controlling terminal from the
 1096          parent */
 1097 
 1098       _dbus_close_all ();
 1099 
 1100       execvp (path, (char * const *) argv);
 1101 
 1102       fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
 1103 
 1104       _exit(1);
 1105     }
 1106 
 1107   /* parent */
 1108   close (fds[1]);
 1109 
 1110   if (!_dbus_set_fd_nonblocking (fds[0], error))
 1111     {
 1112       _DBUS_ASSERT_ERROR_IS_SET (error);
 1113 
 1114       close (fds[0]);
 1115       return -1;
 1116     }
 1117 
 1118   return fds[0];
 1119 }
 1120 
 1121 /**
 1122  * Creates a socket and binds it to the given path,
 1123  * then listens on the socket. The socket is
 1124  * set to be nonblocking.
 1125  *
 1126  * Uses abstract sockets instead of filesystem-linked
 1127  * sockets if requested (it's possible only on Linux;
 1128  * see "man 7 unix" on Linux).
 1129  * On non-Linux abstract socket usage always fails.
 1130  *
 1131  * This will set FD_CLOEXEC for the socket returned
 1132  *
 1133  * @param path the socket name
 1134  * @param abstract #TRUE to use abstract namespace
 1135  * @param error return location for errors
 1136  * @returns the listening file descriptor or -1 on error
 1137  */
 1138 int
 1139 _dbus_listen_unix_socket (const char     *path,
 1140                           dbus_bool_t     abstract,
 1141                           DBusError      *error)
 1142 {
 1143   int listen_fd;
 1144   struct sockaddr_un addr;
 1145   size_t path_len;
 1146   _DBUS_STATIC_ASSERT (sizeof (addr.sun_path) > _DBUS_MAX_SUN_PATH_LENGTH);
 1147 
 1148   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 1149 
 1150   _dbus_verbose ("listening on unix socket %s abstract=%d\n",
 1151                  path, abstract);
 1152 
 1153   if (!_dbus_open_unix_socket (&listen_fd, error))
 1154     {
 1155       _DBUS_ASSERT_ERROR_IS_SET(error);
 1156       return -1;
 1157     }
 1158   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
 1159 
 1160   _DBUS_ZERO (addr);
 1161   addr.sun_family = AF_UNIX;
 1162   path_len = strlen (path);
 1163 
 1164   if (abstract)
 1165     {
 1166 #ifdef __linux__
 1167       /* remember that abstract names aren't nul-terminated so we rely
 1168        * on sun_path being filled in with zeroes above.
 1169        */
 1170       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
 1171       path_len++; /* Account for the extra nul byte added to the start of sun_path */
 1172 
 1173       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
 1174         {
 1175           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
 1176                       "Abstract socket name too long\n");
 1177           _dbus_close (listen_fd, NULL);
 1178           return -1;
 1179     }
 1180 
 1181       strncpy (&addr.sun_path[1], path, sizeof (addr.sun_path) - 2);
 1182       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
 1183 #else /* !__linux__ */
 1184       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
 1185                       "Operating system does not support abstract socket namespace\n");
 1186       _dbus_close (listen_fd, NULL);
 1187       return -1;
 1188 #endif /* !__linux__ */
 1189     }
 1190   else
 1191     {
 1192       /* Discussed security implications of this with Nalin,
 1193        * and we couldn't think of where it would kick our ass, but
 1194        * it still seems a bit sucky. It also has non-security suckage;
 1195        * really we'd prefer to exit if the socket is already in use.
 1196        * But there doesn't seem to be a good way to do this.
 1197        *
 1198        * Just to be extra careful, I threw in the stat() - clearly
 1199        * the stat() can't *fix* any security issue, but it at least
 1200        * avoids inadvertent/accidental data loss.
 1201        */
 1202       {
 1203         struct stat sb;
 1204 
 1205         if (stat (path, &sb) == 0 &&
 1206             S_ISSOCK (sb.st_mode))
 1207           unlink (path);
 1208       }
 1209 
 1210       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
 1211         {
 1212           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
 1213                       "Socket name too long\n");
 1214           _dbus_close (listen_fd, NULL);
 1215           return -1;
 1216     }
 1217 
 1218       strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
 1219     }
 1220 
 1221   if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
 1222     {
 1223       dbus_set_error (error, _dbus_error_from_errno (errno),
 1224                       "Failed to bind socket \"%s\": %s",
 1225                       path, _dbus_strerror (errno));
 1226       _dbus_close (listen_fd, NULL);
 1227       return -1;
 1228     }
 1229 
 1230   if (listen (listen_fd, SOMAXCONN /* backlog */) < 0)
 1231     {
 1232       dbus_set_error (error, _dbus_error_from_errno (errno),
 1233                       "Failed to listen on socket \"%s\": %s",
 1234                       path, _dbus_strerror (errno));
 1235       _dbus_close (listen_fd, NULL);
 1236       return -1;
 1237     }
 1238 
 1239   if (!_dbus_set_fd_nonblocking (listen_fd, error))
 1240     {
 1241       _DBUS_ASSERT_ERROR_IS_SET (error);
 1242       _dbus_close (listen_fd, NULL);
 1243       return -1;
 1244     }
 1245 
 1246   /* Try opening up the permissions, but if we can't, just go ahead
 1247    * and continue, maybe it will be good enough.
 1248    */
 1249   if (!abstract && chmod (path, 0777) < 0)
 1250     _dbus_warn ("Could not set mode 0777 on socket %s", path);
 1251 
 1252   return listen_fd;
 1253 }
 1254 
 1255 /**
 1256  * Acquires one or more sockets passed in from systemd. The sockets
 1257  * are set to be nonblocking.
 1258  *
 1259  * This will set FD_CLOEXEC for the sockets returned.
 1260  *
 1261  * @param fds the file descriptors
 1262  * @param error return location for errors
 1263  * @returns the number of file descriptors
 1264  */
 1265 int
 1266 _dbus_listen_systemd_sockets (DBusSocket **fds,
 1267                               DBusError   *error)
 1268 {
 1269 #ifdef HAVE_SYSTEMD
 1270   int r, n;
 1271   int fd;
 1272   DBusSocket *new_fds;
 1273 
 1274   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 1275 
 1276   n = sd_listen_fds (TRUE);
 1277   if (n < 0)
 1278     {
 1279       dbus_set_error (error, _dbus_error_from_errno (-n),
 1280                       "Failed to acquire systemd socket: %s",
 1281                       _dbus_strerror (-n));
 1282       return -1;
 1283     }
 1284 
 1285   if (n <= 0)
 1286     {
 1287       dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
 1288                       "No socket received.");
 1289       return -1;
 1290     }
 1291 
 1292   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
 1293     {
 1294       r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
 1295       if (r < 0)
 1296         {
 1297           dbus_set_error (error, _dbus_error_from_errno (-r),
 1298                           "Failed to verify systemd socket type: %s",
 1299                           _dbus_strerror (-r));
 1300           return -1;
 1301         }
 1302 
 1303       if (!r)
 1304         {
 1305           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
 1306                           "Passed socket has wrong type.");
 1307           return -1;
 1308         }
 1309     }
 1310 
 1311   /* OK, the file descriptors are all good, so let's take posession of
 1312      them then. */
 1313 
 1314   new_fds = dbus_new (DBusSocket, n);
 1315   if (!new_fds)
 1316     {
 1317       dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
 1318                       "Failed to allocate file handle array.");
 1319       goto fail;
 1320     }
 1321 
 1322   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
 1323     {
 1324       if (!_dbus_set_fd_nonblocking (fd, error))
 1325         {
 1326           _DBUS_ASSERT_ERROR_IS_SET (error);
 1327           goto fail;
 1328         }
 1329 
 1330       new_fds[fd - SD_LISTEN_FDS_START].fd = fd;
 1331     }
 1332 
 1333   *fds = new_fds;
 1334   return n;
 1335 
 1336  fail:
 1337 
 1338   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
 1339     {
 1340       _dbus_close (fd, NULL);
 1341     }
 1342 
 1343   dbus_free (new_fds);
 1344   return -1;
 1345 #else
 1346   dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
 1347                         "dbus was compiled without systemd support");
 1348   return -1;
 1349 #endif
 1350 }
 1351 
 1352 /* Convert an error code from getaddrinfo() or getnameinfo() into
 1353  * a D-Bus error name. */
 1354 static const char *
 1355 _dbus_error_from_gai (int gai_res,
 1356                       int saved_errno)
 1357 {
 1358   switch (gai_res)
 1359     {
 1360 #ifdef EAI_FAMILY
 1361       case EAI_FAMILY:
 1362         /* ai_family not supported (at all) */
 1363         return DBUS_ERROR_NOT_SUPPORTED;
 1364 #endif
 1365 
 1366 #ifdef EAI_SOCKTYPE
 1367       case EAI_SOCKTYPE:
 1368         /* ai_socktype not supported (at all) */
 1369         return DBUS_ERROR_NOT_SUPPORTED;
 1370 #endif
 1371 
 1372 #ifdef EAI_MEMORY
 1373       case EAI_MEMORY:
 1374         /* Out of memory */
 1375         return DBUS_ERROR_NO_MEMORY;
 1376 #endif
 1377 
 1378 #ifdef EAI_SYSTEM
 1379       case EAI_SYSTEM:
 1380         /* Unspecified system error, details in errno */
 1381         return _dbus_error_from_errno (saved_errno);
 1382 #endif
 1383 
 1384       case 0:
 1385         /* It succeeded, but we didn't get any addresses? */
 1386         return DBUS_ERROR_FAILED;
 1387 
 1388       /* EAI_AGAIN: Transient failure */
 1389       /* EAI_BADFLAGS: invalid ai_flags (programming error) */
 1390       /* EAI_FAIL: Non-recoverable failure */
 1391       /* EAI_NODATA: host exists but has no addresses */
 1392       /* EAI_NONAME: host does not exist */
 1393       /* EAI_OVERFLOW: argument buffer overflow */
 1394       /* EAI_SERVICE: service not available for specified socket
 1395        * type (we should never see this because we use numeric
 1396        * ports) */
 1397       default:
 1398         return DBUS_ERROR_FAILED;
 1399     }
 1400 }
 1401 
 1402 /**
 1403  * Creates a socket and connects to a socket at the given host
 1404  * and port. The connection fd is returned, and is set up as
 1405  * nonblocking.
 1406  *
 1407  * This will set FD_CLOEXEC for the socket returned
 1408  *
 1409  * @param host the host name to connect to
 1410  * @param port the port to connect to
 1411  * @param family the address family to listen on, NULL for all
 1412  * @param error return location for error code
 1413  * @returns connection file descriptor or -1 on error
 1414  */
 1415 DBusSocket
 1416 _dbus_connect_tcp_socket (const char     *host,
 1417                           const char     *port,
 1418                           const char     *family,
 1419                           DBusError      *error)
 1420 {
 1421     return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
 1422 }
 1423 
 1424 DBusSocket
 1425 _dbus_connect_tcp_socket_with_nonce (const char     *host,
 1426                                      const char     *port,
 1427                                      const char     *family,
 1428                                      const char     *noncefile,
 1429                                      DBusError      *error)
 1430 {
 1431   int saved_errno = 0;
 1432   DBusSocket fd = DBUS_SOCKET_INIT;
 1433   int res;
 1434   struct addrinfo hints;
 1435   struct addrinfo *ai, *tmp;
 1436 
 1437   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
 1438 
 1439   _DBUS_ZERO (hints);
 1440 
 1441   if (!family)
 1442     hints.ai_family = AF_UNSPEC;
 1443   else if (!strcmp(family, "ipv4"))
 1444     hints.ai_family = AF_INET;
 1445   else if (!strcmp(family, "ipv6"))
 1446     hints.ai_family = AF_INET6;
 1447   else
 1448     {
 1449       dbus_set_error (error,
 1450                       DBUS_ERROR_BAD_ADDRESS,
 1451                       "Unknown address family %s", family);
 1452       return _dbus_socket_get_invalid ();
 1453     }
 1454   hints.ai_protocol = IPPROTO_TCP;
 1455   hints.ai_socktype = SOCK_STREAM;
 1456   hints.ai_flags = AI_ADDRCONFIG;
 1457 
 1458   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
 1459     {
 1460       dbus_set_error (error,
 1461                       _dbus_error_from_gai (res, errno),
 1462                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
 1463                       host, port, gai_strerror(res), res);
 1464       return _dbus_socket_get_invalid ();
 1465     }
 1466 
 1467   tmp = ai;
 1468   while (tmp)
 1469     {
 1470       if (!_dbus_open_socket (&fd.fd, tmp->ai_family, SOCK_STREAM, 0, error))
 1471         {
 1472           freeaddrinfo(ai);
 1473           _DBUS_ASSERT_ERROR_IS_SET(error);
 1474           return _dbus_socket_get_invalid ();
 1475         }
 1476       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
 1477 
 1478       if (connect (fd.fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
 1479         {
 1480           saved_errno = errno;
 1481           _dbus_close (fd.fd, NULL);
 1482           fd.fd = -1;
 1483           tmp = tmp->ai_next;
 1484           continue;
 1485         }
 1486 
 1487       break;
 1488     }
 1489   freeaddrinfo(ai);
 1490 
 1491   if (fd.fd == -1)
 1492     {
 1493       dbus_set_error (error,
 1494                       _dbus_error_from_errno (saved_errno),
 1495                       "Failed to connect to socket \"%s:%s\" %s",
 1496                       host, port, _dbus_strerror(saved_errno));
 1497       return _dbus_socket_get_invalid ();
 1498     }
 1499 
 1500   if (noncefile != NULL)
 1501     {
 1502       DBusString noncefileStr;
 1503       dbus_bool_t ret;
 1504       _dbus_string_init_const (&noncefileStr, noncefile);
 1505       ret = _dbus_send_nonce (fd, &noncefileStr, error);
 1506       _dbus_string_free (&noncefileStr);
 1507 
 1508       if (!ret)
 1509         {
 1510           _dbus_close (fd.fd, NULL);
 1511           return _dbus_socket_get_invalid ();
 1512         }
 1513     }
 1514 
 1515   if (!_dbus_set_fd_nonblocking (fd.fd, error))
 1516     {
 1517       _dbus_close (fd.fd, NULL);
 1518       return _dbus_socket_get_invalid ();
 1519     }
 1520 
 1521   return fd;
 1522 }
 1523 
 1524 /**
 1525  * Creates a socket and binds it to the given path, then listens on
 1526  * the socket. The socket is set to be nonblocking.  In case of port=0
 1527  * a random free port is used and returned in the port parameter.
 1528  * If inaddr_any is specified, the hostname is ignored.
 1529  *
 1530  * This will set FD_CLOEXEC for the socket returned
 1531  *
 1532  * @param host the host name to listen on
 1533  * @param port the port to listen on, if zero a free port will be used
 1534  * @param family the address family to listen on, NULL for all
 1535  * @param retport string to return the actual port listened on
 1536  * @param fds_p location to store returned file descriptors
 1537  * @param error return location for errors
 1538  * @returns the number of listening file descriptors or -1 on error
 1539  */
 1540 int
 1541 _dbus_listen_tcp_socket (const char     *host,
 1542                          const char     *port,
 1543                          const char     *family,
 1544                          DBusString     *retport,
 1545                          DBusSocket    **fds_p,
 1546                          DBusError      *error)
 1547 {
 1548   int saved_errno;
 1549   int nlisten_fd = 0, res, i;
 1550   DBusSocket *listen_fd = NULL;
 1551   struct addrinfo hints;
 1552   struct addrinfo *ai, *tmp;
 1553   unsigned int reuseaddr;
 1554 
 1555   *fds_p = NULL;
 1556   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 1557 
 1558   _DBUS_ZERO (hints);
 1559 
 1560   if (!family)
 1561     hints.ai_family = AF_UNSPEC;
 1562   else if (!strcmp(family, "ipv4"))
 1563     hints.ai_family = AF_INET;
 1564   else if (!strcmp(family, "ipv6"))
 1565     hints.ai_family = AF_INET6;
 1566   else
 1567     {
 1568       dbus_set_error (error,
 1569                       DBUS_ERROR_BAD_ADDRESS,
 1570                       "Unknown address family %s", family);
 1571       return -1;
 1572     }
 1573 
 1574   hints.ai_protocol = IPPROTO_TCP;
 1575   hints.ai_socktype = SOCK_STREAM;
 1576   hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
 1577 
 1578  redo_lookup_with_port:
 1579   ai = NULL;
 1580   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
 1581     {
 1582       dbus_set_error (error,
 1583                       _dbus_error_from_gai (res, errno),
 1584                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
 1585                       host ? host : "*", port, gai_strerror(res), res);
 1586       goto failed;
 1587     }
 1588 
 1589   tmp = ai;
 1590   while (tmp)
 1591     {
 1592       int fd = -1, tcp_nodelay_on;
 1593       DBusSocket *newlisten_fd;
 1594 
 1595       if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
 1596         {
 1597           _DBUS_ASSERT_ERROR_IS_SET(error);
 1598           goto failed;
 1599         }
 1600       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
 1601 
 1602       reuseaddr = 1;
 1603       if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
 1604         {
 1605           _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
 1606                       host ? host : "*", port, _dbus_strerror (errno));
 1607         }
 1608 
 1609       /* Nagle's algorithm imposes a huge delay on the initial messages
 1610          going over TCP. */
 1611       tcp_nodelay_on = 1;
 1612       if (setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &tcp_nodelay_on, sizeof (tcp_nodelay_on)) == -1)
 1613         {
 1614           _dbus_warn ("Failed to set TCP_NODELAY socket option \"%s:%s\": %s",
 1615                       host ? host : "*", port, _dbus_strerror (errno));
 1616         }
 1617 
 1618       if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
 1619         {
 1620           saved_errno = errno;
 1621           _dbus_close(fd, NULL);
 1622           if (saved_errno == EADDRINUSE)
 1623             {
 1624               /* Depending on kernel policy, binding to an IPv6 address
 1625                  might implicitly bind to a corresponding IPv4
 1626                  address or vice versa, resulting in EADDRINUSE for the
 1627                  other one (e.g. bindv6only=0 on Linux).
 1628 
 1629                  Also, after we "goto redo_lookup_with_port" after binding
 1630                  a port on one of the possible addresses, we will
 1631                  try to bind that same port on every address, including the
 1632                  same address again for a second time; that one will
 1633                  also fail with EADDRINUSE.
 1634 
 1635                  For both those reasons, ignore EADDRINUSE here */
 1636               tmp = tmp->ai_next;
 1637               continue;
 1638             }
 1639           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
 1640                           "Failed to bind socket \"%s:%s\": %s",
 1641                           host ? host : "*", port, _dbus_strerror (saved_errno));
 1642           goto failed;
 1643         }
 1644 
 1645       if (listen (fd, 30 /* backlog */) < 0)
 1646         {
 1647           saved_errno = errno;
 1648           _dbus_close (fd, NULL);
 1649           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
 1650                           "Failed to listen on socket \"%s:%s\": %s",
 1651                           host ? host : "*", port, _dbus_strerror (saved_errno));
 1652           goto failed;
 1653         }
 1654 
 1655       newlisten_fd = dbus_realloc(listen_fd, sizeof(DBusSocket)*(nlisten_fd+1));
 1656       if (!newlisten_fd)
 1657         {
 1658           _dbus_close (fd, NULL);
 1659           dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
 1660                           "Failed to allocate file handle array");
 1661           goto failed;
 1662         }
 1663       listen_fd = newlisten_fd;
 1664       listen_fd[nlisten_fd].fd = fd;
 1665       nlisten_fd++;
 1666 
 1667       if (!_dbus_string_get_length(retport))
 1668         {
 1669           /* If the user didn't specify a port, or used 0, then
 1670              the kernel chooses a port. After the first address
 1671              is bound to, we need to force all remaining addresses
 1672              to use the same port */
 1673           if (!port || !strcmp(port, "0"))
 1674             {
 1675               int result;
 1676               struct sockaddr_storage addr;
 1677               socklen_t addrlen;
 1678               char portbuf[50];
 1679 
 1680               addrlen = sizeof(addr);
 1681               result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
 1682 
 1683               if (result == -1)
 1684                 {
 1685                   saved_errno = errno;
 1686                   dbus_set_error (error, _dbus_error_from_errno (saved_errno),
 1687                                   "Failed to retrieve socket name for \"%s:%s\": %s",
 1688                                   host ? host : "*", port, _dbus_strerror (saved_errno));
 1689                   goto failed;
 1690                 }
 1691 
 1692               if ((res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
 1693                                       portbuf, sizeof(portbuf),
 1694                                       NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
 1695                 {
 1696                   saved_errno = errno;
 1697                   dbus_set_error (error, _dbus_error_from_gai (res, saved_errno),
 1698                                   "Failed to resolve port \"%s:%s\": %s (%d)",
 1699                                   host ? host : "*", port, gai_strerror(res), res);
 1700                   goto failed;
 1701                 }
 1702 
 1703               if (!_dbus_string_append(retport, portbuf))
 1704                 {
 1705                   dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
 1706                   goto failed;
 1707                 }
 1708 
 1709               /* Release current address list & redo lookup */
 1710               port = _dbus_string_get_const_data(retport);
 1711               freeaddrinfo(ai);
 1712               goto redo_lookup_with_port;
 1713             }
 1714           else
 1715             {
 1716               if (!_dbus_string_append(retport, port))
 1717                 {
 1718                     dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
 1719                     goto failed;
 1720                 }
 1721             }
 1722         }
 1723 
 1724       tmp = tmp->ai_next;
 1725     }
 1726   freeaddrinfo(ai);
 1727   ai = NULL;
 1728 
 1729   if (!nlisten_fd)
 1730     {
 1731       errno = EADDRINUSE;
 1732       dbus_set_error (error, _dbus_error_from_errno (errno),
 1733                       "Failed to bind socket \"%s:%s\": %s",
 1734                       host ? host : "*", port, _dbus_strerror (errno));
 1735       goto failed;
 1736     }
 1737 
 1738   for (i = 0 ; i < nlisten_fd ; i++)
 1739     {
 1740       if (!_dbus_set_fd_nonblocking (listen_fd[i].fd, error))
 1741         {
 1742           goto failed;
 1743         }
 1744     }
 1745 
 1746   *fds_p = listen_fd;
 1747 
 1748   return nlisten_fd;
 1749 
 1750  failed:
 1751   if (ai)
 1752     freeaddrinfo(ai);
 1753   for (i = 0 ; i < nlisten_fd ; i++)
 1754     _dbus_close(listen_fd[i].fd, NULL);
 1755   dbus_free(listen_fd);
 1756   return -1;
 1757 }
 1758 
 1759 static dbus_bool_t
 1760 write_credentials_byte (int             server_fd,
 1761                         DBusError      *error)
 1762 {
 1763   int bytes_written;
 1764   char buf[1] = { '\0' };
 1765 #if defined(HAVE_CMSGCRED)
 1766   union {
 1767       struct cmsghdr hdr;
 1768       char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
 1769   } cmsg;
 1770   struct iovec iov;
 1771   struct msghdr msg;
 1772   iov.iov_base = buf;
 1773   iov.iov_len = 1;
 1774 
 1775   _DBUS_ZERO(msg);
 1776   msg.msg_iov = &iov;
 1777   msg.msg_iovlen = 1;
 1778 
 1779   msg.msg_control = (caddr_t) &cmsg;
 1780   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
 1781   _DBUS_ZERO(cmsg);
 1782   cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
 1783   cmsg.hdr.cmsg_level = SOL_SOCKET;
 1784   cmsg.hdr.cmsg_type = SCM_CREDS;
 1785 #endif
 1786 
 1787   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 1788 
 1789  again:
 1790 
 1791 #if defined(HAVE_CMSGCRED)
 1792   bytes_written = sendmsg (server_fd, &msg, 0
 1793 #if HAVE_DECL_MSG_NOSIGNAL
 1794                            |MSG_NOSIGNAL
 1795 #endif
 1796                            );
 1797 
 1798   /* If we HAVE_CMSGCRED, the OS still might not let us sendmsg()
 1799    * with a SOL_SOCKET/SCM_CREDS message - for instance, FreeBSD
 1800    * only allows that on AF_UNIX. Try just doing a send() instead. */
 1801   if (bytes_written < 0 && errno == EINVAL)
 1802 #endif
 1803     {
 1804       bytes_written = send (server_fd, buf, 1, 0
 1805 #if HAVE_DECL_MSG_NOSIGNAL
 1806                             |MSG_NOSIGNAL
 1807 #endif
 1808                             );
 1809     }
 1810 
 1811   if (bytes_written < 0 && errno == EINTR)
 1812     goto again;
 1813 
 1814   if (bytes_written < 0)
 1815     {
 1816       dbus_set_error (error, _dbus_error_from_errno (errno),
 1817                       "Failed to write credentials byte: %s",
 1818                      _dbus_strerror (errno));
 1819       return FALSE;
 1820     }
 1821   else if (bytes_written == 0)
 1822     {
 1823       dbus_set_error (error, DBUS_ERROR_IO_ERROR,
 1824                       "wrote zero bytes writing credentials byte");
 1825       return FALSE;
 1826     }
 1827   else
 1828     {
 1829       _dbus_assert (bytes_written == 1);
 1830       _dbus_verbose ("wrote credentials byte\n");
 1831       return TRUE;
 1832     }
 1833 }
 1834 
 1835 /* return FALSE on OOM, TRUE otherwise, even if no credentials were found */
 1836 static dbus_bool_t
 1837 add_linux_security_label_to_credentials (int              client_fd,
 1838                                          DBusCredentials *credentials)
 1839 {
 1840 #if defined(__linux__) && defined(SO_PEERSEC)
 1841   DBusString buf;
 1842   socklen_t len = 1024;
 1843   dbus_bool_t oom = FALSE;
 1844 
 1845   if (!_dbus_string_init_preallocated (&buf, len) ||
 1846       !_dbus_string_set_length (&buf, len))
 1847     return FALSE;
 1848 
 1849   while (getsockopt (client_fd, SOL_SOCKET, SO_PEERSEC,
 1850          _dbus_string_get_data (&buf), &len) < 0)
 1851     {
 1852       int e = errno;
 1853 
 1854       _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
 1855                      _dbus_strerror (e), (unsigned long) len);
 1856 
 1857       if (e != ERANGE || len <= _dbus_string_get_length_uint (&buf))
 1858         {
 1859           _dbus_verbose ("Failed to getsockopt(SO_PEERSEC): %s\n",
 1860                          _dbus_strerror (e));
 1861           goto out;
 1862         }
 1863 
 1864       /* If not enough space, len is updated to be enough.
 1865        * Try again with a large enough buffer. */
 1866       if (!_dbus_string_set_length (&buf, len))
 1867         {
 1868           oom = TRUE;
 1869           goto out;
 1870         }
 1871 
 1872       _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
 1873     }
 1874 
 1875   if (len <= 0)
 1876     {
 1877       _dbus_verbose ("getsockopt(SO_PEERSEC) yielded <= 0 bytes: %lu\n",
 1878                      (unsigned long) len);
 1879       goto out;
 1880     }
 1881 
 1882   if (len > _dbus_string_get_length_uint (&buf))
 1883     {
 1884       _dbus_verbose ("%lu > %u", (unsigned long) len,
 1885                      _dbus_string_get_length_uint (&buf));
 1886       _dbus_assert_not_reached ("getsockopt(SO_PEERSEC) overflowed");
 1887     }
 1888 
 1889   if (_dbus_string_get_byte (&buf, len - 1) == 0)
 1890     {
 1891       /* the kernel included the trailing \0 in its count,
 1892        * but DBusString always has an extra \0 after the data anyway */
 1893       _dbus_verbose ("subtracting trailing \\0\n");
 1894       len--;
 1895     }
 1896 
 1897   if (!_dbus_string_set_length (&buf, len))
 1898     {
 1899       _dbus_assert_not_reached ("shortening string should not lead to OOM");
 1900       oom = TRUE;
 1901       goto out;
 1902     }
 1903 
 1904   if (strlen (_dbus_string_get_const_data (&buf)) != len)
 1905     {
 1906       /* LSM people on the linux-security-module@ mailing list say this
 1907        * should never happen: the label should be a bytestring with
 1908        * an optional trailing \0 */
 1909       _dbus_verbose ("security label from kernel had an embedded \\0, "
 1910                      "ignoring it\n");
 1911       goto out;
 1912     }
 1913 
 1914   _dbus_verbose ("getsockopt(SO_PEERSEC): %lu bytes excluding \\0: %s\n",
 1915                  (unsigned long) len,
 1916                  _dbus_string_get_const_data (&buf));
 1917 
 1918   if (!_dbus_credentials_add_linux_security_label (credentials,
 1919         _dbus_string_get_const_data (&buf)))
 1920     {
 1921       oom = TRUE;
 1922       goto out;
 1923     }
 1924 
 1925 out:
 1926   _dbus_string_free (&buf);
 1927   return !oom;
 1928 #else
 1929   /* no error */
 1930   return TRUE;
 1931 #endif
 1932 }
 1933 
 1934 /**
 1935  * Reads a single byte which must be nul (an error occurs otherwise),
 1936  * and reads unix credentials if available. Clears the credentials
 1937  * object, then adds pid/uid if available, so any previous credentials
 1938  * stored in the object are lost.
 1939  *
 1940  * DBusServer makes the security assumption that the credentials
 1941  * returned by this method are the credentials that were active
 1942  * at the time the socket was opened. Do not add APIs to this
 1943  * method that would break that assumption.
 1944  *
 1945  * In particular, it is incorrect to use any API of the form
 1946  * "get the process ID at the other end of the connection, then
 1947  * determine its uid, gid, or other credentials from the pid"
 1948  * (e.g. looking in /proc on Linux). If we did that, we would
 1949  * be vulnerable to several attacks. A malicious process could
 1950  * queue up the rest of the authentication handshake and a malicious
 1951  * message that it should not be allowed to send, then race with
 1952  * the DBusServer to exec() a more privileged (e.g. setuid) binary that
 1953  * would have been allowed to send that message; or it could exit,
 1954  * and arrange for enough setuid processes to be started that its
 1955  * pid would be recycled for one of those processes with high
 1956  * probability; or it could fd-pass the connection to a more
 1957  * privileged process.
 1958  *
 1959  * Return value indicates whether a byte was read, not whether
 1960  * we got valid credentials. On some systems, such as Linux,
 1961  * reading/writing the byte isn't actually required, but we do it
 1962  * anyway just to avoid multiple codepaths.
 1963  *
 1964  * Fails if no byte is available, so you must select() first.
 1965  *
 1966  * The point of the byte is that on some systems we have to
 1967  * use sendmsg()/recvmsg() to transmit credentials.
 1968  *
 1969  * @param client_fd the client file descriptor
 1970  * @param credentials object to add client credentials to
 1971  * @param error location to store error code
 1972  * @returns #TRUE on success
 1973  */
 1974 dbus_bool_t
 1975 _dbus_read_credentials_socket  (DBusSocket       client_fd,
 1976                                 DBusCredentials *credentials,
 1977                                 DBusError       *error)
 1978 {
 1979   struct msghdr msg;
 1980   struct iovec iov;
 1981   char buf;
 1982   dbus_uid_t uid_read;
 1983   dbus_pid_t pid_read;
 1984   int bytes_read;
 1985 
 1986 #ifdef HAVE_CMSGCRED
 1987   union {
 1988     struct cmsghdr hdr;
 1989     char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
 1990   } cmsg;
 1991 #endif
 1992 
 1993   /* The POSIX spec certainly doesn't promise this, but
 1994    * we need these assertions to fail as soon as we're wrong about
 1995    * it so we can do the porting fixups
 1996    */
 1997   _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
 1998   _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
 1999   _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
 2000 
 2001   uid_read = DBUS_UID_UNSET;
 2002   pid_read = DBUS_PID_UNSET;
 2003 
 2004   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 2005 
 2006   _dbus_credentials_clear (credentials);
 2007 
 2008   iov.iov_base = &buf;
 2009   iov.iov_len = 1;
 2010 
 2011   _DBUS_ZERO(msg);
 2012   msg.msg_iov = &iov;
 2013   msg.msg_iovlen = 1;
 2014 
 2015 #if defined(HAVE_CMSGCRED)
 2016   _DBUS_ZERO(cmsg);
 2017   msg.msg_control = (caddr_t) &cmsg;
 2018   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
 2019 #endif
 2020 
 2021  again:
 2022   bytes_read = recvmsg (client_fd.fd, &msg, 0);
 2023 
 2024   if (bytes_read < 0)
 2025     {
 2026       if (errno == EINTR)
 2027     goto again;
 2028 
 2029       /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
 2030        * normally only call read_credentials if the socket was ready
 2031        * for reading
 2032        */
 2033 
 2034       dbus_set_error (error, _dbus_error_from_errno (errno),
 2035                       "Failed to read credentials byte: %s",
 2036                       _dbus_strerror (errno));
 2037       return FALSE;
 2038     }
 2039   else if (bytes_read == 0)
 2040     {
 2041       /* this should not happen unless we are using recvmsg wrong,
 2042        * so is essentially here for paranoia
 2043        */
 2044       dbus_set_error (error, DBUS_ERROR_FAILED,
 2045                       "Failed to read credentials byte (zero-length read)");
 2046       return FALSE;
 2047     }
 2048   else if (buf != '\0')
 2049     {
 2050       dbus_set_error (error, DBUS_ERROR_FAILED,
 2051                       "Credentials byte was not nul");
 2052       return FALSE;
 2053     }
 2054 
 2055   _dbus_verbose ("read credentials byte\n");
 2056 
 2057   {
 2058 #ifdef SO_PEERCRED
 2059     /* Supported by at least Linux and OpenBSD, with minor differences.
 2060      *
 2061      * This mechanism passes the process ID through and does not require
 2062      * the peer's cooperation, so we prefer it over all others. Notably,
 2063      * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
 2064      * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
 2065      * because this is much less fragile.
 2066      */
 2067 #ifdef __OpenBSD__
 2068     struct sockpeercred cr;
 2069 #else
 2070     struct ucred cr;
 2071 #endif
 2072     socklen_t cr_len = sizeof (cr);
 2073 
 2074     if (getsockopt (client_fd.fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) != 0)
 2075       {
 2076         _dbus_verbose ("Failed to getsockopt(SO_PEERCRED): %s\n",
 2077                        _dbus_strerror (errno));
 2078       }
 2079     else if (cr_len != sizeof (cr))
 2080       {
 2081         _dbus_verbose ("Failed to getsockopt(SO_PEERCRED), returned %d bytes, expected %d\n",
 2082                        cr_len, (int) sizeof (cr));
 2083       }
 2084     else
 2085       {
 2086         pid_read = cr.pid;
 2087         uid_read = cr.uid;
 2088       }
 2089 #elif defined(HAVE_UNPCBID) && defined(LOCAL_PEEREID)
 2090     /* Another variant of the above - used on NetBSD
 2091      */
 2092     struct unpcbid cr;
 2093     socklen_t cr_len = sizeof (cr);
 2094 
 2095     if (getsockopt (client_fd.fd, 0, LOCAL_PEEREID, &cr, &cr_len) != 0)
 2096       {
 2097         _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID): %s\n",
 2098                        _dbus_strerror (errno));
 2099       }
 2100     else if (cr_len != sizeof (cr))
 2101       {
 2102         _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID), returned %d bytes, expected %d\n",
 2103                        cr_len, (int) sizeof (cr));
 2104       }
 2105     else
 2106       {
 2107         pid_read = cr.unp_pid;
 2108         uid_read = cr.unp_euid;
 2109       }
 2110 #elif defined(HAVE_CMSGCRED)
 2111     /* We only check for HAVE_CMSGCRED, but we're really assuming that the
 2112      * presence of that struct implies SCM_CREDS. Supported by at least
 2113      * FreeBSD and DragonflyBSD.
 2114      *
 2115      * This mechanism requires the peer to help us (it has to send us a
 2116      * SCM_CREDS message) but it does pass the process ID through,
 2117      * which makes it better than getpeereid().
 2118      */
 2119     struct cmsgcred *cred;
 2120     struct cmsghdr *cmsgp;
 2121 
 2122     for (cmsgp = CMSG_FIRSTHDR (&msg);
 2123          cmsgp != NULL;
 2124          cmsgp = CMSG_NXTHDR (&msg, cmsgp))
 2125       {
 2126         if (cmsgp->cmsg_type == SCM_CREDS &&
 2127             cmsgp->cmsg_level == SOL_SOCKET &&
 2128             cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
 2129           {
 2130             cred = (struct cmsgcred *) CMSG_DATA (cmsgp);
 2131             pid_read = cred->cmcred_pid;
 2132             uid_read = cred->cmcred_euid;
 2133             break;
 2134           }
 2135       }
 2136 
 2137 #elif defined(HAVE_GETPEERUCRED)
 2138     /* Supported in at least Solaris >= 10. It should probably be higher
 2139      * up this list, because it carries the pid and we use this code path
 2140      * for audit data. */
 2141     ucred_t * ucred = NULL;
 2142     if (getpeerucred (client_fd.fd, &ucred) == 0)
 2143       {
 2144 #ifdef HAVE_ADT
 2145         adt_session_data_t *adth = NULL;
 2146 #endif
 2147         pid_read = ucred_getpid (ucred);
 2148         uid_read = ucred_geteuid (ucred);
 2149 #ifdef HAVE_ADT
 2150         /* generate audit session data based on socket ucred */
 2151         if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
 2152           {
 2153             _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
 2154           }
 2155         else
 2156           {
 2157             if (adt_set_from_ucred (adth, ucred, ADT_NEW))
 2158               {
 2159                 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
 2160               }
 2161             else
 2162               {
 2163                 adt_export_data_t *data = NULL;
 2164                 size_t size = adt_export_session_data (adth, &data);
 2165                 if (size <= 0)
 2166                   {
 2167                     _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
 2168                   }
 2169                 else
 2170                   {
 2171                     _dbus_credentials_add_adt_audit_data (credentials, data, size);
 2172                     free (data);
 2173                   }
 2174               }
 2175             (void) adt_end_session (adth);
 2176           }
 2177 #endif /* HAVE_ADT */
 2178       }
 2179     else
 2180       {
 2181         _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
 2182       }
 2183     if (ucred != NULL)
 2184       ucred_free (ucred);
 2185 
 2186     /* ----------------------------------------------------------------
 2187      * When adding new mechanisms, please add them above this point
 2188      * if they support passing the process ID through, or below if not.
 2189      * ---------------------------------------------------------------- */
 2190 
 2191 #elif defined(HAVE_GETPEEREID)
 2192     /* getpeereid() originates from D.J. Bernstein and is fairly
 2193      * widely-supported. According to a web search, it might be present in
 2194      * any/all of:
 2195      *
 2196      * - AIX?
 2197      * - Blackberry?
 2198      * - Cygwin
 2199      * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
 2200      * - Mac OS X
 2201      * - Minix 3.1.8+
 2202      * - MirBSD?
 2203      * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
 2204      * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
 2205      * - QNX?
 2206      */
 2207     uid_t euid;
 2208     gid_t egid;
 2209     if (getpeereid (client_fd.fd, &euid, &egid) == 0)
 2210       {
 2211         uid_read = euid;
 2212       }
 2213     else
 2214       {
 2215         _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
 2216       }
 2217 #else /* no supported mechanism */
 2218 
 2219 #warning Socket credentials not supported on this Unix OS
 2220 #warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
 2221 
 2222     /* Please add other operating systems known to support at least one of
 2223      * the mechanisms above to this list, keeping alphabetical order.
 2224      * Everything not in this list  is best-effort.
 2225      */
 2226 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
 2227     defined(__linux__) || \
 2228     defined(__OpenBSD__) || \
 2229     defined(__NetBSD__)
 2230 # error Credentials passing not working on this OS is a regression!
 2231 #endif
 2232 
 2233     _dbus_verbose ("Socket credentials not supported on this OS\n");
 2234 #endif
 2235   }
 2236 
 2237   _dbus_verbose ("Credentials:"
 2238                  "  pid "DBUS_PID_FORMAT
 2239                  "  uid "DBUS_UID_FORMAT
 2240                  "\n",
 2241          pid_read,
 2242          uid_read);
 2243 
 2244   if (pid_read != DBUS_PID_UNSET)
 2245     {
 2246       if (!_dbus_credentials_add_pid (credentials, pid_read))
 2247         {
 2248           _DBUS_SET_OOM (error);
 2249           return FALSE;
 2250         }
 2251     }
 2252 
 2253   if (uid_read != DBUS_UID_UNSET)
 2254     {
 2255       if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
 2256         {
 2257           _DBUS_SET_OOM (error);
 2258           return FALSE;
 2259         }
 2260     }
 2261 
 2262   if (!add_linux_security_label_to_credentials (client_fd.fd, credentials))
 2263     {
 2264       _DBUS_SET_OOM (error);
 2265       return FALSE;
 2266     }
 2267 
 2268   return TRUE;
 2269 }
 2270 
 2271 /**
 2272  * Sends a single nul byte with our UNIX credentials as ancillary
 2273  * data.  Returns #TRUE if the data was successfully written.  On
 2274  * systems that don't support sending credentials, just writes a byte,
 2275  * doesn't send any credentials.  On some systems, such as Linux,
 2276  * reading/writing the byte isn't actually required, but we do it
 2277  * anyway just to avoid multiple codepaths.
 2278  *
 2279  * Fails if no byte can be written, so you must select() first.
 2280  *
 2281  * The point of the byte is that on some systems we have to
 2282  * use sendmsg()/recvmsg() to transmit credentials.
 2283  *
 2284  * @param server_fd file descriptor for connection to server
 2285  * @param error return location for error code
 2286  * @returns #TRUE if the byte was sent
 2287  */
 2288 dbus_bool_t
 2289 _dbus_send_credentials_socket  (DBusSocket       server_fd,
 2290                                 DBusError       *error)
 2291 {
 2292   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 2293 
 2294   if (write_credentials_byte (server_fd.fd, error))
 2295     return TRUE;
 2296   else
 2297     return FALSE;
 2298 }
 2299 
 2300 /**
 2301  * Accepts a connection on a listening socket.
 2302  * Handles EINTR for you.
 2303  *
 2304  * This will enable FD_CLOEXEC for the returned socket.
 2305  *
 2306  * @param listen_fd the listen file descriptor
 2307  * @returns the connection fd of the client, or -1 on error
 2308  */
 2309 DBusSocket
 2310 _dbus_accept  (DBusSocket listen_fd)
 2311 {
 2312   DBusSocket client_fd;
 2313   struct sockaddr addr;
 2314   socklen_t addrlen;
 2315 #ifdef HAVE_ACCEPT4
 2316   dbus_bool_t cloexec_done;
 2317 #endif
 2318 
 2319   addrlen = sizeof (addr);
 2320 
 2321  retry:
 2322 
 2323 #ifdef HAVE_ACCEPT4
 2324   /*
 2325    * At compile-time, we assume that if accept4() is available in
 2326    * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
 2327    * not necessarily true that either is supported by the running kernel.
 2328    */
 2329   client_fd.fd = accept4 (listen_fd.fd, &addr, &addrlen, SOCK_CLOEXEC);
 2330   cloexec_done = client_fd.fd >= 0;
 2331 
 2332   if (client_fd.fd < 0 && (errno == ENOSYS || errno == EINVAL))
 2333 #endif
 2334     {
 2335       client_fd.fd = accept (listen_fd.fd, &addr, &addrlen);
 2336     }
 2337 
 2338   if (client_fd.fd < 0)
 2339     {
 2340       if (errno == EINTR)
 2341         goto retry;
 2342     }
 2343 
 2344   _dbus_verbose ("client fd %d accepted\n", client_fd.fd);
 2345 
 2346 #ifdef HAVE_ACCEPT4
 2347   if (!cloexec_done)
 2348 #endif
 2349     {
 2350       _dbus_fd_set_close_on_exec(client_fd.fd);
 2351     }
 2352 
 2353   return client_fd;
 2354 }
 2355 
 2356 /**
 2357  * Checks to make sure the given directory is
 2358  * private to the user
 2359  *
 2360  * @param dir the name of the directory
 2361  * @param error error return
 2362  * @returns #FALSE on failure
 2363  **/
 2364 dbus_bool_t
 2365 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
 2366 {
 2367   const char *directory;
 2368   struct stat sb;
 2369 
 2370   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 2371 
 2372   directory = _dbus_string_get_const_data (dir);
 2373 
 2374   if (stat (directory, &sb) < 0)
 2375     {
 2376       dbus_set_error (error, _dbus_error_from_errno (errno),
 2377                       "%s", _dbus_strerror (errno));
 2378 
 2379       return FALSE;
 2380     }
 2381 
 2382   if (sb.st_uid != geteuid ())
 2383     {
 2384       dbus_set_error (error, DBUS_ERROR_FAILED,
 2385                      "%s directory is owned by user %lu, not %lu",
 2386                      directory,
 2387                      (unsigned long) sb.st_uid,
 2388                      (unsigned long) geteuid ());
 2389       return FALSE;
 2390     }
 2391 
 2392   if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
 2393       (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
 2394     {
 2395       dbus_set_error (error, DBUS_ERROR_FAILED,
 2396                      "%s directory is not private to the user", directory);
 2397       return FALSE;
 2398     }
 2399 
 2400   return TRUE;
 2401 }
 2402 
 2403 static dbus_bool_t
 2404 fill_user_info_from_passwd (struct passwd *p,
 2405                             DBusUserInfo  *info,
 2406                             DBusError     *error)
 2407 {
 2408   _dbus_assert (p->pw_name != NULL);
 2409   _dbus_assert (p->pw_dir != NULL);
 2410 
 2411   info->uid = p->pw_uid;
 2412   info->primary_gid = p->pw_gid;
 2413   info->username = _dbus_strdup (p->pw_name);
 2414   info->homedir = _dbus_strdup (p->pw_dir);
 2415 
 2416   if (info->username == NULL ||
 2417       info->homedir == NULL)
 2418     {
 2419       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
 2420       return FALSE;
 2421     }
 2422 
 2423   return TRUE;
 2424 }
 2425 
 2426 static dbus_bool_t
 2427 fill_user_info (DBusUserInfo       *info,
 2428                 dbus_uid_t          uid,
 2429                 const DBusString   *username,
 2430                 DBusError          *error)
 2431 {
 2432   const char *username_c;
 2433 
 2434   /* exactly one of username/uid provided */
 2435   _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
 2436   _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
 2437 
 2438   info->uid = DBUS_UID_UNSET;
 2439   info->primary_gid = DBUS_GID_UNSET;
 2440   info->group_ids = NULL;
 2441   info->n_group_ids = 0;
 2442   info->username = NULL;
 2443   info->homedir = NULL;
 2444 
 2445   if (username != NULL)
 2446     username_c = _dbus_string_get_const_data (username);
 2447   else
 2448     username_c = NULL;
 2449 
 2450   /* For now assuming that the getpwnam() and getpwuid() flavors
 2451    * are always symmetrical, if not we have to add more configure
 2452    * checks
 2453    */
 2454 
 2455 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
 2456   {
 2457     struct passwd *p;
 2458     int result;
 2459     size_t buflen;
 2460     char *buf;
 2461     struct passwd p_str;
 2462 
 2463     /* retrieve maximum needed size for buf */
 2464     buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
 2465 
 2466     /* sysconf actually returns a long, but everything else expects size_t,
 2467      * so just recast here.
 2468      * https://bugs.freedesktop.org/show_bug.cgi?id=17061
 2469      */
 2470     if ((long) buflen <= 0)
 2471       buflen = 1024;
 2472 
 2473     result = -1;
 2474     while (1)
 2475       {
 2476         buf = dbus_malloc (buflen);
 2477         if (buf == NULL)
 2478           {
 2479             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
 2480             return FALSE;
 2481           }
 2482 
 2483         p = NULL;
 2484 #ifdef HAVE_POSIX_GETPWNAM_R
 2485         if (uid != DBUS_UID_UNSET)
 2486           result = getpwuid_r (uid, &p_str, buf, buflen,
 2487                                &p);
 2488         else
 2489           result = getpwnam_r (username_c, &p_str, buf, buflen,
 2490                                &p);
 2491 #else
 2492         if (uid != DBUS_UID_UNSET)
 2493           p = getpwuid_r (uid, &p_str, buf, buflen);
 2494         else
 2495           p = getpwnam_r (username_c, &p_str, buf, buflen);
 2496         result = 0;
 2497 #endif /* !HAVE_POSIX_GETPWNAM_R */
 2498         //Try a bigger buffer if ERANGE was returned
 2499         if (result == ERANGE && buflen < 512 * 1024)
 2500           {
 2501             dbus_free (buf);
 2502             buflen *= 2;
 2503           }
 2504         else
 2505           {
 2506             break;
 2507           }
 2508       }
 2509     if (result == 0 && p == &p_str)
 2510       {
 2511         if (!fill_user_info_from_passwd (p, info, error))
 2512           {
 2513             dbus_free (buf);
 2514             return FALSE;
 2515           }
 2516         dbus_free (buf);
 2517       }
 2518     else
 2519       {
 2520         dbus_set_error (error, _dbus_error_from_errno (errno),
 2521                         "User \"%s\" unknown or no memory to allocate password entry\n",
 2522                         username_c ? username_c : "???");
 2523         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
 2524         dbus_free (buf);
 2525         return FALSE;
 2526       }
 2527   }
 2528 #else /* ! HAVE_GETPWNAM_R */
 2529   {
 2530     /* I guess we're screwed on thread safety here */
 2531     struct passwd *p;
 2532 
 2533     if (uid != DBUS_UID_UNSET)
 2534       p = getpwuid (uid);
 2535     else
 2536       p = getpwnam (username_c);
 2537 
 2538     if (p != NULL)
 2539       {
 2540         if (!fill_user_info_from_passwd (p, info, error))
 2541           {
 2542             return FALSE;
 2543           }
 2544       }
 2545     else
 2546       {
 2547         dbus_set_error (error, _dbus_error_from_errno (errno),
 2548                         "User \"%s\" unknown or no memory to allocate password entry\n",
 2549                         username_c ? username_c : "???");
 2550         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
 2551         return FALSE;
 2552       }
 2553   }
 2554 #endif  /* ! HAVE_GETPWNAM_R */
 2555 
 2556   /* Fill this in so we can use it to get groups */
 2557   username_c = info->username;
 2558 
 2559 #ifdef HAVE_GETGROUPLIST
 2560   {
 2561     gid_t *buf;
 2562     int buf_count;
 2563     int i;
 2564     int initial_buf_count;
 2565 
 2566     initial_buf_count = 17;
 2567     buf_count = initial_buf_count;
 2568     buf = dbus_new (gid_t, buf_count);
 2569     if (buf == NULL)
 2570       {
 2571         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
 2572         goto failed;
 2573       }
 2574 
 2575     if (getgrouplist (username_c,
 2576                       info->primary_gid,
 2577                       buf, &buf_count) < 0)
 2578       {
 2579         gid_t *new;
 2580         /* Presumed cause of negative return code: buf has insufficient
 2581            entries to hold the entire group list. The Linux behavior in this
 2582            case is to pass back the actual number of groups in buf_count, but
 2583            on Mac OS X 10.5, buf_count is unhelpfully left alone.
 2584            So as a hack, try to help out a bit by guessing a larger
 2585            number of groups, within reason.. might still fail, of course,
 2586            but we can at least print a more informative message.  I looked up
 2587            the "right way" to do this by downloading Apple's own source code
 2588            for the "id" command, and it turns out that they use an
 2589            undocumented library function getgrouplist_2 (!) which is not
 2590            declared in any header in /usr/include (!!). That did not seem
 2591            like the way to go here.
 2592         */
 2593         if (buf_count == initial_buf_count)
 2594           {
 2595             buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
 2596           }
 2597         new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
 2598         if (new == NULL)
 2599           {
 2600             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
 2601             dbus_free (buf);
 2602             goto failed;
 2603           }
 2604 
 2605         buf = new;
 2606 
 2607         errno = 0;
 2608         if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
 2609           {
 2610             if (errno == 0)
 2611               {
 2612                 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
 2613                             username_c, buf_count, buf_count);
 2614               }
 2615             else
 2616               {
 2617                 dbus_set_error (error,
 2618                                 _dbus_error_from_errno (errno),
 2619                                 "Failed to get groups for username \"%s\" primary GID "
 2620                                 DBUS_GID_FORMAT ": %s\n",
 2621                                 username_c, info->primary_gid,
 2622                                 _dbus_strerror (errno));
 2623                 dbus_free (buf);
 2624                 goto failed;
 2625               }
 2626           }
 2627       }
 2628 
 2629     info->group_ids = dbus_new (dbus_gid_t, buf_count);
 2630     if (info->group_ids == NULL)
 2631       {
 2632         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
 2633         dbus_free (buf);
 2634         goto failed;
 2635       }
 2636 
 2637     for (i = 0; i < buf_count; ++i)
 2638       info->group_ids[i] = buf[i];
 2639 
 2640     info->n_group_ids = buf_count;
 2641 
 2642     dbus_free (buf);
 2643   }
 2644 #else  /* HAVE_GETGROUPLIST */
 2645   {
 2646     /* We just get the one group ID */
 2647     info->group_ids = dbus_new (dbus_gid_t, 1);
 2648     if (info->group_ids == NULL)
 2649       {
 2650         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
 2651         goto failed;
 2652       }
 2653 
 2654     info->n_group_ids = 1;
 2655 
 2656     (info->group_ids)[0] = info->primary_gid;
 2657   }
 2658 #endif /* HAVE_GETGROUPLIST */
 2659 
 2660   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 2661 
 2662   return TRUE;
 2663 
 2664  failed:
 2665   _DBUS_ASSERT_ERROR_IS_SET (error);
 2666   return FALSE;
 2667 }
 2668 
 2669 /**
 2670  * Gets user info for the given username.
 2671  *
 2672  * @param info user info object to initialize
 2673  * @param username the username
 2674  * @param error error return
 2675  * @returns #TRUE on success
 2676  */
 2677 dbus_bool_t
 2678 _dbus_user_info_fill (DBusUserInfo     *info,
 2679                       const DBusString *username,
 2680                       DBusError        *error)
 2681 {
 2682   return fill_user_info (info, DBUS_UID_UNSET,
 2683                          username, error);
 2684 }
 2685 
 2686 /**
 2687  * Gets user info for the given user ID.
 2688  *
 2689  * @param info user info object to initialize
 2690  * @param uid the user ID
 2691  * @param error error return
 2692  * @returns #TRUE on success
 2693  */
 2694 dbus_bool_t
 2695 _dbus_user_info_fill_uid (DBusUserInfo *info,
 2696                           dbus_uid_t    uid,
 2697                           DBusError    *error)
 2698 {
 2699   return fill_user_info (info, uid,
 2700                          NULL, error);
 2701 }
 2702 
 2703 /**
 2704  * Adds the credentials of the current process to the
 2705  * passed-in credentials object.
 2706  *
 2707  * @param credentials credentials to add to
 2708  * @returns #FALSE if no memory; does not properly roll back on failure, so only some credentials may have been added
 2709  */
 2710 dbus_bool_t
 2711 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
 2712 {
 2713   /* The POSIX spec certainly doesn't promise this, but
 2714    * we need these assertions to fail as soon as we're wrong about
 2715    * it so we can do the porting fixups
 2716    */
 2717   _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
 2718   _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
 2719   _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
 2720 
 2721   if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
 2722     return FALSE;
 2723   if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
 2724     return FALSE;
 2725 
 2726   return TRUE;
 2727 }
 2728 
 2729 /**
 2730  * Append to the string the identity we would like to have when we
 2731  * authenticate, on UNIX this is the current process UID and on
 2732  * Windows something else, probably a Windows SID string.  No escaping
 2733  * is required, that is done in dbus-auth.c. The username here
 2734  * need not be anything human-readable, it can be the machine-readable
 2735  * form i.e. a user id.
 2736  *
 2737  * @param str the string to append to
 2738  * @returns #FALSE on no memory
 2739  */
 2740 dbus_bool_t
 2741 _dbus_append_user_from_current_process (DBusString *str)
 2742 {
 2743   return _dbus_string_append_uint (str,
 2744                                    _dbus_geteuid ());
 2745 }
 2746 
 2747 /**
 2748  * Gets our process ID
 2749  * @returns process ID
 2750  */
 2751 dbus_pid_t
 2752 _dbus_getpid (void)
 2753 {
 2754   return getpid ();
 2755 }
 2756 
 2757 /** Gets our UID
 2758  * @returns process UID
 2759  */
 2760 dbus_uid_t
 2761 _dbus_getuid (void)
 2762 {
 2763   return getuid ();
 2764 }
 2765 
 2766 /** Gets our effective UID
 2767  * @returns process effective UID
 2768  */
 2769 dbus_uid_t
 2770 _dbus_geteuid (void)
 2771 {
 2772   return geteuid ();
 2773 }
 2774 
 2775 /**
 2776  * The only reason this is separate from _dbus_getpid() is to allow it
 2777  * on Windows for logging but not for other purposes.
 2778  *
 2779  * @returns process ID to put in log messages
 2780  */
 2781 unsigned long
 2782 _dbus_pid_for_log (void)
 2783 {
 2784   return getpid ();
 2785 }
 2786 
 2787 /**
 2788  * Gets a UID from a UID string.
 2789  *
 2790  * @param uid_str the UID in string form
 2791  * @param uid UID to fill in
 2792  * @returns #TRUE if successfully filled in UID
 2793  */
 2794 dbus_bool_t
 2795 _dbus_parse_uid (const DBusString      *uid_str,
 2796                  dbus_uid_t            *uid)
 2797 {
 2798   int end;
 2799   long val;
 2800 
 2801   if (_dbus_string_get_length (uid_str) == 0)
 2802     {
 2803       _dbus_verbose ("UID string was zero length\n");
 2804       return FALSE;
 2805     }
 2806 
 2807   val = -1;
 2808   end = 0;
 2809   if (!_dbus_string_parse_int (uid_str, 0, &val,
 2810                                &end))
 2811     {
 2812       _dbus_verbose ("could not parse string as a UID\n");
 2813       return FALSE;
 2814     }
 2815 
 2816   if (end != _dbus_string_get_length (uid_str))
 2817     {
 2818       _dbus_verbose ("string contained trailing stuff after UID\n");
 2819       return FALSE;
 2820     }
 2821 
 2822   *uid = val;
 2823 
 2824   return TRUE;
 2825 }
 2826 
 2827 #if !DBUS_USE_SYNC
 2828 /* To be thread-safe by default on platforms that don't necessarily have
 2829  * atomic operations (notably Debian armel, which is armv4t), we must
 2830  * use a mutex that can be initialized statically, like this.
 2831  * GLib >= 2.32 uses a similar system.
 2832  */
 2833 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
 2834 #endif
 2835 
 2836 /**
 2837  * Atomically increments an integer
 2838  *
 2839  * @param atomic pointer to the integer to increment
 2840  * @returns the value before incrementing
 2841  */
 2842 dbus_int32_t
 2843 _dbus_atomic_inc (DBusAtomic *atomic)
 2844 {
 2845 #if DBUS_USE_SYNC
 2846   return __sync_add_and_fetch(&atomic->value, 1)-1;
 2847 #else
 2848   dbus_int32_t res;
 2849 
 2850   pthread_mutex_lock (&atomic_mutex);
 2851   res = atomic->value;
 2852   atomic->value += 1;
 2853   pthread_mutex_unlock (&atomic_mutex);
 2854 
 2855   return res;
 2856 #endif
 2857 }
 2858 
 2859 /**
 2860  * Atomically decrement an integer
 2861  *
 2862  * @param atomic pointer to the integer to decrement
 2863  * @returns the value before decrementing
 2864  */
 2865 dbus_int32_t
 2866 _dbus_atomic_dec (DBusAtomic *atomic)
 2867 {
 2868 #if DBUS_USE_SYNC
 2869   return __sync_sub_and_fetch(&atomic->value, 1)+1;
 2870 #else
 2871   dbus_int32_t res;
 2872 
 2873   pthread_mutex_lock (&atomic_mutex);
 2874   res = atomic->value;
 2875   atomic->value -= 1;
 2876   pthread_mutex_unlock (&atomic_mutex);
 2877 
 2878   return res;
 2879 #endif
 2880 }
 2881 
 2882 /**
 2883  * Atomically get the value of an integer. It may change at any time
 2884  * thereafter, so this is mostly only useful for assertions.
 2885  *
 2886  * @param atomic pointer to the integer to get
 2887  * @returns the value at this moment
 2888  */
 2889 dbus_int32_t
 2890 _dbus_atomic_get (DBusAtomic *atomic)
 2891 {
 2892 #if DBUS_USE_SYNC
 2893   __sync_synchronize ();
 2894   return atomic->value;
 2895 #else
 2896   dbus_int32_t res;
 2897 
 2898   pthread_mutex_lock (&atomic_mutex);
 2899   res = atomic->value;
 2900   pthread_mutex_unlock (&atomic_mutex);
 2901 
 2902   return res;
 2903 #endif
 2904 }
 2905 
 2906 /**
 2907  * Wrapper for poll().
 2908  *
 2909  * @param fds the file descriptors to poll
 2910  * @param n_fds number of descriptors in the array
 2911  * @param timeout_milliseconds timeout or -1 for infinite
 2912  * @returns numbers of fds with revents, or <0 on error
 2913  */
 2914 int
 2915 _dbus_poll (DBusPollFD *fds,
 2916             int         n_fds,
 2917             int         timeout_milliseconds)
 2918 {
 2919 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
 2920   /* DBusPollFD is a struct pollfd in this code path, so we can just poll() */
 2921   if (timeout_milliseconds < -1)
 2922     {
 2923       timeout_milliseconds = -1;
 2924     }
 2925 
 2926   return poll (fds,
 2927                n_fds,
 2928                timeout_milliseconds);
 2929 #else /* ! HAVE_POLL */
 2930   /* Emulate poll() in terms of select() */
 2931   fd_set read_set, write_set, err_set;
 2932   int max_fd = 0;
 2933   int i;
 2934   struct timeval tv;
 2935   int ready;
 2936 
 2937   FD_ZERO (&read_set);
 2938   FD_ZERO (&write_set);
 2939   FD_ZERO (&err_set);
 2940 
 2941   for (i = 0; i < n_fds; i++)
 2942     {
 2943       DBusPollFD *fdp = &fds[i];
 2944 
 2945       if (fdp->events & _DBUS_POLLIN)
 2946     FD_SET (fdp->fd, &read_set);
 2947 
 2948       if (fdp->events & _DBUS_POLLOUT)
 2949     FD_SET (fdp->fd, &write_set);
 2950 
 2951       FD_SET (fdp->fd, &err_set);
 2952 
 2953       max_fd = MAX (max_fd, fdp->fd);
 2954     }
 2955 
 2956   tv.tv_sec = timeout_milliseconds / 1000;
 2957   tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
 2958 
 2959   ready = select (max_fd + 1, &read_set, &write_set, &err_set,
 2960                   timeout_milliseconds < 0 ? NULL : &tv);
 2961 
 2962   if (ready > 0)
 2963     {
 2964       for (i = 0; i < n_fds; i++)
 2965     {
 2966       DBusPollFD *fdp = &fds[i];
 2967 
 2968       fdp->revents = 0;
 2969 
 2970       if (FD_ISSET (fdp->fd, &read_set))
 2971         fdp->revents |= _DBUS_POLLIN;
 2972 
 2973       if (FD_ISSET (fdp->fd, &write_set))
 2974         fdp->revents |= _DBUS_POLLOUT;
 2975 
 2976       if (FD_ISSET (fdp->fd, &err_set))
 2977         fdp->revents |= _DBUS_POLLERR;
 2978     }
 2979     }
 2980 
 2981   return ready;
 2982 #endif
 2983 }
 2984 
 2985 /**
 2986  * Get current time, as in gettimeofday(). Use the monotonic clock if
 2987  * available, to avoid problems when the system time changes.
 2988  *
 2989  * @param tv_sec return location for number of seconds
 2990  * @param tv_usec return location for number of microseconds
 2991  */
 2992 void
 2993 _dbus_get_monotonic_time (long *tv_sec,
 2994                           long *tv_usec)
 2995 {
 2996 #ifdef HAVE_MONOTONIC_CLOCK
 2997   struct timespec ts;
 2998   clock_gettime (CLOCK_MONOTONIC, &ts);
 2999 
 3000   if (tv_sec)
 3001     *tv_sec = ts.tv_sec;
 3002   if (tv_usec)
 3003     *tv_usec = ts.tv_nsec / 1000;
 3004 #else
 3005   struct timeval t;
 3006 
 3007   gettimeofday (&t, NULL);
 3008 
 3009   if (tv_sec)
 3010     *tv_sec = t.tv_sec;
 3011   if (tv_usec)
 3012     *tv_usec = t.tv_usec;
 3013 #endif
 3014 }
 3015 
 3016 /**
 3017  * Get current time, as in gettimeofday(). Never uses the monotonic
 3018  * clock.
 3019  *
 3020  * @param tv_sec return location for number of seconds
 3021  * @param tv_usec return location for number of microseconds
 3022  */
 3023 void
 3024 _dbus_get_real_time (long *tv_sec,
 3025                      long *tv_usec)
 3026 {
 3027   struct timeval t;
 3028 
 3029   gettimeofday (&t, NULL);
 3030 
 3031   if (tv_sec)
 3032     *tv_sec = t.tv_sec;
 3033   if (tv_usec)
 3034     *tv_usec = t.tv_usec;
 3035 }
 3036 
 3037 /**
 3038  * Creates a directory; succeeds if the directory
 3039  * is created or already existed.
 3040  *
 3041  * @param filename directory filename
 3042  * @param error initialized error object
 3043  * @returns #TRUE on success
 3044  */
 3045 dbus_bool_t
 3046 _dbus_ensure_directory (const DBusString *filename,
 3047                         DBusError        *error)
 3048 {
 3049   const char *filename_c;
 3050 
 3051   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 3052 
 3053   filename_c = _dbus_string_get_const_data (filename);
 3054 
 3055   if (mkdir (filename_c, 0700) < 0)
 3056     {
 3057       if (errno == EEXIST)
 3058         return TRUE;
 3059 
 3060       dbus_set_error (error, DBUS_ERROR_FAILED,
 3061                       "Failed to create directory %s: %s\n",
 3062                       filename_c, _dbus_strerror (errno));
 3063       return FALSE;
 3064     }
 3065   else
 3066     return TRUE;
 3067 }
 3068 
 3069 /**
 3070  * Creates a directory. Unlike _dbus_ensure_directory(), this only succeeds
 3071  * if the directory is genuinely newly-created.
 3072  *
 3073  * @param filename directory filename
 3074  * @param error initialized error object
 3075  * @returns #TRUE on success
 3076  */
 3077 dbus_bool_t
 3078 _dbus_create_directory (const DBusString *filename,
 3079                         DBusError        *error)
 3080 {
 3081   const char *filename_c;
 3082 
 3083   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 3084 
 3085   filename_c = _dbus_string_get_const_data (filename);
 3086 
 3087   if (mkdir (filename_c, 0700) < 0)
 3088     {
 3089       dbus_set_error (error, DBUS_ERROR_FAILED,
 3090                       "Failed to create directory %s: %s\n",
 3091                       filename_c, _dbus_strerror (errno));
 3092       return FALSE;
 3093     }
 3094   else
 3095     return TRUE;
 3096 }
 3097 
 3098 /**
 3099  * Appends the given filename to the given directory.
 3100  *
 3101  * @todo it might be cute to collapse multiple '/' such as "foo//"
 3102  * concat "//bar"
 3103  *
 3104  * @param dir the directory name
 3105  * @param next_component the filename
 3106  * @returns #TRUE on success
 3107  */
 3108 dbus_bool_t
 3109 _dbus_concat_dir_and_file (DBusString       *dir,
 3110                            const DBusString *next_component)
 3111 {
 3112   dbus_bool_t dir_ends_in_slash;
 3113   dbus_bool_t file_starts_with_slash;
 3114 
 3115   if (_dbus_string_get_length (dir) == 0 ||
 3116       _dbus_string_get_length (next_component) == 0)
 3117     return TRUE;
 3118 
 3119   dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
 3120                                                     _dbus_string_get_length (dir) - 1);
 3121 
 3122   file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
 3123 
 3124   if (dir_ends_in_slash && file_starts_with_slash)
 3125     {
 3126       _dbus_string_shorten (dir, 1);
 3127     }
 3128   else if (!(dir_ends_in_slash || file_starts_with_slash))
 3129     {
 3130       if (!_dbus_string_append_byte (dir, '/'))
 3131         return FALSE;
 3132     }
 3133 
 3134   return _dbus_string_copy (next_component, 0, dir,
 3135                             _dbus_string_get_length (dir));
 3136 }
 3137 
 3138 /** nanoseconds in a second */
 3139 #define NANOSECONDS_PER_SECOND       1000000000
 3140 /** microseconds in a second */
 3141 #define MICROSECONDS_PER_SECOND      1000000
 3142 /** milliseconds in a second */
 3143 #define MILLISECONDS_PER_SECOND      1000
 3144 /** nanoseconds in a millisecond */
 3145 #define NANOSECONDS_PER_MILLISECOND  1000000
 3146 /** microseconds in a millisecond */
 3147 #define MICROSECONDS_PER_MILLISECOND 1000
 3148 
 3149 /**
 3150  * Sleeps the given number of milliseconds.
 3151  * @param milliseconds number of milliseconds
 3152  */
 3153 void
 3154 _dbus_sleep_milliseconds (int milliseconds)
 3155 {
 3156 #ifdef HAVE_NANOSLEEP
 3157   struct timespec req;
 3158   struct timespec rem;
 3159 
 3160   req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
 3161   req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
 3162   rem.tv_sec = 0;
 3163   rem.tv_nsec = 0;
 3164 
 3165   while (nanosleep (&req, &rem) < 0 && errno == EINTR)
 3166     req = rem;
 3167 #elif defined (HAVE_USLEEP)
 3168   usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
 3169 #else /* ! HAVE_USLEEP */
 3170   sleep (MAX (milliseconds / 1000, 1));
 3171 #endif
 3172 }
 3173 
 3174 /**
 3175  * Generates the given number of securely random bytes,
 3176  * using the best mechanism we can come up with.
 3177  *
 3178  * @param str the string
 3179  * @param n_bytes the number of random bytes to append to string
 3180  * @param error location to store reason for failure
 3181  * @returns #TRUE on success, #FALSE on error
 3182  */
 3183 dbus_bool_t
 3184 _dbus_generate_random_bytes (DBusString *str,
 3185                              int         n_bytes,
 3186                              DBusError  *error)
 3187 {
 3188   int old_len;
 3189   int fd;
 3190   int result;
 3191 
 3192   old_len = _dbus_string_get_length (str);
 3193   fd = -1;
 3194 
 3195   /* note, urandom on linux will fall back to pseudorandom */
 3196   fd = open ("/dev/urandom", O_RDONLY);
 3197 
 3198   if (fd < 0)
 3199     {
 3200       dbus_set_error (error, _dbus_error_from_errno (errno),
 3201                       "Could not open /dev/urandom: %s",
 3202                       _dbus_strerror (errno));
 3203       return FALSE;
 3204     }
 3205 
 3206   _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
 3207 
 3208   result = _dbus_read (fd, str, n_bytes);
 3209 
 3210   if (result != n_bytes)
 3211     {
 3212       if (result < 0)
 3213         dbus_set_error (error, _dbus_error_from_errno (errno),
 3214                         "Could not read /dev/urandom: %s",
 3215                         _dbus_strerror (errno));
 3216       else
 3217         dbus_set_error (error, DBUS_ERROR_IO_ERROR,
 3218                         "Short read from /dev/urandom");
 3219 
 3220       _dbus_close (fd, NULL);
 3221       _dbus_string_set_length (str, old_len);
 3222       return FALSE;
 3223     }
 3224 
 3225   _dbus_verbose ("Read %d bytes from /dev/urandom\n",
 3226                  n_bytes);
 3227 
 3228   _dbus_close (fd, NULL);
 3229 
 3230   return TRUE;
 3231 }
 3232 
 3233 /**
 3234  * Exit the process, returning the given value.
 3235  *
 3236  * @param code the exit code
 3237  */
 3238 void
 3239 _dbus_exit (int code)
 3240 {
 3241   _exit (code);
 3242 }
 3243 
 3244 /**
 3245  * A wrapper around strerror() because some platforms
 3246  * may be lame and not have strerror(). Also, never
 3247  * returns NULL.
 3248  *
 3249  * @param error_number errno.
 3250  * @returns error description.
 3251  */
 3252 const char*
 3253 _dbus_strerror (int error_number)
 3254 {
 3255   const char *msg;
 3256 
 3257   msg = strerror (error_number);
 3258   if (msg == NULL)
 3259     msg = "unknown";
 3260 
 3261   return msg;
 3262 }
 3263 
 3264 /**
 3265  * signal (SIGPIPE, SIG_IGN);
 3266  */
 3267 void
 3268 _dbus_disable_sigpipe (void)
 3269 {
 3270   signal (SIGPIPE, SIG_IGN);
 3271 }
 3272 
 3273 /**
 3274  * Sets the file descriptor to be close
 3275  * on exec. Should be called for all file
 3276  * descriptors in D-Bus code.
 3277  *
 3278  * @param fd the file descriptor
 3279  */
 3280 void
 3281 _dbus_fd_set_close_on_exec (int fd)
 3282 {
 3283   int val;
 3284 
 3285   val = fcntl (fd, F_GETFD, 0);
 3286 
 3287   if (val < 0)
 3288     return;
 3289 
 3290   val |= FD_CLOEXEC;
 3291 
 3292   fcntl (fd, F_SETFD, val);
 3293 }
 3294 
 3295 /**
 3296  * Closes a file descriptor.
 3297  *
 3298  * @param fd the file descriptor
 3299  * @param error error object
 3300  * @returns #FALSE if error set
 3301  */
 3302 dbus_bool_t
 3303 _dbus_close (int        fd,
 3304              DBusError *error)
 3305 {
 3306   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 3307 
 3308  again:
 3309   if (close (fd) < 0)
 3310     {
 3311       if (errno == EINTR)
 3312         goto again;
 3313 
 3314       dbus_set_error (error, _dbus_error_from_errno (errno),
 3315                       "Could not close fd %d", fd);
 3316       return FALSE;
 3317     }
 3318 
 3319   return TRUE;
 3320 }
 3321 
 3322 /**
 3323  * Duplicates a file descriptor. Makes sure the fd returned is >= 3
 3324  * (i.e. avoids stdin/stdout/stderr). Sets O_CLOEXEC.
 3325  *
 3326  * @param fd the file descriptor to duplicate
 3327  * @param error address of error location.
 3328  * @returns duplicated file descriptor
 3329  * */
 3330 int
 3331 _dbus_dup(int        fd,
 3332           DBusError *error)
 3333 {
 3334   int new_fd;
 3335 
 3336 #ifdef F_DUPFD_CLOEXEC
 3337   dbus_bool_t cloexec_done;
 3338 
 3339   new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
 3340   cloexec_done = new_fd >= 0;
 3341 
 3342   if (new_fd < 0 && errno == EINVAL)
 3343 #endif
 3344     {
 3345       new_fd = fcntl(fd, F_DUPFD, 3);
 3346     }
 3347 
 3348   if (new_fd < 0) {
 3349 
 3350     dbus_set_error (error, _dbus_error_from_errno (errno),
 3351                     "Could not duplicate fd %d", fd);
 3352     return -1;
 3353   }
 3354 
 3355 #ifdef F_DUPFD_CLOEXEC
 3356   if (!cloexec_done)
 3357 #endif
 3358     {
 3359       _dbus_fd_set_close_on_exec(new_fd);
 3360     }
 3361 
 3362   return new_fd;
 3363 }
 3364 
 3365 /**
 3366  * Sets a file descriptor to be nonblocking.
 3367  *
 3368  * @param fd the file descriptor.
 3369  * @param error address of error location.
 3370  * @returns #TRUE on success.
 3371  */
 3372 dbus_bool_t
 3373 _dbus_set_socket_nonblocking (DBusSocket      fd,
 3374                               DBusError      *error)
 3375 {
 3376   return _dbus_set_fd_nonblocking (fd.fd, error);
 3377 }
 3378 
 3379 static dbus_bool_t
 3380 _dbus_set_fd_nonblocking (int             fd,
 3381                           DBusError      *error)
 3382 {
 3383   int val;
 3384 
 3385   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 3386 
 3387   val = fcntl (fd, F_GETFL, 0);
 3388   if (val < 0)
 3389     {
 3390       dbus_set_error (error, _dbus_error_from_errno (errno),
 3391                       "Failed to get flags from file descriptor %d: %s",
 3392                       fd, _dbus_strerror (errno));
 3393       _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
 3394                      _dbus_strerror (errno));
 3395       return FALSE;
 3396     }
 3397 
 3398   if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
 3399     {
 3400       dbus_set_error (error, _dbus_error_from_errno (errno),
 3401                       "Failed to set nonblocking flag of file descriptor %d: %s",
 3402                       fd, _dbus_strerror (errno));
 3403       _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
 3404                      fd, _dbus_strerror (errno));
 3405 
 3406       return FALSE;
 3407     }
 3408 
 3409   return TRUE;
 3410 }
 3411 
 3412 /**
 3413  * On GNU libc systems, print a crude backtrace to stderr.  On other
 3414  * systems, print "no backtrace support" and block for possible gdb
 3415  * attachment if an appropriate environment variable is set.
 3416  */
 3417 void
 3418 _dbus_print_backtrace (void)
 3419 {
 3420 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
 3421   void *bt[500];
 3422   int bt_size;
 3423   int i;
 3424   char **syms;
 3425 
 3426   bt_size = backtrace (bt, 500);
 3427 
 3428   syms = backtrace_symbols (bt, bt_size);
 3429 
 3430   i = 0;
 3431   while (i < bt_size)
 3432     {
 3433       /* don't use dbus_warn since it can _dbus_abort() */
 3434       fprintf (stderr, "  %s\n", syms[i]);
 3435       ++i;
 3436     }
 3437   fflush (stderr);
 3438 
 3439   free (syms);
 3440 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
 3441   fprintf (stderr, "  D-Bus not built with -rdynamic so unable to print a backtrace\n");
 3442 #else
 3443   fprintf (stderr, "  D-Bus not compiled with backtrace support so unable to print a backtrace\n");
 3444 #endif
 3445 }
 3446 
 3447 /**
 3448  * Creates pair of connect sockets (as in socketpair()).
 3449  * Sets both ends of the pair nonblocking.
 3450  *
 3451  * Marks both file descriptors as close-on-exec
 3452  *
 3453  * @param fd1 return location for one end
 3454  * @param fd2 return location for the other end
 3455  * @param blocking #TRUE if pair should be blocking
 3456  * @param error error return
 3457  * @returns #FALSE on failure (if error is set)
 3458  */
 3459 dbus_bool_t
 3460 _dbus_socketpair (DBusSocket *fd1,
 3461                   DBusSocket *fd2,
 3462                   dbus_bool_t blocking,
 3463                   DBusError  *error)
 3464 {
 3465 #ifdef HAVE_SOCKETPAIR
 3466   int fds[2];
 3467   int retval;
 3468 
 3469 #ifdef SOCK_CLOEXEC
 3470   dbus_bool_t cloexec_done;
 3471 
 3472   retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
 3473   cloexec_done = retval >= 0;
 3474 
 3475   if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
 3476 #endif
 3477     {
 3478       retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
 3479     }
 3480 
 3481   if (retval < 0)
 3482     {
 3483       dbus_set_error (error, _dbus_error_from_errno (errno),
 3484                       "Could not create full-duplex pipe");
 3485       return FALSE;
 3486     }
 3487 
 3488   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 3489 
 3490 #ifdef SOCK_CLOEXEC
 3491   if (!cloexec_done)
 3492 #endif
 3493     {
 3494       _dbus_fd_set_close_on_exec (fds[0]);
 3495       _dbus_fd_set_close_on_exec (fds[1]);
 3496     }
 3497 
 3498   if (!blocking &&
 3499       (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
 3500        !_dbus_set_fd_nonblocking (fds[1], NULL)))
 3501     {
 3502       dbus_set_error (error, _dbus_error_from_errno (errno),
 3503                       "Could not set full-duplex pipe nonblocking");
 3504 
 3505       _dbus_close (fds[0], NULL);
 3506       _dbus_close (fds[1], NULL);
 3507 
 3508       return FALSE;
 3509     }
 3510 
 3511   fd1->fd = fds[0];
 3512   fd2->fd = fds[1];
 3513 
 3514   _dbus_verbose ("full-duplex pipe %d <-> %d\n",
 3515                  fd1->fd, fd2->fd);
 3516 
 3517   return TRUE;
 3518 #else
 3519   _dbus_warn ("_dbus_socketpair() not implemented on this OS");
 3520   dbus_set_error (error, DBUS_ERROR_FAILED,
 3521                   "_dbus_socketpair() not implemented on this OS");
 3522   return FALSE;
 3523 #endif
 3524 }
 3525 
 3526 /**
 3527  * Measure the length of the given format string and arguments,
 3528  * not including the terminating nul.
 3529  *
 3530  * @param format a printf-style format string
 3531  * @param args arguments for the format string
 3532  * @returns length of the given format string and args, or -1 if no memory
 3533  */
 3534 int
 3535 _dbus_printf_string_upper_bound (const char *format,
 3536                                  va_list     args)
 3537 {
 3538   char static_buf[1024];
 3539   int bufsize = sizeof (static_buf);
 3540   int len;
 3541   va_list args_copy;
 3542 
 3543   DBUS_VA_COPY (args_copy, args);
 3544   len = vsnprintf (static_buf, bufsize, format, args_copy);
 3545   va_end (args_copy);
 3546 
 3547   /* If vsnprintf() returned non-negative, then either the string fits in
 3548    * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
 3549    * returns the number of characters that were needed, or this OS returns the
 3550    * truncated length.
 3551    *
 3552    * We ignore the possibility that snprintf might just ignore the length and
 3553    * overrun the buffer (64-bit Solaris 7), because that's pathological.
 3554    * If your libc is really that bad, come back when you have a better one. */
 3555   if (len == bufsize)
 3556     {
 3557       /* This could be the truncated length (Tru64 and IRIX have this bug),
 3558        * or the real length could be coincidentally the same. Which is it?
 3559        * If vsnprintf returns the truncated length, we'll go to the slow
 3560        * path. */
 3561       DBUS_VA_COPY (args_copy, args);
 3562 
 3563       if (vsnprintf (static_buf, 1, format, args_copy) == 1)
 3564         len = -1;
 3565 
 3566       va_end (args_copy);
 3567     }
 3568 
 3569   /* If vsnprintf() returned negative, we have to do more work.
 3570    * HP-UX returns negative. */
 3571   while (len < 0)
 3572     {
 3573       char *buf;
 3574 
 3575       bufsize *= 2;
 3576 
 3577       buf = dbus_malloc (bufsize);
 3578 
 3579       if (buf == NULL)
 3580         return -1;
 3581 
 3582       DBUS_VA_COPY (args_copy, args);
 3583       len = vsnprintf (buf, bufsize, format, args_copy);
 3584       va_end (args_copy);
 3585 
 3586       dbus_free (buf);
 3587 
 3588       /* If the reported length is exactly the buffer size, round up to the
 3589        * next size, in case vsnprintf has been returning the truncated
 3590        * length */
 3591       if (len == bufsize)
 3592         len = -1;
 3593     }
 3594 
 3595   return len;
 3596 }
 3597 
 3598 /**
 3599  * Gets the temporary files directory by inspecting the environment variables
 3600  * TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned
 3601  *
 3602  * @returns location of temp directory, or #NULL if no memory for locking
 3603  */
 3604 const char*
 3605 _dbus_get_tmpdir(void)
 3606 {
 3607   /* Protected by _DBUS_LOCK_sysdeps */
 3608   static const char* tmpdir = NULL;
 3609 
 3610   if (!_DBUS_LOCK (sysdeps))
 3611     return NULL;
 3612 
 3613   if (tmpdir == NULL)
 3614     {
 3615       /* TMPDIR is what glibc uses, then
 3616        * glibc falls back to the P_tmpdir macro which
 3617        * just expands to "/tmp"
 3618        */
 3619       if (tmpdir == NULL)
 3620         tmpdir = getenv("TMPDIR");
 3621 
 3622       /* These two env variables are probably
 3623        * broken, but maybe some OS uses them?
 3624        */
 3625       if (tmpdir == NULL)
 3626         tmpdir = getenv("TMP");
 3627       if (tmpdir == NULL)
 3628         tmpdir = getenv("TEMP");
 3629 
 3630       /* And this is the sane fallback. */
 3631       if (tmpdir == NULL)
 3632         tmpdir = "/tmp";
 3633     }
 3634 
 3635   _DBUS_UNLOCK (sysdeps);
 3636 
 3637   _dbus_assert(tmpdir != NULL);
 3638 
 3639   return tmpdir;
 3640 }
 3641 
 3642 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
 3643 /**
 3644  * Execute a subprocess, returning up to 1024 bytes of output
 3645  * into @p result.
 3646  *
 3647  * If successful, returns #TRUE and appends the output to @p
 3648  * result. If a failure happens, returns #FALSE and
 3649  * sets an error in @p error.
 3650  *
 3651  * @note It's not an error if the subprocess terminates normally
 3652  * without writing any data to stdout. Verify the @p result length
 3653  * before and after this function call to cover this case.
 3654  *
 3655  * @param progname initial path to exec (may or may not be absolute)
 3656  * @param path_fallback if %TRUE, search PATH for executable
 3657  * @param argv NULL-terminated list of arguments
 3658  * @param result a DBusString where the output can be append
 3659  * @param error a DBusError to store the error in case of failure
 3660  * @returns #TRUE on success, #FALSE if an error happened
 3661  */
 3662 static dbus_bool_t
 3663 _read_subprocess_line_argv (const char *progpath,
 3664                             dbus_bool_t path_fallback,
 3665                             const char * const *argv,
 3666                             DBusString *result,
 3667                             DBusError  *error)
 3668 {
 3669   int result_pipe[2] = { -1, -1 };
 3670   int errors_pipe[2] = { -1, -1 };
 3671   pid_t pid;
 3672   int ret;
 3673   int status;
 3674   int orig_len;
 3675 
 3676   dbus_bool_t retval;
 3677   sigset_t new_set, old_set;
 3678 
 3679   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 3680   retval = FALSE;
 3681 
 3682   /* We need to block any existing handlers for SIGCHLD temporarily; they
 3683    * will cause waitpid() below to fail.
 3684    * https://bugs.freedesktop.org/show_bug.cgi?id=21347
 3685    */
 3686   sigemptyset (&new_set);
 3687   sigaddset (&new_set, SIGCHLD);
 3688   sigprocmask (SIG_BLOCK, &new_set, &old_set);
 3689 
 3690   orig_len = _dbus_string_get_length (result);
 3691 
 3692 #define READ_END        0
 3693 #define WRITE_END       1
 3694   if (pipe (result_pipe) < 0)
 3695     {
 3696       dbus_set_error (error, _dbus_error_from_errno (errno),
 3697                       "Failed to create a pipe to call %s: %s",
 3698                       progpath, _dbus_strerror (errno));
 3699       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
 3700                      progpath, _dbus_strerror (errno));
 3701       goto out;
 3702     }
 3703   if (pipe (errors_pipe) < 0)
 3704     {
 3705       dbus_set_error (error, _dbus_error_from_errno (errno),
 3706                       "Failed to create a pipe to call %s: %s",
 3707                       progpath, _dbus_strerror (errno));
 3708       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
 3709                      progpath, _dbus_strerror (errno));
 3710       goto out;
 3711     }
 3712 
 3713   pid = fork ();
 3714   if (pid < 0)
 3715     {
 3716       dbus_set_error (error, _dbus_error_from_errno (errno),
 3717                       "Failed to fork() to call %s: %s",
 3718                       progpath, _dbus_strerror (errno));
 3719       _dbus_verbose ("Failed to fork() to call %s: %s\n",
 3720                      progpath, _dbus_strerror (errno));
 3721       goto out;
 3722     }
 3723 
 3724   if (pid == 0)
 3725     {
 3726       /* child process */
 3727       const char *error_str;
 3728 
 3729       if (!_dbus_ensure_standard_fds (DBUS_FORCE_STDIN_NULL, &error_str))
 3730         {
 3731           int saved_errno = errno;
 3732 
 3733           /* Try to write details into the pipe, but don't bother
 3734            * trying too hard (no retry loop). */
 3735 
 3736           if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0 ||
 3737               write (errors_pipe[WRITE_END], ": ", 2) < 0)
 3738             {
 3739               /* ignore, not much we can do */
 3740             }
 3741 
 3742           error_str = _dbus_strerror (saved_errno);
 3743 
 3744           if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0)
 3745             {
 3746               /* ignore, not much we can do */
 3747             }
 3748 
 3749           _exit (1);
 3750         }
 3751 
 3752       /* set-up stdXXX */
 3753       close (result_pipe[READ_END]);
 3754       close (errors_pipe[READ_END]);
 3755 
 3756       if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
 3757         _exit (1);
 3758       if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
 3759         _exit (1);
 3760 
 3761       _dbus_close_all ();
 3762 
 3763       sigprocmask (SIG_SETMASK, &old_set, NULL);
 3764 
 3765       /* If it looks fully-qualified, try execv first */
 3766       if (progpath[0] == '/')
 3767         {
 3768           execv (progpath, (char * const *) argv);
 3769           /* Ok, that failed.  Now if path_fallback is given, let's
 3770            * try unqualified.  This is mostly a hack to work
 3771            * around systems which ship dbus-launch in /usr/bin
 3772            * but everything else in /bin (because dbus-launch
 3773            * depends on X11).
 3774            */
 3775           if (path_fallback)
 3776             /* We must have a slash, because we checked above */
 3777             execvp (strrchr (progpath, '/')+1, (char * const *) argv);
 3778         }
 3779       else
 3780         execvp (progpath, (char * const *) argv);
 3781 
 3782       /* still nothing, we failed */
 3783       _exit (1);
 3784     }
 3785 
 3786   /* parent process */
 3787   close (result_pipe[WRITE_END]);
 3788   close (errors_pipe[WRITE_END]);
 3789   result_pipe[WRITE_END] = -1;
 3790   errors_pipe[WRITE_END] = -1;
 3791 
 3792   ret = 0;
 3793   do
 3794     {
 3795       ret = _dbus_read (result_pipe[READ_END], result, 1024);
 3796     }
 3797   while (ret > 0);
 3798 
 3799   /* reap the child process to avoid it lingering as zombie */
 3800   do
 3801     {
 3802       ret = waitpid (pid, &status, 0);
 3803     }
 3804   while (ret == -1 && errno == EINTR);
 3805 
 3806   /* We succeeded if the process exited with status 0 and
 3807      anything was read */
 3808   if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
 3809     {
 3810       /* The process ended with error */
 3811       DBusString error_message;
 3812       if (!_dbus_string_init (&error_message))
 3813         {
 3814           _DBUS_SET_OOM (error);
 3815           goto out;
 3816         }
 3817 
 3818       ret = 0;
 3819       do
 3820         {
 3821           ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
 3822         }
 3823       while (ret > 0);
 3824 
 3825       _dbus_string_set_length (result, orig_len);
 3826       if (_dbus_string_get_length (&error_message) > 0)
 3827         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
 3828                         "%s terminated abnormally with the following error: %s",
 3829                         progpath, _dbus_string_get_data (&error_message));
 3830       else
 3831         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
 3832                         "%s terminated abnormally without any error message",
 3833                         progpath);
 3834       goto out;
 3835     }
 3836 
 3837   retval = TRUE;
 3838 
 3839  out:
 3840   sigprocmask (SIG_SETMASK, &old_set, NULL);
 3841 
 3842   if (retval)
 3843     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 3844   else
 3845     _DBUS_ASSERT_ERROR_IS_SET (error);
 3846 
 3847   if (result_pipe[0] != -1)
 3848     close (result_pipe[0]);
 3849   if (result_pipe[1] != -1)
 3850     close (result_pipe[1]);
 3851   if (errors_pipe[0] != -1)
 3852     close (errors_pipe[0]);
 3853   if (errors_pipe[1] != -1)
 3854     close (errors_pipe[1]);
 3855 
 3856   return retval;
 3857 }
 3858 #endif
 3859 
 3860 /**
 3861  * Returns the address of a new session bus.
 3862  *
 3863  * If successful, returns #TRUE and appends the address to @p
 3864  * address. If a failure happens, returns #FALSE and
 3865  * sets an error in @p error.
 3866  *
 3867  * @param scope scope of autolaunch (Windows only)
 3868  * @param address a DBusString where the address can be stored
 3869  * @param error a DBusError to store the error in case of failure
 3870  * @returns #TRUE on success, #FALSE if an error happened
 3871  */
 3872 dbus_bool_t
 3873 _dbus_get_autolaunch_address (const char *scope,
 3874                               DBusString *address,
 3875                               DBusError  *error)
 3876 {
 3877 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
 3878   static const char arg_dbus_launch[] = "dbus-launch";
 3879   static const char arg_autolaunch[] = "--autolaunch";
 3880   static const char arg_binary_syntax[] = "--binary-syntax";
 3881   static const char arg_close_stderr[] = "--close-stderr";
 3882 
 3883   /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
 3884    * but that's done elsewhere, and if it worked, this function wouldn't
 3885    * be called.) */
 3886   const char *display;
 3887   const char *progpath;
 3888   const char *argv[6];
 3889   int i;
 3890   DBusString uuid;
 3891   dbus_bool_t retval;
 3892 
 3893   if (_dbus_check_setuid ())
 3894     {
 3895       dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
 3896                             "Unable to autolaunch when setuid");
 3897       return FALSE;
 3898     }
 3899 
 3900   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 3901   retval = FALSE;
 3902 
 3903   /* fd.o #19997: if $DISPLAY isn't set to something useful, then
 3904    * dbus-launch-x11 is just going to fail. Rather than trying to
 3905    * run it, we might as well bail out early with a nice error.
 3906    *
 3907    * This is not strictly true in a world where the user bus exists,
 3908    * because dbus-launch --autolaunch knows how to connect to that -
 3909    * but if we were going to connect to the user bus, we'd have done
 3910    * so before trying autolaunch: in any case. */
 3911   display = _dbus_getenv ("DISPLAY");
 3912 
 3913   if (display == NULL || display[0] == '\0')
 3914     {
 3915       dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
 3916           "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
 3917       return FALSE;
 3918     }
 3919 
 3920   if (!_dbus_string_init (&uuid))
 3921     {
 3922       _DBUS_SET_OOM (error);
 3923       return FALSE;
 3924     }
 3925 
 3926   if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
 3927     {
 3928       goto out;
 3929     }
 3930 
 3931 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
 3932   progpath = _dbus_getenv ("DBUS_TEST_DBUS_LAUNCH");
 3933 
 3934   if (progpath == NULL)
 3935 #endif
 3936     progpath = DBUS_BINDIR "/dbus-launch";
 3937   /*
 3938    * argv[0] is always dbus-launch, that's the name what we'll
 3939    * get from /proc, or ps(1), regardless what the progpath is,
 3940    * see fd.o#69716
 3941    */
 3942   i = 0;
 3943   argv[i] = arg_dbus_launch;
 3944   ++i;
 3945   argv[i] = arg_autolaunch;
 3946   ++i;
 3947   argv[i] = _dbus_string_get_data (&uuid);
 3948   ++i;
 3949   argv[i] = arg_binary_syntax;
 3950   ++i;
 3951   argv[i] = arg_close_stderr;
 3952   ++i;
 3953   argv[i] = NULL;
 3954   ++i;
 3955 
 3956   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
 3957 
 3958   retval = _read_subprocess_line_argv (progpath,
 3959                                        TRUE,
 3960                                        argv, address, error);
 3961 
 3962  out:
 3963   _dbus_string_free (&uuid);
 3964   return retval;
 3965 #else
 3966   dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
 3967       "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
 3968       "set your DBUS_SESSION_BUS_ADDRESS instead");
 3969   return FALSE;
 3970 #endif
 3971 }
 3972 
 3973 /**
 3974  * Reads the uuid of the machine we're running on from
 3975  * the dbus configuration. Optionally try to create it
 3976  * (only root can do this usually).
 3977  *
 3978  * On UNIX, reads a file that gets created by dbus-uuidgen
 3979  * in a post-install script. On Windows, if there's a standard
 3980  * machine uuid we could just use that, but I can't find one
 3981  * with the right properties (the hardware profile guid can change
 3982  * without rebooting I believe). If there's no standard one
 3983  * we might want to use the registry instead of a file for
 3984  * this, and I'm not sure how we'd ensure the uuid gets created.
 3985  *
 3986  * @param machine_id guid to init with the machine's uuid
 3987  * @param create_if_not_found try to create the uuid if it doesn't exist
 3988  * @param error the error return
 3989  * @returns #FALSE if the error is set
 3990  */
 3991 dbus_bool_t
 3992 _dbus_read_local_machine_uuid (DBusGUID   *machine_id,
 3993                                dbus_bool_t create_if_not_found,
 3994                                DBusError  *error)
 3995 {
 3996   DBusError our_error = DBUS_ERROR_INIT;
 3997   DBusError etc_error = DBUS_ERROR_INIT;
 3998   DBusString filename;
 3999   dbus_bool_t b;
 4000 
 4001   _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
 4002 
 4003   b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &our_error);
 4004   if (b)
 4005     return TRUE;
 4006 
 4007   /* Fallback to the system machine ID */
 4008   _dbus_string_init_const (&filename, "/etc/machine-id");
 4009   b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &etc_error);
 4010 
 4011   if (b)
 4012     {
 4013       if (create_if_not_found)
 4014         {
 4015           /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
 4016            * complain if that isn't possible for whatever reason */
 4017           _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
 4018           _dbus_write_uuid_file (&filename, machine_id, NULL);
 4019         }
 4020 
 4021       dbus_error_free (&our_error);
 4022       return TRUE;
 4023     }
 4024 
 4025   if (!create_if_not_found)
 4026     {
 4027       dbus_set_error (error, etc_error.name,
 4028                       "D-Bus library appears to be incorrectly set up: "
 4029                       "see the manual page for dbus-uuidgen to correct "
 4030                       "this issue. (%s; %s)",
 4031                       our_error.message, etc_error.message);
 4032       dbus_error_free (&our_error);
 4033       dbus_error_free (&etc_error);
 4034       return FALSE;
 4035     }
 4036 
 4037   dbus_error_free (&our_error);
 4038   dbus_error_free (&etc_error);
 4039 
 4040   /* if none found, try to make a new one */
 4041   _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
 4042 
 4043   if (!_dbus_generate_uuid (machine_id, error))
 4044     return FALSE;
 4045 
 4046   return _dbus_write_uuid_file (&filename, machine_id, error);
 4047 }
 4048 
 4049 /**
 4050  * quries launchd for a specific env var which holds the socket path.
 4051  * @param socket_path append the socket path to this DBusString
 4052  * @param launchd_env_var the env var to look up
 4053  * @param error a DBusError to store the error in case of failure
 4054  * @return the value of the env var
 4055  */
 4056 dbus_bool_t
 4057 _dbus_lookup_launchd_socket (DBusString *socket_path,
 4058                              const char *launchd_env_var,
 4059                              DBusError  *error)
 4060 {
 4061 #ifdef DBUS_ENABLE_LAUNCHD
 4062   char *argv[4];
 4063   int i;
 4064 
 4065   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 4066 
 4067   if (_dbus_check_setuid ())
 4068     {
 4069       dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
 4070                             "Unable to find launchd socket when setuid");
 4071       return FALSE;
 4072     }
 4073 
 4074   i = 0;
 4075   argv[i] = "launchctl";
 4076   ++i;
 4077   argv[i] = "getenv";
 4078   ++i;
 4079   argv[i] = (char*)launchd_env_var;
 4080   ++i;
 4081   argv[i] = NULL;
 4082   ++i;
 4083 
 4084   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
 4085 
 4086   if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
 4087     {
 4088       return FALSE;
 4089     }
 4090 
 4091   /* no error, but no result either */
 4092   if (_dbus_string_get_length(socket_path) == 0)
 4093     {
 4094       return FALSE;
 4095     }
 4096 
 4097   /* strip the carriage-return */
 4098   _dbus_string_shorten(socket_path, 1);
 4099   return TRUE;
 4100 #else /* DBUS_ENABLE_LAUNCHD */
 4101   dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
 4102                 "can't lookup socket from launchd; launchd support not compiled in");
 4103   return FALSE;
 4104 #endif
 4105 }
 4106 
 4107 #ifdef DBUS_ENABLE_LAUNCHD
 4108 static dbus_bool_t
 4109 _dbus_lookup_session_address_launchd (DBusString *address, DBusError  *error)
 4110 {
 4111   dbus_bool_t valid_socket;
 4112   DBusString socket_path;
 4113 
 4114   if (_dbus_check_setuid ())
 4115     {
 4116       dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
 4117                             "Unable to find launchd socket when setuid");
 4118       return FALSE;
 4119     }
 4120 
 4121   if (!_dbus_string_init (&socket_path))
 4122     {
 4123       _DBUS_SET_OOM (error);
 4124       return FALSE;
 4125     }
 4126 
 4127   valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
 4128 
 4129   if (dbus_error_is_set(error))
 4130     {
 4131       _dbus_string_free(&socket_path);
 4132       return FALSE;
 4133     }
 4134 
 4135   if (!valid_socket)
 4136     {
 4137       dbus_set_error(error, "no socket path",
 4138                 "launchd did not provide a socket path, "
 4139                 "verify that org.freedesktop.dbus-session.plist is loaded!");
 4140       _dbus_string_free(&socket_path);
 4141       return FALSE;
 4142     }
 4143   if (!_dbus_string_append (address, "unix:path="))
 4144     {
 4145       _DBUS_SET_OOM (error);
 4146       _dbus_string_free(&socket_path);
 4147       return FALSE;
 4148     }
 4149   if (!_dbus_string_copy (&socket_path, 0, address,
 4150                           _dbus_string_get_length (address)))
 4151     {
 4152       _DBUS_SET_OOM (error);
 4153       _dbus_string_free(&socket_path);
 4154       return FALSE;
 4155     }
 4156 
 4157   _dbus_string_free(&socket_path);
 4158   return TRUE;
 4159 }
 4160 #endif
 4161 
 4162 dbus_bool_t
 4163 _dbus_lookup_user_bus (dbus_bool_t *supported,
 4164                        DBusString  *address,
 4165                        DBusError   *error)
 4166 {
 4167   const char *runtime_dir = _dbus_getenv ("XDG_RUNTIME_DIR");
 4168   dbus_bool_t ret = FALSE;
 4169   struct stat stbuf;
 4170   DBusString user_bus_path;
 4171 
 4172   if (runtime_dir == NULL)
 4173     {
 4174       _dbus_verbose ("XDG_RUNTIME_DIR not found in environment");
 4175       *supported = FALSE;
 4176       return TRUE;        /* Cannot use it, but not an error */
 4177     }
 4178 
 4179   if (!_dbus_string_init (&user_bus_path))
 4180     {
 4181       _DBUS_SET_OOM (error);
 4182       return FALSE;
 4183     }
 4184 
 4185   if (!_dbus_string_append_printf (&user_bus_path, "%s/bus", runtime_dir))
 4186     {
 4187       _DBUS_SET_OOM (error);
 4188       goto out;
 4189     }
 4190 
 4191   if (lstat (_dbus_string_get_const_data (&user_bus_path), &stbuf) == -1)
 4192     {
 4193       _dbus_verbose ("XDG_RUNTIME_DIR/bus not available: %s",
 4194                      _dbus_strerror (errno));
 4195       *supported = FALSE;
 4196       ret = TRUE;       /* Cannot use it, but not an error */
 4197       goto out;
 4198     }
 4199 
 4200   if (stbuf.st_uid != getuid ())
 4201     {
 4202       _dbus_verbose ("XDG_RUNTIME_DIR/bus owned by uid %ld, not our uid %ld",
 4203                      (long) stbuf.st_uid, (long) getuid ());
 4204       *supported = FALSE;
 4205       ret = TRUE;       /* Cannot use it, but not an error */
 4206       goto out;
 4207     }
 4208 
 4209   if ((stbuf.st_mode & S_IFMT) != S_IFSOCK)
 4210     {
 4211       _dbus_verbose ("XDG_RUNTIME_DIR/bus is not a socket: st_mode = 0o%lo",
 4212                      (long) stbuf.st_mode);
 4213       *supported = FALSE;
 4214       ret = TRUE;       /* Cannot use it, but not an error */
 4215       goto out;
 4216     }
 4217 
 4218   if (!_dbus_string_append (address, "unix:path=") ||
 4219       !_dbus_address_append_escaped (address, &user_bus_path))
 4220     {
 4221       _DBUS_SET_OOM (error);
 4222       goto out;
 4223     }
 4224 
 4225   *supported = TRUE;
 4226   ret = TRUE;
 4227 
 4228 out:
 4229   _dbus_string_free (&user_bus_path);
 4230   return ret;
 4231 }
 4232 
 4233 /**
 4234  * Determines the address of the session bus by querying a
 4235  * platform-specific method.
 4236  *
 4237  * The first parameter will be a boolean specifying whether
 4238  * or not a dynamic session lookup is supported on this platform.
 4239  *
 4240  * If supported is TRUE and the return value is #TRUE, the
 4241  * address will be  appended to @p address.
 4242  * If a failure happens, returns #FALSE and sets an error in
 4243  * @p error.
 4244  *
 4245  * If supported is FALSE, ignore the return value.
 4246  *
 4247  * @param supported returns whether this method is supported
 4248  * @param address a DBusString where the address can be stored
 4249  * @param error a DBusError to store the error in case of failure
 4250  * @returns #TRUE on success, #FALSE if an error happened
 4251  */
 4252 dbus_bool_t
 4253 _dbus_lookup_session_address (dbus_bool_t *supported,
 4254                               DBusString  *address,
 4255                               DBusError   *error)
 4256 {
 4257 #ifdef DBUS_ENABLE_LAUNCHD
 4258   *supported = TRUE;
 4259   return _dbus_lookup_session_address_launchd (address, error);
 4260 #else
 4261   *supported = FALSE;
 4262 
 4263   if (!_dbus_lookup_user_bus (supported, address, error))
 4264     return FALSE;
 4265   else if (*supported)
 4266     return TRUE;
 4267 
 4268   /* On non-Mac Unix platforms, if the session address isn't already
 4269    * set in DBUS_SESSION_BUS_ADDRESS environment variable and the
 4270    * $XDG_RUNTIME_DIR/bus can't be used, we punt and fall back to the
 4271    * autolaunch: global default; see init_session_address in
 4272    * dbus/dbus-bus.c. */
 4273   return TRUE;
 4274 #endif
 4275 }
 4276 
 4277 /**
 4278  * Called when the bus daemon is signaled to reload its configuration; any
 4279  * caches should be nuked. Of course any caches that need explicit reload
 4280  * are probably broken, but c'est la vie.
 4281  *
 4282  *
 4283  */
 4284 void
 4285 _dbus_flush_caches (void)
 4286 {
 4287   _dbus_user_database_flush_system ();
 4288 }
 4289 
 4290 /**
 4291  * Appends the directory in which a keyring for the given credentials
 4292  * should be stored.  The credentials should have either a Windows or
 4293  * UNIX user in them.  The directory should be an absolute path.
 4294  *
 4295  * On UNIX the directory is ~/.dbus-keyrings while on Windows it should probably
 4296  * be something else, since the dotfile convention is not normal on Windows.
 4297  *
 4298  * @param directory string to append directory to
 4299  * @param credentials credentials the directory should be for
 4300  *
 4301  * @returns #FALSE on no memory
 4302  */
 4303 dbus_bool_t
 4304 _dbus_append_keyring_directory_for_credentials (DBusString      *directory,
 4305                                                 DBusCredentials *credentials)
 4306 {
 4307   DBusString homedir;
 4308   DBusString dotdir;
 4309   dbus_uid_t uid;
 4310 
 4311   _dbus_assert (credentials != NULL);
 4312   _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
 4313 
 4314   if (!_dbus_string_init (&homedir))
 4315     return FALSE;
 4316 
 4317   uid = _dbus_credentials_get_unix_uid (credentials);
 4318   _dbus_assert (uid != DBUS_UID_UNSET);
 4319 
 4320   if (!_dbus_homedir_from_uid (uid, &homedir))
 4321     goto failed;
 4322 
 4323 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
 4324   {
 4325     const char *override;
 4326 
 4327     override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
 4328     if (override != NULL && *override != '\0')
 4329       {
 4330         _dbus_string_set_length (&homedir, 0);
 4331         if (!_dbus_string_append (&homedir, override))
 4332           goto failed;
 4333 
 4334         _dbus_verbose ("Using fake homedir for testing: %s\n",
 4335                        _dbus_string_get_const_data (&homedir));
 4336       }
 4337     else
 4338       {
 4339         /* Not strictly thread-safe, but if we fail at thread-safety here,
 4340          * the worst that will happen is some extra warnings. */
 4341         static dbus_bool_t already_warned = FALSE;
 4342         if (!already_warned)
 4343           {
 4344             _dbus_warn ("Using %s for testing, set DBUS_TEST_HOMEDIR to avoid",
 4345                 _dbus_string_get_const_data (&homedir));
 4346             already_warned = TRUE;
 4347           }
 4348       }
 4349   }
 4350 #endif
 4351 
 4352   _dbus_string_init_const (&dotdir, ".dbus-keyrings");
 4353   if (!_dbus_concat_dir_and_file (&homedir,
 4354                                   &dotdir))
 4355     goto failed;
 4356 
 4357   if (!_dbus_string_copy (&homedir, 0,
 4358                           directory, _dbus_string_get_length (directory))) {
 4359     goto failed;
 4360   }
 4361 
 4362   _dbus_string_free (&homedir);
 4363   return TRUE;
 4364 
 4365  failed:
 4366   _dbus_string_free (&homedir);
 4367   return FALSE;
 4368 }
 4369 
 4370 //PENDING(kdab) docs
 4371 dbus_bool_t
 4372 _dbus_daemon_publish_session_bus_address (const char* addr,
 4373                                           const char *scope)
 4374 {
 4375   return TRUE;
 4376 }
 4377 
 4378 //PENDING(kdab) docs
 4379 void
 4380 _dbus_daemon_unpublish_session_bus_address (void)
 4381 {
 4382 
 4383 }
 4384 
 4385 /**
 4386  * See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently
 4387  * for Winsock so is abstracted)
 4388  *
 4389  * @returns #TRUE if e == EAGAIN or e == EWOULDBLOCK
 4390  */
 4391 dbus_bool_t
 4392 _dbus_get_is_errno_eagain_or_ewouldblock (int e)
 4393 {
 4394   /* Avoid the -Wlogical-op GCC warning, which can be triggered when EAGAIN and
 4395    * EWOULDBLOCK are numerically equal, which is permitted as described by
 4396    * errno(3).
 4397    */
 4398 #if EAGAIN == EWOULDBLOCK
 4399   return e == EAGAIN;
 4400 #else
 4401   return e == EAGAIN || e == EWOULDBLOCK;
 4402 #endif
 4403 }
 4404 
 4405 /**
 4406  * Removes a directory; Directory must be empty
 4407  *
 4408  * @param filename directory filename
 4409  * @param error initialized error object
 4410  * @returns #TRUE on success
 4411  */
 4412 dbus_bool_t
 4413 _dbus_delete_directory (const DBusString *filename,
 4414                         DBusError        *error)
 4415 {
 4416   const char *filename_c;
 4417 
 4418   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 4419 
 4420   filename_c = _dbus_string_get_const_data (filename);
 4421 
 4422   if (rmdir (filename_c) != 0)
 4423     {
 4424       dbus_set_error (error, DBUS_ERROR_FAILED,
 4425                       "Failed to remove directory %s: %s\n",
 4426                       filename_c, _dbus_strerror (errno));
 4427       return FALSE;
 4428     }
 4429 
 4430   return TRUE;
 4431 }
 4432 
 4433 /**
 4434  *  Checks whether file descriptors may be passed via the socket
 4435  *
 4436  *  @param fd the socket
 4437  *  @return TRUE when fd passing over this socket is supported
 4438  *
 4439  */
 4440 dbus_bool_t
 4441 _dbus_socket_can_pass_unix_fd (DBusSocket fd)
 4442 {
 4443 #ifdef SCM_RIGHTS
 4444   union {
 4445     struct sockaddr sa;
 4446     struct sockaddr_storage storage;
 4447     struct sockaddr_un un;
 4448   } sa_buf;
 4449 
 4450   socklen_t sa_len = sizeof(sa_buf);
 4451 
 4452   _DBUS_ZERO(sa_buf);
 4453 
 4454   if (getsockname(fd.fd, &sa_buf.sa, &sa_len) < 0)
 4455     return FALSE;
 4456 
 4457   return sa_buf.sa.sa_family == AF_UNIX;
 4458 
 4459 #else
 4460   return FALSE;
 4461 
 4462 #endif
 4463 }
 4464 
 4465 /**
 4466  * Closes all file descriptors except the first three (i.e. stdin,
 4467  * stdout, stderr).
 4468  */
 4469 void
 4470 _dbus_close_all (void)
 4471 {
 4472   int maxfds, i;
 4473 
 4474 #ifdef __linux__
 4475   DIR *d;
 4476 
 4477   /* On Linux we can optimize this a bit if /proc is available. If it
 4478      isn't available, fall back to the brute force way. */
 4479 
 4480   d = opendir ("/proc/self/fd");
 4481   if (d)
 4482     {
 4483       for (;;)
 4484         {
 4485           struct dirent *de;
 4486           int fd;
 4487           long l;
 4488           char *e = NULL;
 4489 
 4490           de = readdir (d);
 4491           if (!de)
 4492             break;
 4493 
 4494           if (de->d_name[0] == '.')
 4495             continue;
 4496 
 4497           errno = 0;
 4498           l = strtol (de->d_name, &e, 10);
 4499           if (errno != 0 || e == NULL || *e != '\0')
 4500             continue;
 4501 
 4502           fd = (int) l;
 4503           if (fd < 3)
 4504             continue;
 4505 
 4506           if (fd == dirfd (d))
 4507             continue;
 4508 
 4509           close (fd);
 4510         }
 4511 
 4512       closedir (d);
 4513       return;
 4514     }
 4515 #endif
 4516 
 4517   maxfds = sysconf (_SC_OPEN_MAX);
 4518 
 4519   /* Pick something reasonable if for some reason sysconf says
 4520    * unlimited.
 4521    */
 4522   if (maxfds < 0)
 4523     maxfds = 1024;
 4524 
 4525   /* close all inherited fds */
 4526   for (i = 3; i < maxfds; i++)
 4527     close (i);
 4528 }
 4529 
 4530 /**
 4531  * **NOTE**: If you modify this function, please also consider making
 4532  * the corresponding change in GLib.  See
 4533  * glib/gutils.c:g_check_setuid().
 4534  *
 4535  * Returns TRUE if the current process was executed as setuid (or an
 4536  * equivalent __libc_enable_secure is available).  See:
 4537  * http://osdir.com/ml/linux.lfs.hardened/2007-04/msg00032.html
 4538  */
 4539 dbus_bool_t
 4540 _dbus_check_setuid (void)
 4541 {
 4542   /* TODO: get __libc_enable_secure exported from glibc.
 4543    * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
 4544    */
 4545 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
 4546   {
 4547     /* See glibc/include/unistd.h */
 4548     extern int __libc_enable_secure;
 4549     return __libc_enable_secure;
 4550   }
 4551 #elif defined(HAVE_ISSETUGID)
 4552   /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
 4553   return issetugid ();
 4554 #else
 4555   uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
 4556   gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
 4557 
 4558   /* We call into this function from _dbus_threads_init_platform_specific()
 4559    * to make sure these are initialized before we start threading. */
 4560   static dbus_bool_t check_setuid_initialised;
 4561   static dbus_bool_t is_setuid;
 4562 
 4563   if (_DBUS_UNLIKELY (!check_setuid_initialised))
 4564     {
 4565 #ifdef HAVE_GETRESUID
 4566       if (getresuid (&ruid, &euid, &suid) != 0 ||
 4567           getresgid (&rgid, &egid, &sgid) != 0)
 4568 #endif /* HAVE_GETRESUID */
 4569         {
 4570           suid = ruid = getuid ();
 4571           sgid = rgid = getgid ();
 4572           euid = geteuid ();
 4573           egid = getegid ();
 4574         }
 4575 
 4576       check_setuid_initialised = TRUE;
 4577       is_setuid = (ruid != euid || ruid != suid ||
 4578                    rgid != egid || rgid != sgid);
 4579 
 4580     }
 4581   return is_setuid;
 4582 #endif
 4583 }
 4584 
 4585 /**
 4586  * Read the address from the socket and append it to the string
 4587  *
 4588  * @param fd the socket
 4589  * @param address
 4590  * @param error return location for error code
 4591  */
 4592 dbus_bool_t
 4593 _dbus_append_address_from_socket (DBusSocket  fd,
 4594                                   DBusString *address,
 4595                                   DBusError  *error)
 4596 {
 4597   union {
 4598       struct sockaddr sa;
 4599       struct sockaddr_storage storage;
 4600       struct sockaddr_un un;
 4601       struct sockaddr_in ipv4;
 4602       struct sockaddr_in6 ipv6;
 4603   } socket;
 4604   char hostip[INET6_ADDRSTRLEN];
 4605   socklen_t size = sizeof (socket);
 4606   DBusString path_str;
 4607 
 4608   if (getsockname (fd.fd, &socket.sa, &size))
 4609     goto err;
 4610 
 4611   switch (socket.sa.sa_family)
 4612     {
 4613     case AF_UNIX:
 4614       if (socket.un.sun_path[0]=='\0')
 4615         {
 4616           _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
 4617           if (_dbus_string_append (address, "unix:abstract=") &&
 4618               _dbus_address_append_escaped (address, &path_str))
 4619             return TRUE;
 4620         }
 4621       else
 4622         {
 4623           _dbus_string_init_const (&path_str, socket.un.sun_path);
 4624           if (_dbus_string_append (address, "unix:path=") &&
 4625               _dbus_address_append_escaped (address, &path_str))
 4626             return TRUE;
 4627         }
 4628       break;
 4629     case AF_INET:
 4630       if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
 4631         if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
 4632                                         hostip, ntohs (socket.ipv4.sin_port)))
 4633           return TRUE;
 4634       break;
 4635 #ifdef AF_INET6
 4636     case AF_INET6:
 4637       _dbus_string_init_const (&path_str, hostip);
 4638       if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
 4639         if (_dbus_string_append_printf (address, "tcp:family=ipv6,port=%u,host=",
 4640                                         ntohs (socket.ipv6.sin6_port)) &&
 4641             _dbus_address_append_escaped (address, &path_str))
 4642           return TRUE;
 4643       break;
 4644 #endif
 4645     default:
 4646       dbus_set_error (error,
 4647                       _dbus_error_from_errno (EINVAL),
 4648                       "Failed to read address from socket: Unknown socket type.");
 4649       return FALSE;
 4650     }
 4651  err:
 4652   dbus_set_error (error,
 4653                   _dbus_error_from_errno (errno),
 4654                   "Failed to open socket: %s",
 4655                   _dbus_strerror (errno));
 4656   return FALSE;
 4657 }
 4658 
 4659 int
 4660 _dbus_save_socket_errno (void)
 4661 {
 4662   return errno;
 4663 }
 4664 
 4665 void
 4666 _dbus_restore_socket_errno (int saved_errno)
 4667 {
 4668   errno = saved_errno;
 4669 }
 4670 
 4671 static const char *syslog_tag = "dbus";
 4672 #ifdef HAVE_SYSLOG_H
 4673 static DBusLogFlags log_flags = DBUS_LOG_FLAGS_STDERR;
 4674 #endif
 4675 
 4676 /**
 4677  * Initialize the system log.
 4678  *
 4679  * The "tag" is not copied, and must remain valid for the entire lifetime of
 4680  * the process or until _dbus_init_system_log() is called again. In practice
 4681  * it will normally be a constant.
 4682  *
 4683  * On platforms that do not support a system log, the
 4684  * #DBUS_LOG_FLAGS_SYSTEM_LOG flag is treated as equivalent to
 4685  * #DBUS_LOG_FLAGS_STDERR.
 4686  *
 4687  * @param tag the name of the executable (syslog tag)
 4688  * @param mode whether to log to stderr, the system log or both
 4689  */
 4690 void
 4691 _dbus_init_system_log (const char   *tag,
 4692                        DBusLogFlags  flags)
 4693 {
 4694   /* We never want to turn off logging completely */
 4695   _dbus_assert (
 4696       (flags & (DBUS_LOG_FLAGS_STDERR | DBUS_LOG_FLAGS_SYSTEM_LOG)) != 0);
 4697 
 4698   syslog_tag = tag;
 4699 
 4700 #ifdef HAVE_SYSLOG_H
 4701   log_flags = flags;
 4702 
 4703   if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
 4704     openlog (tag, LOG_PID, LOG_DAEMON);
 4705 #endif
 4706 }
 4707 
 4708 /**
 4709  * Log a message to the system log file (e.g. syslog on Unix) and/or stderr.
 4710  *
 4711  * @param severity a severity value
 4712  * @param msg a printf-style format string
 4713  * @param args arguments for the format string
 4714  */
 4715 void
 4716 _dbus_logv (DBusSystemLogSeverity  severity,
 4717             const char            *msg,
 4718             va_list                args)
 4719 {
 4720   va_list tmp;
 4721 #ifdef HAVE_SYSLOG_H
 4722   if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
 4723     {
 4724       int flags;
 4725       switch (severity)
 4726         {
 4727           case DBUS_SYSTEM_LOG_INFO:
 4728             flags =  LOG_DAEMON | LOG_INFO;
 4729             break;
 4730           case DBUS_SYSTEM_LOG_WARNING:
 4731             flags =  LOG_DAEMON | LOG_WARNING;
 4732             break;
 4733           case DBUS_SYSTEM_LOG_SECURITY:
 4734             flags = LOG_AUTH | LOG_NOTICE;
 4735             break;
 4736           case DBUS_SYSTEM_LOG_ERROR:
 4737             flags = LOG_DAEMON|LOG_CRIT;
 4738             break;
 4739           default:
 4740             _dbus_assert_not_reached ("invalid log severity");
 4741         }
 4742 
 4743       DBUS_VA_COPY (tmp, args);
 4744       vsyslog (flags, msg, tmp);
 4745       va_end (tmp);
 4746     }
 4747 
 4748   /* If we don't have syslog.h, we always behave as though stderr was in
 4749    * the flags */
 4750   if (log_flags & DBUS_LOG_FLAGS_STDERR)
 4751 #endif
 4752     {
 4753       DBUS_VA_COPY (tmp, args);
 4754       fprintf (stderr, "%s[" DBUS_PID_FORMAT "]: ", syslog_tag, _dbus_getpid ());
 4755       vfprintf (stderr, msg, tmp);
 4756       fputc ('\n', stderr);
 4757       va_end (tmp);
 4758     }
 4759 }
 4760 
 4761 /* tests in dbus-sysdeps-util.c */