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