added dbus support
[monky] / src / 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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   struct {
1045           struct cmsghdr hdr;
1046           struct cmsgcred cred;
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 = &cmsg;
1058   msg.msg_controllen = sizeof (cmsg);
1059   memset (&cmsg, 0, sizeof (cmsg));
1060   cmsg.hdr.cmsg_len = sizeof (cmsg);
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   uid_read = DBUS_UID_UNSET;
1133   pid_read = DBUS_PID_UNSET;
1134   
1135 #ifdef HAVE_CMSGCRED 
1136   struct {
1137     struct cmsghdr hdr;
1138     struct cmsgcred cred;
1139   } cmsg;
1140
1141 #elif defined(LOCAL_CREDS)
1142   struct {
1143     struct cmsghdr hdr;
1144     struct sockcred cred;
1145   } cmsg;
1146 #endif
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 = &cmsg;
1176   msg.msg_controllen = sizeof (cmsg);
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 < sizeof (cmsg) || cmsg.hdr.cmsg_type != SCM_CREDS)
1215     {
1216       dbus_set_error (error, DBUS_ERROR_FAILED,
1217                       "Message from recvmsg() was not SCM_CREDS");
1218       return FALSE;
1219     }
1220 #endif
1221
1222   _dbus_verbose ("read credentials byte\n");
1223
1224   {
1225 #ifdef SO_PEERCRED
1226     struct ucred cr;   
1227     int cr_len = sizeof (cr);
1228     
1229     if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1230         cr_len == sizeof (cr))
1231       {
1232         pid_read = cr.pid;
1233         uid_read = cr.uid;
1234       }
1235     else
1236       {
1237         _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1238                        cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1239       }
1240 #elif defined(HAVE_CMSGCRED)
1241     pid_read = cmsg.cred.cmcred_pid;
1242     uid_read = cmsg.cred.cmcred_euid;
1243 #elif defined(LOCAL_CREDS)
1244     pid_read = DBUS_PID_UNSET;
1245     uid_read = cmsg.cred.sc_uid;
1246     /* Since we have already got the credentials from this socket, we can
1247      * disable its LOCAL_CREDS flag if it was ever set. */
1248     _dbus_set_local_creds (client_fd, FALSE);
1249 #elif defined(HAVE_GETPEEREID)
1250     uid_t euid;
1251     gid_t egid;
1252     if (getpeereid (client_fd, &euid, &egid) == 0)
1253       {
1254         uid_read = euid;
1255       }
1256     else
1257       {
1258         _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1259       }
1260 #elif defined(HAVE_GETPEERUCRED)
1261     ucred_t * ucred = NULL;
1262     if (getpeerucred (client_fd, &ucred) == 0)
1263       {
1264         pid_read = ucred_getpid (ucred);
1265         uid_read = ucred_geteuid (ucred);
1266 #ifdef HAVE_ADT
1267         /* generate audit session data based on socket ucred */
1268         adt_session_data_t *adth = NULL;
1269         adt_export_data_t *data = NULL;
1270         size_t size = 0;
1271         if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1272           {
1273             _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1274           }
1275         else 
1276           {
1277             if (adt_set_from_ucred (adth, ucred, ADT_NEW)) 
1278               {
1279                 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1280               }
1281             else
1282               {
1283                 size = adt_export_session_data (adth, &data);
1284                 if (size <= 0)
1285                   {
1286                     _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
1287                   }
1288                 else
1289                   {
1290                     _dbus_credentials_add_adt_audit_data (credentials, data, size);
1291                     free (data);
1292                   }
1293               }
1294             (void) adt_end_session (adth);
1295           }
1296 #endif /* HAVE_ADT */
1297       }
1298     else
1299       {
1300         _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1301       }
1302     if (ucred != NULL)
1303       ucred_free (ucred);
1304 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
1305     _dbus_verbose ("Socket credentials not supported on this OS\n");
1306 #endif
1307   }
1308
1309   _dbus_verbose ("Credentials:"
1310                  "  pid "DBUS_PID_FORMAT
1311                  "  uid "DBUS_UID_FORMAT
1312                  "\n",
1313                  pid_read,
1314                  uid_read);
1315
1316   if (pid_read != DBUS_PID_UNSET)
1317     {
1318       if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
1319         {
1320           _DBUS_SET_OOM (error);
1321           return FALSE;
1322         }
1323     }
1324
1325   if (uid_read != DBUS_UID_UNSET)
1326     {
1327       if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
1328         {
1329           _DBUS_SET_OOM (error);
1330           return FALSE;
1331         }
1332     }
1333   
1334   return TRUE;
1335 }
1336
1337 /**
1338  * Sends a single nul byte with our UNIX credentials as ancillary
1339  * data.  Returns #TRUE if the data was successfully written.  On
1340  * systems that don't support sending credentials, just writes a byte,
1341  * doesn't send any credentials.  On some systems, such as Linux,
1342  * reading/writing the byte isn't actually required, but we do it
1343  * anyway just to avoid multiple codepaths.
1344  *
1345  * Fails if no byte can be written, so you must select() first.
1346  *
1347  * The point of the byte is that on some systems we have to
1348  * use sendmsg()/recvmsg() to transmit credentials.
1349  *
1350  * @param server_fd file descriptor for connection to server
1351  * @param error return location for error code
1352  * @returns #TRUE if the byte was sent
1353  */
1354 dbus_bool_t
1355 _dbus_send_credentials_socket  (int              server_fd,
1356                                 DBusError       *error)
1357 {
1358   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1359   
1360   if (write_credentials_byte (server_fd, error))
1361     return TRUE;
1362   else
1363     return FALSE;
1364 }
1365
1366 /**
1367  * Accepts a connection on a listening socket.
1368  * Handles EINTR for you.
1369  *
1370  * @param listen_fd the listen file descriptor
1371  * @returns the connection fd of the client, or -1 on error
1372  */
1373 int
1374 _dbus_accept  (int listen_fd)
1375 {
1376   int client_fd;
1377   struct sockaddr addr;
1378   socklen_t addrlen;
1379
1380   addrlen = sizeof (addr);
1381   
1382  retry:
1383   client_fd = accept (listen_fd, &addr, &addrlen);
1384   
1385   if (client_fd < 0)
1386     {
1387       if (errno == EINTR)
1388         goto retry;
1389     }
1390
1391   _dbus_verbose ("client fd %d accepted\n", client_fd);
1392   
1393   return client_fd;
1394 }
1395
1396 /**
1397  * Checks to make sure the given directory is 
1398  * private to the user 
1399  *
1400  * @param dir the name of the directory
1401  * @param error error return
1402  * @returns #FALSE on failure
1403  **/
1404 dbus_bool_t
1405 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
1406 {
1407   const char *directory;
1408   struct stat sb;
1409         
1410   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1411     
1412   directory = _dbus_string_get_const_data (dir);
1413         
1414   if (stat (directory, &sb) < 0)
1415     {
1416       dbus_set_error (error, _dbus_error_from_errno (errno),
1417                       "%s", _dbus_strerror (errno));
1418    
1419       return FALSE;
1420     }
1421     
1422   if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
1423       (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
1424     {
1425       dbus_set_error (error, DBUS_ERROR_FAILED,
1426                      "%s directory is not private to the user", directory);
1427       return FALSE;
1428     }
1429     
1430   return TRUE;
1431 }
1432
1433 static dbus_bool_t
1434 fill_user_info_from_passwd (struct passwd *p,
1435                             DBusUserInfo  *info,
1436                             DBusError     *error)
1437 {
1438   _dbus_assert (p->pw_name != NULL);
1439   _dbus_assert (p->pw_dir != NULL);
1440   
1441   info->uid = p->pw_uid;
1442   info->primary_gid = p->pw_gid;
1443   info->username = _dbus_strdup (p->pw_name);
1444   info->homedir = _dbus_strdup (p->pw_dir);
1445   
1446   if (info->username == NULL ||
1447       info->homedir == NULL)
1448     {
1449       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1450       return FALSE;
1451     }
1452
1453   return TRUE;
1454 }
1455
1456 static dbus_bool_t
1457 fill_user_info (DBusUserInfo       *info,
1458                 dbus_uid_t          uid,
1459                 const DBusString   *username,
1460                 DBusError          *error)
1461 {
1462   const char *username_c;
1463   
1464   /* exactly one of username/uid provided */
1465   _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
1466   _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
1467
1468   info->uid = DBUS_UID_UNSET;
1469   info->primary_gid = DBUS_GID_UNSET;
1470   info->group_ids = NULL;
1471   info->n_group_ids = 0;
1472   info->username = NULL;
1473   info->homedir = NULL;
1474   
1475   if (username != NULL)
1476     username_c = _dbus_string_get_const_data (username);
1477   else
1478     username_c = NULL;
1479
1480   /* For now assuming that the getpwnam() and getpwuid() flavors
1481    * are always symmetrical, if not we have to add more configure
1482    * checks
1483    */
1484   
1485 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
1486   {
1487     struct passwd *p;
1488     int result;
1489     size_t buflen;
1490     char *buf;
1491     struct passwd p_str;
1492
1493     /* retrieve maximum needed size for buf */
1494     buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
1495
1496     /* sysconf actually returns a long, but everything else expects size_t,
1497      * so just recast here.
1498      * https://bugs.freedesktop.org/show_bug.cgi?id=17061
1499      */
1500     if ((long) buflen <= 0)
1501       buflen = 1024;
1502
1503     result = -1;
1504     while (1)
1505       {
1506         buf = dbus_malloc (buflen);
1507         if (buf == NULL)
1508           {
1509             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1510             return FALSE;
1511           }
1512
1513         p = NULL;
1514 #ifdef HAVE_POSIX_GETPWNAM_R
1515         if (uid != DBUS_UID_UNSET)
1516           result = getpwuid_r (uid, &p_str, buf, buflen,
1517                                &p);
1518         else
1519           result = getpwnam_r (username_c, &p_str, buf, buflen,
1520                                &p);
1521 #else
1522         if (uid != DBUS_UID_UNSET)
1523           p = getpwuid_r (uid, &p_str, buf, buflen);
1524         else
1525           p = getpwnam_r (username_c, &p_str, buf, buflen);
1526         result = 0;
1527 #endif /* !HAVE_POSIX_GETPWNAM_R */
1528         //Try a bigger buffer if ERANGE was returned
1529         if (result == ERANGE && buflen < 512 * 1024)
1530           {
1531             dbus_free (buf);
1532             buflen *= 2;
1533           }
1534         else
1535           {
1536             break;
1537           }
1538       }
1539     if (result == 0 && p == &p_str)
1540       {
1541         if (!fill_user_info_from_passwd (p, info, error))
1542           {
1543             dbus_free (buf);
1544             return FALSE;
1545           }
1546         dbus_free (buf);
1547       }
1548     else
1549       {
1550         dbus_set_error (error, _dbus_error_from_errno (errno),
1551                         "User \"%s\" unknown or no memory to allocate password entry\n",
1552                         username_c ? username_c : "???");
1553         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
1554         dbus_free (buf);
1555         return FALSE;
1556       }
1557   }
1558 #else /* ! HAVE_GETPWNAM_R */
1559   {
1560     /* I guess we're screwed on thread safety here */
1561     struct passwd *p;
1562
1563     if (uid != DBUS_UID_UNSET)
1564       p = getpwuid (uid);
1565     else
1566       p = getpwnam (username_c);
1567
1568     if (p != NULL)
1569       {
1570         if (!fill_user_info_from_passwd (p, info, error))
1571           {
1572             return FALSE;
1573           }
1574       }
1575     else
1576       {
1577         dbus_set_error (error, _dbus_error_from_errno (errno),
1578                         "User \"%s\" unknown or no memory to allocate password entry\n",
1579                         username_c ? username_c : "???");
1580         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
1581         return FALSE;
1582       }
1583   }
1584 #endif  /* ! HAVE_GETPWNAM_R */
1585
1586   /* Fill this in so we can use it to get groups */
1587   username_c = info->username;
1588   
1589 #ifdef HAVE_GETGROUPLIST
1590   {
1591     gid_t *buf;
1592     int buf_count;
1593     int i;
1594     
1595     buf_count = 17;
1596     buf = dbus_new (gid_t, buf_count);
1597     if (buf == NULL)
1598       {
1599         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1600         goto failed;
1601       }
1602     
1603     if (getgrouplist (username_c,
1604                       info->primary_gid,
1605                       buf, &buf_count) < 0)
1606       {
1607         gid_t *new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
1608         if (new == NULL)
1609           {
1610             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1611             dbus_free (buf);
1612             goto failed;
1613           }
1614         
1615         buf = new;
1616
1617         errno = 0;
1618         if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
1619           {
1620             dbus_set_error (error,
1621                             _dbus_error_from_errno (errno),
1622                             "Failed to get groups for username \"%s\" primary GID "
1623                             DBUS_GID_FORMAT ": %s\n",
1624                             username_c, info->primary_gid,
1625                             _dbus_strerror (errno));
1626             dbus_free (buf);
1627             goto failed;
1628           }
1629       }
1630
1631     info->group_ids = dbus_new (dbus_gid_t, buf_count);
1632     if (info->group_ids == NULL)
1633       {
1634         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1635         dbus_free (buf);
1636         goto failed;
1637       }
1638     
1639     for (i = 0; i < buf_count; ++i)
1640       info->group_ids[i] = buf[i];
1641
1642     info->n_group_ids = buf_count;
1643     
1644     dbus_free (buf);
1645   }
1646 #else  /* HAVE_GETGROUPLIST */
1647   {
1648     /* We just get the one group ID */
1649     info->group_ids = dbus_new (dbus_gid_t, 1);
1650     if (info->group_ids == NULL)
1651       {
1652         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1653         goto failed;
1654       }
1655
1656     info->n_group_ids = 1;
1657
1658     (info->group_ids)[0] = info->primary_gid;
1659   }
1660 #endif /* HAVE_GETGROUPLIST */
1661
1662   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1663   
1664   return TRUE;
1665   
1666  failed:
1667   _DBUS_ASSERT_ERROR_IS_SET (error);
1668   return FALSE;
1669 }
1670
1671 /**
1672  * Gets user info for the given username.
1673  *
1674  * @param info user info object to initialize
1675  * @param username the username
1676  * @param error error return
1677  * @returns #TRUE on success
1678  */
1679 dbus_bool_t
1680 _dbus_user_info_fill (DBusUserInfo     *info,
1681                       const DBusString *username,
1682                       DBusError        *error)
1683 {
1684   return fill_user_info (info, DBUS_UID_UNSET,
1685                          username, error);
1686 }
1687
1688 /**
1689  * Gets user info for the given user ID.
1690  *
1691  * @param info user info object to initialize
1692  * @param uid the user ID
1693  * @param error error return
1694  * @returns #TRUE on success
1695  */
1696 dbus_bool_t
1697 _dbus_user_info_fill_uid (DBusUserInfo *info,
1698                           dbus_uid_t    uid,
1699                           DBusError    *error)
1700 {
1701   return fill_user_info (info, uid,
1702                          NULL, error);
1703 }
1704
1705 /**
1706  * Adds the credentials of the current process to the
1707  * passed-in credentials object.
1708  *
1709  * @param credentials credentials to add to
1710  * @returns #FALSE if no memory; does not properly roll back on failure, so only some credentials may have been added
1711  */
1712 dbus_bool_t
1713 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
1714 {
1715   /* The POSIX spec certainly doesn't promise this, but
1716    * we need these assertions to fail as soon as we're wrong about
1717    * it so we can do the porting fixups
1718    */
1719   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1720   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1721   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1722
1723   if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
1724     return FALSE;
1725   if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
1726     return FALSE;
1727
1728   return TRUE;
1729 }
1730
1731 /**
1732  * Append to the string the identity we would like to have when we
1733  * authenticate, on UNIX this is the current process UID and on
1734  * Windows something else, probably a Windows SID string.  No escaping
1735  * is required, that is done in dbus-auth.c. The username here
1736  * need not be anything human-readable, it can be the machine-readable
1737  * form i.e. a user id.
1738  * 
1739  * @param str the string to append to
1740  * @returns #FALSE on no memory
1741  */
1742 dbus_bool_t
1743 _dbus_append_user_from_current_process (DBusString *str)
1744 {
1745   return _dbus_string_append_uint (str,
1746                                    _dbus_geteuid ());
1747 }
1748
1749 /**
1750  * Gets our process ID
1751  * @returns process ID
1752  */
1753 dbus_pid_t
1754 _dbus_getpid (void)
1755 {
1756   return getpid ();
1757 }
1758
1759 /** Gets our UID
1760  * @returns process UID
1761  */
1762 dbus_uid_t
1763 _dbus_getuid (void)
1764 {
1765   return getuid ();
1766 }
1767
1768 /** Gets our effective UID
1769  * @returns process effective UID
1770  */
1771 dbus_uid_t
1772 _dbus_geteuid (void)
1773 {
1774   return geteuid ();
1775 }
1776
1777 /**
1778  * The only reason this is separate from _dbus_getpid() is to allow it
1779  * on Windows for logging but not for other purposes.
1780  * 
1781  * @returns process ID to put in log messages
1782  */
1783 unsigned long
1784 _dbus_pid_for_log (void)
1785 {
1786   return getpid ();
1787 }
1788
1789 /**
1790  * Gets a UID from a UID string.
1791  *
1792  * @param uid_str the UID in string form
1793  * @param uid UID to fill in
1794  * @returns #TRUE if successfully filled in UID
1795  */
1796 dbus_bool_t
1797 _dbus_parse_uid (const DBusString      *uid_str,
1798                  dbus_uid_t            *uid)
1799 {
1800   int end;
1801   long val;
1802   
1803   if (_dbus_string_get_length (uid_str) == 0)
1804     {
1805       _dbus_verbose ("UID string was zero length\n");
1806       return FALSE;
1807     }
1808
1809   val = -1;
1810   end = 0;
1811   if (!_dbus_string_parse_int (uid_str, 0, &val,
1812                                &end))
1813     {
1814       _dbus_verbose ("could not parse string as a UID\n");
1815       return FALSE;
1816     }
1817   
1818   if (end != _dbus_string_get_length (uid_str))
1819     {
1820       _dbus_verbose ("string contained trailing stuff after UID\n");
1821       return FALSE;
1822     }
1823
1824   *uid = val;
1825
1826   return TRUE;
1827 }
1828
1829
1830 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
1831
1832 #if DBUS_USE_ATOMIC_INT_486_COND
1833 /* Taken from CVS version 1.7 of glibc's sysdeps/i386/i486/atomicity.h */
1834 /* Since the asm stuff here is gcc-specific we go ahead and use "inline" also */
1835 static inline dbus_int32_t
1836 atomic_exchange_and_add (DBusAtomic            *atomic,
1837                          volatile dbus_int32_t  val)
1838 {
1839   register dbus_int32_t result;
1840
1841   __asm__ __volatile__ ("lock; xaddl %0,%1"
1842                         : "=r" (result), "=m" (atomic->value)
1843                         : "0" (val), "m" (atomic->value));
1844   return result;
1845 }
1846 #endif
1847
1848 /**
1849  * Atomically increments an integer
1850  *
1851  * @param atomic pointer to the integer to increment
1852  * @returns the value before incrementing
1853  *
1854  * @todo implement arch-specific faster atomic ops
1855  */
1856 dbus_int32_t
1857 _dbus_atomic_inc (DBusAtomic *atomic)
1858 {
1859 #if DBUS_USE_ATOMIC_INT_486_COND
1860   return atomic_exchange_and_add (atomic, 1);
1861 #else
1862   dbus_int32_t res;
1863   _DBUS_LOCK (atomic);
1864   res = atomic->value;
1865   atomic->value += 1;
1866   _DBUS_UNLOCK (atomic);
1867   return res;
1868 #endif
1869 }
1870
1871 /**
1872  * Atomically decrement an integer
1873  *
1874  * @param atomic pointer to the integer to decrement
1875  * @returns the value before decrementing
1876  *
1877  * @todo implement arch-specific faster atomic ops
1878  */
1879 dbus_int32_t
1880 _dbus_atomic_dec (DBusAtomic *atomic)
1881 {
1882 #if DBUS_USE_ATOMIC_INT_486_COND
1883   return atomic_exchange_and_add (atomic, -1);
1884 #else
1885   dbus_int32_t res;
1886   
1887   _DBUS_LOCK (atomic);
1888   res = atomic->value;
1889   atomic->value -= 1;
1890   _DBUS_UNLOCK (atomic);
1891   return res;
1892 #endif
1893 }
1894
1895 #ifdef DBUS_BUILD_TESTS
1896 /** Gets our GID
1897  * @returns process GID
1898  */
1899 dbus_gid_t
1900 _dbus_getgid (void)
1901 {
1902   return getgid ();
1903 }
1904 #endif
1905
1906 /**
1907  * Wrapper for poll().
1908  *
1909  * @param fds the file descriptors to poll
1910  * @param n_fds number of descriptors in the array
1911  * @param timeout_milliseconds timeout or -1 for infinite
1912  * @returns numbers of fds with revents, or <0 on error
1913  */
1914 int
1915 _dbus_poll (DBusPollFD *fds,
1916             int         n_fds,
1917             int         timeout_milliseconds)
1918 {
1919 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
1920   /* This big thing is a constant expression and should get optimized
1921    * out of existence. So it's more robust than a configure check at
1922    * no cost.
1923    */
1924   if (_DBUS_POLLIN == POLLIN &&
1925       _DBUS_POLLPRI == POLLPRI &&
1926       _DBUS_POLLOUT == POLLOUT &&
1927       _DBUS_POLLERR == POLLERR &&
1928       _DBUS_POLLHUP == POLLHUP &&
1929       _DBUS_POLLNVAL == POLLNVAL &&
1930       sizeof (DBusPollFD) == sizeof (struct pollfd) &&
1931       _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
1932       _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
1933       _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
1934       _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
1935       _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
1936       _DBUS_STRUCT_OFFSET (struct pollfd, revents))
1937     {
1938       return poll ((struct pollfd*) fds,
1939                    n_fds, 
1940                    timeout_milliseconds);
1941     }
1942   else
1943     {
1944       /* We have to convert the DBusPollFD to an array of
1945        * struct pollfd, poll, and convert back.
1946        */
1947       _dbus_warn ("didn't implement poll() properly for this system yet\n");
1948       return -1;
1949     }
1950 #else /* ! HAVE_POLL */
1951
1952   fd_set read_set, write_set, err_set;
1953   int max_fd = 0;
1954   int i;
1955   struct timeval tv;
1956   int ready;
1957   
1958   FD_ZERO (&read_set);
1959   FD_ZERO (&write_set);
1960   FD_ZERO (&err_set);
1961
1962   for (i = 0; i < n_fds; i++)
1963     {
1964       DBusPollFD *fdp = &fds[i];
1965
1966       if (fdp->events & _DBUS_POLLIN)
1967         FD_SET (fdp->fd, &read_set);
1968
1969       if (fdp->events & _DBUS_POLLOUT)
1970         FD_SET (fdp->fd, &write_set);
1971
1972       FD_SET (fdp->fd, &err_set);
1973
1974       max_fd = MAX (max_fd, fdp->fd);
1975     }
1976     
1977   tv.tv_sec = timeout_milliseconds / 1000;
1978   tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
1979
1980   ready = select (max_fd + 1, &read_set, &write_set, &err_set,
1981                   timeout_milliseconds < 0 ? NULL : &tv);
1982
1983   if (ready > 0)
1984     {
1985       for (i = 0; i < n_fds; i++)
1986         {
1987           DBusPollFD *fdp = &fds[i];
1988
1989           fdp->revents = 0;
1990
1991           if (FD_ISSET (fdp->fd, &read_set))
1992             fdp->revents |= _DBUS_POLLIN;
1993
1994           if (FD_ISSET (fdp->fd, &write_set))
1995             fdp->revents |= _DBUS_POLLOUT;
1996
1997           if (FD_ISSET (fdp->fd, &err_set))
1998             fdp->revents |= _DBUS_POLLERR;
1999         }
2000     }
2001
2002   return ready;
2003 #endif
2004 }
2005
2006 /**
2007  * Get current time, as in gettimeofday().
2008  *
2009  * @param tv_sec return location for number of seconds
2010  * @param tv_usec return location for number of microseconds (thousandths)
2011  */
2012 void
2013 _dbus_get_current_time (long *tv_sec,
2014                         long *tv_usec)
2015 {
2016   struct timeval t;
2017
2018   gettimeofday (&t, NULL);
2019
2020   if (tv_sec)
2021     *tv_sec = t.tv_sec;
2022   if (tv_usec)
2023     *tv_usec = t.tv_usec;
2024 }
2025
2026 /**
2027  * Appends the contents of the given file to the string,
2028  * returning error code. At the moment, won't open a file
2029  * more than a megabyte in size.
2030  *
2031  * @param str the string to append to
2032  * @param filename filename to load
2033  * @param error place to set an error
2034  * @returns #FALSE if error was set
2035  */
2036 dbus_bool_t
2037 _dbus_file_get_contents (DBusString       *str,
2038                          const DBusString *filename,
2039                          DBusError        *error)
2040 {
2041   int fd;
2042   struct stat sb;
2043   int orig_len;
2044   int total;
2045   const char *filename_c;
2046
2047   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2048   
2049   filename_c = _dbus_string_get_const_data (filename);
2050   
2051   /* O_BINARY useful on Cygwin */
2052   fd = open (filename_c, O_RDONLY | O_BINARY);
2053   if (fd < 0)
2054     {
2055       dbus_set_error (error, _dbus_error_from_errno (errno),
2056                       "Failed to open \"%s\": %s",
2057                       filename_c,
2058                       _dbus_strerror (errno));
2059       return FALSE;
2060     }
2061
2062   _dbus_verbose ("file fd %d opened\n", fd);
2063   
2064   if (fstat (fd, &sb) < 0)
2065     {
2066       dbus_set_error (error, _dbus_error_from_errno (errno),
2067                       "Failed to stat \"%s\": %s",
2068                       filename_c,
2069                       _dbus_strerror (errno));
2070
2071       _dbus_verbose ("fstat() failed: %s",
2072                      _dbus_strerror (errno));
2073       
2074       _dbus_close (fd, NULL);
2075       
2076       return FALSE;
2077     }
2078
2079   if (sb.st_size > _DBUS_ONE_MEGABYTE)
2080     {
2081       dbus_set_error (error, DBUS_ERROR_FAILED,
2082                       "File size %lu of \"%s\" is too large.",
2083                       (unsigned long) sb.st_size, filename_c);
2084       _dbus_close (fd, NULL);
2085       return FALSE;
2086     }
2087   
2088   total = 0;
2089   orig_len = _dbus_string_get_length (str);
2090   if (sb.st_size > 0 && S_ISREG (sb.st_mode))
2091     {
2092       int bytes_read;
2093
2094       while (total < (int) sb.st_size)
2095         {
2096           bytes_read = _dbus_read (fd, str,
2097                                    sb.st_size - total);
2098           if (bytes_read <= 0)
2099             {
2100               dbus_set_error (error, _dbus_error_from_errno (errno),
2101                               "Error reading \"%s\": %s",
2102                               filename_c,
2103                               _dbus_strerror (errno));
2104
2105               _dbus_verbose ("read() failed: %s",
2106                              _dbus_strerror (errno));
2107               
2108               _dbus_close (fd, NULL);
2109               _dbus_string_set_length (str, orig_len);
2110               return FALSE;
2111             }
2112           else
2113             total += bytes_read;
2114         }
2115
2116       _dbus_close (fd, NULL);
2117       return TRUE;
2118     }
2119   else if (sb.st_size != 0)
2120     {
2121       _dbus_verbose ("Can only open regular files at the moment.\n");
2122       dbus_set_error (error, DBUS_ERROR_FAILED,
2123                       "\"%s\" is not a regular file",
2124                       filename_c);
2125       _dbus_close (fd, NULL);
2126       return FALSE;
2127     }
2128   else
2129     {
2130       _dbus_close (fd, NULL);
2131       return TRUE;
2132     }
2133 }
2134
2135 /**
2136  * Writes a string out to a file. If the file exists,
2137  * it will be atomically overwritten by the new data.
2138  *
2139  * @param str the string to write out
2140  * @param filename the file to save string to
2141  * @param error error to be filled in on failure
2142  * @returns #FALSE on failure
2143  */
2144 dbus_bool_t
2145 _dbus_string_save_to_file (const DBusString *str,
2146                            const DBusString *filename,
2147                            DBusError        *error)
2148 {
2149   int fd;
2150   int bytes_to_write;
2151   const char *filename_c;
2152   DBusString tmp_filename;
2153   const char *tmp_filename_c;
2154   int total;
2155   dbus_bool_t need_unlink;
2156   dbus_bool_t retval;
2157
2158   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2159   
2160   fd = -1;
2161   retval = FALSE;
2162   need_unlink = FALSE;
2163   
2164   if (!_dbus_string_init (&tmp_filename))
2165     {
2166       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2167       return FALSE;
2168     }
2169
2170   if (!_dbus_string_copy (filename, 0, &tmp_filename, 0))
2171     {
2172       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2173       _dbus_string_free (&tmp_filename);
2174       return FALSE;
2175     }
2176   
2177   if (!_dbus_string_append (&tmp_filename, "."))
2178     {
2179       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2180       _dbus_string_free (&tmp_filename);
2181       return FALSE;
2182     }
2183
2184 #define N_TMP_FILENAME_RANDOM_BYTES 8
2185   if (!_dbus_generate_random_ascii (&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES))
2186     {
2187       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2188       _dbus_string_free (&tmp_filename);
2189       return FALSE;
2190     }
2191     
2192   filename_c = _dbus_string_get_const_data (filename);
2193   tmp_filename_c = _dbus_string_get_const_data (&tmp_filename);
2194
2195   fd = open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
2196              0600);
2197   if (fd < 0)
2198     {
2199       dbus_set_error (error, _dbus_error_from_errno (errno),
2200                       "Could not create %s: %s", tmp_filename_c,
2201                       _dbus_strerror (errno));
2202       goto out;
2203     }
2204
2205   _dbus_verbose ("tmp file fd %d opened\n", fd);
2206   
2207   need_unlink = TRUE;
2208   
2209   total = 0;
2210   bytes_to_write = _dbus_string_get_length (str);
2211
2212   while (total < bytes_to_write)
2213     {
2214       int bytes_written;
2215
2216       bytes_written = _dbus_write (fd, str, total,
2217                                    bytes_to_write - total);
2218
2219       if (bytes_written <= 0)
2220         {
2221           dbus_set_error (error, _dbus_error_from_errno (errno),
2222                           "Could not write to %s: %s", tmp_filename_c,
2223                           _dbus_strerror (errno));
2224           
2225           goto out;
2226         }
2227
2228       total += bytes_written;
2229     }
2230
2231   if (fsync(fd))
2232     {
2233       dbus_set_error (error, _dbus_error_from_errno (errno),
2234                       "Could not synchronize file %s: %s",
2235                       tmp_filename_c, _dbus_strerror (errno));
2236
2237       goto out;
2238   }
2239
2240   if (!_dbus_close (fd, NULL))
2241     {
2242       dbus_set_error (error, _dbus_error_from_errno (errno),
2243                       "Could not close file %s: %s",
2244                       tmp_filename_c, _dbus_strerror (errno));
2245
2246       goto out;
2247     }
2248
2249   fd = -1;
2250   
2251   if (rename (tmp_filename_c, filename_c) < 0)
2252     {
2253       dbus_set_error (error, _dbus_error_from_errno (errno),
2254                       "Could not rename %s to %s: %s",
2255                       tmp_filename_c, filename_c,
2256                       _dbus_strerror (errno));
2257
2258       goto out;
2259     }
2260
2261   need_unlink = FALSE;
2262   
2263   retval = TRUE;
2264   
2265  out:
2266   /* close first, then unlink, to prevent ".nfs34234235" garbage
2267    * files
2268    */
2269
2270   if (fd >= 0)
2271     _dbus_close (fd, NULL);
2272         
2273   if (need_unlink && unlink (tmp_filename_c) < 0)
2274     _dbus_verbose ("Failed to unlink temp file %s: %s\n",
2275                    tmp_filename_c, _dbus_strerror (errno));
2276
2277   _dbus_string_free (&tmp_filename);
2278
2279   if (!retval)
2280     _DBUS_ASSERT_ERROR_IS_SET (error);
2281   
2282   return retval;
2283 }
2284
2285 /** Makes the file readable by every user in the system.
2286  *
2287  * @param filename the filename
2288  * @param error error location
2289  * @returns #TRUE if the file's permissions could be changed.
2290  */
2291 dbus_bool_t
2292 _dbus_make_file_world_readable(const DBusString *filename,
2293                                DBusError *error)
2294 {
2295   const char *filename_c;
2296
2297   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2298
2299   filename_c = _dbus_string_get_const_data (filename);
2300   if (chmod (filename_c, 0644) == -1)
2301     {
2302       dbus_set_error (error,
2303                       DBUS_ERROR_FAILED,
2304                       "Could not change permissions of file %s: %s\n",
2305                       filename_c,
2306                       _dbus_strerror (errno));
2307       return FALSE;
2308     }
2309   return TRUE;
2310 }
2311
2312 /** Creates the given file, failing if the file already exists.
2313  *
2314  * @param filename the filename
2315  * @param error error location
2316  * @returns #TRUE if we created the file and it didn't exist
2317  */
2318 dbus_bool_t
2319 _dbus_create_file_exclusively (const DBusString *filename,
2320                                DBusError        *error)
2321 {
2322   int fd;
2323   const char *filename_c;
2324
2325   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2326   
2327   filename_c = _dbus_string_get_const_data (filename);
2328   
2329   fd = open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
2330              0600);
2331   if (fd < 0)
2332     {
2333       dbus_set_error (error,
2334                       DBUS_ERROR_FAILED,
2335                       "Could not create file %s: %s\n",
2336                       filename_c,
2337                       _dbus_strerror (errno));
2338       return FALSE;
2339     }
2340
2341   _dbus_verbose ("exclusive file fd %d opened\n", fd);
2342   
2343   if (!_dbus_close (fd, NULL))
2344     {
2345       dbus_set_error (error,
2346                       DBUS_ERROR_FAILED,
2347                       "Could not close file %s: %s\n",
2348                       filename_c,
2349                       _dbus_strerror (errno));
2350       return FALSE;
2351     }
2352   
2353   return TRUE;
2354 }
2355
2356 /**
2357  * Deletes the given file.
2358  *
2359  * @param filename the filename
2360  * @param error error location
2361  * 
2362  * @returns #TRUE if unlink() succeeded
2363  */
2364 dbus_bool_t
2365 _dbus_delete_file (const DBusString *filename,
2366                    DBusError        *error)
2367 {
2368   const char *filename_c;
2369
2370   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2371   
2372   filename_c = _dbus_string_get_const_data (filename);
2373
2374   if (unlink (filename_c) < 0)
2375     {
2376       dbus_set_error (error, DBUS_ERROR_FAILED,
2377                       "Failed to delete file %s: %s\n",
2378                       filename_c, _dbus_strerror (errno));
2379       return FALSE;
2380     }
2381   else
2382     return TRUE;
2383 }
2384
2385 /**
2386  * Creates a directory; succeeds if the directory
2387  * is created or already existed.
2388  *
2389  * @param filename directory filename
2390  * @param error initialized error object
2391  * @returns #TRUE on success
2392  */
2393 dbus_bool_t
2394 _dbus_create_directory (const DBusString *filename,
2395                         DBusError        *error)
2396 {
2397   const char *filename_c;
2398
2399   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2400   
2401   filename_c = _dbus_string_get_const_data (filename);
2402
2403   if (mkdir (filename_c, 0700) < 0)
2404     {
2405       if (errno == EEXIST)
2406         return TRUE;
2407       
2408       dbus_set_error (error, DBUS_ERROR_FAILED,
2409                       "Failed to create directory %s: %s\n",
2410                       filename_c, _dbus_strerror (errno));
2411       return FALSE;
2412     }
2413   else
2414     return TRUE;
2415 }
2416
2417 /**
2418  * Appends the given filename to the given directory.
2419  *
2420  * @todo it might be cute to collapse multiple '/' such as "foo//"
2421  * concat "//bar"
2422  *
2423  * @param dir the directory name
2424  * @param next_component the filename
2425  * @returns #TRUE on success
2426  */
2427 dbus_bool_t
2428 _dbus_concat_dir_and_file (DBusString       *dir,
2429                            const DBusString *next_component)
2430 {
2431   dbus_bool_t dir_ends_in_slash;
2432   dbus_bool_t file_starts_with_slash;
2433
2434   if (_dbus_string_get_length (dir) == 0 ||
2435       _dbus_string_get_length (next_component) == 0)
2436     return TRUE;
2437   
2438   dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2439                                                     _dbus_string_get_length (dir) - 1);
2440
2441   file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2442
2443   if (dir_ends_in_slash && file_starts_with_slash)
2444     {
2445       _dbus_string_shorten (dir, 1);
2446     }
2447   else if (!(dir_ends_in_slash || file_starts_with_slash))
2448     {
2449       if (!_dbus_string_append_byte (dir, '/'))
2450         return FALSE;
2451     }
2452
2453   return _dbus_string_copy (next_component, 0, dir,
2454                             _dbus_string_get_length (dir));
2455 }
2456
2457 /** nanoseconds in a second */
2458 #define NANOSECONDS_PER_SECOND       1000000000
2459 /** microseconds in a second */
2460 #define MICROSECONDS_PER_SECOND      1000000
2461 /** milliseconds in a second */
2462 #define MILLISECONDS_PER_SECOND      1000
2463 /** nanoseconds in a millisecond */
2464 #define NANOSECONDS_PER_MILLISECOND  1000000
2465 /** microseconds in a millisecond */
2466 #define MICROSECONDS_PER_MILLISECOND 1000
2467
2468 /**
2469  * Sleeps the given number of milliseconds.
2470  * @param milliseconds number of milliseconds
2471  */
2472 void
2473 _dbus_sleep_milliseconds (int milliseconds)
2474 {
2475 #ifdef HAVE_NANOSLEEP
2476   struct timespec req;
2477   struct timespec rem;
2478
2479   req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2480   req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2481   rem.tv_sec = 0;
2482   rem.tv_nsec = 0;
2483
2484   while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2485     req = rem;
2486 #elif defined (HAVE_USLEEP)
2487   usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2488 #else /* ! HAVE_USLEEP */
2489   sleep (MAX (milliseconds / 1000, 1));
2490 #endif
2491 }
2492
2493 static dbus_bool_t
2494 _dbus_generate_pseudorandom_bytes (DBusString *str,
2495                                    int         n_bytes)
2496 {
2497   int old_len;
2498   char *p;
2499   
2500   old_len = _dbus_string_get_length (str);
2501
2502   if (!_dbus_string_lengthen (str, n_bytes))
2503     return FALSE;
2504
2505   p = _dbus_string_get_data_len (str, old_len, n_bytes);
2506
2507   _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
2508
2509   return TRUE;
2510 }
2511
2512 /**
2513  * Generates the given number of random bytes,
2514  * using the best mechanism we can come up with.
2515  *
2516  * @param str the string
2517  * @param n_bytes the number of random bytes to append to string
2518  * @returns #TRUE on success, #FALSE if no memory
2519  */
2520 dbus_bool_t
2521 _dbus_generate_random_bytes (DBusString *str,
2522                              int         n_bytes)
2523 {
2524   int old_len;
2525   int fd;
2526
2527   /* FALSE return means "no memory", if it could
2528    * mean something else then we'd need to return
2529    * a DBusError. So we always fall back to pseudorandom
2530    * if the I/O fails.
2531    */
2532   
2533   old_len = _dbus_string_get_length (str);
2534   fd = -1;
2535
2536   /* note, urandom on linux will fall back to pseudorandom */
2537   fd = open ("/dev/urandom", O_RDONLY);
2538   if (fd < 0)
2539     return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2540
2541   _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2542   
2543   if (_dbus_read (fd, str, n_bytes) != n_bytes)
2544     {
2545       _dbus_close (fd, NULL);
2546       _dbus_string_set_length (str, old_len);
2547       return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2548     }
2549
2550   _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2551                  n_bytes);
2552   
2553   _dbus_close (fd, NULL);
2554   
2555   return TRUE;
2556 }
2557
2558 /**
2559  * Exit the process, returning the given value.
2560  *
2561  * @param code the exit code
2562  */
2563 void
2564 _dbus_exit (int code)
2565 {
2566   _exit (code);
2567 }
2568
2569 /**
2570  * A wrapper around strerror() because some platforms
2571  * may be lame and not have strerror(). Also, never
2572  * returns NULL.
2573  *
2574  * @param error_number errno.
2575  * @returns error description.
2576  */
2577 const char*
2578 _dbus_strerror (int error_number)
2579 {
2580   const char *msg;
2581   
2582   msg = strerror (error_number);
2583   if (msg == NULL)
2584     msg = "unknown";
2585
2586   return msg;
2587 }
2588
2589 /**
2590  * signal (SIGPIPE, SIG_IGN);
2591  */
2592 void
2593 _dbus_disable_sigpipe (void)
2594 {
2595   signal (SIGPIPE, SIG_IGN);
2596 }
2597
2598 /**
2599  * Sets the file descriptor to be close
2600  * on exec. Should be called for all file
2601  * descriptors in D-Bus code.
2602  *
2603  * @param fd the file descriptor
2604  */
2605 void
2606 _dbus_fd_set_close_on_exec (int fd)
2607 {
2608   int val;
2609   
2610   val = fcntl (fd, F_GETFD, 0);
2611   
2612   if (val < 0)
2613     return;
2614
2615   val |= FD_CLOEXEC;
2616   
2617   fcntl (fd, F_SETFD, val);
2618 }
2619
2620 /**
2621  * Closes a file descriptor.
2622  *
2623  * @param fd the file descriptor
2624  * @param error error object
2625  * @returns #FALSE if error set
2626  */
2627 dbus_bool_t
2628 _dbus_close (int        fd,
2629              DBusError *error)
2630 {
2631   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2632   
2633  again:
2634   if (close (fd) < 0)
2635     {
2636       if (errno == EINTR)
2637         goto again;
2638
2639       dbus_set_error (error, _dbus_error_from_errno (errno),
2640                       "Could not close fd %d", fd);
2641       return FALSE;
2642     }
2643
2644   return TRUE;
2645 }
2646
2647 /**
2648  * Sets a file descriptor to be nonblocking.
2649  *
2650  * @param fd the file descriptor.
2651  * @param error address of error location.
2652  * @returns #TRUE on success.
2653  */
2654 dbus_bool_t
2655 _dbus_set_fd_nonblocking (int             fd,
2656                           DBusError      *error)
2657 {
2658   int val;
2659
2660   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2661   
2662   val = fcntl (fd, F_GETFL, 0);
2663   if (val < 0)
2664     {
2665       dbus_set_error (error, _dbus_error_from_errno (errno),
2666                       "Failed to get flags from file descriptor %d: %s",
2667                       fd, _dbus_strerror (errno));
2668       _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
2669                      _dbus_strerror (errno));
2670       return FALSE;
2671     }
2672
2673   if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
2674     {
2675       dbus_set_error (error, _dbus_error_from_errno (errno),
2676                       "Failed to set nonblocking flag of file descriptor %d: %s",
2677                       fd, _dbus_strerror (errno));
2678       _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
2679                      fd, _dbus_strerror (errno));
2680
2681       return FALSE;
2682     }
2683
2684   return TRUE;
2685 }
2686
2687 /**
2688  * On GNU libc systems, print a crude backtrace to stderr.  On other
2689  * systems, print "no backtrace support" and block for possible gdb
2690  * attachment if an appropriate environment variable is set.
2691  */
2692 void
2693 _dbus_print_backtrace (void)
2694 {  
2695 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
2696   void *bt[500];
2697   int bt_size;
2698   int i;
2699   char **syms;
2700   
2701   bt_size = backtrace (bt, 500);
2702
2703   syms = backtrace_symbols (bt, bt_size);
2704   
2705   i = 0;
2706   while (i < bt_size)
2707     {
2708       /* don't use dbus_warn since it can _dbus_abort() */
2709       fprintf (stderr, "  %s\n", syms[i]);
2710       ++i;
2711     }
2712   fflush (stderr);
2713
2714   free (syms);
2715 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
2716   fprintf (stderr, "  D-Bus not built with -rdynamic so unable to print a backtrace\n");
2717 #else
2718   fprintf (stderr, "  D-Bus not compiled with backtrace support so unable to print a backtrace\n");
2719 #endif
2720 }
2721
2722 /**
2723  * Creates a full-duplex pipe (as in socketpair()).
2724  * Sets both ends of the pipe nonblocking.
2725  *
2726  * @todo libdbus only uses this for the debug-pipe server, so in
2727  * principle it could be in dbus-sysdeps-util.c, except that
2728  * dbus-sysdeps-util.c isn't in libdbus when tests are enabled and the
2729  * debug-pipe server is used.
2730  * 
2731  * @param fd1 return location for one end
2732  * @param fd2 return location for the other end
2733  * @param blocking #TRUE if pipe should be blocking
2734  * @param error error return
2735  * @returns #FALSE on failure (if error is set)
2736  */
2737 dbus_bool_t
2738 _dbus_full_duplex_pipe (int        *fd1,
2739                         int        *fd2,
2740                         dbus_bool_t blocking,
2741                         DBusError  *error)
2742 {
2743 #ifdef HAVE_SOCKETPAIR
2744   int fds[2];
2745
2746   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2747   
2748   if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) < 0)
2749     {
2750       dbus_set_error (error, _dbus_error_from_errno (errno),
2751                       "Could not create full-duplex pipe");
2752       return FALSE;
2753     }
2754
2755   if (!blocking &&
2756       (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
2757        !_dbus_set_fd_nonblocking (fds[1], NULL)))
2758     {
2759       dbus_set_error (error, _dbus_error_from_errno (errno),
2760                       "Could not set full-duplex pipe nonblocking");
2761       
2762       _dbus_close (fds[0], NULL);
2763       _dbus_close (fds[1], NULL);
2764       
2765       return FALSE;
2766     }
2767   
2768   *fd1 = fds[0];
2769   *fd2 = fds[1];
2770
2771   _dbus_verbose ("full-duplex pipe %d <-> %d\n",
2772                  *fd1, *fd2);
2773   
2774   return TRUE;  
2775 #else
2776   _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
2777   dbus_set_error (error, DBUS_ERROR_FAILED,
2778                   "_dbus_full_duplex_pipe() not implemented on this OS");
2779   return FALSE;
2780 #endif
2781 }
2782
2783 /**
2784  * Measure the length of the given format string and arguments,
2785  * not including the terminating nul.
2786  *
2787  * @param format a printf-style format string
2788  * @param args arguments for the format string
2789  * @returns length of the given format string and args
2790  */
2791 int
2792 _dbus_printf_string_upper_bound (const char *format,
2793                                  va_list     args)
2794 {
2795   char c;
2796   return vsnprintf (&c, 1, format, args);
2797 }
2798
2799 /**
2800  * Gets the temporary files directory by inspecting the environment variables 
2801  * TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned
2802  *
2803  * @returns location of temp directory
2804  */
2805 const char*
2806 _dbus_get_tmpdir(void)
2807 {
2808   static const char* tmpdir = NULL;
2809
2810   if (tmpdir == NULL)
2811     {
2812       /* TMPDIR is what glibc uses, then
2813        * glibc falls back to the P_tmpdir macro which
2814        * just expands to "/tmp"
2815        */
2816       if (tmpdir == NULL)
2817         tmpdir = getenv("TMPDIR");
2818
2819       /* These two env variables are probably
2820        * broken, but maybe some OS uses them?
2821        */
2822       if (tmpdir == NULL)
2823         tmpdir = getenv("TMP");
2824       if (tmpdir == NULL)
2825         tmpdir = getenv("TEMP");
2826
2827       /* And this is the sane fallback. */
2828       if (tmpdir == NULL)
2829         tmpdir = "/tmp";
2830     }
2831   
2832   _dbus_assert(tmpdir != NULL);
2833   
2834   return tmpdir;
2835 }
2836
2837 /**
2838  * Determines the address of the session bus by querying a
2839  * platform-specific method.
2840  *
2841  * If successful, returns #TRUE and appends the address to @p
2842  * address. If a failure happens, returns #FALSE and
2843  * sets an error in @p error.
2844  *
2845  * @param address a DBusString where the address can be stored
2846  * @param error a DBusError to store the error in case of failure
2847  * @returns #TRUE on success, #FALSE if an error happened
2848  */
2849 dbus_bool_t
2850 _dbus_get_autolaunch_address (DBusString *address,
2851                               DBusError  *error)
2852 {
2853   static char *argv[6];
2854   int address_pipe[2] = { -1, -1 };
2855   int errors_pipe[2] = { -1, -1 };
2856   pid_t pid;
2857   int ret;
2858   int status;
2859   int orig_len;
2860   int i;
2861   DBusString uuid;
2862   dbus_bool_t retval;
2863   
2864   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2865   retval = FALSE;
2866
2867   if (!_dbus_string_init (&uuid))
2868     {
2869       _DBUS_SET_OOM (error);
2870       return FALSE;
2871     }
2872   
2873   if (!_dbus_get_local_machine_uuid_encoded (&uuid))
2874     {
2875       _DBUS_SET_OOM (error);
2876       goto out;
2877     }
2878   
2879   i = 0;
2880   argv[i] = "dbus-launch";
2881   ++i;
2882   argv[i] = "--autolaunch";
2883   ++i;
2884   argv[i] = _dbus_string_get_data (&uuid);
2885   ++i;
2886   argv[i] = "--binary-syntax";
2887   ++i;
2888   argv[i] = "--close-stderr";
2889   ++i;
2890   argv[i] = NULL;
2891   ++i;
2892
2893   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
2894   
2895   orig_len = _dbus_string_get_length (address);
2896   
2897 #define READ_END        0
2898 #define WRITE_END       1
2899   if (pipe (address_pipe) < 0)
2900     {
2901       dbus_set_error (error, _dbus_error_from_errno (errno),
2902                       "Failed to create a pipe: %s",
2903                       _dbus_strerror (errno));
2904       _dbus_verbose ("Failed to create a pipe to call dbus-launch: %s\n",
2905                      _dbus_strerror (errno));
2906       goto out;
2907     }
2908   if (pipe (errors_pipe) < 0)
2909     {
2910       dbus_set_error (error, _dbus_error_from_errno (errno),
2911                       "Failed to create a pipe: %s",
2912                       _dbus_strerror (errno));
2913       _dbus_verbose ("Failed to create a pipe to call dbus-launch: %s\n",
2914                      _dbus_strerror (errno));
2915       goto out;
2916     }
2917
2918   pid = fork ();
2919   if (pid < 0)
2920     {
2921       dbus_set_error (error, _dbus_error_from_errno (errno),
2922                       "Failed to fork(): %s",
2923                       _dbus_strerror (errno));
2924       _dbus_verbose ("Failed to fork() to call dbus-launch: %s\n",
2925                      _dbus_strerror (errno));
2926       goto out;
2927     }
2928
2929   if (pid == 0)
2930     {
2931       /* child process */
2932       int maxfds;
2933       int fd;
2934
2935       fd = open ("/dev/null", O_RDWR);
2936       if (fd == -1)
2937         /* huh?! can't open /dev/null? */
2938         _exit (1);
2939
2940       _dbus_verbose ("/dev/null fd %d opened\n", fd);
2941       
2942       /* set-up stdXXX */
2943       close (address_pipe[READ_END]);
2944       close (errors_pipe[READ_END]);
2945       close (0);                /* close stdin */
2946       close (1);                /* close stdout */
2947       close (2);                /* close stderr */
2948
2949       if (dup2 (fd, 0) == -1)
2950         _exit (1);
2951       if (dup2 (address_pipe[WRITE_END], 1) == -1)
2952         _exit (1);
2953       if (dup2 (errors_pipe[WRITE_END], 2) == -1)
2954         _exit (1);
2955
2956       maxfds = sysconf (_SC_OPEN_MAX);
2957       /* Pick something reasonable if for some reason sysconf
2958        * says unlimited.
2959        */
2960       if (maxfds < 0)
2961         maxfds = 1024;
2962       /* close all inherited fds */
2963       for (i = 3; i < maxfds; i++)
2964         close (i);
2965
2966       execv (DBUS_BINDIR "/dbus-launch", argv);
2967
2968       /* failed, try searching PATH */
2969       execvp ("dbus-launch", argv);
2970
2971       /* still nothing, we failed */
2972       _exit (1);
2973     }
2974
2975   /* parent process */
2976   close (address_pipe[WRITE_END]);
2977   close (errors_pipe[WRITE_END]);
2978   address_pipe[WRITE_END] = -1;
2979   errors_pipe[WRITE_END] = -1;
2980
2981   ret = 0;
2982   do 
2983     {
2984       ret = _dbus_read (address_pipe[READ_END], address, 1024);
2985     }
2986   while (ret > 0);
2987
2988   /* reap the child process to avoid it lingering as zombie */
2989   do
2990     {
2991       ret = waitpid (pid, &status, 0);
2992     }
2993   while (ret == -1 && errno == EINTR);
2994
2995   /* We succeeded if the process exited with status 0 and
2996      anything was read */
2997   if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 ||
2998       _dbus_string_get_length (address) == orig_len)
2999     {
3000       /* The process ended with error */
3001       DBusString error_message;
3002       _dbus_string_init (&error_message);
3003       ret = 0;
3004       do
3005         {
3006           ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3007         }
3008       while (ret > 0);
3009
3010       _dbus_string_set_length (address, orig_len);
3011       if (_dbus_string_get_length (&error_message) > 0)
3012         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3013                         "dbus-launch failed to autolaunch D-Bus session: %s",
3014                         _dbus_string_get_data (&error_message));
3015       else
3016         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3017                         "Failed to execute dbus-launch to autolaunch D-Bus session");
3018       goto out;
3019     }
3020
3021   retval = TRUE;
3022   
3023  out:
3024   if (retval)
3025     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3026   else
3027     _DBUS_ASSERT_ERROR_IS_SET (error);
3028
3029   if (address_pipe[0] != -1)
3030     close (address_pipe[0]);
3031   if (address_pipe[1] != -1)
3032     close (address_pipe[1]);
3033   if (errors_pipe[0] != -1)
3034     close (errors_pipe[0]);
3035   if (errors_pipe[1] != -1)
3036     close (errors_pipe[1]);
3037
3038   _dbus_string_free (&uuid);
3039   return retval;
3040 }
3041
3042 /**
3043  * Reads the uuid of the machine we're running on from
3044  * the dbus configuration. Optionally try to create it
3045  * (only root can do this usually).
3046  *
3047  * On UNIX, reads a file that gets created by dbus-uuidgen
3048  * in a post-install script. On Windows, if there's a standard
3049  * machine uuid we could just use that, but I can't find one
3050  * with the right properties (the hardware profile guid can change
3051  * without rebooting I believe). If there's no standard one
3052  * we might want to use the registry instead of a file for
3053  * this, and I'm not sure how we'd ensure the uuid gets created.
3054  *
3055  * @param machine_id guid to init with the machine's uuid
3056  * @param create_if_not_found try to create the uuid if it doesn't exist
3057  * @param error the error return
3058  * @returns #FALSE if the error is set
3059  */
3060 dbus_bool_t
3061 _dbus_read_local_machine_uuid (DBusGUID   *machine_id,
3062                                dbus_bool_t create_if_not_found,
3063                                DBusError  *error)
3064 {
3065   DBusString filename;
3066   _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3067   return _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
3068 }
3069
3070 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
3071 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
3072
3073
3074 /**
3075  * Returns the standard directories for a session bus to look for service 
3076  * activation files 
3077  *
3078  * On UNIX this should be the standard xdg freedesktop.org data directories:
3079  *
3080  * XDG_DATA_HOME=${XDG_DATA_HOME-$HOME/.local/share}
3081  * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3082  *
3083  * and
3084  *
3085  * DBUS_DATADIR
3086  *
3087  * @param dirs the directory list we are returning
3088  * @returns #FALSE on OOM 
3089  */
3090
3091 dbus_bool_t 
3092 _dbus_get_standard_session_servicedirs (DBusList **dirs)
3093 {
3094   const char *xdg_data_home;
3095   const char *xdg_data_dirs;
3096   DBusString servicedir_path;
3097
3098   if (!_dbus_string_init (&servicedir_path))
3099     return FALSE;
3100
3101   xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
3102   xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3103
3104   if (xdg_data_dirs != NULL)
3105     {
3106       if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3107         goto oom;
3108
3109       if (!_dbus_string_append (&servicedir_path, ":"))
3110         goto oom;
3111     }
3112   else
3113     {
3114       if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3115         goto oom;
3116     }
3117
3118   /* 
3119    * add configured datadir to defaults
3120    * this may be the same as an xdg dir
3121    * however the config parser should take 
3122    * care of duplicates 
3123    */
3124   if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
3125         goto oom;
3126
3127   if (xdg_data_home != NULL)
3128     {
3129       if (!_dbus_string_append (&servicedir_path, xdg_data_home))
3130         goto oom;
3131     }
3132   else
3133     {
3134       const DBusString *homedir;
3135       DBusString local_share;
3136
3137       if (!_dbus_homedir_from_current_process (&homedir))
3138         goto oom;
3139        
3140       if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
3141         goto oom;
3142
3143       _dbus_string_init_const (&local_share, "/.local/share");
3144       if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
3145         goto oom;
3146     }
3147
3148   if (!_dbus_split_paths_and_append (&servicedir_path, 
3149                                      DBUS_UNIX_STANDARD_SESSION_SERVICEDIR, 
3150                                      dirs))
3151     goto oom;
3152
3153   _dbus_string_free (&servicedir_path);  
3154   return TRUE;
3155
3156  oom:
3157   _dbus_string_free (&servicedir_path);
3158   return FALSE;
3159 }
3160
3161
3162 /**
3163  * Returns the standard directories for a system bus to look for service 
3164  * activation files 
3165  *
3166  * On UNIX this should be the standard xdg freedesktop.org data directories:
3167  *
3168  * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3169  *
3170  * and
3171  *
3172  * DBUS_DATADIR
3173  *
3174  * On Windows there is no system bus and this function can return nothing.
3175  *
3176  * @param dirs the directory list we are returning
3177  * @returns #FALSE on OOM 
3178  */
3179
3180 dbus_bool_t 
3181 _dbus_get_standard_system_servicedirs (DBusList **dirs)
3182 {
3183   const char *xdg_data_dirs;
3184   DBusString servicedir_path;
3185
3186   if (!_dbus_string_init (&servicedir_path))
3187     return FALSE;
3188
3189   xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3190
3191   if (xdg_data_dirs != NULL)
3192     {
3193       if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3194         goto oom;
3195
3196       if (!_dbus_string_append (&servicedir_path, ":"))
3197         goto oom;
3198     }
3199   else
3200     {
3201       if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3202         goto oom;
3203     }
3204
3205   /* 
3206    * add configured datadir to defaults
3207    * this may be the same as an xdg dir
3208    * however the config parser should take 
3209    * care of duplicates 
3210    */
3211   if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
3212         goto oom;
3213
3214   if (!_dbus_split_paths_and_append (&servicedir_path, 
3215                                      DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR, 
3216                                      dirs))
3217     goto oom;
3218
3219   _dbus_string_free (&servicedir_path);  
3220   return TRUE;
3221
3222  oom:
3223   _dbus_string_free (&servicedir_path);
3224   return FALSE;
3225 }
3226
3227 /**
3228  * Append the absolute path of the system.conf file
3229  * (there is no system bus on Windows so this can just
3230  * return FALSE and print a warning or something)
3231  * 
3232  * @param str the string to append to
3233  * @returns #FALSE if no memory
3234  */
3235 dbus_bool_t
3236 _dbus_append_system_config_file (DBusString *str)
3237 {
3238   return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
3239 }
3240
3241 /**
3242  * Append the absolute path of the session.conf file.
3243  * 
3244  * @param str the string to append to
3245  * @returns #FALSE if no memory
3246  */
3247 dbus_bool_t
3248 _dbus_append_session_config_file (DBusString *str)
3249 {
3250   return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
3251 }
3252
3253 /**
3254  * Called when the bus daemon is signaled to reload its configuration; any
3255  * caches should be nuked. Of course any caches that need explicit reload
3256  * are probably broken, but c'est la vie.
3257  *
3258  * 
3259  */
3260 void
3261 _dbus_flush_caches (void)
3262 {
3263   _dbus_user_database_flush_system ();
3264 }
3265
3266 /**
3267  * Appends the directory in which a keyring for the given credentials
3268  * should be stored.  The credentials should have either a Windows or
3269  * UNIX user in them.  The directory should be an absolute path.
3270  *
3271  * On UNIX the directory is ~/.dbus-keyrings while on Windows it should probably
3272  * be something else, since the dotfile convention is not normal on Windows.
3273  * 
3274  * @param directory string to append directory to
3275  * @param credentials credentials the directory should be for
3276  *  
3277  * @returns #FALSE on no memory
3278  */
3279 dbus_bool_t
3280 _dbus_append_keyring_directory_for_credentials (DBusString      *directory,
3281                                                 DBusCredentials *credentials)
3282 {
3283   DBusString homedir;
3284   DBusString dotdir;
3285   dbus_uid_t uid;
3286   
3287   _dbus_assert (credentials != NULL);
3288   _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
3289   
3290   if (!_dbus_string_init (&homedir))
3291     return FALSE;
3292
3293   uid = _dbus_credentials_get_unix_uid (credentials);
3294   _dbus_assert (uid != DBUS_UID_UNSET);
3295
3296   if (!_dbus_homedir_from_uid (uid, &homedir))
3297     goto failed;
3298   
3299 #ifdef DBUS_BUILD_TESTS
3300   {
3301     const char *override;
3302     
3303     override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3304     if (override != NULL && *override != '\0')
3305       {
3306         _dbus_string_set_length (&homedir, 0);
3307         if (!_dbus_string_append (&homedir, override))
3308           goto failed;
3309
3310         _dbus_verbose ("Using fake homedir for testing: %s\n",
3311                        _dbus_string_get_const_data (&homedir));
3312       }
3313     else
3314       {
3315         static dbus_bool_t already_warned = FALSE;
3316         if (!already_warned)
3317           {
3318             _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3319             already_warned = TRUE;
3320           }
3321       }
3322   }
3323 #endif
3324
3325   _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3326   if (!_dbus_concat_dir_and_file (&homedir,
3327                                   &dotdir))
3328     goto failed;
3329   
3330   if (!_dbus_string_copy (&homedir, 0,
3331                           directory, _dbus_string_get_length (directory))) {
3332     goto failed;
3333   }
3334
3335   _dbus_string_free (&homedir);
3336   return TRUE;
3337   
3338  failed: 
3339   _dbus_string_free (&homedir);
3340   return FALSE;
3341 }
3342
3343
3344 /**
3345  * See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently
3346  * for Winsock so is abstracted)
3347  *
3348  * @returns #TRUE if errno == EAGAIN or errno == EWOULDBLOCK
3349  */
3350 dbus_bool_t
3351 _dbus_get_is_errno_eagain_or_ewouldblock (void)
3352 {
3353   return errno == EAGAIN || errno == EWOULDBLOCK;
3354 }
3355
3356 /* tests in dbus-sysdeps-util.c */