sysdeps-unix: check for HAVE_DECL_MSG_NOSIGNAL
[platform/upstream/dbus.git] / dbus / dbus-sysdeps-unix.c
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-transport.h"
33 #include "dbus-string.h"
34 #include "dbus-userdb.h"
35 #include "dbus-list.h"
36 #include "dbus-credentials.h"
37 #include "dbus-nonce.h"
38
39 #include <sys/types.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <signal.h>
43 #include <unistd.h>
44 #include <stdio.h>
45 #include <fcntl.h>
46 #include <sys/socket.h>
47 #include <dirent.h>
48 #include <sys/un.h>
49 #include <pwd.h>
50 #include <time.h>
51 #include <locale.h>
52 #include <sys/time.h>
53 #include <sys/stat.h>
54 #include <sys/wait.h>
55 #include <netinet/in.h>
56 #include <netdb.h>
57 #include <grp.h>
58
59 #ifdef HAVE_ERRNO_H
60 #include <errno.h>
61 #endif
62 #ifdef HAVE_WRITEV
63 #include <sys/uio.h>
64 #endif
65 #ifdef HAVE_POLL
66 #include <sys/poll.h>
67 #endif
68 #ifdef HAVE_BACKTRACE
69 #include <execinfo.h>
70 #endif
71 #ifdef HAVE_GETPEERUCRED
72 #include <ucred.h>
73 #endif
74
75 #ifdef HAVE_ADT
76 #include <bsm/adt.h>
77 #endif
78
79 #include "sd-daemon.h"
80
81 #ifndef O_BINARY
82 #define O_BINARY 0
83 #endif
84
85 #ifndef AI_ADDRCONFIG
86 #define AI_ADDRCONFIG 0
87 #endif
88
89 #ifndef HAVE_SOCKLEN_T
90 #define socklen_t int
91 #endif
92
93 static dbus_bool_t
94 _dbus_open_socket (int              *fd_p,
95                    int               domain,
96                    int               type,
97                    int               protocol,
98                    DBusError        *error)
99 {
100 #ifdef SOCK_CLOEXEC
101   dbus_bool_t cloexec_done;
102
103   *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
104   cloexec_done = *fd_p >= 0;
105
106   /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
107   if (*fd_p < 0 && errno == EINVAL)
108 #endif
109     {
110       *fd_p = socket (domain, type, protocol);
111     }
112
113   if (*fd_p >= 0)
114     {
115 #ifdef SOCK_CLOEXEC
116       if (!cloexec_done)
117 #endif
118         {
119           _dbus_fd_set_close_on_exec(*fd_p);
120         }
121
122       _dbus_verbose ("socket fd %d opened\n", *fd_p);
123       return TRUE;
124     }
125   else
126     {
127       dbus_set_error(error,
128                      _dbus_error_from_errno (errno),
129                      "Failed to open socket: %s",
130                      _dbus_strerror (errno));
131       return FALSE;
132     }
133 }
134
135 dbus_bool_t
136 _dbus_open_tcp_socket (int              *fd,
137                        DBusError        *error)
138 {
139   return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error);
140 }
141
142 /**
143  * Opens a UNIX domain socket (as in the socket() call).
144  * Does not bind the socket.
145  *
146  * This will set FD_CLOEXEC for the socket returned
147  *
148  * @param fd return location for socket descriptor
149  * @param error return location for an error
150  * @returns #FALSE if error is set
151  */
152 dbus_bool_t
153 _dbus_open_unix_socket (int              *fd,
154                         DBusError        *error)
155 {
156   return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
157 }
158
159 /**
160  * Closes a socket. Should not be used on non-socket
161  * file descriptors or handles.
162  *
163  * @param fd the socket
164  * @param error return location for an error
165  * @returns #FALSE if error is set
166  */
167 dbus_bool_t
168 _dbus_close_socket (int               fd,
169                     DBusError        *error)
170 {
171   return _dbus_close (fd, error);
172 }
173
174 /**
175  * Like _dbus_read(), but only works on sockets so is
176  * available on Windows.
177  *
178  * @param fd the socket
179  * @param buffer string to append data to
180  * @param count max amount of data to read
181  * @returns number of bytes appended to the string
182  */
183 int
184 _dbus_read_socket (int               fd,
185                    DBusString       *buffer,
186                    int               count)
187 {
188   return _dbus_read (fd, buffer, count);
189 }
190
191 /**
192  * Like _dbus_write(), but only supports sockets
193  * and is thus available on Windows.
194  *
195  * @param fd the file descriptor to write
196  * @param buffer the buffer to write data from
197  * @param start the first byte in the buffer to write
198  * @param len the number of bytes to try to write
199  * @returns the number of bytes written or -1 on error
200  */
201 int
202 _dbus_write_socket (int               fd,
203                     const DBusString *buffer,
204                     int               start,
205                     int               len)
206 {
207 #ifdef HAVE_DECL_MSG_NOSIGNAL
208   const char *data;
209   int bytes_written;
210
211   data = _dbus_string_get_const_data_len (buffer, start, len);
212
213  again:
214
215   bytes_written = send (fd, data, len, MSG_NOSIGNAL);
216
217   if (bytes_written < 0 && errno == EINTR)
218     goto again;
219
220   return bytes_written;
221
222 #else
223   return _dbus_write (fd, buffer, start, len);
224 #endif
225 }
226
227 /**
228  * Like _dbus_read_socket() but also tries to read unix fds from the
229  * socket. When there are more fds to read than space in the array
230  * passed this function will fail with ENOSPC.
231  *
232  * @param fd the socket
233  * @param buffer string to append data to
234  * @param count max amount of data to read
235  * @param fds array to place read file descriptors in
236  * @param n_fds on input space in fds array, on output how many fds actually got read
237  * @returns number of bytes appended to string
238  */
239 int
240 _dbus_read_socket_with_unix_fds (int               fd,
241                                  DBusString       *buffer,
242                                  int               count,
243                                  int              *fds,
244                                  int              *n_fds) {
245 #ifndef HAVE_UNIX_FD_PASSING
246   int r;
247
248   if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
249     return r;
250
251   *n_fds = 0;
252   return r;
253
254 #else
255   int bytes_read;
256   int start;
257   struct msghdr m;
258   struct iovec iov;
259
260   _dbus_assert (count >= 0);
261   _dbus_assert (*n_fds >= 0);
262
263   start = _dbus_string_get_length (buffer);
264
265   if (!_dbus_string_lengthen (buffer, count))
266     {
267       errno = ENOMEM;
268       return -1;
269     }
270
271   _DBUS_ZERO(iov);
272   iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
273   iov.iov_len = count;
274
275   _DBUS_ZERO(m);
276   m.msg_iov = &iov;
277   m.msg_iovlen = 1;
278
279   /* Hmm, we have no clue how long the control data will actually be
280      that is queued for us. The least we can do is assume that the
281      caller knows. Hence let's make space for the number of fds that
282      we shall read at max plus the cmsg header. */
283   m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
284
285   /* It's probably safe to assume that systems with SCM_RIGHTS also
286      know alloca() */
287   m.msg_control = alloca(m.msg_controllen);
288   memset(m.msg_control, 0, m.msg_controllen);
289
290  again:
291
292   bytes_read = recvmsg(fd, &m, 0
293 #ifdef MSG_CMSG_CLOEXEC
294                        |MSG_CMSG_CLOEXEC
295 #endif
296                        );
297
298   if (bytes_read < 0)
299     {
300       if (errno == EINTR)
301         goto again;
302       else
303         {
304           /* put length back (note that this doesn't actually realloc anything) */
305           _dbus_string_set_length (buffer, start);
306           return -1;
307         }
308     }
309   else
310     {
311       struct cmsghdr *cm;
312       dbus_bool_t found = FALSE;
313
314       if (m.msg_flags & MSG_CTRUNC)
315         {
316           /* Hmm, apparently the control data was truncated. The bad
317              thing is that we might have completely lost a couple of fds
318              without chance to recover them. Hence let's treat this as a
319              serious error. */
320
321           errno = ENOSPC;
322           _dbus_string_set_length (buffer, start);
323           return -1;
324         }
325
326       for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
327         if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
328           {
329             unsigned i;
330
331             _dbus_assert(cm->cmsg_len <= CMSG_LEN(*n_fds * sizeof(int)));
332             *n_fds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(int);
333
334             memcpy(fds, CMSG_DATA(cm), *n_fds * sizeof(int));
335             found = TRUE;
336
337             /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
338                worked, hence we need to go through this list and set
339                CLOEXEC everywhere in any case */
340             for (i = 0; i < *n_fds; i++)
341               _dbus_fd_set_close_on_exec(fds[i]);
342
343             break;
344           }
345
346       if (!found)
347         *n_fds = 0;
348
349       /* put length back (doesn't actually realloc) */
350       _dbus_string_set_length (buffer, start + bytes_read);
351
352 #if 0
353       if (bytes_read > 0)
354         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
355 #endif
356
357       return bytes_read;
358     }
359 #endif
360 }
361
362 int
363 _dbus_write_socket_with_unix_fds(int               fd,
364                                  const DBusString *buffer,
365                                  int               start,
366                                  int               len,
367                                  const int        *fds,
368                                  int               n_fds) {
369
370 #ifndef HAVE_UNIX_FD_PASSING
371
372   if (n_fds > 0) {
373     errno = ENOTSUP;
374     return -1;
375   }
376
377   return _dbus_write_socket(fd, buffer, start, len);
378 #else
379   return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
380 #endif
381 }
382
383 int
384 _dbus_write_socket_with_unix_fds_two(int               fd,
385                                      const DBusString *buffer1,
386                                      int               start1,
387                                      int               len1,
388                                      const DBusString *buffer2,
389                                      int               start2,
390                                      int               len2,
391                                      const int        *fds,
392                                      int               n_fds) {
393
394 #ifndef HAVE_UNIX_FD_PASSING
395
396   if (n_fds > 0) {
397     errno = ENOTSUP;
398     return -1;
399   }
400
401   return _dbus_write_socket_two(fd,
402                                 buffer1, start1, len1,
403                                 buffer2, start2, len2);
404 #else
405
406   struct msghdr m;
407   struct cmsghdr *cm;
408   struct iovec iov[2];
409   int bytes_written;
410
411   _dbus_assert (len1 >= 0);
412   _dbus_assert (len2 >= 0);
413   _dbus_assert (n_fds >= 0);
414
415   _DBUS_ZERO(iov);
416   iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
417   iov[0].iov_len = len1;
418
419   if (buffer2)
420     {
421       iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
422       iov[1].iov_len = len2;
423     }
424
425   _DBUS_ZERO(m);
426   m.msg_iov = iov;
427   m.msg_iovlen = buffer2 ? 2 : 1;
428
429   if (n_fds > 0)
430     {
431       m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
432       m.msg_control = alloca(m.msg_controllen);
433       memset(m.msg_control, 0, m.msg_controllen);
434
435       cm = CMSG_FIRSTHDR(&m);
436       cm->cmsg_level = SOL_SOCKET;
437       cm->cmsg_type = SCM_RIGHTS;
438       cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
439       memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
440     }
441
442  again:
443
444   bytes_written = sendmsg (fd, &m, 0
445 #ifdef HAVE_DECL_MSG_NOSIGNAL
446                            |MSG_NOSIGNAL
447 #endif
448                            );
449
450   if (bytes_written < 0 && errno == EINTR)
451     goto again;
452
453 #if 0
454   if (bytes_written > 0)
455     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
456 #endif
457
458   return bytes_written;
459 #endif
460 }
461
462 /**
463  * Like _dbus_write_two() but only works on sockets and is thus
464  * available on Windows.
465  *
466  * @param fd the file descriptor
467  * @param buffer1 first buffer
468  * @param start1 first byte to write in first buffer
469  * @param len1 number of bytes to write from first buffer
470  * @param buffer2 second buffer, or #NULL
471  * @param start2 first byte to write in second buffer
472  * @param len2 number of bytes to write in second buffer
473  * @returns total bytes written from both buffers, or -1 on error
474  */
475 int
476 _dbus_write_socket_two (int               fd,
477                         const DBusString *buffer1,
478                         int               start1,
479                         int               len1,
480                         const DBusString *buffer2,
481                         int               start2,
482                         int               len2)
483 {
484 #ifdef HAVE_DECL_MSG_NOSIGNAL
485   struct iovec vectors[2];
486   const char *data1;
487   const char *data2;
488   int bytes_written;
489   struct msghdr m;
490
491   _dbus_assert (buffer1 != NULL);
492   _dbus_assert (start1 >= 0);
493   _dbus_assert (start2 >= 0);
494   _dbus_assert (len1 >= 0);
495   _dbus_assert (len2 >= 0);
496
497   data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
498
499   if (buffer2 != NULL)
500     data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
501   else
502     {
503       data2 = NULL;
504       start2 = 0;
505       len2 = 0;
506     }
507
508   vectors[0].iov_base = (char*) data1;
509   vectors[0].iov_len = len1;
510   vectors[1].iov_base = (char*) data2;
511   vectors[1].iov_len = len2;
512
513   _DBUS_ZERO(m);
514   m.msg_iov = vectors;
515   m.msg_iovlen = data2 ? 2 : 1;
516
517  again:
518
519   bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
520
521   if (bytes_written < 0 && errno == EINTR)
522     goto again;
523
524   return bytes_written;
525
526 #else
527   return _dbus_write_two (fd, buffer1, start1, len1,
528                           buffer2, start2, len2);
529 #endif
530 }
531
532 dbus_bool_t
533 _dbus_socket_is_invalid (int fd)
534 {
535     return fd < 0 ? TRUE : FALSE;
536 }
537
538 /**
539  * Thin wrapper around the read() system call that appends
540  * the data it reads to the DBusString buffer. It appends
541  * up to the given count, and returns the same value
542  * and same errno as read(). The only exception is that
543  * _dbus_read() handles EINTR for you. Also, _dbus_read() can
544  * return ENOMEM, even though regular UNIX read doesn't.
545  *
546  * Unlike _dbus_read_socket(), _dbus_read() is not available
547  * on Windows.
548  *
549  * @param fd the file descriptor to read from
550  * @param buffer the buffer to append data to
551  * @param count the amount of data to read
552  * @returns the number of bytes read or -1
553  */
554 int
555 _dbus_read (int               fd,
556             DBusString       *buffer,
557             int               count)
558 {
559   int bytes_read;
560   int start;
561   char *data;
562
563   _dbus_assert (count >= 0);
564
565   start = _dbus_string_get_length (buffer);
566
567   if (!_dbus_string_lengthen (buffer, count))
568     {
569       errno = ENOMEM;
570       return -1;
571     }
572
573   data = _dbus_string_get_data_len (buffer, start, count);
574
575  again:
576
577   bytes_read = read (fd, data, count);
578
579   if (bytes_read < 0)
580     {
581       if (errno == EINTR)
582         goto again;
583       else
584         {
585           /* put length back (note that this doesn't actually realloc anything) */
586           _dbus_string_set_length (buffer, start);
587           return -1;
588         }
589     }
590   else
591     {
592       /* put length back (doesn't actually realloc) */
593       _dbus_string_set_length (buffer, start + bytes_read);
594
595 #if 0
596       if (bytes_read > 0)
597         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
598 #endif
599
600       return bytes_read;
601     }
602 }
603
604 /**
605  * Thin wrapper around the write() system call that writes a part of a
606  * DBusString and handles EINTR for you.
607  *
608  * @param fd the file descriptor to write
609  * @param buffer the buffer to write data from
610  * @param start the first byte in the buffer to write
611  * @param len the number of bytes to try to write
612  * @returns the number of bytes written or -1 on error
613  */
614 int
615 _dbus_write (int               fd,
616              const DBusString *buffer,
617              int               start,
618              int               len)
619 {
620   const char *data;
621   int bytes_written;
622
623   data = _dbus_string_get_const_data_len (buffer, start, len);
624
625  again:
626
627   bytes_written = write (fd, data, len);
628
629   if (bytes_written < 0 && errno == EINTR)
630     goto again;
631
632 #if 0
633   if (bytes_written > 0)
634     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
635 #endif
636
637   return bytes_written;
638 }
639
640 /**
641  * Like _dbus_write() but will use writev() if possible
642  * to write both buffers in sequence. The return value
643  * is the number of bytes written in the first buffer,
644  * plus the number written in the second. If the first
645  * buffer is written successfully and an error occurs
646  * writing the second, the number of bytes in the first
647  * is returned (i.e. the error is ignored), on systems that
648  * don't have writev. Handles EINTR for you.
649  * The second buffer may be #NULL.
650  *
651  * @param fd the file descriptor
652  * @param buffer1 first buffer
653  * @param start1 first byte to write in first buffer
654  * @param len1 number of bytes to write from first buffer
655  * @param buffer2 second buffer, or #NULL
656  * @param start2 first byte to write in second buffer
657  * @param len2 number of bytes to write in second buffer
658  * @returns total bytes written from both buffers, or -1 on error
659  */
660 int
661 _dbus_write_two (int               fd,
662                  const DBusString *buffer1,
663                  int               start1,
664                  int               len1,
665                  const DBusString *buffer2,
666                  int               start2,
667                  int               len2)
668 {
669   _dbus_assert (buffer1 != NULL);
670   _dbus_assert (start1 >= 0);
671   _dbus_assert (start2 >= 0);
672   _dbus_assert (len1 >= 0);
673   _dbus_assert (len2 >= 0);
674
675 #ifdef HAVE_WRITEV
676   {
677     struct iovec vectors[2];
678     const char *data1;
679     const char *data2;
680     int bytes_written;
681
682     data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
683
684     if (buffer2 != NULL)
685       data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
686     else
687       {
688         data2 = NULL;
689         start2 = 0;
690         len2 = 0;
691       }
692
693     vectors[0].iov_base = (char*) data1;
694     vectors[0].iov_len = len1;
695     vectors[1].iov_base = (char*) data2;
696     vectors[1].iov_len = len2;
697
698   again:
699
700     bytes_written = writev (fd,
701                             vectors,
702                             data2 ? 2 : 1);
703
704     if (bytes_written < 0 && errno == EINTR)
705       goto again;
706
707     return bytes_written;
708   }
709 #else /* HAVE_WRITEV */
710   {
711     int ret1;
712
713     ret1 = _dbus_write (fd, buffer1, start1, len1);
714     if (ret1 == len1 && buffer2 != NULL)
715       {
716         ret2 = _dbus_write (fd, buffer2, start2, len2);
717         if (ret2 < 0)
718           ret2 = 0; /* we can't report an error as the first write was OK */
719
720         return ret1 + ret2;
721       }
722     else
723       return ret1;
724   }
725 #endif /* !HAVE_WRITEV */
726 }
727
728 #define _DBUS_MAX_SUN_PATH_LENGTH 99
729
730 /**
731  * @def _DBUS_MAX_SUN_PATH_LENGTH
732  *
733  * Maximum length of the path to a UNIX domain socket,
734  * sockaddr_un::sun_path member. POSIX requires that all systems
735  * support at least 100 bytes here, including the nul termination.
736  * We use 99 for the max value to allow for the nul.
737  *
738  * We could probably also do sizeof (addr.sun_path)
739  * but this way we are the same on all platforms
740  * which is probably a good idea.
741  */
742
743 /**
744  * Creates a socket and connects it to the UNIX domain socket at the
745  * given path.  The connection fd is returned, and is set up as
746  * nonblocking.
747  *
748  * Uses abstract sockets instead of filesystem-linked sockets if
749  * requested (it's possible only on Linux; see "man 7 unix" on Linux).
750  * On non-Linux abstract socket usage always fails.
751  *
752  * This will set FD_CLOEXEC for the socket returned.
753  *
754  * @param path the path to UNIX domain socket
755  * @param abstract #TRUE to use abstract namespace
756  * @param error return location for error code
757  * @returns connection file descriptor or -1 on error
758  */
759 int
760 _dbus_connect_unix_socket (const char     *path,
761                            dbus_bool_t     abstract,
762                            DBusError      *error)
763 {
764   int fd;
765   size_t path_len;
766   struct sockaddr_un addr;
767
768   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
769
770   _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
771                  path, abstract);
772
773
774   if (!_dbus_open_unix_socket (&fd, error))
775     {
776       _DBUS_ASSERT_ERROR_IS_SET(error);
777       return -1;
778     }
779   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
780
781   _DBUS_ZERO (addr);
782   addr.sun_family = AF_UNIX;
783   path_len = strlen (path);
784
785   if (abstract)
786     {
787 #ifdef HAVE_ABSTRACT_SOCKETS
788       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
789       path_len++; /* Account for the extra nul byte added to the start of sun_path */
790
791       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
792         {
793           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
794                       "Abstract socket name too long\n");
795           _dbus_close (fd, NULL);
796           return -1;
797         }
798
799       strncpy (&addr.sun_path[1], path, path_len);
800       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
801 #else /* HAVE_ABSTRACT_SOCKETS */
802       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
803                       "Operating system does not support abstract socket namespace\n");
804       _dbus_close (fd, NULL);
805       return -1;
806 #endif /* ! HAVE_ABSTRACT_SOCKETS */
807     }
808   else
809     {
810       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
811         {
812           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
813                       "Socket name too long\n");
814           _dbus_close (fd, NULL);
815           return -1;
816         }
817
818       strncpy (addr.sun_path, path, path_len);
819     }
820
821   if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
822     {
823       dbus_set_error (error,
824                       _dbus_error_from_errno (errno),
825                       "Failed to connect to socket %s: %s",
826                       path, _dbus_strerror (errno));
827
828       _dbus_close (fd, NULL);
829       fd = -1;
830
831       return -1;
832     }
833
834   if (!_dbus_set_fd_nonblocking (fd, error))
835     {
836       _DBUS_ASSERT_ERROR_IS_SET (error);
837
838       _dbus_close (fd, NULL);
839       fd = -1;
840
841       return -1;
842     }
843
844   return fd;
845 }
846
847 /**
848  * Enables or disables the reception of credentials on the given socket during
849  * the next message transmission.  This is only effective if the #LOCAL_CREDS
850  * system feature exists, in which case the other side of the connection does
851  * not have to do anything special to send the credentials.
852  *
853  * @param fd socket on which to change the #LOCAL_CREDS flag.
854  * @param on whether to enable or disable the #LOCAL_CREDS flag.
855  */
856 static dbus_bool_t
857 _dbus_set_local_creds (int fd, dbus_bool_t on)
858 {
859   dbus_bool_t retval = TRUE;
860
861 #if defined(HAVE_CMSGCRED)
862   /* NOOP just to make sure only one codepath is used
863    *      and to prefer CMSGCRED
864    */
865 #elif defined(LOCAL_CREDS)
866   int val = on ? 1 : 0;
867   if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
868     {
869       _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
870       retval = FALSE;
871     }
872   else
873     _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
874                    on ? "enabled" : "disabled", fd);
875 #endif
876
877   return retval;
878 }
879
880 /**
881  * Creates a socket and binds it to the given path,
882  * then listens on the socket. The socket is
883  * set to be nonblocking.
884  *
885  * Uses abstract sockets instead of filesystem-linked
886  * sockets if requested (it's possible only on Linux;
887  * see "man 7 unix" on Linux).
888  * On non-Linux abstract socket usage always fails.
889  *
890  * This will set FD_CLOEXEC for the socket returned
891  *
892  * @param path the socket name
893  * @param abstract #TRUE to use abstract namespace
894  * @param error return location for errors
895  * @returns the listening file descriptor or -1 on error
896  */
897 int
898 _dbus_listen_unix_socket (const char     *path,
899                           dbus_bool_t     abstract,
900                           DBusError      *error)
901 {
902   int listen_fd;
903   struct sockaddr_un addr;
904   size_t path_len;
905   unsigned int reuseaddr;
906
907   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
908
909   _dbus_verbose ("listening on unix socket %s abstract=%d\n",
910                  path, abstract);
911
912   if (!_dbus_open_unix_socket (&listen_fd, error))
913     {
914       _DBUS_ASSERT_ERROR_IS_SET(error);
915       return -1;
916     }
917   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
918
919   _DBUS_ZERO (addr);
920   addr.sun_family = AF_UNIX;
921   path_len = strlen (path);
922
923   if (abstract)
924     {
925 #ifdef HAVE_ABSTRACT_SOCKETS
926       /* remember that abstract names aren't nul-terminated so we rely
927        * on sun_path being filled in with zeroes above.
928        */
929       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
930       path_len++; /* Account for the extra nul byte added to the start of sun_path */
931
932       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
933         {
934           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
935                       "Abstract socket name too long\n");
936           _dbus_close (listen_fd, NULL);
937           return -1;
938         }
939
940       strncpy (&addr.sun_path[1], path, path_len);
941       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
942 #else /* HAVE_ABSTRACT_SOCKETS */
943       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
944                       "Operating system does not support abstract socket namespace\n");
945       _dbus_close (listen_fd, NULL);
946       return -1;
947 #endif /* ! HAVE_ABSTRACT_SOCKETS */
948     }
949   else
950     {
951       /* Discussed security implications of this with Nalin,
952        * and we couldn't think of where it would kick our ass, but
953        * it still seems a bit sucky. It also has non-security suckage;
954        * really we'd prefer to exit if the socket is already in use.
955        * But there doesn't seem to be a good way to do this.
956        *
957        * Just to be extra careful, I threw in the stat() - clearly
958        * the stat() can't *fix* any security issue, but it at least
959        * avoids inadvertent/accidental data loss.
960        */
961       {
962         struct stat sb;
963
964         if (stat (path, &sb) == 0 &&
965             S_ISSOCK (sb.st_mode))
966           unlink (path);
967       }
968
969       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
970         {
971           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
972                       "Abstract socket name too long\n");
973           _dbus_close (listen_fd, NULL);
974           return -1;
975         }
976
977       strncpy (addr.sun_path, path, path_len);
978     }
979
980   reuseaddr = 1;
981   if (setsockopt  (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
982     {
983       _dbus_warn ("Failed to set socket option\"%s\": %s",
984                   path, _dbus_strerror (errno));
985     }
986
987   if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
988     {
989       dbus_set_error (error, _dbus_error_from_errno (errno),
990                       "Failed to bind socket \"%s\": %s",
991                       path, _dbus_strerror (errno));
992       _dbus_close (listen_fd, NULL);
993       return -1;
994     }
995
996   if (listen (listen_fd, 30 /* backlog */) < 0)
997     {
998       dbus_set_error (error, _dbus_error_from_errno (errno),
999                       "Failed to listen on socket \"%s\": %s",
1000                       path, _dbus_strerror (errno));
1001       _dbus_close (listen_fd, NULL);
1002       return -1;
1003     }
1004
1005   if (!_dbus_set_local_creds (listen_fd, TRUE))
1006     {
1007       dbus_set_error (error, _dbus_error_from_errno (errno),
1008                       "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
1009                       path, _dbus_strerror (errno));
1010       close (listen_fd);
1011       return -1;
1012     }
1013
1014   if (!_dbus_set_fd_nonblocking (listen_fd, error))
1015     {
1016       _DBUS_ASSERT_ERROR_IS_SET (error);
1017       _dbus_close (listen_fd, NULL);
1018       return -1;
1019     }
1020
1021   /* Try opening up the permissions, but if we can't, just go ahead
1022    * and continue, maybe it will be good enough.
1023    */
1024   if (!abstract && chmod (path, 0777) < 0)
1025     _dbus_warn ("Could not set mode 0777 on socket %s\n",
1026                 path);
1027
1028   return listen_fd;
1029 }
1030
1031 /**
1032  * Acquires one or more sockets passed in from systemd. The sockets
1033  * are set to be nonblocking.
1034  *
1035  * This will set FD_CLOEXEC for the sockets returned.
1036  *
1037  * @oaram fds the file descriptors
1038  * @param error return location for errors
1039  * @returns the number of file descriptors
1040  */
1041 int
1042 _dbus_listen_systemd_sockets (int       **fds,
1043                               DBusError *error)
1044 {
1045   int r, n;
1046   unsigned fd;
1047   int *new_fds;
1048
1049   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1050
1051   n = sd_listen_fds (TRUE);
1052   if (n < 0)
1053     {
1054       dbus_set_error (error, _dbus_error_from_errno (-n),
1055                       "Failed to acquire systemd socket: %s",
1056                       _dbus_strerror (-n));
1057       return -1;
1058     }
1059
1060   if (n <= 0)
1061     {
1062       dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1063                       "No socket received.");
1064       return -1;
1065     }
1066
1067   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1068     {
1069       r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1070       if (r < 0)
1071         {
1072           dbus_set_error (error, _dbus_error_from_errno (-r),
1073                           "Failed to verify systemd socket type: %s",
1074                           _dbus_strerror (-r));
1075           return -1;
1076         }
1077
1078       if (!r)
1079         {
1080           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1081                           "Passed socket has wrong type.");
1082           return -1;
1083         }
1084     }
1085
1086   /* OK, the file descriptors are all good, so let's take posession of
1087      them then. */
1088
1089   new_fds = dbus_new (int, n);
1090   if (!new_fds)
1091     {
1092       dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
1093                       "Failed to allocate file handle array.");
1094       goto fail;
1095     }
1096
1097   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1098     {
1099       if (!_dbus_set_local_creds (fd, TRUE))
1100         {
1101           dbus_set_error (error, _dbus_error_from_errno (errno),
1102                           "Failed to enable LOCAL_CREDS on systemd socket: %s",
1103                           _dbus_strerror (errno));
1104           goto fail;
1105         }
1106
1107       if (!_dbus_set_fd_nonblocking (fd, error))
1108         {
1109           _DBUS_ASSERT_ERROR_IS_SET (error);
1110           goto fail;
1111         }
1112
1113       new_fds[fd - SD_LISTEN_FDS_START] = fd;
1114     }
1115
1116   *fds = new_fds;
1117   return n;
1118
1119  fail:
1120
1121   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1122     {
1123       _dbus_close (fd, NULL);
1124     }
1125
1126   dbus_free (new_fds);
1127   return -1;
1128 }
1129
1130 /**
1131  * Creates a socket and connects to a socket at the given host
1132  * and port. The connection fd is returned, and is set up as
1133  * nonblocking.
1134  *
1135  * This will set FD_CLOEXEC for the socket returned
1136  *
1137  * @param host the host name to connect to
1138  * @param port the port to connect to
1139  * @param family the address family to listen on, NULL for all
1140  * @param error return location for error code
1141  * @returns connection file descriptor or -1 on error
1142  */
1143 int
1144 _dbus_connect_tcp_socket (const char     *host,
1145                           const char     *port,
1146                           const char     *family,
1147                           DBusError      *error)
1148 {
1149     return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1150 }
1151
1152 int
1153 _dbus_connect_tcp_socket_with_nonce (const char     *host,
1154                                      const char     *port,
1155                                      const char     *family,
1156                                      const char     *noncefile,
1157                                      DBusError      *error)
1158 {
1159   int saved_errno = 0;
1160   int fd = -1, res;
1161   struct addrinfo hints;
1162   struct addrinfo *ai, *tmp;
1163
1164   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1165
1166   if (!_dbus_open_tcp_socket (&fd, error))
1167     {
1168       _DBUS_ASSERT_ERROR_IS_SET(error);
1169       return -1;
1170     }
1171
1172   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1173
1174   _DBUS_ZERO (hints);
1175
1176   if (!family)
1177     hints.ai_family = AF_UNSPEC;
1178   else if (!strcmp(family, "ipv4"))
1179     hints.ai_family = AF_INET;
1180   else if (!strcmp(family, "ipv6"))
1181     hints.ai_family = AF_INET6;
1182   else
1183     {
1184       dbus_set_error (error,
1185                       DBUS_ERROR_BAD_ADDRESS,
1186                       "Unknown address family %s", family);
1187       return -1;
1188     }
1189   hints.ai_protocol = IPPROTO_TCP;
1190   hints.ai_socktype = SOCK_STREAM;
1191   hints.ai_flags = AI_ADDRCONFIG;
1192
1193   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1194     {
1195       dbus_set_error (error,
1196                       _dbus_error_from_errno (errno),
1197                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1198                       host, port, gai_strerror(res), res);
1199       _dbus_close (fd, NULL);
1200       return -1;
1201     }
1202
1203   tmp = ai;
1204   while (tmp)
1205     {
1206       if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1207         {
1208           freeaddrinfo(ai);
1209           _DBUS_ASSERT_ERROR_IS_SET(error);
1210           return -1;
1211         }
1212       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1213
1214       if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1215         {
1216           saved_errno = errno;
1217           _dbus_close(fd, NULL);
1218           fd = -1;
1219           tmp = tmp->ai_next;
1220           continue;
1221         }
1222
1223       break;
1224     }
1225   freeaddrinfo(ai);
1226
1227   if (fd == -1)
1228     {
1229       dbus_set_error (error,
1230                       _dbus_error_from_errno (saved_errno),
1231                       "Failed to connect to socket \"%s:%s\" %s",
1232                       host, port, _dbus_strerror(saved_errno));
1233       return -1;
1234     }
1235
1236   if (noncefile != NULL)
1237     {
1238       DBusString noncefileStr;
1239       dbus_bool_t ret;
1240       _dbus_string_init_const (&noncefileStr, noncefile);
1241       ret = _dbus_send_nonce (fd, &noncefileStr, error);
1242       _dbus_string_free (&noncefileStr);
1243
1244       if (!ret)
1245     {
1246       _dbus_close (fd, NULL);
1247           return -1;
1248         }
1249     }
1250
1251   if (!_dbus_set_fd_nonblocking (fd, error))
1252     {
1253       _dbus_close (fd, NULL);
1254       return -1;
1255     }
1256
1257   return fd;
1258 }
1259
1260 /**
1261  * Creates a socket and binds it to the given path, then listens on
1262  * the socket. The socket is set to be nonblocking.  In case of port=0
1263  * a random free port is used and returned in the port parameter.
1264  * If inaddr_any is specified, the hostname is ignored.
1265  *
1266  * This will set FD_CLOEXEC for the socket returned
1267  *
1268  * @param host the host name to listen on
1269  * @param port the port to listen on, if zero a free port will be used
1270  * @param family the address family to listen on, NULL for all
1271  * @param retport string to return the actual port listened on
1272  * @param fds_p location to store returned file descriptors
1273  * @param error return location for errors
1274  * @returns the number of listening file descriptors or -1 on error
1275  */
1276 int
1277 _dbus_listen_tcp_socket (const char     *host,
1278                          const char     *port,
1279                          const char     *family,
1280                          DBusString     *retport,
1281                          int           **fds_p,
1282                          DBusError      *error)
1283 {
1284   int saved_errno;
1285   int nlisten_fd = 0, *listen_fd = NULL, res, i;
1286   struct addrinfo hints;
1287   struct addrinfo *ai, *tmp;
1288   unsigned int reuseaddr;
1289
1290   *fds_p = NULL;
1291   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1292
1293   _DBUS_ZERO (hints);
1294
1295   if (!family)
1296     hints.ai_family = AF_UNSPEC;
1297   else if (!strcmp(family, "ipv4"))
1298     hints.ai_family = AF_INET;
1299   else if (!strcmp(family, "ipv6"))
1300     hints.ai_family = AF_INET6;
1301   else
1302     {
1303       dbus_set_error (error,
1304                       DBUS_ERROR_BAD_ADDRESS,
1305                       "Unknown address family %s", family);
1306       return -1;
1307     }
1308
1309   hints.ai_protocol = IPPROTO_TCP;
1310   hints.ai_socktype = SOCK_STREAM;
1311   hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1312
1313  redo_lookup_with_port:
1314   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1315     {
1316       dbus_set_error (error,
1317                       _dbus_error_from_errno (errno),
1318                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1319                       host ? host : "*", port, gai_strerror(res), res);
1320       return -1;
1321     }
1322
1323   tmp = ai;
1324   while (tmp)
1325     {
1326       int fd = -1, *newlisten_fd;
1327       if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1328         {
1329           _DBUS_ASSERT_ERROR_IS_SET(error);
1330           goto failed;
1331         }
1332       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1333
1334       reuseaddr = 1;
1335       if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1336         {
1337           _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1338                       host ? host : "*", port, _dbus_strerror (errno));
1339         }
1340
1341       if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1342         {
1343           saved_errno = errno;
1344           _dbus_close(fd, NULL);
1345           if (saved_errno == EADDRINUSE)
1346             {
1347               /* Depending on kernel policy, it may or may not
1348                  be neccessary to bind to both IPv4 & 6 addresses
1349                  so ignore EADDRINUSE here */
1350               tmp = tmp->ai_next;
1351               continue;
1352             }
1353           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1354                           "Failed to bind socket \"%s:%s\": %s",
1355                           host ? host : "*", port, _dbus_strerror (saved_errno));
1356           goto failed;
1357         }
1358
1359       if (listen (fd, 30 /* backlog */) < 0)
1360         {
1361           saved_errno = errno;
1362           _dbus_close (fd, NULL);
1363           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1364                           "Failed to listen on socket \"%s:%s\": %s",
1365                           host ? host : "*", port, _dbus_strerror (saved_errno));
1366           goto failed;
1367         }
1368
1369       newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
1370       if (!newlisten_fd)
1371         {
1372           saved_errno = errno;
1373           _dbus_close (fd, NULL);
1374           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1375                           "Failed to allocate file handle array: %s",
1376                           _dbus_strerror (saved_errno));
1377           goto failed;
1378         }
1379       listen_fd = newlisten_fd;
1380       listen_fd[nlisten_fd] = fd;
1381       nlisten_fd++;
1382
1383       if (!_dbus_string_get_length(retport))
1384         {
1385           /* If the user didn't specify a port, or used 0, then
1386              the kernel chooses a port. After the first address
1387              is bound to, we need to force all remaining addresses
1388              to use the same port */
1389           if (!port || !strcmp(port, "0"))
1390             {
1391               struct sockaddr_storage addr;
1392               socklen_t addrlen;
1393               char portbuf[50];
1394
1395               addrlen = sizeof(addr);
1396               getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1397
1398               if ((res = getnameinfo((struct sockaddr*)&addr, addrlen, NULL, 0,
1399                                      portbuf, sizeof(portbuf),
1400                                      NI_NUMERICHOST)) != 0)
1401                 {
1402                   dbus_set_error (error, _dbus_error_from_errno (errno),
1403                                   "Failed to resolve port \"%s:%s\": %s (%s)",
1404                                   host ? host : "*", port, gai_strerror(res), res);
1405                   goto failed;
1406                 }
1407               if (!_dbus_string_append(retport, portbuf))
1408                 {
1409                   dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1410                   goto failed;
1411                 }
1412
1413               /* Release current address list & redo lookup */
1414               port = _dbus_string_get_const_data(retport);
1415               freeaddrinfo(ai);
1416               goto redo_lookup_with_port;
1417             }
1418           else
1419             {
1420               if (!_dbus_string_append(retport, port))
1421                 {
1422                     dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1423                     goto failed;
1424                 }
1425             }
1426         }
1427
1428       tmp = tmp->ai_next;
1429     }
1430   freeaddrinfo(ai);
1431   ai = NULL;
1432
1433   if (!nlisten_fd)
1434     {
1435       errno = EADDRINUSE;
1436       dbus_set_error (error, _dbus_error_from_errno (errno),
1437                       "Failed to bind socket \"%s:%s\": %s",
1438                       host ? host : "*", port, _dbus_strerror (errno));
1439       return -1;
1440     }
1441
1442   for (i = 0 ; i < nlisten_fd ; i++)
1443     {
1444       if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1445         {
1446           goto failed;
1447         }
1448     }
1449
1450   *fds_p = listen_fd;
1451
1452   return nlisten_fd;
1453
1454  failed:
1455   if (ai)
1456     freeaddrinfo(ai);
1457   for (i = 0 ; i < nlisten_fd ; i++)
1458     _dbus_close(listen_fd[i], NULL);
1459   dbus_free(listen_fd);
1460   return -1;
1461 }
1462
1463 static dbus_bool_t
1464 write_credentials_byte (int             server_fd,
1465                         DBusError      *error)
1466 {
1467   int bytes_written;
1468   char buf[1] = { '\0' };
1469 #if defined(HAVE_CMSGCRED)
1470   union {
1471           struct cmsghdr hdr;
1472           char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1473   } cmsg;
1474   struct iovec iov;
1475   struct msghdr msg;
1476   iov.iov_base = buf;
1477   iov.iov_len = 1;
1478
1479   _DBUS_ZERO(msg);
1480   msg.msg_iov = &iov;
1481   msg.msg_iovlen = 1;
1482
1483   msg.msg_control = (caddr_t) &cmsg;
1484   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1485   _DBUS_ZERO(cmsg);
1486   cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1487   cmsg.hdr.cmsg_level = SOL_SOCKET;
1488   cmsg.hdr.cmsg_type = SCM_CREDS;
1489 #endif
1490
1491   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1492
1493  again:
1494
1495 #if defined(HAVE_CMSGCRED)
1496   bytes_written = sendmsg (server_fd, &msg, 0
1497 #ifdef HAVE_DECL_MSG_NOSIGNAL
1498                            |MSG_NOSIGNAL
1499 #endif
1500                            );
1501 #else
1502   bytes_written = send (server_fd, buf, 1, 0
1503 #ifdef HAVE_DECL_MSG_NOSIGNAL
1504                         |MSG_NOSIGNAL
1505 #endif
1506                         );
1507 #endif
1508
1509   if (bytes_written < 0 && errno == EINTR)
1510     goto again;
1511
1512   if (bytes_written < 0)
1513     {
1514       dbus_set_error (error, _dbus_error_from_errno (errno),
1515                       "Failed to write credentials byte: %s",
1516                      _dbus_strerror (errno));
1517       return FALSE;
1518     }
1519   else if (bytes_written == 0)
1520     {
1521       dbus_set_error (error, DBUS_ERROR_IO_ERROR,
1522                       "wrote zero bytes writing credentials byte");
1523       return FALSE;
1524     }
1525   else
1526     {
1527       _dbus_assert (bytes_written == 1);
1528       _dbus_verbose ("wrote credentials byte\n");
1529       return TRUE;
1530     }
1531 }
1532
1533 /**
1534  * Reads a single byte which must be nul (an error occurs otherwise),
1535  * and reads unix credentials if available. Clears the credentials
1536  * object, then adds pid/uid if available, so any previous credentials
1537  * stored in the object are lost.
1538  *
1539  * Return value indicates whether a byte was read, not whether
1540  * we got valid credentials. On some systems, such as Linux,
1541  * reading/writing the byte isn't actually required, but we do it
1542  * anyway just to avoid multiple codepaths.
1543  *
1544  * Fails if no byte is available, so you must select() first.
1545  *
1546  * The point of the byte is that on some systems we have to
1547  * use sendmsg()/recvmsg() to transmit credentials.
1548  *
1549  * @param client_fd the client file descriptor
1550  * @param credentials object to add client credentials to
1551  * @param error location to store error code
1552  * @returns #TRUE on success
1553  */
1554 dbus_bool_t
1555 _dbus_read_credentials_socket  (int              client_fd,
1556                                 DBusCredentials *credentials,
1557                                 DBusError       *error)
1558 {
1559   struct msghdr msg;
1560   struct iovec iov;
1561   char buf;
1562   dbus_uid_t uid_read;
1563   dbus_pid_t pid_read;
1564   int bytes_read;
1565
1566 #ifdef HAVE_CMSGCRED
1567   union {
1568     struct cmsghdr hdr;
1569     char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1570   } cmsg;
1571
1572 #elif defined(LOCAL_CREDS)
1573   struct {
1574     struct cmsghdr hdr;
1575     struct sockcred cred;
1576   } cmsg;
1577 #endif
1578
1579   uid_read = DBUS_UID_UNSET;
1580   pid_read = DBUS_PID_UNSET;
1581
1582   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1583
1584   /* The POSIX spec certainly doesn't promise this, but
1585    * we need these assertions to fail as soon as we're wrong about
1586    * it so we can do the porting fixups
1587    */
1588   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1589   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1590   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1591
1592   _dbus_credentials_clear (credentials);
1593
1594   /* Systems supporting LOCAL_CREDS are configured to have this feature
1595    * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
1596    * the connection.  Therefore, the received message must carry the
1597    * credentials information without doing anything special.
1598    */
1599
1600   iov.iov_base = &buf;
1601   iov.iov_len = 1;
1602
1603   _DBUS_ZERO(msg);
1604   msg.msg_iov = &iov;
1605   msg.msg_iovlen = 1;
1606
1607 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1608   _DBUS_ZERO(cmsg);
1609   msg.msg_control = (caddr_t) &cmsg;
1610   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1611 #endif
1612
1613  again:
1614   bytes_read = recvmsg (client_fd, &msg, 0);
1615
1616   if (bytes_read < 0)
1617     {
1618       if (errno == EINTR)
1619         goto again;
1620
1621       /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1622        * normally only call read_credentials if the socket was ready
1623        * for reading
1624        */
1625
1626       dbus_set_error (error, _dbus_error_from_errno (errno),
1627                       "Failed to read credentials byte: %s",
1628                       _dbus_strerror (errno));
1629       return FALSE;
1630     }
1631   else if (bytes_read == 0)
1632     {
1633       /* this should not happen unless we are using recvmsg wrong,
1634        * so is essentially here for paranoia
1635        */
1636       dbus_set_error (error, DBUS_ERROR_FAILED,
1637                       "Failed to read credentials byte (zero-length read)");
1638       return FALSE;
1639     }
1640   else if (buf != '\0')
1641     {
1642       dbus_set_error (error, DBUS_ERROR_FAILED,
1643                       "Credentials byte was not nul");
1644       return FALSE;
1645     }
1646
1647 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1648   if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
1649                   || cmsg.hdr.cmsg_type != SCM_CREDS)
1650     {
1651       dbus_set_error (error, DBUS_ERROR_FAILED,
1652                       "Message from recvmsg() was not SCM_CREDS");
1653       return FALSE;
1654     }
1655 #endif
1656
1657   _dbus_verbose ("read credentials byte\n");
1658
1659   {
1660 #ifdef SO_PEERCRED
1661     struct ucred cr;
1662     int cr_len = sizeof (cr);
1663
1664     if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1665         cr_len == sizeof (cr))
1666       {
1667         pid_read = cr.pid;
1668         uid_read = cr.uid;
1669       }
1670     else
1671       {
1672         _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1673                        cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1674       }
1675 #elif defined(HAVE_CMSGCRED)
1676     struct cmsgcred *cred;
1677
1678     cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
1679     pid_read = cred->cmcred_pid;
1680     uid_read = cred->cmcred_euid;
1681 #elif defined(LOCAL_CREDS)
1682     pid_read = DBUS_PID_UNSET;
1683     uid_read = cmsg.cred.sc_uid;
1684     /* Since we have already got the credentials from this socket, we can
1685      * disable its LOCAL_CREDS flag if it was ever set. */
1686     _dbus_set_local_creds (client_fd, FALSE);
1687 #elif defined(HAVE_GETPEEREID)
1688     uid_t euid;
1689     gid_t egid;
1690     if (getpeereid (client_fd, &euid, &egid) == 0)
1691       {
1692         uid_read = euid;
1693       }
1694     else
1695       {
1696         _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1697       }
1698 #elif defined(HAVE_GETPEERUCRED)
1699     ucred_t * ucred = NULL;
1700     if (getpeerucred (client_fd, &ucred) == 0)
1701       {
1702         pid_read = ucred_getpid (ucred);
1703         uid_read = ucred_geteuid (ucred);
1704 #ifdef HAVE_ADT
1705         /* generate audit session data based on socket ucred */
1706         adt_session_data_t *adth = NULL;
1707         adt_export_data_t *data = NULL;
1708         size_t size = 0;
1709         if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1710           {
1711             _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1712           }
1713         else
1714           {
1715             if (adt_set_from_ucred (adth, ucred, ADT_NEW))
1716               {
1717                 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1718               }
1719             else
1720               {
1721                 size = adt_export_session_data (adth, &data);
1722                 if (size <= 0)
1723                   {
1724                     _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
1725                   }
1726                 else
1727                   {
1728                     _dbus_credentials_add_adt_audit_data (credentials, data, size);
1729                     free (data);
1730                   }
1731               }
1732             (void) adt_end_session (adth);
1733           }
1734 #endif /* HAVE_ADT */
1735       }
1736     else
1737       {
1738         _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1739       }
1740     if (ucred != NULL)
1741       ucred_free (ucred);
1742 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
1743     _dbus_verbose ("Socket credentials not supported on this OS\n");
1744 #endif
1745   }
1746
1747   _dbus_verbose ("Credentials:"
1748                  "  pid "DBUS_PID_FORMAT
1749                  "  uid "DBUS_UID_FORMAT
1750                  "\n",
1751                  pid_read,
1752                  uid_read);
1753
1754   if (pid_read != DBUS_PID_UNSET)
1755     {
1756       if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
1757         {
1758           _DBUS_SET_OOM (error);
1759           return FALSE;
1760         }
1761     }
1762
1763   if (uid_read != DBUS_UID_UNSET)
1764     {
1765       if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
1766         {
1767           _DBUS_SET_OOM (error);
1768           return FALSE;
1769         }
1770     }
1771
1772   return TRUE;
1773 }
1774
1775 /**
1776  * Sends a single nul byte with our UNIX credentials as ancillary
1777  * data.  Returns #TRUE if the data was successfully written.  On
1778  * systems that don't support sending credentials, just writes a byte,
1779  * doesn't send any credentials.  On some systems, such as Linux,
1780  * reading/writing the byte isn't actually required, but we do it
1781  * anyway just to avoid multiple codepaths.
1782  *
1783  * Fails if no byte can be written, so you must select() first.
1784  *
1785  * The point of the byte is that on some systems we have to
1786  * use sendmsg()/recvmsg() to transmit credentials.
1787  *
1788  * @param server_fd file descriptor for connection to server
1789  * @param error return location for error code
1790  * @returns #TRUE if the byte was sent
1791  */
1792 dbus_bool_t
1793 _dbus_send_credentials_socket  (int              server_fd,
1794                                 DBusError       *error)
1795 {
1796   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1797
1798   if (write_credentials_byte (server_fd, error))
1799     return TRUE;
1800   else
1801     return FALSE;
1802 }
1803
1804 /**
1805  * Accepts a connection on a listening socket.
1806  * Handles EINTR for you.
1807  *
1808  * This will enable FD_CLOEXEC for the returned socket.
1809  *
1810  * @param listen_fd the listen file descriptor
1811  * @returns the connection fd of the client, or -1 on error
1812  */
1813 int
1814 _dbus_accept  (int listen_fd)
1815 {
1816   int client_fd;
1817   struct sockaddr addr;
1818   socklen_t addrlen;
1819 #ifdef HAVE_ACCEPT4
1820   dbus_bool_t cloexec_done;
1821 #endif
1822
1823   addrlen = sizeof (addr);
1824
1825  retry:
1826
1827 #ifdef HAVE_ACCEPT4
1828   /* We assume that if accept4 is available SOCK_CLOEXEC is too */
1829   client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
1830   cloexec_done = client_fd >= 0;
1831
1832   if (client_fd < 0 && errno == ENOSYS)
1833 #endif
1834     {
1835       client_fd = accept (listen_fd, &addr, &addrlen);
1836     }
1837
1838   if (client_fd < 0)
1839     {
1840       if (errno == EINTR)
1841         goto retry;
1842     }
1843
1844   _dbus_verbose ("client fd %d accepted\n", client_fd);
1845
1846 #ifdef HAVE_ACCEPT4
1847   if (!cloexec_done)
1848 #endif
1849     {
1850       _dbus_fd_set_close_on_exec(client_fd);
1851     }
1852
1853   return client_fd;
1854 }
1855
1856 /**
1857  * Checks to make sure the given directory is
1858  * private to the user
1859  *
1860  * @param dir the name of the directory
1861  * @param error error return
1862  * @returns #FALSE on failure
1863  **/
1864 dbus_bool_t
1865 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
1866 {
1867   const char *directory;
1868   struct stat sb;
1869
1870   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1871
1872   directory = _dbus_string_get_const_data (dir);
1873
1874   if (stat (directory, &sb) < 0)
1875     {
1876       dbus_set_error (error, _dbus_error_from_errno (errno),
1877                       "%s", _dbus_strerror (errno));
1878
1879       return FALSE;
1880     }
1881
1882   if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
1883       (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
1884     {
1885       dbus_set_error (error, DBUS_ERROR_FAILED,
1886                      "%s directory is not private to the user", directory);
1887       return FALSE;
1888     }
1889
1890   return TRUE;
1891 }
1892
1893 static dbus_bool_t
1894 fill_user_info_from_passwd (struct passwd *p,
1895                             DBusUserInfo  *info,
1896                             DBusError     *error)
1897 {
1898   _dbus_assert (p->pw_name != NULL);
1899   _dbus_assert (p->pw_dir != NULL);
1900
1901   info->uid = p->pw_uid;
1902   info->primary_gid = p->pw_gid;
1903   info->username = _dbus_strdup (p->pw_name);
1904   info->homedir = _dbus_strdup (p->pw_dir);
1905
1906   if (info->username == NULL ||
1907       info->homedir == NULL)
1908     {
1909       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1910       return FALSE;
1911     }
1912
1913   return TRUE;
1914 }
1915
1916 static dbus_bool_t
1917 fill_user_info (DBusUserInfo       *info,
1918                 dbus_uid_t          uid,
1919                 const DBusString   *username,
1920                 DBusError          *error)
1921 {
1922   const char *username_c;
1923
1924   /* exactly one of username/uid provided */
1925   _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
1926   _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
1927
1928   info->uid = DBUS_UID_UNSET;
1929   info->primary_gid = DBUS_GID_UNSET;
1930   info->group_ids = NULL;
1931   info->n_group_ids = 0;
1932   info->username = NULL;
1933   info->homedir = NULL;
1934
1935   if (username != NULL)
1936     username_c = _dbus_string_get_const_data (username);
1937   else
1938     username_c = NULL;
1939
1940   /* For now assuming that the getpwnam() and getpwuid() flavors
1941    * are always symmetrical, if not we have to add more configure
1942    * checks
1943    */
1944
1945 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
1946   {
1947     struct passwd *p;
1948     int result;
1949     size_t buflen;
1950     char *buf;
1951     struct passwd p_str;
1952
1953     /* retrieve maximum needed size for buf */
1954     buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
1955
1956     /* sysconf actually returns a long, but everything else expects size_t,
1957      * so just recast here.
1958      * https://bugs.freedesktop.org/show_bug.cgi?id=17061
1959      */
1960     if ((long) buflen <= 0)
1961       buflen = 1024;
1962
1963     result = -1;
1964     while (1)
1965       {
1966         buf = dbus_malloc (buflen);
1967         if (buf == NULL)
1968           {
1969             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1970             return FALSE;
1971           }
1972
1973         p = NULL;
1974 #ifdef HAVE_POSIX_GETPWNAM_R
1975         if (uid != DBUS_UID_UNSET)
1976           result = getpwuid_r (uid, &p_str, buf, buflen,
1977                                &p);
1978         else
1979           result = getpwnam_r (username_c, &p_str, buf, buflen,
1980                                &p);
1981 #else
1982         if (uid != DBUS_UID_UNSET)
1983           p = getpwuid_r (uid, &p_str, buf, buflen);
1984         else
1985           p = getpwnam_r (username_c, &p_str, buf, buflen);
1986         result = 0;
1987 #endif /* !HAVE_POSIX_GETPWNAM_R */
1988         //Try a bigger buffer if ERANGE was returned
1989         if (result == ERANGE && buflen < 512 * 1024)
1990           {
1991             dbus_free (buf);
1992             buflen *= 2;
1993           }
1994         else
1995           {
1996             break;
1997           }
1998       }
1999     if (result == 0 && p == &p_str)
2000       {
2001         if (!fill_user_info_from_passwd (p, info, error))
2002           {
2003             dbus_free (buf);
2004             return FALSE;
2005           }
2006         dbus_free (buf);
2007       }
2008     else
2009       {
2010         dbus_set_error (error, _dbus_error_from_errno (errno),
2011                         "User \"%s\" unknown or no memory to allocate password entry\n",
2012                         username_c ? username_c : "???");
2013         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2014         dbus_free (buf);
2015         return FALSE;
2016       }
2017   }
2018 #else /* ! HAVE_GETPWNAM_R */
2019   {
2020     /* I guess we're screwed on thread safety here */
2021     struct passwd *p;
2022
2023     if (uid != DBUS_UID_UNSET)
2024       p = getpwuid (uid);
2025     else
2026       p = getpwnam (username_c);
2027
2028     if (p != NULL)
2029       {
2030         if (!fill_user_info_from_passwd (p, info, error))
2031           {
2032             return FALSE;
2033           }
2034       }
2035     else
2036       {
2037         dbus_set_error (error, _dbus_error_from_errno (errno),
2038                         "User \"%s\" unknown or no memory to allocate password entry\n",
2039                         username_c ? username_c : "???");
2040         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2041         return FALSE;
2042       }
2043   }
2044 #endif  /* ! HAVE_GETPWNAM_R */
2045
2046   /* Fill this in so we can use it to get groups */
2047   username_c = info->username;
2048
2049 #ifdef HAVE_GETGROUPLIST
2050   {
2051     gid_t *buf;
2052     int buf_count;
2053     int i;
2054     int initial_buf_count;
2055
2056     initial_buf_count = 17;
2057     buf_count = initial_buf_count;
2058     buf = dbus_new (gid_t, buf_count);
2059     if (buf == NULL)
2060       {
2061         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2062         goto failed;
2063       }
2064
2065     if (getgrouplist (username_c,
2066                       info->primary_gid,
2067                       buf, &buf_count) < 0)
2068       {
2069         gid_t *new;
2070         /* Presumed cause of negative return code: buf has insufficient
2071            entries to hold the entire group list. The Linux behavior in this
2072            case is to pass back the actual number of groups in buf_count, but
2073            on Mac OS X 10.5, buf_count is unhelpfully left alone.
2074            So as a hack, try to help out a bit by guessing a larger
2075            number of groups, within reason.. might still fail, of course,
2076            but we can at least print a more informative message.  I looked up
2077            the "right way" to do this by downloading Apple's own source code
2078            for the "id" command, and it turns out that they use an
2079            undocumented library function getgrouplist_2 (!) which is not
2080            declared in any header in /usr/include (!!). That did not seem
2081            like the way to go here.
2082         */
2083         if (buf_count == initial_buf_count)
2084           {
2085             buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2086           }
2087         new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2088         if (new == NULL)
2089           {
2090             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2091             dbus_free (buf);
2092             goto failed;
2093           }
2094
2095         buf = new;
2096
2097         errno = 0;
2098         if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2099           {
2100             if (errno == 0)
2101               {
2102                 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2103                             username_c, buf_count, buf_count);
2104               }
2105             else
2106               {
2107                 dbus_set_error (error,
2108                                 _dbus_error_from_errno (errno),
2109                                 "Failed to get groups for username \"%s\" primary GID "
2110                                 DBUS_GID_FORMAT ": %s\n",
2111                                 username_c, info->primary_gid,
2112                                 _dbus_strerror (errno));
2113                 dbus_free (buf);
2114                 goto failed;
2115               }
2116           }
2117       }
2118
2119     info->group_ids = dbus_new (dbus_gid_t, buf_count);
2120     if (info->group_ids == NULL)
2121       {
2122         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2123         dbus_free (buf);
2124         goto failed;
2125       }
2126
2127     for (i = 0; i < buf_count; ++i)
2128       info->group_ids[i] = buf[i];
2129
2130     info->n_group_ids = buf_count;
2131
2132     dbus_free (buf);
2133   }
2134 #else  /* HAVE_GETGROUPLIST */
2135   {
2136     /* We just get the one group ID */
2137     info->group_ids = dbus_new (dbus_gid_t, 1);
2138     if (info->group_ids == NULL)
2139       {
2140         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2141         goto failed;
2142       }
2143
2144     info->n_group_ids = 1;
2145
2146     (info->group_ids)[0] = info->primary_gid;
2147   }
2148 #endif /* HAVE_GETGROUPLIST */
2149
2150   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2151
2152   return TRUE;
2153
2154  failed:
2155   _DBUS_ASSERT_ERROR_IS_SET (error);
2156   return FALSE;
2157 }
2158
2159 /**
2160  * Gets user info for the given username.
2161  *
2162  * @param info user info object to initialize
2163  * @param username the username
2164  * @param error error return
2165  * @returns #TRUE on success
2166  */
2167 dbus_bool_t
2168 _dbus_user_info_fill (DBusUserInfo     *info,
2169                       const DBusString *username,
2170                       DBusError        *error)
2171 {
2172   return fill_user_info (info, DBUS_UID_UNSET,
2173                          username, error);
2174 }
2175
2176 /**
2177  * Gets user info for the given user ID.
2178  *
2179  * @param info user info object to initialize
2180  * @param uid the user ID
2181  * @param error error return
2182  * @returns #TRUE on success
2183  */
2184 dbus_bool_t
2185 _dbus_user_info_fill_uid (DBusUserInfo *info,
2186                           dbus_uid_t    uid,
2187                           DBusError    *error)
2188 {
2189   return fill_user_info (info, uid,
2190                          NULL, error);
2191 }
2192
2193 /**
2194  * Adds the credentials of the current process to the
2195  * passed-in credentials object.
2196  *
2197  * @param credentials credentials to add to
2198  * @returns #FALSE if no memory; does not properly roll back on failure, so only some credentials may have been added
2199  */
2200 dbus_bool_t
2201 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
2202 {
2203   /* The POSIX spec certainly doesn't promise this, but
2204    * we need these assertions to fail as soon as we're wrong about
2205    * it so we can do the porting fixups
2206    */
2207   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
2208   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
2209   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
2210
2211   if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
2212     return FALSE;
2213   if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2214     return FALSE;
2215
2216   return TRUE;
2217 }
2218
2219 /**
2220  * Append to the string the identity we would like to have when we
2221  * authenticate, on UNIX this is the current process UID and on
2222  * Windows something else, probably a Windows SID string.  No escaping
2223  * is required, that is done in dbus-auth.c. The username here
2224  * need not be anything human-readable, it can be the machine-readable
2225  * form i.e. a user id.
2226  *
2227  * @param str the string to append to
2228  * @returns #FALSE on no memory
2229  */
2230 dbus_bool_t
2231 _dbus_append_user_from_current_process (DBusString *str)
2232 {
2233   return _dbus_string_append_uint (str,
2234                                    _dbus_geteuid ());
2235 }
2236
2237 /**
2238  * Gets our process ID
2239  * @returns process ID
2240  */
2241 dbus_pid_t
2242 _dbus_getpid (void)
2243 {
2244   return getpid ();
2245 }
2246
2247 /** Gets our UID
2248  * @returns process UID
2249  */
2250 dbus_uid_t
2251 _dbus_getuid (void)
2252 {
2253   return getuid ();
2254 }
2255
2256 /** Gets our effective UID
2257  * @returns process effective UID
2258  */
2259 dbus_uid_t
2260 _dbus_geteuid (void)
2261 {
2262   return geteuid ();
2263 }
2264
2265 /**
2266  * The only reason this is separate from _dbus_getpid() is to allow it
2267  * on Windows for logging but not for other purposes.
2268  *
2269  * @returns process ID to put in log messages
2270  */
2271 unsigned long
2272 _dbus_pid_for_log (void)
2273 {
2274   return getpid ();
2275 }
2276
2277 /**
2278  * Gets a UID from a UID string.
2279  *
2280  * @param uid_str the UID in string form
2281  * @param uid UID to fill in
2282  * @returns #TRUE if successfully filled in UID
2283  */
2284 dbus_bool_t
2285 _dbus_parse_uid (const DBusString      *uid_str,
2286                  dbus_uid_t            *uid)
2287 {
2288   int end;
2289   long val;
2290
2291   if (_dbus_string_get_length (uid_str) == 0)
2292     {
2293       _dbus_verbose ("UID string was zero length\n");
2294       return FALSE;
2295     }
2296
2297   val = -1;
2298   end = 0;
2299   if (!_dbus_string_parse_int (uid_str, 0, &val,
2300                                &end))
2301     {
2302       _dbus_verbose ("could not parse string as a UID\n");
2303       return FALSE;
2304     }
2305
2306   if (end != _dbus_string_get_length (uid_str))
2307     {
2308       _dbus_verbose ("string contained trailing stuff after UID\n");
2309       return FALSE;
2310     }
2311
2312   *uid = val;
2313
2314   return TRUE;
2315 }
2316
2317 #if !DBUS_USE_SYNC
2318 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
2319 #endif
2320
2321 /**
2322  * Atomically increments an integer
2323  *
2324  * @param atomic pointer to the integer to increment
2325  * @returns the value before incrementing
2326  */
2327 dbus_int32_t
2328 _dbus_atomic_inc (DBusAtomic *atomic)
2329 {
2330 #if DBUS_USE_SYNC
2331   return __sync_add_and_fetch(&atomic->value, 1)-1;
2332 #else
2333   dbus_int32_t res;
2334   _DBUS_LOCK (atomic);
2335   res = atomic->value;
2336   atomic->value += 1;
2337   _DBUS_UNLOCK (atomic);
2338   return res;
2339 #endif
2340 }
2341
2342 /**
2343  * Atomically decrement an integer
2344  *
2345  * @param atomic pointer to the integer to decrement
2346  * @returns the value before decrementing
2347  */
2348 dbus_int32_t
2349 _dbus_atomic_dec (DBusAtomic *atomic)
2350 {
2351 #if DBUS_USE_SYNC
2352   return __sync_sub_and_fetch(&atomic->value, 1)+1;
2353 #else
2354   dbus_int32_t res;
2355
2356   _DBUS_LOCK (atomic);
2357   res = atomic->value;
2358   atomic->value -= 1;
2359   _DBUS_UNLOCK (atomic);
2360   return res;
2361 #endif
2362 }
2363
2364 #ifdef DBUS_BUILD_TESTS
2365 /** Gets our GID
2366  * @returns process GID
2367  */
2368 dbus_gid_t
2369 _dbus_getgid (void)
2370 {
2371   return getgid ();
2372 }
2373 #endif
2374
2375 /**
2376  * Wrapper for poll().
2377  *
2378  * @param fds the file descriptors to poll
2379  * @param n_fds number of descriptors in the array
2380  * @param timeout_milliseconds timeout or -1 for infinite
2381  * @returns numbers of fds with revents, or <0 on error
2382  */
2383 int
2384 _dbus_poll (DBusPollFD *fds,
2385             int         n_fds,
2386             int         timeout_milliseconds)
2387 {
2388 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2389   /* This big thing is a constant expression and should get optimized
2390    * out of existence. So it's more robust than a configure check at
2391    * no cost.
2392    */
2393   if (_DBUS_POLLIN == POLLIN &&
2394       _DBUS_POLLPRI == POLLPRI &&
2395       _DBUS_POLLOUT == POLLOUT &&
2396       _DBUS_POLLERR == POLLERR &&
2397       _DBUS_POLLHUP == POLLHUP &&
2398       _DBUS_POLLNVAL == POLLNVAL &&
2399       sizeof (DBusPollFD) == sizeof (struct pollfd) &&
2400       _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
2401       _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
2402       _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
2403       _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
2404       _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
2405       _DBUS_STRUCT_OFFSET (struct pollfd, revents))
2406     {
2407       return poll ((struct pollfd*) fds,
2408                    n_fds,
2409                    timeout_milliseconds);
2410     }
2411   else
2412     {
2413       /* We have to convert the DBusPollFD to an array of
2414        * struct pollfd, poll, and convert back.
2415        */
2416       _dbus_warn ("didn't implement poll() properly for this system yet\n");
2417       return -1;
2418     }
2419 #else /* ! HAVE_POLL */
2420
2421   fd_set read_set, write_set, err_set;
2422   int max_fd = 0;
2423   int i;
2424   struct timeval tv;
2425   int ready;
2426
2427   FD_ZERO (&read_set);
2428   FD_ZERO (&write_set);
2429   FD_ZERO (&err_set);
2430
2431   for (i = 0; i < n_fds; i++)
2432     {
2433       DBusPollFD *fdp = &fds[i];
2434
2435       if (fdp->events & _DBUS_POLLIN)
2436         FD_SET (fdp->fd, &read_set);
2437
2438       if (fdp->events & _DBUS_POLLOUT)
2439         FD_SET (fdp->fd, &write_set);
2440
2441       FD_SET (fdp->fd, &err_set);
2442
2443       max_fd = MAX (max_fd, fdp->fd);
2444     }
2445
2446   tv.tv_sec = timeout_milliseconds / 1000;
2447   tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2448
2449   ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2450                   timeout_milliseconds < 0 ? NULL : &tv);
2451
2452   if (ready > 0)
2453     {
2454       for (i = 0; i < n_fds; i++)
2455         {
2456           DBusPollFD *fdp = &fds[i];
2457
2458           fdp->revents = 0;
2459
2460           if (FD_ISSET (fdp->fd, &read_set))
2461             fdp->revents |= _DBUS_POLLIN;
2462
2463           if (FD_ISSET (fdp->fd, &write_set))
2464             fdp->revents |= _DBUS_POLLOUT;
2465
2466           if (FD_ISSET (fdp->fd, &err_set))
2467             fdp->revents |= _DBUS_POLLERR;
2468         }
2469     }
2470
2471   return ready;
2472 #endif
2473 }
2474
2475 /**
2476  * Get current time, as in gettimeofday(). Use the monotonic clock if
2477  * available, to avoid problems when the system time changes.
2478  *
2479  * @param tv_sec return location for number of seconds
2480  * @param tv_usec return location for number of microseconds (thousandths)
2481  */
2482 void
2483 _dbus_get_current_time (long *tv_sec,
2484                         long *tv_usec)
2485 {
2486   struct timeval t;
2487
2488 #ifdef HAVE_MONOTONIC_CLOCK
2489   struct timespec ts;
2490   clock_gettime (CLOCK_MONOTONIC, &ts);
2491
2492   if (tv_sec)
2493     *tv_sec = ts.tv_sec;
2494   if (tv_usec)
2495     *tv_usec = ts.tv_nsec / 1000;
2496 #else
2497   gettimeofday (&t, NULL);
2498
2499   if (tv_sec)
2500     *tv_sec = t.tv_sec;
2501   if (tv_usec)
2502     *tv_usec = t.tv_usec;
2503 #endif
2504 }
2505
2506 /**
2507  * Creates a directory; succeeds if the directory
2508  * is created or already existed.
2509  *
2510  * @param filename directory filename
2511  * @param error initialized error object
2512  * @returns #TRUE on success
2513  */
2514 dbus_bool_t
2515 _dbus_create_directory (const DBusString *filename,
2516                         DBusError        *error)
2517 {
2518   const char *filename_c;
2519
2520   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2521
2522   filename_c = _dbus_string_get_const_data (filename);
2523
2524   if (mkdir (filename_c, 0700) < 0)
2525     {
2526       if (errno == EEXIST)
2527         return TRUE;
2528
2529       dbus_set_error (error, DBUS_ERROR_FAILED,
2530                       "Failed to create directory %s: %s\n",
2531                       filename_c, _dbus_strerror (errno));
2532       return FALSE;
2533     }
2534   else
2535     return TRUE;
2536 }
2537
2538 /**
2539  * Appends the given filename to the given directory.
2540  *
2541  * @todo it might be cute to collapse multiple '/' such as "foo//"
2542  * concat "//bar"
2543  *
2544  * @param dir the directory name
2545  * @param next_component the filename
2546  * @returns #TRUE on success
2547  */
2548 dbus_bool_t
2549 _dbus_concat_dir_and_file (DBusString       *dir,
2550                            const DBusString *next_component)
2551 {
2552   dbus_bool_t dir_ends_in_slash;
2553   dbus_bool_t file_starts_with_slash;
2554
2555   if (_dbus_string_get_length (dir) == 0 ||
2556       _dbus_string_get_length (next_component) == 0)
2557     return TRUE;
2558
2559   dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2560                                                     _dbus_string_get_length (dir) - 1);
2561
2562   file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2563
2564   if (dir_ends_in_slash && file_starts_with_slash)
2565     {
2566       _dbus_string_shorten (dir, 1);
2567     }
2568   else if (!(dir_ends_in_slash || file_starts_with_slash))
2569     {
2570       if (!_dbus_string_append_byte (dir, '/'))
2571         return FALSE;
2572     }
2573
2574   return _dbus_string_copy (next_component, 0, dir,
2575                             _dbus_string_get_length (dir));
2576 }
2577
2578 /** nanoseconds in a second */
2579 #define NANOSECONDS_PER_SECOND       1000000000
2580 /** microseconds in a second */
2581 #define MICROSECONDS_PER_SECOND      1000000
2582 /** milliseconds in a second */
2583 #define MILLISECONDS_PER_SECOND      1000
2584 /** nanoseconds in a millisecond */
2585 #define NANOSECONDS_PER_MILLISECOND  1000000
2586 /** microseconds in a millisecond */
2587 #define MICROSECONDS_PER_MILLISECOND 1000
2588
2589 /**
2590  * Sleeps the given number of milliseconds.
2591  * @param milliseconds number of milliseconds
2592  */
2593 void
2594 _dbus_sleep_milliseconds (int milliseconds)
2595 {
2596 #ifdef HAVE_NANOSLEEP
2597   struct timespec req;
2598   struct timespec rem;
2599
2600   req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2601   req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2602   rem.tv_sec = 0;
2603   rem.tv_nsec = 0;
2604
2605   while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2606     req = rem;
2607 #elif defined (HAVE_USLEEP)
2608   usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2609 #else /* ! HAVE_USLEEP */
2610   sleep (MAX (milliseconds / 1000, 1));
2611 #endif
2612 }
2613
2614 static dbus_bool_t
2615 _dbus_generate_pseudorandom_bytes (DBusString *str,
2616                                    int         n_bytes)
2617 {
2618   int old_len;
2619   char *p;
2620
2621   old_len = _dbus_string_get_length (str);
2622
2623   if (!_dbus_string_lengthen (str, n_bytes))
2624     return FALSE;
2625
2626   p = _dbus_string_get_data_len (str, old_len, n_bytes);
2627
2628   _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
2629
2630   return TRUE;
2631 }
2632
2633 /**
2634  * Generates the given number of random bytes,
2635  * using the best mechanism we can come up with.
2636  *
2637  * @param str the string
2638  * @param n_bytes the number of random bytes to append to string
2639  * @returns #TRUE on success, #FALSE if no memory
2640  */
2641 dbus_bool_t
2642 _dbus_generate_random_bytes (DBusString *str,
2643                              int         n_bytes)
2644 {
2645   int old_len;
2646   int fd;
2647
2648   /* FALSE return means "no memory", if it could
2649    * mean something else then we'd need to return
2650    * a DBusError. So we always fall back to pseudorandom
2651    * if the I/O fails.
2652    */
2653
2654   old_len = _dbus_string_get_length (str);
2655   fd = -1;
2656
2657   /* note, urandom on linux will fall back to pseudorandom */
2658   fd = open ("/dev/urandom", O_RDONLY);
2659   if (fd < 0)
2660     return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2661
2662   _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2663
2664   if (_dbus_read (fd, str, n_bytes) != n_bytes)
2665     {
2666       _dbus_close (fd, NULL);
2667       _dbus_string_set_length (str, old_len);
2668       return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2669     }
2670
2671   _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2672                  n_bytes);
2673
2674   _dbus_close (fd, NULL);
2675
2676   return TRUE;
2677 }
2678
2679 /**
2680  * Exit the process, returning the given value.
2681  *
2682  * @param code the exit code
2683  */
2684 void
2685 _dbus_exit (int code)
2686 {
2687   _exit (code);
2688 }
2689
2690 /**
2691  * A wrapper around strerror() because some platforms
2692  * may be lame and not have strerror(). Also, never
2693  * returns NULL.
2694  *
2695  * @param error_number errno.
2696  * @returns error description.
2697  */
2698 const char*
2699 _dbus_strerror (int error_number)
2700 {
2701   const char *msg;
2702
2703   msg = strerror (error_number);
2704   if (msg == NULL)
2705     msg = "unknown";
2706
2707   return msg;
2708 }
2709
2710 /**
2711  * signal (SIGPIPE, SIG_IGN);
2712  */
2713 void
2714 _dbus_disable_sigpipe (void)
2715 {
2716   signal (SIGPIPE, SIG_IGN);
2717 }
2718
2719 /**
2720  * Sets the file descriptor to be close
2721  * on exec. Should be called for all file
2722  * descriptors in D-Bus code.
2723  *
2724  * @param fd the file descriptor
2725  */
2726 void
2727 _dbus_fd_set_close_on_exec (intptr_t fd)
2728 {
2729   int val;
2730
2731   val = fcntl (fd, F_GETFD, 0);
2732
2733   if (val < 0)
2734     return;
2735
2736   val |= FD_CLOEXEC;
2737
2738   fcntl (fd, F_SETFD, val);
2739 }
2740
2741 /**
2742  * Closes a file descriptor.
2743  *
2744  * @param fd the file descriptor
2745  * @param error error object
2746  * @returns #FALSE if error set
2747  */
2748 dbus_bool_t
2749 _dbus_close (int        fd,
2750              DBusError *error)
2751 {
2752   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2753
2754  again:
2755   if (close (fd) < 0)
2756     {
2757       if (errno == EINTR)
2758         goto again;
2759
2760       dbus_set_error (error, _dbus_error_from_errno (errno),
2761                       "Could not close fd %d", fd);
2762       return FALSE;
2763     }
2764
2765   return TRUE;
2766 }
2767
2768 /**
2769  * Duplicates a file descriptor. Makes sure the fd returned is >= 3
2770  * (i.e. avoids stdin/stdout/stderr). Sets O_CLOEXEC.
2771  *
2772  * @param fd the file descriptor to duplicate
2773  * @returns duplicated file descriptor
2774  * */
2775 int
2776 _dbus_dup(int        fd,
2777           DBusError *error)
2778 {
2779   int new_fd;
2780
2781 #ifdef F_DUPFD_CLOEXEC
2782   dbus_bool_t cloexec_done;
2783
2784   new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2785   cloexec_done = new_fd >= 0;
2786
2787   if (new_fd < 0 && errno == EINVAL)
2788 #endif
2789     {
2790       new_fd = fcntl(fd, F_DUPFD, 3);
2791     }
2792
2793   if (new_fd < 0) {
2794
2795     dbus_set_error (error, _dbus_error_from_errno (errno),
2796                     "Could not duplicate fd %d", fd);
2797     return -1;
2798   }
2799
2800 #ifdef F_DUPFD_CLOEXEC
2801   if (!cloexec_done)
2802 #endif
2803     {
2804       _dbus_fd_set_close_on_exec(new_fd);
2805     }
2806
2807   return new_fd;
2808 }
2809
2810 /**
2811  * Sets a file descriptor to be nonblocking.
2812  *
2813  * @param fd the file descriptor.
2814  * @param error address of error location.
2815  * @returns #TRUE on success.
2816  */
2817 dbus_bool_t
2818 _dbus_set_fd_nonblocking (int             fd,
2819                           DBusError      *error)
2820 {
2821   int val;
2822
2823   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2824
2825   val = fcntl (fd, F_GETFL, 0);
2826   if (val < 0)
2827     {
2828       dbus_set_error (error, _dbus_error_from_errno (errno),
2829                       "Failed to get flags from file descriptor %d: %s",
2830                       fd, _dbus_strerror (errno));
2831       _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
2832                      _dbus_strerror (errno));
2833       return FALSE;
2834     }
2835
2836   if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
2837     {
2838       dbus_set_error (error, _dbus_error_from_errno (errno),
2839                       "Failed to set nonblocking flag of file descriptor %d: %s",
2840                       fd, _dbus_strerror (errno));
2841       _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
2842                      fd, _dbus_strerror (errno));
2843
2844       return FALSE;
2845     }
2846
2847   return TRUE;
2848 }
2849
2850 /**
2851  * On GNU libc systems, print a crude backtrace to stderr.  On other
2852  * systems, print "no backtrace support" and block for possible gdb
2853  * attachment if an appropriate environment variable is set.
2854  */
2855 void
2856 _dbus_print_backtrace (void)
2857 {
2858 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
2859   void *bt[500];
2860   int bt_size;
2861   int i;
2862   char **syms;
2863
2864   bt_size = backtrace (bt, 500);
2865
2866   syms = backtrace_symbols (bt, bt_size);
2867
2868   i = 0;
2869   while (i < bt_size)
2870     {
2871       /* don't use dbus_warn since it can _dbus_abort() */
2872       fprintf (stderr, "  %s\n", syms[i]);
2873       ++i;
2874     }
2875   fflush (stderr);
2876
2877   free (syms);
2878 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
2879   fprintf (stderr, "  D-Bus not built with -rdynamic so unable to print a backtrace\n");
2880 #else
2881   fprintf (stderr, "  D-Bus not compiled with backtrace support so unable to print a backtrace\n");
2882 #endif
2883 }
2884
2885 /**
2886  * Creates a full-duplex pipe (as in socketpair()).
2887  * Sets both ends of the pipe nonblocking.
2888  *
2889  * Marks both file descriptors as close-on-exec
2890  *
2891  * @todo libdbus only uses this for the debug-pipe server, so in
2892  * principle it could be in dbus-sysdeps-util.c, except that
2893  * dbus-sysdeps-util.c isn't in libdbus when tests are enabled and the
2894  * debug-pipe server is used.
2895  *
2896  * @param fd1 return location for one end
2897  * @param fd2 return location for the other end
2898  * @param blocking #TRUE if pipe should be blocking
2899  * @param error error return
2900  * @returns #FALSE on failure (if error is set)
2901  */
2902 dbus_bool_t
2903 _dbus_full_duplex_pipe (int        *fd1,
2904                         int        *fd2,
2905                         dbus_bool_t blocking,
2906                         DBusError  *error)
2907 {
2908 #ifdef HAVE_SOCKETPAIR
2909   int fds[2];
2910   int retval;
2911
2912 #ifdef SOCK_CLOEXEC
2913   dbus_bool_t cloexec_done;
2914
2915   retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
2916   cloexec_done = retval >= 0;
2917
2918   if (retval < 0 && errno == EINVAL)
2919 #endif
2920     {
2921       retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
2922     }
2923
2924   if (retval < 0)
2925     {
2926       dbus_set_error (error, _dbus_error_from_errno (errno),
2927                       "Could not create full-duplex pipe");
2928       return FALSE;
2929     }
2930
2931   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2932
2933 #ifdef SOCK_CLOEXEC
2934   if (!cloexec_done)
2935 #endif
2936     {
2937       _dbus_fd_set_close_on_exec (fds[0]);
2938       _dbus_fd_set_close_on_exec (fds[1]);
2939     }
2940
2941   if (!blocking &&
2942       (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
2943        !_dbus_set_fd_nonblocking (fds[1], NULL)))
2944     {
2945       dbus_set_error (error, _dbus_error_from_errno (errno),
2946                       "Could not set full-duplex pipe nonblocking");
2947
2948       _dbus_close (fds[0], NULL);
2949       _dbus_close (fds[1], NULL);
2950
2951       return FALSE;
2952     }
2953
2954   *fd1 = fds[0];
2955   *fd2 = fds[1];
2956
2957   _dbus_verbose ("full-duplex pipe %d <-> %d\n",
2958                  *fd1, *fd2);
2959
2960   return TRUE;
2961 #else
2962   _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
2963   dbus_set_error (error, DBUS_ERROR_FAILED,
2964                   "_dbus_full_duplex_pipe() not implemented on this OS");
2965   return FALSE;
2966 #endif
2967 }
2968
2969 /**
2970  * Measure the length of the given format string and arguments,
2971  * not including the terminating nul.
2972  *
2973  * @param format a printf-style format string
2974  * @param args arguments for the format string
2975  * @returns length of the given format string and args
2976  */
2977 int
2978 _dbus_printf_string_upper_bound (const char *format,
2979                                  va_list     args)
2980 {
2981   char c;
2982   return vsnprintf (&c, 1, format, args);
2983 }
2984
2985 /**
2986  * Gets the temporary files directory by inspecting the environment variables
2987  * TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned
2988  *
2989  * @returns location of temp directory
2990  */
2991 const char*
2992 _dbus_get_tmpdir(void)
2993 {
2994   static const char* tmpdir = NULL;
2995
2996   if (tmpdir == NULL)
2997     {
2998       /* TMPDIR is what glibc uses, then
2999        * glibc falls back to the P_tmpdir macro which
3000        * just expands to "/tmp"
3001        */
3002       if (tmpdir == NULL)
3003         tmpdir = getenv("TMPDIR");
3004
3005       /* These two env variables are probably
3006        * broken, but maybe some OS uses them?
3007        */
3008       if (tmpdir == NULL)
3009         tmpdir = getenv("TMP");
3010       if (tmpdir == NULL)
3011         tmpdir = getenv("TEMP");
3012
3013       /* And this is the sane fallback. */
3014       if (tmpdir == NULL)
3015         tmpdir = "/tmp";
3016     }
3017
3018   _dbus_assert(tmpdir != NULL);
3019
3020   return tmpdir;
3021 }
3022
3023 /**
3024  * Execute a subprocess, returning up to 1024 bytes of output
3025  * into @p result.
3026  *
3027  * If successful, returns #TRUE and appends the output to @p
3028  * result. If a failure happens, returns #FALSE and
3029  * sets an error in @p error.
3030  *
3031  * @note It's not an error if the subprocess terminates normally
3032  * without writing any data to stdout. Verify the @p result length
3033  * before and after this function call to cover this case.
3034  *
3035  * @param progname initial path to exec (may or may not be absolute)
3036  * @param path_fallback if %TRUE, search PATH for executable
3037  * @param argv NULL-terminated list of arguments
3038  * @param result a DBusString where the output can be append
3039  * @param error a DBusError to store the error in case of failure
3040  * @returns #TRUE on success, #FALSE if an error happened
3041  */
3042 static dbus_bool_t
3043 _read_subprocess_line_argv (const char *progpath,
3044                             dbus_bool_t path_fallback,
3045                             char       * const *argv,
3046                             DBusString *result,
3047                             DBusError  *error)
3048 {
3049   int result_pipe[2] = { -1, -1 };
3050   int errors_pipe[2] = { -1, -1 };
3051   pid_t pid;
3052   int ret;
3053   int status;
3054   int orig_len;
3055   int i;
3056
3057   dbus_bool_t retval;
3058   sigset_t new_set, old_set;
3059
3060   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3061   retval = FALSE;
3062
3063   /* We need to block any existing handlers for SIGCHLD temporarily; they
3064    * will cause waitpid() below to fail.
3065    * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3066    */
3067   sigemptyset (&new_set);
3068   sigaddset (&new_set, SIGCHLD);
3069   sigprocmask (SIG_BLOCK, &new_set, &old_set);
3070
3071   orig_len = _dbus_string_get_length (result);
3072
3073 #define READ_END        0
3074 #define WRITE_END       1
3075   if (pipe (result_pipe) < 0)
3076     {
3077       dbus_set_error (error, _dbus_error_from_errno (errno),
3078                       "Failed to create a pipe to call %s: %s",
3079                       progpath, _dbus_strerror (errno));
3080       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3081                      progpath, _dbus_strerror (errno));
3082       goto out;
3083     }
3084   if (pipe (errors_pipe) < 0)
3085     {
3086       dbus_set_error (error, _dbus_error_from_errno (errno),
3087                       "Failed to create a pipe to call %s: %s",
3088                       progpath, _dbus_strerror (errno));
3089       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3090                      progpath, _dbus_strerror (errno));
3091       goto out;
3092     }
3093
3094   pid = fork ();
3095   if (pid < 0)
3096     {
3097       dbus_set_error (error, _dbus_error_from_errno (errno),
3098                       "Failed to fork() to call %s: %s",
3099                       progpath, _dbus_strerror (errno));
3100       _dbus_verbose ("Failed to fork() to call %s: %s\n",
3101                      progpath, _dbus_strerror (errno));
3102       goto out;
3103     }
3104
3105   if (pid == 0)
3106     {
3107       /* child process */
3108       int maxfds;
3109       int fd;
3110
3111       fd = open ("/dev/null", O_RDWR);
3112       if (fd == -1)
3113         /* huh?! can't open /dev/null? */
3114         _exit (1);
3115
3116       _dbus_verbose ("/dev/null fd %d opened\n", fd);
3117
3118       /* set-up stdXXX */
3119       close (result_pipe[READ_END]);
3120       close (errors_pipe[READ_END]);
3121       close (0);                /* close stdin */
3122       close (1);                /* close stdout */
3123       close (2);                /* close stderr */
3124
3125       if (dup2 (fd, 0) == -1)
3126         _exit (1);
3127       if (dup2 (result_pipe[WRITE_END], 1) == -1)
3128         _exit (1);
3129       if (dup2 (errors_pipe[WRITE_END], 2) == -1)
3130         _exit (1);
3131
3132       maxfds = sysconf (_SC_OPEN_MAX);
3133       /* Pick something reasonable if for some reason sysconf
3134        * says unlimited.
3135        */
3136       if (maxfds < 0)
3137         maxfds = 1024;
3138       /* close all inherited fds */
3139       for (i = 3; i < maxfds; i++)
3140         close (i);
3141
3142       sigprocmask (SIG_SETMASK, &old_set, NULL);
3143
3144       /* If it looks fully-qualified, try execv first */
3145       if (progpath[0] == '/')
3146         {
3147           execv (progpath, argv);
3148           /* Ok, that failed.  Now if path_fallback is given, let's
3149            * try unqualified.  This is mostly a hack to work
3150            * around systems which ship dbus-launch in /usr/bin
3151            * but everything else in /bin (because dbus-launch
3152            * depends on X11).
3153            */
3154           if (path_fallback)
3155             /* We must have a slash, because we checked above */
3156             execvp (strrchr (progpath, '/')+1, argv);
3157         }
3158       else
3159         execvp (progpath, argv);
3160
3161       /* still nothing, we failed */
3162       _exit (1);
3163     }
3164
3165   /* parent process */
3166   close (result_pipe[WRITE_END]);
3167   close (errors_pipe[WRITE_END]);
3168   result_pipe[WRITE_END] = -1;
3169   errors_pipe[WRITE_END] = -1;
3170
3171   ret = 0;
3172   do
3173     {
3174       ret = _dbus_read (result_pipe[READ_END], result, 1024);
3175     }
3176   while (ret > 0);
3177
3178   /* reap the child process to avoid it lingering as zombie */
3179   do
3180     {
3181       ret = waitpid (pid, &status, 0);
3182     }
3183   while (ret == -1 && errno == EINTR);
3184
3185   /* We succeeded if the process exited with status 0 and
3186      anything was read */
3187   if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3188     {
3189       /* The process ended with error */
3190       DBusString error_message;
3191       _dbus_string_init (&error_message);
3192       ret = 0;
3193       do
3194         {
3195           ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3196         }
3197       while (ret > 0);
3198
3199       _dbus_string_set_length (result, orig_len);
3200       if (_dbus_string_get_length (&error_message) > 0)
3201         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3202                         "%s terminated abnormally with the following error: %s",
3203                         progpath, _dbus_string_get_data (&error_message));
3204       else
3205         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3206                         "%s terminated abnormally without any error message",
3207                         progpath);
3208       goto out;
3209     }
3210
3211   retval = TRUE;
3212
3213  out:
3214   sigprocmask (SIG_SETMASK, &old_set, NULL);
3215
3216   if (retval)
3217     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3218   else
3219     _DBUS_ASSERT_ERROR_IS_SET (error);
3220
3221   if (result_pipe[0] != -1)
3222     close (result_pipe[0]);
3223   if (result_pipe[1] != -1)
3224     close (result_pipe[1]);
3225   if (errors_pipe[0] != -1)
3226     close (errors_pipe[0]);
3227   if (errors_pipe[1] != -1)
3228     close (errors_pipe[1]);
3229
3230   return retval;
3231 }
3232
3233 /**
3234  * Returns the address of a new session bus.
3235  *
3236  * If successful, returns #TRUE and appends the address to @p
3237  * address. If a failure happens, returns #FALSE and
3238  * sets an error in @p error.
3239  *
3240  * @param address a DBusString where the address can be stored
3241  * @param error a DBusError to store the error in case of failure
3242  * @returns #TRUE on success, #FALSE if an error happened
3243  */
3244 dbus_bool_t
3245 _dbus_get_autolaunch_address (const char *scope,
3246                               DBusString *address,
3247                               DBusError  *error)
3248 {
3249   static char *argv[6];
3250   int i;
3251   DBusString uuid;
3252   dbus_bool_t retval;
3253
3254   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3255   retval = FALSE;
3256
3257   if (!_dbus_string_init (&uuid))
3258     {
3259       _DBUS_SET_OOM (error);
3260       return FALSE;
3261     }
3262
3263   if (!_dbus_get_local_machine_uuid_encoded (&uuid))
3264     {
3265       _DBUS_SET_OOM (error);
3266       goto out;
3267     }
3268
3269   i = 0;
3270   argv[i] = "dbus-launch";
3271   ++i;
3272   argv[i] = "--autolaunch";
3273   ++i;
3274   argv[i] = _dbus_string_get_data (&uuid);
3275   ++i;
3276   argv[i] = "--binary-syntax";
3277   ++i;
3278   argv[i] = "--close-stderr";
3279   ++i;
3280   argv[i] = NULL;
3281   ++i;
3282
3283   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3284
3285   retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
3286                                        TRUE,
3287                                        argv, address, error);
3288
3289  out:
3290   _dbus_string_free (&uuid);
3291   return retval;
3292 }
3293
3294 /**
3295  * Reads the uuid of the machine we're running on from
3296  * the dbus configuration. Optionally try to create it
3297  * (only root can do this usually).
3298  *
3299  * On UNIX, reads a file that gets created by dbus-uuidgen
3300  * in a post-install script. On Windows, if there's a standard
3301  * machine uuid we could just use that, but I can't find one
3302  * with the right properties (the hardware profile guid can change
3303  * without rebooting I believe). If there's no standard one
3304  * we might want to use the registry instead of a file for
3305  * this, and I'm not sure how we'd ensure the uuid gets created.
3306  *
3307  * @param machine_id guid to init with the machine's uuid
3308  * @param create_if_not_found try to create the uuid if it doesn't exist
3309  * @param error the error return
3310  * @returns #FALSE if the error is set
3311  */
3312 dbus_bool_t
3313 _dbus_read_local_machine_uuid (DBusGUID   *machine_id,
3314                                dbus_bool_t create_if_not_found,
3315                                DBusError  *error)
3316 {
3317   DBusString filename;
3318   _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3319   return _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
3320 }
3321
3322 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
3323 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
3324
3325 /**
3326  * quries launchd for a specific env var which holds the socket path.
3327  * @param launchd_env_var the env var to look up
3328  * @param error a DBusError to store the error in case of failure
3329  * @return the value of the env var
3330  */
3331 dbus_bool_t
3332 _dbus_lookup_launchd_socket (DBusString *socket_path,
3333                              const char *launchd_env_var,
3334                              DBusError  *error)
3335 {
3336 #ifdef DBUS_ENABLE_LAUNCHD
3337   char *argv[4];
3338   int i;
3339
3340   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3341
3342   i = 0;
3343   argv[i] = "launchctl";
3344   ++i;
3345   argv[i] = "getenv";
3346   ++i;
3347   argv[i] = (char*)launchd_env_var;
3348   ++i;
3349   argv[i] = NULL;
3350   ++i;
3351
3352   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3353
3354   if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
3355     {
3356       return FALSE;
3357     }
3358
3359   /* no error, but no result either */
3360   if (_dbus_string_get_length(socket_path) == 0)
3361     {
3362       return FALSE;
3363     }
3364
3365   /* strip the carriage-return */
3366   _dbus_string_shorten(socket_path, 1);
3367   return TRUE;
3368 #else /* DBUS_ENABLE_LAUNCHD */
3369   dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
3370                 "can't lookup socket from launchd; launchd support not compiled in");
3371   return FALSE;
3372 #endif
3373 }
3374
3375 static dbus_bool_t
3376 _dbus_lookup_session_address_launchd (DBusString *address, DBusError  *error)
3377 {
3378 #ifdef DBUS_ENABLE_LAUNCHD
3379   dbus_bool_t valid_socket;
3380   DBusString socket_path;
3381
3382   if (!_dbus_string_init (&socket_path))
3383     {
3384       _DBUS_SET_OOM (error);
3385       return FALSE;
3386     }
3387
3388   valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
3389
3390   if (dbus_error_is_set(error))
3391     {
3392       _dbus_string_free(&socket_path);
3393       return FALSE;
3394     }
3395
3396   if (!valid_socket)
3397     {
3398       dbus_set_error(error, "no socket path",
3399                 "launchd did not provide a socket path, "
3400                 "verify that org.freedesktop.dbus-session.plist is loaded!");
3401       _dbus_string_free(&socket_path);
3402       return FALSE;
3403     }
3404   if (!_dbus_string_append (address, "unix:path="))
3405     {
3406       _DBUS_SET_OOM (error);
3407       _dbus_string_free(&socket_path);
3408       return FALSE;
3409     }
3410   if (!_dbus_string_copy (&socket_path, 0, address,
3411                           _dbus_string_get_length (address)))
3412     {
3413       _DBUS_SET_OOM (error);
3414       _dbus_string_free(&socket_path);
3415       return FALSE;
3416     }
3417
3418   _dbus_string_free(&socket_path);
3419   return TRUE;
3420 #else
3421   dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
3422                 "can't lookup session address from launchd; launchd support not compiled in");
3423   return FALSE;
3424 #endif
3425 }
3426
3427 /**
3428  * Determines the address of the session bus by querying a
3429  * platform-specific method.
3430  *
3431  * The first parameter will be a boolean specifying whether
3432  * or not a dynamic session lookup is supported on this platform.
3433  *
3434  * If supported is TRUE and the return value is #TRUE, the
3435  * address will be  appended to @p address.
3436  * If a failure happens, returns #FALSE and sets an error in
3437  * @p error.
3438  *
3439  * If supported is FALSE, ignore the return value.
3440  *
3441  * @param supported returns whether this method is supported
3442  * @param address a DBusString where the address can be stored
3443  * @param error a DBusError to store the error in case of failure
3444  * @returns #TRUE on success, #FALSE if an error happened
3445  */
3446 dbus_bool_t
3447 _dbus_lookup_session_address (dbus_bool_t *supported,
3448                               DBusString  *address,
3449                               DBusError   *error)
3450 {
3451 #ifdef DBUS_ENABLE_LAUNCHD
3452   *supported = TRUE;
3453   return _dbus_lookup_session_address_launchd (address, error);
3454 #else
3455   /* On non-Mac Unix platforms, if the session address isn't already
3456    * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
3457    * fall back to the autolaunch: global default; see
3458    * init_session_address in dbus/dbus-bus.c. */
3459   *supported = FALSE;
3460   return TRUE;
3461 #endif
3462 }
3463
3464 /**
3465  * Returns the standard directories for a session bus to look for service
3466  * activation files
3467  *
3468  * On UNIX this should be the standard xdg freedesktop.org data directories:
3469  *
3470  * XDG_DATA_HOME=${XDG_DATA_HOME-$HOME/.local/share}
3471  * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3472  *
3473  * and
3474  *
3475  * DBUS_DATADIR
3476  *
3477  * @param dirs the directory list we are returning
3478  * @returns #FALSE on OOM
3479  */
3480
3481 dbus_bool_t
3482 _dbus_get_standard_session_servicedirs (DBusList **dirs)
3483 {
3484   const char *xdg_data_home;
3485   const char *xdg_data_dirs;
3486   DBusString servicedir_path;
3487
3488   if (!_dbus_string_init (&servicedir_path))
3489     return FALSE;
3490
3491   xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
3492   xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3493
3494   if (xdg_data_dirs != NULL)
3495     {
3496       if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3497         goto oom;
3498
3499       if (!_dbus_string_append (&servicedir_path, ":"))
3500         goto oom;
3501     }
3502   else
3503     {
3504       if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3505         goto oom;
3506     }
3507
3508   /*
3509    * add configured datadir to defaults
3510    * this may be the same as an xdg dir
3511    * however the config parser should take
3512    * care of duplicates
3513    */
3514   if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
3515         goto oom;
3516
3517   if (xdg_data_home != NULL)
3518     {
3519       if (!_dbus_string_append (&servicedir_path, xdg_data_home))
3520         goto oom;
3521     }
3522   else
3523     {
3524       const DBusString *homedir;
3525       DBusString local_share;
3526
3527       if (!_dbus_homedir_from_current_process (&homedir))
3528         goto oom;
3529
3530       if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
3531         goto oom;
3532
3533       _dbus_string_init_const (&local_share, "/.local/share");
3534       if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
3535         goto oom;
3536     }
3537
3538   if (!_dbus_split_paths_and_append (&servicedir_path,
3539                                      DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
3540                                      dirs))
3541     goto oom;
3542
3543   _dbus_string_free (&servicedir_path);
3544   return TRUE;
3545
3546  oom:
3547   _dbus_string_free (&servicedir_path);
3548   return FALSE;
3549 }
3550
3551
3552 /**
3553  * Returns the standard directories for a system bus to look for service
3554  * activation files
3555  *
3556  * On UNIX this should be the standard xdg freedesktop.org data directories:
3557  *
3558  * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3559  *
3560  * and
3561  *
3562  * DBUS_DATADIR
3563  *
3564  * On Windows there is no system bus and this function can return nothing.
3565  *
3566  * @param dirs the directory list we are returning
3567  * @returns #FALSE on OOM
3568  */
3569
3570 dbus_bool_t
3571 _dbus_get_standard_system_servicedirs (DBusList **dirs)
3572 {
3573   const char *xdg_data_dirs;
3574   DBusString servicedir_path;
3575
3576   if (!_dbus_string_init (&servicedir_path))
3577     return FALSE;
3578
3579   xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3580
3581   if (xdg_data_dirs != NULL)
3582     {
3583       if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3584         goto oom;
3585
3586       if (!_dbus_string_append (&servicedir_path, ":"))
3587         goto oom;
3588     }
3589   else
3590     {
3591       if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3592         goto oom;
3593     }
3594
3595   /*
3596    * add configured datadir to defaults
3597    * this may be the same as an xdg dir
3598    * however the config parser should take
3599    * care of duplicates
3600    */
3601   if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
3602         goto oom;
3603
3604   if (!_dbus_split_paths_and_append (&servicedir_path,
3605                                      DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
3606                                      dirs))
3607     goto oom;
3608
3609   _dbus_string_free (&servicedir_path);
3610   return TRUE;
3611
3612  oom:
3613   _dbus_string_free (&servicedir_path);
3614   return FALSE;
3615 }
3616
3617 /**
3618  * Append the absolute path of the system.conf file
3619  * (there is no system bus on Windows so this can just
3620  * return FALSE and print a warning or something)
3621  *
3622  * @param str the string to append to
3623  * @returns #FALSE if no memory
3624  */
3625 dbus_bool_t
3626 _dbus_append_system_config_file (DBusString *str)
3627 {
3628   return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
3629 }
3630
3631 /**
3632  * Append the absolute path of the session.conf file.
3633  *
3634  * @param str the string to append to
3635  * @returns #FALSE if no memory
3636  */
3637 dbus_bool_t
3638 _dbus_append_session_config_file (DBusString *str)
3639 {
3640   return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
3641 }
3642
3643 /**
3644  * Called when the bus daemon is signaled to reload its configuration; any
3645  * caches should be nuked. Of course any caches that need explicit reload
3646  * are probably broken, but c'est la vie.
3647  *
3648  *
3649  */
3650 void
3651 _dbus_flush_caches (void)
3652 {
3653   _dbus_user_database_flush_system ();
3654 }
3655
3656 /**
3657  * Appends the directory in which a keyring for the given credentials
3658  * should be stored.  The credentials should have either a Windows or
3659  * UNIX user in them.  The directory should be an absolute path.
3660  *
3661  * On UNIX the directory is ~/.dbus-keyrings while on Windows it should probably
3662  * be something else, since the dotfile convention is not normal on Windows.
3663  *
3664  * @param directory string to append directory to
3665  * @param credentials credentials the directory should be for
3666  *
3667  * @returns #FALSE on no memory
3668  */
3669 dbus_bool_t
3670 _dbus_append_keyring_directory_for_credentials (DBusString      *directory,
3671                                                 DBusCredentials *credentials)
3672 {
3673   DBusString homedir;
3674   DBusString dotdir;
3675   dbus_uid_t uid;
3676
3677   _dbus_assert (credentials != NULL);
3678   _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
3679
3680   if (!_dbus_string_init (&homedir))
3681     return FALSE;
3682
3683   uid = _dbus_credentials_get_unix_uid (credentials);
3684   _dbus_assert (uid != DBUS_UID_UNSET);
3685
3686   if (!_dbus_homedir_from_uid (uid, &homedir))
3687     goto failed;
3688
3689 #ifdef DBUS_BUILD_TESTS
3690   {
3691     const char *override;
3692
3693     override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3694     if (override != NULL && *override != '\0')
3695       {
3696         _dbus_string_set_length (&homedir, 0);
3697         if (!_dbus_string_append (&homedir, override))
3698           goto failed;
3699
3700         _dbus_verbose ("Using fake homedir for testing: %s\n",
3701                        _dbus_string_get_const_data (&homedir));
3702       }
3703     else
3704       {
3705         static dbus_bool_t already_warned = FALSE;
3706         if (!already_warned)
3707           {
3708             _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3709             already_warned = TRUE;
3710           }
3711       }
3712   }
3713 #endif
3714
3715   _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3716   if (!_dbus_concat_dir_and_file (&homedir,
3717                                   &dotdir))
3718     goto failed;
3719
3720   if (!_dbus_string_copy (&homedir, 0,
3721                           directory, _dbus_string_get_length (directory))) {
3722     goto failed;
3723   }
3724
3725   _dbus_string_free (&homedir);
3726   return TRUE;
3727
3728  failed:
3729   _dbus_string_free (&homedir);
3730   return FALSE;
3731 }
3732
3733 //PENDING(kdab) docs
3734 dbus_bool_t
3735 _dbus_daemon_publish_session_bus_address (const char* addr,
3736                                           const char *scope)
3737 {
3738   return TRUE;
3739 }
3740
3741 //PENDING(kdab) docs
3742 void
3743 _dbus_daemon_unpublish_session_bus_address (void)
3744 {
3745
3746 }
3747
3748 /**
3749  * See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently
3750  * for Winsock so is abstracted)
3751  *
3752  * @returns #TRUE if errno == EAGAIN or errno == EWOULDBLOCK
3753  */
3754 dbus_bool_t
3755 _dbus_get_is_errno_eagain_or_ewouldblock (void)
3756 {
3757   return errno == EAGAIN || errno == EWOULDBLOCK;
3758 }
3759
3760 /**
3761  * Removes a directory; Directory must be empty
3762  *
3763  * @param filename directory filename
3764  * @param error initialized error object
3765  * @returns #TRUE on success
3766  */
3767 dbus_bool_t
3768 _dbus_delete_directory (const DBusString *filename,
3769                         DBusError        *error)
3770 {
3771   const char *filename_c;
3772
3773   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3774
3775   filename_c = _dbus_string_get_const_data (filename);
3776
3777   if (rmdir (filename_c) != 0)
3778     {
3779       dbus_set_error (error, DBUS_ERROR_FAILED,
3780                       "Failed to remove directory %s: %s\n",
3781                       filename_c, _dbus_strerror (errno));
3782       return FALSE;
3783     }
3784
3785   return TRUE;
3786 }
3787
3788 /**
3789  *  Checks whether file descriptors may be passed via the socket
3790  *
3791  *  @param fd the socket
3792  *  @return TRUE when fd passing over this socket is supported
3793  *
3794  */
3795 dbus_bool_t
3796 _dbus_socket_can_pass_unix_fd(int fd) {
3797
3798 #ifdef SCM_RIGHTS
3799   union {
3800     struct sockaddr sa;
3801     struct sockaddr_storage storage;
3802     struct sockaddr_un un;
3803   } sa_buf;
3804
3805   socklen_t sa_len = sizeof(sa_buf);
3806
3807   _DBUS_ZERO(sa_buf);
3808
3809   if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
3810     return FALSE;
3811
3812   return sa_buf.sa.sa_family == AF_UNIX;
3813
3814 #else
3815   return FALSE;
3816
3817 #endif
3818 }
3819
3820
3821 /*
3822  * replaces the term DBUS_PREFIX in configure_time_path by the
3823  * current dbus installation directory. On unix this function is a noop
3824  *
3825  * @param configure_time_path
3826  * @return real path
3827  */
3828 const char *
3829 _dbus_replace_install_prefix (const char *configure_time_path)
3830 {
3831   return configure_time_path;
3832 }
3833
3834 /* tests in dbus-sysdeps-util.c */