Windows fixes
[platform/upstream/dbus.git] / dbus / dbus-sysdeps-unix.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-sysdeps-unix.c Wrappers around UNIX system/libc features (internal to D-Bus implementation)
3  * 
4  * Copyright (C) 2002, 2003, 2006  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  */
24
25 #include <config.h>
26
27 #include "dbus-internals.h"
28 #include "dbus-sysdeps.h"
29 #include "dbus-sysdeps-unix.h"
30 #include "dbus-threads.h"
31 #include "dbus-protocol.h"
32 #include "dbus-transport.h"
33 #include "dbus-string.h"
34 #include "dbus-userdb.h"
35 #include "dbus-list.h"
36 #include "dbus-credentials.h"
37 #include "dbus-nonce.h"
38
39 #include <sys/types.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <signal.h>
43 #include <unistd.h>
44 #include <stdio.h>
45 #include <fcntl.h>
46 #include <sys/socket.h>
47 #include <dirent.h>
48 #include <sys/un.h>
49 #include <pwd.h>
50 #include <time.h>
51 #include <locale.h>
52 #include <sys/time.h>
53 #include <sys/stat.h>
54 #include <sys/wait.h>
55 #include <netinet/in.h>
56 #include <netdb.h>
57 #include <grp.h>
58
59 #ifdef HAVE_ERRNO_H
60 #include <errno.h>
61 #endif
62 #ifdef HAVE_WRITEV
63 #include <sys/uio.h>
64 #endif
65 #ifdef HAVE_POLL
66 #include <sys/poll.h>
67 #endif
68 #ifdef HAVE_BACKTRACE
69 #include <execinfo.h>
70 #endif
71 #ifdef HAVE_GETPEERUCRED
72 #include <ucred.h>
73 #endif
74
75 #ifdef HAVE_ADT
76 #include <bsm/adt.h>
77 #endif
78
79 #ifndef O_BINARY
80 #define O_BINARY 0
81 #endif
82
83 #ifndef AI_ADDRCONFIG
84 #define AI_ADDRCONFIG 0
85 #endif
86
87 #ifndef HAVE_SOCKLEN_T
88 #define socklen_t int
89 #endif
90
91 static dbus_bool_t
92 _dbus_open_socket (int              *fd_p,
93                    int               domain,
94                    int               type,
95                    int               protocol,
96                    DBusError        *error)
97 {
98 #ifdef SOCK_CLOEXEC
99   dbus_bool_t cloexec_done;
100
101   *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
102   cloexec_done = *fd_p >= 0;
103
104   /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
105   if (*fd_p < 0 && errno == EINVAL)
106 #endif
107     {
108       *fd_p = socket (domain, type, protocol);
109     }
110
111   if (*fd_p >= 0)
112     {
113 #ifdef SOCK_CLOEXEC
114       if (!cloexec_done)
115 #endif
116         {
117           _dbus_fd_set_close_on_exec(*fd_p);
118         }
119
120       _dbus_verbose ("socket fd %d opened\n", *fd_p);
121       return TRUE;
122     }
123   else
124     {
125       dbus_set_error(error,
126                      _dbus_error_from_errno (errno),
127                      "Failed to open socket: %s",
128                      _dbus_strerror (errno));
129       return FALSE;
130     }
131 }
132
133 dbus_bool_t
134 _dbus_open_tcp_socket (int              *fd,
135                        DBusError        *error)
136 {
137   return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error);
138 }
139
140 /**
141  * Opens a UNIX domain socket (as in the socket() call).
142  * Does not bind the socket.
143  *
144  * This will set FD_CLOEXEC for the socket returned
145  *
146  * @param fd return location for socket descriptor
147  * @param error return location for an error
148  * @returns #FALSE if error is set
149  */
150 dbus_bool_t
151 _dbus_open_unix_socket (int              *fd,
152                         DBusError        *error)
153 {
154   return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
155 }
156
157 /**
158  * Closes a socket. Should not be used on non-socket
159  * file descriptors or handles.
160  *
161  * @param fd the socket
162  * @param error return location for an error
163  * @returns #FALSE if error is set
164  */
165 dbus_bool_t 
166 _dbus_close_socket (int               fd,
167                     DBusError        *error)
168 {
169   return _dbus_close (fd, error);
170 }
171
172 /**
173  * Like _dbus_read(), but only works on sockets so is
174  * available on Windows.
175  *
176  * @param fd the socket
177  * @param buffer string to append data to
178  * @param count max amount of data to read
179  * @returns number of bytes appended to the string
180  */
181 int
182 _dbus_read_socket (int               fd,
183                    DBusString       *buffer,
184                    int               count)
185 {
186   return _dbus_read (fd, buffer, count);
187 }
188
189 /**
190  * Like _dbus_write(), but only supports sockets
191  * and is thus available on Windows.
192  *
193  * @param fd the file descriptor to write
194  * @param buffer the buffer to write data from
195  * @param start the first byte in the buffer to write
196  * @param len the number of bytes to try to write
197  * @returns the number of bytes written or -1 on error
198  */
199 int
200 _dbus_write_socket (int               fd,
201                     const DBusString *buffer,
202                     int               start,
203                     int               len)
204 {
205 #ifdef MSG_NOSIGNAL
206   const char *data;
207   int bytes_written;
208
209   data = _dbus_string_get_const_data_len (buffer, start, len);
210
211  again:
212
213   bytes_written = send (fd, data, len, MSG_NOSIGNAL);
214
215   if (bytes_written < 0 && errno == EINTR)
216     goto again;
217
218   return bytes_written;
219
220 #else
221   return _dbus_write (fd, buffer, start, len);
222 #endif
223 }
224
225 /**
226  * Like _dbus_read_socket() but also tries to read unix fds from the
227  * socket. When there are more fds to read than space in the array
228  * passed this function will fail with ENOSPC.
229  *
230  * @param fd the socket
231  * @param buffer string to append data to
232  * @param count max amount of data to read
233  * @param fds array to place read file descriptors in
234  * @param n_fds on input space in fds array, on output how many fds actually got read
235  * @returns number of bytes appended to string
236  */
237 int
238 _dbus_read_socket_with_unix_fds (int               fd,
239                                  DBusString       *buffer,
240                                  int               count,
241                                  int              *fds,
242                                  int              *n_fds) {
243 #ifndef HAVE_UNIX_FD_PASSING
244   int r;
245
246   if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
247     return r;
248
249   *n_fds = 0;
250   return r;
251
252 #else
253   int bytes_read;
254   int start;
255   struct msghdr m;
256   struct iovec iov;
257
258   _dbus_assert (count >= 0);
259   _dbus_assert (*n_fds >= 0);
260
261   start = _dbus_string_get_length (buffer);
262
263   if (!_dbus_string_lengthen (buffer, count))
264     {
265       errno = ENOMEM;
266       return -1;
267     }
268
269   _DBUS_ZERO(iov);
270   iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
271   iov.iov_len = count;
272
273   _DBUS_ZERO(m);
274   m.msg_iov = &iov;
275   m.msg_iovlen = 1;
276
277   /* Hmm, we have no clue how long the control data will actually be
278      that is queued for us. The least we can do is assume that the
279      caller knows. Hence let's make space for the number of fds that
280      we shall read at max plus the cmsg header. */
281   m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
282
283   /* It's probably safe to assume that systems with SCM_RIGHTS also
284      know alloca() */
285   m.msg_control = alloca(m.msg_controllen);
286   memset(m.msg_control, 0, m.msg_controllen);
287
288  again:
289
290   bytes_read = recvmsg(fd, &m, 0
291 #ifdef MSG_CMSG_CLOEXEC
292                        |MSG_CMSG_CLOEXEC
293 #endif
294                        );
295
296   if (bytes_read < 0)
297     {
298       if (errno == EINTR)
299         goto again;
300       else
301         {
302           /* put length back (note that this doesn't actually realloc anything) */
303           _dbus_string_set_length (buffer, start);
304           return -1;
305         }
306     }
307   else
308     {
309       struct cmsghdr *cm;
310       dbus_bool_t found = FALSE;
311
312       if (m.msg_flags & MSG_CTRUNC)
313         {
314           /* Hmm, apparently the control data was truncated. The bad
315              thing is that we might have completely lost a couple of fds
316              without chance to recover them. Hence let's treat this as a
317              serious error. */
318
319           errno = ENOSPC;
320           _dbus_string_set_length (buffer, start);
321           return -1;
322         }
323
324       for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
325         if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
326           {
327             unsigned i;
328
329             _dbus_assert(cm->cmsg_len <= CMSG_LEN(*n_fds * sizeof(int)));
330             *n_fds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(int);
331
332             memcpy(fds, CMSG_DATA(cm), *n_fds * sizeof(int));
333             found = TRUE;
334
335             /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
336                worked, hence we need to go through this list and set
337                CLOEXEC everywhere in any case */
338             for (i = 0; i < *n_fds; i++)
339               _dbus_fd_set_close_on_exec(fds[i]);
340
341             break;
342           }
343
344       if (!found)
345         *n_fds = 0;
346
347       /* put length back (doesn't actually realloc) */
348       _dbus_string_set_length (buffer, start + bytes_read);
349
350 #if 0
351       if (bytes_read > 0)
352         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
353 #endif
354
355       return bytes_read;
356     }
357 #endif
358 }
359
360 int
361 _dbus_write_socket_with_unix_fds(int               fd,
362                                  const DBusString *buffer,
363                                  int               start,
364                                  int               len,
365                                  const int        *fds,
366                                  int               n_fds) {
367
368 #ifndef HAVE_UNIX_FD_PASSING
369
370   if (n_fds > 0) {
371     errno = ENOTSUP;
372     return -1;
373   }
374
375   return _dbus_write_socket(fd, buffer, start, len);
376 #else
377   return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
378 #endif
379 }
380
381 int
382 _dbus_write_socket_with_unix_fds_two(int               fd,
383                                      const DBusString *buffer1,
384                                      int               start1,
385                                      int               len1,
386                                      const DBusString *buffer2,
387                                      int               start2,
388                                      int               len2,
389                                      const int        *fds,
390                                      int               n_fds) {
391
392 #ifndef HAVE_UNIX_FD_PASSING
393
394   if (n_fds > 0) {
395     errno = ENOTSUP;
396     return -1;
397   }
398
399   return _dbus_write_socket_two(fd,
400                                 buffer1, start1, len1,
401                                 buffer2, start2, len2);
402 #else
403
404   struct msghdr m;
405   struct cmsghdr *cm;
406   struct iovec iov[2];
407   int bytes_written;
408
409   _dbus_assert (len1 >= 0);
410   _dbus_assert (len2 >= 0);
411   _dbus_assert (n_fds >= 0);
412
413   _DBUS_ZERO(iov);
414   iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
415   iov[0].iov_len = len1;
416
417   if (buffer2)
418     {
419       iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
420       iov[1].iov_len = len2;
421     }
422
423   _DBUS_ZERO(m);
424   m.msg_iov = iov;
425   m.msg_iovlen = buffer2 ? 2 : 1;
426
427   if (n_fds > 0)
428     {
429       m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
430       m.msg_control = alloca(m.msg_controllen);
431       memset(m.msg_control, 0, m.msg_controllen);
432
433       cm = CMSG_FIRSTHDR(&m);
434       cm->cmsg_level = SOL_SOCKET;
435       cm->cmsg_type = SCM_RIGHTS;
436       cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
437       memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
438     }
439
440  again:
441
442   bytes_written = sendmsg (fd, &m, 0
443 #ifdef MSG_NOSIGNAL
444                            |MSG_NOSIGNAL
445 #endif
446                            );
447
448   if (bytes_written < 0 && errno == EINTR)
449     goto again;
450
451 #if 0
452   if (bytes_written > 0)
453     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
454 #endif
455
456   return bytes_written;
457 #endif
458 }
459
460 /**
461  * write data to a pipe.
462  *
463  * @param pipe the pipe instance
464  * @param buffer the buffer to write data from
465  * @param start the first byte in the buffer to write
466  * @param len the number of bytes to try to write
467  * @param error error return
468  * @returns the number of bytes written or -1 on error
469  */
470 int
471 _dbus_pipe_write (DBusPipe         *pipe,
472                   const DBusString *buffer,
473                   int               start,
474                   int               len,
475                   DBusError        *error)
476 {
477   int written;
478   
479   written = _dbus_write (pipe->fd_or_handle, buffer, start, len);
480   if (written < 0)
481     {
482       dbus_set_error (error, DBUS_ERROR_FAILED,
483                       "Writing to pipe: %s\n",
484                       _dbus_strerror (errno));
485     }
486   return written;
487 }
488
489 /**
490  * close a pipe.
491  *
492  * @param pipe the pipe instance
493  * @param error return location for an error
494  * @returns #FALSE if error is set
495  */
496 int
497 _dbus_pipe_close  (DBusPipe         *pipe,
498                    DBusError        *error)
499 {
500   if (_dbus_close (pipe->fd_or_handle, error) < 0)
501     {
502       return -1;
503     }
504   else
505     {
506       _dbus_pipe_invalidate (pipe);
507       return 0;
508     }
509 }
510
511 /**
512  * Like _dbus_write_two() but only works on sockets and is thus
513  * available on Windows.
514  * 
515  * @param fd the file descriptor
516  * @param buffer1 first buffer
517  * @param start1 first byte to write in first buffer
518  * @param len1 number of bytes to write from first buffer
519  * @param buffer2 second buffer, or #NULL
520  * @param start2 first byte to write in second buffer
521  * @param len2 number of bytes to write in second buffer
522  * @returns total bytes written from both buffers, or -1 on error
523  */
524 int
525 _dbus_write_socket_two (int               fd,
526                         const DBusString *buffer1,
527                         int               start1,
528                         int               len1,
529                         const DBusString *buffer2,
530                         int               start2,
531                         int               len2)
532 {
533 #ifdef MSG_NOSIGNAL
534   struct iovec vectors[2];
535   const char *data1;
536   const char *data2;
537   int bytes_written;
538   struct msghdr m;
539
540   _dbus_assert (buffer1 != NULL);
541   _dbus_assert (start1 >= 0);
542   _dbus_assert (start2 >= 0);
543   _dbus_assert (len1 >= 0);
544   _dbus_assert (len2 >= 0);
545
546   data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
547
548   if (buffer2 != NULL)
549     data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
550   else
551     {
552       data2 = NULL;
553       start2 = 0;
554       len2 = 0;
555     }
556
557   vectors[0].iov_base = (char*) data1;
558   vectors[0].iov_len = len1;
559   vectors[1].iov_base = (char*) data2;
560   vectors[1].iov_len = len2;
561
562   _DBUS_ZERO(m);
563   m.msg_iov = vectors;
564   m.msg_iovlen = data2 ? 2 : 1;
565
566  again:
567
568   bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
569
570   if (bytes_written < 0 && errno == EINTR)
571     goto again;
572
573   return bytes_written;
574
575 #else
576   return _dbus_write_two (fd, buffer1, start1, len1,
577                           buffer2, start2, len2);
578 #endif
579 }
580
581 dbus_bool_t
582 _dbus_socket_is_invalid (int fd)
583 {
584     return fd < 0 ? TRUE : FALSE;
585 }
586
587 /**
588  * Thin wrapper around the read() system call that appends
589  * the data it reads to the DBusString buffer. It appends
590  * up to the given count, and returns the same value
591  * and same errno as read(). The only exception is that
592  * _dbus_read() handles EINTR for you. Also, _dbus_read() can
593  * return ENOMEM, even though regular UNIX read doesn't.
594  *
595  * Unlike _dbus_read_socket(), _dbus_read() is not available
596  * on Windows.
597  * 
598  * @param fd the file descriptor to read from
599  * @param buffer the buffer to append data to
600  * @param count the amount of data to read
601  * @returns the number of bytes read or -1
602  */
603 int
604 _dbus_read (int               fd,
605             DBusString       *buffer,
606             int               count)
607 {
608   int bytes_read;
609   int start;
610   char *data;
611
612   _dbus_assert (count >= 0);
613   
614   start = _dbus_string_get_length (buffer);
615
616   if (!_dbus_string_lengthen (buffer, count))
617     {
618       errno = ENOMEM;
619       return -1;
620     }
621
622   data = _dbus_string_get_data_len (buffer, start, count);
623
624  again:
625   
626   bytes_read = read (fd, data, count);
627
628   if (bytes_read < 0)
629     {
630       if (errno == EINTR)
631         goto again;
632       else
633         {
634           /* put length back (note that this doesn't actually realloc anything) */
635           _dbus_string_set_length (buffer, start);
636           return -1;
637         }
638     }
639   else
640     {
641       /* put length back (doesn't actually realloc) */
642       _dbus_string_set_length (buffer, start + bytes_read);
643
644 #if 0
645       if (bytes_read > 0)
646         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
647 #endif
648       
649       return bytes_read;
650     }
651 }
652
653 /**
654  * Thin wrapper around the write() system call that writes a part of a
655  * DBusString and handles EINTR for you.
656  * 
657  * @param fd the file descriptor to write
658  * @param buffer the buffer to write data from
659  * @param start the first byte in the buffer to write
660  * @param len the number of bytes to try to write
661  * @returns the number of bytes written or -1 on error
662  */
663 int
664 _dbus_write (int               fd,
665              const DBusString *buffer,
666              int               start,
667              int               len)
668 {
669   const char *data;
670   int bytes_written;
671   
672   data = _dbus_string_get_const_data_len (buffer, start, len);
673   
674  again:
675
676   bytes_written = write (fd, data, len);
677
678   if (bytes_written < 0 && errno == EINTR)
679     goto again;
680
681 #if 0
682   if (bytes_written > 0)
683     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
684 #endif
685   
686   return bytes_written;
687 }
688
689 /**
690  * Like _dbus_write() but will use writev() if possible
691  * to write both buffers in sequence. The return value
692  * is the number of bytes written in the first buffer,
693  * plus the number written in the second. If the first
694  * buffer is written successfully and an error occurs
695  * writing the second, the number of bytes in the first
696  * is returned (i.e. the error is ignored), on systems that
697  * don't have writev. Handles EINTR for you.
698  * The second buffer may be #NULL.
699  *
700  * @param fd the file descriptor
701  * @param buffer1 first buffer
702  * @param start1 first byte to write in first buffer
703  * @param len1 number of bytes to write from first buffer
704  * @param buffer2 second buffer, or #NULL
705  * @param start2 first byte to write in second buffer
706  * @param len2 number of bytes to write in second buffer
707  * @returns total bytes written from both buffers, or -1 on error
708  */
709 int
710 _dbus_write_two (int               fd,
711                  const DBusString *buffer1,
712                  int               start1,
713                  int               len1,
714                  const DBusString *buffer2,
715                  int               start2,
716                  int               len2)
717 {
718   _dbus_assert (buffer1 != NULL);
719   _dbus_assert (start1 >= 0);
720   _dbus_assert (start2 >= 0);
721   _dbus_assert (len1 >= 0);
722   _dbus_assert (len2 >= 0);
723   
724 #ifdef HAVE_WRITEV
725   {
726     struct iovec vectors[2];
727     const char *data1;
728     const char *data2;
729     int bytes_written;
730
731     data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
732
733     if (buffer2 != NULL)
734       data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
735     else
736       {
737         data2 = NULL;
738         start2 = 0;
739         len2 = 0;
740       }
741    
742     vectors[0].iov_base = (char*) data1;
743     vectors[0].iov_len = len1;
744     vectors[1].iov_base = (char*) data2;
745     vectors[1].iov_len = len2;
746
747   again:
748    
749     bytes_written = writev (fd,
750                             vectors,
751                             data2 ? 2 : 1);
752
753     if (bytes_written < 0 && errno == EINTR)
754       goto again;
755    
756     return bytes_written;
757   }
758 #else /* HAVE_WRITEV */
759   {
760     int ret1;
761     
762     ret1 = _dbus_write (fd, buffer1, start1, len1);
763     if (ret1 == len1 && buffer2 != NULL)
764       {
765         ret2 = _dbus_write (fd, buffer2, start2, len2);
766         if (ret2 < 0)
767           ret2 = 0; /* we can't report an error as the first write was OK */
768        
769         return ret1 + ret2;
770       }
771     else
772       return ret1;
773   }
774 #endif /* !HAVE_WRITEV */   
775 }
776
777 #define _DBUS_MAX_SUN_PATH_LENGTH 99
778
779 /**
780  * @def _DBUS_MAX_SUN_PATH_LENGTH
781  *
782  * Maximum length of the path to a UNIX domain socket,
783  * sockaddr_un::sun_path member. POSIX requires that all systems
784  * support at least 100 bytes here, including the nul termination.
785  * We use 99 for the max value to allow for the nul.
786  *
787  * We could probably also do sizeof (addr.sun_path)
788  * but this way we are the same on all platforms
789  * which is probably a good idea.
790  */
791
792 /**
793  * Creates a socket and connects it to the UNIX domain socket at the
794  * given path.  The connection fd is returned, and is set up as
795  * nonblocking.
796  * 
797  * Uses abstract sockets instead of filesystem-linked sockets if
798  * requested (it's possible only on Linux; see "man 7 unix" on Linux).
799  * On non-Linux abstract socket usage always fails.
800  *
801  * This will set FD_CLOEXEC for the socket returned.
802  *
803  * @param path the path to UNIX domain socket
804  * @param abstract #TRUE to use abstract namespace
805  * @param error return location for error code
806  * @returns connection file descriptor or -1 on error
807  */
808 int
809 _dbus_connect_unix_socket (const char     *path,
810                            dbus_bool_t     abstract,
811                            DBusError      *error)
812 {
813   int fd;
814   size_t path_len;
815   struct sockaddr_un addr;  
816
817   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
818
819   _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
820                  path, abstract);
821   
822   
823   if (!_dbus_open_unix_socket (&fd, error))
824     {
825       _DBUS_ASSERT_ERROR_IS_SET(error);
826       return -1;
827     }
828   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
829
830   _DBUS_ZERO (addr);
831   addr.sun_family = AF_UNIX;
832   path_len = strlen (path);
833
834   if (abstract)
835     {
836 #ifdef HAVE_ABSTRACT_SOCKETS
837       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
838       path_len++; /* Account for the extra nul byte added to the start of sun_path */
839
840       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
841         {
842           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
843                       "Abstract socket name too long\n");
844           _dbus_close (fd, NULL);
845           return -1;
846         }
847         
848       strncpy (&addr.sun_path[1], path, path_len);
849       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
850 #else /* HAVE_ABSTRACT_SOCKETS */
851       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
852                       "Operating system does not support abstract socket namespace\n");
853       _dbus_close (fd, NULL);
854       return -1;
855 #endif /* ! HAVE_ABSTRACT_SOCKETS */
856     }
857   else
858     {
859       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
860         {
861           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
862                       "Socket name too long\n");
863           _dbus_close (fd, NULL);
864           return -1;
865         }
866
867       strncpy (addr.sun_path, path, path_len);
868     }
869   
870   if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
871     {      
872       dbus_set_error (error,
873                       _dbus_error_from_errno (errno),
874                       "Failed to connect to socket %s: %s",
875                       path, _dbus_strerror (errno));
876
877       _dbus_close (fd, NULL);
878       fd = -1;
879       
880       return -1;
881     }
882
883   if (!_dbus_set_fd_nonblocking (fd, error))
884     {
885       _DBUS_ASSERT_ERROR_IS_SET (error);
886       
887       _dbus_close (fd, NULL);
888       fd = -1;
889
890       return -1;
891     }
892
893   return fd;
894 }
895
896 /**
897  * Enables or disables the reception of credentials on the given socket during
898  * the next message transmission.  This is only effective if the #LOCAL_CREDS
899  * system feature exists, in which case the other side of the connection does
900  * not have to do anything special to send the credentials.
901  *
902  * @param fd socket on which to change the #LOCAL_CREDS flag.
903  * @param on whether to enable or disable the #LOCAL_CREDS flag.
904  */
905 static dbus_bool_t
906 _dbus_set_local_creds (int fd, dbus_bool_t on)
907 {
908   dbus_bool_t retval = TRUE;
909
910 #if defined(HAVE_CMSGCRED)
911   /* NOOP just to make sure only one codepath is used 
912    *      and to prefer CMSGCRED
913    */
914 #elif defined(LOCAL_CREDS) 
915   int val = on ? 1 : 0;
916   if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
917     {
918       _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
919       retval = FALSE;
920     }
921   else
922     _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
923                    on ? "enabled" : "disabled", fd);
924 #endif
925
926   return retval;
927 }
928
929 /**
930  * Creates a socket and binds it to the given path,
931  * then listens on the socket. The socket is
932  * set to be nonblocking.
933  *
934  * Uses abstract sockets instead of filesystem-linked
935  * sockets if requested (it's possible only on Linux;
936  * see "man 7 unix" on Linux).
937  * On non-Linux abstract socket usage always fails.
938  *
939  * This will set FD_CLOEXEC for the socket returned
940  *
941  * @param path the socket name
942  * @param abstract #TRUE to use abstract namespace
943  * @param error return location for errors
944  * @returns the listening file descriptor or -1 on error
945  */
946 int
947 _dbus_listen_unix_socket (const char     *path,
948                           dbus_bool_t     abstract,
949                           DBusError      *error)
950 {
951   int listen_fd;
952   struct sockaddr_un addr;
953   size_t path_len;
954
955   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
956
957   _dbus_verbose ("listening on unix socket %s abstract=%d\n",
958                  path, abstract);
959   
960   if (!_dbus_open_unix_socket (&listen_fd, error))
961     {
962       _DBUS_ASSERT_ERROR_IS_SET(error);
963       return -1;
964     }
965   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
966
967   _DBUS_ZERO (addr);
968   addr.sun_family = AF_UNIX;
969   path_len = strlen (path);
970   
971   if (abstract)
972     {
973 #ifdef HAVE_ABSTRACT_SOCKETS
974       /* remember that abstract names aren't nul-terminated so we rely
975        * on sun_path being filled in with zeroes above.
976        */
977       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
978       path_len++; /* Account for the extra nul byte added to the start of sun_path */
979
980       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
981         {
982           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
983                       "Abstract socket name too long\n");
984           _dbus_close (listen_fd, NULL);
985           return -1;
986         }
987       
988       strncpy (&addr.sun_path[1], path, path_len);
989       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
990 #else /* HAVE_ABSTRACT_SOCKETS */
991       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
992                       "Operating system does not support abstract socket namespace\n");
993       _dbus_close (listen_fd, NULL);
994       return -1;
995 #endif /* ! HAVE_ABSTRACT_SOCKETS */
996     }
997   else
998     {
999       /* Discussed security implications of this with Nalin,
1000        * and we couldn't think of where it would kick our ass, but
1001        * it still seems a bit sucky. It also has non-security suckage;
1002        * really we'd prefer to exit if the socket is already in use.
1003        * But there doesn't seem to be a good way to do this.
1004        *
1005        * Just to be extra careful, I threw in the stat() - clearly
1006        * the stat() can't *fix* any security issue, but it at least
1007        * avoids inadvertent/accidental data loss.
1008        */
1009       {
1010         struct stat sb;
1011
1012         if (stat (path, &sb) == 0 &&
1013             S_ISSOCK (sb.st_mode))
1014           unlink (path);
1015       }
1016
1017       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1018         {
1019           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1020                       "Abstract socket name too long\n");
1021           _dbus_close (listen_fd, NULL);
1022           return -1;
1023         }
1024         
1025       strncpy (addr.sun_path, path, path_len);
1026     }
1027   
1028   if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1029     {
1030       dbus_set_error (error, _dbus_error_from_errno (errno),
1031                       "Failed to bind socket \"%s\": %s",
1032                       path, _dbus_strerror (errno));
1033       _dbus_close (listen_fd, NULL);
1034       return -1;
1035     }
1036
1037   if (listen (listen_fd, 30 /* backlog */) < 0)
1038     {
1039       dbus_set_error (error, _dbus_error_from_errno (errno),
1040                       "Failed to listen on socket \"%s\": %s",
1041                       path, _dbus_strerror (errno));
1042       _dbus_close (listen_fd, NULL);
1043       return -1;
1044     }
1045
1046   if (!_dbus_set_local_creds (listen_fd, TRUE))
1047     {
1048       dbus_set_error (error, _dbus_error_from_errno (errno),
1049                       "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
1050                       path, _dbus_strerror (errno));
1051       close (listen_fd);
1052       return -1;
1053     }
1054
1055   if (!_dbus_set_fd_nonblocking (listen_fd, error))
1056     {
1057       _DBUS_ASSERT_ERROR_IS_SET (error);
1058       _dbus_close (listen_fd, NULL);
1059       return -1;
1060     }
1061   
1062   /* Try opening up the permissions, but if we can't, just go ahead
1063    * and continue, maybe it will be good enough.
1064    */
1065   if (!abstract && chmod (path, 0777) < 0)
1066     _dbus_warn ("Could not set mode 0777 on socket %s\n",
1067                 path);
1068   
1069   return listen_fd;
1070 }
1071
1072 /**
1073  * Creates a socket and connects to a socket at the given host 
1074  * and port. The connection fd is returned, and is set up as
1075  * nonblocking.
1076  *
1077  * This will set FD_CLOEXEC for the socket returned
1078  *
1079  * @param host the host name to connect to
1080  * @param port the port to connect to
1081  * @param family the address family to listen on, NULL for all
1082  * @param error return location for error code
1083  * @returns connection file descriptor or -1 on error
1084  */
1085 int
1086 _dbus_connect_tcp_socket (const char     *host,
1087                           const char     *port,
1088                           const char     *family,
1089                           DBusError      *error)
1090 {
1091     return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1092 }
1093
1094 int
1095 _dbus_connect_tcp_socket_with_nonce (const char     *host,
1096                                      const char     *port,
1097                                      const char     *family,
1098                                      const char     *noncefile,
1099                                      DBusError      *error)
1100 {
1101   int saved_errno = 0;
1102   int fd = -1, res;
1103   struct addrinfo hints;
1104   struct addrinfo *ai, *tmp;
1105
1106   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1107
1108   if (!_dbus_open_tcp_socket (&fd, error))
1109     {
1110       _DBUS_ASSERT_ERROR_IS_SET(error);
1111       return -1;
1112     }
1113
1114   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1115
1116   _DBUS_ZERO (hints);
1117
1118   if (!family)
1119     hints.ai_family = AF_UNSPEC;
1120   else if (!strcmp(family, "ipv4"))
1121     hints.ai_family = AF_INET;
1122   else if (!strcmp(family, "ipv6"))
1123     hints.ai_family = AF_INET6;
1124   else
1125     {
1126       dbus_set_error (error,
1127                       DBUS_ERROR_BAD_ADDRESS,
1128                       "Unknown address family %s", family);
1129       return -1;
1130     }
1131   hints.ai_protocol = IPPROTO_TCP;
1132   hints.ai_socktype = SOCK_STREAM;
1133   hints.ai_flags = AI_ADDRCONFIG;
1134
1135   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1136     {
1137       dbus_set_error (error,
1138                       _dbus_error_from_errno (errno),
1139                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1140                       host, port, gai_strerror(res), res);
1141       _dbus_close (fd, NULL);
1142       return -1;
1143     }
1144
1145   tmp = ai;
1146   while (tmp)
1147     {
1148       if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1149         {
1150           freeaddrinfo(ai);
1151           _DBUS_ASSERT_ERROR_IS_SET(error);
1152           return -1;
1153         }
1154       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1155
1156       if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1157         {
1158           saved_errno = errno;
1159           _dbus_close(fd, NULL);
1160           fd = -1;
1161           tmp = tmp->ai_next;
1162           continue;
1163         }
1164
1165       break;
1166     }
1167   freeaddrinfo(ai);
1168
1169   if (fd == -1)
1170     {
1171       dbus_set_error (error,
1172                       _dbus_error_from_errno (saved_errno),
1173                       "Failed to connect to socket \"%s:%s\" %s",
1174                       host, port, _dbus_strerror(saved_errno));
1175       return -1;
1176     }
1177
1178   if (noncefile != NULL)
1179     {
1180       DBusString noncefileStr;
1181       dbus_bool_t ret;
1182       _dbus_string_init_const (&noncefileStr, noncefile);
1183       ret = _dbus_send_nonce (fd, &noncefileStr, error);
1184       _dbus_string_free (&noncefileStr);
1185
1186       if (!ret)
1187     {
1188       _dbus_close (fd, NULL);
1189           return -1;
1190         }
1191     }
1192
1193   if (!_dbus_set_fd_nonblocking (fd, error))
1194     {
1195       _dbus_close (fd, NULL);
1196       return -1;
1197     }
1198
1199   return fd;
1200 }
1201
1202 /**
1203  * Creates a socket and binds it to the given path, then listens on
1204  * the socket. The socket is set to be nonblocking.  In case of port=0
1205  * a random free port is used and returned in the port parameter.
1206  * If inaddr_any is specified, the hostname is ignored.
1207  *
1208  * This will set FD_CLOEXEC for the socket returned
1209  *
1210  * @param host the host name to listen on
1211  * @param port the port to listen on, if zero a free port will be used
1212  * @param family the address family to listen on, NULL for all
1213  * @param retport string to return the actual port listened on
1214  * @param fds_p location to store returned file descriptors
1215  * @param error return location for errors
1216  * @returns the number of listening file descriptors or -1 on error
1217  */
1218 int
1219 _dbus_listen_tcp_socket (const char     *host,
1220                          const char     *port,
1221                          const char     *family,
1222                          DBusString     *retport,
1223                          int           **fds_p,
1224                          DBusError      *error)
1225 {
1226   int saved_errno;
1227   int nlisten_fd = 0, *listen_fd = NULL, res, i;
1228   struct addrinfo hints;
1229   struct addrinfo *ai, *tmp;
1230
1231   *fds_p = NULL;
1232   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1233
1234   _DBUS_ZERO (hints);
1235
1236   if (!family)
1237     hints.ai_family = AF_UNSPEC;
1238   else if (!strcmp(family, "ipv4"))
1239     hints.ai_family = AF_INET;
1240   else if (!strcmp(family, "ipv6"))
1241     hints.ai_family = AF_INET6;
1242   else
1243     {
1244       dbus_set_error (error,
1245                       DBUS_ERROR_BAD_ADDRESS,
1246                       "Unknown address family %s", family);
1247       return -1;
1248     }
1249
1250   hints.ai_protocol = IPPROTO_TCP;
1251   hints.ai_socktype = SOCK_STREAM;
1252   hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1253
1254  redo_lookup_with_port:
1255   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1256     {
1257       dbus_set_error (error,
1258                       _dbus_error_from_errno (errno),
1259                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1260                       host ? host : "*", port, gai_strerror(res), res);
1261       return -1;
1262     }
1263
1264   tmp = ai;
1265   while (tmp)
1266     {
1267       int fd = -1, *newlisten_fd;
1268       if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1269         {
1270           _DBUS_ASSERT_ERROR_IS_SET(error);
1271           goto failed;
1272         }
1273       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1274
1275       if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1276         {
1277           saved_errno = errno;
1278           _dbus_close(fd, NULL);
1279           if (saved_errno == EADDRINUSE)
1280             {
1281               /* Depending on kernel policy, it may or may not
1282                  be neccessary to bind to both IPv4 & 6 addresses
1283                  so ignore EADDRINUSE here */
1284               tmp = tmp->ai_next;
1285               continue;
1286             }
1287           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1288                           "Failed to bind socket \"%s:%s\": %s",
1289                           host ? host : "*", port, _dbus_strerror (saved_errno));
1290           goto failed;
1291         }
1292
1293       if (listen (fd, 30 /* backlog */) < 0)
1294         {
1295           saved_errno = errno;
1296           _dbus_close (fd, NULL);
1297           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1298                           "Failed to listen on socket \"%s:%s\": %s",
1299                           host ? host : "*", port, _dbus_strerror (saved_errno));
1300           goto failed;
1301         }
1302
1303       newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
1304       if (!newlisten_fd)
1305         {
1306           saved_errno = errno;
1307           _dbus_close (fd, NULL);
1308           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1309                           "Failed to allocate file handle array: %s",
1310                           _dbus_strerror (saved_errno));
1311           goto failed;
1312         }
1313       listen_fd = newlisten_fd;
1314       listen_fd[nlisten_fd] = fd;
1315       nlisten_fd++;
1316
1317       if (!_dbus_string_get_length(retport))
1318         {
1319           /* If the user didn't specify a port, or used 0, then
1320              the kernel chooses a port. After the first address
1321              is bound to, we need to force all remaining addresses
1322              to use the same port */
1323           if (!port || !strcmp(port, "0"))
1324             {
1325               struct sockaddr_storage addr;
1326               socklen_t addrlen;
1327               char portbuf[50];
1328
1329               addrlen = sizeof(addr);
1330               getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1331
1332               if ((res = getnameinfo((struct sockaddr*)&addr, addrlen, NULL, 0,
1333                                      portbuf, sizeof(portbuf),
1334                                      NI_NUMERICHOST)) != 0)
1335                 {
1336                   dbus_set_error (error, _dbus_error_from_errno (errno),
1337                                   "Failed to resolve port \"%s:%s\": %s (%s)",
1338                                   host ? host : "*", port, gai_strerror(res), res);
1339                   goto failed;
1340                 }
1341               if (!_dbus_string_append(retport, portbuf))
1342                 {
1343                   dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1344                   goto failed;
1345                 }
1346
1347               /* Release current address list & redo lookup */
1348               port = _dbus_string_get_const_data(retport);
1349               freeaddrinfo(ai);
1350               goto redo_lookup_with_port;
1351             }
1352           else
1353             {
1354               if (!_dbus_string_append(retport, port))
1355                 {
1356                     dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1357                     goto failed;
1358                 }
1359             }
1360         }
1361
1362       tmp = tmp->ai_next;
1363     }
1364   freeaddrinfo(ai);
1365   ai = NULL;
1366
1367   if (!nlisten_fd)
1368     {
1369       errno = EADDRINUSE;
1370       dbus_set_error (error, _dbus_error_from_errno (errno),
1371                       "Failed to bind socket \"%s:%s\": %s",
1372                       host ? host : "*", port, _dbus_strerror (errno));
1373       return -1;
1374     }
1375
1376   for (i = 0 ; i < nlisten_fd ; i++)
1377     {
1378       if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1379         {
1380           goto failed;
1381         }
1382     }
1383
1384   *fds_p = listen_fd;
1385
1386   return nlisten_fd;
1387
1388  failed:
1389   if (ai)
1390     freeaddrinfo(ai);
1391   for (i = 0 ; i < nlisten_fd ; i++)
1392     _dbus_close(listen_fd[i], NULL);
1393   dbus_free(listen_fd);
1394   return -1;
1395 }
1396
1397 static dbus_bool_t
1398 write_credentials_byte (int             server_fd,
1399                         DBusError      *error)
1400 {
1401   int bytes_written;
1402   char buf[1] = { '\0' };
1403 #if defined(HAVE_CMSGCRED) 
1404   union {
1405           struct cmsghdr hdr;
1406           char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1407   } cmsg;
1408   struct iovec iov;
1409   struct msghdr msg;
1410   iov.iov_base = buf;
1411   iov.iov_len = 1;
1412
1413   _DBUS_ZERO(msg);
1414   msg.msg_iov = &iov;
1415   msg.msg_iovlen = 1;
1416
1417   msg.msg_control = (caddr_t) &cmsg;
1418   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1419   _DBUS_ZERO(cmsg);
1420   cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1421   cmsg.hdr.cmsg_level = SOL_SOCKET;
1422   cmsg.hdr.cmsg_type = SCM_CREDS;
1423 #endif
1424
1425   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1426   
1427  again:
1428
1429 #if defined(HAVE_CMSGCRED) 
1430   bytes_written = sendmsg (server_fd, &msg, 0);
1431 #else
1432   bytes_written = write (server_fd, buf, 1);
1433 #endif
1434
1435   if (bytes_written < 0 && errno == EINTR)
1436     goto again;
1437
1438   if (bytes_written < 0)
1439     {
1440       dbus_set_error (error, _dbus_error_from_errno (errno),
1441                       "Failed to write credentials byte: %s",
1442                      _dbus_strerror (errno));
1443       return FALSE;
1444     }
1445   else if (bytes_written == 0)
1446     {
1447       dbus_set_error (error, DBUS_ERROR_IO_ERROR,
1448                       "wrote zero bytes writing credentials byte");
1449       return FALSE;
1450     }
1451   else
1452     {
1453       _dbus_assert (bytes_written == 1);
1454       _dbus_verbose ("wrote credentials byte\n");
1455       return TRUE;
1456     }
1457 }
1458
1459 /**
1460  * Reads a single byte which must be nul (an error occurs otherwise),
1461  * and reads unix credentials if available. Clears the credentials
1462  * object, then adds pid/uid if available, so any previous credentials
1463  * stored in the object are lost.
1464  *
1465  * Return value indicates whether a byte was read, not whether
1466  * we got valid credentials. On some systems, such as Linux,
1467  * reading/writing the byte isn't actually required, but we do it
1468  * anyway just to avoid multiple codepaths.
1469  * 
1470  * Fails if no byte is available, so you must select() first.
1471  *
1472  * The point of the byte is that on some systems we have to
1473  * use sendmsg()/recvmsg() to transmit credentials.
1474  *
1475  * @param client_fd the client file descriptor
1476  * @param credentials object to add client credentials to
1477  * @param error location to store error code
1478  * @returns #TRUE on success
1479  */
1480 dbus_bool_t
1481 _dbus_read_credentials_socket  (int              client_fd,
1482                                 DBusCredentials *credentials,
1483                                 DBusError       *error)
1484 {
1485   struct msghdr msg;
1486   struct iovec iov;
1487   char buf;
1488   dbus_uid_t uid_read;
1489   dbus_pid_t pid_read;
1490   int bytes_read;
1491   
1492 #ifdef HAVE_CMSGCRED 
1493   union {
1494     struct cmsghdr hdr;
1495     char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1496   } cmsg;
1497
1498 #elif defined(LOCAL_CREDS)
1499   struct {
1500     struct cmsghdr hdr;
1501     struct sockcred cred;
1502   } cmsg;
1503 #endif
1504
1505   uid_read = DBUS_UID_UNSET;
1506   pid_read = DBUS_PID_UNSET;
1507
1508   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1509   
1510   /* The POSIX spec certainly doesn't promise this, but
1511    * we need these assertions to fail as soon as we're wrong about
1512    * it so we can do the porting fixups
1513    */
1514   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1515   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1516   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1517
1518   _dbus_credentials_clear (credentials);
1519
1520   /* Systems supporting LOCAL_CREDS are configured to have this feature
1521    * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
1522    * the connection.  Therefore, the received message must carry the
1523    * credentials information without doing anything special.
1524    */
1525
1526   iov.iov_base = &buf;
1527   iov.iov_len = 1;
1528
1529   _DBUS_ZERO(msg);
1530   msg.msg_iov = &iov;
1531   msg.msg_iovlen = 1;
1532
1533 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1534   _DBUS_ZERO(cmsg);
1535   msg.msg_control = (caddr_t) &cmsg;
1536   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1537 #endif
1538
1539  again:
1540   bytes_read = recvmsg (client_fd, &msg, 0);
1541
1542   if (bytes_read < 0)
1543     {
1544       if (errno == EINTR)
1545         goto again;
1546
1547       /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1548        * normally only call read_credentials if the socket was ready
1549        * for reading
1550        */
1551       
1552       dbus_set_error (error, _dbus_error_from_errno (errno),
1553                       "Failed to read credentials byte: %s",
1554                       _dbus_strerror (errno));
1555       return FALSE;
1556     }
1557   else if (bytes_read == 0)
1558     {
1559       /* this should not happen unless we are using recvmsg wrong,
1560        * so is essentially here for paranoia
1561        */
1562       dbus_set_error (error, DBUS_ERROR_FAILED,
1563                       "Failed to read credentials byte (zero-length read)");
1564       return FALSE;
1565     }
1566   else if (buf != '\0')
1567     {
1568       dbus_set_error (error, DBUS_ERROR_FAILED,
1569                       "Credentials byte was not nul");
1570       return FALSE;
1571     }
1572
1573 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1574   if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
1575                   || cmsg.hdr.cmsg_type != SCM_CREDS)
1576     {
1577       dbus_set_error (error, DBUS_ERROR_FAILED,
1578                       "Message from recvmsg() was not SCM_CREDS");
1579       return FALSE;
1580     }
1581 #endif
1582
1583   _dbus_verbose ("read credentials byte\n");
1584
1585   {
1586 #ifdef SO_PEERCRED
1587     struct ucred cr;   
1588     int cr_len = sizeof (cr);
1589     
1590     if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1591         cr_len == sizeof (cr))
1592       {
1593         pid_read = cr.pid;
1594         uid_read = cr.uid;
1595       }
1596     else
1597       {
1598         _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1599                        cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1600       }
1601 #elif defined(HAVE_CMSGCRED)
1602     struct cmsgcred *cred;
1603
1604     cred = (struct cmsgcred *) CMSG_DATA (&cmsg);
1605     pid_read = cred->cmcred_pid;
1606     uid_read = cred->cmcred_euid;
1607 #elif defined(LOCAL_CREDS)
1608     pid_read = DBUS_PID_UNSET;
1609     uid_read = cmsg.cred.sc_uid;
1610     /* Since we have already got the credentials from this socket, we can
1611      * disable its LOCAL_CREDS flag if it was ever set. */
1612     _dbus_set_local_creds (client_fd, FALSE);
1613 #elif defined(HAVE_GETPEEREID)
1614     uid_t euid;
1615     gid_t egid;
1616     if (getpeereid (client_fd, &euid, &egid) == 0)
1617       {
1618         uid_read = euid;
1619       }
1620     else
1621       {
1622         _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1623       }
1624 #elif defined(HAVE_GETPEERUCRED)
1625     ucred_t * ucred = NULL;
1626     if (getpeerucred (client_fd, &ucred) == 0)
1627       {
1628         pid_read = ucred_getpid (ucred);
1629         uid_read = ucred_geteuid (ucred);
1630 #ifdef HAVE_ADT
1631         /* generate audit session data based on socket ucred */
1632         adt_session_data_t *adth = NULL;
1633         adt_export_data_t *data = NULL;
1634         size_t size = 0;
1635         if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1636           {
1637             _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1638           }
1639         else 
1640           {
1641             if (adt_set_from_ucred (adth, ucred, ADT_NEW)) 
1642               {
1643                 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1644               }
1645             else
1646               {
1647                 size = adt_export_session_data (adth, &data);
1648                 if (size <= 0)
1649                   {
1650                     _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
1651                   }
1652                 else
1653                   {
1654                     _dbus_credentials_add_adt_audit_data (credentials, data, size);
1655                     free (data);
1656                   }
1657               }
1658             (void) adt_end_session (adth);
1659           }
1660 #endif /* HAVE_ADT */
1661       }
1662     else
1663       {
1664         _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1665       }
1666     if (ucred != NULL)
1667       ucred_free (ucred);
1668 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
1669     _dbus_verbose ("Socket credentials not supported on this OS\n");
1670 #endif
1671   }
1672
1673   _dbus_verbose ("Credentials:"
1674                  "  pid "DBUS_PID_FORMAT
1675                  "  uid "DBUS_UID_FORMAT
1676                  "\n",
1677                  pid_read,
1678                  uid_read);
1679
1680   if (pid_read != DBUS_PID_UNSET)
1681     {
1682       if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
1683         {
1684           _DBUS_SET_OOM (error);
1685           return FALSE;
1686         }
1687     }
1688
1689   if (uid_read != DBUS_UID_UNSET)
1690     {
1691       if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
1692         {
1693           _DBUS_SET_OOM (error);
1694           return FALSE;
1695         }
1696     }
1697   
1698   return TRUE;
1699 }
1700
1701 /**
1702  * Sends a single nul byte with our UNIX credentials as ancillary
1703  * data.  Returns #TRUE if the data was successfully written.  On
1704  * systems that don't support sending credentials, just writes a byte,
1705  * doesn't send any credentials.  On some systems, such as Linux,
1706  * reading/writing the byte isn't actually required, but we do it
1707  * anyway just to avoid multiple codepaths.
1708  *
1709  * Fails if no byte can be written, so you must select() first.
1710  *
1711  * The point of the byte is that on some systems we have to
1712  * use sendmsg()/recvmsg() to transmit credentials.
1713  *
1714  * @param server_fd file descriptor for connection to server
1715  * @param error return location for error code
1716  * @returns #TRUE if the byte was sent
1717  */
1718 dbus_bool_t
1719 _dbus_send_credentials_socket  (int              server_fd,
1720                                 DBusError       *error)
1721 {
1722   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1723   
1724   if (write_credentials_byte (server_fd, error))
1725     return TRUE;
1726   else
1727     return FALSE;
1728 }
1729
1730 /**
1731  * Accepts a connection on a listening socket.
1732  * Handles EINTR for you.
1733  *
1734  * This will enable FD_CLOEXEC for the returned socket.
1735  *
1736  * @param listen_fd the listen file descriptor
1737  * @returns the connection fd of the client, or -1 on error
1738  */
1739 int
1740 _dbus_accept  (int listen_fd)
1741 {
1742   int client_fd;
1743   struct sockaddr addr;
1744   socklen_t addrlen;
1745 #ifdef HAVE_ACCEPT4
1746   dbus_bool_t cloexec_done;
1747 #endif
1748
1749   addrlen = sizeof (addr);
1750
1751  retry:
1752
1753 #ifdef HAVE_ACCEPT4
1754   /* We assume that if accept4 is available SOCK_CLOEXEC is too */
1755   client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
1756   cloexec_done = client_fd >= 0;
1757
1758   if (client_fd < 0 && errno == ENOSYS)
1759 #endif
1760     {
1761       client_fd = accept (listen_fd, &addr, &addrlen);
1762     }
1763
1764   if (client_fd < 0)
1765     {
1766       if (errno == EINTR)
1767         goto retry;
1768     }
1769
1770   _dbus_verbose ("client fd %d accepted\n", client_fd);
1771
1772 #ifdef HAVE_ACCEPT4
1773   if (!cloexec_done)
1774 #endif
1775     {
1776       _dbus_fd_set_close_on_exec(client_fd);
1777     }
1778
1779   return client_fd;
1780 }
1781
1782 /**
1783  * Checks to make sure the given directory is 
1784  * private to the user 
1785  *
1786  * @param dir the name of the directory
1787  * @param error error return
1788  * @returns #FALSE on failure
1789  **/
1790 dbus_bool_t
1791 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
1792 {
1793   const char *directory;
1794   struct stat sb;
1795         
1796   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1797     
1798   directory = _dbus_string_get_const_data (dir);
1799         
1800   if (stat (directory, &sb) < 0)
1801     {
1802       dbus_set_error (error, _dbus_error_from_errno (errno),
1803                       "%s", _dbus_strerror (errno));
1804    
1805       return FALSE;
1806     }
1807     
1808   if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
1809       (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
1810     {
1811       dbus_set_error (error, DBUS_ERROR_FAILED,
1812                      "%s directory is not private to the user", directory);
1813       return FALSE;
1814     }
1815     
1816   return TRUE;
1817 }
1818
1819 static dbus_bool_t
1820 fill_user_info_from_passwd (struct passwd *p,
1821                             DBusUserInfo  *info,
1822                             DBusError     *error)
1823 {
1824   _dbus_assert (p->pw_name != NULL);
1825   _dbus_assert (p->pw_dir != NULL);
1826   
1827   info->uid = p->pw_uid;
1828   info->primary_gid = p->pw_gid;
1829   info->username = _dbus_strdup (p->pw_name);
1830   info->homedir = _dbus_strdup (p->pw_dir);
1831   
1832   if (info->username == NULL ||
1833       info->homedir == NULL)
1834     {
1835       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1836       return FALSE;
1837     }
1838
1839   return TRUE;
1840 }
1841
1842 static dbus_bool_t
1843 fill_user_info (DBusUserInfo       *info,
1844                 dbus_uid_t          uid,
1845                 const DBusString   *username,
1846                 DBusError          *error)
1847 {
1848   const char *username_c;
1849   
1850   /* exactly one of username/uid provided */
1851   _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
1852   _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
1853
1854   info->uid = DBUS_UID_UNSET;
1855   info->primary_gid = DBUS_GID_UNSET;
1856   info->group_ids = NULL;
1857   info->n_group_ids = 0;
1858   info->username = NULL;
1859   info->homedir = NULL;
1860   
1861   if (username != NULL)
1862     username_c = _dbus_string_get_const_data (username);
1863   else
1864     username_c = NULL;
1865
1866   /* For now assuming that the getpwnam() and getpwuid() flavors
1867    * are always symmetrical, if not we have to add more configure
1868    * checks
1869    */
1870   
1871 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
1872   {
1873     struct passwd *p;
1874     int result;
1875     size_t buflen;
1876     char *buf;
1877     struct passwd p_str;
1878
1879     /* retrieve maximum needed size for buf */
1880     buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
1881
1882     /* sysconf actually returns a long, but everything else expects size_t,
1883      * so just recast here.
1884      * https://bugs.freedesktop.org/show_bug.cgi?id=17061
1885      */
1886     if ((long) buflen <= 0)
1887       buflen = 1024;
1888
1889     result = -1;
1890     while (1)
1891       {
1892         buf = dbus_malloc (buflen);
1893         if (buf == NULL)
1894           {
1895             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1896             return FALSE;
1897           }
1898
1899         p = NULL;
1900 #ifdef HAVE_POSIX_GETPWNAM_R
1901         if (uid != DBUS_UID_UNSET)
1902           result = getpwuid_r (uid, &p_str, buf, buflen,
1903                                &p);
1904         else
1905           result = getpwnam_r (username_c, &p_str, buf, buflen,
1906                                &p);
1907 #else
1908         if (uid != DBUS_UID_UNSET)
1909           p = getpwuid_r (uid, &p_str, buf, buflen);
1910         else
1911           p = getpwnam_r (username_c, &p_str, buf, buflen);
1912         result = 0;
1913 #endif /* !HAVE_POSIX_GETPWNAM_R */
1914         //Try a bigger buffer if ERANGE was returned
1915         if (result == ERANGE && buflen < 512 * 1024)
1916           {
1917             dbus_free (buf);
1918             buflen *= 2;
1919           }
1920         else
1921           {
1922             break;
1923           }
1924       }
1925     if (result == 0 && p == &p_str)
1926       {
1927         if (!fill_user_info_from_passwd (p, info, error))
1928           {
1929             dbus_free (buf);
1930             return FALSE;
1931           }
1932         dbus_free (buf);
1933       }
1934     else
1935       {
1936         dbus_set_error (error, _dbus_error_from_errno (errno),
1937                         "User \"%s\" unknown or no memory to allocate password entry\n",
1938                         username_c ? username_c : "???");
1939         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
1940         dbus_free (buf);
1941         return FALSE;
1942       }
1943   }
1944 #else /* ! HAVE_GETPWNAM_R */
1945   {
1946     /* I guess we're screwed on thread safety here */
1947     struct passwd *p;
1948
1949     if (uid != DBUS_UID_UNSET)
1950       p = getpwuid (uid);
1951     else
1952       p = getpwnam (username_c);
1953
1954     if (p != NULL)
1955       {
1956         if (!fill_user_info_from_passwd (p, info, error))
1957           {
1958             return FALSE;
1959           }
1960       }
1961     else
1962       {
1963         dbus_set_error (error, _dbus_error_from_errno (errno),
1964                         "User \"%s\" unknown or no memory to allocate password entry\n",
1965                         username_c ? username_c : "???");
1966         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
1967         return FALSE;
1968       }
1969   }
1970 #endif  /* ! HAVE_GETPWNAM_R */
1971
1972   /* Fill this in so we can use it to get groups */
1973   username_c = info->username;
1974   
1975 #ifdef HAVE_GETGROUPLIST
1976   {
1977     gid_t *buf;
1978     int buf_count;
1979     int i;
1980     int initial_buf_count;
1981
1982     initial_buf_count = 17;
1983     buf_count = initial_buf_count;
1984     buf = dbus_new (gid_t, buf_count);
1985     if (buf == NULL)
1986       {
1987         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1988         goto failed;
1989       }
1990     
1991     if (getgrouplist (username_c,
1992                       info->primary_gid,
1993                       buf, &buf_count) < 0)
1994       {
1995         gid_t *new;
1996         /* Presumed cause of negative return code: buf has insufficient
1997            entries to hold the entire group list. The Linux behavior in this
1998            case is to pass back the actual number of groups in buf_count, but
1999            on Mac OS X 10.5, buf_count is unhelpfully left alone.
2000            So as a hack, try to help out a bit by guessing a larger
2001            number of groups, within reason.. might still fail, of course,
2002            but we can at least print a more informative message.  I looked up
2003            the "right way" to do this by downloading Apple's own source code
2004            for the "id" command, and it turns out that they use an
2005            undocumented library function getgrouplist_2 (!) which is not
2006            declared in any header in /usr/include (!!). That did not seem
2007            like the way to go here.  
2008         */
2009         if (buf_count == initial_buf_count) 
2010           { 
2011             buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2012           }
2013         new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2014         if (new == NULL)
2015           {
2016             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2017             dbus_free (buf);
2018             goto failed;
2019           }
2020         
2021         buf = new;
2022
2023         errno = 0;
2024         if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2025           {
2026             if (errno == 0)
2027               {
2028                 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2029                             username_c, buf_count, buf_count);
2030               } 
2031             else
2032               {
2033                 dbus_set_error (error,
2034                                 _dbus_error_from_errno (errno),
2035                                 "Failed to get groups for username \"%s\" primary GID "
2036                                 DBUS_GID_FORMAT ": %s\n",
2037                                 username_c, info->primary_gid,
2038                                 _dbus_strerror (errno));
2039                 dbus_free (buf);
2040                 goto failed;
2041               }
2042           }
2043       }
2044
2045     info->group_ids = dbus_new (dbus_gid_t, buf_count);
2046     if (info->group_ids == NULL)
2047       {
2048         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2049         dbus_free (buf);
2050         goto failed;
2051       }
2052     
2053     for (i = 0; i < buf_count; ++i)
2054       info->group_ids[i] = buf[i];
2055
2056     info->n_group_ids = buf_count;
2057     
2058     dbus_free (buf);
2059   }
2060 #else  /* HAVE_GETGROUPLIST */
2061   {
2062     /* We just get the one group ID */
2063     info->group_ids = dbus_new (dbus_gid_t, 1);
2064     if (info->group_ids == NULL)
2065       {
2066         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2067         goto failed;
2068       }
2069
2070     info->n_group_ids = 1;
2071
2072     (info->group_ids)[0] = info->primary_gid;
2073   }
2074 #endif /* HAVE_GETGROUPLIST */
2075
2076   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2077   
2078   return TRUE;
2079   
2080  failed:
2081   _DBUS_ASSERT_ERROR_IS_SET (error);
2082   return FALSE;
2083 }
2084
2085 /**
2086  * Gets user info for the given username.
2087  *
2088  * @param info user info object to initialize
2089  * @param username the username
2090  * @param error error return
2091  * @returns #TRUE on success
2092  */
2093 dbus_bool_t
2094 _dbus_user_info_fill (DBusUserInfo     *info,
2095                       const DBusString *username,
2096                       DBusError        *error)
2097 {
2098   return fill_user_info (info, DBUS_UID_UNSET,
2099                          username, error);
2100 }
2101
2102 /**
2103  * Gets user info for the given user ID.
2104  *
2105  * @param info user info object to initialize
2106  * @param uid the user ID
2107  * @param error error return
2108  * @returns #TRUE on success
2109  */
2110 dbus_bool_t
2111 _dbus_user_info_fill_uid (DBusUserInfo *info,
2112                           dbus_uid_t    uid,
2113                           DBusError    *error)
2114 {
2115   return fill_user_info (info, uid,
2116                          NULL, error);
2117 }
2118
2119 /**
2120  * Adds the credentials of the current process to the
2121  * passed-in credentials object.
2122  *
2123  * @param credentials credentials to add to
2124  * @returns #FALSE if no memory; does not properly roll back on failure, so only some credentials may have been added
2125  */
2126 dbus_bool_t
2127 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
2128 {
2129   /* The POSIX spec certainly doesn't promise this, but
2130    * we need these assertions to fail as soon as we're wrong about
2131    * it so we can do the porting fixups
2132    */
2133   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
2134   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
2135   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
2136
2137   if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
2138     return FALSE;
2139   if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2140     return FALSE;
2141
2142   return TRUE;
2143 }
2144
2145 /**
2146  * Append to the string the identity we would like to have when we
2147  * authenticate, on UNIX this is the current process UID and on
2148  * Windows something else, probably a Windows SID string.  No escaping
2149  * is required, that is done in dbus-auth.c. The username here
2150  * need not be anything human-readable, it can be the machine-readable
2151  * form i.e. a user id.
2152  * 
2153  * @param str the string to append to
2154  * @returns #FALSE on no memory
2155  */
2156 dbus_bool_t
2157 _dbus_append_user_from_current_process (DBusString *str)
2158 {
2159   return _dbus_string_append_uint (str,
2160                                    _dbus_geteuid ());
2161 }
2162
2163 /**
2164  * Gets our process ID
2165  * @returns process ID
2166  */
2167 dbus_pid_t
2168 _dbus_getpid (void)
2169 {
2170   return getpid ();
2171 }
2172
2173 /** Gets our UID
2174  * @returns process UID
2175  */
2176 dbus_uid_t
2177 _dbus_getuid (void)
2178 {
2179   return getuid ();
2180 }
2181
2182 /** Gets our effective UID
2183  * @returns process effective UID
2184  */
2185 dbus_uid_t
2186 _dbus_geteuid (void)
2187 {
2188   return geteuid ();
2189 }
2190
2191 /**
2192  * The only reason this is separate from _dbus_getpid() is to allow it
2193  * on Windows for logging but not for other purposes.
2194  * 
2195  * @returns process ID to put in log messages
2196  */
2197 unsigned long
2198 _dbus_pid_for_log (void)
2199 {
2200   return getpid ();
2201 }
2202
2203 /**
2204  * Gets a UID from a UID string.
2205  *
2206  * @param uid_str the UID in string form
2207  * @param uid UID to fill in
2208  * @returns #TRUE if successfully filled in UID
2209  */
2210 dbus_bool_t
2211 _dbus_parse_uid (const DBusString      *uid_str,
2212                  dbus_uid_t            *uid)
2213 {
2214   int end;
2215   long val;
2216   
2217   if (_dbus_string_get_length (uid_str) == 0)
2218     {
2219       _dbus_verbose ("UID string was zero length\n");
2220       return FALSE;
2221     }
2222
2223   val = -1;
2224   end = 0;
2225   if (!_dbus_string_parse_int (uid_str, 0, &val,
2226                                &end))
2227     {
2228       _dbus_verbose ("could not parse string as a UID\n");
2229       return FALSE;
2230     }
2231   
2232   if (end != _dbus_string_get_length (uid_str))
2233     {
2234       _dbus_verbose ("string contained trailing stuff after UID\n");
2235       return FALSE;
2236     }
2237
2238   *uid = val;
2239
2240   return TRUE;
2241 }
2242
2243 #if !DBUS_USE_SYNC
2244 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
2245 #endif
2246
2247 /**
2248  * Atomically increments an integer
2249  *
2250  * @param atomic pointer to the integer to increment
2251  * @returns the value before incrementing
2252  */
2253 dbus_int32_t
2254 _dbus_atomic_inc (DBusAtomic *atomic)
2255 {
2256 #if DBUS_USE_SYNC
2257   return __sync_add_and_fetch(&atomic->value, 1)-1;
2258 #else
2259   dbus_int32_t res;
2260   _DBUS_LOCK (atomic);
2261   res = atomic->value;
2262   atomic->value += 1;
2263   _DBUS_UNLOCK (atomic);
2264   return res;
2265 #endif
2266 }
2267
2268 /**
2269  * Atomically decrement an integer
2270  *
2271  * @param atomic pointer to the integer to decrement
2272  * @returns the value before decrementing
2273  */
2274 dbus_int32_t
2275 _dbus_atomic_dec (DBusAtomic *atomic)
2276 {
2277 #if DBUS_USE_SYNC
2278   return __sync_sub_and_fetch(&atomic->value, 1)+1;
2279 #else
2280   dbus_int32_t res;
2281   
2282   _DBUS_LOCK (atomic);
2283   res = atomic->value;
2284   atomic->value -= 1;
2285   _DBUS_UNLOCK (atomic);
2286   return res;
2287 #endif
2288 }
2289
2290 #ifdef DBUS_BUILD_TESTS
2291 /** Gets our GID
2292  * @returns process GID
2293  */
2294 dbus_gid_t
2295 _dbus_getgid (void)
2296 {
2297   return getgid ();
2298 }
2299 #endif
2300
2301 /**
2302  * Wrapper for poll().
2303  *
2304  * @param fds the file descriptors to poll
2305  * @param n_fds number of descriptors in the array
2306  * @param timeout_milliseconds timeout or -1 for infinite
2307  * @returns numbers of fds with revents, or <0 on error
2308  */
2309 int
2310 _dbus_poll (DBusPollFD *fds,
2311             int         n_fds,
2312             int         timeout_milliseconds)
2313 {
2314 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2315   /* This big thing is a constant expression and should get optimized
2316    * out of existence. So it's more robust than a configure check at
2317    * no cost.
2318    */
2319   if (_DBUS_POLLIN == POLLIN &&
2320       _DBUS_POLLPRI == POLLPRI &&
2321       _DBUS_POLLOUT == POLLOUT &&
2322       _DBUS_POLLERR == POLLERR &&
2323       _DBUS_POLLHUP == POLLHUP &&
2324       _DBUS_POLLNVAL == POLLNVAL &&
2325       sizeof (DBusPollFD) == sizeof (struct pollfd) &&
2326       _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
2327       _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
2328       _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
2329       _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
2330       _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
2331       _DBUS_STRUCT_OFFSET (struct pollfd, revents))
2332     {
2333       return poll ((struct pollfd*) fds,
2334                    n_fds, 
2335                    timeout_milliseconds);
2336     }
2337   else
2338     {
2339       /* We have to convert the DBusPollFD to an array of
2340        * struct pollfd, poll, and convert back.
2341        */
2342       _dbus_warn ("didn't implement poll() properly for this system yet\n");
2343       return -1;
2344     }
2345 #else /* ! HAVE_POLL */
2346
2347   fd_set read_set, write_set, err_set;
2348   int max_fd = 0;
2349   int i;
2350   struct timeval tv;
2351   int ready;
2352   
2353   FD_ZERO (&read_set);
2354   FD_ZERO (&write_set);
2355   FD_ZERO (&err_set);
2356
2357   for (i = 0; i < n_fds; i++)
2358     {
2359       DBusPollFD *fdp = &fds[i];
2360
2361       if (fdp->events & _DBUS_POLLIN)
2362         FD_SET (fdp->fd, &read_set);
2363
2364       if (fdp->events & _DBUS_POLLOUT)
2365         FD_SET (fdp->fd, &write_set);
2366
2367       FD_SET (fdp->fd, &err_set);
2368
2369       max_fd = MAX (max_fd, fdp->fd);
2370     }
2371     
2372   tv.tv_sec = timeout_milliseconds / 1000;
2373   tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2374
2375   ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2376                   timeout_milliseconds < 0 ? NULL : &tv);
2377
2378   if (ready > 0)
2379     {
2380       for (i = 0; i < n_fds; i++)
2381         {
2382           DBusPollFD *fdp = &fds[i];
2383
2384           fdp->revents = 0;
2385
2386           if (FD_ISSET (fdp->fd, &read_set))
2387             fdp->revents |= _DBUS_POLLIN;
2388
2389           if (FD_ISSET (fdp->fd, &write_set))
2390             fdp->revents |= _DBUS_POLLOUT;
2391
2392           if (FD_ISSET (fdp->fd, &err_set))
2393             fdp->revents |= _DBUS_POLLERR;
2394         }
2395     }
2396
2397   return ready;
2398 #endif
2399 }
2400
2401 /**
2402  * Get current time, as in gettimeofday().
2403  *
2404  * @param tv_sec return location for number of seconds
2405  * @param tv_usec return location for number of microseconds (thousandths)
2406  */
2407 void
2408 _dbus_get_current_time (long *tv_sec,
2409                         long *tv_usec)
2410 {
2411   struct timeval t;
2412
2413   gettimeofday (&t, NULL);
2414
2415   if (tv_sec)
2416     *tv_sec = t.tv_sec;
2417   if (tv_usec)
2418     *tv_usec = t.tv_usec;
2419 }
2420
2421 /**
2422  * Appends the contents of the given file to the string,
2423  * returning error code. At the moment, won't open a file
2424  * more than a megabyte in size.
2425  *
2426  * @param str the string to append to
2427  * @param filename filename to load
2428  * @param error place to set an error
2429  * @returns #FALSE if error was set
2430  */
2431 dbus_bool_t
2432 _dbus_file_get_contents (DBusString       *str,
2433                          const DBusString *filename,
2434                          DBusError        *error)
2435 {
2436   int fd;
2437   struct stat sb;
2438   int orig_len;
2439   int total;
2440   const char *filename_c;
2441
2442   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2443   
2444   filename_c = _dbus_string_get_const_data (filename);
2445   
2446   /* O_BINARY useful on Cygwin */
2447   fd = open (filename_c, O_RDONLY | O_BINARY);
2448   if (fd < 0)
2449     {
2450       dbus_set_error (error, _dbus_error_from_errno (errno),
2451                       "Failed to open \"%s\": %s",
2452                       filename_c,
2453                       _dbus_strerror (errno));
2454       return FALSE;
2455     }
2456
2457   _dbus_verbose ("file fd %d opened\n", fd);
2458   
2459   if (fstat (fd, &sb) < 0)
2460     {
2461       dbus_set_error (error, _dbus_error_from_errno (errno),
2462                       "Failed to stat \"%s\": %s",
2463                       filename_c,
2464                       _dbus_strerror (errno));
2465
2466       _dbus_verbose ("fstat() failed: %s",
2467                      _dbus_strerror (errno));
2468       
2469       _dbus_close (fd, NULL);
2470       
2471       return FALSE;
2472     }
2473
2474   if (sb.st_size > _DBUS_ONE_MEGABYTE)
2475     {
2476       dbus_set_error (error, DBUS_ERROR_FAILED,
2477                       "File size %lu of \"%s\" is too large.",
2478                       (unsigned long) sb.st_size, filename_c);
2479       _dbus_close (fd, NULL);
2480       return FALSE;
2481     }
2482   
2483   total = 0;
2484   orig_len = _dbus_string_get_length (str);
2485   if (sb.st_size > 0 && S_ISREG (sb.st_mode))
2486     {
2487       int bytes_read;
2488
2489       while (total < (int) sb.st_size)
2490         {
2491           bytes_read = _dbus_read (fd, str,
2492                                    sb.st_size - total);
2493           if (bytes_read <= 0)
2494             {
2495               dbus_set_error (error, _dbus_error_from_errno (errno),
2496                               "Error reading \"%s\": %s",
2497                               filename_c,
2498                               _dbus_strerror (errno));
2499
2500               _dbus_verbose ("read() failed: %s",
2501                              _dbus_strerror (errno));
2502               
2503               _dbus_close (fd, NULL);
2504               _dbus_string_set_length (str, orig_len);
2505               return FALSE;
2506             }
2507           else
2508             total += bytes_read;
2509         }
2510
2511       _dbus_close (fd, NULL);
2512       return TRUE;
2513     }
2514   else if (sb.st_size != 0)
2515     {
2516       _dbus_verbose ("Can only open regular files at the moment.\n");
2517       dbus_set_error (error, DBUS_ERROR_FAILED,
2518                       "\"%s\" is not a regular file",
2519                       filename_c);
2520       _dbus_close (fd, NULL);
2521       return FALSE;
2522     }
2523   else
2524     {
2525       _dbus_close (fd, NULL);
2526       return TRUE;
2527     }
2528 }
2529
2530 /**
2531  * Writes a string out to a file. If the file exists,
2532  * it will be atomically overwritten by the new data.
2533  *
2534  * @param str the string to write out
2535  * @param filename the file to save string to
2536  * @param error error to be filled in on failure
2537  * @returns #FALSE on failure
2538  */
2539 dbus_bool_t
2540 _dbus_string_save_to_file (const DBusString *str,
2541                            const DBusString *filename,
2542                            DBusError        *error)
2543 {
2544   int fd;
2545   int bytes_to_write;
2546   const char *filename_c;
2547   DBusString tmp_filename;
2548   const char *tmp_filename_c;
2549   int total;
2550   dbus_bool_t need_unlink;
2551   dbus_bool_t retval;
2552
2553   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2554   
2555   fd = -1;
2556   retval = FALSE;
2557   need_unlink = FALSE;
2558   
2559   if (!_dbus_string_init (&tmp_filename))
2560     {
2561       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2562       return FALSE;
2563     }
2564
2565   if (!_dbus_string_copy (filename, 0, &tmp_filename, 0))
2566     {
2567       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2568       _dbus_string_free (&tmp_filename);
2569       return FALSE;
2570     }
2571   
2572   if (!_dbus_string_append (&tmp_filename, "."))
2573     {
2574       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2575       _dbus_string_free (&tmp_filename);
2576       return FALSE;
2577     }
2578
2579 #define N_TMP_FILENAME_RANDOM_BYTES 8
2580   if (!_dbus_generate_random_ascii (&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES))
2581     {
2582       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2583       _dbus_string_free (&tmp_filename);
2584       return FALSE;
2585     }
2586     
2587   filename_c = _dbus_string_get_const_data (filename);
2588   tmp_filename_c = _dbus_string_get_const_data (&tmp_filename);
2589
2590   fd = open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
2591              0600);
2592   if (fd < 0)
2593     {
2594       dbus_set_error (error, _dbus_error_from_errno (errno),
2595                       "Could not create %s: %s", tmp_filename_c,
2596                       _dbus_strerror (errno));
2597       goto out;
2598     }
2599
2600   _dbus_verbose ("tmp file fd %d opened\n", fd);
2601   
2602   need_unlink = TRUE;
2603   
2604   total = 0;
2605   bytes_to_write = _dbus_string_get_length (str);
2606
2607   while (total < bytes_to_write)
2608     {
2609       int bytes_written;
2610
2611       bytes_written = _dbus_write (fd, str, total,
2612                                    bytes_to_write - total);
2613
2614       if (bytes_written <= 0)
2615         {
2616           dbus_set_error (error, _dbus_error_from_errno (errno),
2617                           "Could not write to %s: %s", tmp_filename_c,
2618                           _dbus_strerror (errno));
2619           
2620           goto out;
2621         }
2622
2623       total += bytes_written;
2624     }
2625
2626   if (fsync(fd))
2627     {
2628       dbus_set_error (error, _dbus_error_from_errno (errno),
2629                       "Could not synchronize file %s: %s",
2630                       tmp_filename_c, _dbus_strerror (errno));
2631
2632       goto out;
2633   }
2634
2635   if (!_dbus_close (fd, NULL))
2636     {
2637       dbus_set_error (error, _dbus_error_from_errno (errno),
2638                       "Could not close file %s: %s",
2639                       tmp_filename_c, _dbus_strerror (errno));
2640
2641       goto out;
2642     }
2643
2644   fd = -1;
2645   
2646   if (rename (tmp_filename_c, filename_c) < 0)
2647     {
2648       dbus_set_error (error, _dbus_error_from_errno (errno),
2649                       "Could not rename %s to %s: %s",
2650                       tmp_filename_c, filename_c,
2651                       _dbus_strerror (errno));
2652
2653       goto out;
2654     }
2655
2656   need_unlink = FALSE;
2657   
2658   retval = TRUE;
2659   
2660  out:
2661   /* close first, then unlink, to prevent ".nfs34234235" garbage
2662    * files
2663    */
2664
2665   if (fd >= 0)
2666     _dbus_close (fd, NULL);
2667         
2668   if (need_unlink && unlink (tmp_filename_c) < 0)
2669     _dbus_verbose ("Failed to unlink temp file %s: %s\n",
2670                    tmp_filename_c, _dbus_strerror (errno));
2671
2672   _dbus_string_free (&tmp_filename);
2673
2674   if (!retval)
2675     _DBUS_ASSERT_ERROR_IS_SET (error);
2676   
2677   return retval;
2678 }
2679
2680 /** Makes the file readable by every user in the system.
2681  *
2682  * @param filename the filename
2683  * @param error error location
2684  * @returns #TRUE if the file's permissions could be changed.
2685  */
2686 dbus_bool_t
2687 _dbus_make_file_world_readable(const DBusString *filename,
2688                                DBusError *error)
2689 {
2690   const char *filename_c;
2691
2692   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2693
2694   filename_c = _dbus_string_get_const_data (filename);
2695   if (chmod (filename_c, 0644) == -1)
2696     {
2697       dbus_set_error (error,
2698                       DBUS_ERROR_FAILED,
2699                       "Could not change permissions of file %s: %s\n",
2700                       filename_c,
2701                       _dbus_strerror (errno));
2702       return FALSE;
2703     }
2704   return TRUE;
2705 }
2706
2707 /** Creates the given file, failing if the file already exists.
2708  *
2709  * @param filename the filename
2710  * @param error error location
2711  * @returns #TRUE if we created the file and it didn't exist
2712  */
2713 dbus_bool_t
2714 _dbus_create_file_exclusively (const DBusString *filename,
2715                                DBusError        *error)
2716 {
2717   int fd;
2718   const char *filename_c;
2719
2720   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2721   
2722   filename_c = _dbus_string_get_const_data (filename);
2723   
2724   fd = open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
2725              0600);
2726   if (fd < 0)
2727     {
2728       dbus_set_error (error,
2729                       DBUS_ERROR_FAILED,
2730                       "Could not create file %s: %s\n",
2731                       filename_c,
2732                       _dbus_strerror (errno));
2733       return FALSE;
2734     }
2735
2736   _dbus_verbose ("exclusive file fd %d opened\n", fd);
2737   
2738   if (!_dbus_close (fd, NULL))
2739     {
2740       dbus_set_error (error,
2741                       DBUS_ERROR_FAILED,
2742                       "Could not close file %s: %s\n",
2743                       filename_c,
2744                       _dbus_strerror (errno));
2745       return FALSE;
2746     }
2747   
2748   return TRUE;
2749 }
2750
2751 /**
2752  * Deletes the given file.
2753  *
2754  * @param filename the filename
2755  * @param error error location
2756  * 
2757  * @returns #TRUE if unlink() succeeded
2758  */
2759 dbus_bool_t
2760 _dbus_delete_file (const DBusString *filename,
2761                    DBusError        *error)
2762 {
2763   const char *filename_c;
2764
2765   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2766   
2767   filename_c = _dbus_string_get_const_data (filename);
2768
2769   if (unlink (filename_c) < 0)
2770     {
2771       dbus_set_error (error, DBUS_ERROR_FAILED,
2772                       "Failed to delete file %s: %s\n",
2773                       filename_c, _dbus_strerror (errno));
2774       return FALSE;
2775     }
2776   else
2777     return TRUE;
2778 }
2779
2780 /**
2781  * Creates a directory; succeeds if the directory
2782  * is created or already existed.
2783  *
2784  * @param filename directory filename
2785  * @param error initialized error object
2786  * @returns #TRUE on success
2787  */
2788 dbus_bool_t
2789 _dbus_create_directory (const DBusString *filename,
2790                         DBusError        *error)
2791 {
2792   const char *filename_c;
2793
2794   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2795   
2796   filename_c = _dbus_string_get_const_data (filename);
2797
2798   if (mkdir (filename_c, 0700) < 0)
2799     {
2800       if (errno == EEXIST)
2801         return TRUE;
2802       
2803       dbus_set_error (error, DBUS_ERROR_FAILED,
2804                       "Failed to create directory %s: %s\n",
2805                       filename_c, _dbus_strerror (errno));
2806       return FALSE;
2807     }
2808   else
2809     return TRUE;
2810 }
2811
2812 /**
2813  * Appends the given filename to the given directory.
2814  *
2815  * @todo it might be cute to collapse multiple '/' such as "foo//"
2816  * concat "//bar"
2817  *
2818  * @param dir the directory name
2819  * @param next_component the filename
2820  * @returns #TRUE on success
2821  */
2822 dbus_bool_t
2823 _dbus_concat_dir_and_file (DBusString       *dir,
2824                            const DBusString *next_component)
2825 {
2826   dbus_bool_t dir_ends_in_slash;
2827   dbus_bool_t file_starts_with_slash;
2828
2829   if (_dbus_string_get_length (dir) == 0 ||
2830       _dbus_string_get_length (next_component) == 0)
2831     return TRUE;
2832   
2833   dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2834                                                     _dbus_string_get_length (dir) - 1);
2835
2836   file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2837
2838   if (dir_ends_in_slash && file_starts_with_slash)
2839     {
2840       _dbus_string_shorten (dir, 1);
2841     }
2842   else if (!(dir_ends_in_slash || file_starts_with_slash))
2843     {
2844       if (!_dbus_string_append_byte (dir, '/'))
2845         return FALSE;
2846     }
2847
2848   return _dbus_string_copy (next_component, 0, dir,
2849                             _dbus_string_get_length (dir));
2850 }
2851
2852 /** nanoseconds in a second */
2853 #define NANOSECONDS_PER_SECOND       1000000000
2854 /** microseconds in a second */
2855 #define MICROSECONDS_PER_SECOND      1000000
2856 /** milliseconds in a second */
2857 #define MILLISECONDS_PER_SECOND      1000
2858 /** nanoseconds in a millisecond */
2859 #define NANOSECONDS_PER_MILLISECOND  1000000
2860 /** microseconds in a millisecond */
2861 #define MICROSECONDS_PER_MILLISECOND 1000
2862
2863 /**
2864  * Sleeps the given number of milliseconds.
2865  * @param milliseconds number of milliseconds
2866  */
2867 void
2868 _dbus_sleep_milliseconds (int milliseconds)
2869 {
2870 #ifdef HAVE_NANOSLEEP
2871   struct timespec req;
2872   struct timespec rem;
2873
2874   req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2875   req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2876   rem.tv_sec = 0;
2877   rem.tv_nsec = 0;
2878
2879   while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2880     req = rem;
2881 #elif defined (HAVE_USLEEP)
2882   usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2883 #else /* ! HAVE_USLEEP */
2884   sleep (MAX (milliseconds / 1000, 1));
2885 #endif
2886 }
2887
2888 static dbus_bool_t
2889 _dbus_generate_pseudorandom_bytes (DBusString *str,
2890                                    int         n_bytes)
2891 {
2892   int old_len;
2893   char *p;
2894   
2895   old_len = _dbus_string_get_length (str);
2896
2897   if (!_dbus_string_lengthen (str, n_bytes))
2898     return FALSE;
2899
2900   p = _dbus_string_get_data_len (str, old_len, n_bytes);
2901
2902   _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
2903
2904   return TRUE;
2905 }
2906
2907 /**
2908  * Generates the given number of random bytes,
2909  * using the best mechanism we can come up with.
2910  *
2911  * @param str the string
2912  * @param n_bytes the number of random bytes to append to string
2913  * @returns #TRUE on success, #FALSE if no memory
2914  */
2915 dbus_bool_t
2916 _dbus_generate_random_bytes (DBusString *str,
2917                              int         n_bytes)
2918 {
2919   int old_len;
2920   int fd;
2921
2922   /* FALSE return means "no memory", if it could
2923    * mean something else then we'd need to return
2924    * a DBusError. So we always fall back to pseudorandom
2925    * if the I/O fails.
2926    */
2927   
2928   old_len = _dbus_string_get_length (str);
2929   fd = -1;
2930
2931   /* note, urandom on linux will fall back to pseudorandom */
2932   fd = open ("/dev/urandom", O_RDONLY);
2933   if (fd < 0)
2934     return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2935
2936   _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2937   
2938   if (_dbus_read (fd, str, n_bytes) != n_bytes)
2939     {
2940       _dbus_close (fd, NULL);
2941       _dbus_string_set_length (str, old_len);
2942       return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2943     }
2944
2945   _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2946                  n_bytes);
2947   
2948   _dbus_close (fd, NULL);
2949   
2950   return TRUE;
2951 }
2952
2953 /**
2954  * Exit the process, returning the given value.
2955  *
2956  * @param code the exit code
2957  */
2958 void
2959 _dbus_exit (int code)
2960 {
2961   _exit (code);
2962 }
2963
2964 /**
2965  * A wrapper around strerror() because some platforms
2966  * may be lame and not have strerror(). Also, never
2967  * returns NULL.
2968  *
2969  * @param error_number errno.
2970  * @returns error description.
2971  */
2972 const char*
2973 _dbus_strerror (int error_number)
2974 {
2975   const char *msg;
2976   
2977   msg = strerror (error_number);
2978   if (msg == NULL)
2979     msg = "unknown";
2980
2981   return msg;
2982 }
2983
2984 /**
2985  * signal (SIGPIPE, SIG_IGN);
2986  */
2987 void
2988 _dbus_disable_sigpipe (void)
2989 {
2990   signal (SIGPIPE, SIG_IGN);
2991 }
2992
2993 /**
2994  * Sets the file descriptor to be close
2995  * on exec. Should be called for all file
2996  * descriptors in D-Bus code.
2997  *
2998  * @param fd the file descriptor
2999  */
3000 void
3001 _dbus_fd_set_close_on_exec (int fd)
3002 {
3003   int val;
3004   
3005   val = fcntl (fd, F_GETFD, 0);
3006   
3007   if (val < 0)
3008     return;
3009
3010   val |= FD_CLOEXEC;
3011   
3012   fcntl (fd, F_SETFD, val);
3013 }
3014
3015 /**
3016  * Closes a file descriptor.
3017  *
3018  * @param fd the file descriptor
3019  * @param error error object
3020  * @returns #FALSE if error set
3021  */
3022 dbus_bool_t
3023 _dbus_close (int        fd,
3024              DBusError *error)
3025 {
3026   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3027   
3028  again:
3029   if (close (fd) < 0)
3030     {
3031       if (errno == EINTR)
3032         goto again;
3033
3034       dbus_set_error (error, _dbus_error_from_errno (errno),
3035                       "Could not close fd %d", fd);
3036       return FALSE;
3037     }
3038
3039   return TRUE;
3040 }
3041
3042 /**
3043  * Duplicates a file descriptor. Makes sure the fd returned is >= 3
3044  * (i.e. avoids stdin/stdout/stderr). Sets O_CLOEXEC.
3045  *
3046  * @param fd the file descriptor to duplicate
3047  * @returns duplicated file descriptor
3048  * */
3049 int
3050 _dbus_dup(int        fd,
3051           DBusError *error)
3052 {
3053   int new_fd;
3054
3055 #ifdef F_DUPFD_CLOEXEC
3056   dbus_bool_t cloexec_done;
3057
3058   new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
3059   cloexec_done = new_fd >= 0;
3060
3061   if (new_fd < 0 && errno == EINVAL)
3062 #endif
3063     {
3064       new_fd = fcntl(fd, F_DUPFD, 3);
3065     }
3066
3067   if (new_fd < 0) {
3068
3069     dbus_set_error (error, _dbus_error_from_errno (errno),
3070                     "Could not duplicate fd %d", fd);
3071     return -1;
3072   }
3073
3074 #ifdef F_DUPFD_CLOEXEC
3075   if (!cloexec_done)
3076 #endif
3077     {
3078       _dbus_fd_set_close_on_exec(new_fd);
3079     }
3080
3081   return new_fd;
3082 }
3083
3084 /**
3085  * Sets a file descriptor to be nonblocking.
3086  *
3087  * @param fd the file descriptor.
3088  * @param error address of error location.
3089  * @returns #TRUE on success.
3090  */
3091 dbus_bool_t
3092 _dbus_set_fd_nonblocking (int             fd,
3093                           DBusError      *error)
3094 {
3095   int val;
3096
3097   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3098   
3099   val = fcntl (fd, F_GETFL, 0);
3100   if (val < 0)
3101     {
3102       dbus_set_error (error, _dbus_error_from_errno (errno),
3103                       "Failed to get flags from file descriptor %d: %s",
3104                       fd, _dbus_strerror (errno));
3105       _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3106                      _dbus_strerror (errno));
3107       return FALSE;
3108     }
3109
3110   if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3111     {
3112       dbus_set_error (error, _dbus_error_from_errno (errno),
3113                       "Failed to set nonblocking flag of file descriptor %d: %s",
3114                       fd, _dbus_strerror (errno));
3115       _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3116                      fd, _dbus_strerror (errno));
3117
3118       return FALSE;
3119     }
3120
3121   return TRUE;
3122 }
3123
3124 /**
3125  * On GNU libc systems, print a crude backtrace to stderr.  On other
3126  * systems, print "no backtrace support" and block for possible gdb
3127  * attachment if an appropriate environment variable is set.
3128  */
3129 void
3130 _dbus_print_backtrace (void)
3131 {  
3132 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3133   void *bt[500];
3134   int bt_size;
3135   int i;
3136   char **syms;
3137   
3138   bt_size = backtrace (bt, 500);
3139
3140   syms = backtrace_symbols (bt, bt_size);
3141   
3142   i = 0;
3143   while (i < bt_size)
3144     {
3145       /* don't use dbus_warn since it can _dbus_abort() */
3146       fprintf (stderr, "  %s\n", syms[i]);
3147       ++i;
3148     }
3149   fflush (stderr);
3150
3151   free (syms);
3152 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3153   fprintf (stderr, "  D-Bus not built with -rdynamic so unable to print a backtrace\n");
3154 #else
3155   fprintf (stderr, "  D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3156 #endif
3157 }
3158
3159 /**
3160  * Creates a full-duplex pipe (as in socketpair()).
3161  * Sets both ends of the pipe nonblocking.
3162  *
3163  * Marks both file descriptors as close-on-exec
3164  *
3165  * @todo libdbus only uses this for the debug-pipe server, so in
3166  * principle it could be in dbus-sysdeps-util.c, except that
3167  * dbus-sysdeps-util.c isn't in libdbus when tests are enabled and the
3168  * debug-pipe server is used.
3169  * 
3170  * @param fd1 return location for one end
3171  * @param fd2 return location for the other end
3172  * @param blocking #TRUE if pipe should be blocking
3173  * @param error error return
3174  * @returns #FALSE on failure (if error is set)
3175  */
3176 dbus_bool_t
3177 _dbus_full_duplex_pipe (int        *fd1,
3178                         int        *fd2,
3179                         dbus_bool_t blocking,
3180                         DBusError  *error)
3181 {
3182 #ifdef HAVE_SOCKETPAIR
3183   int fds[2];
3184   int retval;
3185
3186 #ifdef SOCK_CLOEXEC
3187   dbus_bool_t cloexec_done;
3188
3189   retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3190   cloexec_done = retval >= 0;
3191
3192   if (retval < 0 && errno == EINVAL)
3193 #endif
3194     {
3195       retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3196     }
3197
3198   if (retval < 0)
3199     {
3200       dbus_set_error (error, _dbus_error_from_errno (errno),
3201                       "Could not create full-duplex pipe");
3202       return FALSE;
3203     }
3204
3205   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3206
3207 #ifdef SOCK_CLOEXEC
3208   if (!cloexec_done)
3209 #endif
3210     {
3211       _dbus_fd_set_close_on_exec (fds[0]);
3212       _dbus_fd_set_close_on_exec (fds[1]);
3213     }
3214
3215   if (!blocking &&
3216       (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3217        !_dbus_set_fd_nonblocking (fds[1], NULL)))
3218     {
3219       dbus_set_error (error, _dbus_error_from_errno (errno),
3220                       "Could not set full-duplex pipe nonblocking");
3221       
3222       _dbus_close (fds[0], NULL);
3223       _dbus_close (fds[1], NULL);
3224       
3225       return FALSE;
3226     }
3227   
3228   *fd1 = fds[0];
3229   *fd2 = fds[1];
3230
3231   _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3232                  *fd1, *fd2);
3233   
3234   return TRUE;  
3235 #else
3236   _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
3237   dbus_set_error (error, DBUS_ERROR_FAILED,
3238                   "_dbus_full_duplex_pipe() not implemented on this OS");
3239   return FALSE;
3240 #endif
3241 }
3242
3243 /**
3244  * Measure the length of the given format string and arguments,
3245  * not including the terminating nul.
3246  *
3247  * @param format a printf-style format string
3248  * @param args arguments for the format string
3249  * @returns length of the given format string and args
3250  */
3251 int
3252 _dbus_printf_string_upper_bound (const char *format,
3253                                  va_list     args)
3254 {
3255   char c;
3256   return vsnprintf (&c, 1, format, args);
3257 }
3258
3259 /**
3260  * Gets the temporary files directory by inspecting the environment variables 
3261  * TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned
3262  *
3263  * @returns location of temp directory
3264  */
3265 const char*
3266 _dbus_get_tmpdir(void)
3267 {
3268   static const char* tmpdir = NULL;
3269
3270   if (tmpdir == NULL)
3271     {
3272       /* TMPDIR is what glibc uses, then
3273        * glibc falls back to the P_tmpdir macro which
3274        * just expands to "/tmp"
3275        */
3276       if (tmpdir == NULL)
3277         tmpdir = getenv("TMPDIR");
3278
3279       /* These two env variables are probably
3280        * broken, but maybe some OS uses them?
3281        */
3282       if (tmpdir == NULL)
3283         tmpdir = getenv("TMP");
3284       if (tmpdir == NULL)
3285         tmpdir = getenv("TEMP");
3286
3287       /* And this is the sane fallback. */
3288       if (tmpdir == NULL)
3289         tmpdir = "/tmp";
3290     }
3291   
3292   _dbus_assert(tmpdir != NULL);
3293   
3294   return tmpdir;
3295 }
3296
3297 /**
3298  * Execute a subprocess, returning up to 1024 bytes of output
3299  * into @p result.
3300  *
3301  * If successful, returns #TRUE and appends the output to @p
3302  * result. If a failure happens, returns #FALSE and
3303  * sets an error in @p error.
3304  *
3305  * @note It's not an error if the subprocess terminates normally
3306  * without writing any data to stdout. Verify the @p result length
3307  * before and after this function call to cover this case.
3308  *
3309  * @param progname initial path to exec (may or may not be absolute)
3310  * @param path_fallback if %TRUE, search PATH for executable
3311  * @param argv NULL-terminated list of arguments
3312  * @param result a DBusString where the output can be append
3313  * @param error a DBusError to store the error in case of failure
3314  * @returns #TRUE on success, #FALSE if an error happened
3315  */
3316 static dbus_bool_t
3317 _read_subprocess_line_argv (const char *progpath,
3318                             dbus_bool_t path_fallback,
3319                             char       * const *argv,
3320                             DBusString *result,
3321                             DBusError  *error)
3322 {
3323   int result_pipe[2] = { -1, -1 };
3324   int errors_pipe[2] = { -1, -1 };
3325   pid_t pid;
3326   int ret;
3327   int status;
3328   int orig_len;
3329   int i;
3330
3331   dbus_bool_t retval;
3332   sigset_t new_set, old_set;
3333   
3334   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3335   retval = FALSE;
3336
3337   /* We need to block any existing handlers for SIGCHLD temporarily; they
3338    * will cause waitpid() below to fail.
3339    * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3340    */
3341   sigemptyset (&new_set);
3342   sigaddset (&new_set, SIGCHLD);
3343   sigprocmask (SIG_BLOCK, &new_set, &old_set);
3344   
3345   orig_len = _dbus_string_get_length (result);
3346   
3347 #define READ_END        0
3348 #define WRITE_END       1
3349   if (pipe (result_pipe) < 0)
3350     {
3351       dbus_set_error (error, _dbus_error_from_errno (errno),
3352                       "Failed to create a pipe to call %s: %s",
3353                       progpath, _dbus_strerror (errno));
3354       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3355                      progpath, _dbus_strerror (errno));
3356       goto out;
3357     }
3358   if (pipe (errors_pipe) < 0)
3359     {
3360       dbus_set_error (error, _dbus_error_from_errno (errno),
3361                       "Failed to create a pipe to call %s: %s",
3362                       progpath, _dbus_strerror (errno));
3363       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3364                      progpath, _dbus_strerror (errno));
3365       goto out;
3366     }
3367
3368   pid = fork ();
3369   if (pid < 0)
3370     {
3371       dbus_set_error (error, _dbus_error_from_errno (errno),
3372                       "Failed to fork() to call %s: %s",
3373                       progpath, _dbus_strerror (errno));
3374       _dbus_verbose ("Failed to fork() to call %s: %s\n",
3375                      progpath, _dbus_strerror (errno));
3376       goto out;
3377     }
3378
3379   if (pid == 0)
3380     {
3381       /* child process */
3382       int maxfds;
3383       int fd;
3384
3385       fd = open ("/dev/null", O_RDWR);
3386       if (fd == -1)
3387         /* huh?! can't open /dev/null? */
3388         _exit (1);
3389
3390       _dbus_verbose ("/dev/null fd %d opened\n", fd);
3391       
3392       /* set-up stdXXX */
3393       close (result_pipe[READ_END]);
3394       close (errors_pipe[READ_END]);
3395       close (0);                /* close stdin */
3396       close (1);                /* close stdout */
3397       close (2);                /* close stderr */
3398
3399       if (dup2 (fd, 0) == -1)
3400         _exit (1);
3401       if (dup2 (result_pipe[WRITE_END], 1) == -1)
3402         _exit (1);
3403       if (dup2 (errors_pipe[WRITE_END], 2) == -1)
3404         _exit (1);
3405
3406       maxfds = sysconf (_SC_OPEN_MAX);
3407       /* Pick something reasonable if for some reason sysconf
3408        * says unlimited.
3409        */
3410       if (maxfds < 0)
3411         maxfds = 1024;
3412       /* close all inherited fds */
3413       for (i = 3; i < maxfds; i++)
3414         close (i);
3415
3416       sigprocmask (SIG_SETMASK, &old_set, NULL);
3417
3418       /* If it looks fully-qualified, try execv first */
3419       if (progpath[0] == '/')
3420         {
3421           execv (progpath, argv);
3422           /* Ok, that failed.  Now if path_fallback is given, let's
3423            * try unqualified.  This is mostly a hack to work
3424            * around systems which ship dbus-launch in /usr/bin
3425            * but everything else in /bin (because dbus-launch
3426            * depends on X11).
3427            */
3428           if (path_fallback)
3429             /* We must have a slash, because we checked above */
3430             execvp (strrchr (progpath, '/')+1, argv);
3431         }
3432       else
3433         execvp (progpath, argv);
3434
3435       /* still nothing, we failed */
3436       _exit (1);
3437     }
3438
3439   /* parent process */
3440   close (result_pipe[WRITE_END]);
3441   close (errors_pipe[WRITE_END]);
3442   result_pipe[WRITE_END] = -1;
3443   errors_pipe[WRITE_END] = -1;
3444
3445   ret = 0;
3446   do 
3447     {
3448       ret = _dbus_read (result_pipe[READ_END], result, 1024);
3449     }
3450   while (ret > 0);
3451
3452   /* reap the child process to avoid it lingering as zombie */
3453   do
3454     {
3455       ret = waitpid (pid, &status, 0);
3456     }
3457   while (ret == -1 && errno == EINTR);
3458
3459   /* We succeeded if the process exited with status 0 and
3460      anything was read */
3461   if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3462     {
3463       /* The process ended with error */
3464       DBusString error_message;
3465       _dbus_string_init (&error_message);
3466       ret = 0;
3467       do
3468         {
3469           ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3470         }
3471       while (ret > 0);
3472
3473       _dbus_string_set_length (result, orig_len);
3474       if (_dbus_string_get_length (&error_message) > 0)
3475         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3476                         "%s terminated abnormally with the following error: %s",
3477                         progpath, _dbus_string_get_data (&error_message));
3478       else
3479         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3480                         "%s terminated abnormally without any error message",
3481                         progpath);
3482       goto out;
3483     }
3484
3485   retval = TRUE;
3486   
3487  out:
3488   sigprocmask (SIG_SETMASK, &old_set, NULL);
3489
3490   if (retval)
3491     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3492   else
3493     _DBUS_ASSERT_ERROR_IS_SET (error);
3494
3495   if (result_pipe[0] != -1)
3496     close (result_pipe[0]);
3497   if (result_pipe[1] != -1)
3498     close (result_pipe[1]);
3499   if (errors_pipe[0] != -1)
3500     close (errors_pipe[0]);
3501   if (errors_pipe[1] != -1)
3502     close (errors_pipe[1]);
3503
3504   return retval;  
3505 }
3506
3507 /**
3508  * Returns the address of a new session bus.
3509  *
3510  * If successful, returns #TRUE and appends the address to @p
3511  * address. If a failure happens, returns #FALSE and
3512  * sets an error in @p error.
3513  *
3514  * @param address a DBusString where the address can be stored
3515  * @param error a DBusError to store the error in case of failure
3516  * @returns #TRUE on success, #FALSE if an error happened
3517  */
3518 dbus_bool_t
3519 _dbus_get_autolaunch_address (DBusString *address,
3520                               DBusError  *error)
3521 {
3522   static char *argv[6];
3523   int i;
3524   DBusString uuid;
3525   dbus_bool_t retval;
3526   
3527   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3528   retval = FALSE;
3529
3530   if (!_dbus_string_init (&uuid))
3531     {
3532       _DBUS_SET_OOM (error);
3533       return FALSE;
3534     }
3535   
3536   if (!_dbus_get_local_machine_uuid_encoded (&uuid))
3537     {
3538       _DBUS_SET_OOM (error);
3539       goto out;
3540     }
3541   
3542   i = 0;
3543   argv[i] = "dbus-launch";
3544   ++i;
3545   argv[i] = "--autolaunch";
3546   ++i;
3547   argv[i] = _dbus_string_get_data (&uuid);
3548   ++i;
3549   argv[i] = "--binary-syntax";
3550   ++i;
3551   argv[i] = "--close-stderr";
3552   ++i;
3553   argv[i] = NULL;
3554   ++i;
3555
3556   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3557
3558   retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
3559                                        TRUE,
3560                                        argv, address, error);
3561
3562  out:
3563   _dbus_string_free (&uuid);
3564   return retval;
3565 }
3566
3567 /**
3568  * Reads the uuid of the machine we're running on from
3569  * the dbus configuration. Optionally try to create it
3570  * (only root can do this usually).
3571  *
3572  * On UNIX, reads a file that gets created by dbus-uuidgen
3573  * in a post-install script. On Windows, if there's a standard
3574  * machine uuid we could just use that, but I can't find one
3575  * with the right properties (the hardware profile guid can change
3576  * without rebooting I believe). If there's no standard one
3577  * we might want to use the registry instead of a file for
3578  * this, and I'm not sure how we'd ensure the uuid gets created.
3579  *
3580  * @param machine_id guid to init with the machine's uuid
3581  * @param create_if_not_found try to create the uuid if it doesn't exist
3582  * @param error the error return
3583  * @returns #FALSE if the error is set
3584  */
3585 dbus_bool_t
3586 _dbus_read_local_machine_uuid (DBusGUID   *machine_id,
3587                                dbus_bool_t create_if_not_found,
3588                                DBusError  *error)
3589 {
3590   DBusString filename;
3591   _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3592   return _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
3593 }
3594
3595 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
3596 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
3597
3598 /**
3599  * Determines the address of the session bus by querying a
3600  * platform-specific method.  
3601  *
3602  * The first parameter will be a boolean specifying whether
3603  * or not a dynamic session lookup is supported on this platform.
3604  * 
3605  * If supported is TRUE and the return value is #TRUE, the
3606  * address will be  appended to @p address.
3607  * If a failure happens, returns #FALSE and sets an error in 
3608  * @p error.
3609  *
3610  * If supported is FALSE, ignore the return value.
3611  *
3612  * @param supported returns whether this method is supported
3613  * @param address a DBusString where the address can be stored
3614  * @param error a DBusError to store the error in case of failure
3615  * @returns #TRUE on success, #FALSE if an error happened
3616  */
3617 dbus_bool_t
3618 _dbus_lookup_session_address (dbus_bool_t *supported,
3619                               DBusString  *address,
3620                               DBusError   *error)
3621 {
3622   /* On non-Mac Unix platforms, if the session address isn't already
3623    * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
3624    * fall back to the autolaunch: global default; see 
3625    * init_session_address in dbus/dbus-bus.c. */
3626   *supported = FALSE;
3627   return TRUE;
3628 }
3629
3630 /**
3631  * Returns the standard directories for a session bus to look for service 
3632  * activation files 
3633  *
3634  * On UNIX this should be the standard xdg freedesktop.org data directories:
3635  *
3636  * XDG_DATA_HOME=${XDG_DATA_HOME-$HOME/.local/share}
3637  * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3638  *
3639  * and
3640  *
3641  * DBUS_DATADIR
3642  *
3643  * @param dirs the directory list we are returning
3644  * @returns #FALSE on OOM 
3645  */
3646
3647 dbus_bool_t 
3648 _dbus_get_standard_session_servicedirs (DBusList **dirs)
3649 {
3650   const char *xdg_data_home;
3651   const char *xdg_data_dirs;
3652   DBusString servicedir_path;
3653
3654   if (!_dbus_string_init (&servicedir_path))
3655     return FALSE;
3656
3657   xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
3658   xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3659
3660   if (xdg_data_dirs != NULL)
3661     {
3662       if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3663         goto oom;
3664
3665       if (!_dbus_string_append (&servicedir_path, ":"))
3666         goto oom;
3667     }
3668   else
3669     {
3670       if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3671         goto oom;
3672     }
3673
3674   /* 
3675    * add configured datadir to defaults
3676    * this may be the same as an xdg dir
3677    * however the config parser should take 
3678    * care of duplicates 
3679    */
3680   if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
3681         goto oom;
3682
3683   if (xdg_data_home != NULL)
3684     {
3685       if (!_dbus_string_append (&servicedir_path, xdg_data_home))
3686         goto oom;
3687     }
3688   else
3689     {
3690       const DBusString *homedir;
3691       DBusString local_share;
3692
3693       if (!_dbus_homedir_from_current_process (&homedir))
3694         goto oom;
3695        
3696       if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
3697         goto oom;
3698
3699       _dbus_string_init_const (&local_share, "/.local/share");
3700       if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
3701         goto oom;
3702     }
3703
3704   if (!_dbus_split_paths_and_append (&servicedir_path, 
3705                                      DBUS_UNIX_STANDARD_SESSION_SERVICEDIR, 
3706                                      dirs))
3707     goto oom;
3708
3709   _dbus_string_free (&servicedir_path);  
3710   return TRUE;
3711
3712  oom:
3713   _dbus_string_free (&servicedir_path);
3714   return FALSE;
3715 }
3716
3717
3718 /**
3719  * Returns the standard directories for a system bus to look for service 
3720  * activation files 
3721  *
3722  * On UNIX this should be the standard xdg freedesktop.org data directories:
3723  *
3724  * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3725  *
3726  * and
3727  *
3728  * DBUS_DATADIR
3729  *
3730  * On Windows there is no system bus and this function can return nothing.
3731  *
3732  * @param dirs the directory list we are returning
3733  * @returns #FALSE on OOM 
3734  */
3735
3736 dbus_bool_t 
3737 _dbus_get_standard_system_servicedirs (DBusList **dirs)
3738 {
3739   const char *xdg_data_dirs;
3740   DBusString servicedir_path;
3741
3742   if (!_dbus_string_init (&servicedir_path))
3743     return FALSE;
3744
3745   xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3746
3747   if (xdg_data_dirs != NULL)
3748     {
3749       if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3750         goto oom;
3751
3752       if (!_dbus_string_append (&servicedir_path, ":"))
3753         goto oom;
3754     }
3755   else
3756     {
3757       if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3758         goto oom;
3759     }
3760
3761   /* 
3762    * add configured datadir to defaults
3763    * this may be the same as an xdg dir
3764    * however the config parser should take 
3765    * care of duplicates 
3766    */
3767   if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
3768         goto oom;
3769
3770   if (!_dbus_split_paths_and_append (&servicedir_path, 
3771                                      DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR, 
3772                                      dirs))
3773     goto oom;
3774
3775   _dbus_string_free (&servicedir_path);  
3776   return TRUE;
3777
3778  oom:
3779   _dbus_string_free (&servicedir_path);
3780   return FALSE;
3781 }
3782
3783 /**
3784  * Append the absolute path of the system.conf file
3785  * (there is no system bus on Windows so this can just
3786  * return FALSE and print a warning or something)
3787  * 
3788  * @param str the string to append to
3789  * @returns #FALSE if no memory
3790  */
3791 dbus_bool_t
3792 _dbus_append_system_config_file (DBusString *str)
3793 {
3794   return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
3795 }
3796
3797 /**
3798  * Append the absolute path of the session.conf file.
3799  * 
3800  * @param str the string to append to
3801  * @returns #FALSE if no memory
3802  */
3803 dbus_bool_t
3804 _dbus_append_session_config_file (DBusString *str)
3805 {
3806   return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
3807 }
3808
3809 /**
3810  * Called when the bus daemon is signaled to reload its configuration; any
3811  * caches should be nuked. Of course any caches that need explicit reload
3812  * are probably broken, but c'est la vie.
3813  *
3814  * 
3815  */
3816 void
3817 _dbus_flush_caches (void)
3818 {
3819   _dbus_user_database_flush_system ();
3820 }
3821
3822 /**
3823  * Appends the directory in which a keyring for the given credentials
3824  * should be stored.  The credentials should have either a Windows or
3825  * UNIX user in them.  The directory should be an absolute path.
3826  *
3827  * On UNIX the directory is ~/.dbus-keyrings while on Windows it should probably
3828  * be something else, since the dotfile convention is not normal on Windows.
3829  * 
3830  * @param directory string to append directory to
3831  * @param credentials credentials the directory should be for
3832  *  
3833  * @returns #FALSE on no memory
3834  */
3835 dbus_bool_t
3836 _dbus_append_keyring_directory_for_credentials (DBusString      *directory,
3837                                                 DBusCredentials *credentials)
3838 {
3839   DBusString homedir;
3840   DBusString dotdir;
3841   dbus_uid_t uid;
3842   
3843   _dbus_assert (credentials != NULL);
3844   _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
3845   
3846   if (!_dbus_string_init (&homedir))
3847     return FALSE;
3848
3849   uid = _dbus_credentials_get_unix_uid (credentials);
3850   _dbus_assert (uid != DBUS_UID_UNSET);
3851
3852   if (!_dbus_homedir_from_uid (uid, &homedir))
3853     goto failed;
3854   
3855 #ifdef DBUS_BUILD_TESTS
3856   {
3857     const char *override;
3858     
3859     override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3860     if (override != NULL && *override != '\0')
3861       {
3862         _dbus_string_set_length (&homedir, 0);
3863         if (!_dbus_string_append (&homedir, override))
3864           goto failed;
3865
3866         _dbus_verbose ("Using fake homedir for testing: %s\n",
3867                        _dbus_string_get_const_data (&homedir));
3868       }
3869     else
3870       {
3871         static dbus_bool_t already_warned = FALSE;
3872         if (!already_warned)
3873           {
3874             _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3875             already_warned = TRUE;
3876           }
3877       }
3878   }
3879 #endif
3880
3881   _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3882   if (!_dbus_concat_dir_and_file (&homedir,
3883                                   &dotdir))
3884     goto failed;
3885   
3886   if (!_dbus_string_copy (&homedir, 0,
3887                           directory, _dbus_string_get_length (directory))) {
3888     goto failed;
3889   }
3890
3891   _dbus_string_free (&homedir);
3892   return TRUE;
3893   
3894  failed: 
3895   _dbus_string_free (&homedir);
3896   return FALSE;
3897 }
3898
3899 //PENDING(kdab) docs
3900 void
3901 _dbus_daemon_publish_session_bus_address (const char* addr)
3902 {
3903
3904 }
3905
3906 //PENDING(kdab) docs
3907 void
3908 _dbus_daemon_unpublish_session_bus_address (void)
3909 {
3910
3911 }
3912
3913 /**
3914  * See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently
3915  * for Winsock so is abstracted)
3916  *
3917  * @returns #TRUE if errno == EAGAIN or errno == EWOULDBLOCK
3918  */
3919 dbus_bool_t
3920 _dbus_get_is_errno_eagain_or_ewouldblock (void)
3921 {
3922   return errno == EAGAIN || errno == EWOULDBLOCK;
3923 }
3924
3925 /**
3926  * Removes a directory; Directory must be empty
3927  *
3928  * @param filename directory filename
3929  * @param error initialized error object
3930  * @returns #TRUE on success
3931  */
3932 dbus_bool_t
3933 _dbus_delete_directory (const DBusString *filename,
3934                         DBusError        *error)
3935 {
3936   const char *filename_c;
3937
3938   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3939
3940   filename_c = _dbus_string_get_const_data (filename);
3941
3942   if (rmdir (filename_c) != 0)
3943     {
3944       dbus_set_error (error, DBUS_ERROR_FAILED,
3945                       "Failed to remove directory %s: %s\n",
3946                       filename_c, _dbus_strerror (errno));
3947       return FALSE;
3948     }
3949
3950   return TRUE;
3951 }
3952
3953 /**
3954  *  Checks whether file descriptors may be passed via the socket
3955  *
3956  *  @param fd the socket
3957  *  @return TRUE when fd passing over this socket is supported
3958  *
3959  */
3960 dbus_bool_t
3961 _dbus_socket_can_pass_unix_fd(int fd) {
3962
3963 #ifdef SCM_RIGHTS
3964   union {
3965     struct sockaddr sa;
3966     struct sockaddr_storage storage;
3967     struct sockaddr_un un;
3968   } sa_buf;
3969
3970   socklen_t sa_len = sizeof(sa_buf);
3971
3972   _DBUS_ZERO(sa_buf);
3973
3974   if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
3975     return FALSE;
3976
3977   return sa_buf.sa.sa_family == AF_UNIX;
3978
3979 #else
3980   return FALSE;
3981
3982 #endif
3983 }
3984
3985 /* tests in dbus-sysdeps-util.c */