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