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