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