Fix IPv6 setup (the default on Vista)
[platform/upstream/dbus.git] / dbus / dbus-sysdeps-win.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-sysdeps.c Wrappers around system/libc features (internal to D-BUS implementation)
3  * 
4  * Copyright (C) 2002, 2003  Red Hat, Inc.
5  * Copyright (C) 2003 CodeFactory AB
6  * Copyright (C) 2005 Novell, Inc.
7  * Copyright (C) 2006 Ralf Habacker <ralf.habacker@freenet.de>
8  * Copyright (C) 2006 Peter Kümmel  <syntheticpp@gmx.net>
9  * Copyright (C) 2006 Christian Ehrlicher <ch.ehrlicher@gmx.de>
10  *
11  * Licensed under the Academic Free License version 2.1
12  * 
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  * 
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
26  *
27  */
28
29 #define STRSAFE_NO_DEPRECATE
30
31 #ifndef DBUS_WINCE
32 #ifndef _WIN32_WINNT
33 #define _WIN32_WINNT 0x0501
34 #endif
35 #endif
36
37 #include "dbus-internals.h"
38 #include "dbus-sysdeps.h"
39 #include "dbus-threads.h"
40 #include "dbus-protocol.h"
41 #include "dbus-string.h"
42 #include "dbus-sysdeps-win.h"
43 #include "dbus-protocol.h"
44 #include "dbus-hash.h"
45 #include "dbus-sockets-win.h"
46 #include "dbus-list.h"
47 #include "dbus-nonce.h"
48 #include "dbus-credentials.h"
49
50 #include <windows.h>
51 #include <ws2tcpip.h>
52 #include <wincrypt.h>
53
54 /* Declarations missing in mingw's headers */
55 extern BOOL WINAPI ConvertStringSidToSidA (LPCSTR  StringSid, PSID *Sid);
56 extern BOOL WINAPI ConvertSidToStringSidA (PSID Sid, LPSTR *StringSid);
57
58 #include <fcntl.h>
59
60 #include <process.h>
61 #include <stdio.h>
62 #include <io.h>
63
64 #include <string.h>
65 #include <errno.h>
66 #include <sys/stat.h>
67 #include <sys/types.h>
68
69 #ifdef HAVE_WSPIAPI_H
70 // needed for w2k compatibility (getaddrinfo/freeaddrinfo/getnameinfo)
71 #ifdef __GNUC__
72 #define _inline
73 #include "wspiapi.h"
74 #else
75 #include <wspiapi.h>
76 #endif
77 #endif // HAVE_WSPIAPI_H
78
79 #ifndef O_BINARY
80 #define O_BINARY 0
81 #endif
82
83 typedef int socklen_t;
84
85 static char*
86 _dbus_win_error_string (int error_number)
87 {
88   char *msg;
89
90   FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
91                  FORMAT_MESSAGE_IGNORE_INSERTS |
92                  FORMAT_MESSAGE_FROM_SYSTEM,
93                  NULL, error_number, 0,
94                  (LPSTR) &msg, 0, NULL);
95
96   if (msg[strlen (msg) - 1] == '\n')
97     msg[strlen (msg) - 1] = '\0';
98   if (msg[strlen (msg) - 1] == '\r')
99     msg[strlen (msg) - 1] = '\0';
100
101   return msg;
102 }
103
104 static void
105 _dbus_win_free_error_string (char *string)
106 {
107   LocalFree (string);
108 }
109
110 /**
111  * write data to a pipe.
112  *
113  * @param pipe the pipe instance
114  * @param buffer the buffer to write data from
115  * @param start the first byte in the buffer to write
116  * @param len the number of bytes to try to write
117  * @param error error return
118  * @returns the number of bytes written or -1 on error
119  */
120 int
121 _dbus_pipe_write (DBusPipe         *pipe,
122                   const DBusString *buffer,
123                   int               start,
124                   int               len,
125                   DBusError        *error)
126 {
127   int written;
128   const char *buffer_c = _dbus_string_get_const_data (buffer);
129
130   written = _write (pipe->fd_or_handle, buffer_c + start, len);
131   if (written < 0)
132     {
133       dbus_set_error (error, DBUS_ERROR_FAILED,
134                       "Writing to pipe: %s\n",
135                       strerror (errno));
136     }
137   return written;
138 }
139
140 /**
141  * close a pipe.
142  *
143  * @param pipe the pipe instance
144  * @param error return location for an error
145  * @returns #FALSE if error is set
146  */
147 int
148 _dbus_pipe_close  (DBusPipe         *pipe,
149                    DBusError        *error)
150 {
151   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
152
153   if (_close (pipe->fd_or_handle) < 0)
154     {
155       dbus_set_error (error, _dbus_error_from_errno (errno),
156                       "Could not close pipe %d: %s", pipe->fd_or_handle, strerror (errno));
157       return -1;
158     }
159   else
160     {
161       _dbus_pipe_invalidate (pipe);
162       return 0;
163     }
164 }
165
166 /**
167  * Socket interface
168  *
169  */
170
171 /**
172  * Thin wrapper around the read() system call that appends
173  * the data it reads to the DBusString buffer. It appends
174  * up to the given count, and returns the same value
175  * and same errno as read(). The only exception is that
176  * _dbus_read() handles EINTR for you. _dbus_read() can
177  * return ENOMEM, even though regular UNIX read doesn't.
178  *
179  * @param fd the file descriptor to read from
180  * @param buffer the buffer to append data to
181  * @param count the amount of data to read
182  * @returns the number of bytes read or -1
183  */
184
185 int
186 _dbus_read_socket (int               fd,
187                    DBusString       *buffer,
188                    int               count)
189 {
190   int bytes_read;
191   int start;
192   char *data;
193
194   _dbus_assert (count >= 0);
195
196   start = _dbus_string_get_length (buffer);
197
198   if (!_dbus_string_lengthen (buffer, count))
199     {
200       errno = ENOMEM;
201       return -1;
202     }
203
204   data = _dbus_string_get_data_len (buffer, start, count);
205
206  again:
207  
208   _dbus_verbose ("recv: count=%d fd=%d\n", count, fd);
209   bytes_read = recv (fd, data, count, 0);
210   
211   if (bytes_read == SOCKET_ERROR)
212         {
213           DBUS_SOCKET_SET_ERRNO();
214           _dbus_verbose ("recv: failed: %s (%d)\n", _dbus_strerror (errno), errno);
215           bytes_read = -1;
216         }
217         else
218           _dbus_verbose ("recv: = %d\n", bytes_read);
219
220   if (bytes_read < 0)
221     {
222       if (errno == EINTR)
223         goto again;
224       else      
225         {
226           /* put length back (note that this doesn't actually realloc anything) */
227           _dbus_string_set_length (buffer, start);
228           return -1;
229         }
230     }
231   else
232     {
233       /* put length back (doesn't actually realloc) */
234       _dbus_string_set_length (buffer, start + bytes_read);
235
236 #if 0
237       if (bytes_read > 0)
238         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
239 #endif
240
241       return bytes_read;
242     }
243 }
244
245 /**
246  * Thin wrapper around the write() system call that writes a part of a
247  * DBusString and handles EINTR for you.
248  * 
249  * @param fd the file descriptor to write
250  * @param buffer the buffer to write data from
251  * @param start the first byte in the buffer to write
252  * @param len the number of bytes to try to write
253  * @returns the number of bytes written or -1 on error
254  */
255 int
256 _dbus_write_socket (int               fd,
257                     const DBusString *buffer,
258                     int               start,
259                     int               len)
260 {
261   const char *data;
262   int bytes_written;
263
264   data = _dbus_string_get_const_data_len (buffer, start, len);
265
266  again:
267
268   _dbus_verbose ("send: len=%d fd=%d\n", len, fd);
269   bytes_written = send (fd, data, len, 0);
270
271   if (bytes_written == SOCKET_ERROR)
272     {
273       DBUS_SOCKET_SET_ERRNO();
274       _dbus_verbose ("send: failed: %s\n", _dbus_strerror (errno));
275       bytes_written = -1;
276     }
277     else
278       _dbus_verbose ("send: = %d\n", bytes_written);
279
280   if (bytes_written < 0 && errno == EINTR)
281     goto again;
282     
283 #if 0
284   if (bytes_written > 0)
285     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
286 #endif
287
288   return bytes_written;
289 }
290
291
292 /**
293  * Closes a file descriptor.
294  *
295  * @param fd the file descriptor
296  * @param error error object
297  * @returns #FALSE if error set
298  */
299 dbus_bool_t
300 _dbus_close_socket (int        fd,
301                     DBusError *error)
302 {
303   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
304
305  again:
306   if (closesocket (fd) == SOCKET_ERROR)
307     {
308       DBUS_SOCKET_SET_ERRNO ();
309       
310       if (errno == EINTR)
311         goto again;
312         
313       dbus_set_error (error, _dbus_error_from_errno (errno),
314                       "Could not close socket: socket=%d, , %s",
315                       fd, _dbus_strerror (errno));
316       return FALSE;
317     }
318   _dbus_verbose ("_dbus_close_socket: socket=%d, \n", fd);
319
320   return TRUE;
321 }
322
323 /**
324  * Sets the file descriptor to be close
325  * on exec. Should be called for all file
326  * descriptors in D-Bus code.
327  *
328  * @param fd the file descriptor
329  */
330 void
331 _dbus_fd_set_close_on_exec (int handle)
332 {
333 #ifdef ENABLE_DBUSSOCKET
334   DBusSocket *s;
335   if (handle < 0)
336     return;
337
338   _dbus_lock_sockets();
339
340   _dbus_handle_to_socket_unlocked (handle, &s);
341   s->close_on_exec = TRUE;
342
343   _dbus_unlock_sockets();
344 #else
345   /* TODO unic code.
346   int val;
347   
348   val = fcntl (fd, F_GETFD, 0);
349   
350   if (val < 0)
351     return;
352
353   val |= FD_CLOEXEC;
354   
355   fcntl (fd, F_SETFD, val);
356   */
357 #endif
358 }
359
360 /**
361  * Sets a file descriptor to be nonblocking.
362  *
363  * @param fd the file descriptor.
364  * @param error address of error location.
365  * @returns #TRUE on success.
366  */
367 dbus_bool_t
368 _dbus_set_fd_nonblocking (int             handle,
369                           DBusError      *error)
370 {
371   u_long one = 1;
372
373   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
374
375   if (ioctlsocket (handle, FIONBIO, &one) == SOCKET_ERROR)
376     {
377       dbus_set_error (error, _dbus_error_from_errno (WSAGetLastError ()),
378                       "Failed to set socket %d:%d to nonblocking: %s", handle,
379                       _dbus_strerror (WSAGetLastError ()));
380       return FALSE;
381     }
382
383   return TRUE;
384 }
385
386
387 /**
388  * Like _dbus_write() but will use writev() if possible
389  * to write both buffers in sequence. The return value
390  * is the number of bytes written in the first buffer,
391  * plus the number written in the second. If the first
392  * buffer is written successfully and an error occurs
393  * writing the second, the number of bytes in the first
394  * is returned (i.e. the error is ignored), on systems that
395  * don't have writev. Handles EINTR for you.
396  * The second buffer may be #NULL.
397  *
398  * @param fd the file descriptor
399  * @param buffer1 first buffer
400  * @param start1 first byte to write in first buffer
401  * @param len1 number of bytes to write from first buffer
402  * @param buffer2 second buffer, or #NULL
403  * @param start2 first byte to write in second buffer
404  * @param len2 number of bytes to write in second buffer
405  * @returns total bytes written from both buffers, or -1 on error
406  */
407 int
408 _dbus_write_socket_two (int               fd,
409                         const DBusString *buffer1,
410                         int               start1,
411                         int               len1,
412                         const DBusString *buffer2,
413                         int               start2,
414                         int               len2)
415 {
416   WSABUF vectors[2];
417   const char *data1;
418   const char *data2;
419   int rc;
420   DWORD bytes_written;
421
422   _dbus_assert (buffer1 != NULL);
423   _dbus_assert (start1 >= 0);
424   _dbus_assert (start2 >= 0);
425   _dbus_assert (len1 >= 0);
426   _dbus_assert (len2 >= 0);
427
428
429   data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
430
431   if (buffer2 != NULL)
432     data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
433   else
434     {
435       data2 = NULL;
436       start2 = 0;
437       len2 = 0;
438     }
439
440   vectors[0].buf = (char*) data1;
441   vectors[0].len = len1;
442   vectors[1].buf = (char*) data2;
443   vectors[1].len = len2;
444
445  again:
446  
447   _dbus_verbose ("WSASend: len1+2=%d+%d fd=%d\n", len1, len2, fd);
448   rc = WSASend (fd, 
449                 vectors,
450                 data2 ? 2 : 1, 
451                 &bytes_written,
452                 0, 
453                 NULL, 
454                 NULL);
455                 
456   if (rc < 0)
457     {
458       DBUS_SOCKET_SET_ERRNO ();
459       _dbus_verbose ("WSASend: failed: %s\n", _dbus_strerror (errno));
460       bytes_written = -1;
461     }
462   else
463     _dbus_verbose ("WSASend: = %ld\n", bytes_written);
464     
465   if (bytes_written < 0 && errno == EINTR)
466     goto again;
467       
468   return bytes_written;
469 }
470
471 dbus_bool_t
472 _dbus_socket_is_invalid (int fd)
473 {
474     return fd == INVALID_SOCKET ? TRUE : FALSE;
475 }
476
477 #if 0
478
479 /**
480  * Opens the client side of a Windows named pipe. The connection D-BUS
481  * file descriptor index is returned. It is set up as nonblocking.
482  * 
483  * @param path the path to named pipe socket
484  * @param error return location for error code
485  * @returns connection D-BUS file descriptor or -1 on error
486  */
487 int
488 _dbus_connect_named_pipe (const char     *path,
489                           DBusError      *error)
490 {
491   _dbus_assert_not_reached ("not implemented");
492 }
493
494 #endif
495
496
497
498 void
499 _dbus_win_startup_winsock (void)
500 {
501   /* Straight from MSDN, deuglified */
502
503   static dbus_bool_t beenhere = FALSE;
504
505   WORD wVersionRequested;
506   WSADATA wsaData;
507   int err;
508
509   if (beenhere)
510     return;
511
512   wVersionRequested = MAKEWORD (2, 0);
513
514   err = WSAStartup (wVersionRequested, &wsaData);
515   if (err != 0)
516     {
517       _dbus_assert_not_reached ("Could not initialize WinSock");
518       _dbus_abort ();
519     }
520
521   /* Confirm that the WinSock DLL supports 2.0.  Note that if the DLL
522    * supports versions greater than 2.0 in addition to 2.0, it will
523    * still return 2.0 in wVersion since that is the version we
524    * requested.
525    */
526   if (LOBYTE (wsaData.wVersion) != 2 ||
527       HIBYTE (wsaData.wVersion) != 0)
528     {
529       _dbus_assert_not_reached ("No usable WinSock found");
530       _dbus_abort ();
531     }
532
533   beenhere = TRUE;
534 }
535
536
537
538
539
540
541
542
543
544 /************************************************************************
545  
546  UTF / string code
547  
548  ************************************************************************/
549
550 /**
551  * Measure the message length without terminating nul 
552  */
553 int _dbus_printf_string_upper_bound (const char *format,
554                                      va_list args)
555 {
556   /* MSVCRT's vsnprintf semantics are a bit different */
557   char buf[1024];
558   int bufsize;
559   int len;
560
561   bufsize = sizeof (buf);
562   len = _vsnprintf (buf, bufsize - 1, format, args);
563
564   while (len == -1) /* try again */
565     {
566       char *p;
567
568       bufsize *= 2;
569
570       p = malloc (bufsize);
571       len = _vsnprintf (p, bufsize - 1, format, args);
572       free (p);
573     }
574
575   return len;
576 }
577
578
579 /**
580  * Returns the UTF-16 form of a UTF-8 string. The result should be
581  * freed with dbus_free() when no longer needed.
582  *
583  * @param str the UTF-8 string
584  * @param error return location for error code
585  */
586 wchar_t *
587 _dbus_win_utf8_to_utf16 (const char *str,
588                          DBusError  *error)
589 {
590   DBusString s;
591   int n;
592   wchar_t *retval;
593
594   _dbus_string_init_const (&s, str);
595
596   if (!_dbus_string_validate_utf8 (&s, 0, _dbus_string_get_length (&s)))
597     {
598       dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid UTF-8");
599       return NULL;
600     }
601
602   n = MultiByteToWideChar (CP_UTF8, 0, str, -1, NULL, 0);
603
604   if (n == 0)
605     {
606       _dbus_win_set_error_from_win_error (error, GetLastError ());
607       return NULL;
608     }
609
610   retval = dbus_new (wchar_t, n);
611
612   if (!retval)
613     {
614       _DBUS_SET_OOM (error);
615       return NULL;
616     }
617
618   if (MultiByteToWideChar (CP_UTF8, 0, str, -1, retval, n) != n)
619     {
620       dbus_free (retval);
621       dbus_set_error_const (error, DBUS_ERROR_FAILED, "MultiByteToWideChar inconsistency");
622       return NULL;
623     }
624
625   return retval;
626 }
627
628 /**
629  * Returns the UTF-8 form of a UTF-16 string. The result should be
630  * freed with dbus_free() when no longer needed.
631  *
632  * @param str the UTF-16 string
633  * @param error return location for error code
634  */
635 char *
636 _dbus_win_utf16_to_utf8 (const wchar_t *str,
637                          DBusError     *error)
638 {
639   int n;
640   char *retval;
641
642   n = WideCharToMultiByte (CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
643
644   if (n == 0)
645     {
646       _dbus_win_set_error_from_win_error (error, GetLastError ());
647       return NULL;
648     }
649
650   retval = dbus_malloc (n);
651
652   if (!retval)
653     {
654       _DBUS_SET_OOM (error);
655       return NULL;
656     }
657
658   if (WideCharToMultiByte (CP_UTF8, 0, str, -1, retval, n, NULL, NULL) != n)
659     {
660       dbus_free (retval);
661       dbus_set_error_const (error, DBUS_ERROR_FAILED, "WideCharToMultiByte inconsistency");
662       return NULL;
663     }
664
665   return retval;
666 }
667
668
669
670
671
672
673 /************************************************************************
674  
675  
676  ************************************************************************/
677
678 dbus_bool_t
679 _dbus_win_account_to_sid (const wchar_t *waccount,
680                           void           **ppsid,
681                           DBusError       *error)
682 {
683   dbus_bool_t retval = FALSE;
684   DWORD sid_length, wdomain_length;
685   SID_NAME_USE use;
686   wchar_t *wdomain;
687
688   *ppsid = NULL;
689
690   sid_length = 0;
691   wdomain_length = 0;
692   if (!LookupAccountNameW (NULL, waccount, NULL, &sid_length,
693                            NULL, &wdomain_length, &use) &&
694       GetLastError () != ERROR_INSUFFICIENT_BUFFER)
695     {
696       _dbus_win_set_error_from_win_error (error, GetLastError ());
697       return FALSE;
698     }
699
700   *ppsid = dbus_malloc (sid_length);
701   if (!*ppsid)
702     {
703       _DBUS_SET_OOM (error);
704       return FALSE;
705     }
706
707   wdomain = dbus_new (wchar_t, wdomain_length);
708   if (!wdomain)
709     {
710       _DBUS_SET_OOM (error);
711       goto out1;
712     }
713
714   if (!LookupAccountNameW (NULL, waccount, (PSID) *ppsid, &sid_length,
715                            wdomain, &wdomain_length, &use))
716     {
717       _dbus_win_set_error_from_win_error (error, GetLastError ());
718       goto out2;
719     }
720
721   if (!IsValidSid ((PSID) *ppsid))
722     {
723       dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid SID");
724       goto out2;
725     }
726
727   retval = TRUE;
728
729 out2:
730   dbus_free (wdomain);
731 out1:
732   if (!retval)
733     {
734       dbus_free (*ppsid);
735       *ppsid = NULL;
736     }
737
738   return retval;
739 }
740
741 /** @} end of sysdeps-win */
742
743
744 /** Gets our UID
745  * @returns process UID
746  */
747 dbus_uid_t
748 _dbus_getuid (void)
749 {
750         return DBUS_UID_UNSET;
751 }
752
753 /**
754  * The only reason this is separate from _dbus_getpid() is to allow it
755  * on Windows for logging but not for other purposes.
756  * 
757  * @returns process ID to put in log messages
758  */
759 unsigned long
760 _dbus_pid_for_log (void)
761 {
762   return _dbus_getpid ();
763 }
764
765 /** Gets our SID
766  * @param points to sid buffer, need to be freed with LocalFree()
767  * @returns process sid
768  */
769 dbus_bool_t
770 _dbus_getsid(char **sid)
771 {
772   HANDLE process_token = NULL;
773   TOKEN_USER *token_user = NULL;
774   DWORD n;
775   PSID psid;
776   int retval = FALSE;
777   
778   if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &process_token)) 
779     {
780       _dbus_win_warn_win_error ("OpenProcessToken failed", GetLastError ());
781       goto failed;
782     }
783   if ((!GetTokenInformation (process_token, TokenUser, NULL, 0, &n)
784             && GetLastError () != ERROR_INSUFFICIENT_BUFFER)
785            || (token_user = alloca (n)) == NULL
786            || !GetTokenInformation (process_token, TokenUser, token_user, n, &n))
787     {
788       _dbus_win_warn_win_error ("GetTokenInformation failed", GetLastError ());
789       goto failed;
790     }
791   psid = token_user->User.Sid;
792   if (!IsValidSid (psid))
793     {
794       _dbus_verbose("%s invalid sid\n",__FUNCTION__);
795       goto failed;
796     }
797   if (!ConvertSidToStringSidA (psid, sid))
798     {
799       _dbus_verbose("%s invalid sid\n",__FUNCTION__);
800       goto failed;
801     }
802 //okay:
803   retval = TRUE;
804
805 failed:
806   if (process_token != NULL)
807     CloseHandle (process_token);
808
809   _dbus_verbose("_dbus_getsid() returns %d\n",retval);
810   return retval;
811 }
812
813
814 #ifdef DBUS_BUILD_TESTS
815 /** Gets our GID
816  * @returns process GID
817  */
818 dbus_gid_t
819 _dbus_getgid (void)
820 {
821         return DBUS_GID_UNSET;
822 }
823
824 #if 0
825 dbus_bool_t
826 _dbus_domain_test (const char *test_data_dir)
827 {
828   if (!_dbus_test_oom_handling ("spawn_nonexistent",
829                                 check_spawn_nonexistent,
830                                 NULL))
831     return FALSE;
832 }
833
834 #endif
835
836 #endif //DBUS_BUILD_TESTS
837
838 /************************************************************************
839  
840  pipes
841  
842  ************************************************************************/
843
844 /**
845  * Creates a full-duplex pipe (as in socketpair()).
846  * Sets both ends of the pipe nonblocking.
847  *
848  * @todo libdbus only uses this for the debug-pipe server, so in
849  * principle it could be in dbus-sysdeps-util.c, except that
850  * dbus-sysdeps-util.c isn't in libdbus when tests are enabled and the
851  * debug-pipe server is used.
852  * 
853  * @param fd1 return location for one end
854  * @param fd2 return location for the other end
855  * @param blocking #TRUE if pipe should be blocking
856  * @param error error return
857  * @returns #FALSE on failure (if error is set)
858  */
859 dbus_bool_t
860 _dbus_full_duplex_pipe (int        *fd1,
861                         int        *fd2,
862                         dbus_bool_t blocking,
863                         DBusError  *error)
864 {
865   SOCKET temp, socket1 = -1, socket2 = -1;
866   struct sockaddr_in saddr;
867   int len;
868   u_long arg;
869   fd_set read_set, write_set;
870   struct timeval tv;
871
872   _dbus_win_startup_winsock ();
873
874   temp = socket (AF_INET, SOCK_STREAM, 0);
875   if (temp == INVALID_SOCKET)
876     {
877       DBUS_SOCKET_SET_ERRNO ();
878       goto out0;
879     }
880
881   arg = 1;
882   if (ioctlsocket (temp, FIONBIO, &arg) == SOCKET_ERROR)
883     {
884       DBUS_SOCKET_SET_ERRNO ();
885       goto out0;
886     }
887
888   _DBUS_ZERO (saddr);
889   saddr.sin_family = AF_INET;
890   saddr.sin_port = 0;
891   saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
892
893   if (bind (temp, (struct sockaddr *)&saddr, sizeof (saddr)))
894     {
895       DBUS_SOCKET_SET_ERRNO ();
896       goto out0;
897     }
898
899   if (listen (temp, 1) == SOCKET_ERROR)
900     {
901       DBUS_SOCKET_SET_ERRNO ();
902       goto out0;
903     }
904
905   len = sizeof (saddr);
906   if (getsockname (temp, (struct sockaddr *)&saddr, &len))
907     {
908       DBUS_SOCKET_SET_ERRNO ();
909       goto out0;
910     }
911
912   socket1 = socket (AF_INET, SOCK_STREAM, 0);
913   if (socket1 == INVALID_SOCKET)
914     {
915       DBUS_SOCKET_SET_ERRNO ();
916       goto out0;
917     }
918
919   arg = 1;
920   if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR)
921     {
922       DBUS_SOCKET_SET_ERRNO ();
923       goto out1;
924     }
925
926   if (connect (socket1, (struct sockaddr  *)&saddr, len) != SOCKET_ERROR ||
927       WSAGetLastError () != WSAEWOULDBLOCK)
928     {
929       DBUS_SOCKET_SET_ERRNO ();
930       goto out1;
931     }
932
933   FD_ZERO (&read_set);
934   FD_SET (temp, &read_set);
935
936   tv.tv_sec = 0;
937   tv.tv_usec = 0;
938
939   if (select (0, &read_set, NULL, NULL, NULL) == SOCKET_ERROR)
940     {
941       DBUS_SOCKET_SET_ERRNO ();
942       goto out1;
943     }
944
945   _dbus_assert (FD_ISSET (temp, &read_set));
946
947   socket2 = accept (temp, (struct sockaddr *) &saddr, &len);
948   if (socket2 == INVALID_SOCKET)
949     {
950       DBUS_SOCKET_SET_ERRNO ();
951       goto out1;
952     }
953
954   FD_ZERO (&write_set);
955   FD_SET (socket1, &write_set);
956
957   tv.tv_sec = 0;
958   tv.tv_usec = 0;
959
960   if (select (0, NULL, &write_set, NULL, NULL) == SOCKET_ERROR)
961     {
962       DBUS_SOCKET_SET_ERRNO ();
963       goto out2;
964     }
965
966   _dbus_assert (FD_ISSET (socket1, &write_set));
967
968   if (blocking)
969     {
970       arg = 0;
971       if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR)
972         {
973           DBUS_SOCKET_SET_ERRNO ();
974           goto out2;
975         }
976
977       arg = 0;
978       if (ioctlsocket (socket2, FIONBIO, &arg) == SOCKET_ERROR)
979         {
980           DBUS_SOCKET_SET_ERRNO ();
981           goto out2;
982         }
983     }
984   else
985     {
986       arg = 1;
987       if (ioctlsocket (socket2, FIONBIO, &arg) == SOCKET_ERROR)
988         {
989           DBUS_SOCKET_SET_ERRNO ();
990           goto out2;
991         }
992     }
993
994   *fd1 = socket1;
995   *fd2 = socket2;
996
997   _dbus_verbose ("full-duplex pipe %d:%d <-> %d:%d\n",
998                  *fd1, socket1, *fd2, socket2);
999
1000   closesocket (temp);
1001
1002   return TRUE;
1003
1004 out2:
1005   closesocket (socket2);
1006 out1:
1007   closesocket (socket1);
1008 out0:
1009   closesocket (temp);
1010
1011   dbus_set_error (error, _dbus_error_from_errno (errno),
1012                   "Could not setup socket pair: %s",
1013                   _dbus_strerror (errno));
1014
1015   return FALSE;
1016 }
1017
1018 /**
1019  * Wrapper for poll().
1020  *
1021  * @param fds the file descriptors to poll
1022  * @param n_fds number of descriptors in the array
1023  * @param timeout_milliseconds timeout or -1 for infinite
1024  * @returns numbers of fds with revents, or <0 on error
1025  */
1026 int
1027 _dbus_poll (DBusPollFD *fds,
1028             int         n_fds,
1029             int         timeout_milliseconds)
1030 {
1031 #define USE_CHRIS_IMPL 0
1032
1033 #if USE_CHRIS_IMPL
1034
1035 #define DBUS_POLL_CHAR_BUFFER_SIZE 2000
1036   char msg[DBUS_POLL_CHAR_BUFFER_SIZE];
1037   char *msgp;
1038
1039   int ret = 0;
1040   int i;
1041   struct timeval tv;
1042   int ready;
1043
1044 #define DBUS_STACK_WSAEVENTS 256
1045   WSAEVENT eventsOnStack[DBUS_STACK_WSAEVENTS];
1046   WSAEVENT *pEvents = NULL;
1047   if (n_fds > DBUS_STACK_WSAEVENTS)
1048     pEvents = calloc(sizeof(WSAEVENT), n_fds);
1049   else
1050     pEvents = eventsOnStack;
1051
1052
1053 #ifdef DBUS_ENABLE_VERBOSE_MODE
1054   msgp = msg;
1055   msgp += sprintf (msgp, "WSAEventSelect: to=%d\n\t", timeout_milliseconds);
1056   for (i = 0; i < n_fds; i++)
1057     {
1058       static dbus_bool_t warned = FALSE;
1059       DBusPollFD *fdp = &fds[i];
1060
1061
1062       if (fdp->events & _DBUS_POLLIN)
1063         msgp += sprintf (msgp, "R:%d ", fdp->fd);
1064
1065       if (fdp->events & _DBUS_POLLOUT)
1066         msgp += sprintf (msgp, "W:%d ", fdp->fd);
1067
1068       msgp += sprintf (msgp, "E:%d\n\t", fdp->fd);
1069
1070       // FIXME: more robust code for long  msg
1071       //        create on heap when msg[] becomes too small
1072       if (msgp >= msg + DBUS_POLL_CHAR_BUFFER_SIZE)
1073         {
1074           _dbus_assert_not_reached ("buffer overflow in _dbus_poll");
1075         }
1076     }
1077
1078   msgp += sprintf (msgp, "\n");
1079   _dbus_verbose ("%s",msg);
1080 #endif
1081   for (i = 0; i < n_fds; i++)
1082     {
1083       DBusPollFD *fdp = &fds[i];
1084       WSAEVENT ev;
1085       long lNetworkEvents = FD_OOB;
1086
1087       ev = WSACreateEvent();
1088
1089       if (fdp->events & _DBUS_POLLIN)
1090         lNetworkEvents |= FD_READ | FD_ACCEPT | FD_CLOSE;
1091
1092       if (fdp->events & _DBUS_POLLOUT)
1093         lNetworkEvents |= FD_WRITE | FD_CONNECT;
1094
1095       WSAEventSelect(fdp->fd, ev, lNetworkEvents);
1096
1097       pEvents[i] = ev;
1098     }
1099
1100
1101   ready = WSAWaitForMultipleEvents (n_fds, pEvents, FALSE, timeout_milliseconds, FALSE);
1102
1103   if (DBUS_SOCKET_API_RETURNS_ERROR (ready))
1104     {
1105       DBUS_SOCKET_SET_ERRNO ();
1106       if (errno != EWOULDBLOCK)
1107         _dbus_verbose ("WSAWaitForMultipleEvents: failed: %s\n", strerror (errno));
1108       ret = -1;
1109     }
1110   else if (ready == WSA_WAIT_TIMEOUT)
1111     {
1112       _dbus_verbose ("WSAWaitForMultipleEvents: WSA_WAIT_TIMEOUT\n");
1113       ret = 0;
1114     }
1115   else if (ready >= WSA_WAIT_EVENT_0 && ready < (int)(WSA_WAIT_EVENT_0 + n_fds))
1116     {
1117       msgp = msg;
1118       msgp += sprintf (msgp, "WSAWaitForMultipleEvents: =%d\n\t", ready);
1119
1120       for (i = 0; i < n_fds; i++)
1121         {
1122           DBusPollFD *fdp = &fds[i];
1123           WSANETWORKEVENTS ne;
1124
1125           fdp->revents = 0;
1126
1127           WSAEnumNetworkEvents(fdp->fd, pEvents[i], &ne);
1128
1129           if (ne.lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
1130             fdp->revents |= _DBUS_POLLIN;
1131
1132           if (ne.lNetworkEvents & (FD_WRITE | FD_CONNECT))
1133             fdp->revents |= _DBUS_POLLOUT;
1134
1135           if (ne.lNetworkEvents & (FD_OOB))
1136             fdp->revents |= _DBUS_POLLERR;
1137
1138           if (ne.lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
1139               msgp += sprintf (msgp, "R:%d ", fdp->fd);
1140
1141           if (ne.lNetworkEvents & (FD_WRITE | FD_CONNECT))
1142               msgp += sprintf (msgp, "W:%d ", fdp->fd);
1143
1144           if (ne.lNetworkEvents & (FD_OOB))
1145               msgp += sprintf (msgp, "E:%d ", fdp->fd);
1146
1147           msgp += sprintf (msgp, "lNetworkEvents:%d ", ne.lNetworkEvents);
1148
1149           if(ne.lNetworkEvents)
1150             ret++;
1151
1152           WSAEventSelect(fdp->fd, pEvents[i], 0);
1153         }
1154
1155       msgp += sprintf (msgp, "\n");
1156       _dbus_verbose ("%s",msg);
1157     }
1158   else
1159     {
1160       _dbus_verbose ("WSAWaitForMultipleEvents: failed for unknown reason!");
1161       ret = -1;
1162     }
1163
1164   for(i = 0; i < n_fds; i++)
1165     {
1166       WSACloseEvent(pEvents[i]);
1167     }
1168
1169   if (n_fds > DBUS_STACK_WSAEVENTS)
1170     free(pEvents);
1171
1172   return ret;
1173
1174 #else   /* USE_CHRIS_IMPL */
1175
1176 #define DBUS_POLL_CHAR_BUFFER_SIZE 2000
1177   char msg[DBUS_POLL_CHAR_BUFFER_SIZE];
1178   char *msgp;
1179
1180   fd_set read_set, write_set, err_set;
1181   int max_fd = 0;
1182   int i;
1183   struct timeval tv;
1184   int ready;
1185
1186   FD_ZERO (&read_set);
1187   FD_ZERO (&write_set);
1188   FD_ZERO (&err_set);
1189
1190
1191 #ifdef DBUS_ENABLE_VERBOSE_MODE
1192   msgp = msg;
1193   msgp += sprintf (msgp, "select: to=%d\n\t", timeout_milliseconds);
1194   for (i = 0; i < n_fds; i++)
1195     {
1196       static dbus_bool_t warned = FALSE;
1197       DBusPollFD *fdp = &fds[i];
1198
1199
1200       if (fdp->events & _DBUS_POLLIN)
1201         msgp += sprintf (msgp, "R:%d ", fdp->fd);
1202
1203       if (fdp->events & _DBUS_POLLOUT)
1204         msgp += sprintf (msgp, "W:%d ", fdp->fd);
1205
1206       msgp += sprintf (msgp, "E:%d\n\t", fdp->fd);
1207
1208       // FIXME: more robust code for long  msg
1209       //        create on heap when msg[] becomes too small
1210       if (msgp >= msg + DBUS_POLL_CHAR_BUFFER_SIZE)
1211         {
1212           _dbus_assert_not_reached ("buffer overflow in _dbus_poll");
1213         }
1214     }
1215
1216   msgp += sprintf (msgp, "\n");
1217   _dbus_verbose ("%s",msg);
1218 #endif
1219   for (i = 0; i < n_fds; i++)
1220     {
1221       DBusPollFD *fdp = &fds[i]; 
1222
1223       if (fdp->events & _DBUS_POLLIN)
1224         FD_SET (fdp->fd, &read_set);
1225
1226       if (fdp->events & _DBUS_POLLOUT)
1227         FD_SET (fdp->fd, &write_set);
1228
1229       FD_SET (fdp->fd, &err_set);
1230
1231       max_fd = MAX (max_fd, fdp->fd);
1232     }
1233
1234
1235   tv.tv_sec = timeout_milliseconds / 1000;
1236   tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
1237
1238   ready = select (max_fd + 1, &read_set, &write_set, &err_set,
1239                   timeout_milliseconds < 0 ? NULL : &tv);
1240
1241   if (DBUS_SOCKET_API_RETURNS_ERROR (ready))
1242     {
1243       DBUS_SOCKET_SET_ERRNO ();
1244       if (errno != EWOULDBLOCK)
1245         _dbus_verbose ("select: failed: %s\n", _dbus_strerror (errno));
1246     }
1247   else if (ready == 0)
1248     _dbus_verbose ("select: = 0\n");
1249   else
1250     if (ready > 0)
1251       {
1252 #ifdef DBUS_ENABLE_VERBOSE_MODE
1253         msgp = msg;
1254         msgp += sprintf (msgp, "select: = %d:\n\t", ready);
1255
1256         for (i = 0; i < n_fds; i++)
1257           {
1258             DBusPollFD *fdp = &fds[i];
1259
1260             if (FD_ISSET (fdp->fd, &read_set))
1261               msgp += sprintf (msgp, "R:%d ", fdp->fd);
1262
1263             if (FD_ISSET (fdp->fd, &write_set))
1264               msgp += sprintf (msgp, "W:%d ", fdp->fd);
1265
1266             if (FD_ISSET (fdp->fd, &err_set))
1267               msgp += sprintf (msgp, "E:%d\n\t", fdp->fd);
1268           }
1269         msgp += sprintf (msgp, "\n");
1270         _dbus_verbose ("%s",msg);
1271 #endif
1272
1273         for (i = 0; i < n_fds; i++)
1274           {
1275             DBusPollFD *fdp = &fds[i];
1276
1277             fdp->revents = 0;
1278
1279             if (FD_ISSET (fdp->fd, &read_set))
1280               fdp->revents |= _DBUS_POLLIN;
1281
1282             if (FD_ISSET (fdp->fd, &write_set))
1283               fdp->revents |= _DBUS_POLLOUT;
1284
1285             if (FD_ISSET (fdp->fd, &err_set))
1286               fdp->revents |= _DBUS_POLLERR;
1287           }
1288       }
1289   return ready;
1290 #endif  /* USE_CHRIS_IMPL */
1291 }
1292
1293
1294
1295
1296 /******************************************************************************
1297  
1298 Original CVS version of dbus-sysdeps.c
1299  
1300 ******************************************************************************/
1301 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
1302 /* dbus-sysdeps.c Wrappers around system/libc features (internal to D-Bus implementation)
1303  * 
1304  * Copyright (C) 2002, 2003  Red Hat, Inc.
1305  * Copyright (C) 2003 CodeFactory AB
1306  * Copyright (C) 2005 Novell, Inc.
1307  *
1308  * Licensed under the Academic Free License version 2.1
1309  * 
1310  * This program is free software; you can redistribute it and/or modify
1311  * it under the terms of the GNU General Public License as published by
1312  * the Free Software Foundation; either version 2 of the License, or
1313  * (at your option) any later version.
1314  *
1315  * This program is distributed in the hope that it will be useful,
1316  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1317  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1318  * GNU General Public License for more details.
1319  * 
1320  * You should have received a copy of the GNU General Public License
1321  * along with this program; if not, write to the Free Software
1322  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
1323  *
1324  */
1325
1326
1327 /**
1328  * Exit the process, returning the given value.
1329  *
1330  * @param code the exit code
1331  */
1332 void
1333 _dbus_exit (int code)
1334 {
1335   _exit (code);
1336 }
1337
1338 /**
1339  * Creates a socket and connects to a socket at the given host 
1340  * and port. The connection fd is returned, and is set up as
1341  * nonblocking.
1342  *
1343  * @param host the host name to connect to
1344  * @param port the port to connect to
1345  * @param family the address family to listen on, NULL for all
1346  * @param error return location for error code
1347  * @returns connection file descriptor or -1 on error
1348  */
1349 int
1350 _dbus_connect_tcp_socket (const char     *host,
1351                           const char     *port,
1352                           const char     *family,
1353                           DBusError      *error)
1354 {
1355   return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1356 }
1357
1358 int
1359 _dbus_connect_tcp_socket_with_nonce (const char     *host,
1360                                      const char     *port,
1361                                      const char     *family,
1362                                      const char     *noncefile,
1363                                      DBusError      *error)
1364 {
1365   int fd = -1, res;
1366   struct addrinfo hints;
1367   struct addrinfo *ai, *tmp;
1368
1369   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1370
1371   _dbus_win_startup_winsock ();
1372
1373   fd = socket (AF_INET, SOCK_STREAM, 0);
1374
1375   if (DBUS_SOCKET_IS_INVALID (fd))
1376     {
1377       DBUS_SOCKET_SET_ERRNO ();
1378       dbus_set_error (error,
1379                       _dbus_error_from_errno (errno),
1380                       "Failed to create socket: %s",
1381                       _dbus_strerror (errno));
1382
1383       return -1;
1384     }
1385
1386   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1387
1388   _DBUS_ZERO (hints);
1389
1390   if (!family)
1391     hints.ai_family = AF_UNSPEC;
1392   else if (!strcmp(family, "ipv4"))
1393     hints.ai_family = AF_INET;
1394   else if (!strcmp(family, "ipv6"))
1395     hints.ai_family = AF_INET6;
1396   else
1397     {
1398       dbus_set_error (error,
1399                       _dbus_error_from_errno (errno),
1400                       "Unknown address family %s", family);
1401       return -1;
1402     }
1403   hints.ai_protocol = IPPROTO_TCP;
1404   hints.ai_socktype = SOCK_STREAM;
1405 #ifdef AI_ADDRCONFIG
1406   hints.ai_flags = AI_ADDRCONFIG;
1407 #else
1408   hints.ai_flags = 0;
1409 #endif
1410
1411   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1412     {
1413       dbus_set_error (error,
1414                       _dbus_error_from_errno (errno),
1415                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1416                       host, port, gai_strerror(res), res);
1417       closesocket (fd);
1418       return -1;
1419     }
1420
1421   tmp = ai;
1422   while (tmp)
1423     {
1424       if ((fd = socket (tmp->ai_family, SOCK_STREAM, 0)) < 0)
1425         {
1426           freeaddrinfo(ai);
1427       dbus_set_error (error,
1428                       _dbus_error_from_errno (errno),
1429                          "Failed to open socket: %s",
1430                          _dbus_strerror (errno));
1431           return -1;
1432         }
1433       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1434
1435       if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) != 0)
1436         {
1437           closesocket(fd);
1438       fd = -1;
1439           tmp = tmp->ai_next;
1440           continue;
1441         }
1442
1443       break;
1444     }
1445   freeaddrinfo(ai);
1446
1447   if (fd == -1)
1448     {
1449       dbus_set_error (error,
1450                       _dbus_error_from_errno (errno),
1451                       "Failed to connect to socket \"%s:%s\" %s",
1452                       host, port, _dbus_strerror(errno));
1453       return -1;
1454     }
1455
1456   if ( noncefile != NULL )
1457     {
1458       DBusString noncefileStr;
1459       dbus_bool_t ret;
1460       if (!_dbus_string_init (&noncefileStr) ||
1461           !_dbus_string_append(&noncefileStr, noncefile))
1462         {
1463           closesocket (fd);
1464           dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1465           return -1;
1466        }
1467
1468       ret = _dbus_send_nonce (fd, &noncefileStr, error);
1469
1470       _dbus_string_free (&noncefileStr);
1471
1472       if (!ret)
1473     {
1474       closesocket (fd);
1475           return -1;
1476         }
1477     }
1478
1479   if (!_dbus_set_fd_nonblocking (fd, error) )
1480     {
1481       closesocket (fd);
1482       return -1;
1483     }
1484
1485   return fd;
1486 }
1487
1488
1489 void
1490 _dbus_daemon_init(const char *host, dbus_uint32_t port);
1491
1492 /**
1493  * Creates a socket and binds it to the given path, then listens on
1494  * the socket. The socket is set to be nonblocking.  In case of port=0
1495  * a random free port is used and returned in the port parameter.
1496  * If inaddr_any is specified, the hostname is ignored.
1497  *
1498  * @param host the host name to listen on
1499  * @param port the port to listen on, if zero a free port will be used 
1500  * @param family the address family to listen on, NULL for all
1501  * @param retport string to return the actual port listened on
1502  * @param fds_p location to store returned file descriptors
1503  * @param error return location for errors
1504  * @returns the number of listening file descriptors or -1 on error
1505  */
1506
1507 int
1508 _dbus_listen_tcp_socket (const char     *host,
1509                          const char     *port,
1510                          const char     *family,
1511                          DBusString     *retport,
1512                          int           **fds_p,
1513                          DBusError      *error)
1514 {
1515   int nlisten_fd = 0, *listen_fd = NULL, res, i, port_num = -1;
1516   struct addrinfo hints;
1517   struct addrinfo *ai, *tmp;
1518
1519   // On Vista, sockaddr_gen must be a sockaddr_in6, and not a sockaddr_in6_old
1520   //That's required for family == IPv6(which is the default on Vista if family is not given)
1521   //So we use our own union instead of sockaddr_gen:
1522
1523   typedef union {
1524         struct sockaddr Address;
1525         struct sockaddr_in AddressIn;
1526         struct sockaddr_in6 AddressIn6;
1527   } mysockaddr_gen;
1528
1529   *fds_p = NULL;
1530   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1531
1532   _dbus_win_startup_winsock ();
1533
1534   _DBUS_ZERO (hints);
1535
1536   if (!family)
1537     hints.ai_family = AF_UNSPEC;
1538   else if (!strcmp(family, "ipv4"))
1539     hints.ai_family = AF_INET;
1540   else if (!strcmp(family, "ipv6"))
1541     hints.ai_family = AF_INET6;
1542   else
1543     {
1544       dbus_set_error (error,
1545                       _dbus_error_from_errno (errno),
1546                       "Unknown address family %s", family);
1547       return -1;
1548     }
1549
1550   hints.ai_protocol = IPPROTO_TCP;
1551   hints.ai_socktype = SOCK_STREAM;
1552 #ifdef AI_ADDRCONFIG
1553   hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1554 #else
1555   hints.ai_flags = AI_PASSIVE;
1556 #endif
1557
1558  redo_lookup_with_port:
1559   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1560     {
1561       dbus_set_error (error,
1562                       _dbus_error_from_errno (errno),
1563                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1564                       host ? host : "*", port, gai_strerror(res), res);
1565       return -1;
1566     }
1567
1568   tmp = ai;
1569   while (tmp)
1570     {
1571       int fd = -1, *newlisten_fd;
1572       if ((fd = socket (tmp->ai_family, SOCK_STREAM, 0)) < 0)
1573         {
1574           dbus_set_error (error,
1575                           _dbus_error_from_errno (errno),
1576                          "Failed to open socket: %s",
1577                          _dbus_strerror (errno));
1578           goto failed;
1579         }
1580       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1581
1582       if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) == SOCKET_ERROR)
1583         {
1584           closesocket (fd);
1585           dbus_set_error (error, _dbus_error_from_errno (errno),
1586                           "Failed to bind socket \"%s:%s\": %s",
1587                           host ? host : "*", port, _dbus_strerror (errno));
1588           goto failed;
1589     }
1590
1591       if (listen (fd, 30 /* backlog */) == SOCKET_ERROR)
1592         {
1593           closesocket (fd);
1594           dbus_set_error (error, _dbus_error_from_errno (errno),
1595                           "Failed to listen on socket \"%s:%s\": %s",
1596                           host ? host : "*", port, _dbus_strerror (errno));
1597           goto failed;
1598         }
1599
1600       newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
1601       if (!newlisten_fd)
1602     {
1603           closesocket (fd);
1604       dbus_set_error (error, _dbus_error_from_errno (errno),
1605                           "Failed to allocate file handle array: %s",
1606                           _dbus_strerror (errno));
1607           goto failed;
1608     }
1609       listen_fd = newlisten_fd;
1610       listen_fd[nlisten_fd] = fd;
1611       nlisten_fd++;
1612
1613       if (!_dbus_string_get_length(retport))
1614         {
1615           /* If the user didn't specify a port, or used 0, then
1616              the kernel chooses a port. After the first address
1617              is bound to, we need to force all remaining addresses
1618              to use the same port */
1619           if (!port || !strcmp(port, "0"))
1620             {
1621               mysockaddr_gen addr;
1622               socklen_t addrlen = sizeof(addr);
1623               char portbuf[10];
1624
1625               if ((res = getsockname(fd, &addr.Address, &addrlen)) != 0)
1626     {
1627       dbus_set_error (error, _dbus_error_from_errno (errno),
1628                                   "Failed to resolve port \"%s:%s\": %s (%d)",
1629                                   host ? host : "*", port, gai_strerror(res), res);
1630                   goto failed;
1631                 }
1632               snprintf( portbuf, sizeof( portbuf ) - 1, "%d", addr.AddressIn.sin_port );
1633               if (!_dbus_string_append(retport, portbuf))
1634                 {
1635                   dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1636                   goto failed;
1637     }
1638
1639               /* Release current address list & redo lookup */
1640               port = _dbus_string_get_const_data(retport);
1641               freeaddrinfo(ai);
1642               goto redo_lookup_with_port;
1643             }
1644           else
1645             {
1646               if (!_dbus_string_append(retport, port))
1647                 {
1648                     dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1649                     goto failed;
1650                 }
1651             }
1652         }
1653   
1654       tmp = tmp->ai_next;
1655     }
1656   freeaddrinfo(ai);
1657   ai = NULL;
1658
1659   if (!nlisten_fd)
1660     {
1661       errno = WSAEADDRINUSE;
1662       dbus_set_error (error, _dbus_error_from_errno (errno),
1663                       "Failed to bind socket \"%s:%s\": %s",
1664                       host ? host : "*", port, _dbus_strerror (errno));
1665       return -1;
1666     }
1667
1668   sscanf(_dbus_string_get_const_data(retport), "%d", &port_num);
1669   _dbus_daemon_init(host, port_num);
1670
1671   for (i = 0 ; i < nlisten_fd ; i++)
1672     {
1673       if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1674         {
1675           goto failed;
1676         }
1677     }
1678
1679   *fds_p = listen_fd;
1680
1681   return nlisten_fd;
1682
1683  failed:
1684   if (ai)
1685     freeaddrinfo(ai);
1686   for (i = 0 ; i < nlisten_fd ; i++)
1687     closesocket (listen_fd[i]);
1688   dbus_free(listen_fd);
1689   return -1;
1690 }
1691
1692
1693 /**
1694  * Accepts a connection on a listening socket.
1695  * Handles EINTR for you.
1696  *
1697  * @param listen_fd the listen file descriptor
1698  * @returns the connection fd of the client, or -1 on error
1699  */
1700 int
1701 _dbus_accept  (int listen_fd)
1702 {
1703   int client_fd;
1704
1705  retry:
1706   client_fd = accept (listen_fd, NULL, NULL);
1707
1708   if (DBUS_SOCKET_IS_INVALID (client_fd))
1709     {
1710       DBUS_SOCKET_SET_ERRNO ();
1711       if (errno == EINTR)
1712         goto retry;
1713     }
1714
1715   _dbus_verbose ("client fd %d accepted\n", client_fd);
1716   
1717   return client_fd;
1718 }
1719
1720
1721
1722
1723 dbus_bool_t
1724 _dbus_send_credentials_socket (int            handle,
1725                         DBusError      *error)
1726 {
1727 /* FIXME: for the session bus credentials shouldn't matter (?), but
1728  * for the system bus they are presumably essential. A rough outline
1729  * of a way to implement the credential transfer would be this:
1730  *
1731  * client waits to *read* a byte.
1732  *
1733  * server creates a named pipe with a random name, sends a byte
1734  * contining its length, and its name.
1735  *
1736  * client reads the name, connects to it (using Win32 API).
1737  *
1738  * server waits for connection to the named pipe, then calls
1739  * ImpersonateNamedPipeClient(), notes its now-current credentials,
1740  * calls RevertToSelf(), closes its handles to the named pipe, and
1741  * is done. (Maybe there is some other way to get the SID of a named
1742  * pipe client without having to use impersonation?)
1743  *
1744  * client closes its handles and is done.
1745  * 
1746  * Ralf: Why not sending credentials over the given this connection ?
1747  * Using named pipes makes it impossible to be connected from a unix client.  
1748  *
1749  */
1750   int bytes_written;
1751   DBusString buf; 
1752
1753   _dbus_string_init_const_len (&buf, "\0", 1);
1754 again:
1755   bytes_written = _dbus_write_socket (handle, &buf, 0, 1 );
1756
1757   if (bytes_written < 0 && errno == EINTR)
1758     goto again;
1759
1760   if (bytes_written < 0)
1761     {
1762       dbus_set_error (error, _dbus_error_from_errno (errno),
1763                       "Failed to write credentials byte: %s",
1764                      _dbus_strerror (errno));
1765       return FALSE;
1766     }
1767   else if (bytes_written == 0)
1768     {
1769       dbus_set_error (error, DBUS_ERROR_IO_ERROR,
1770                       "wrote zero bytes writing credentials byte");
1771       return FALSE;
1772     }
1773   else
1774     {
1775       _dbus_assert (bytes_written == 1);
1776       _dbus_verbose ("wrote 1 zero byte, credential sending isn't implemented yet\n");
1777       return TRUE;
1778     }
1779   return TRUE;
1780 }
1781
1782 /**
1783  * Reads a single byte which must be nul (an error occurs otherwise),
1784  * and reads unix credentials if available. Fills in pid/uid/gid with
1785  * -1 if no credentials are available. Return value indicates whether
1786  * a byte was read, not whether we got valid credentials. On some
1787  * systems, such as Linux, reading/writing the byte isn't actually
1788  * required, but we do it anyway just to avoid multiple codepaths.
1789  * 
1790  * Fails if no byte is available, so you must select() first.
1791  *
1792  * The point of the byte is that on some systems we have to
1793  * use sendmsg()/recvmsg() to transmit credentials.
1794  *
1795  * @param client_fd the client file descriptor
1796  * @param credentials struct to fill with credentials of client
1797  * @param error location to store error code
1798  * @returns #TRUE on success
1799  */
1800 dbus_bool_t
1801 _dbus_read_credentials_socket  (int              handle,
1802                                 DBusCredentials *credentials,
1803                                 DBusError       *error)
1804 {
1805   int bytes_read = 0;
1806   DBusString buf;
1807   
1808   // could fail due too OOM
1809   if (_dbus_string_init(&buf))
1810     {
1811       bytes_read = _dbus_read_socket(handle, &buf, 1 );
1812
1813       if (bytes_read > 0) 
1814         _dbus_verbose("got one zero byte from server");
1815
1816       _dbus_string_free(&buf);
1817     }
1818
1819   _dbus_credentials_add_from_current_process (credentials);
1820   _dbus_verbose("FIXME: get faked credentials from current process");
1821
1822   return TRUE;
1823 }
1824
1825 /**
1826 * Checks to make sure the given directory is 
1827 * private to the user 
1828 *
1829 * @param dir the name of the directory
1830 * @param error error return
1831 * @returns #FALSE on failure
1832 **/
1833 dbus_bool_t
1834 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
1835 {
1836   const char *directory;
1837   struct stat sb;
1838
1839   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1840
1841   return TRUE;
1842 }
1843
1844
1845 /**
1846  * Appends the given filename to the given directory.
1847  *
1848  * @todo it might be cute to collapse multiple '/' such as "foo//"
1849  * concat "//bar"
1850  *
1851  * @param dir the directory name
1852  * @param next_component the filename
1853  * @returns #TRUE on success
1854  */
1855 dbus_bool_t
1856 _dbus_concat_dir_and_file (DBusString       *dir,
1857                            const DBusString *next_component)
1858 {
1859   dbus_bool_t dir_ends_in_slash;
1860   dbus_bool_t file_starts_with_slash;
1861
1862   if (_dbus_string_get_length (dir) == 0 ||
1863       _dbus_string_get_length (next_component) == 0)
1864     return TRUE;
1865
1866   dir_ends_in_slash =
1867     ('/' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1) ||
1868      '\\' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1));
1869
1870   file_starts_with_slash =
1871     ('/' == _dbus_string_get_byte (next_component, 0) ||
1872      '\\' == _dbus_string_get_byte (next_component, 0));
1873
1874   if (dir_ends_in_slash && file_starts_with_slash)
1875     {
1876       _dbus_string_shorten (dir, 1);
1877     }
1878   else if (!(dir_ends_in_slash || file_starts_with_slash))
1879     {
1880       if (!_dbus_string_append_byte (dir, '\\'))
1881         return FALSE;
1882     }
1883
1884   return _dbus_string_copy (next_component, 0, dir,
1885                             _dbus_string_get_length (dir));
1886 }
1887
1888 /*---------------- DBusCredentials ----------------------------------
1889
1890 /**
1891  * Adds the credentials corresponding to the given username.
1892  *
1893  * @param credentials credentials to fill in 
1894  * @param username the username
1895  * @returns #TRUE if the username existed and we got some credentials
1896  */
1897 dbus_bool_t
1898 _dbus_credentials_add_from_user (DBusCredentials  *credentials,
1899                                      const DBusString *username)
1900 {
1901   return _dbus_credentials_add_windows_sid (credentials,
1902                     _dbus_string_get_const_data(username));
1903 }
1904
1905 /**
1906  * Adds the credentials of the current process to the
1907  * passed-in credentials object.
1908  *
1909  * @param credentials credentials to add to
1910  * @returns #FALSE if no memory; does not properly roll back on failure, so only some credentials may have been added
1911  */
1912
1913 dbus_bool_t
1914 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
1915 {
1916   dbus_bool_t retval = FALSE;
1917   char *sid = NULL;
1918
1919   if (!_dbus_getsid(&sid))
1920     goto failed;
1921
1922   if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
1923     goto failed;
1924
1925   if (!_dbus_credentials_add_windows_sid (credentials,sid))
1926     goto failed;
1927
1928   retval = TRUE;
1929   goto end;
1930 failed:
1931   retval = FALSE;
1932 end:
1933   if (sid)
1934     LocalFree(sid);
1935
1936   return retval;
1937 }
1938
1939 /**
1940  * Append to the string the identity we would like to have when we
1941  * authenticate, on UNIX this is the current process UID and on
1942  * Windows something else, probably a Windows SID string.  No escaping
1943  * is required, that is done in dbus-auth.c. The username here
1944  * need not be anything human-readable, it can be the machine-readable
1945  * form i.e. a user id.
1946  * 
1947  * @param str the string to append to
1948  * @returns #FALSE on no memory
1949  * @todo to which class belongs this 
1950  */
1951 dbus_bool_t
1952 _dbus_append_user_from_current_process (DBusString *str)
1953 {
1954   dbus_bool_t retval = FALSE;
1955   char *sid = NULL;
1956
1957   if (!_dbus_getsid(&sid))
1958     return FALSE;
1959
1960   retval = _dbus_string_append (str,sid);
1961
1962   LocalFree(sid);
1963   return retval;
1964 }
1965
1966 /**
1967  * Gets our process ID
1968  * @returns process ID
1969  */
1970 dbus_pid_t
1971 _dbus_getpid (void)
1972 {
1973   return GetCurrentProcessId ();
1974 }
1975
1976 /** nanoseconds in a second */
1977 #define NANOSECONDS_PER_SECOND       1000000000
1978 /** microseconds in a second */
1979 #define MICROSECONDS_PER_SECOND      1000000
1980 /** milliseconds in a second */
1981 #define MILLISECONDS_PER_SECOND      1000
1982 /** nanoseconds in a millisecond */
1983 #define NANOSECONDS_PER_MILLISECOND  1000000
1984 /** microseconds in a millisecond */
1985 #define MICROSECONDS_PER_MILLISECOND 1000
1986
1987 /**
1988  * Sleeps the given number of milliseconds.
1989  * @param milliseconds number of milliseconds
1990  */
1991 void
1992 _dbus_sleep_milliseconds (int milliseconds)
1993 {
1994   Sleep (milliseconds);
1995 }
1996
1997
1998 /**
1999  * Get current time, as in gettimeofday().
2000  *
2001  * @param tv_sec return location for number of seconds
2002  * @param tv_usec return location for number of microseconds
2003  */
2004 void
2005 _dbus_get_current_time (long *tv_sec,
2006                         long *tv_usec)
2007 {
2008   FILETIME ft;
2009   dbus_uint64_t *time64 = (dbus_uint64_t *) &ft;
2010
2011   GetSystemTimeAsFileTime (&ft);
2012
2013   /* Convert from 100s of nanoseconds since 1601-01-01
2014   * to Unix epoch. Yes, this is Y2038 unsafe.
2015   */
2016   *time64 -= DBUS_INT64_CONSTANT (116444736000000000);
2017   *time64 /= 10;
2018
2019   if (tv_sec)
2020     *tv_sec = *time64 / 1000000;
2021
2022   if (tv_usec)
2023     *tv_usec = *time64 % 1000000;
2024 }
2025
2026
2027 /**
2028  * signal (SIGPIPE, SIG_IGN);
2029  */
2030 void
2031 _dbus_disable_sigpipe (void)
2032 {
2033 }
2034
2035
2036 /* _dbus_read() is static on Windows, only used below in this file.
2037  */
2038 static int
2039 _dbus_read (int               fd,
2040             DBusString       *buffer,
2041             int               count)
2042 {
2043   int bytes_read;
2044   int start;
2045   char *data;
2046
2047   _dbus_assert (count >= 0);
2048
2049   start = _dbus_string_get_length (buffer);
2050
2051   if (!_dbus_string_lengthen (buffer, count))
2052     {
2053       errno = ENOMEM;
2054       return -1;
2055     }
2056
2057   data = _dbus_string_get_data_len (buffer, start, count);
2058
2059  again:
2060
2061   bytes_read = _read (fd, data, count);
2062
2063   if (bytes_read < 0)
2064     {
2065       if (errno == EINTR)
2066         goto again;
2067       else
2068         {
2069           /* put length back (note that this doesn't actually realloc anything) */
2070           _dbus_string_set_length (buffer, start);
2071           return -1;
2072         }
2073     }
2074   else
2075     {
2076       /* put length back (doesn't actually realloc) */
2077       _dbus_string_set_length (buffer, start + bytes_read);
2078
2079 #if 0
2080       if (bytes_read > 0)
2081         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
2082 #endif
2083
2084       return bytes_read;
2085     }
2086 }
2087
2088 /**
2089  * Appends the contents of the given file to the string,
2090  * returning error code. At the moment, won't open a file
2091  * more than a megabyte in size.
2092  *
2093  * @param str the string to append to
2094  * @param filename filename to load
2095  * @param error place to set an error
2096  * @returns #FALSE if error was set
2097  */
2098 dbus_bool_t
2099 _dbus_file_get_contents (DBusString       *str,
2100                          const DBusString *filename,
2101                          DBusError        *error)
2102 {
2103   int fd;
2104   struct _stati64 sb;
2105   int orig_len;
2106   int total;
2107   const char *filename_c;
2108
2109   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2110
2111   filename_c = _dbus_string_get_const_data (filename);
2112
2113   fd = _open (filename_c, O_RDONLY | O_BINARY);
2114   if (fd < 0)
2115     {
2116       dbus_set_error (error, _dbus_error_from_errno (errno),
2117                       "Failed to open \"%s\": %s",
2118                       filename_c,
2119                       strerror (errno));
2120       return FALSE;
2121     }
2122
2123   _dbus_verbose ("file %s fd %d opened\n", filename_c, fd);
2124
2125   if (_fstati64 (fd, &sb) < 0)
2126     {
2127       dbus_set_error (error, _dbus_error_from_errno (errno),
2128                       "Failed to stat \"%s\": %s",
2129                       filename_c,
2130                       strerror (errno));
2131
2132       _dbus_verbose ("fstat() failed: %s",
2133                      strerror (errno));
2134
2135       _close (fd);
2136
2137       return FALSE;
2138     }
2139
2140   if (sb.st_size > _DBUS_ONE_MEGABYTE)
2141     {
2142       dbus_set_error (error, DBUS_ERROR_FAILED,
2143                       "File size %lu of \"%s\" is too large.",
2144                       (unsigned long) sb.st_size, filename_c);
2145       _close (fd);
2146       return FALSE;
2147     }
2148
2149   total = 0;
2150   orig_len = _dbus_string_get_length (str);
2151   if (sb.st_size > 0 && S_ISREG (sb.st_mode))
2152     {
2153       int bytes_read;
2154
2155       while (total < (int) sb.st_size)
2156         {
2157           bytes_read = _dbus_read (fd, str, sb.st_size - total);
2158           if (bytes_read <= 0)
2159             {
2160               dbus_set_error (error, _dbus_error_from_errno (errno),
2161                               "Error reading \"%s\": %s",
2162                               filename_c,
2163                               strerror (errno));
2164
2165               _dbus_verbose ("read() failed: %s",
2166                              strerror (errno));
2167
2168               _close (fd);
2169               _dbus_string_set_length (str, orig_len);
2170               return FALSE;
2171             }
2172           else
2173             total += bytes_read;
2174         }
2175
2176       _close (fd);
2177       return TRUE;
2178     }
2179   else if (sb.st_size != 0)
2180     {
2181       _dbus_verbose ("Can only open regular files at the moment.\n");
2182       dbus_set_error (error, DBUS_ERROR_FAILED,
2183                       "\"%s\" is not a regular file",
2184                       filename_c);
2185       _close (fd);
2186       return FALSE;
2187     }
2188   else
2189     {
2190       _close (fd);
2191       return TRUE;
2192     }
2193 }
2194
2195 /**
2196  * Writes a string out to a file. If the file exists,
2197  * it will be atomically overwritten by the new data.
2198  *
2199  * @param str the string to write out
2200  * @param filename the file to save string to
2201  * @param error error to be filled in on failure
2202  * @returns #FALSE on failure
2203  */
2204 dbus_bool_t
2205 _dbus_string_save_to_file (const DBusString *str,
2206                            const DBusString *filename,
2207                            DBusError        *error)
2208 {
2209   int fd;
2210   int bytes_to_write;
2211   const char *filename_c;
2212   DBusString tmp_filename;
2213   const char *tmp_filename_c;
2214   int total;
2215   const char *str_c;
2216   dbus_bool_t need_unlink;
2217   dbus_bool_t retval;
2218
2219   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2220
2221   fd = -1;
2222   retval = FALSE;
2223   need_unlink = FALSE;
2224
2225   if (!_dbus_string_init (&tmp_filename))
2226     {
2227       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2228       return FALSE;
2229     }
2230
2231   if (!_dbus_string_copy (filename, 0, &tmp_filename, 0))
2232     {
2233       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2234       _dbus_string_free (&tmp_filename);
2235       return FALSE;
2236     }
2237
2238   if (!_dbus_string_append (&tmp_filename, "."))
2239     {
2240       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2241       _dbus_string_free (&tmp_filename);
2242       return FALSE;
2243     }
2244
2245 #define N_TMP_FILENAME_RANDOM_BYTES 8
2246   if (!_dbus_generate_random_ascii (&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES))
2247     {
2248       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2249       _dbus_string_free (&tmp_filename);
2250       return FALSE;
2251     }
2252
2253   filename_c = _dbus_string_get_const_data (filename);
2254   tmp_filename_c = _dbus_string_get_const_data (&tmp_filename);
2255
2256   fd = _open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
2257               0600);
2258   if (fd < 0)
2259     {
2260       dbus_set_error (error, _dbus_error_from_errno (errno),
2261                       "Could not create %s: %s", tmp_filename_c,
2262                       strerror (errno));
2263       goto out;
2264     }
2265
2266   _dbus_verbose ("tmp file %s fd %d opened\n", tmp_filename_c, fd);
2267
2268   need_unlink = TRUE;
2269
2270   total = 0;
2271   bytes_to_write = _dbus_string_get_length (str);
2272   str_c = _dbus_string_get_const_data (str);
2273
2274   while (total < bytes_to_write)
2275     {
2276       int bytes_written;
2277
2278       bytes_written = _write (fd, str_c + total, bytes_to_write - total);
2279
2280       if (bytes_written <= 0)
2281         {
2282           dbus_set_error (error, _dbus_error_from_errno (errno),
2283                           "Could not write to %s: %s", tmp_filename_c,
2284                           strerror (errno));
2285           goto out;
2286         }
2287
2288       total += bytes_written;
2289     }
2290
2291   if (_close (fd) < 0)
2292     {
2293       dbus_set_error (error, _dbus_error_from_errno (errno),
2294                       "Could not close file %s: %s",
2295                       tmp_filename_c, strerror (errno));
2296
2297       goto out;
2298     }
2299
2300   fd = -1;
2301
2302   /* Unlike rename(), MoveFileEx() can replace existing files */
2303   if (MoveFileExA (tmp_filename_c, filename_c, MOVEFILE_REPLACE_EXISTING) < 0)
2304     {
2305       char *emsg = _dbus_win_error_string (GetLastError ());
2306       dbus_set_error (error, DBUS_ERROR_FAILED,
2307                       "Could not rename %s to %s: %s",
2308                       tmp_filename_c, filename_c,
2309                       emsg);
2310       _dbus_win_free_error_string (emsg);
2311
2312       goto out;
2313     }
2314
2315   need_unlink = FALSE;
2316
2317   retval = TRUE;
2318
2319  out:
2320   /* close first, then unlink */
2321
2322   if (fd >= 0)
2323     _close (fd);
2324
2325   if (need_unlink && _unlink (tmp_filename_c) < 0)
2326     _dbus_verbose ("failed to unlink temp file %s: %s\n",
2327                    tmp_filename_c, strerror (errno));
2328
2329   _dbus_string_free (&tmp_filename);
2330
2331   if (!retval)
2332     _DBUS_ASSERT_ERROR_IS_SET (error);
2333
2334   return retval;
2335 }
2336
2337
2338 /** Creates the given file, failing if the file already exists.
2339  *
2340  * @param filename the filename
2341  * @param error error location
2342  * @returns #TRUE if we created the file and it didn't exist
2343  */
2344 dbus_bool_t
2345 _dbus_create_file_exclusively (const DBusString *filename,
2346                                DBusError        *error)
2347 {
2348   int fd;
2349   const char *filename_c;
2350
2351   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2352
2353   filename_c = _dbus_string_get_const_data (filename);
2354
2355   fd = _open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
2356               0600);
2357   if (fd < 0)
2358     {
2359       dbus_set_error (error,
2360                       DBUS_ERROR_FAILED,
2361                       "Could not create file %s: %s\n",
2362                       filename_c,
2363                       strerror (errno));
2364       return FALSE;
2365     }
2366
2367   _dbus_verbose ("exclusive file %s fd %d opened\n", filename_c, fd);
2368
2369   if (_close (fd) < 0)
2370     {
2371       dbus_set_error (error,
2372                       DBUS_ERROR_FAILED,
2373                       "Could not close file %s: %s\n",
2374                       filename_c,
2375                       strerror (errno));
2376       return FALSE;
2377     }
2378
2379   return TRUE;
2380 }
2381
2382
2383 /**
2384  * Creates a directory; succeeds if the directory
2385  * is created or already existed.
2386  *
2387  * @param filename directory filename
2388  * @param error initialized error object
2389  * @returns #TRUE on success
2390  */
2391 dbus_bool_t
2392 _dbus_create_directory (const DBusString *filename,
2393                         DBusError        *error)
2394 {
2395   const char *filename_c;
2396
2397   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2398
2399   filename_c = _dbus_string_get_const_data (filename);
2400
2401   if (!CreateDirectory (filename_c, NULL))
2402     {
2403       if (GetLastError () == ERROR_ALREADY_EXISTS)
2404         return TRUE;
2405
2406       dbus_set_error (error, DBUS_ERROR_FAILED,
2407                       "Failed to create directory %s: %s\n",
2408                       filename_c, strerror (errno));
2409       return FALSE;
2410     }
2411   else
2412     return TRUE;
2413 }
2414
2415
2416 /**
2417  * Generates the given number of random bytes,
2418  * using the best mechanism we can come up with.
2419  *
2420  * @param str the string
2421  * @param n_bytes the number of random bytes to append to string
2422  * @returns #TRUE on success, #FALSE if no memory
2423  */
2424 dbus_bool_t
2425 _dbus_generate_random_bytes (DBusString *str,
2426                              int         n_bytes)
2427 {
2428   int old_len;
2429   char *p;
2430   HCRYPTPROV hprov;
2431
2432   old_len = _dbus_string_get_length (str);
2433
2434   if (!_dbus_string_lengthen (str, n_bytes))
2435     return FALSE;
2436
2437   p = _dbus_string_get_data_len (str, old_len, n_bytes);
2438
2439   if (!CryptAcquireContext (&hprov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
2440     return FALSE;
2441
2442   if (!CryptGenRandom (hprov, n_bytes, p))
2443     {
2444       CryptReleaseContext (hprov, 0);
2445       return FALSE;
2446     }
2447
2448   CryptReleaseContext (hprov, 0);
2449
2450   return TRUE;
2451 }
2452
2453 /**
2454  * Gets the temporary files directory by inspecting the environment variables 
2455  * TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned
2456  *
2457  * @returns location of temp directory
2458  */
2459 const char*
2460 _dbus_get_tmpdir(void)
2461 {
2462   static const char* tmpdir = NULL;
2463   static char buf[1000];
2464
2465   if (tmpdir == NULL)
2466     {
2467       if (!GetTempPath (sizeof (buf), buf))
2468         strcpy (buf, "\\");
2469
2470       tmpdir = buf;
2471     }
2472
2473   _dbus_assert(tmpdir != NULL);
2474
2475   return tmpdir;
2476 }
2477
2478
2479 /**
2480  * Deletes the given file.
2481  *
2482  * @param filename the filename
2483  * @param error error location
2484  * 
2485  * @returns #TRUE if unlink() succeeded
2486  */
2487 dbus_bool_t
2488 _dbus_delete_file (const DBusString *filename,
2489                    DBusError        *error)
2490 {
2491   const char *filename_c;
2492
2493   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2494
2495   filename_c = _dbus_string_get_const_data (filename);
2496
2497   if (_unlink (filename_c) < 0)
2498     {
2499       dbus_set_error (error, DBUS_ERROR_FAILED,
2500                       "Failed to delete file %s: %s\n",
2501                       filename_c, strerror (errno));
2502       return FALSE;
2503     }
2504   else
2505     return TRUE;
2506 }
2507
2508 #if !defined (DBUS_DISABLE_ASSERT) || defined(DBUS_BUILD_TESTS)
2509
2510 #ifdef _MSC_VER
2511 # ifdef BACKTRACES
2512 #  undef BACKTRACES
2513 # endif
2514 #else
2515 # define BACKTRACES
2516 #endif
2517
2518 #ifdef BACKTRACES
2519 /*
2520  * Backtrace Generator
2521  *
2522  * Copyright 2004 Eric Poech
2523  * Copyright 2004 Robert Shearman
2524  *
2525  * This library is free software; you can redistribute it and/or
2526  * modify it under the terms of the GNU Lesser General Public
2527  * License as published by the Free Software Foundation; either
2528  * version 2.1 of the License, or (at your option) any later version.
2529  *
2530  * This library is distributed in the hope that it will be useful,
2531  * but WITHOUT ANY WARRANTY; without even the implied warranty of
2532  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
2533  * Lesser General Public License for more details.
2534  *
2535  * You should have received a copy of the GNU Lesser General Public
2536  * License along with this library; if not, write to the Free Software
2537  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
2538  */
2539
2540 #include <winver.h>
2541 #include <imagehlp.h>
2542 #include <stdio.h>
2543
2544 #define DPRINTF _dbus_warn
2545
2546 #ifdef _MSC_VER
2547 #define BOOL int
2548
2549 #define __i386__
2550 #endif
2551
2552 //#define MAKE_FUNCPTR(f) static typeof(f) * p##f
2553
2554 //MAKE_FUNCPTR(StackWalk);
2555 //MAKE_FUNCPTR(SymGetModuleBase);
2556 //MAKE_FUNCPTR(SymFunctionTableAccess);
2557 //MAKE_FUNCPTR(SymInitialize);
2558 //MAKE_FUNCPTR(SymGetSymFromAddr);
2559 //MAKE_FUNCPTR(SymGetModuleInfo);
2560 static BOOL (WINAPI *pStackWalk)(
2561   DWORD MachineType,
2562   HANDLE hProcess,
2563   HANDLE hThread,
2564   LPSTACKFRAME StackFrame,
2565   PVOID ContextRecord,
2566   PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
2567   PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
2568   PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
2569   PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
2570 );
2571 static DWORD (WINAPI *pSymGetModuleBase)(
2572   HANDLE hProcess,
2573   DWORD dwAddr
2574 );
2575 static PVOID  (WINAPI *pSymFunctionTableAccess)(
2576   HANDLE hProcess,
2577   DWORD AddrBase
2578 );
2579 static BOOL  (WINAPI *pSymInitialize)(
2580   HANDLE hProcess,
2581   PSTR UserSearchPath,
2582   BOOL fInvadeProcess
2583 );
2584 static BOOL  (WINAPI *pSymGetSymFromAddr)(
2585   HANDLE hProcess,
2586   DWORD Address,
2587   PDWORD Displacement,
2588   PIMAGEHLP_SYMBOL Symbol
2589 );
2590 static BOOL  (WINAPI *pSymGetModuleInfo)(
2591   HANDLE hProcess,
2592   DWORD dwAddr,
2593   PIMAGEHLP_MODULE ModuleInfo
2594 );
2595 static DWORD  (WINAPI *pSymSetOptions)(
2596   DWORD SymOptions
2597 );
2598
2599
2600 static BOOL init_backtrace()
2601 {
2602     HMODULE hmodDbgHelp = LoadLibraryA("dbghelp");
2603 /*
2604     #define GETFUNC(x) \
2605     p##x = (typeof(x)*)GetProcAddress(hmodDbgHelp, #x); \
2606     if (!p##x) \
2607     { \
2608         return FALSE; \
2609     }
2610     */
2611
2612
2613 //    GETFUNC(StackWalk);
2614 //    GETFUNC(SymGetModuleBase);
2615 //    GETFUNC(SymFunctionTableAccess);
2616 //    GETFUNC(SymInitialize);
2617 //    GETFUNC(SymGetSymFromAddr);
2618 //    GETFUNC(SymGetModuleInfo);
2619
2620 #define FUNC(x) #x
2621
2622       pStackWalk = (BOOL  (WINAPI *)(
2623 DWORD MachineType,
2624 HANDLE hProcess,
2625 HANDLE hThread,
2626 LPSTACKFRAME StackFrame,
2627 PVOID ContextRecord,
2628 PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
2629 PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
2630 PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
2631 PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
2632 ))GetProcAddress (hmodDbgHelp, FUNC(StackWalk));
2633     pSymGetModuleBase=(DWORD  (WINAPI *)(
2634   HANDLE hProcess,
2635   DWORD dwAddr
2636 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleBase));
2637     pSymFunctionTableAccess=(PVOID  (WINAPI *)(
2638   HANDLE hProcess,
2639   DWORD AddrBase
2640 ))GetProcAddress (hmodDbgHelp, FUNC(SymFunctionTableAccess));
2641     pSymInitialize = (BOOL  (WINAPI *)(
2642   HANDLE hProcess,
2643   PSTR UserSearchPath,
2644   BOOL fInvadeProcess
2645 ))GetProcAddress (hmodDbgHelp, FUNC(SymInitialize));
2646     pSymGetSymFromAddr = (BOOL  (WINAPI *)(
2647   HANDLE hProcess,
2648   DWORD Address,
2649   PDWORD Displacement,
2650   PIMAGEHLP_SYMBOL Symbol
2651 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetSymFromAddr));
2652     pSymGetModuleInfo = (BOOL  (WINAPI *)(
2653   HANDLE hProcess,
2654   DWORD dwAddr,
2655   PIMAGEHLP_MODULE ModuleInfo
2656 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleInfo));
2657 pSymSetOptions = (DWORD  (WINAPI *)(
2658 DWORD SymOptions
2659 ))GetProcAddress (hmodDbgHelp, FUNC(SymSetOptions));
2660
2661
2662     pSymSetOptions(SYMOPT_UNDNAME);
2663
2664     pSymInitialize(GetCurrentProcess(), NULL, TRUE);
2665
2666     return TRUE;
2667 }
2668
2669 static void dump_backtrace_for_thread(HANDLE hThread)
2670 {
2671     STACKFRAME sf;
2672     CONTEXT context;
2673     DWORD dwImageType;
2674
2675     if (!pStackWalk)
2676         if (!init_backtrace())
2677             return;
2678
2679     /* can't use this function for current thread as GetThreadContext
2680      * doesn't support getting context from current thread */
2681     if (hThread == GetCurrentThread())
2682         return;
2683
2684     DPRINTF("Backtrace:\n");
2685
2686     _DBUS_ZERO(context);
2687     context.ContextFlags = CONTEXT_FULL;
2688
2689     SuspendThread(hThread);
2690
2691     if (!GetThreadContext(hThread, &context))
2692     {
2693         DPRINTF("Couldn't get thread context (error %ld)\n", GetLastError());
2694         ResumeThread(hThread);
2695         return;
2696     }
2697
2698     _DBUS_ZERO(sf);
2699
2700 #ifdef __i386__
2701     sf.AddrFrame.Offset = context.Ebp;
2702     sf.AddrFrame.Mode = AddrModeFlat;
2703     sf.AddrPC.Offset = context.Eip;
2704     sf.AddrPC.Mode = AddrModeFlat;
2705     dwImageType = IMAGE_FILE_MACHINE_I386;
2706 #else
2707 # error You need to fill in the STACKFRAME structure for your architecture
2708 #endif
2709
2710     while (pStackWalk(dwImageType, GetCurrentProcess(),
2711                      hThread, &sf, &context, NULL, pSymFunctionTableAccess,
2712                      pSymGetModuleBase, NULL))
2713     {
2714         BYTE buffer[256];
2715         IMAGEHLP_SYMBOL * pSymbol = (IMAGEHLP_SYMBOL *)buffer;
2716         DWORD dwDisplacement;
2717
2718         pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
2719         pSymbol->MaxNameLength = sizeof(buffer) - sizeof(IMAGEHLP_SYMBOL) + 1;
2720
2721         if (!pSymGetSymFromAddr(GetCurrentProcess(), sf.AddrPC.Offset,
2722                                 &dwDisplacement, pSymbol))
2723         {
2724             IMAGEHLP_MODULE ModuleInfo;
2725             ModuleInfo.SizeOfStruct = sizeof(ModuleInfo);
2726
2727             if (!pSymGetModuleInfo(GetCurrentProcess(), sf.AddrPC.Offset,
2728                                    &ModuleInfo))
2729                 DPRINTF("1\t%p\n", (void*)sf.AddrPC.Offset);
2730             else
2731                 DPRINTF("2\t%s+0x%lx\n", ModuleInfo.ImageName,
2732                     sf.AddrPC.Offset - ModuleInfo.BaseOfImage);
2733         }
2734         else if (dwDisplacement)
2735             DPRINTF("3\t%s+0x%lx\n", pSymbol->Name, dwDisplacement);
2736         else
2737             DPRINTF("4\t%s\n", pSymbol->Name);
2738     }
2739
2740     ResumeThread(hThread);
2741 }
2742
2743 static DWORD WINAPI dump_thread_proc(LPVOID lpParameter)
2744 {
2745     dump_backtrace_for_thread((HANDLE)lpParameter);
2746     return 0;
2747 }
2748
2749 /* cannot get valid context from current thread, so we have to execute
2750  * backtrace from another thread */
2751 static void dump_backtrace()
2752 {
2753     HANDLE hCurrentThread;
2754     HANDLE hThread;
2755     DWORD dwThreadId;
2756     DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
2757         GetCurrentProcess(), &hCurrentThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
2758     hThread = CreateThread(NULL, 0, dump_thread_proc, (LPVOID)hCurrentThread,
2759         0, &dwThreadId);
2760     WaitForSingleObject(hThread, INFINITE);
2761     CloseHandle(hThread);
2762     CloseHandle(hCurrentThread);
2763 }
2764
2765 void _dbus_print_backtrace(void)
2766 {
2767   init_backtrace();
2768   dump_backtrace();
2769 }
2770 #else
2771 void _dbus_print_backtrace(void)
2772 {
2773   _dbus_verbose ("  D-Bus not compiled with backtrace support\n");
2774 }
2775 #endif
2776
2777 static dbus_uint32_t fromAscii(char ascii)
2778 {
2779     if(ascii >= '0' && ascii <= '9')
2780         return ascii - '0';
2781     if(ascii >= 'A' && ascii <= 'F')
2782         return ascii - 'A' + 10;
2783     if(ascii >= 'a' && ascii <= 'f')
2784         return ascii - 'a' + 10;
2785     return 0;    
2786 }
2787
2788 dbus_bool_t _dbus_read_local_machine_uuid   (DBusGUID         *machine_id,
2789                                              dbus_bool_t       create_if_not_found,
2790                                              DBusError        *error)
2791 {
2792 #ifdef DBUS_WINCE
2793         return TRUE;
2794   // TODO
2795 #else
2796     HW_PROFILE_INFOA info;
2797     char *lpc = &info.szHwProfileGuid[0];
2798     dbus_uint32_t u;
2799
2800     //  the hw-profile guid lives long enough
2801     if(!GetCurrentHwProfileA(&info))
2802       {
2803         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); // FIXME
2804         return FALSE;  
2805       }
2806
2807     // Form: {12340001-4980-1920-6788-123456789012}
2808     lpc++;
2809     // 12340001
2810     u = ((fromAscii(lpc[0]) <<  0) |
2811          (fromAscii(lpc[1]) <<  4) |
2812          (fromAscii(lpc[2]) <<  8) |
2813          (fromAscii(lpc[3]) << 12) |
2814          (fromAscii(lpc[4]) << 16) |
2815          (fromAscii(lpc[5]) << 20) |
2816          (fromAscii(lpc[6]) << 24) |
2817          (fromAscii(lpc[7]) << 28));
2818     machine_id->as_uint32s[0] = u;
2819
2820     lpc += 9;
2821     // 4980-1920
2822     u = ((fromAscii(lpc[0]) <<  0) |
2823          (fromAscii(lpc[1]) <<  4) |
2824          (fromAscii(lpc[2]) <<  8) |
2825          (fromAscii(lpc[3]) << 12) |
2826          (fromAscii(lpc[5]) << 16) |
2827          (fromAscii(lpc[6]) << 20) |
2828          (fromAscii(lpc[7]) << 24) |
2829          (fromAscii(lpc[8]) << 28));
2830     machine_id->as_uint32s[1] = u;
2831     
2832     lpc += 10;
2833     // 6788-1234
2834     u = ((fromAscii(lpc[0]) <<  0) |
2835          (fromAscii(lpc[1]) <<  4) |
2836          (fromAscii(lpc[2]) <<  8) |
2837          (fromAscii(lpc[3]) << 12) |
2838          (fromAscii(lpc[5]) << 16) |
2839          (fromAscii(lpc[6]) << 20) |
2840          (fromAscii(lpc[7]) << 24) |
2841          (fromAscii(lpc[8]) << 28));
2842     machine_id->as_uint32s[2] = u;
2843     
2844     lpc += 9;
2845     // 56789012
2846     u = ((fromAscii(lpc[0]) <<  0) |
2847          (fromAscii(lpc[1]) <<  4) |
2848          (fromAscii(lpc[2]) <<  8) |
2849          (fromAscii(lpc[3]) << 12) |
2850          (fromAscii(lpc[4]) << 16) |
2851          (fromAscii(lpc[5]) << 20) |
2852          (fromAscii(lpc[6]) << 24) |
2853          (fromAscii(lpc[7]) << 28));
2854     machine_id->as_uint32s[3] = u;
2855 #endif
2856     return TRUE;
2857 }
2858
2859 static
2860 HANDLE _dbus_global_lock (const char *mutexname)
2861 {
2862   HANDLE mutex;
2863   DWORD gotMutex;
2864
2865   mutex = CreateMutex( NULL, FALSE, mutexname );
2866   if( !mutex )
2867     {
2868       return FALSE;
2869     }
2870
2871    gotMutex = WaitForSingleObject( mutex, INFINITE );
2872    switch( gotMutex )
2873      {
2874        case WAIT_ABANDONED:
2875                ReleaseMutex (mutex);
2876                CloseHandle (mutex);
2877                return 0;
2878        case WAIT_FAILED:
2879        case WAIT_TIMEOUT:
2880                return 0;
2881      }
2882
2883    return mutex;
2884 }
2885
2886 static
2887 void _dbus_global_unlock (HANDLE mutex)
2888 {
2889   ReleaseMutex (mutex);
2890   CloseHandle (mutex); 
2891 }
2892
2893 // for proper cleanup in dbus-daemon
2894 static HANDLE hDBusDaemonMutex = NULL;
2895 static HANDLE hDBusSharedMem = NULL;
2896 // sync _dbus_daemon_init, _dbus_daemon_uninit and _dbus_daemon_already_runs
2897 static const char *cUniqueDBusInitMutex = "UniqueDBusInitMutex";
2898 // sync _dbus_get_autolaunch_address
2899 static const char *cDBusAutolaunchMutex = "DBusAutolaunchMutex";
2900 // mutex to determine if dbus-daemon is already started (per user)
2901 static const char *cDBusDaemonMutex = "DBusDaemonMutex";
2902 // named shm for dbus adress info (per user)
2903 #ifdef _DEBUG
2904 static const char *cDBusDaemonAddressInfo = "DBusDaemonAddressInfoDebug";
2905 #else
2906 static const char *cDBusDaemonAddressInfo = "DBusDaemonAddressInfo";
2907 #endif
2908
2909 void
2910 _dbus_daemon_init(const char *host, dbus_uint32_t port)
2911 {
2912   HANDLE lock;
2913   char *adr = NULL;
2914   char szUserName[64];
2915   DWORD dwUserNameSize = sizeof(szUserName);
2916   char szDBusDaemonMutex[128];
2917   char szDBusDaemonAddressInfo[128];
2918   char szAddress[128];
2919   DWORD ret;
2920
2921   _dbus_assert(host);
2922   _dbus_assert(port);
2923
2924   _snprintf(szAddress, sizeof(szAddress) - 1, "tcp:host=%s,port=%d", host, port);
2925   ret = GetUserName(szUserName, &dwUserNameSize);
2926   _dbus_assert(ret != 0);
2927   _snprintf(szDBusDaemonMutex, sizeof(szDBusDaemonMutex) - 1, "%s:%s",
2928             cDBusDaemonMutex, szUserName);
2929   _snprintf(szDBusDaemonAddressInfo, sizeof(szDBusDaemonAddressInfo) - 1, "%s:%s",
2930             cDBusDaemonAddressInfo, szUserName);
2931
2932   // before _dbus_global_lock to keep correct lock/release order
2933   hDBusDaemonMutex = CreateMutex( NULL, FALSE, szDBusDaemonMutex );
2934   ret = WaitForSingleObject( hDBusDaemonMutex, 1000 );
2935   if ( ret != WAIT_OBJECT_0 ) {
2936     _dbus_warn("Could not lock mutex %s (return code %d). daemon already running?\n", szDBusDaemonMutex, ret );
2937     _dbus_assert( !"Could not lock mutex, daemon already running?" );
2938   }
2939
2940   // sync _dbus_daemon_init, _dbus_daemon_uninit and _dbus_daemon_already_runs
2941   lock = _dbus_global_lock( cUniqueDBusInitMutex );
2942
2943   // create shm
2944   hDBusSharedMem = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
2945                                       0, strlen( szAddress ) + 1, szDBusDaemonAddressInfo );
2946   _dbus_assert( hDBusSharedMem );
2947
2948   adr = MapViewOfFile( hDBusSharedMem, FILE_MAP_WRITE, 0, 0, 0 );
2949
2950   _dbus_assert( adr );
2951
2952   strcpy( adr, szAddress);
2953
2954   // cleanup
2955   UnmapViewOfFile( adr );
2956
2957   _dbus_global_unlock( lock );
2958 }
2959
2960 void
2961 _dbus_daemon_release()
2962 {
2963   HANDLE lock;
2964
2965   // sync _dbus_daemon_init, _dbus_daemon_uninit and _dbus_daemon_already_runs
2966   lock = _dbus_global_lock( cUniqueDBusInitMutex );
2967
2968   CloseHandle( hDBusSharedMem );
2969
2970   hDBusSharedMem = NULL;
2971
2972   ReleaseMutex( hDBusDaemonMutex );
2973
2974   CloseHandle( hDBusDaemonMutex );
2975
2976   hDBusDaemonMutex = NULL;
2977
2978   _dbus_global_unlock( lock );
2979 }
2980
2981 static dbus_bool_t
2982 _dbus_get_autolaunch_shm(DBusString *adress)
2983 {
2984   HANDLE sharedMem;
2985   char *adr;
2986   char szUserName[64];
2987   DWORD dwUserNameSize = sizeof(szUserName);
2988   char szDBusDaemonAddressInfo[128];
2989   int i;
2990
2991   if( !GetUserName(szUserName, &dwUserNameSize) )
2992       return FALSE;
2993   _snprintf(szDBusDaemonAddressInfo, sizeof(szDBusDaemonAddressInfo) - 1, "%s:%s",
2994             cDBusDaemonAddressInfo, szUserName);
2995
2996   // read shm
2997   for(i=0;i<20;++i) {
2998       // we know that dbus-daemon is available, so we wait until shm is available
2999       sharedMem = OpenFileMapping( FILE_MAP_READ, FALSE, szDBusDaemonAddressInfo );
3000       if( sharedMem == 0 )
3001           Sleep( 100 );
3002       if ( sharedMem != 0)
3003           break;
3004   }
3005
3006   if( sharedMem == 0 )
3007       return FALSE;
3008
3009   adr = MapViewOfFile( sharedMem, FILE_MAP_READ, 0, 0, 0 );
3010
3011   if( adr == 0 )
3012       return FALSE;
3013
3014   _dbus_string_init( adress );
3015
3016   _dbus_string_append( adress, adr ); 
3017
3018   // cleanup
3019   UnmapViewOfFile( adr );
3020
3021   CloseHandle( sharedMem );
3022
3023   return TRUE;
3024 }
3025
3026 static dbus_bool_t
3027 _dbus_daemon_already_runs (DBusString *adress)
3028 {
3029   HANDLE lock;
3030   HANDLE daemon;
3031   dbus_bool_t bRet = TRUE;
3032   char szUserName[64];
3033   DWORD dwUserNameSize = sizeof(szUserName);
3034   char szDBusDaemonMutex[128];
3035
3036   // sync _dbus_daemon_init, _dbus_daemon_uninit and _dbus_daemon_already_runs
3037   lock = _dbus_global_lock( cUniqueDBusInitMutex );
3038
3039   if( !GetUserName(szUserName, &dwUserNameSize) )
3040       return FALSE;
3041   _snprintf(szDBusDaemonMutex, sizeof(szDBusDaemonMutex) - 1, "%s:%s",
3042             cDBusDaemonMutex, szUserName);
3043
3044   // do checks
3045   daemon = CreateMutex( NULL, FALSE, szDBusDaemonMutex );
3046   if(WaitForSingleObject( daemon, 10 ) != WAIT_TIMEOUT)
3047     {
3048       ReleaseMutex (daemon);
3049       CloseHandle (daemon);
3050
3051       _dbus_global_unlock( lock );
3052       return FALSE;
3053     }
3054
3055   // read shm
3056   bRet = _dbus_get_autolaunch_shm( adress );
3057
3058   // cleanup
3059   CloseHandle ( daemon );
3060
3061   _dbus_global_unlock( lock );
3062
3063   return bRet;
3064 }
3065
3066 dbus_bool_t
3067 _dbus_get_autolaunch_address (DBusString *address, 
3068                               DBusError *error)
3069 {
3070   HANDLE mutex;
3071   STARTUPINFOA si;
3072   PROCESS_INFORMATION pi;
3073   dbus_bool_t retval = FALSE;
3074   LPSTR lpFile;
3075   char dbus_exe_path[MAX_PATH];
3076   char dbus_args[MAX_PATH * 2];
3077 #ifdef _DEBUG
3078   const char * daemon_name = "dbus-daemond.exe";
3079 #else
3080   const char * daemon_name = "dbus-daemon.exe";
3081 #endif
3082
3083   mutex = _dbus_global_lock ( cDBusAutolaunchMutex );
3084
3085   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3086
3087   if (_dbus_daemon_already_runs(address))
3088     {
3089         _dbus_verbose("found already running dbus daemon\n");
3090         retval = TRUE;
3091         goto out;
3092     }
3093
3094   if (!SearchPathA(NULL, daemon_name, NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile))
3095     {
3096       printf ("please add the path to %s to your PATH environment variable\n", daemon_name);
3097       printf ("or start the daemon manually\n\n");
3098       printf ("");
3099       goto out;
3100     }
3101
3102   // Create process
3103   ZeroMemory( &si, sizeof(si) );
3104   si.cb = sizeof(si);
3105   ZeroMemory( &pi, sizeof(pi) );
3106
3107   _snprintf(dbus_args, sizeof(dbus_args) - 1, "\"%s\" %s", dbus_exe_path,  " --session");
3108
3109 //  argv[i] = "--config-file=bus\\session.conf";
3110 //  printf("create process \"%s\" %s\n", dbus_exe_path, dbus_args);
3111   if(CreateProcessA(dbus_exe_path, dbus_args, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
3112     {
3113
3114       retval = _dbus_get_autolaunch_shm( address );
3115     }
3116   
3117   if (retval == FALSE)
3118     dbus_set_error_const (error, DBUS_ERROR_FAILED, "Failed to launch dbus-daemon");
3119
3120 out:
3121   if (retval)
3122     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3123   else
3124     _DBUS_ASSERT_ERROR_IS_SET (error);
3125   
3126   _dbus_global_unlock (mutex);
3127
3128   return retval;
3129  }
3130
3131
3132 /** Makes the file readable by every user in the system.
3133  *
3134  * @param filename the filename
3135  * @param error error location
3136  * @returns #TRUE if the file's permissions could be changed.
3137  */
3138 dbus_bool_t
3139 _dbus_make_file_world_readable(const DBusString *filename,
3140                                DBusError *error)
3141 {
3142   // TODO
3143   return TRUE;
3144 }
3145
3146
3147 #define DBUS_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
3148 #define DBUS_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
3149
3150 /**
3151  * Returns the standard directories for a session bus to look for service 
3152  * activation files 
3153  *
3154  * On Windows this should be data directories:
3155  *
3156  * %CommonProgramFiles%/dbus
3157  *
3158  * and
3159  *
3160  * DBUS_DATADIR
3161  *
3162  * @param dirs the directory list we are returning
3163  * @returns #FALSE on OOM 
3164  */
3165
3166 dbus_bool_t 
3167 _dbus_get_standard_session_servicedirs (DBusList **dirs)
3168 {
3169   const char *common_progs;
3170   DBusString servicedir_path;
3171
3172   if (!_dbus_string_init (&servicedir_path))
3173     return FALSE;
3174
3175   if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR _DBUS_PATH_SEPARATOR))
3176         goto oom;
3177
3178   common_progs = _dbus_getenv ("CommonProgramFiles");
3179
3180   if (common_progs != NULL)
3181     {
3182       if (!_dbus_string_append (&servicedir_path, common_progs))
3183         goto oom;
3184
3185       if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
3186         goto oom;
3187     }
3188
3189   if (!_dbus_split_paths_and_append (&servicedir_path, 
3190                                DBUS_STANDARD_SESSION_SERVICEDIR, 
3191                                dirs))
3192     goto oom;
3193
3194   _dbus_string_free (&servicedir_path);  
3195   return TRUE;
3196
3197  oom:
3198   _dbus_string_free (&servicedir_path);
3199   return FALSE;
3200 }
3201
3202 /**
3203  * Returns the standard directories for a system bus to look for service
3204  * activation files
3205  *
3206  * On UNIX this should be the standard xdg freedesktop.org data directories:
3207  *
3208  * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3209  *
3210  * and
3211  *
3212  * DBUS_DATADIR
3213  *
3214  * On Windows there is no system bus and this function can return nothing.
3215  *
3216  * @param dirs the directory list we are returning
3217  * @returns #FALSE on OOM
3218  */
3219
3220 dbus_bool_t
3221 _dbus_get_standard_system_servicedirs (DBusList **dirs)
3222 {
3223   *dirs = NULL;
3224   return TRUE;
3225 }
3226
3227 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
3228
3229 /**
3230  * Atomically increments an integer
3231  *
3232  * @param atomic pointer to the integer to increment
3233  * @returns the value before incrementing
3234  *
3235  */
3236 dbus_int32_t
3237 _dbus_atomic_inc (DBusAtomic *atomic)
3238 {
3239   // +/- 1 is needed here!
3240   // no volatile argument with mingw
3241   return InterlockedIncrement (&atomic->value) - 1;
3242 }
3243
3244 /**
3245  * Atomically decrement an integer
3246  *
3247  * @param atomic pointer to the integer to decrement
3248  * @returns the value before decrementing
3249  *
3250  */
3251 dbus_int32_t
3252 _dbus_atomic_dec (DBusAtomic *atomic)
3253 {
3254   // +/- 1 is needed here!
3255   // no volatile argument with mingw
3256   return InterlockedDecrement (&atomic->value) + 1;
3257 }
3258
3259 #endif /* asserts or tests enabled */
3260
3261 /**
3262  * Called when the bus daemon is signaled to reload its configuration; any
3263  * caches should be nuked. Of course any caches that need explicit reload
3264  * are probably broken, but c'est la vie.
3265  *
3266  * 
3267  */
3268 void
3269 _dbus_flush_caches (void)
3270 {
3271 }
3272
3273 /**
3274  * See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently
3275  * for Winsock so is abstracted)
3276  *
3277  * @returns #TRUE if errno == EAGAIN or errno == EWOULDBLOCK
3278  */
3279 dbus_bool_t
3280 _dbus_get_is_errno_eagain_or_ewouldblock (void)
3281 {
3282   return errno == EAGAIN || errno == EWOULDBLOCK;
3283 }
3284
3285 /**
3286  * return the absolute path of the dbus installation 
3287  *
3288  * @param s buffer for installation path
3289  * @param len length of buffer
3290  * @returns #FALSE on failure
3291  */
3292 dbus_bool_t 
3293 _dbus_get_install_root(char *prefix, int len)
3294 {
3295     //To find the prefix, we cut the filename and also \bin\ if present
3296     char* p = 0;
3297     int i;
3298     DWORD pathLength;
3299     int lastSlash;
3300     SetLastError( 0 );
3301     pathLength = GetModuleFileName(NULL, prefix, len);
3302     if ( pathLength == 0 || GetLastError() != 0 ) {
3303         *prefix = '\0';
3304         return FALSE;
3305     }
3306     lastSlash = -1;
3307     for (i = 0; i < pathLength; ++i)
3308         if (prefix[i] == '\\')
3309             lastSlash = i;
3310     if (lastSlash == -1) {
3311         *prefix = '\0';
3312         return FALSE;
3313     }
3314     //cut off binary name
3315     prefix[lastSlash+1] = 0;
3316     //cut possible "\\bin"
3317     if (lastSlash > 3 && strncmp(prefix + lastSlash - 4, "\\bin", 4) == 0)
3318         prefix[lastSlash-3] = 0;
3319     return TRUE;
3320 }
3321
3322 /** 
3323   find config file either from installation or build root according to 
3324   the following path layout 
3325     install-root/
3326       bin/dbus-daemon[d].exe
3327       etc/<config-file>.conf 
3328
3329     build-root/
3330       bin/dbus-daemon[d].exe
3331       bus/<config-file>.conf 
3332 */
3333 dbus_bool_t 
3334 _dbus_get_config_file_name(DBusString *config_file, char *s)
3335 {
3336   char path[MAX_PATH*2];
3337   int path_size = sizeof(path);
3338   int len = 4 + strlen(s);
3339
3340   if (!_dbus_get_install_root(path,path_size))
3341     return FALSE;
3342
3343   if(len > sizeof(path)-2)
3344     return FALSE;
3345   strcat(path,"etc\\");
3346   strcat(path,s);
3347   if (_dbus_file_exists(path)) 
3348     {
3349       // find path from executable 
3350       if (!_dbus_string_append (config_file, path))
3351         return FALSE;
3352     }
3353   else 
3354     {
3355       if (!_dbus_get_install_root(path,path_size))
3356         return FALSE;
3357       if(len + strlen(path) > sizeof(path)-2)
3358         return FALSE;
3359       strcat(path,"bus\\");
3360       strcat(path,s);
3361   
3362       if (_dbus_file_exists(path)) 
3363         {
3364           if (!_dbus_string_append (config_file, path))
3365             return FALSE;
3366         }
3367     }
3368   return TRUE;
3369 }    
3370
3371 /**
3372  * Append the absolute path of the system.conf file
3373  * (there is no system bus on Windows so this can just
3374  * return FALSE and print a warning or something)
3375  * 
3376  * @param str the string to append to
3377  * @returns #FALSE if no memory
3378  */
3379 dbus_bool_t
3380 _dbus_append_system_config_file (DBusString *str)
3381 {
3382   return _dbus_get_config_file_name(str, "system.conf");
3383 }
3384
3385 /**
3386  * Append the absolute path of the session.conf file.
3387  * 
3388  * @param str the string to append to
3389  * @returns #FALSE if no memory
3390  */
3391 dbus_bool_t
3392 _dbus_append_session_config_file (DBusString *str)
3393 {
3394   return _dbus_get_config_file_name(str, "session.conf");
3395 }
3396
3397 /* See comment in dbus-sysdeps-unix.c */
3398 dbus_bool_t
3399 _dbus_lookup_session_address (dbus_bool_t *supported,
3400                               DBusString  *address,
3401                               DBusError   *error)
3402 {
3403   /* Probably fill this in with something based on COM? */
3404   *supported = FALSE;
3405   return TRUE;
3406 }
3407
3408 /**
3409  * Appends the directory in which a keyring for the given credentials
3410  * should be stored.  The credentials should have either a Windows or
3411  * UNIX user in them.  The directory should be an absolute path.
3412  *
3413  * On UNIX the directory is ~/.dbus-keyrings while on Windows it should probably
3414  * be something else, since the dotfile convention is not normal on Windows.
3415  * 
3416  * @param directory string to append directory to
3417  * @param credentials credentials the directory should be for
3418  *  
3419  * @returns #FALSE on no memory
3420  */
3421 dbus_bool_t
3422 _dbus_append_keyring_directory_for_credentials (DBusString      *directory,
3423                                                 DBusCredentials *credentials)
3424 {
3425   DBusString homedir;
3426   DBusString dotdir;
3427   dbus_uid_t uid;
3428   const char *homepath;
3429
3430   _dbus_assert (credentials != NULL);
3431   _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
3432   
3433   if (!_dbus_string_init (&homedir))
3434     return FALSE;
3435
3436   homepath = _dbus_getenv("HOMEPATH");
3437   if (homepath != NULL && *homepath != '\0')
3438     {
3439       _dbus_string_append(&homedir,homepath);
3440     }
3441   
3442 #ifdef DBUS_BUILD_TESTS
3443   {
3444     const char *override;
3445     
3446     override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3447     if (override != NULL && *override != '\0')
3448       {
3449         _dbus_string_set_length (&homedir, 0);
3450         if (!_dbus_string_append (&homedir, override))
3451           goto failed;
3452
3453         _dbus_verbose ("Using fake homedir for testing: %s\n",
3454                        _dbus_string_get_const_data (&homedir));
3455       }
3456     else
3457       {
3458         static dbus_bool_t already_warned = FALSE;
3459         if (!already_warned)
3460           {
3461             _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3462             already_warned = TRUE;
3463           }
3464       }
3465   }
3466 #endif
3467
3468   _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3469   if (!_dbus_concat_dir_and_file (&homedir,
3470                                   &dotdir))
3471     goto failed;
3472   
3473   if (!_dbus_string_copy (&homedir, 0,
3474                           directory, _dbus_string_get_length (directory))) {
3475     goto failed;
3476   }
3477
3478   _dbus_string_free (&homedir);
3479   return TRUE;
3480   
3481  failed: 
3482   _dbus_string_free (&homedir);
3483   return FALSE;
3484 }
3485
3486 /** Checks if a file exists
3487 *
3488 * @param file full path to the file
3489 * @returns #TRUE if file exists
3490 */
3491 dbus_bool_t 
3492 _dbus_file_exists (const char *file)
3493 {
3494   DWORD attributes = GetFileAttributes (file);
3495
3496   if (attributes != INVALID_FILE_ATTRIBUTES && GetLastError() != ERROR_PATH_NOT_FOUND)
3497     return TRUE;
3498   else
3499     return FALSE;  
3500 }
3501
3502 /**
3503  * A wrapper around strerror() because some platforms
3504  * may be lame and not have strerror().
3505  *
3506  * @param error_number errno.
3507  * @returns error description.
3508  */
3509 const char*
3510 _dbus_strerror (int error_number)
3511 {
3512 #ifdef DBUS_WINCE
3513   // TODO
3514   return "unknown";
3515 #else
3516   const char *msg;
3517
3518   switch (error_number)
3519     {
3520     case WSAEINTR:
3521       return "Interrupted function call";
3522     case WSAEACCES:
3523       return "Permission denied";
3524     case WSAEFAULT:
3525       return "Bad address";
3526     case WSAEINVAL:
3527       return "Invalid argument";
3528     case WSAEMFILE:
3529       return "Too many open files";
3530     case WSAEWOULDBLOCK:
3531       return "Resource temporarily unavailable";
3532     case WSAEINPROGRESS:
3533       return "Operation now in progress";
3534     case WSAEALREADY:
3535       return "Operation already in progress";
3536     case WSAENOTSOCK:
3537       return "Socket operation on nonsocket";
3538     case WSAEDESTADDRREQ:
3539       return "Destination address required";
3540     case WSAEMSGSIZE:
3541       return "Message too long";
3542     case WSAEPROTOTYPE:
3543       return "Protocol wrong type for socket";
3544     case WSAENOPROTOOPT:
3545       return "Bad protocol option";
3546     case WSAEPROTONOSUPPORT:
3547       return "Protocol not supported";
3548     case WSAESOCKTNOSUPPORT:
3549       return "Socket type not supported";
3550     case WSAEOPNOTSUPP:
3551       return "Operation not supported";
3552     case WSAEPFNOSUPPORT:
3553       return "Protocol family not supported";
3554     case WSAEAFNOSUPPORT:
3555       return "Address family not supported by protocol family";
3556     case WSAEADDRINUSE:
3557       return "Address already in use";
3558     case WSAEADDRNOTAVAIL:
3559       return "Cannot assign requested address";
3560     case WSAENETDOWN:
3561       return "Network is down";
3562     case WSAENETUNREACH:
3563       return "Network is unreachable";
3564     case WSAENETRESET:
3565       return "Network dropped connection on reset";
3566     case WSAECONNABORTED:
3567       return "Software caused connection abort";
3568     case WSAECONNRESET:
3569       return "Connection reset by peer";
3570     case WSAENOBUFS:
3571       return "No buffer space available";
3572     case WSAEISCONN:
3573       return "Socket is already connected";
3574     case WSAENOTCONN:
3575       return "Socket is not connected";
3576     case WSAESHUTDOWN:
3577       return "Cannot send after socket shutdown";
3578     case WSAETIMEDOUT:
3579       return "Connection timed out";
3580     case WSAECONNREFUSED:
3581       return "Connection refused";
3582     case WSAEHOSTDOWN:
3583       return "Host is down";
3584     case WSAEHOSTUNREACH:
3585       return "No route to host";
3586     case WSAEPROCLIM:
3587       return "Too many processes";
3588     case WSAEDISCON:
3589       return "Graceful shutdown in progress";
3590     case WSATYPE_NOT_FOUND:
3591       return "Class type not found";
3592     case WSAHOST_NOT_FOUND:
3593       return "Host not found";
3594     case WSATRY_AGAIN:
3595       return "Nonauthoritative host not found";
3596     case WSANO_RECOVERY:
3597       return "This is a nonrecoverable error";
3598     case WSANO_DATA:
3599       return "Valid name, no data record of requested type";
3600     case WSA_INVALID_HANDLE:
3601       return "Specified event object handle is invalid";
3602     case WSA_INVALID_PARAMETER:
3603       return "One or more parameters are invalid";
3604     case WSA_IO_INCOMPLETE:
3605       return "Overlapped I/O event object not in signaled state";
3606     case WSA_IO_PENDING:
3607       return "Overlapped operations will complete later";
3608     case WSA_NOT_ENOUGH_MEMORY:
3609       return "Insufficient memory available";
3610     case WSA_OPERATION_ABORTED:
3611       return "Overlapped operation aborted";
3612 #ifdef WSAINVALIDPROCTABLE
3613
3614     case WSAINVALIDPROCTABLE:
3615       return "Invalid procedure table from service provider";
3616 #endif
3617 #ifdef WSAINVALIDPROVIDER
3618
3619     case WSAINVALIDPROVIDER:
3620       return "Invalid service provider version number";
3621 #endif
3622 #ifdef WSAPROVIDERFAILEDINIT
3623
3624     case WSAPROVIDERFAILEDINIT:
3625       return "Unable to initialize a service provider";
3626 #endif
3627
3628     case WSASYSCALLFAILURE:
3629       return "System call failure";
3630     }
3631   msg = strerror (error_number);
3632   if (msg == NULL)
3633     msg = "unknown";
3634
3635   return msg;
3636 #endif //DBUS_WINCE
3637 }
3638
3639 /**
3640  * Assigns an error name and message corresponding to a Win32 error
3641  * code to a DBusError. Does nothing if error is #NULL.
3642  *
3643  * @param error the error.
3644  * @param code the Win32 error code
3645  */
3646 void
3647 _dbus_win_set_error_from_win_error (DBusError *error,
3648                                     int        code)
3649 {
3650   char *msg;
3651
3652   /* As we want the English message, use the A API */
3653   FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
3654                   FORMAT_MESSAGE_IGNORE_INSERTS |
3655                   FORMAT_MESSAGE_FROM_SYSTEM,
3656                   NULL, code, MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US),
3657                   (LPTSTR) &msg, 0, NULL);
3658   if (msg)
3659     {
3660       char *msg_copy;
3661
3662       msg_copy = dbus_malloc (strlen (msg));
3663       strcpy (msg_copy, msg);
3664       LocalFree (msg);
3665
3666       dbus_set_error (error, "win32.error", "%s", msg_copy);
3667     }
3668   else
3669     dbus_set_error (error, "win32.error", "Unknown error code %d or FormatMessage failed", code);
3670 }
3671
3672 void
3673 _dbus_win_warn_win_error (const char *message,
3674                           int         code)
3675 {
3676   DBusError error;
3677
3678   dbus_error_init (&error);
3679   _dbus_win_set_error_from_win_error (&error, code);
3680   _dbus_warn ("%s: %s\n", message, error.message);
3681   dbus_error_free (&error);
3682 }
3683
3684 /** @} end of sysdeps-win */
3685 /* tests in dbus-sysdeps-util.c */
3686