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