00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #undef open
00030
00031 #define STRSAFE_NO_DEPRECATE
00032
00033 #ifndef DBUS_WINCE
00034 #define _WIN32_WINNT 0x0500
00035 #endif
00036
00037 #include "dbus-internals.h"
00038 #include "dbus-sysdeps.h"
00039 #include "dbus-threads.h"
00040 #include "dbus-protocol.h"
00041 #include "dbus-string.h"
00042 #include "dbus-sysdeps-win.h"
00043 #include "dbus-protocol.h"
00044 #include "dbus-hash.h"
00045 #include "dbus-sockets-win.h"
00046 #include "dbus-list.h"
00047 #include "dbus-credentials.h"
00048
00049 #include <windows.h>
00050 #include <fcntl.h>
00051
00052 #include <process.h>
00053 #include <sys/stat.h>
00054 #include <sys/types.h>
00055
00056 #ifndef O_BINARY
00057 #define O_BINARY 0
00058 #endif
00059
00060 #ifndef HAVE_SOCKLEN_T
00061 #define socklen_t int
00062 #endif
00063
00068 dbus_bool_t
00069 _dbus_file_open (DBusFile *file,
00070 const char *filename,
00071 int oflag,
00072 int pmode)
00073 {
00074 if (pmode!=-1)
00075 file->FDATA = _open (filename, oflag, pmode);
00076 else
00077 file->FDATA = _open (filename, oflag);
00078 if (file->FDATA >= 0)
00079 return TRUE;
00080 else
00081 {
00082 file->FDATA = -1;
00083 return FALSE;
00084 }
00085 }
00086
00087 dbus_bool_t
00088 _dbus_file_close (DBusFile *file,
00089 DBusError *error)
00090 {
00091 const int fd = file->FDATA;
00092
00093 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00094
00095 _dbus_assert (fd >= 0);
00096
00097 if (_close (fd) == -1)
00098 {
00099 dbus_set_error (error, _dbus_error_from_errno (errno),
00100 "Could not close fd %d: %s", fd,
00101 _dbus_strerror (errno));
00102 return FALSE;
00103 }
00104
00105 file->FDATA = -1;
00106 _dbus_verbose ("closed C file descriptor %d:\n",fd);
00107
00108 return TRUE;
00109 }
00110
00111 int
00112 _dbus_file_read(DBusFile *file,
00113 DBusString *buffer,
00114 int count)
00115 {
00116 const int fd = file->FDATA;
00117 int bytes_read;
00118 int start;
00119 char *data;
00120 _dbus_assert (count >= 0);
00121
00122 start = _dbus_string_get_length (buffer);
00123
00124 if (!_dbus_string_lengthen (buffer, count))
00125 {
00126 errno = ENOMEM;
00127 return -1;
00128 }
00129
00130 data = _dbus_string_get_data_len (buffer, start, count);
00131
00132 _dbus_assert (fd >= 0);
00133
00134 _dbus_verbose ("read: count=%d fd=%d\n", count, fd);
00135 bytes_read = read (fd, data, count);
00136
00137 if (bytes_read == -1)
00138 _dbus_verbose ("read: failed: %s\n", _dbus_strerror (errno));
00139 else
00140 _dbus_verbose ("read: = %d\n", bytes_read);
00141
00142 if (bytes_read < 0)
00143 {
00144
00145 _dbus_string_set_length (buffer, start);
00146 return -1;
00147 }
00148 else
00149 {
00150
00151 _dbus_string_set_length (buffer, start + bytes_read);
00152
00153 #if 0
00154
00155 if (bytes_read > 0)
00156 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00157 #endif
00158
00159 return bytes_read;
00160 }
00161 }
00162
00163 int
00164 _dbus_file_write (DBusFile *file,
00165 const DBusString *buffer,
00166 int start,
00167 int len)
00168 {
00169 const int fd = file->FDATA;
00170 const char *data;
00171 int bytes_written;
00172
00173 data = _dbus_string_get_const_data_len (buffer, start, len);
00174
00175 _dbus_assert (fd >= 0);
00176
00177 _dbus_verbose ("write: len=%d fd=%d\n", len, fd);
00178 bytes_written = write (fd, data, len);
00179
00180 if (bytes_written == -1)
00181 _dbus_verbose ("write: failed: %s\n", _dbus_strerror (errno));
00182 else
00183 _dbus_verbose ("write: = %d\n", bytes_written);
00184
00185 #if 0
00186
00187 if (bytes_written > 0)
00188 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00189 #endif
00190
00191 return bytes_written;
00192 }
00193
00194 dbus_bool_t
00195 _dbus_is_valid_file (DBusFile* file)
00196 {
00197 return file->FDATA >= 0;
00198 }
00199
00200 dbus_bool_t _dbus_fstat (DBusFile *file,
00201 struct stat *sb)
00202 {
00203 return fstat(file->FDATA, sb) >= 0;
00204 }
00205
00216 int
00217 _dbus_pipe_write (DBusPipe *pipe,
00218 const DBusString *buffer,
00219 int start,
00220 int len,
00221 DBusError *error)
00222 {
00223 int written;
00224 DBusFile file;
00225 file.FDATA = pipe->fd_or_handle;
00226 written = _dbus_file_write (&file, buffer, start, len);
00227 if (written < 0)
00228 {
00229 dbus_set_error (error, DBUS_ERROR_FAILED,
00230 "Writing to pipe: %s\n",
00231 _dbus_strerror (errno));
00232 }
00233 return written;
00234 }
00235
00243 int
00244 _dbus_pipe_close (DBusPipe *pipe,
00245 DBusError *error)
00246 {
00247 DBusFile file;
00248 file.FDATA = pipe->fd_or_handle;
00249 if (_dbus_file_close (&file, error) < 0)
00250 {
00251 return -1;
00252 }
00253 else
00254 {
00255 _dbus_pipe_invalidate (pipe);
00256 return 0;
00257 }
00258 }
00259
00260 #undef FDATA
00261
00280 int
00281 _dbus_read_socket (int fd,
00282 DBusString *buffer,
00283 int count)
00284 {
00285 int bytes_read;
00286 int start;
00287 char *data;
00288
00289 _dbus_assert (count >= 0);
00290
00291 start = _dbus_string_get_length (buffer);
00292
00293 if (!_dbus_string_lengthen (buffer, count))
00294 {
00295 errno = ENOMEM;
00296 return -1;
00297 }
00298
00299 data = _dbus_string_get_data_len (buffer, start, count);
00300
00301 again:
00302
00303 _dbus_verbose ("recv: count=%d fd=%d\n", count, fd);
00304 bytes_read = recv (fd, data, count, 0);
00305
00306 if (bytes_read == SOCKET_ERROR)
00307 {
00308 DBUS_SOCKET_SET_ERRNO();
00309 _dbus_verbose ("recv: failed: %s\n", _dbus_strerror (errno));
00310 bytes_read = -1;
00311 }
00312 else
00313 _dbus_verbose ("recv: = %d\n", bytes_read);
00314
00315 if (bytes_read < 0)
00316 {
00317 if (errno == EINTR)
00318 goto again;
00319 else
00320 {
00321
00322 _dbus_string_set_length (buffer, start);
00323 return -1;
00324 }
00325 }
00326 else
00327 {
00328
00329 _dbus_string_set_length (buffer, start + bytes_read);
00330
00331 #if 0
00332 if (bytes_read > 0)
00333 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00334 #endif
00335
00336 return bytes_read;
00337 }
00338 }
00339
00350 int
00351 _dbus_write_socket (int fd,
00352 const DBusString *buffer,
00353 int start,
00354 int len)
00355 {
00356 const char *data;
00357 int bytes_written;
00358
00359 data = _dbus_string_get_const_data_len (buffer, start, len);
00360
00361 again:
00362
00363 _dbus_verbose ("send: len=%d fd=%d\n", len, fd);
00364 bytes_written = send (fd, data, len, 0);
00365
00366 if (bytes_written == SOCKET_ERROR)
00367 {
00368 DBUS_SOCKET_SET_ERRNO();
00369 _dbus_verbose ("send: failed: %s\n", _dbus_strerror (errno));
00370 bytes_written = -1;
00371 }
00372 else
00373 _dbus_verbose ("send: = %d\n", bytes_written);
00374
00375 if (bytes_written < 0 && errno == EINTR)
00376 goto again;
00377
00378 #if 0
00379 if (bytes_written > 0)
00380 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00381 #endif
00382
00383 return bytes_written;
00384 }
00385
00386
00394 dbus_bool_t
00395 _dbus_close_socket (int fd,
00396 DBusError *error)
00397 {
00398 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00399
00400 again:
00401 if (closesocket (fd) == SOCKET_ERROR)
00402 {
00403 DBUS_SOCKET_SET_ERRNO ();
00404
00405 if (errno == EINTR)
00406 goto again;
00407
00408 dbus_set_error (error, _dbus_error_from_errno (errno),
00409 "Could not close socket: socket=%d, , %s",
00410 fd, _dbus_strerror (errno));
00411 return FALSE;
00412 }
00413 _dbus_verbose ("_dbus_close_socket: socket=%d, \n", fd);
00414
00415 return TRUE;
00416 }
00417
00425 void
00426 _dbus_fd_set_close_on_exec (int handle)
00427 {
00428 #ifdef ENABLE_DBUSSOCKET
00429 DBusSocket *s;
00430 if (handle < 0)
00431 return;
00432
00433 _dbus_lock_sockets();
00434
00435 _dbus_handle_to_socket_unlocked (handle, &s);
00436 s->close_on_exec = TRUE;
00437
00438 _dbus_unlock_sockets();
00439 #else
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452 #endif
00453 }
00454
00462 dbus_bool_t
00463 _dbus_set_fd_nonblocking (int handle,
00464 DBusError *error)
00465 {
00466 u_long one = 1;
00467
00468 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00469
00470 if (ioctlsocket (handle, FIONBIO, &one) == SOCKET_ERROR)
00471 {
00472 dbus_set_error (error, _dbus_error_from_errno (WSAGetLastError ()),
00473 "Failed to set socket %d:%d to nonblocking: %s", handle,
00474 _dbus_strerror (WSAGetLastError ()));
00475 return FALSE;
00476 }
00477
00478 return TRUE;
00479 }
00480
00481
00502 int
00503 _dbus_write_socket_two (int fd,
00504 const DBusString *buffer1,
00505 int start1,
00506 int len1,
00507 const DBusString *buffer2,
00508 int start2,
00509 int len2)
00510 {
00511 WSABUF vectors[2];
00512 const char *data1;
00513 const char *data2;
00514 int rc;
00515 DWORD bytes_written;
00516 int ret1;
00517
00518 _dbus_assert (buffer1 != NULL);
00519 _dbus_assert (start1 >= 0);
00520 _dbus_assert (start2 >= 0);
00521 _dbus_assert (len1 >= 0);
00522 _dbus_assert (len2 >= 0);
00523
00524
00525 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00526
00527 if (buffer2 != NULL)
00528 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00529 else
00530 {
00531 data2 = NULL;
00532 start2 = 0;
00533 len2 = 0;
00534 }
00535
00536 vectors[0].buf = (char*) data1;
00537 vectors[0].len = len1;
00538 vectors[1].buf = (char*) data2;
00539 vectors[1].len = len2;
00540
00541 again:
00542
00543 _dbus_verbose ("WSASend: len1+2=%d+%d fd=%d\n", len1, len2, fd);
00544 rc = WSASend (fd,
00545 vectors,
00546 data2 ? 2 : 1,
00547 &bytes_written,
00548 0,
00549 NULL,
00550 NULL);
00551
00552 if (rc < 0)
00553 {
00554 DBUS_SOCKET_SET_ERRNO ();
00555 _dbus_verbose ("WSASend: failed: %s\n", _dbus_strerror (errno));
00556 bytes_written = -1;
00557 }
00558 else
00559 _dbus_verbose ("WSASend: = %ld\n", bytes_written);
00560
00561 if (bytes_written < 0 && errno == EINTR)
00562 goto again;
00563
00564 return bytes_written;
00565 }
00566
00567 #if 0
00568
00577 int
00578 _dbus_connect_named_pipe (const char *path,
00579 DBusError *error)
00580 {
00581 _dbus_assert_not_reached ("not implemented");
00582 }
00583
00584 #endif
00585
00586
00587
00588 void
00589 _dbus_win_startup_winsock (void)
00590 {
00591
00592
00593 static dbus_bool_t beenhere = FALSE;
00594
00595 WORD wVersionRequested;
00596 WSADATA wsaData;
00597 int err;
00598
00599 if (beenhere)
00600 return;
00601
00602 wVersionRequested = MAKEWORD (2, 0);
00603
00604 err = WSAStartup (wVersionRequested, &wsaData);
00605 if (err != 0)
00606 {
00607 _dbus_assert_not_reached ("Could not initialize WinSock");
00608 _dbus_abort ();
00609 }
00610
00611
00612
00613
00614
00615
00616 if (LOBYTE (wsaData.wVersion) != 2 ||
00617 HIBYTE (wsaData.wVersion) != 0)
00618 {
00619 _dbus_assert_not_reached ("No usable WinSock found");
00620 _dbus_abort ();
00621 }
00622
00623 beenhere = TRUE;
00624 }
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00643 int _dbus_printf_string_upper_bound (const char *format,
00644 va_list args)
00645 {
00646
00647
00648
00649
00650
00651
00652
00653
00654 char p[1024];
00655 int len;
00656 len = _vsnprintf (p, sizeof(p)-1, format, args);
00657 if (len == -1)
00658 {
00659 char *p;
00660 p = malloc (strlen(format)*3);
00661 len = _vsnprintf (p, sizeof(p)-1, format, args);
00662 free(p);
00663 }
00664 return len;
00665 }
00666
00667
00675 wchar_t *
00676 _dbus_win_utf8_to_utf16 (const char *str,
00677 DBusError *error)
00678 {
00679 DBusString s;
00680 int n;
00681 wchar_t *retval;
00682
00683 _dbus_string_init_const (&s, str);
00684
00685 if (!_dbus_string_validate_utf8 (&s, 0, _dbus_string_get_length (&s)))
00686 {
00687 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid UTF-8");
00688 return NULL;
00689 }
00690
00691 n = MultiByteToWideChar (CP_UTF8, 0, str, -1, NULL, 0);
00692
00693 if (n == 0)
00694 {
00695 _dbus_win_set_error_from_win_error (error, GetLastError ());
00696 return NULL;
00697 }
00698
00699 retval = dbus_new (wchar_t, n);
00700
00701 if (!retval)
00702 {
00703 _DBUS_SET_OOM (error);
00704 return NULL;
00705 }
00706
00707 if (MultiByteToWideChar (CP_UTF8, 0, str, -1, retval, n) != n)
00708 {
00709 dbus_free (retval);
00710 dbus_set_error_const (error, DBUS_ERROR_FAILED, "MultiByteToWideChar inconsistency");
00711 return NULL;
00712 }
00713
00714 return retval;
00715 }
00716
00724 char *
00725 _dbus_win_utf16_to_utf8 (const wchar_t *str,
00726 DBusError *error)
00727 {
00728 int n;
00729 char *retval;
00730
00731 n = WideCharToMultiByte (CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
00732
00733 if (n == 0)
00734 {
00735 _dbus_win_set_error_from_win_error (error, GetLastError ());
00736 return NULL;
00737 }
00738
00739 retval = dbus_malloc (n);
00740
00741 if (!retval)
00742 {
00743 _DBUS_SET_OOM (error);
00744 return NULL;
00745 }
00746
00747 if (WideCharToMultiByte (CP_UTF8, 0, str, -1, retval, n, NULL, NULL) != n)
00748 {
00749 dbus_free (retval);
00750 dbus_set_error_const (error, DBUS_ERROR_FAILED, "WideCharToMultiByte inconsistency");
00751 return NULL;
00752 }
00753
00754 return retval;
00755 }
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767 dbus_bool_t
00768 _dbus_win_account_to_sid (const wchar_t *waccount,
00769 void **ppsid,
00770 DBusError *error)
00771 {
00772 dbus_bool_t retval = FALSE;
00773 DWORD sid_length, wdomain_length;
00774 SID_NAME_USE use;
00775 wchar_t *wdomain;
00776
00777 *ppsid = NULL;
00778
00779 sid_length = 0;
00780 wdomain_length = 0;
00781 if (!LookupAccountNameW (NULL, waccount, NULL, &sid_length,
00782 NULL, &wdomain_length, &use) &&
00783 GetLastError () != ERROR_INSUFFICIENT_BUFFER)
00784 {
00785 _dbus_win_set_error_from_win_error (error, GetLastError ());
00786 return FALSE;
00787 }
00788
00789 *ppsid = dbus_malloc (sid_length);
00790 if (!*ppsid)
00791 {
00792 _DBUS_SET_OOM (error);
00793 return FALSE;
00794 }
00795
00796 wdomain = dbus_new (wchar_t, wdomain_length);
00797 if (!wdomain)
00798 {
00799 _DBUS_SET_OOM (error);
00800 goto out1;
00801 }
00802
00803 if (!LookupAccountNameW (NULL, waccount, (PSID) *ppsid, &sid_length,
00804 wdomain, &wdomain_length, &use))
00805 {
00806 _dbus_win_set_error_from_win_error (error, GetLastError ());
00807 goto out2;
00808 }
00809
00810 if (!IsValidSid ((PSID) *ppsid))
00811 {
00812 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid SID");
00813 goto out2;
00814 }
00815
00816 retval = TRUE;
00817
00818 out2:
00819 dbus_free (wdomain);
00820 out1:
00821 if (!retval)
00822 {
00823 dbus_free (*ppsid);
00824 *ppsid = NULL;
00825 }
00826
00827 return retval;
00828 }
00829
00836 dbus_uid_t
00837 _dbus_getuid (void)
00838 {
00839 return DBUS_UID_UNSET;
00840 }
00841
00845 dbus_uid_t
00846 _dbus_geteuid (void)
00847 {
00848 return DBUS_UID_UNSET;
00849 }
00850
00857 unsigned long
00858 _dbus_pid_for_log (void)
00859 {
00860 return _dbus_getpid ();
00861 }
00862
00867 dbus_bool_t
00868 _dbus_getsid(char **sid)
00869 {
00870 HANDLE process_token = NULL;
00871 TOKEN_USER *token_user = NULL;
00872 DWORD n;
00873 PSID psid;
00874 int retval = FALSE;
00875
00876 if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &process_token))
00877 {
00878 _dbus_win_warn_win_error ("OpenProcessToken failed", GetLastError ());
00879 goto failed;
00880 }
00881 if ((!GetTokenInformation (process_token, TokenUser, NULL, 0, &n)
00882 && GetLastError () != ERROR_INSUFFICIENT_BUFFER)
00883 || (token_user = alloca (n)) == NULL
00884 || !GetTokenInformation (process_token, TokenUser, token_user, n, &n))
00885 {
00886 _dbus_win_warn_win_error ("GetTokenInformation failed", GetLastError ());
00887 goto failed;
00888 }
00889 psid = token_user->User.Sid;
00890 if (!IsValidSid (psid))
00891 {
00892 _dbus_verbose("%s invalid sid\n",__FUNCTION__);
00893 goto failed;
00894 }
00895 if (!ConvertSidToStringSidA (psid, sid))
00896 {
00897 _dbus_verbose("%s invalid sid\n",__FUNCTION__);
00898 goto failed;
00899 }
00900
00901 retval = TRUE;
00902
00903 failed:
00904 if (process_token != NULL)
00905 CloseHandle (process_token);
00906
00907 _dbus_verbose("_dbus_getsid() returns %d\n",retval);
00908 return retval;
00909 }
00910
00911
00912 #ifdef DBUS_BUILD_TESTS
00913
00916 dbus_gid_t
00917 _dbus_getgid (void)
00918 {
00919 return DBUS_GID_UNSET;
00920 }
00921
00922 #if 0
00923 dbus_bool_t
00924 _dbus_domain_test (const char *test_data_dir)
00925 {
00926 if (!_dbus_test_oom_handling ("spawn_nonexistent",
00927 check_spawn_nonexistent,
00928 NULL))
00929 return FALSE;
00930 }
00931
00932 #endif
00933
00934 #endif //DBUS_BUILD_TESTS
00935
00936
00937
00938
00939
00940
00941
00957 dbus_bool_t
00958 _dbus_full_duplex_pipe (int *fd1,
00959 int *fd2,
00960 dbus_bool_t blocking,
00961 DBusError *error)
00962 {
00963 SOCKET temp, socket1 = -1, socket2 = -1;
00964 struct sockaddr_in saddr;
00965 int len;
00966 u_long arg;
00967 fd_set read_set, write_set;
00968 struct timeval tv;
00969
00970 _dbus_win_startup_winsock ();
00971
00972 temp = socket (AF_INET, SOCK_STREAM, 0);
00973 if (temp == INVALID_SOCKET)
00974 {
00975 DBUS_SOCKET_SET_ERRNO ();
00976 goto out0;
00977 }
00978
00979 arg = 1;
00980 if (ioctlsocket (temp, FIONBIO, &arg) == SOCKET_ERROR)
00981 {
00982 DBUS_SOCKET_SET_ERRNO ();
00983 goto out0;
00984 }
00985
00986 _DBUS_ZERO (saddr);
00987 saddr.sin_family = AF_INET;
00988 saddr.sin_port = 0;
00989 saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
00990
00991 if (bind (temp, (struct sockaddr *)&saddr, sizeof (saddr)))
00992 {
00993 DBUS_SOCKET_SET_ERRNO ();
00994 goto out0;
00995 }
00996
00997 if (listen (temp, 1) == SOCKET_ERROR)
00998 {
00999 DBUS_SOCKET_SET_ERRNO ();
01000 goto out0;
01001 }
01002
01003 len = sizeof (saddr);
01004 if (getsockname (temp, (struct sockaddr *)&saddr, &len))
01005 {
01006 DBUS_SOCKET_SET_ERRNO ();
01007 goto out0;
01008 }
01009
01010 socket1 = socket (AF_INET, SOCK_STREAM, 0);
01011 if (socket1 == INVALID_SOCKET)
01012 {
01013 DBUS_SOCKET_SET_ERRNO ();
01014 goto out0;
01015 }
01016
01017 arg = 1;
01018 if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR)
01019 {
01020 DBUS_SOCKET_SET_ERRNO ();
01021 goto out1;
01022 }
01023
01024 if (connect (socket1, (struct sockaddr *)&saddr, len) != SOCKET_ERROR ||
01025 WSAGetLastError () != WSAEWOULDBLOCK)
01026 {
01027 DBUS_SOCKET_SET_ERRNO ();
01028 goto out1;
01029 }
01030
01031 FD_ZERO (&read_set);
01032 FD_SET (temp, &read_set);
01033
01034 tv.tv_sec = 0;
01035 tv.tv_usec = 0;
01036
01037 if (select (0, &read_set, NULL, NULL, NULL) == SOCKET_ERROR)
01038 {
01039 DBUS_SOCKET_SET_ERRNO ();
01040 goto out1;
01041 }
01042
01043 _dbus_assert (FD_ISSET (temp, &read_set));
01044
01045 socket2 = accept (temp, (struct sockaddr *) &saddr, &len);
01046 if (socket2 == INVALID_SOCKET)
01047 {
01048 DBUS_SOCKET_SET_ERRNO ();
01049 goto out1;
01050 }
01051
01052 FD_ZERO (&write_set);
01053 FD_SET (socket1, &write_set);
01054
01055 tv.tv_sec = 0;
01056 tv.tv_usec = 0;
01057
01058 if (select (0, NULL, &write_set, NULL, NULL) == SOCKET_ERROR)
01059 {
01060 DBUS_SOCKET_SET_ERRNO ();
01061 goto out2;
01062 }
01063
01064 _dbus_assert (FD_ISSET (socket1, &write_set));
01065
01066 if (blocking)
01067 {
01068 arg = 0;
01069 if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR)
01070 {
01071 DBUS_SOCKET_SET_ERRNO ();
01072 goto out2;
01073 }
01074
01075 arg = 0;
01076 if (ioctlsocket (socket2, FIONBIO, &arg) == SOCKET_ERROR)
01077 {
01078 DBUS_SOCKET_SET_ERRNO ();
01079 goto out2;
01080 }
01081 }
01082 else
01083 {
01084 arg = 1;
01085 if (ioctlsocket (socket2, FIONBIO, &arg) == SOCKET_ERROR)
01086 {
01087 DBUS_SOCKET_SET_ERRNO ();
01088 goto out2;
01089 }
01090 }
01091
01092 *fd1 = socket1;
01093 *fd2 = socket2;
01094
01095 _dbus_verbose ("full-duplex pipe %d:%d <-> %d:%d\n",
01096 *fd1, socket1, *fd2, socket2);
01097
01098 closesocket (temp);
01099
01100 return TRUE;
01101
01102 out2:
01103 closesocket (socket2);
01104 out1:
01105 closesocket (socket1);
01106 out0:
01107 closesocket (temp);
01108
01109 dbus_set_error (error, _dbus_error_from_errno (errno),
01110 "Could not setup socket pair: %s",
01111 _dbus_strerror (errno));
01112
01113 return FALSE;
01114 }
01115
01124 #define USE_CHRIS_IMPL 0
01125 #if USE_CHRIS_IMPL
01126 int
01127 _dbus_poll (DBusPollFD *fds,
01128 int n_fds,
01129 int timeout_milliseconds)
01130 {
01131 #define DBUS_POLL_CHAR_BUFFER_SIZE 2000
01132 char msg[DBUS_POLL_CHAR_BUFFER_SIZE];
01133 char *msgp;
01134
01135 int ret = 0;
01136 int i;
01137 struct timeval tv;
01138 int ready;
01139
01140 #define DBUS_STACK_WSAEVENTS 256
01141 WSAEVENT eventsOnStack[DBUS_STACK_WSAEVENTS];
01142 WSAEVENT *pEvents = NULL;
01143 if (n_fds > DBUS_STACK_WSAEVENTS)
01144 pEvents = calloc(sizeof(WSAEVENT), n_fds);
01145 else
01146 pEvents = eventsOnStack;
01147
01148
01149 #ifdef DBUS_ENABLE_VERBOSE_MODE
01150 msgp = msg;
01151 msgp += sprintf (msgp, "WSAEventSelect: to=%d\n\t", timeout_milliseconds);
01152 for (i = 0; i < n_fds; i++)
01153 {
01154 static dbus_bool_t warned = FALSE;
01155 DBusPollFD *fdp = &fds[i];
01156
01157
01158 if (fdp->events & _DBUS_POLLIN)
01159 msgp += sprintf (msgp, "R:%d ", fdp->fd);
01160
01161 if (fdp->events & _DBUS_POLLOUT)
01162 msgp += sprintf (msgp, "W:%d ", fdp->fd);
01163
01164 msgp += sprintf (msgp, "E:%d\n\t", fdp->fd);
01165
01166
01167
01168 if (msgp >= msg + DBUS_POLL_CHAR_BUFFER_SIZE)
01169 {
01170 _dbus_assert_not_reached ("buffer overflow in _dbus_poll");
01171 }
01172 }
01173
01174 msgp += sprintf (msgp, "\n");
01175 _dbus_verbose ("%s",msg);
01176 #endif
01177 for (i = 0; i < n_fds; i++)
01178 {
01179 DBusPollFD *fdp = &fds[i];
01180 WSAEVENT ev;
01181 long lNetworkEvents = FD_OOB;
01182
01183 ev = WSACreateEvent();
01184
01185 if (fdp->events & _DBUS_POLLIN)
01186 lNetworkEvents |= FD_READ | FD_ACCEPT | FD_CLOSE;
01187
01188 if (fdp->events & _DBUS_POLLOUT)
01189 lNetworkEvents |= FD_WRITE | FD_CONNECT;
01190
01191 WSAEventSelect(fdp->fd, ev, lNetworkEvents);
01192
01193 pEvents[i] = ev;
01194 }
01195
01196
01197 ready = WSAWaitForMultipleEvents (n_fds, pEvents, FALSE, timeout_milliseconds, FALSE);
01198
01199 if (DBUS_SOCKET_API_RETURNS_ERROR (ready))
01200 {
01201 DBUS_SOCKET_SET_ERRNO ();
01202 if (errno != EWOULDBLOCK)
01203 _dbus_verbose ("WSAWaitForMultipleEvents: failed: %s\n", _dbus_strerror (errno));
01204 ret = -1;
01205 }
01206 else if (ready == WSA_WAIT_TIMEOUT)
01207 {
01208 _dbus_verbose ("WSAWaitForMultipleEvents: WSA_WAIT_TIMEOUT\n");
01209 ret = 0;
01210 }
01211 else if (ready >= WSA_WAIT_EVENT_0 && ready < (int)(WSA_WAIT_EVENT_0 + n_fds))
01212 {
01213 msgp = msg;
01214 msgp += sprintf (msgp, "WSAWaitForMultipleEvents: =%d\n\t", ready);
01215
01216 for (i = 0; i < n_fds; i++)
01217 {
01218 DBusPollFD *fdp = &fds[i];
01219 WSANETWORKEVENTS ne;
01220
01221 fdp->revents = 0;
01222
01223 WSAEnumNetworkEvents(fdp->fd, pEvents[i], &ne);
01224
01225 if (ne.lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
01226 fdp->revents |= _DBUS_POLLIN;
01227
01228 if (ne.lNetworkEvents & (FD_WRITE | FD_CONNECT))
01229 fdp->revents |= _DBUS_POLLOUT;
01230
01231 if (ne.lNetworkEvents & (FD_OOB))
01232 fdp->revents |= _DBUS_POLLERR;
01233
01234 if (ne.lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
01235 msgp += sprintf (msgp, "R:%d ", fdp->fd);
01236
01237 if (ne.lNetworkEvents & (FD_WRITE | FD_CONNECT))
01238 msgp += sprintf (msgp, "W:%d ", fdp->fd);
01239
01240 if (ne.lNetworkEvents & (FD_OOB))
01241 msgp += sprintf (msgp, "E:%d ", fdp->fd);
01242
01243 msgp += sprintf (msgp, "lNetworkEvents:%d ", ne.lNetworkEvents);
01244
01245 if(ne.lNetworkEvents)
01246 ret++;
01247
01248 WSAEventSelect(fdp->fd, pEvents[i], 0);
01249 }
01250
01251 msgp += sprintf (msgp, "\n");
01252 _dbus_verbose ("%s",msg);
01253 }
01254 else
01255 {
01256 _dbus_verbose ("WSAWaitForMultipleEvents: failed for unknown reason!");
01257 ret = -1;
01258 }
01259
01260 for(i = 0; i < n_fds; i++)
01261 {
01262 WSACloseEvent(pEvents[i]);
01263 }
01264
01265 if (n_fds > DBUS_STACK_WSAEVENTS)
01266 free(pEvents);
01267
01268 return ret;
01269 }
01270
01271 #else // USE_CHRIS_IMPL
01272
01273 int
01274 _dbus_poll (DBusPollFD *fds,
01275 int n_fds,
01276 int timeout_milliseconds)
01277 {
01278 #define DBUS_POLL_CHAR_BUFFER_SIZE 2000
01279 char msg[DBUS_POLL_CHAR_BUFFER_SIZE];
01280 char *msgp;
01281
01282 fd_set read_set, write_set, err_set;
01283 int max_fd = 0;
01284 int i;
01285 struct timeval tv;
01286 int ready;
01287
01288 FD_ZERO (&read_set);
01289 FD_ZERO (&write_set);
01290 FD_ZERO (&err_set);
01291
01292
01293 #ifdef DBUS_ENABLE_VERBOSE_MODE
01294 msgp = msg;
01295 msgp += sprintf (msgp, "select: to=%d\n\t", timeout_milliseconds);
01296 for (i = 0; i < n_fds; i++)
01297 {
01298 static dbus_bool_t warned = FALSE;
01299 DBusPollFD *fdp = &fds[i];
01300
01301
01302 if (fdp->events & _DBUS_POLLIN)
01303 msgp += sprintf (msgp, "R:%d ", fdp->fd);
01304
01305 if (fdp->events & _DBUS_POLLOUT)
01306 msgp += sprintf (msgp, "W:%d ", fdp->fd);
01307
01308 msgp += sprintf (msgp, "E:%d\n\t", fdp->fd);
01309
01310
01311
01312 if (msgp >= msg + DBUS_POLL_CHAR_BUFFER_SIZE)
01313 {
01314 _dbus_assert_not_reached ("buffer overflow in _dbus_poll");
01315 }
01316 }
01317
01318 msgp += sprintf (msgp, "\n");
01319 _dbus_verbose ("%s",msg);
01320 #endif
01321 for (i = 0; i < n_fds; i++)
01322 {
01323 DBusPollFD *fdp = &fds[i];
01324
01325 if (fdp->events & _DBUS_POLLIN)
01326 FD_SET (fdp->fd, &read_set);
01327
01328 if (fdp->events & _DBUS_POLLOUT)
01329 FD_SET (fdp->fd, &write_set);
01330
01331 FD_SET (fdp->fd, &err_set);
01332
01333 max_fd = MAX (max_fd, fdp->fd);
01334 }
01335
01336
01337 tv.tv_sec = timeout_milliseconds / 1000;
01338 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
01339
01340 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
01341 timeout_milliseconds < 0 ? NULL : &tv);
01342
01343 if (DBUS_SOCKET_API_RETURNS_ERROR (ready))
01344 {
01345 DBUS_SOCKET_SET_ERRNO ();
01346 if (errno != EWOULDBLOCK)
01347 _dbus_verbose ("select: failed: %s\n", _dbus_strerror (errno));
01348 }
01349 else if (ready == 0)
01350 _dbus_verbose ("select: = 0\n");
01351 else
01352 if (ready > 0)
01353 {
01354 #ifdef DBUS_ENABLE_VERBOSE_MODE
01355 msgp = msg;
01356 msgp += sprintf (msgp, "select: = %d:\n\t", ready);
01357
01358 for (i = 0; i < n_fds; i++)
01359 {
01360 DBusPollFD *fdp = &fds[i];
01361
01362 if (FD_ISSET (fdp->fd, &read_set))
01363 msgp += sprintf (msgp, "R:%d ", fdp->fd);
01364
01365 if (FD_ISSET (fdp->fd, &write_set))
01366 msgp += sprintf (msgp, "W:%d ", fdp->fd);
01367
01368 if (FD_ISSET (fdp->fd, &err_set))
01369 msgp += sprintf (msgp, "E:%d\n\t", fdp->fd);
01370 }
01371 msgp += sprintf (msgp, "\n");
01372 _dbus_verbose ("%s",msg);
01373 #endif
01374
01375 for (i = 0; i < n_fds; i++)
01376 {
01377 DBusPollFD *fdp = &fds[i];
01378
01379 fdp->revents = 0;
01380
01381 if (FD_ISSET (fdp->fd, &read_set))
01382 fdp->revents |= _DBUS_POLLIN;
01383
01384 if (FD_ISSET (fdp->fd, &write_set))
01385 fdp->revents |= _DBUS_POLLOUT;
01386
01387 if (FD_ISSET (fdp->fd, &err_set))
01388 fdp->revents |= _DBUS_POLLERR;
01389 }
01390 }
01391 return ready;
01392 }
01393
01394 #endif // USE_CHRIS_IMPL
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01435 int _dbus_mkdir (const char *path,
01436 mode_t mode)
01437 {
01438 return _mkdir(path);
01439 }
01440
01446 void
01447 _dbus_exit (int code)
01448 {
01449 _exit (code);
01450 }
01451
01462 int
01463 _dbus_connect_tcp_socket (const char *host,
01464 dbus_uint32_t port,
01465 DBusError *error)
01466 {
01467 int fd;
01468 struct sockaddr_in addr;
01469 struct hostent *he;
01470 struct in_addr *haddr;
01471 struct in_addr ina;
01472
01473 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01474
01475 _dbus_win_startup_winsock ();
01476
01477 fd = socket (AF_INET, SOCK_STREAM, 0);
01478
01479 if (DBUS_SOCKET_IS_INVALID (fd))
01480 {
01481 DBUS_SOCKET_SET_ERRNO ();
01482 dbus_set_error (error,
01483 _dbus_error_from_errno (errno),
01484 "Failed to create socket: %s",
01485 _dbus_strerror (errno));
01486
01487 return -1;
01488 }
01489
01490 if (host == NULL)
01491 {
01492 host = "localhost";
01493 ina.s_addr = htonl (INADDR_LOOPBACK);
01494 haddr = &ina;
01495 }
01496
01497 he = gethostbyname (host);
01498 if (he == NULL)
01499 {
01500 DBUS_SOCKET_SET_ERRNO ();
01501 dbus_set_error (error,
01502 _dbus_error_from_errno (errno),
01503 "Failed to lookup hostname: %s",
01504 host);
01505 DBUS_CLOSE_SOCKET (fd);
01506 return -1;
01507 }
01508
01509 haddr = ((struct in_addr *) (he->h_addr_list)[0]);
01510
01511 _DBUS_ZERO (addr);
01512 memcpy (&addr.sin_addr, haddr, sizeof(struct in_addr));
01513 addr.sin_family = AF_INET;
01514 addr.sin_port = htons (port);
01515
01516 if (DBUS_SOCKET_API_RETURNS_ERROR
01517 (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0))
01518 {
01519 DBUS_SOCKET_SET_ERRNO ();
01520 dbus_set_error (error,
01521 _dbus_error_from_errno (errno),
01522 "Failed to connect to socket %s:%d %s",
01523 host, port, _dbus_strerror (errno));
01524
01525 DBUS_CLOSE_SOCKET (fd);
01526 fd = -1;
01527
01528 return -1;
01529 }
01530
01531 if (!_dbus_set_fd_nonblocking (fd, error))
01532 {
01533 _dbus_close_socket (fd, NULL);
01534 fd = -1;
01535
01536 return -1;
01537 }
01538
01539 return fd;
01540 }
01541
01542 void
01543 _dbus_daemon_init(const char *host, dbus_uint32_t port);
01557 int
01558 _dbus_listen_tcp_socket (const char *host,
01559 dbus_uint32_t *port,
01560 dbus_bool_t inaddr_any,
01561 DBusError *error)
01562 {
01563 int fd;
01564 struct sockaddr_in addr;
01565 struct hostent *he;
01566 struct in_addr *haddr;
01567 socklen_t len = (socklen_t) sizeof (struct sockaddr);
01568 struct in_addr ina;
01569
01570
01571 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01572
01573 _dbus_win_startup_winsock ();
01574
01575 fd = socket (AF_INET, SOCK_STREAM, 0);
01576
01577 if (DBUS_SOCKET_IS_INVALID (fd))
01578 {
01579 DBUS_SOCKET_SET_ERRNO ();
01580 dbus_set_error (error, _dbus_error_from_errno (errno),
01581 "Failed to create socket \"%s:%d\": %s",
01582 host, port, _dbus_strerror (errno));
01583 return -1;
01584 }
01585 if (host == NULL)
01586 {
01587 host = "localhost";
01588 ina.s_addr = htonl (INADDR_LOOPBACK);
01589 haddr = &ina;
01590 }
01591 else if (!host[0])
01592 {
01593 ina.s_addr = htonl (INADDR_ANY);
01594 haddr = &ina;
01595 }
01596 else
01597 {
01598 he = gethostbyname (host);
01599 if (he == NULL)
01600 {
01601 DBUS_SOCKET_SET_ERRNO ();
01602 dbus_set_error (error,
01603 _dbus_error_from_errno (errno),
01604 "Failed to lookup hostname: %s",
01605 host);
01606 DBUS_CLOSE_SOCKET (fd);
01607 return -1;
01608 }
01609
01610 haddr = ((struct in_addr *) (he->h_addr_list)[0]);
01611 }
01612
01613 _DBUS_ZERO (addr);
01614 memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr));
01615 addr.sin_family = AF_INET;
01616 addr.sin_port = htons (*port);
01617
01618 if (bind (fd, (struct sockaddr*) &addr, sizeof (struct sockaddr)))
01619 {
01620 DBUS_SOCKET_SET_ERRNO ();
01621 dbus_set_error (error, _dbus_error_from_errno (errno),
01622 "Failed to bind socket \"%s:%d\": %s",
01623 host, *port, _dbus_strerror (errno));
01624 DBUS_CLOSE_SOCKET (fd);
01625 return -1;
01626 }
01627
01628 if (DBUS_SOCKET_API_RETURNS_ERROR (listen (fd, 30 )))
01629 {
01630 DBUS_SOCKET_SET_ERRNO ();
01631 dbus_set_error (error, _dbus_error_from_errno (errno),
01632 "Failed to listen on socket \"%s:%d\": %s",
01633 host, *port, _dbus_strerror (errno));
01634 DBUS_CLOSE_SOCKET (fd);
01635 return -1;
01636 }
01637
01638 getsockname(fd, (struct sockaddr*) &addr, &len);
01639 *port = (dbus_uint32_t) ntohs(addr.sin_port);
01640
01641 _dbus_daemon_init(host, ntohs(addr.sin_port));
01642
01643 if (!_dbus_set_fd_nonblocking (fd, error))
01644 {
01645 _dbus_close_socket (fd, NULL);
01646 return -1;
01647 }
01648
01649 return fd;
01650 }
01651
01652
01660 int
01661 _dbus_accept (int listen_fd)
01662 {
01663 int client_fd;
01664 struct sockaddr addr;
01665 socklen_t addrlen;
01666
01667 addrlen = sizeof (addr);
01668
01669 retry:
01670 client_fd = accept (listen_fd, &addr, &addrlen);
01671
01672 if (DBUS_SOCKET_IS_INVALID (client_fd))
01673 {
01674 DBUS_SOCKET_SET_ERRNO ();
01675 if (errno == EINTR)
01676 goto retry;
01677 }
01678
01679 _dbus_verbose ("client fd %d accepted\n", client_fd);
01680
01681 return client_fd;
01682 }
01683
01684
01685
01686
01687 dbus_bool_t
01688 _dbus_send_credentials_socket (int handle,
01689 DBusError *error)
01690 {
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714 int bytes_written;
01715 DBusString buf;
01716
01717 _dbus_string_init_const_len (&buf, "\0", 1);
01718 again:
01719 bytes_written = _dbus_write_socket (handle, &buf, 0, 1 );
01720
01721 if (bytes_written < 0 && errno == EINTR)
01722 goto again;
01723
01724 if (bytes_written < 0)
01725 {
01726 dbus_set_error (error, _dbus_error_from_errno (errno),
01727 "Failed to write credentials byte: %s",
01728 _dbus_strerror (errno));
01729 return FALSE;
01730 }
01731 else if (bytes_written == 0)
01732 {
01733 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
01734 "wrote zero bytes writing credentials byte");
01735 return FALSE;
01736 }
01737 else
01738 {
01739 _dbus_assert (bytes_written == 1);
01740 _dbus_verbose ("wrote 1 zero byte, credential sending isn't implemented yet\n");
01741 return TRUE;
01742 }
01743 return TRUE;
01744 }
01745
01764 dbus_bool_t
01765 _dbus_read_credentials_socket (int handle,
01766 DBusCredentials *credentials,
01767 DBusError *error)
01768 {
01769 int bytes_read = 0;
01770 DBusString buf;
01771
01772
01773 if (_dbus_string_init(&buf))
01774 {
01775 bytes_read = _dbus_read_socket(handle, &buf, 1 );
01776
01777 if (bytes_read > 0)
01778 _dbus_verbose("got one zero byte from server");
01779
01780 _dbus_string_free(&buf);
01781 }
01782
01783 _dbus_credentials_add_from_current_process (credentials);
01784 _dbus_verbose("FIXME: get faked credentials from current process");
01785
01786 return TRUE;
01787 }
01788
01797 dbus_bool_t
01798 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
01799 {
01800 const char *directory;
01801 struct stat sb;
01802
01803 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01804
01805 return TRUE;
01806 }
01807
01808
01819 dbus_bool_t
01820 _dbus_concat_dir_and_file (DBusString *dir,
01821 const DBusString *next_component)
01822 {
01823 dbus_bool_t dir_ends_in_slash;
01824 dbus_bool_t file_starts_with_slash;
01825
01826 if (_dbus_string_get_length (dir) == 0 ||
01827 _dbus_string_get_length (next_component) == 0)
01828 return TRUE;
01829
01830 dir_ends_in_slash =
01831 ('/' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1) ||
01832 '\\' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1));
01833
01834 file_starts_with_slash =
01835 ('/' == _dbus_string_get_byte (next_component, 0) ||
01836 '\\' == _dbus_string_get_byte (next_component, 0));
01837
01838 if (dir_ends_in_slash && file_starts_with_slash)
01839 {
01840 _dbus_string_shorten (dir, 1);
01841 }
01842 else if (!(dir_ends_in_slash || file_starts_with_slash))
01843 {
01844 if (!_dbus_string_append_byte (dir, '\\'))
01845 return FALSE;
01846 }
01847
01848 return _dbus_string_copy (next_component, 0, dir,
01849 _dbus_string_get_length (dir));
01850 }
01851
01852
01853
01861
01862
01863
01864
01865
01866
01867
01868
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01934
01935
01936
01937
01938
01939
01941
01943
01945
01947
01949
01950
01955
01956
01957
01958
01959
01960
01961
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980 *time64 -= DBUS_INT64_CONSTANT (116444736000000000);
01981 *time64 /= 10;
01982
01983 if (tv_sec)
01984 *tv_sec = *time64 / 1000000;
01985
01986 if (tv_usec)
01987 *tv_usec = *time64 % 1000000;
01988 }
01989
01990
01994 void
01995 _dbus_disable_sigpipe (void)
01996 {
01997 _dbus_verbose("FIXME: implement _dbus_disable_sigpipe (void)\n");
01998 }
01999
02000
02011 dbus_bool_t
02012 _dbus_file_get_contents (DBusString *str,
02013 const DBusString *filename,
02014 DBusError *error)
02015 {
02016 DBusFile file;
02017 struct stat sb;
02018 int orig_len;
02019 int total;
02020 const char *filename_c;
02021
02022 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02023
02024 filename_c = _dbus_string_get_const_data (filename);
02025
02026
02027 if (!_dbus_file_open (&file, filename_c, O_RDONLY | O_BINARY, -1))
02028 {
02029 dbus_set_error (error, _dbus_error_from_errno (errno),
02030 "Failed to open \"%s\": %s",
02031 filename_c,
02032 _dbus_strerror (errno));
02033 return FALSE;
02034 }
02035
02036 if (!_dbus_fstat (&file, &sb))
02037 {
02038 dbus_set_error (error, _dbus_error_from_errno (errno),
02039 "Failed to stat \"%s\": %s",
02040 filename_c,
02041 _dbus_strerror (errno));
02042
02043 _dbus_verbose ("fstat() failed: %s",
02044 _dbus_strerror (errno));
02045
02046 _dbus_file_close (&file, NULL);
02047
02048 return FALSE;
02049 }
02050
02051 if (sb.st_size > _DBUS_ONE_MEGABYTE)
02052 {
02053 dbus_set_error (error, DBUS_ERROR_FAILED,
02054 "File size %lu of \"%s\" is too large.",
02055 (unsigned long) sb.st_size, filename_c);
02056 _dbus_file_close (&file, NULL);
02057 return FALSE;
02058 }
02059
02060 total = 0;
02061 orig_len = _dbus_string_get_length (str);
02062 if (sb.st_size > 0 && S_ISREG (sb.st_mode))
02063 {
02064 int bytes_read;
02065
02066 while (total < (int) sb.st_size)
02067 {
02068 bytes_read = _dbus_file_read (&file, str,
02069 sb.st_size - total);
02070 if (bytes_read <= 0)
02071 {
02072 dbus_set_error (error, _dbus_error_from_errno (errno),
02073 "Error reading \"%s\": %s",
02074 filename_c,
02075 _dbus_strerror (errno));
02076
02077 _dbus_verbose ("read() failed: %s",
02078 _dbus_strerror (errno));
02079
02080 _dbus_file_close (&file, NULL);
02081 _dbus_string_set_length (str, orig_len);
02082 return FALSE;
02083 }
02084 else
02085 total += bytes_read;
02086 }
02087
02088 _dbus_file_close (&file, NULL);
02089 return TRUE;
02090 }
02091 else if (sb.st_size != 0)
02092 {
02093 _dbus_verbose ("Can only open regular files at the moment.\n");
02094 dbus_set_error (error, DBUS_ERROR_FAILED,
02095 "\"%s\" is not a regular file",
02096 filename_c);
02097 _dbus_file_close (&file, NULL);
02098 return FALSE;
02099 }
02100 else
02101 {
02102 _dbus_file_close (&file, NULL);
02103 return TRUE;
02104 }
02105 }
02106
02116 dbus_bool_t
02117 _dbus_string_save_to_file (const DBusString *str,
02118 const DBusString *filename,
02119 DBusError *error)
02120 {
02121 DBusFile file;
02122 int bytes_to_write;
02123 const char *filename_c;
02124 DBusString tmp_filename;
02125 const char *tmp_filename_c;
02126 int total;
02127 dbus_bool_t need_unlink;
02128 dbus_bool_t retval;
02129
02130 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02131
02132 retval = FALSE;
02133 need_unlink = FALSE;
02134
02135 if (!_dbus_string_init (&tmp_filename))
02136 {
02137 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02138 return FALSE;
02139 }
02140
02141 if (!_dbus_string_copy (filename, 0, &tmp_filename, 0))
02142 {
02143 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02144 _dbus_string_free (&tmp_filename);
02145 return FALSE;
02146 }
02147
02148 if (!_dbus_string_append (&tmp_filename, "."))
02149 {
02150 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02151 _dbus_string_free (&tmp_filename);
02152 return FALSE;
02153 }
02154
02155 #define N_TMP_FILENAME_RANDOM_BYTES 8
02156 if (!_dbus_generate_random_ascii (&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES))
02157 {
02158 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02159 _dbus_string_free (&tmp_filename);
02160 return FALSE;
02161 }
02162
02163 filename_c = _dbus_string_get_const_data (filename);
02164 tmp_filename_c = _dbus_string_get_const_data (&tmp_filename);
02165
02166 if (!_dbus_file_open (&file, tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
02167 0600))
02168 {
02169 dbus_set_error (error, _dbus_error_from_errno (errno),
02170 "Could not create %s: %s", tmp_filename_c,
02171 _dbus_strerror (errno));
02172 goto out;
02173 }
02174
02175 need_unlink = TRUE;
02176
02177 total = 0;
02178 bytes_to_write = _dbus_string_get_length (str);
02179
02180 while (total < bytes_to_write)
02181 {
02182 int bytes_written;
02183
02184 bytes_written = _dbus_file_write (&file, str, total,
02185 bytes_to_write - total);
02186
02187 if (bytes_written <= 0)
02188 {
02189 dbus_set_error (error, _dbus_error_from_errno (errno),
02190 "Could not write to %s: %s", tmp_filename_c,
02191 _dbus_strerror (errno));
02192
02193 goto out;
02194 }
02195
02196 total += bytes_written;
02197 }
02198
02199 if (!_dbus_file_close (&file, NULL))
02200 {
02201 dbus_set_error (error, _dbus_error_from_errno (errno),
02202 "Could not close file %s: %s",
02203 tmp_filename_c, _dbus_strerror (errno));
02204
02205 goto out;
02206 }
02207
02208
02209 if ((unlink (filename_c) == -1 && errno != ENOENT) ||
02210 rename (tmp_filename_c, filename_c) < 0)
02211 {
02212 dbus_set_error (error, _dbus_error_from_errno (errno),
02213 "Could not rename %s to %s: %s",
02214 tmp_filename_c, filename_c,
02215 _dbus_strerror (errno));
02216
02217 goto out;
02218 }
02219
02220 need_unlink = FALSE;
02221
02222 retval = TRUE;
02223
02224 out:
02225
02226
02227
02228
02229 if (_dbus_is_valid_file(&file))
02230 _dbus_file_close (&file, NULL);
02231
02232 if (need_unlink && unlink (tmp_filename_c) < 0)
02233 _dbus_verbose ("Failed to unlink temp file %s: %s\n",
02234 tmp_filename_c, _dbus_strerror (errno));
02235
02236 _dbus_string_free (&tmp_filename);
02237
02238 if (!retval)
02239 _DBUS_ASSERT_ERROR_IS_SET (error);
02240
02241 return retval;
02242 }
02243
02244
02251 dbus_bool_t
02252 _dbus_create_file_exclusively (const DBusString *filename,
02253 DBusError *error)
02254 {
02255 DBusFile file;
02256 const char *filename_c;
02257
02258 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02259
02260 filename_c = _dbus_string_get_const_data (filename);
02261
02262 if (!_dbus_file_open (&file, filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
02263 0600))
02264 {
02265 dbus_set_error (error,
02266 DBUS_ERROR_FAILED,
02267 "Could not create file %s: %s\n",
02268 filename_c,
02269 _dbus_strerror (errno));
02270 return FALSE;
02271 }
02272
02273 if (!_dbus_file_close (&file, NULL))
02274 {
02275 dbus_set_error (error,
02276 DBUS_ERROR_FAILED,
02277 "Could not close file %s: %s\n",
02278 filename_c,
02279 _dbus_strerror (errno));
02280 return FALSE;
02281 }
02282
02283 return TRUE;
02284 }
02285
02286
02295 dbus_bool_t
02296 _dbus_create_directory (const DBusString *filename,
02297 DBusError *error)
02298 {
02299 const char *filename_c;
02300
02301 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02302
02303 filename_c = _dbus_string_get_const_data (filename);
02304
02305 if (_dbus_mkdir (filename_c, 0700) < 0)
02306 {
02307 if (errno == EEXIST)
02308 return TRUE;
02309
02310 dbus_set_error (error, DBUS_ERROR_FAILED,
02311 "Failed to create directory %s: %s\n",
02312 filename_c, _dbus_strerror (errno));
02313 return FALSE;
02314 }
02315 else
02316 return TRUE;
02317 }
02318
02319
02320 static void
02321 pseudorandom_generate_random_bytes_buffer (char *buffer,
02322 int n_bytes)
02323 {
02324 long tv_usec;
02325 int i;
02326
02327
02328 _dbus_verbose ("Falling back to pseudorandom for %d bytes\n",
02329 n_bytes);
02330
02331 _dbus_get_current_time (NULL, &tv_usec);
02332 srand (tv_usec);
02333
02334 i = 0;
02335 while (i < n_bytes)
02336 {
02337 double r;
02338 unsigned int b;
02339
02340 r = rand ();
02341 b = (r / (double) RAND_MAX) * 255.0;
02342
02343 buffer[i] = b;
02344
02345 ++i;
02346 }
02347 }
02348
02349 static dbus_bool_t
02350 pseudorandom_generate_random_bytes (DBusString *str,
02351 int n_bytes)
02352 {
02353 int old_len;
02354 char *p;
02355
02356 old_len = _dbus_string_get_length (str);
02357
02358 if (!_dbus_string_lengthen (str, n_bytes))
02359 return FALSE;
02360
02361 p = _dbus_string_get_data_len (str, old_len, n_bytes);
02362
02363 pseudorandom_generate_random_bytes_buffer (p, n_bytes);
02364
02365 return TRUE;
02366 }
02367
02374 const char*
02375 _dbus_get_tmpdir(void)
02376 {
02377 static const char* tmpdir = NULL;
02378
02379 if (tmpdir == NULL)
02380 {
02381 if (tmpdir == NULL)
02382 tmpdir = getenv("TMP");
02383 if (tmpdir == NULL)
02384 tmpdir = getenv("TEMP");
02385 if (tmpdir == NULL)
02386 tmpdir = getenv("TMPDIR");
02387 if (tmpdir == NULL)
02388 tmpdir = "C:\\Temp";
02389 }
02390
02391 _dbus_assert(tmpdir != NULL);
02392
02393 return tmpdir;
02394 }
02395
02396
02405 dbus_bool_t
02406 _dbus_delete_file (const DBusString *filename,
02407 DBusError *error)
02408 {
02409 const char *filename_c;
02410
02411 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02412
02413 filename_c = _dbus_string_get_const_data (filename);
02414
02415 if (unlink (filename_c) < 0)
02416 {
02417 dbus_set_error (error, DBUS_ERROR_FAILED,
02418 "Failed to delete file %s: %s\n",
02419 filename_c, _dbus_strerror (errno));
02420 return FALSE;
02421 }
02422 else
02423 return TRUE;
02424 }
02425
02434 dbus_bool_t
02435 _dbus_generate_random_bytes (DBusString *str,
02436 int n_bytes)
02437 {
02438 return pseudorandom_generate_random_bytes (str, n_bytes);
02439 }
02440
02441 #if !defined (DBUS_DISABLE_ASSERT) || defined(DBUS_BUILD_TESTS)
02442
02443 #ifdef _MSC_VER
02444 # ifdef BACKTRACES
02445 # undef BACKTRACES
02446 # endif
02447 #else
02448 # define BACKTRACES
02449 #endif
02450
02451 #ifdef BACKTRACES
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473 #include <winver.h>
02474 #include <imagehlp.h>
02475 #include <stdio.h>
02476
02477 #define DPRINTF _dbus_warn
02478
02479 #ifdef _MSC_VER
02480 #define BOOL int
02481
02482 #define __i386__
02483 #endif
02484
02485
02486
02487
02488
02489
02490
02491
02492
02493 static BOOL (WINAPI *pStackWalk)(
02494 DWORD MachineType,
02495 HANDLE hProcess,
02496 HANDLE hThread,
02497 LPSTACKFRAME StackFrame,
02498 PVOID ContextRecord,
02499 PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
02500 PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
02501 PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
02502 PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
02503 );
02504 static DWORD (WINAPI *pSymGetModuleBase)(
02505 HANDLE hProcess,
02506 DWORD dwAddr
02507 );
02508 static PVOID (WINAPI *pSymFunctionTableAccess)(
02509 HANDLE hProcess,
02510 DWORD AddrBase
02511 );
02512 static BOOL (WINAPI *pSymInitialize)(
02513 HANDLE hProcess,
02514 PSTR UserSearchPath,
02515 BOOL fInvadeProcess
02516 );
02517 static BOOL (WINAPI *pSymGetSymFromAddr)(
02518 HANDLE hProcess,
02519 DWORD Address,
02520 PDWORD Displacement,
02521 PIMAGEHLP_SYMBOL Symbol
02522 );
02523 static BOOL (WINAPI *pSymGetModuleInfo)(
02524 HANDLE hProcess,
02525 DWORD dwAddr,
02526 PIMAGEHLP_MODULE ModuleInfo
02527 );
02528 static DWORD (WINAPI *pSymSetOptions)(
02529 DWORD SymOptions
02530 );
02531
02532
02533 static BOOL init_backtrace()
02534 {
02535 HMODULE hmodDbgHelp = LoadLibraryA("dbghelp");
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546
02547
02548
02549
02550
02551
02552
02553 #define FUNC(x) #x
02554
02555 pStackWalk = (BOOL (WINAPI *)(
02556 DWORD MachineType,
02557 HANDLE hProcess,
02558 HANDLE hThread,
02559 LPSTACKFRAME StackFrame,
02560 PVOID ContextRecord,
02561 PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
02562 PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
02563 PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
02564 PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
02565 ))GetProcAddress (hmodDbgHelp, FUNC(StackWalk));
02566 pSymGetModuleBase=(DWORD (WINAPI *)(
02567 HANDLE hProcess,
02568 DWORD dwAddr
02569 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleBase));
02570 pSymFunctionTableAccess=(PVOID (WINAPI *)(
02571 HANDLE hProcess,
02572 DWORD AddrBase
02573 ))GetProcAddress (hmodDbgHelp, FUNC(SymFunctionTableAccess));
02574 pSymInitialize = (BOOL (WINAPI *)(
02575 HANDLE hProcess,
02576 PSTR UserSearchPath,
02577 BOOL fInvadeProcess
02578 ))GetProcAddress (hmodDbgHelp, FUNC(SymInitialize));
02579 pSymGetSymFromAddr = (BOOL (WINAPI *)(
02580 HANDLE hProcess,
02581 DWORD Address,
02582 PDWORD Displacement,
02583 PIMAGEHLP_SYMBOL Symbol
02584 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetSymFromAddr));
02585 pSymGetModuleInfo = (BOOL (WINAPI *)(
02586 HANDLE hProcess,
02587 DWORD dwAddr,
02588 PIMAGEHLP_MODULE ModuleInfo
02589 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleInfo));
02590 pSymSetOptions = (DWORD (WINAPI *)(
02591 DWORD SymOptions
02592 ))GetProcAddress (hmodDbgHelp, FUNC(SymSetOptions));
02593
02594
02595 pSymSetOptions(SYMOPT_UNDNAME);
02596
02597 pSymInitialize(GetCurrentProcess(), NULL, TRUE);
02598
02599 return TRUE;
02600 }
02601
02602 static void dump_backtrace_for_thread(HANDLE hThread)
02603 {
02604 STACKFRAME sf;
02605 CONTEXT context;
02606 DWORD dwImageType;
02607
02608 if (!pStackWalk)
02609 if (!init_backtrace())
02610 return;
02611
02612
02613
02614 if (hThread == GetCurrentThread())
02615 return;
02616
02617 DPRINTF("Backtrace:\n");
02618
02619 memset(&context, 0, sizeof(context));
02620 context.ContextFlags = CONTEXT_FULL;
02621
02622 SuspendThread(hThread);
02623
02624 if (!GetThreadContext(hThread, &context))
02625 {
02626 DPRINTF("Couldn't get thread context (error %ld)\n", GetLastError());
02627 ResumeThread(hThread);
02628 return;
02629 }
02630
02631 memset(&sf, 0, sizeof(sf));
02632
02633 #ifdef __i386__
02634 sf.AddrFrame.Offset = context.Ebp;
02635 sf.AddrFrame.Mode = AddrModeFlat;
02636 sf.AddrPC.Offset = context.Eip;
02637 sf.AddrPC.Mode = AddrModeFlat;
02638 dwImageType = IMAGE_FILE_MACHINE_I386;
02639 #else
02640 # error You need to fill in the STACKFRAME structure for your architecture
02641 #endif
02642
02643 while (pStackWalk(dwImageType, GetCurrentProcess(),
02644 hThread, &sf, &context, NULL, pSymFunctionTableAccess,
02645 pSymGetModuleBase, NULL))
02646 {
02647 BYTE buffer[256];
02648 IMAGEHLP_SYMBOL * pSymbol = (IMAGEHLP_SYMBOL *)buffer;
02649 DWORD dwDisplacement;
02650
02651 pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
02652 pSymbol->MaxNameLength = sizeof(buffer) - sizeof(IMAGEHLP_SYMBOL) + 1;
02653
02654 if (!pSymGetSymFromAddr(GetCurrentProcess(), sf.AddrPC.Offset,
02655 &dwDisplacement, pSymbol))
02656 {
02657 IMAGEHLP_MODULE ModuleInfo;
02658 ModuleInfo.SizeOfStruct = sizeof(ModuleInfo);
02659
02660 if (!pSymGetModuleInfo(GetCurrentProcess(), sf.AddrPC.Offset,
02661 &ModuleInfo))
02662 DPRINTF("1\t%p\n", (void*)sf.AddrPC.Offset);
02663 else
02664 DPRINTF("2\t%s+0x%lx\n", ModuleInfo.ImageName,
02665 sf.AddrPC.Offset - ModuleInfo.BaseOfImage);
02666 }
02667 else if (dwDisplacement)
02668 DPRINTF("3\t%s+0x%lx\n", pSymbol->Name, dwDisplacement);
02669 else
02670 DPRINTF("4\t%s\n", pSymbol->Name);
02671 }
02672
02673 ResumeThread(hThread);
02674 }
02675
02676 static DWORD WINAPI dump_thread_proc(LPVOID lpParameter)
02677 {
02678 dump_backtrace_for_thread((HANDLE)lpParameter);
02679 return 0;
02680 }
02681
02682
02683
02684 static void dump_backtrace()
02685 {
02686 HANDLE hCurrentThread;
02687 HANDLE hThread;
02688 DWORD dwThreadId;
02689 DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
02690 GetCurrentProcess(), &hCurrentThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
02691 hThread = CreateThread(NULL, 0, dump_thread_proc, (LPVOID)hCurrentThread,
02692 0, &dwThreadId);
02693 WaitForSingleObject(hThread, INFINITE);
02694 CloseHandle(hThread);
02695 CloseHandle(hCurrentThread);
02696 }
02697
02698 void _dbus_print_backtrace(void)
02699 {
02700 init_backtrace();
02701 dump_backtrace();
02702 }
02703 #else
02704 void _dbus_print_backtrace(void)
02705 {
02706 _dbus_verbose (" D-Bus not compiled with backtrace support\n");
02707 }
02708 #endif
02709
02710 static dbus_uint32_t fromAscii(char ascii)
02711 {
02712 if(ascii >= '0' && ascii <= '9')
02713 return ascii - '0';
02714 if(ascii >= 'A' && ascii <= 'F')
02715 return ascii - 'A' + 10;
02716 if(ascii >= 'a' && ascii <= 'f')
02717 return ascii - 'a' + 10;
02718 return 0;
02719 }
02720
02721 dbus_bool_t _dbus_read_local_machine_uuid (DBusGUID *machine_id,
02722 dbus_bool_t create_if_not_found,
02723 DBusError *error)
02724 {
02725 #ifdef DBUS_WINCE
02726 return TRUE;
02727
02728 #else
02729 HW_PROFILE_INFOA info;
02730 char *lpc = &info.szHwProfileGuid[0];
02731 dbus_uint32_t u;
02732
02733
02734 if(!GetCurrentHwProfileA(&info))
02735 {
02736 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02737 return FALSE;
02738 }
02739
02740
02741 lpc++;
02742
02743 u = ((fromAscii(lpc[0]) << 0) |
02744 (fromAscii(lpc[1]) << 4) |
02745 (fromAscii(lpc[2]) << 8) |
02746 (fromAscii(lpc[3]) << 12) |
02747 (fromAscii(lpc[4]) << 16) |
02748 (fromAscii(lpc[5]) << 20) |
02749 (fromAscii(lpc[6]) << 24) |
02750 (fromAscii(lpc[7]) << 28));
02751 machine_id->as_uint32s[0] = u;
02752
02753 lpc += 9;
02754
02755 u = ((fromAscii(lpc[0]) << 0) |
02756 (fromAscii(lpc[1]) << 4) |
02757 (fromAscii(lpc[2]) << 8) |
02758 (fromAscii(lpc[3]) << 12) |
02759 (fromAscii(lpc[5]) << 16) |
02760 (fromAscii(lpc[6]) << 20) |
02761 (fromAscii(lpc[7]) << 24) |
02762 (fromAscii(lpc[8]) << 28));
02763 machine_id->as_uint32s[1] = u;
02764
02765 lpc += 10;
02766
02767 u = ((fromAscii(lpc[0]) << 0) |
02768 (fromAscii(lpc[1]) << 4) |
02769 (fromAscii(lpc[2]) << 8) |
02770 (fromAscii(lpc[3]) << 12) |
02771 (fromAscii(lpc[5]) << 16) |
02772 (fromAscii(lpc[6]) << 20) |
02773 (fromAscii(lpc[7]) << 24) |
02774 (fromAscii(lpc[8]) << 28));
02775 machine_id->as_uint32s[2] = u;
02776
02777 lpc += 9;
02778
02779 u = ((fromAscii(lpc[0]) << 0) |
02780 (fromAscii(lpc[1]) << 4) |
02781 (fromAscii(lpc[2]) << 8) |
02782 (fromAscii(lpc[3]) << 12) |
02783 (fromAscii(lpc[4]) << 16) |
02784 (fromAscii(lpc[5]) << 20) |
02785 (fromAscii(lpc[6]) << 24) |
02786 (fromAscii(lpc[7]) << 28));
02787 machine_id->as_uint32s[3] = u;
02788 #endif
02789 return TRUE;
02790 }
02791
02792 static
02793 HANDLE _dbus_global_lock (const char *mutexname)
02794 {
02795 HANDLE mutex;
02796 DWORD gotMutex;
02797
02798 mutex = CreateMutex( NULL, FALSE, mutexname );
02799 if( !mutex )
02800 {
02801 return FALSE;
02802 }
02803
02804 gotMutex = WaitForSingleObject( mutex, INFINITE );
02805 switch( gotMutex )
02806 {
02807 case WAIT_ABANDONED:
02808 ReleaseMutex (mutex);
02809 CloseHandle (mutex);
02810 return 0;
02811 case WAIT_FAILED:
02812 case WAIT_TIMEOUT:
02813 return 0;
02814 }
02815
02816 return mutex;
02817 }
02818
02819 static
02820 void _dbus_global_unlock (HANDLE mutex)
02821 {
02822 ReleaseMutex (mutex);
02823 CloseHandle (mutex);
02824 }
02825
02826
02827 static HANDLE hDBusDaemonMutex = NULL;
02828 static HANDLE hDBusSharedMem = NULL;
02829
02830 static const char *cUniqueDBusInitMutex = "UniqueDBusInitMutex";
02831
02832 static const char *cDBusAutolaunchMutex = "DBusAutolaunchMutex";
02833
02834 static const char *cDBusDaemonMutex = "DBusDaemonMutex";
02835
02836 static const char *cDBusDaemonAddressInfo = "DBusDaemonAddressInfo";
02837
02838 void
02839 _dbus_daemon_init(const char *host, dbus_uint32_t port)
02840 {
02841 HANDLE lock;
02842 const char *adr = NULL;
02843 char szUserName[64];
02844 DWORD dwUserNameSize = sizeof(szUserName);
02845 char szDBusDaemonMutex[128];
02846 char szDBusDaemonAddressInfo[128];
02847 char szAddress[128];
02848
02849 _dbus_assert(host);
02850 _dbus_assert(port);
02851
02852 _snprintf(szAddress, sizeof(szAddress) - 1, "tcp:host=%s,port=%d", host, port);
02853
02854 _dbus_assert( GetUserName(szUserName, &dwUserNameSize) != 0);
02855 _snprintf(szDBusDaemonMutex, sizeof(szDBusDaemonMutex) - 1, "%s:%s",
02856 cDBusDaemonMutex, szUserName);
02857 _snprintf(szDBusDaemonAddressInfo, sizeof(szDBusDaemonAddressInfo) - 1, "%s:%s",
02858 cDBusDaemonAddressInfo, szUserName);
02859
02860
02861 hDBusDaemonMutex = CreateMutex( NULL, FALSE, szDBusDaemonMutex );
02862
02863 _dbus_assert(WaitForSingleObject( hDBusDaemonMutex, 1000 ) == WAIT_OBJECT_0);
02864
02865
02866 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02867
02868
02869 hDBusSharedMem = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
02870 0, strlen( szAddress ) + 1, szDBusDaemonAddressInfo );
02871 _dbus_assert( hDBusSharedMem );
02872
02873 adr = MapViewOfFile( hDBusSharedMem, FILE_MAP_WRITE, 0, 0, 0 );
02874
02875 _dbus_assert( adr );
02876
02877 strcpy( (char*) adr, szAddress);
02878
02879
02880 UnmapViewOfFile( (char*) adr );
02881
02882 _dbus_global_unlock( lock );
02883 }
02884
02885 void
02886 _dbus_daemon_release()
02887 {
02888 HANDLE lock;
02889
02890
02891 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02892
02893 CloseHandle( hDBusSharedMem );
02894
02895 hDBusSharedMem = NULL;
02896
02897 ReleaseMutex( hDBusDaemonMutex );
02898
02899 CloseHandle( hDBusDaemonMutex );
02900
02901 hDBusDaemonMutex = NULL;
02902
02903 _dbus_global_unlock( lock );
02904 }
02905
02906 static dbus_bool_t
02907 _dbus_get_autolaunch_shm(DBusString *adress)
02908 {
02909 HANDLE sharedMem;
02910 const char *adr;
02911 char szUserName[64];
02912 DWORD dwUserNameSize = sizeof(szUserName);
02913 char szDBusDaemonAddressInfo[128];
02914
02915 if( !GetUserName(szUserName, &dwUserNameSize) )
02916 return FALSE;
02917 _snprintf(szDBusDaemonAddressInfo, sizeof(szDBusDaemonAddressInfo) - 1, "%s:%s",
02918 cDBusDaemonAddressInfo, szUserName);
02919
02920
02921 do {
02922
02923 sharedMem = OpenFileMapping( FILE_MAP_READ, FALSE, szDBusDaemonAddressInfo );
02924 if( sharedMem == 0 )
02925 Sleep( 100 );
02926 } while( sharedMem == 0 );
02927
02928 if( sharedMem == 0 )
02929 return FALSE;
02930
02931 adr = MapViewOfFile( sharedMem, FILE_MAP_READ, 0, 0, 0 );
02932
02933 if( adr == 0 )
02934 return FALSE;
02935
02936 _dbus_string_init( adress );
02937
02938 _dbus_string_append( adress, adr );
02939
02940
02941 UnmapViewOfFile( (char*) adr );
02942
02943 CloseHandle( sharedMem );
02944
02945 return TRUE;
02946 }
02947
02948 static dbus_bool_t
02949 _dbus_daemon_already_runs (DBusString *adress)
02950 {
02951 HANDLE lock;
02952 HANDLE daemon;
02953 dbus_bool_t bRet = TRUE;
02954 char szUserName[64];
02955 DWORD dwUserNameSize = sizeof(szUserName);
02956 char szDBusDaemonMutex[128];
02957
02958
02959 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02960
02961 if( !GetUserName(szUserName, &dwUserNameSize) )
02962 return FALSE;
02963 _snprintf(szDBusDaemonMutex, sizeof(szDBusDaemonMutex) - 1, "%s:%s",
02964 cDBusDaemonMutex, szUserName);
02965
02966
02967 daemon = CreateMutex( NULL, FALSE, szDBusDaemonMutex );
02968 if(WaitForSingleObject( daemon, 10 ) != WAIT_TIMEOUT)
02969 {
02970 ReleaseMutex (daemon);
02971 CloseHandle (daemon);
02972
02973 _dbus_global_unlock( lock );
02974 return FALSE;
02975 }
02976
02977
02978 bRet = _dbus_get_autolaunch_shm( adress );
02979
02980
02981 CloseHandle ( daemon );
02982
02983 _dbus_global_unlock( lock );
02984
02985 return bRet;
02986 }
02987
02988 dbus_bool_t
02989 _dbus_get_autolaunch_address (DBusString *address,
02990 DBusError *error)
02991 {
02992 HANDLE mutex;
02993 STARTUPINFOA si;
02994 PROCESS_INFORMATION pi;
02995 dbus_bool_t retval = FALSE;
02996 LPSTR lpFile;
02997 char dbus_exe_path[MAX_PATH];
02998 char dbus_args[MAX_PATH * 2];
02999
03000 mutex = _dbus_global_lock ( cDBusAutolaunchMutex );
03001
03002 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03003
03004 if (_dbus_daemon_already_runs(address))
03005 {
03006 printf("dbus daemon already exists\n");
03007 retval = TRUE;
03008 goto out;
03009 }
03010
03011 if (!SearchPathA(NULL, "dbus-daemon.exe", NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile))
03012 {
03013 printf ("could not find dbus-daemon executable\n");
03014 goto out;
03015 }
03016
03017
03018 ZeroMemory( &si, sizeof(si) );
03019 si.cb = sizeof(si);
03020 ZeroMemory( &pi, sizeof(pi) );
03021
03022 _snprintf(dbus_args, sizeof(dbus_args) - 1, "\"%s\" %s", dbus_exe_path, " --session");
03023
03024
03025 printf("create process \"%s\" %s\n", dbus_exe_path, dbus_args);
03026 if(CreateProcessA(dbus_exe_path, dbus_args, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
03027 {
03028 retval = TRUE;
03029
03030
03031 WaitForInputIdle(pi.hProcess, INFINITE);
03032
03033 retval = _dbus_get_autolaunch_shm( address );
03034 } else {
03035 retval = FALSE;
03036 }
03037
03038 out:
03039 if (retval)
03040 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03041 else
03042 _DBUS_ASSERT_ERROR_IS_SET (error);
03043
03044 _dbus_global_unlock (mutex);
03045
03046 return retval;
03047 }
03048
03049
03056 dbus_bool_t
03057 _dbus_make_file_world_readable(const DBusString *filename,
03058 DBusError *error)
03059 {
03060
03061 return TRUE;
03062 }
03063
03064
03065 #define DBUS_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
03066 #define DBUS_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
03067
03084 dbus_bool_t
03085 _dbus_get_standard_session_servicedirs (DBusList **dirs)
03086 {
03087 const char *common_progs;
03088 DBusString servicedir_path;
03089
03090 if (!_dbus_string_init (&servicedir_path))
03091 return FALSE;
03092
03093 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR _DBUS_PATH_SEPARATOR))
03094 goto oom;
03095
03096 common_progs = _dbus_getenv ("CommonProgramFiles");
03097
03098 if (common_progs != NULL)
03099 {
03100 if (!_dbus_string_append (&servicedir_path, common_progs))
03101 goto oom;
03102
03103 if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
03104 goto oom;
03105 }
03106
03107 if (!_dbus_split_paths_and_append (&servicedir_path,
03108 DBUS_STANDARD_SESSION_SERVICEDIR,
03109 dirs))
03110 goto oom;
03111
03112 _dbus_string_free (&servicedir_path);
03113 return TRUE;
03114
03115 oom:
03116 _dbus_string_free (&servicedir_path);
03117 return FALSE;
03118 }
03119
03120 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
03121
03129 dbus_int32_t
03130 _dbus_atomic_inc (DBusAtomic *atomic)
03131 {
03132
03133
03134 return InterlockedIncrement (&atomic->value) - 1;
03135 }
03136
03144 dbus_int32_t
03145 _dbus_atomic_dec (DBusAtomic *atomic)
03146 {
03147
03148
03149 return InterlockedDecrement (&atomic->value) + 1;
03150 }
03151
03152 #endif
03153
03161 void
03162 _dbus_flush_caches (void)
03163 {
03164
03165 }
03166
03167 dbus_bool_t _dbus_windows_user_is_process_owner (const char *windows_sid)
03168 {
03169 return TRUE;
03170 }
03171
03178 dbus_bool_t
03179 _dbus_get_is_errno_eagain_or_ewouldblock (void)
03180 {
03181 return errno == EAGAIN || errno == EWOULDBLOCK;
03182 }
03183
03191 dbus_bool_t
03192 _dbus_get_install_root(char *s, int len)
03193 {
03194 char *p = NULL;
03195 int ret = GetModuleFileName(NULL,s,len);
03196 if ( ret == 0
03197 || ret == len && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
03198 {
03199 *s = '\0';
03200 return FALSE;
03201 }
03202 else if ((p = strstr(s,"\\bin\\")))
03203 {
03204 *(p+1)= '\0';
03205 return TRUE;
03206 }
03207 else
03208 {
03209 *s = '\0';
03210 return FALSE;
03211 }
03212 }
03213
03225 dbus_bool_t
03226 _dbus_get_config_file_name(DBusString *config_file, char *s)
03227 {
03228 char path[MAX_PATH*2];
03229 int path_size = sizeof(path);
03230
03231 if (!_dbus_get_install_root(path,path_size))
03232 return FALSE;
03233
03234 strcat_s(path,path_size,"etc\\");
03235 strcat_s(path,path_size,s);
03236 if (_dbus_file_exists(path))
03237 {
03238
03239 if (!_dbus_string_append (config_file, path))
03240 return FALSE;
03241 }
03242 else
03243 {
03244 if (!_dbus_get_install_root(path,path_size))
03245 return FALSE;
03246 strcat_s(path,path_size,"bus\\");
03247 strcat_s(path,path_size,s);
03248
03249 if (_dbus_file_exists(path))
03250 {
03251 if (!_dbus_string_append (config_file, path))
03252 return FALSE;
03253 }
03254 }
03255 return TRUE;
03256 }
03257
03266 dbus_bool_t
03267 _dbus_append_system_config_file (DBusString *str)
03268 {
03269 return _dbus_get_config_file_name(str, "system.conf");
03270 }
03271
03278 dbus_bool_t
03279 _dbus_append_session_config_file (DBusString *str)
03280 {
03281 return _dbus_get_config_file_name(str, "session.conf");
03282 }
03283
03297 dbus_bool_t
03298 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
03299 DBusCredentials *credentials)
03300 {
03301 DBusString homedir;
03302 DBusString dotdir;
03303 dbus_uid_t uid;
03304 const char *homepath;
03305
03306 _dbus_assert (credentials != NULL);
03307 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
03308
03309 if (!_dbus_string_init (&homedir))
03310 return FALSE;
03311
03312 homepath = _dbus_getenv("HOMEPATH");
03313 if (homepath != NULL && *homepath != '\0')
03314 {
03315 _dbus_string_append(&homedir,homepath);
03316 }
03317
03318 #ifdef DBUS_BUILD_TESTS
03319 {
03320 const char *override;
03321
03322 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
03323 if (override != NULL && *override != '\0')
03324 {
03325 _dbus_string_set_length (&homedir, 0);
03326 if (!_dbus_string_append (&homedir, override))
03327 goto failed;
03328
03329 _dbus_verbose ("Using fake homedir for testing: %s\n",
03330 _dbus_string_get_const_data (&homedir));
03331 }
03332 else
03333 {
03334 static dbus_bool_t already_warned = FALSE;
03335 if (!already_warned)
03336 {
03337 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
03338 already_warned = TRUE;
03339 }
03340 }
03341 }
03342 #endif
03343
03344 _dbus_string_init_const (&dotdir, ".dbus-keyrings");
03345 if (!_dbus_concat_dir_and_file (&homedir,
03346 &dotdir))
03347 goto failed;
03348
03349 if (!_dbus_string_copy (&homedir, 0,
03350 directory, _dbus_string_get_length (directory))) {
03351 goto failed;
03352 }
03353
03354 _dbus_string_free (&homedir);
03355 return TRUE;
03356
03357 failed:
03358 _dbus_string_free (&homedir);
03359 return FALSE;
03360 }
03361
03363
03364