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