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