2003-04-01 Havoc Pennington <hp@redhat.com>
[platform/upstream/dbus.git] / dbus / dbus-sysdeps.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-sysdeps.c Wrappers around system/libc features (internal to D-BUS implementation)
3  * 
4  * Copyright (C) 2002, 2003  Red Hat, Inc.
5  *
6  * Licensed under the Academic Free License version 1.2
7  * 
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  * 
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  */
23
24 #include "dbus-internals.h"
25 #include "dbus-sysdeps.h"
26 #include "dbus-threads.h"
27 #include <sys/types.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <signal.h>
31 #include <unistd.h>
32 #include <stdio.h>
33 #include <errno.h>
34 #include <unistd.h>
35 #include <fcntl.h>
36 #include <sys/socket.h>
37 #include <dirent.h>
38 #include <sys/un.h>
39 #include <pwd.h>
40 #include <time.h>
41 #include <sys/time.h>
42 #include <sys/stat.h>
43 #include <sys/wait.h>
44 #include <netinet/in.h>
45 #include <netdb.h>
46 #include <grp.h>
47
48 #ifdef HAVE_WRITEV
49 #include <sys/uio.h>
50 #endif
51 #ifdef HAVE_POLL
52 #include <sys/poll.h>
53 #endif
54 #ifdef HAVE_BACKTRACE
55 #include <execinfo.h>
56 #endif
57
58
59 #ifndef O_BINARY
60 #define O_BINARY 0
61 #endif
62
63 #ifndef SUN_LEN
64 /* This system is not POSIX.1g.         */
65 #define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path)  \
66        + strlen ((ptr)->sun_path))
67 #endif
68
69 /**
70  * @addtogroup DBusInternalsUtils
71  * @{
72  */
73 /**
74  * Aborts the program with SIGABRT (dumping core).
75  */
76 void
77 _dbus_abort (void)
78 {
79   abort ();
80   _exit (1); /* in case someone manages to ignore SIGABRT */
81 }
82
83 /**
84  * Wrapper for setenv().
85  *
86  * @param varname name of environment variable
87  * @param value value of environment variable
88  * @returns #TRUE on success.
89  */
90 dbus_bool_t
91 _dbus_setenv (const char *varname, const char *value)
92 {
93 #ifdef HAVE_SETENV
94   return (setenv (varname, value, TRUE) == 0);
95 #else
96   DBusString str;
97   char *putenv_value;
98
99   if (!_dbus_string_init (&str))
100     return FALSE;
101
102   if (!_dbus_string_append (&str, varname) ||
103       !_dbus_string_append (&str, "=") ||
104       !_dbus_string_append (&str, value) ||
105       !_dbus_string_steal_data (&str, &putenv_value))
106     {
107       _dbus_string_free (&str);
108       return FALSE;
109     }
110
111   _dbus_string_free (&str);
112
113   return (putenv (putenv_value) == 0);
114 #endif
115 }
116
117 /**
118  * Wrapper for getenv().
119  *
120  * @param varname name of environment variable
121  * @returns value of environment variable or #NULL if unset
122  */
123 const char*
124 _dbus_getenv (const char *varname)
125 {  
126   return getenv (varname);
127 }
128
129 /**
130  * Thin wrapper around the read() system call that appends
131  * the data it reads to the DBusString buffer. It appends
132  * up to the given count, and returns the same value
133  * and same errno as read(). The only exception is that
134  * _dbus_read() handles EINTR for you. _dbus_read() can
135  * return ENOMEM, even though regular UNIX read doesn't.
136  *
137  * @param fd the file descriptor to read from
138  * @param buffer the buffer to append data to
139  * @param count the amount of data to read
140  * @returns the number of bytes read or -1
141  */
142 int
143 _dbus_read (int               fd,
144             DBusString       *buffer,
145             int               count)
146 {
147   int bytes_read;
148   int start;
149   char *data;
150
151   _dbus_assert (count >= 0);
152   
153   start = _dbus_string_get_length (buffer);
154
155   if (!_dbus_string_lengthen (buffer, count))
156     {
157       errno = ENOMEM;
158       return -1;
159     }
160
161   data = _dbus_string_get_data_len (buffer, start, count);
162
163  again:
164   
165   bytes_read = read (fd, data, count);
166
167   if (bytes_read < 0)
168     {
169       if (errno == EINTR)
170         goto again;
171       else
172         {
173           /* put length back (note that this doesn't actually realloc anything) */
174           _dbus_string_set_length (buffer, start);
175           return -1;
176         }
177     }
178   else
179     {
180       /* put length back (doesn't actually realloc) */
181       _dbus_string_set_length (buffer, start + bytes_read);
182
183 #if 0
184       if (bytes_read > 0)
185         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
186 #endif
187       
188       return bytes_read;
189     }
190 }
191
192 /**
193  * Thin wrapper around the write() system call that writes a part of a
194  * DBusString and handles EINTR for you.
195  * 
196  * @param fd the file descriptor to write
197  * @param buffer the buffer to write data from
198  * @param start the first byte in the buffer to write
199  * @param len the number of bytes to try to write
200  * @returns the number of bytes written or -1 on error
201  */
202 int
203 _dbus_write (int               fd,
204              const DBusString *buffer,
205              int               start,
206              int               len)
207 {
208   const char *data;
209   int bytes_written;
210   
211   data = _dbus_string_get_const_data_len (buffer, start, len);
212   
213  again:
214
215   bytes_written = write (fd, data, len);
216
217   if (bytes_written < 0 && errno == EINTR)
218     goto again;
219
220 #if 0
221   if (bytes_written > 0)
222     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
223 #endif
224   
225   return bytes_written;
226 }
227
228 /**
229  * Like _dbus_write() but will use writev() if possible
230  * to write both buffers in sequence. The return value
231  * is the number of bytes written in the first buffer,
232  * plus the number written in the second. If the first
233  * buffer is written successfully and an error occurs
234  * writing the second, the number of bytes in the first
235  * is returned (i.e. the error is ignored), on systems that
236  * don't have writev. Handles EINTR for you.
237  * The second buffer may be #NULL.
238  *
239  * @param fd the file descriptor
240  * @param buffer1 first buffer
241  * @param start1 first byte to write in first buffer
242  * @param len1 number of bytes to write from first buffer
243  * @param buffer2 second buffer, or #NULL
244  * @param start2 first byte to write in second buffer
245  * @param len2 number of bytes to write in second buffer
246  * @returns total bytes written from both buffers, or -1 on error
247  */
248 int
249 _dbus_write_two (int               fd,
250                  const DBusString *buffer1,
251                  int               start1,
252                  int               len1,
253                  const DBusString *buffer2,
254                  int               start2,
255                  int               len2)
256 {
257   _dbus_assert (buffer1 != NULL);
258   _dbus_assert (start1 >= 0);
259   _dbus_assert (start2 >= 0);
260   _dbus_assert (len1 >= 0);
261   _dbus_assert (len2 >= 0);
262   
263 #ifdef HAVE_WRITEV
264   {
265     struct iovec vectors[2];
266     const char *data1;
267     const char *data2;
268     int bytes_written;
269
270     data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
271
272     if (buffer2 != NULL)
273       data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
274     else
275       {
276         data2 = NULL;
277         start2 = 0;
278         len2 = 0;
279       }
280    
281     vectors[0].iov_base = (char*) data1;
282     vectors[0].iov_len = len1;
283     vectors[1].iov_base = (char*) data2;
284     vectors[1].iov_len = len2;
285
286   again:
287    
288     bytes_written = writev (fd,
289                             vectors,
290                             data2 ? 2 : 1);
291
292     if (bytes_written < 0 && errno == EINTR)
293       goto again;
294    
295     return bytes_written;
296   }
297 #else /* HAVE_WRITEV */
298   {
299     int ret1;
300     
301     ret1 = _dbus_write (fd, buffer1, start1, len1);
302     if (ret1 == len1 && buffer2 != NULL)
303       {
304         ret2 = _dbus_write (fd, buffer2, start2, len2);
305         if (ret2 < 0)
306           ret2 = 0; /* we can't report an error as the first write was OK */
307        
308         return ret1 + ret2;
309       }
310     else
311       return ret1;
312   }
313 #endif /* !HAVE_WRITEV */   
314 }
315
316 #define _DBUS_MAX_SUN_PATH_LENGTH 99
317
318 /**
319  * @def _DBUS_MAX_SUN_PATH_LENGTH
320  *
321  * Maximum length of the path to a UNIX domain socket,
322  * sockaddr_un::sun_path member. POSIX requires that all systems
323  * support at least 100 bytes here, including the nul termination.
324  * We use 99 for the max value to allow for the nul.
325  *
326  * We could probably also do sizeof (addr.sun_path)
327  * but this way we are the same on all platforms
328  * which is probably a good idea.
329  */
330
331 /**
332  * Creates a socket and connects it to the UNIX domain socket at the
333  * given path.  The connection fd is returned, and is set up as
334  * nonblocking.
335  *
336  * @param path the path to UNIX domain socket
337  * @param error return location for error code
338  * @returns connection file descriptor or -1 on error
339  */
340 int
341 _dbus_connect_unix_socket (const char     *path,
342                            DBusError      *error)
343 {
344   int fd;
345   struct sockaddr_un addr;  
346
347   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
348   
349   fd = socket (PF_UNIX, SOCK_STREAM, 0);
350   
351   if (fd < 0)
352     {
353       dbus_set_error (error,
354                       _dbus_error_from_errno (errno),
355                       "Failed to create socket: %s",
356                       _dbus_strerror (errno)); 
357       
358       return -1;
359     }
360
361   _DBUS_ZERO (addr);
362   addr.sun_family = AF_UNIX;
363   strncpy (addr.sun_path, path, _DBUS_MAX_SUN_PATH_LENGTH - 1);
364   
365   if (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0)
366     {      
367       dbus_set_error (error,
368                       _dbus_error_from_errno (errno),
369                       "Failed to connect to socket %s: %s",
370                       path, _dbus_strerror (errno));
371
372       close (fd);
373       fd = -1;
374       
375       return -1;
376     }
377
378   if (!_dbus_set_fd_nonblocking (fd, error))
379     {
380       _DBUS_ASSERT_ERROR_IS_SET (error);
381       
382       close (fd);
383       fd = -1;
384
385       return -1;
386     }
387
388   return fd;
389 }
390
391 /**
392  * Creates a socket and binds it to the given path,
393  * then listens on the socket. The socket is
394  * set to be nonblocking.
395  *
396  * @todo we'd like to be able to use the abstract namespace on linux
397  * (see "man 7 unix"). The question is whether to silently move all
398  * paths into that namespace if we can (I think that's best) or to
399  * require it to be specified explicitly in the dbus address.  Also,
400  * need to sort out how to check for abstract namespace support.
401  *
402  * @param path the socket name
403  * @param error return location for errors
404  * @returns the listening file descriptor or -1 on error
405  */
406 int
407 _dbus_listen_unix_socket (const char     *path,
408                           DBusError      *error)
409 {
410   int listen_fd;
411   struct sockaddr_un addr;
412
413   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
414   
415   listen_fd = socket (PF_UNIX, SOCK_STREAM, 0);
416   
417   if (listen_fd < 0)
418     {
419       dbus_set_error (error, _dbus_error_from_errno (errno),
420                       "Failed to create socket \"%s\": %s",
421                       path, _dbus_strerror (errno));
422       return -1;
423     }
424
425   /* FIXME discussed security implications of this with Nalin,
426    * and we couldn't think of where it would kick our ass, but
427    * it still seems a bit sucky. It also has non-security suckage;
428    * really we'd prefer to exit if the socket is already in use.
429    * But there doesn't seem to be a good way to do this.
430    *
431    * Just to be extra careful, I threw in the stat() - clearly
432    * the stat() can't *fix* any security issue, but it probably
433    * makes it harder to exploit.
434    */
435   {
436     struct stat sb;
437
438     if (stat (path, &sb) == 0 &&
439         S_ISSOCK (sb.st_mode))
440       unlink (path);
441   }
442   
443   _DBUS_ZERO (addr);
444   addr.sun_family = AF_UNIX;
445   strncpy (addr.sun_path, path, _DBUS_MAX_SUN_PATH_LENGTH - 1);
446   
447   if (bind (listen_fd, (struct sockaddr*) &addr, SUN_LEN (&addr)) < 0)
448     {
449       dbus_set_error (error, _dbus_error_from_errno (errno),
450                       "Failed to bind socket \"%s\": %s",
451                       path, _dbus_strerror (errno));
452       close (listen_fd);
453       return -1;
454     }
455
456   if (listen (listen_fd, 30 /* backlog */) < 0)
457     {
458       dbus_set_error (error, _dbus_error_from_errno (errno),
459                       "Failed to listen on socket \"%s\": %s",
460                       path, _dbus_strerror (errno));
461       close (listen_fd);
462       return -1;
463     }
464
465   if (!_dbus_set_fd_nonblocking (listen_fd, error))
466     {
467       _DBUS_ASSERT_ERROR_IS_SET (error);
468       close (listen_fd);
469       return -1;
470     }
471
472   /* Try opening up the permissions, but if we can't, just go ahead
473    * and continue, maybe it will be good enough.
474    */
475   if (chmod (path, 0777) < 0)
476     _dbus_warn ("Could not set mode 0777 on socket %s\n",
477                 path);
478   
479   return listen_fd;
480 }
481
482 /**
483  * Creates a socket and connects to a socket at the given host 
484  * and port. The connection fd is returned, and is set up as
485  * nonblocking.
486  *
487  * @param host the host name to connect to
488  * @param port the prot to connect to
489  * @param error return location for error code
490  * @returns connection file descriptor or -1 on error
491  */
492 int
493 _dbus_connect_tcp_socket (const char     *host,
494                           dbus_uint32_t   port,
495                           DBusError      *error)
496 {
497   int fd;
498   struct sockaddr_in addr;
499   struct hostent *he;
500   struct in_addr *haddr;
501
502   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
503   
504   fd = socket (AF_INET, SOCK_STREAM, 0);
505   
506   if (fd < 0)
507     {
508       dbus_set_error (error,
509                       _dbus_error_from_errno (errno),
510                       "Failed to create socket: %s",
511                       _dbus_strerror (errno)); 
512       
513       return -1;
514     }
515
516   if (host == NULL)
517     host = "localhost";
518
519   he = gethostbyname (host);
520   if (he == NULL) 
521     {
522       dbus_set_error (error,
523                       _dbus_error_from_errno (errno),
524                       "Failed to lookup hostname: %s",
525                       host);
526       return -1;
527     }
528   
529   haddr = ((struct in_addr *) (he->h_addr_list)[0]);
530
531   _DBUS_ZERO (addr);
532   memcpy (&addr.sin_addr, haddr, sizeof(struct in_addr));
533   addr.sin_family = AF_INET;
534   addr.sin_port = htons (port);
535   
536   if (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0)
537     {      
538       dbus_set_error (error,
539                        _dbus_error_from_errno (errno),
540                       "Failed to connect to socket %s: %s:%d",
541                       host, _dbus_strerror (errno), port);
542
543       close (fd);
544       fd = -1;
545       
546       return -1;
547     }
548
549   if (!_dbus_set_fd_nonblocking (fd, error))
550     {
551       close (fd);
552       fd = -1;
553
554       return -1;
555     }
556
557   return fd;
558 }
559
560 /**
561  * Creates a socket and binds it to the given path,
562  * then listens on the socket. The socket is
563  * set to be nonblocking. 
564  *
565  * @param host the host name to listen on
566  * @param port the prot to listen on
567  * @param error return location for errors
568  * @returns the listening file descriptor or -1 on error
569  */
570 int
571 _dbus_listen_tcp_socket (const char     *host,
572                          dbus_uint32_t   port,
573                          DBusError      *error)
574 {
575   int listen_fd;
576   struct sockaddr_in addr;
577   struct hostent *he;
578   struct in_addr *haddr;
579
580   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
581   
582   listen_fd = socket (AF_INET, SOCK_STREAM, 0);
583   
584   if (listen_fd < 0)
585     {
586       dbus_set_error (error, _dbus_error_from_errno (errno),
587                       "Failed to create socket \"%s:%d\": %s",
588                       host, port, _dbus_strerror (errno));
589       return -1;
590     }
591
592   if (host == NULL)
593     host = "localhost";
594   
595   he = gethostbyname (host);
596   if (he == NULL) 
597     {
598       dbus_set_error (error,
599                       _dbus_error_from_errno (errno),
600                       "Failed to lookup hostname: %s",
601                       host);
602       return -1;
603     }
604   
605   haddr = ((struct in_addr *) (he->h_addr_list)[0]);
606
607   _DBUS_ZERO (addr);
608   memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr));
609   addr.sin_family = AF_INET;
610   addr.sin_port = htons (port);
611
612   if (bind (listen_fd, (struct sockaddr*) &addr, sizeof (struct sockaddr)))
613     {
614       dbus_set_error (error, _dbus_error_from_errno (errno),
615                       "Failed to bind socket \"%s:%d\": %s",
616                       host, port, _dbus_strerror (errno));
617       close (listen_fd);
618       return -1;
619     }
620
621   if (listen (listen_fd, 30 /* backlog */) < 0)
622     {
623       dbus_set_error (error, _dbus_error_from_errno (errno),  
624                       "Failed to listen on socket \"%s:%d\": %s",
625                       host, port, _dbus_strerror (errno));
626       close (listen_fd);
627       return -1;
628     }
629
630   if (!_dbus_set_fd_nonblocking (listen_fd, error))
631     {
632       close (listen_fd);
633       return -1;
634     }
635   
636   return listen_fd;
637 }
638
639 static dbus_bool_t
640 write_credentials_byte (int             server_fd,
641                         DBusError      *error)
642 {
643   int bytes_written;
644   char buf[1] = { '\0' };
645
646   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
647   
648  again:
649
650   bytes_written = write (server_fd, buf, 1);
651
652   if (bytes_written < 0 && errno == EINTR)
653     goto again;
654
655   if (bytes_written < 0)
656     {
657       dbus_set_error (error, _dbus_error_from_errno (errno),
658                       "Failed to write credentials byte: %s",
659                      _dbus_strerror (errno));
660       return FALSE;
661     }
662   else if (bytes_written == 0)
663     {
664       dbus_set_error (error, DBUS_ERROR_IO_ERROR,
665                       "wrote zero bytes writing credentials byte");
666       return FALSE;
667     }
668   else
669     {
670       _dbus_assert (bytes_written == 1);
671       _dbus_verbose ("wrote credentials byte\n");
672       return TRUE;
673     }
674 }
675
676 /**
677  * Reads a single byte which must be nul (an error occurs otherwise),
678  * and reads unix credentials if available. Fills in pid/uid/gid with
679  * -1 if no credentials are available. Return value indicates whether
680  * a byte was read, not whether we got valid credentials. On some
681  * systems, such as Linux, reading/writing the byte isn't actually
682  * required, but we do it anyway just to avoid multiple codepaths.
683  * 
684  * Fails if no byte is available, so you must select() first.
685  *
686  * The point of the byte is that on some systems we have to
687  * use sendmsg()/recvmsg() to transmit credentials.
688  *
689  * @param client_fd the client file descriptor
690  * @param credentials struct to fill with credentials of client
691  * @param error location to store error code
692  * @returns #TRUE on success
693  */
694 dbus_bool_t
695 _dbus_read_credentials_unix_socket  (int              client_fd,
696                                      DBusCredentials *credentials,
697                                      DBusError       *error)
698 {
699   struct msghdr msg;
700   struct iovec iov;
701   char buf;
702
703 #ifdef HAVE_CMSGCRED 
704   char cmsgmem[CMSG_SPACE (sizeof (struct cmsgcred))];
705   struct cmsghdr *cmsg = (struct cmsghdr *) cmsgmem;
706 #endif
707
708   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
709   
710   /* The POSIX spec certainly doesn't promise this, but
711    * we need these assertions to fail as soon as we're wrong about
712    * it so we can do the porting fixups
713    */
714   _dbus_assert (sizeof (pid_t) <= sizeof (credentials->pid));
715   _dbus_assert (sizeof (uid_t) <= sizeof (credentials->uid));
716   _dbus_assert (sizeof (gid_t) <= sizeof (credentials->gid));
717   
718   credentials->pid = -1;
719   credentials->uid = -1;
720   credentials->gid = -1;
721
722 #if defined(LOCAL_CREDS) && defined(HAVE_CMSGCRED)
723   /* Set the socket to receive credentials on the next message */
724   {
725     int on = 1;
726     if (setsockopt (client_fd, 0, LOCAL_CREDS, &on, sizeof (on)) < 0)
727       {
728         _dbus_verbose ("Unable to set LOCAL_CREDS socket option\n");
729         return FALSE;
730       }
731   }
732 #endif
733
734   iov.iov_base = &buf;
735   iov.iov_len = 1;
736
737   memset (&msg, 0, sizeof (msg));
738   msg.msg_iov = &iov;
739   msg.msg_iovlen = 1;
740
741 #ifdef HAVE_CMSGCRED
742   memset (cmsgmem, 0, sizeof (cmsgmem));
743   msg.msg_control = cmsgmem;
744   msg.msg_controllen = sizeof (cmsgmem);
745 #endif
746
747  again:
748   if (recvmsg (client_fd, &msg, 0) < 0)
749     {
750       if (errno == EINTR)
751         goto again;
752
753       dbus_set_error (error, _dbus_error_from_errno (errno),
754                       "Failed to read credentials byte: %s",
755                       _dbus_strerror (errno));
756       return FALSE;
757     }
758
759   if (buf != '\0')
760     {
761       dbus_set_error (error, DBUS_ERROR_FAILED,
762                       "Credentials byte was not nul");
763       return FALSE;
764     }
765
766 #ifdef HAVE_CMSGCRED
767   if (cmsg->cmsg_len < sizeof (cmsgmem) || cmsg->cmsg_type != SCM_CREDS)
768     {
769       dbus_set_error (error, DBUS_ERROR_FAILED);
770       _dbus_verbose ("Message from recvmsg() was not SCM_CREDS\n");
771       return FALSE;
772     }
773 #endif
774
775   _dbus_verbose ("read credentials byte\n");
776
777   {
778 #ifdef SO_PEERCRED
779     struct ucred cr;   
780     int cr_len = sizeof (cr);
781    
782     if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
783         cr_len == sizeof (cr))
784       {
785         credentials->pid = cr.pid;
786         credentials->uid = cr.uid;
787         credentials->gid = cr.gid;
788       }
789     else
790       {
791         _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
792                        cr_len, (int) sizeof (cr), _dbus_strerror (errno));
793       }
794 #elif defined(HAVE_CMSGCRED)
795     struct cmsgcred *cred;
796
797     cred = (struct cmsgcred *) CMSG_DATA (cmsg);
798
799     credentials->pid = cred->cmcred_pid;
800     credentials->uid = cred->cmcred_euid;
801     credentials->gid = cred->cmcred_groups[0];
802 #else /* !SO_PEERCRED && !HAVE_CMSGCRED */
803     _dbus_verbose ("Socket credentials not supported on this OS\n");
804 #endif
805   }
806
807   _dbus_verbose ("Credentials: pid %d  uid %d  gid %d\n",
808                  credentials->pid,
809                  credentials->uid,
810                  credentials->gid);
811     
812   return TRUE;
813 }
814
815 /**
816  * Sends a single nul byte with our UNIX credentials as ancillary
817  * data.  Returns #TRUE if the data was successfully written.  On
818  * systems that don't support sending credentials, just writes a byte,
819  * doesn't send any credentials.  On some systems, such as Linux,
820  * reading/writing the byte isn't actually required, but we do it
821  * anyway just to avoid multiple codepaths.
822  *
823  * Fails if no byte can be written, so you must select() first.
824  *
825  * The point of the byte is that on some systems we have to
826  * use sendmsg()/recvmsg() to transmit credentials.
827  *
828  * @param server_fd file descriptor for connection to server
829  * @param error return location for error code
830  * @returns #TRUE if the byte was sent
831  */
832 dbus_bool_t
833 _dbus_send_credentials_unix_socket  (int              server_fd,
834                                      DBusError       *error)
835 {
836   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
837   
838   if (write_credentials_byte (server_fd, error))
839     return TRUE;
840   else
841     return FALSE;
842 }
843
844 /**
845  * Accepts a connection on a listening socket.
846  * Handles EINTR for you.
847  *
848  * @param listen_fd the listen file descriptor
849  * @returns the connection fd of the client, or -1 on error
850  */
851 int
852 _dbus_accept  (int listen_fd)
853 {
854   int client_fd;
855   struct sockaddr addr;
856   socklen_t addrlen;
857
858   addrlen = sizeof (addr);
859   
860  retry:
861   client_fd = accept (listen_fd, &addr, &addrlen);
862   
863   if (client_fd < 0)
864     {
865       if (errno == EINTR)
866         goto retry;
867     }
868   
869   return client_fd;
870 }
871
872 /** @} */
873
874 /**
875  * @addtogroup DBusString
876  *
877  * @{
878  */
879 /**
880  * Appends an integer to a DBusString.
881  * 
882  * @param str the string
883  * @param value the integer value
884  * @returns #FALSE if not enough memory or other failure.
885  */
886 dbus_bool_t
887 _dbus_string_append_int (DBusString *str,
888                          long        value)
889 {
890   /* this calculation is from comp.lang.c faq */
891 #define MAX_LONG_LEN ((sizeof (long) * 8 + 2) / 3 + 1)  /* +1 for '-' */
892   int orig_len;
893   int i;
894   char *buf;
895   
896   orig_len = _dbus_string_get_length (str);
897
898   if (!_dbus_string_lengthen (str, MAX_LONG_LEN))
899     return FALSE;
900
901   buf = _dbus_string_get_data_len (str, orig_len, MAX_LONG_LEN);
902
903   snprintf (buf, MAX_LONG_LEN, "%ld", value);
904
905   i = 0;
906   while (*buf)
907     {
908       ++buf;
909       ++i;
910     }
911   
912   _dbus_string_shorten (str, MAX_LONG_LEN - i);
913   
914   return TRUE;
915 }
916
917 /**
918  * Appends an unsigned integer to a DBusString.
919  * 
920  * @param str the string
921  * @param value the integer value
922  * @returns #FALSE if not enough memory or other failure.
923  */
924 dbus_bool_t
925 _dbus_string_append_uint (DBusString    *str,
926                           unsigned long  value)
927 {
928   /* this is wrong, but definitely on the high side. */
929 #define MAX_ULONG_LEN (MAX_LONG_LEN * 2)
930   int orig_len;
931   int i;
932   char *buf;
933   
934   orig_len = _dbus_string_get_length (str);
935
936   if (!_dbus_string_lengthen (str, MAX_ULONG_LEN))
937     return FALSE;
938
939   buf = _dbus_string_get_data_len (str, orig_len, MAX_ULONG_LEN);
940
941   snprintf (buf, MAX_ULONG_LEN, "%lu", value);
942
943   i = 0;
944   while (*buf)
945     {
946       ++buf;
947       ++i;
948     }
949   
950   _dbus_string_shorten (str, MAX_ULONG_LEN - i);
951   
952   return TRUE;
953 }
954
955 /**
956  * Appends a double to a DBusString.
957  * 
958  * @param str the string
959  * @param value the floating point value
960  * @returns #FALSE if not enough memory or other failure.
961  */
962 dbus_bool_t
963 _dbus_string_append_double (DBusString *str,
964                             double      value)
965 {
966 #define MAX_DOUBLE_LEN 64 /* this is completely made up :-/ */
967   int orig_len;
968   char *buf;
969   int i;
970   
971   orig_len = _dbus_string_get_length (str);
972
973   if (!_dbus_string_lengthen (str, MAX_DOUBLE_LEN))
974     return FALSE;
975
976   buf = _dbus_string_get_data_len (str, orig_len, MAX_DOUBLE_LEN);
977
978   snprintf (buf, MAX_LONG_LEN, "%g", value);
979
980   i = 0;
981   while (*buf)
982     {
983       ++buf;
984       ++i;
985     }
986   
987   _dbus_string_shorten (str, MAX_DOUBLE_LEN - i);
988   
989   return TRUE;
990 }
991
992 /**
993  * Parses an integer contained in a DBusString. Either return parameter
994  * may be #NULL if you aren't interested in it. The integer is parsed
995  * and stored in value_return. Return parameters are not initialized
996  * if the function returns #FALSE.
997  *
998  * @param str the string
999  * @param start the byte index of the start of the integer
1000  * @param value_return return location of the integer value or #NULL
1001  * @param end_return return location of the end of the integer, or #NULL
1002  * @returns #TRUE on success
1003  */
1004 dbus_bool_t
1005 _dbus_string_parse_int (const DBusString *str,
1006                         int               start,
1007                         long             *value_return,
1008                         int              *end_return)
1009 {
1010   long v;
1011   const char *p;
1012   char *end;
1013
1014   p = _dbus_string_get_const_data_len (str, start,
1015                                        _dbus_string_get_length (str) - start);
1016
1017   end = NULL;
1018   errno = 0;
1019   v = strtol (p, &end, 0);
1020   if (end == NULL || end == p || errno != 0)
1021     return FALSE;
1022
1023   if (value_return)
1024     *value_return = v;
1025   if (end_return)
1026     *end_return = start + (end - p);
1027
1028   return TRUE;
1029 }
1030
1031 /**
1032  * Parses an unsigned integer contained in a DBusString. Either return
1033  * parameter may be #NULL if you aren't interested in it. The integer
1034  * is parsed and stored in value_return. Return parameters are not
1035  * initialized if the function returns #FALSE.
1036  *
1037  * @param str the string
1038  * @param start the byte index of the start of the integer
1039  * @param value_return return location of the integer value or #NULL
1040  * @param end_return return location of the end of the integer, or #NULL
1041  * @returns #TRUE on success
1042  */
1043 dbus_bool_t
1044 _dbus_string_parse_uint (const DBusString *str,
1045                          int               start,
1046                          unsigned long    *value_return,
1047                          int              *end_return)
1048 {
1049   unsigned long v;
1050   const char *p;
1051   char *end;
1052
1053   p = _dbus_string_get_const_data_len (str, start,
1054                                        _dbus_string_get_length (str) - start);
1055
1056   end = NULL;
1057   errno = 0;
1058   v = strtoul (p, &end, 0);
1059   if (end == NULL || end == p || errno != 0)
1060     return FALSE;
1061
1062   if (value_return)
1063     *value_return = v;
1064   if (end_return)
1065     *end_return = start + (end - p);
1066
1067   return TRUE;
1068 }
1069
1070 /**
1071  * Parses a floating point number contained in a DBusString. Either
1072  * return parameter may be #NULL if you aren't interested in it. The
1073  * integer is parsed and stored in value_return. Return parameters are
1074  * not initialized if the function returns #FALSE.
1075  *
1076  * @todo this function is currently locale-dependent. Should
1077  * ask alexl to relicense g_ascii_strtod() code and put that in
1078  * here instead, so it's locale-independent.
1079  *
1080  * @param str the string
1081  * @param start the byte index of the start of the float
1082  * @param value_return return location of the float value or #NULL
1083  * @param end_return return location of the end of the float, or #NULL
1084  * @returns #TRUE on success
1085  */
1086 dbus_bool_t
1087 _dbus_string_parse_double (const DBusString *str,
1088                            int               start,
1089                            double           *value_return,
1090                            int              *end_return)
1091 {
1092   double v;
1093   const char *p;
1094   char *end;
1095
1096   _dbus_warn ("_dbus_string_parse_double() needs to be made locale-independent\n");
1097   
1098   p = _dbus_string_get_const_data_len (str, start,
1099                                        _dbus_string_get_length (str) - start);
1100
1101   end = NULL;
1102   errno = 0;
1103   v = strtod (p, &end);
1104   if (end == NULL || end == p || errno != 0)
1105     return FALSE;
1106
1107   if (value_return)
1108     *value_return = v;
1109   if (end_return)
1110     *end_return = start + (end - p);
1111
1112   return TRUE;
1113 }
1114
1115 /** @} */ /* DBusString group */
1116
1117 /**
1118  * @addtogroup DBusInternalsUtils
1119  * @{
1120  */
1121
1122 static dbus_bool_t
1123 store_user_info (struct passwd    *p,
1124                  DBusCredentials  *credentials,
1125                  DBusString       *homedir,
1126                  DBusString       *username_out)
1127 {
1128   int old_homedir_len;
1129   
1130   if (credentials != NULL)
1131     {
1132       credentials->uid = p->pw_uid;
1133       credentials->gid = p->pw_gid;
1134     }
1135
1136   old_homedir_len = 0;
1137   if (homedir != NULL)
1138     {
1139       old_homedir_len = _dbus_string_get_length (homedir);
1140       
1141       if (!_dbus_string_append (homedir, p->pw_dir))
1142         {
1143           _dbus_verbose ("No memory to get homedir\n");
1144           return FALSE;
1145         }
1146     }
1147   
1148   if (username_out &&
1149       !_dbus_string_append (username_out, p->pw_name))
1150     {
1151       if (homedir)
1152         _dbus_string_set_length (homedir, old_homedir_len);
1153       _dbus_verbose ("No memory to get username\n");
1154       return FALSE;
1155     }
1156       
1157   _dbus_verbose ("Username %s has uid %d gid %d homedir %s\n",
1158                  p->pw_name, (int) p->pw_uid, (int) p->pw_gid,
1159                  p->pw_dir);
1160
1161   return TRUE;
1162 }
1163   
1164 /**
1165  * Gets user info using either username or uid. Only
1166  * one of these may be passed in, either username
1167  * must be #NULL or uid must be < 0.
1168  *
1169  * @param username the username
1170  * @param uid the user ID
1171  * @param credentials to fill in or #NULL
1172  * @param homedir string to append homedir to or #NULL
1173  * @param username_out string to append username to or #NULL
1174  *
1175  * @returns #TRUE on success
1176  */
1177 static dbus_bool_t
1178 get_user_info (const DBusString *username,
1179                int               uid,
1180                DBusCredentials  *credentials,
1181                DBusString       *homedir,
1182                DBusString       *username_out)
1183 {
1184   const char *username_c_str;
1185       
1186   /* exactly one of username/uid provided */
1187   _dbus_assert (username != NULL || uid >= 0);
1188   _dbus_assert (username == NULL || uid < 0);
1189
1190   if (credentials)
1191     {
1192       credentials->pid = -1;
1193       credentials->uid = -1;
1194       credentials->gid = -1;
1195     }
1196   
1197   if (username != NULL)
1198     username_c_str = _dbus_string_get_const_data (username);
1199   else
1200     username_c_str = NULL;
1201
1202   /* For now assuming that the getpwnam() and getpwuid() flavors
1203    * are always symmetrical, if not we have to add more configure
1204    * checks
1205    */
1206   
1207 #if defined (HAVE_POSIX_GETPWNAME_R) || defined (HAVE_NONPOSIX_GETPWNAME_R)
1208   {
1209     struct passwd *p;
1210     int result;
1211     char buf[1024];
1212     struct passwd p_str;
1213
1214     p = NULL;
1215 #ifdef HAVE_POSIX_GETPWNAME_R
1216     if (uid >= 0)
1217       result = getpwuid_r (uid, &p_str, buf, sizeof (buf),
1218                            &p);
1219     else
1220       result = getpwnam_r (username_c_str, &p_str, buf, sizeof (buf),
1221                            &p);
1222 #else
1223     if (uid >= 0)
1224       p = getpwuid_r (uid, &p_str, buf, sizeof (buf));
1225     else
1226       p = getpwnam_r (username_c_str, &p_str, buf, sizeof (buf));
1227     result = 0;
1228 #endif /* !HAVE_POSIX_GETPWNAME_R */
1229     if (result == 0 && p == &p_str)
1230       {
1231         return store_user_info (p, credentials, homedir,
1232                                 username_out);
1233       }
1234     else
1235       {
1236         _dbus_verbose ("User %s unknown\n", username_c_str);
1237         return FALSE;
1238       }
1239   }
1240 #else /* ! HAVE_GETPWNAM_R */
1241   {
1242     /* I guess we're screwed on thread safety here */
1243     struct passwd *p;
1244
1245     if (uid >= 0)
1246       p = getpwuid (uid);
1247     else
1248       p = getpwnam (username_c_str);
1249
1250     if (p != NULL)
1251       {
1252         return store_user_info (p, credentials, homedir,
1253                                 username_out);
1254       }
1255     else
1256       {
1257         _dbus_verbose ("User %s unknown\n", username_c_str);
1258         return FALSE;
1259       }
1260   }
1261 #endif  /* ! HAVE_GETPWNAM_R */
1262 }
1263
1264 /**
1265  * Gets the credentials corresponding to the given username.
1266  *
1267  * @param username the username
1268  * @param credentials credentials to fill in
1269  * @returns #TRUE if the username existed and we got some credentials
1270  */
1271 dbus_bool_t
1272 _dbus_credentials_from_username (const DBusString *username,
1273                                  DBusCredentials  *credentials)
1274 {
1275   return get_user_info (username, -1, credentials, NULL, NULL);
1276 }
1277
1278 /**
1279  * Gets the credentials corresponding to the given user ID.
1280  *
1281  * @param user_id the user ID
1282  * @param credentials credentials to fill in
1283  * @returns #TRUE if the username existed and we got some credentials
1284  */
1285 dbus_bool_t
1286 _dbus_credentials_from_user_id (unsigned long     user_id,
1287                                 DBusCredentials  *credentials)
1288 {
1289   return get_user_info (NULL, user_id, credentials, NULL, NULL);
1290 }
1291
1292 _DBUS_DEFINE_GLOBAL_LOCK (user_info);
1293
1294 typedef struct
1295 {
1296   DBusString name;
1297   DBusString dir;
1298   DBusCredentials creds;
1299 } UserInfo;
1300
1301 static void
1302 shutdown_user_info (void *data)
1303 {
1304   UserInfo *u = data;
1305
1306   _dbus_string_free (&u->name);
1307   _dbus_string_free (&u->dir);
1308 }
1309
1310 /**
1311  * Gets information about the user running this process.
1312  *
1313  * @param username return location for username or #NULL
1314  * @param homedir return location for home directory or #NULL
1315  * @param credentials return location for credentials or #NULL
1316  * @returns #TRUE on success
1317  */
1318 dbus_bool_t
1319 _dbus_user_info_from_current_process (const DBusString      **username,
1320                                       const DBusString      **homedir,
1321                                       const DBusCredentials **credentials)
1322 {
1323   static UserInfo u;
1324   static int initialized_generation = 0;
1325   
1326   if (!_DBUS_LOCK (user_info))
1327     return FALSE;
1328
1329   if (initialized_generation != _dbus_current_generation)
1330     {
1331       if (!_dbus_string_init (&u.name))
1332         {
1333           _DBUS_UNLOCK (user_info);
1334           return FALSE;
1335         }
1336
1337       if (!_dbus_string_init (&u.dir))
1338         {
1339           _dbus_string_free (&u.name);
1340           _DBUS_UNLOCK (user_info);
1341           return FALSE;
1342         }
1343       
1344       u.creds.uid = -1;
1345       u.creds.gid = -1;
1346       u.creds.pid = -1;
1347
1348       if (!get_user_info (NULL, getuid (),
1349                           &u.creds, &u.dir, &u.name))
1350         goto fail_init;
1351       
1352       if (!_dbus_register_shutdown_func (shutdown_user_info,
1353                                          &u))
1354         goto fail_init;
1355       
1356       initialized_generation = _dbus_current_generation;
1357     fail_init:
1358       if (initialized_generation != _dbus_current_generation)
1359         {
1360           _dbus_string_free (&u.name);
1361           _dbus_string_free (&u.dir);
1362           _DBUS_UNLOCK (user_info);
1363           return FALSE;
1364         }
1365     }
1366
1367   if (username)
1368     *username = &u.name;
1369   if (homedir)
1370     *homedir = &u.dir;
1371   if (credentials)
1372     *credentials = &u.creds;
1373   
1374   _DBUS_UNLOCK (user_info);
1375
1376   return TRUE;
1377 }
1378
1379 /**
1380  * Gets the home directory for the given user.
1381  *
1382  * @param username the username
1383  * @param homedir string to append home directory to
1384  * @returns #TRUE if user existed and we appended their homedir
1385  */
1386 dbus_bool_t
1387 _dbus_homedir_from_username (const DBusString *username,
1388                              DBusString       *homedir)
1389 {
1390   return get_user_info (username, -1, NULL, homedir, NULL);
1391 }
1392
1393 /**
1394  * Gets credentials from a UID string. (Parses a string to a UID
1395  * and converts to a DBusCredentials.)
1396  *
1397  * @param uid_str the UID in string form
1398  * @param credentials credentials to fill in
1399  * @returns #TRUE if successfully filled in some credentials
1400  */
1401 dbus_bool_t
1402 _dbus_credentials_from_uid_string (const DBusString      *uid_str,
1403                                    DBusCredentials       *credentials)
1404 {
1405   int end;
1406   long uid;
1407
1408   credentials->pid = -1;
1409   credentials->uid = -1;
1410   credentials->gid = -1;
1411   
1412   if (_dbus_string_get_length (uid_str) == 0)
1413     {
1414       _dbus_verbose ("UID string was zero length\n");
1415       return FALSE;
1416     }
1417
1418   uid = -1;
1419   end = 0;
1420   if (!_dbus_string_parse_int (uid_str, 0, &uid,
1421                                &end))
1422     {
1423       _dbus_verbose ("could not parse string as a UID\n");
1424       return FALSE;
1425     }
1426   
1427   if (end != _dbus_string_get_length (uid_str))
1428     {
1429       _dbus_verbose ("string contained trailing stuff after UID\n");
1430       return FALSE;
1431     }
1432
1433   credentials->uid = uid;
1434
1435   return TRUE;
1436 }
1437
1438 /**
1439  * Gets the credentials of the current process.
1440  *
1441  * @param credentials credentials to fill in.
1442  */
1443 void
1444 _dbus_credentials_from_current_process (DBusCredentials *credentials)
1445 {
1446   /* The POSIX spec certainly doesn't promise this, but
1447    * we need these assertions to fail as soon as we're wrong about
1448    * it so we can do the porting fixups
1449    */
1450   _dbus_assert (sizeof (pid_t) <= sizeof (credentials->pid));
1451   _dbus_assert (sizeof (uid_t) <= sizeof (credentials->uid));
1452   _dbus_assert (sizeof (gid_t) <= sizeof (credentials->gid));
1453   
1454   credentials->pid = getpid ();
1455   credentials->uid = getuid ();
1456   credentials->gid = getgid ();
1457 }
1458
1459 /**
1460  * Checks whether the provided_credentials are allowed to log in
1461  * as the expected_credentials.
1462  *
1463  * @param expected_credentials credentials we're trying to log in as
1464  * @param provided_credentials credentials we have
1465  * @returns #TRUE if we can log in
1466  */
1467 dbus_bool_t
1468 _dbus_credentials_match (const DBusCredentials *expected_credentials,
1469                          const DBusCredentials *provided_credentials)
1470 {
1471   if (provided_credentials->uid < 0)
1472     return FALSE;
1473   else if (expected_credentials->uid < 0)
1474     return FALSE;
1475   else if (provided_credentials->uid == 0)
1476     return TRUE;
1477   else if (provided_credentials->uid == expected_credentials->uid)
1478     return TRUE;
1479   else
1480     return FALSE;
1481 }
1482
1483 /**
1484  * Gets group ID from group name.
1485  *
1486  * @param group_name name of the group
1487  * @param gid location to store group ID
1488  * @returns #TRUE if group was known
1489  */
1490 dbus_bool_t
1491 _dbus_get_group_id (const DBusString *group_name,
1492                     unsigned long    *gid)
1493 {
1494   const char *group_c_str;
1495   
1496   group_c_str = _dbus_string_get_const_data (group_name);
1497   
1498   /* For now assuming that the getgrnam() and getgrgid() flavors
1499    * always correspond to the pwnam flavors, if not we have
1500    * to add more configure checks.
1501    */
1502   
1503 #if defined (HAVE_POSIX_GETPWNAME_R) || defined (HAVE_NONPOSIX_GETPWNAME_R)
1504   {
1505     struct group *g;
1506     int result;
1507     char buf[1024];
1508     struct group g_str;
1509
1510     g = NULL;
1511 #ifdef HAVE_POSIX_GETPWNAME_R
1512
1513     result = getgrnam_r (group_c_str, &g_str, buf, sizeof (buf),
1514                          &g);
1515 #else
1516     p = getgrnam_r (group_c_str, &g_str, buf, sizeof (buf));
1517     result = 0;
1518 #endif /* !HAVE_POSIX_GETPWNAME_R */
1519     if (result == 0 && g == &g_str)
1520       {
1521         *gid = g->gr_gid;
1522         return TRUE;
1523       }
1524     else
1525       {
1526         _dbus_verbose ("Group %s unknown\n", group_c_str);
1527         return FALSE;
1528       }
1529   }
1530 #else /* ! HAVE_GETPWNAM_R */
1531   {
1532     /* I guess we're screwed on thread safety here */
1533     struct group *g;
1534
1535     g = getgrnam (group_c_str);
1536
1537     if (g != NULL)
1538       {
1539         *gid = g->gr_gid;
1540         return TRUE;
1541       }
1542     else
1543       {
1544         _dbus_verbose ("Group %s unknown\n", group_c_str);
1545         return FALSE;
1546       }
1547   }
1548 #endif  /* ! HAVE_GETPWNAM_R */
1549 }
1550
1551 /**
1552  * Gets all groups for a particular user. Returns #FALSE
1553  * if no memory, or user isn't known, but always initializes
1554  * group_ids to a NULL array.
1555  *
1556  * @todo failing to distinguish "out of memory" from
1557  * "unknown user" is kind of bogus and would probably
1558  * result in a failure in a comprehensive test suite.
1559  *
1560  * @param uid the user ID
1561  * @param group_ids return location for array of group IDs
1562  * @param n_group_ids return location for length of returned array
1563  * @returns #TRUE on success
1564  */
1565 dbus_bool_t
1566 _dbus_get_groups (unsigned long   uid,
1567                   unsigned long **group_ids,
1568                   int            *n_group_ids)
1569 {
1570   DBusCredentials creds;
1571   DBusString username;
1572   const char *username_c;
1573   dbus_bool_t retval;
1574   
1575   *group_ids = NULL;
1576   *n_group_ids = 0;
1577
1578   retval = FALSE;
1579
1580   if (!_dbus_string_init (&username))
1581     return FALSE;
1582
1583   if (!get_user_info (NULL, uid, &creds,
1584                       NULL, &username) ||
1585       creds.gid < 0)
1586     goto out;
1587
1588   username_c = _dbus_string_get_const_data (&username);
1589   
1590 #ifdef HAVE_GETGROUPLIST
1591   {
1592     gid_t *buf;
1593     int buf_count;
1594     int i;
1595     
1596     buf_count = 17;
1597     buf = dbus_new (gid_t, buf_count);
1598     if (buf == NULL)
1599       goto out;
1600     
1601     if (getgrouplist (username_c,
1602                       creds.gid,
1603                       buf, &buf_count) < 0)
1604       {
1605         gid_t *new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
1606         if (new == NULL)
1607           {
1608             dbus_free (buf);
1609             goto out;
1610           }
1611         
1612         buf = new;
1613
1614         getgrouplist (username_c, creds.gid, buf, &buf_count);
1615       }
1616
1617     *group_ids = dbus_new (unsigned long, buf_count);
1618     if (*group_ids == NULL)
1619       {
1620         dbus_free (buf);
1621         goto out;
1622       }
1623     
1624     for (i = 0; i < buf_count; ++i)
1625       (*group_ids)[i] = buf[i];
1626
1627     *n_group_ids = buf_count;
1628     
1629     dbus_free (buf);
1630   }
1631 #else  /* HAVE_GETGROUPLIST */
1632   {
1633     /* We just get the one group ID */
1634     *group_ids = dbus_new (unsigned long, 1);
1635     if (*group_ids == NULL)
1636       goto out;
1637
1638     *n_group_ids = 1;
1639
1640     (*group_ids)[0] = creds.gid;
1641   }
1642 #endif /* HAVE_GETGROUPLIST */
1643
1644     retval = TRUE;
1645     
1646   out:
1647     _dbus_string_free (&username);
1648     return retval;
1649 }
1650
1651 /**
1652  * Appends the uid of the current process to the given string.
1653  *
1654  * @param str the string to append to
1655  * @returns #TRUE on success
1656  */
1657 dbus_bool_t
1658 _dbus_string_append_our_uid (DBusString *str)
1659 {
1660   return _dbus_string_append_int (str, getuid ());
1661 }
1662
1663
1664 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
1665
1666 /**
1667  * Atomically increments an integer
1668  *
1669  * @param atomic pointer to the integer to increment
1670  * @returns the value after incrementing
1671  *
1672  * @todo implement arch-specific faster atomic ops
1673  */
1674 dbus_atomic_t
1675 _dbus_atomic_inc (dbus_atomic_t *atomic)
1676 {
1677   dbus_atomic_t res;
1678   
1679   _DBUS_LOCK (atomic);
1680   *atomic += 1;
1681   res = *atomic;
1682   _DBUS_UNLOCK (atomic);
1683   return res;
1684 }
1685
1686 /**
1687  * Atomically decrement an integer
1688  *
1689  * @param atomic pointer to the integer to decrement
1690  * @returns the value after decrementing
1691  *
1692  * @todo implement arch-specific faster atomic ops
1693  */
1694 dbus_atomic_t
1695 _dbus_atomic_dec (dbus_atomic_t *atomic)
1696 {
1697   dbus_atomic_t res;
1698   
1699   _DBUS_LOCK (atomic);
1700   *atomic -= 1;
1701   res = *atomic;
1702   _DBUS_UNLOCK (atomic);
1703   return res;
1704 }
1705
1706 /**
1707  * Wrapper for poll().
1708  *
1709  * @todo need a fallback implementation using select()
1710  *
1711  * @param fds the file descriptors to poll
1712  * @param n_fds number of descriptors in the array
1713  * @param timeout_milliseconds timeout or -1 for infinite
1714  * @returns numbers of fds with revents, or <0 on error
1715  */
1716 int
1717 _dbus_poll (DBusPollFD *fds,
1718             int         n_fds,
1719             int         timeout_milliseconds)
1720 {
1721 #ifdef HAVE_POLL
1722   /* This big thing is a constant expression and should get optimized
1723    * out of existence. So it's more robust than a configure check at
1724    * no cost.
1725    */
1726   if (_DBUS_POLLIN == POLLIN &&
1727       _DBUS_POLLPRI == POLLPRI &&
1728       _DBUS_POLLOUT == POLLOUT &&
1729       _DBUS_POLLERR == POLLERR &&
1730       _DBUS_POLLHUP == POLLHUP &&
1731       _DBUS_POLLNVAL == POLLNVAL &&
1732       sizeof (DBusPollFD) == sizeof (struct pollfd) &&
1733       _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
1734       _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
1735       _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
1736       _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
1737       _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
1738       _DBUS_STRUCT_OFFSET (struct pollfd, revents))
1739     {
1740       return poll ((struct pollfd*) fds,
1741                    n_fds, 
1742                    timeout_milliseconds);
1743     }
1744   else
1745     {
1746       /* We have to convert the DBusPollFD to an array of
1747        * struct pollfd, poll, and convert back.
1748        */
1749       _dbus_warn ("didn't implement poll() properly for this system yet\n");
1750       return -1;
1751     }
1752 #else /* ! HAVE_POLL */
1753
1754   fd_set read_set, write_set, err_set;
1755   int max_fd = 0;
1756   int i;
1757   struct timeval tv;
1758   int ready;
1759   
1760   FD_ZERO (&read_set);
1761   FD_ZERO (&write_set);
1762   FD_ZERO (&err_set);
1763
1764   for (i = 0; i < n_fds; i++)
1765     {
1766       DBusPollFD f = fds[i];
1767
1768       if (f.events & _DBUS_POLLIN)
1769         FD_SET (f.fd, &read_set);
1770
1771       if (f.events & _DBUS_POLLOUT)
1772         FD_SET (f.fd, &write_set);
1773
1774       FD_SET (f.fd, &err_set);
1775
1776       max_fd = MAX (max_fd, f.fd);
1777     }
1778     
1779   tv.tv_sec = timeout_milliseconds / 1000;
1780   tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
1781
1782   ready = select (max_fd + 1, &read_set, &write_set, &err_set, &tv);
1783
1784   if (ready > 0)
1785     {
1786       for (i = 0; i < n_fds; i++)
1787         {
1788           DBusPollFD f = fds[i];
1789
1790           f.revents = 0;
1791
1792           if (FD_ISSET (f.fd, &read_set))
1793             f.revents |= _DBUS_POLLIN;
1794
1795           if (FD_ISSET (f.fd, &write_set))
1796             f.revents |= _DBUS_POLLOUT;
1797
1798           if (FD_ISSET (f.fd, &err_set))
1799             f.revents |= _DBUS_POLLERR;
1800         }
1801     }
1802
1803   return ready;
1804 #endif
1805 }
1806
1807 /** nanoseconds in a second */
1808 #define NANOSECONDS_PER_SECOND       1000000000
1809 /** microseconds in a second */
1810 #define MICROSECONDS_PER_SECOND      1000000
1811 /** milliseconds in a second */
1812 #define MILLISECONDS_PER_SECOND      1000
1813 /** nanoseconds in a millisecond */
1814 #define NANOSECONDS_PER_MILLISECOND  1000000
1815 /** microseconds in a millisecond */
1816 #define MICROSECONDS_PER_MILLISECOND 1000
1817
1818 /**
1819  * Sleeps the given number of milliseconds.
1820  * @param milliseconds number of milliseconds
1821  */
1822 void
1823 _dbus_sleep_milliseconds (int milliseconds)
1824 {
1825 #ifdef HAVE_NANOSLEEP
1826   struct timespec req;
1827   struct timespec rem;
1828
1829   req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
1830   req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
1831   rem.tv_sec = 0;
1832   rem.tv_nsec = 0;
1833
1834   while (nanosleep (&req, &rem) < 0 && errno == EINTR)
1835     req = rem;
1836 #elif defined (HAVE_USLEEP)
1837   usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
1838 #else /* ! HAVE_USLEEP */
1839   sleep (MAX (milliseconds / 1000, 1));
1840 #endif
1841 }
1842
1843 /**
1844  * Get current time, as in gettimeofday().
1845  *
1846  * @param tv_sec return location for number of seconds
1847  * @param tv_usec return location for number of microseconds (thousandths)
1848  */
1849 void
1850 _dbus_get_current_time (long *tv_sec,
1851                         long *tv_usec)
1852 {
1853   struct timeval t;
1854
1855   gettimeofday (&t, NULL);
1856
1857   if (tv_sec)
1858     *tv_sec = t.tv_sec;
1859   if (tv_usec)
1860     *tv_usec = t.tv_usec;
1861 }
1862
1863 /**
1864  * Appends the contents of the given file to the string,
1865  * returning error code. At the moment, won't open a file
1866  * more than a megabyte in size.
1867  *
1868  * @param str the string to append to
1869  * @param filename filename to load
1870  * @param error place to set an error
1871  * @returns #FALSE if error was set
1872  */
1873 dbus_bool_t
1874 _dbus_file_get_contents (DBusString       *str,
1875                          const DBusString *filename,
1876                          DBusError        *error)
1877 {
1878   int fd;
1879   struct stat sb;
1880   int orig_len;
1881   int total;
1882   const char *filename_c;
1883
1884   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1885   
1886   filename_c = _dbus_string_get_const_data (filename);
1887   
1888   /* O_BINARY useful on Cygwin */
1889   fd = open (filename_c, O_RDONLY | O_BINARY);
1890   if (fd < 0)
1891     {
1892       dbus_set_error (error, _dbus_error_from_errno (errno),
1893                       "%s", _dbus_strerror (errno));
1894       return FALSE;
1895     }
1896
1897   if (fstat (fd, &sb) < 0)
1898     {
1899       dbus_set_error (error, _dbus_error_from_errno (errno),
1900                       "%s", _dbus_strerror (errno));
1901
1902       _dbus_verbose ("fstat() failed: %s",
1903                      _dbus_strerror (errno));
1904       
1905       close (fd);
1906       
1907       return FALSE;
1908     }
1909
1910   if (sb.st_size > _DBUS_ONE_MEGABYTE)
1911     {
1912       dbus_set_error (error, DBUS_ERROR_FAILED,
1913                       "File size %lu is too large.\n",
1914                      (unsigned long) sb.st_size);
1915       close (fd);
1916       return FALSE;
1917     }
1918   
1919   total = 0;
1920   orig_len = _dbus_string_get_length (str);
1921   if (sb.st_size > 0 && S_ISREG (sb.st_mode))
1922     {
1923       int bytes_read;
1924
1925       while (total < (int) sb.st_size)
1926         {
1927           bytes_read = _dbus_read (fd, str,
1928                                    sb.st_size - total);
1929           if (bytes_read <= 0)
1930             {
1931               dbus_set_error (error, _dbus_error_from_errno (errno),
1932                               "%s", _dbus_strerror (errno));
1933
1934               _dbus_verbose ("read() failed: %s",
1935                              _dbus_strerror (errno));
1936               
1937               close (fd);
1938               _dbus_string_set_length (str, orig_len);
1939               return FALSE;
1940             }
1941           else
1942             total += bytes_read;
1943         }
1944
1945       close (fd);
1946       return TRUE;
1947     }
1948   else if (sb.st_size != 0)
1949     {
1950       _dbus_verbose ("Can only open regular files at the moment.\n");
1951       dbus_set_error (error, DBUS_ERROR_FAILED,
1952                       "Not a regular file");
1953       close (fd);
1954       return FALSE;
1955     }
1956   else
1957     {
1958       close (fd);
1959       return TRUE;
1960     }
1961 }
1962
1963 static dbus_bool_t
1964 append_unique_chars (DBusString *str)
1965 {
1966   static const char letters[] =
1967     "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
1968   int i;
1969   int len;
1970
1971 #define N_UNIQUE_CHARS 8
1972   
1973   if (!_dbus_generate_random_bytes (str, N_UNIQUE_CHARS))
1974     return FALSE;
1975   
1976   len = _dbus_string_get_length (str);
1977   i = len - N_UNIQUE_CHARS;
1978   while (i < len)
1979     {
1980       _dbus_string_set_byte (str, i,
1981                              letters[_dbus_string_get_byte (str, i) %
1982                                      (sizeof (letters) - 1)]);
1983
1984       ++i;
1985     }
1986
1987   _dbus_assert (_dbus_string_validate_ascii (str, len - N_UNIQUE_CHARS,
1988                                              N_UNIQUE_CHARS));
1989
1990   return TRUE;
1991 }
1992
1993 /**
1994  * Writes a string out to a file. If the file exists,
1995  * it will be atomically overwritten by the new data.
1996  *
1997  * @param str the string to write out
1998  * @param filename the file to save string to
1999  * @param error error to be filled in on failure
2000  * @returns #FALSE on failure
2001  */
2002 dbus_bool_t
2003 _dbus_string_save_to_file (const DBusString *str,
2004                            const DBusString *filename,
2005                            DBusError        *error)
2006 {
2007   int fd;
2008   int bytes_to_write;
2009   const char *filename_c;
2010   DBusString tmp_filename;
2011   const char *tmp_filename_c;
2012   int total;
2013   dbus_bool_t need_unlink;
2014   dbus_bool_t retval;
2015
2016   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2017   
2018   fd = -1;
2019   retval = FALSE;
2020   need_unlink = FALSE;
2021   
2022   if (!_dbus_string_init (&tmp_filename))
2023     {
2024       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2025       return FALSE;
2026     }
2027
2028   if (!_dbus_string_copy (filename, 0, &tmp_filename, 0))
2029     {
2030       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2031       return FALSE;
2032     }
2033   
2034   if (!_dbus_string_append (&tmp_filename, "."))
2035     {
2036       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2037       return FALSE;
2038     }
2039   
2040   if (!append_unique_chars (&tmp_filename))
2041     {
2042       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2043       return FALSE;
2044     }
2045     
2046   filename_c = _dbus_string_get_const_data (filename);
2047   tmp_filename_c = _dbus_string_get_const_data (&tmp_filename);
2048
2049   fd = open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
2050              0600);
2051   if (fd < 0)
2052     {
2053       dbus_set_error (error, _dbus_error_from_errno (errno),
2054                       "Could not create %s: %s", tmp_filename_c,
2055                       _dbus_strerror (errno));
2056       goto out;
2057     }
2058
2059   need_unlink = TRUE;
2060   
2061   total = 0;
2062   bytes_to_write = _dbus_string_get_length (str);
2063
2064   while (total < bytes_to_write)
2065     {
2066       int bytes_written;
2067
2068       bytes_written = _dbus_write (fd, str, total,
2069                                    bytes_to_write - total);
2070
2071       if (bytes_written <= 0)
2072         {
2073           dbus_set_error (error, _dbus_error_from_errno (errno),
2074                           "Could not write to %s: %s", tmp_filename_c,
2075                           _dbus_strerror (errno));
2076           
2077           goto out;
2078         }
2079
2080       total += bytes_written;
2081     }
2082
2083   if (close (fd) < 0)
2084     {
2085       dbus_set_error (error, _dbus_error_from_errno (errno),
2086                       "Could not close file %s: %s",
2087                       tmp_filename_c, _dbus_strerror (errno));
2088
2089       goto out;
2090     }
2091
2092   fd = -1;
2093   
2094   if (rename (tmp_filename_c, filename_c) < 0)
2095     {
2096       dbus_set_error (error, _dbus_error_from_errno (errno),
2097                       "Could not rename %s to %s: %s",
2098                       tmp_filename_c, filename_c,
2099                       _dbus_strerror (errno));
2100
2101       goto out;
2102     }
2103
2104   need_unlink = FALSE;
2105   
2106   retval = TRUE;
2107   
2108  out:
2109   /* close first, then unlink, to prevent ".nfs34234235" garbage
2110    * files
2111    */
2112
2113   if (fd >= 0)
2114     close (fd);
2115         
2116   if (need_unlink && unlink (tmp_filename_c) < 0)
2117     _dbus_verbose ("Failed to unlink temp file %s: %s\n",
2118                    tmp_filename_c, _dbus_strerror (errno));
2119
2120   _dbus_string_free (&tmp_filename);
2121
2122   if (!retval)
2123     _DBUS_ASSERT_ERROR_IS_SET (error);
2124   
2125   return retval;
2126 }
2127
2128 /** Creates the given file, failing if the file already exists.
2129  *
2130  * @param filename the filename
2131  * @param error error location
2132  * @returns #TRUE if we created the file and it didn't exist
2133  */
2134 dbus_bool_t
2135 _dbus_create_file_exclusively (const DBusString *filename,
2136                                DBusError        *error)
2137 {
2138   int fd;
2139   const char *filename_c;
2140
2141   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2142   
2143   filename_c = _dbus_string_get_const_data (filename);
2144   
2145   fd = open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
2146              0600);
2147   if (fd < 0)
2148     {
2149       dbus_set_error (error,
2150                       DBUS_ERROR_FAILED,
2151                       "Could not create file %s: %s\n",
2152                       filename_c,
2153                       _dbus_errno_to_string (errno));
2154       return FALSE;
2155     }
2156
2157   if (close (fd) < 0)
2158     {
2159       dbus_set_error (error,
2160                       DBUS_ERROR_FAILED,
2161                       "Could not close file %s: %s\n",
2162                       filename_c,
2163                       _dbus_errno_to_string (errno));
2164       return FALSE;
2165     }
2166   
2167   return TRUE;
2168 }
2169
2170 /**
2171  * Deletes the given file.
2172  *
2173  * @param filename the filename
2174  * @param error error location
2175  * 
2176  * @returns #TRUE if unlink() succeeded
2177  */
2178 dbus_bool_t
2179 _dbus_delete_file (const DBusString *filename,
2180                    DBusError        *error)
2181 {
2182   const char *filename_c;
2183
2184   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2185   
2186   filename_c = _dbus_string_get_const_data (filename);
2187
2188   if (unlink (filename_c) < 0)
2189     {
2190       dbus_set_error (error, DBUS_ERROR_FAILED,
2191                       "Failed to delete file %s: %s\n",
2192                       filename_c, _dbus_strerror (errno));
2193       return FALSE;
2194     }
2195   else
2196     return TRUE;
2197 }
2198
2199 /**
2200  * Creates a directory; succeeds if the directory
2201  * is created or already existed.
2202  *
2203  * @param filename directory filename
2204  * @param error initialized error object
2205  * @returns #TRUE on success
2206  */
2207 dbus_bool_t
2208 _dbus_create_directory (const DBusString *filename,
2209                         DBusError        *error)
2210 {
2211   const char *filename_c;
2212
2213   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2214   
2215   filename_c = _dbus_string_get_const_data (filename);
2216
2217   if (mkdir (filename_c, 0700) < 0)
2218     {
2219       if (errno == EEXIST)
2220         return TRUE;
2221       
2222       dbus_set_error (error, DBUS_ERROR_FAILED,
2223                       "Failed to create directory %s: %s\n",
2224                       filename_c, _dbus_strerror (errno));
2225       return FALSE;
2226     }
2227   else
2228     return TRUE;
2229 }
2230
2231 /**
2232  * Appends the given filename to the given directory.
2233  *
2234  * @param dir the directory name
2235  * @param next_component the filename
2236  * @returns #TRUE on success
2237  */
2238 dbus_bool_t
2239 _dbus_concat_dir_and_file (DBusString       *dir,
2240                            const DBusString *next_component)
2241 {
2242   dbus_bool_t dir_ends_in_slash;
2243   dbus_bool_t file_starts_with_slash;
2244
2245   if (_dbus_string_get_length (dir) == 0 ||
2246       _dbus_string_get_length (next_component) == 0)
2247     return TRUE;
2248   
2249   dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2250                                                     _dbus_string_get_length (dir) - 1);
2251
2252   file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2253
2254   if (dir_ends_in_slash && file_starts_with_slash)
2255     {
2256       _dbus_string_shorten (dir, 1);
2257     }
2258   else if (!(dir_ends_in_slash || file_starts_with_slash))
2259     {
2260       if (!_dbus_string_append_byte (dir, '/'))
2261         return FALSE;
2262     }
2263
2264   return _dbus_string_copy (next_component, 0, dir,
2265                             _dbus_string_get_length (dir));
2266 }
2267
2268 struct DBusDirIter
2269 {
2270   DIR *d;
2271   
2272 };
2273
2274 /**
2275  * Open a directory to iterate over.
2276  *
2277  * @param filename the directory name
2278  * @param error exception return object or #NULL
2279  * @returns new iterator, or #NULL on error
2280  */
2281 DBusDirIter*
2282 _dbus_directory_open (const DBusString *filename,
2283                       DBusError        *error)
2284 {
2285   DIR *d;
2286   DBusDirIter *iter;
2287   const char *filename_c;
2288
2289   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2290   
2291   filename_c = _dbus_string_get_const_data (filename);
2292
2293   d = opendir (filename_c);
2294   if (d == NULL)
2295     {
2296       dbus_set_error (error, _dbus_error_from_errno (errno),
2297                       "%s", _dbus_strerror (errno));
2298       return NULL;
2299     }
2300   iter = dbus_new0 (DBusDirIter, 1);
2301   if (iter == NULL)
2302     {
2303       closedir (d);
2304       dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
2305                       "Could not allocate memory for directory iterator");
2306       return NULL;
2307     }
2308
2309   iter->d = d;
2310
2311   return iter;
2312 }
2313
2314 /**
2315  * Get next file in the directory. Will not return "." or ".."  on
2316  * UNIX. If an error occurs, the contents of "filename" are
2317  * undefined. The error is never set if the function succeeds.
2318  *
2319  * @todo for thread safety, I think we have to use
2320  * readdir_r(). (GLib has the same issue, should file a bug.)
2321  *
2322  * @param iter the iterator
2323  * @param filename string to be set to the next file in the dir
2324  * @param error return location for error
2325  * @returns #TRUE if filename was filled in with a new filename
2326  */
2327 dbus_bool_t
2328 _dbus_directory_get_next_file (DBusDirIter      *iter,
2329                                DBusString       *filename,
2330                                DBusError        *error)
2331 {
2332   struct dirent *ent;
2333
2334   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2335   
2336  again:
2337   errno = 0;
2338   ent = readdir (iter->d);
2339   if (ent == NULL)
2340     {
2341       if (errno != 0)
2342         dbus_set_error (error,
2343                         _dbus_error_from_errno (errno),
2344                         "%s", _dbus_strerror (errno));
2345       return FALSE;
2346     }
2347   else if (ent->d_name[0] == '.' &&
2348            (ent->d_name[1] == '\0' ||
2349             (ent->d_name[1] == '.' && ent->d_name[2] == '\0')))
2350     goto again;
2351   else
2352     {
2353       _dbus_string_set_length (filename, 0);
2354       if (!_dbus_string_append (filename, ent->d_name))
2355         {
2356           dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
2357                           "No memory to read directory entry");
2358           return FALSE;
2359         }
2360       else
2361         return TRUE;
2362     }
2363 }
2364
2365 /**
2366  * Closes a directory iteration.
2367  */
2368 void
2369 _dbus_directory_close (DBusDirIter *iter)
2370 {
2371   closedir (iter->d);
2372   dbus_free (iter);
2373 }
2374
2375 /**
2376  * Generates the given number of random bytes,
2377  * using the best mechanism we can come up with.
2378  *
2379  * @param str the string
2380  * @param n_bytes the number of random bytes to append to string
2381  * @returns #TRUE on success, #FALSE if no memory or other failure
2382  */
2383 dbus_bool_t
2384 _dbus_generate_random_bytes (DBusString *str,
2385                              int         n_bytes)
2386 {
2387   int old_len;
2388   int fd;
2389   
2390   old_len = _dbus_string_get_length (str);
2391   fd = -1;
2392
2393   /* note, urandom on linux will fall back to pseudorandom */
2394   fd = open ("/dev/urandom", O_RDONLY);
2395   if (fd < 0)
2396     {
2397       unsigned long tv_usec;
2398       int i;
2399
2400       /* fall back to pseudorandom */
2401       _dbus_verbose ("Falling back to pseudorandom for %d bytes\n",
2402                      n_bytes);
2403       
2404       _dbus_get_current_time (NULL, &tv_usec);
2405       srand (tv_usec);
2406       
2407       i = 0;
2408       while (i < n_bytes)
2409         {
2410           double r;
2411           unsigned int b;
2412           
2413           r = rand ();
2414           b = (r / (double) RAND_MAX) * 255.0;
2415           
2416           if (!_dbus_string_append_byte (str, b))
2417             goto failed;
2418           
2419           ++i;
2420         }
2421
2422       return TRUE;
2423     }
2424   else
2425     {
2426       if (_dbus_read (fd, str, n_bytes) != n_bytes)
2427         goto failed;
2428
2429       _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2430                      n_bytes);
2431       
2432       close (fd);
2433
2434       return TRUE;
2435     }
2436
2437  failed:
2438   _dbus_string_set_length (str, old_len);
2439   if (fd >= 0)
2440     close (fd);
2441   return FALSE;
2442 }
2443
2444 /**
2445  * A wrapper around strerror()
2446  *
2447  * @todo get rid of this function, it's the same as
2448  * _dbus_strerror().
2449  * 
2450  * @param errnum the errno
2451  * @returns an error message (never #NULL)
2452  */
2453 const char *
2454 _dbus_errno_to_string (int errnum)
2455 {
2456   const char *msg;
2457   
2458   msg = strerror (errnum);
2459   if (msg == NULL)
2460     msg = "unknown";
2461
2462   return msg;
2463 }
2464
2465 /**
2466  * A wrapper around strerror() because some platforms
2467  * may be lame and not have strerror().
2468  *
2469  * @param error_number errno.
2470  * @returns error description.
2471  */
2472 const char*
2473 _dbus_strerror (int error_number)
2474 {
2475   const char *msg;
2476   
2477   msg = strerror (error_number);
2478   if (msg == NULL)
2479     msg = "unknown";
2480
2481   return msg;
2482 }
2483
2484 /* Avoids a danger in threaded situations (calling close()
2485  * on a file descriptor twice, and another thread has
2486  * re-opened it since the first close)
2487  */
2488 static int
2489 close_and_invalidate (int *fd)
2490 {
2491   int ret;
2492
2493   if (*fd < 0)
2494     return -1;
2495   else
2496     {
2497       ret = close (*fd);
2498       *fd = -1;
2499     }
2500
2501   return ret;
2502 }
2503
2504 static dbus_bool_t
2505 make_pipe (int        p[2],
2506            DBusError *error)
2507 {
2508   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2509   
2510   if (pipe (p) < 0)
2511     {
2512       dbus_set_error (error,
2513                       DBUS_ERROR_SPAWN_FAILED,
2514                       "Failed to create pipe for communicating with child process (%s)",
2515                       _dbus_errno_to_string (errno));
2516       return FALSE;
2517     }
2518   else
2519     {
2520       _dbus_fd_set_close_on_exec (p[0]);
2521       _dbus_fd_set_close_on_exec (p[1]);      
2522       return TRUE;
2523     }
2524 }
2525
2526 enum
2527 {
2528   CHILD_CHDIR_FAILED,
2529   CHILD_EXEC_FAILED,
2530   CHILD_DUP2_FAILED,
2531   CHILD_FORK_FAILED
2532 };
2533
2534 static void
2535 write_err_and_exit (int fd, int msg)
2536 {
2537   int en = errno;
2538   
2539   write (fd, &msg, sizeof(msg));
2540   write (fd, &en, sizeof(en));
2541   
2542   _exit (1);
2543 }
2544
2545 static dbus_bool_t
2546 read_ints (int        fd,
2547            int       *buf,
2548            int        n_ints_in_buf,
2549            int       *n_ints_read,
2550            DBusError *error)
2551 {
2552   size_t bytes = 0;    
2553
2554   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2555   
2556   while (TRUE)
2557     {
2558       size_t chunk;    
2559
2560       if (bytes >= sizeof(int)*2)
2561         break; /* give up, who knows what happened, should not be
2562                 * possible.
2563                 */
2564           
2565     again:
2566       chunk = read (fd,
2567                     ((char*)buf) + bytes,
2568                     sizeof(int) * n_ints_in_buf - bytes);
2569       if (chunk < 0 && errno == EINTR)
2570         goto again;
2571           
2572       if (chunk < 0)
2573         {
2574           /* Some weird shit happened, bail out */
2575               
2576           dbus_set_error (error,
2577                           DBUS_ERROR_SPAWN_FAILED,
2578                           "Failed to read from child pipe (%s)",
2579                           _dbus_errno_to_string (errno));
2580
2581           return FALSE;
2582         }
2583       else if (chunk == 0)
2584         break; /* EOF */
2585       else /* chunk > 0 */
2586         bytes += chunk;
2587     }
2588
2589   *n_ints_read = (int)(bytes / sizeof(int));
2590
2591   return TRUE;
2592 }
2593
2594 static void
2595 do_exec (int                       child_err_report_fd,
2596          char                    **argv,
2597          DBusSpawnChildSetupFunc   child_setup,
2598          void                     *user_data)
2599 {
2600 #ifdef DBUS_BUILD_TESTS
2601   int i, max_open;
2602 #endif
2603
2604   if (child_setup)
2605     (* child_setup) (user_data);
2606
2607 #ifdef DBUS_BUILD_TESTS
2608   max_open = sysconf (_SC_OPEN_MAX);
2609   
2610   for (i = 3; i < max_open; i++)
2611     {
2612       int retval;
2613
2614       retval = fcntl (i, F_GETFD);
2615
2616       if (retval != -1 && !(retval & FD_CLOEXEC))
2617         _dbus_warn ("Fd %d did not have the close-on-exec flag set!\n", i);
2618     }
2619 #endif
2620   
2621   execv (argv[0], argv);
2622
2623   /* Exec failed */
2624   write_err_and_exit (child_err_report_fd,
2625                       CHILD_EXEC_FAILED);
2626   
2627 }
2628
2629 /**
2630  * Spawns a new process. The executable name and argv[0]
2631  * are the same, both are provided in argv[0]. The child_setup
2632  * function is passed the given user_data and is run in the child
2633  * just before calling exec().
2634  *
2635  * @todo this code should be reviewed/double-checked as it's fairly
2636  * complex and no one has reviewed it yet.
2637  *
2638  * @param argv the executable and arguments
2639  * @param child_setup function to call in child pre-exec()
2640  * @param user_data user data for setup function
2641  * @param error error object to be filled in if function fails
2642  * @returns #TRUE on success, #FALSE if error is filled in
2643  */
2644 dbus_bool_t
2645 _dbus_spawn_async (char                    **argv,
2646                    DBusSpawnChildSetupFunc   child_setup,
2647                    void                     *user_data,
2648                    DBusError                *error)
2649 {
2650   int pid = -1, grandchild_pid;
2651   int child_err_report_pipe[2] = { -1, -1 };
2652   int status;
2653
2654   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2655   
2656   if (!make_pipe (child_err_report_pipe, error))
2657     return FALSE;
2658
2659   pid = fork ();
2660   
2661   if (pid < 0)
2662     {
2663       dbus_set_error (error,
2664                       DBUS_ERROR_SPAWN_FORK_FAILED,
2665                       "Failed to fork (%s)",
2666                       _dbus_errno_to_string (errno));
2667       return FALSE;
2668     }
2669   else if (pid == 0)
2670     {
2671       /* Immediate child. */
2672       
2673       /* Be sure we crash if the parent exits
2674        * and we write to the err_report_pipe
2675        */
2676       signal (SIGPIPE, SIG_DFL);
2677
2678       /* Close the parent's end of the pipes;
2679        * not needed in the close_descriptors case,
2680        * though
2681        */
2682       close_and_invalidate (&child_err_report_pipe[0]);
2683
2684       /* We need to fork an intermediate child that launches the
2685        * final child. The purpose of the intermediate child
2686        * is to exit, so we can waitpid() it immediately.
2687        * Then the grandchild will not become a zombie.
2688        */
2689       grandchild_pid = fork ();
2690       
2691       if (grandchild_pid < 0)
2692         {
2693           write_err_and_exit (child_err_report_pipe[1],
2694                               CHILD_FORK_FAILED);              
2695         }
2696       else if (grandchild_pid == 0)
2697         {
2698           do_exec (child_err_report_pipe[1],
2699                    argv,
2700                    child_setup, user_data);
2701         }
2702       else
2703         {
2704           _exit (0);
2705         }
2706     }
2707   else
2708     {
2709       /* Parent */
2710
2711       int buf[2];
2712       int n_ints = 0;    
2713       
2714       /* Close the uncared-about ends of the pipes */
2715       close_and_invalidate (&child_err_report_pipe[1]);
2716
2717     wait_again:
2718       if (waitpid (pid, &status, 0) < 0)
2719         {
2720           if (errno == EINTR)
2721             goto wait_again;
2722           else if (errno == ECHILD)
2723             ; /* do nothing, child already reaped */
2724           else
2725             _dbus_warn ("waitpid() should not fail in "
2726                         "'_dbus_spawn_async'");
2727         }
2728
2729       if (!read_ints (child_err_report_pipe[0],
2730                       buf, 2, &n_ints,
2731                       error))
2732           goto cleanup_and_fail;
2733       
2734       if (n_ints >= 2)
2735         {
2736           /* Error from the child. */
2737           switch (buf[0])
2738             {
2739             default:
2740               dbus_set_error (error,
2741                               DBUS_ERROR_SPAWN_FAILED,
2742                               "Unknown error executing child process \"%s\"",
2743                               argv[0]);
2744               break;
2745             }
2746
2747           goto cleanup_and_fail;
2748         }
2749
2750
2751       /* Success against all odds! return the information */
2752       close_and_invalidate (&child_err_report_pipe[0]);
2753
2754       return TRUE;
2755     }
2756
2757  cleanup_and_fail:
2758
2759   /* There was an error from the Child, reap the child to avoid it being
2760      a zombie.
2761   */
2762   if (pid > 0)
2763     {
2764     wait_failed:
2765       if (waitpid (pid, NULL, 0) < 0)
2766         {
2767           if (errno == EINTR)
2768             goto wait_failed;
2769           else if (errno == ECHILD)
2770             ; /* do nothing, child already reaped */
2771           else
2772             _dbus_warn ("waitpid() should not fail in "
2773                         "'_dbus_spawn_async'");
2774         }
2775     }
2776   
2777   close_and_invalidate (&child_err_report_pipe[0]);
2778   close_and_invalidate (&child_err_report_pipe[1]);
2779
2780   return FALSE;
2781 }
2782
2783 /**
2784  * signal (SIGPIPE, SIG_IGN);
2785  */
2786 void
2787 _dbus_disable_sigpipe (void)
2788 {
2789   signal (SIGPIPE, SIG_IGN);
2790 }
2791
2792 /**
2793  * Sets the file descriptor to be close
2794  * on exec. Should be called for all file
2795  * descriptors in D-BUS code.
2796  *
2797  * @param fd the file descriptor
2798  */
2799 void
2800 _dbus_fd_set_close_on_exec (int fd)
2801 {
2802   int val;
2803   
2804   val = fcntl (fd, F_GETFD, 0);
2805   
2806   if (val < 0)
2807     return;
2808
2809   val |= FD_CLOEXEC;
2810   
2811   fcntl (fd, F_SETFD, val);
2812 }
2813
2814 /**
2815  * Converts a UNIX errno into a #DBusError name.
2816  *
2817  * @todo should cover more errnos, specifically those
2818  * from open().
2819  * 
2820  * @param error_number the errno.
2821  * @returns an error name
2822  */
2823 const char*
2824 _dbus_error_from_errno (int error_number)
2825 {
2826   switch (error_number)
2827     {
2828     case 0:
2829       return DBUS_ERROR_FAILED;
2830       
2831 #ifdef EPROTONOSUPPORT
2832     case EPROTONOSUPPORT:
2833       return DBUS_ERROR_NOT_SUPPORTED;
2834 #endif
2835 #ifdef EAFNOSUPPORT
2836     case EAFNOSUPPORT:
2837       return DBUS_ERROR_NOT_SUPPORTED;
2838 #endif
2839 #ifdef ENFILE
2840     case ENFILE:
2841       return DBUS_ERROR_LIMITS_EXCEEDED; /* kernel out of memory */
2842 #endif
2843 #ifdef EMFILE
2844     case EMFILE:
2845       return DBUS_ERROR_LIMITS_EXCEEDED;
2846 #endif
2847 #ifdef EACCES
2848     case EACCES:
2849       return DBUS_ERROR_ACCESS_DENIED;
2850 #endif
2851 #ifdef EPERM
2852     case EPERM:
2853       return DBUS_ERROR_ACCESS_DENIED;
2854 #endif
2855 #ifdef ENOBUFS
2856     case ENOBUFS:
2857       return DBUS_ERROR_NO_MEMORY;
2858 #endif
2859 #ifdef ENOMEM
2860     case ENOMEM:
2861       return DBUS_ERROR_NO_MEMORY;
2862 #endif
2863 #ifdef EINVAL
2864     case EINVAL:
2865       return DBUS_ERROR_FAILED;
2866 #endif
2867 #ifdef EBADF
2868     case EBADF:
2869       return DBUS_ERROR_FAILED;
2870 #endif
2871 #ifdef EFAULT
2872     case EFAULT:
2873       return DBUS_ERROR_FAILED;
2874 #endif
2875 #ifdef ENOTSOCK
2876     case ENOTSOCK:
2877       return DBUS_ERROR_FAILED;
2878 #endif
2879 #ifdef EISCONN
2880     case EISCONN:
2881       return DBUS_ERROR_FAILED;
2882 #endif
2883 #ifdef ECONNREFUSED
2884     case ECONNREFUSED:
2885       return DBUS_ERROR_NO_SERVER;
2886 #endif
2887 #ifdef ETIMEDOUT
2888     case ETIMEDOUT:
2889       return DBUS_ERROR_TIMEOUT;
2890 #endif
2891 #ifdef ENETUNREACH
2892     case ENETUNREACH:
2893       return DBUS_ERROR_NO_NETWORK;
2894 #endif
2895 #ifdef EADDRINUSE
2896     case EADDRINUSE:
2897       return DBUS_ERROR_ADDRESS_IN_USE;
2898 #endif
2899 #ifdef EEXIST
2900     case EEXIST:
2901       return DBUS_ERROR_FILE_NOT_FOUND;
2902 #endif
2903 #ifdef ENOENT
2904     case ENOENT:
2905       return DBUS_ERROR_FILE_NOT_FOUND;
2906 #endif
2907     }
2908
2909   return DBUS_ERROR_FAILED;
2910 }
2911
2912 /**
2913  * Exit the process, returning the given value.
2914  *
2915  * @param code the exit code
2916  */
2917 void
2918 _dbus_exit (int code)
2919 {
2920   _exit (code);
2921 }
2922
2923 /**
2924  * stat() wrapper.
2925  *
2926  * @param filename the filename to stat
2927  * @param statbuf the stat info to fill in
2928  * @param error return location for error
2929  * @returns #FALSE if error was set
2930  */
2931 dbus_bool_t
2932 _dbus_stat (const DBusString *filename,
2933             DBusStat         *statbuf,
2934             DBusError        *error)
2935 {
2936   const char *filename_c;
2937   struct stat sb;
2938
2939   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2940   
2941   filename_c = _dbus_string_get_const_data (filename);
2942
2943   if (stat (filename_c, &sb) < 0)
2944     {
2945       dbus_set_error (error, _dbus_error_from_errno (errno),
2946                       "%s", _dbus_strerror (errno));
2947       return FALSE;
2948     }
2949
2950   statbuf->mode = sb.st_mode;
2951   statbuf->nlink = sb.st_nlink;
2952   statbuf->uid = sb.st_uid;
2953   statbuf->gid = sb.st_gid;
2954   statbuf->size = sb.st_size;
2955   statbuf->atime = sb.st_atime;
2956   statbuf->mtime = sb.st_mtime;
2957   statbuf->ctime = sb.st_ctime;
2958
2959   return TRUE;
2960 }
2961
2962 /**
2963  * Creates a full-duplex pipe (as in socketpair()).
2964  * Sets both ends of the pipe nonblocking.
2965  *
2966  * @param fd1 return location for one end
2967  * @param fd2 return location for the other end
2968  * @param error error return
2969  * @returns #FALSE on failure (if error is set)
2970  */
2971 dbus_bool_t
2972 _dbus_full_duplex_pipe (int       *fd1,
2973                         int       *fd2,
2974                         DBusError *error)
2975 {
2976 #ifdef HAVE_SOCKETPAIR
2977   int fds[2];
2978
2979   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2980   
2981   if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) < 0)
2982     {
2983       dbus_set_error (error, _dbus_error_from_errno (errno),
2984                       "Could not create full-duplex pipe");
2985       return FALSE;
2986     }
2987
2988   if (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
2989       !_dbus_set_fd_nonblocking (fds[1], NULL))
2990     {
2991       dbus_set_error (error, _dbus_error_from_errno (errno),
2992                       "Could not set full-duplex pipe nonblocking");
2993       
2994       close (fds[0]);
2995       close (fds[1]);
2996       
2997       return FALSE;
2998     }
2999   
3000   *fd1 = fds[0];
3001   *fd2 = fds[1];
3002   
3003   return TRUE;  
3004 #else
3005   _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
3006   dbus_set_error (error, DBUS_ERROR_FAILED,
3007                   "_dbus_full_duplex_pipe() not implemented on this OS");
3008   return FALSE;
3009 #endif
3010 }
3011
3012 /**
3013  * Closes a file descriptor.
3014  *
3015  * @param fd the file descriptor
3016  * @param error error object
3017  * @returns #FALSE if error set
3018  */
3019 dbus_bool_t
3020 _dbus_close (int        fd,
3021              DBusError *error)
3022 {
3023   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3024   
3025  again:
3026   if (close (fd) < 0)
3027     {
3028       if (errno == EINTR)
3029         goto again;
3030
3031       dbus_set_error (error, _dbus_error_from_errno (errno),
3032                       "Could not close fd %d", fd);
3033       return FALSE;
3034     }
3035
3036   return TRUE;
3037 }
3038
3039 /**
3040  * Sets a file descriptor to be nonblocking.
3041  *
3042  * @param fd the file descriptor.
3043  * @param error address of error location.
3044  * @returns #TRUE on success.
3045  */
3046 dbus_bool_t
3047 _dbus_set_fd_nonblocking (int             fd,
3048                           DBusError      *error)
3049 {
3050   int val;
3051
3052   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3053   
3054   val = fcntl (fd, F_GETFL, 0);
3055   if (val < 0)
3056     {
3057       dbus_set_error (error, _dbus_error_from_errno (errno),
3058                       "Failed to get flags from file descriptor %d: %s",
3059                       fd, _dbus_strerror (errno));
3060       _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3061                      _dbus_strerror (errno));
3062       return FALSE;
3063     }
3064
3065   if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3066     {
3067       dbus_set_error (error, _dbus_error_from_errno (errno),
3068                       "Failed to set nonblocking flag of file descriptor %d: %s",
3069                       fd, _dbus_strerror (errno));
3070       _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3071                      fd, _dbus_strerror (errno));
3072
3073       return FALSE;
3074     }
3075
3076   return TRUE;
3077 }
3078
3079 /**
3080  * On GNU libc systems, print a crude backtrace to the verbose log.
3081  * On other systems, print "no backtrace support"
3082  *
3083  */
3084 void
3085 _dbus_print_backtrace (void)
3086 {
3087 #if defined (HAVE_BACKTRACE) && defined (DBUS_ENABLE_VERBOSE_MODE)
3088   void *bt[500];
3089   int bt_size;
3090   int i;
3091   char **syms;
3092   
3093   bt_size = backtrace (bt, 500);
3094
3095   syms = backtrace_symbols (bt, bt_size);
3096   
3097   i = 0;
3098   while (i < bt_size)
3099     {
3100       _dbus_verbose ("  %s\n", syms[i]);
3101       ++i;
3102     }
3103
3104   free (syms);
3105 #else
3106   _dbus_verbose ("  D-BUS not compiled with backtrace support\n");
3107 #endif
3108 }
3109
3110 /**
3111  * Does the chdir, fork, setsid, etc. to become a daemon process.
3112  *
3113  * @param error return location for errors
3114  * @returns #FALSE on failure
3115  */
3116 dbus_bool_t
3117 _dbus_become_daemon (DBusError *error)
3118 {
3119   const char *s;
3120
3121   /* This is so we don't prevent unmounting of devices. We divert
3122    * all messages to syslog
3123    */
3124   if (chdir ("/") < 0)
3125     {
3126       dbus_set_error (error, DBUS_ERROR_FAILED,
3127                       "Could not chdir() to root directory");
3128       return FALSE;
3129     }
3130
3131   s = _dbus_getenv ("DBUS_DEBUG_OUTPUT");
3132   if (s == NULL || *s == '\0')
3133     {
3134       int dev_null_fd;
3135
3136       /* silently ignore failures here, if someone
3137        * doesn't have /dev/null we may as well try
3138        * to continue anyhow
3139        */
3140
3141       dev_null_fd = open ("/dev/null", O_RDWR);
3142       if (dev_null_fd >= 0)
3143         {
3144          dup2 (dev_null_fd, 0);
3145          dup2 (dev_null_fd, 1);
3146          dup2 (dev_null_fd, 2);
3147        }
3148     }
3149
3150   /* Get a predictable umask */
3151   umask (022);
3152
3153   switch (fork ())
3154     {
3155     case -1:
3156       dbus_set_error (error, _dbus_error_from_errno (errno),
3157                       "Failed to fork daemon: %s", _dbus_strerror (errno));
3158       return FALSE;
3159       break;
3160
3161     case 0:      
3162       break;
3163
3164     default:
3165       _exit (0);
3166       break;
3167     }
3168
3169   if (setsid () == -1)
3170     _dbus_assert_not_reached ("setsid() failed");
3171   
3172   return TRUE;
3173 }
3174
3175 /**
3176  * Changes the user and group the bus is running as.
3177  *
3178  * @param uid the new user ID
3179  * @param gid the new group ID
3180  * @param error return location for errors
3181  * @returns #FALSE on failure
3182  */
3183 dbus_bool_t
3184 _dbus_change_identity  (unsigned long  uid,
3185                         unsigned long  gid,
3186                         DBusError     *error)
3187 {
3188   /* Set GID first, or the setuid may remove our permission
3189    * to change the GID
3190    */
3191   if (setgid (gid) < 0)
3192     {
3193       dbus_set_error (error, _dbus_error_from_errno (errno),
3194                       "Failed to set GID to %lu: %s", gid,
3195                       _dbus_strerror (errno));
3196       return FALSE;
3197     }
3198   
3199   if (setuid (uid) < 0)
3200     {
3201       dbus_set_error (error, _dbus_error_from_errno (errno),
3202                       "Failed to set UID to %lu: %s", uid,
3203                       _dbus_strerror (errno));
3204       return FALSE;
3205     }
3206   
3207   return TRUE;
3208 }
3209
3210 /** @} end of sysdeps */