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