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