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