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