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