diff --git a/Makefile.am b/Makefile.am index ac31a7f..a07a87e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -14,7 +14,8 @@ EXTRA_DIST = \ ChangeLog.pre-1-0 \ NEWS.pre-1-0 \ ChangeLog.pre-1-2 \ - NEWS.pre-1-2 + NEWS.pre-1-2 \ + dbus-zip.in all-local: Doxyfile diff --git a/bus/Makefile.am b/bus/Makefile.am index 3b4f69d..e02cea6 100644 --- a/bus/Makefile.am +++ b/bus/Makefile.am @@ -12,8 +12,12 @@ CONFIG_IN_FILES= \ system.conf.in config_DATA= \ - session.conf \ + session.conf + +if DBUS_UNIX +config_DATA+= \ system.conf +endif if DBUS_USE_LIBXML XML_SOURCES=config-loader-libxml.c @@ -142,14 +146,20 @@ bus_test_launch_helper_CPPFLAGS= \ ## TESTS if DBUS_BUILD_TESTS TESTS_ENVIRONMENT=DBUS_TEST_DATA=$(top_builddir)/test/data DBUS_TEST_HOMEDIR=$(top_builddir)/dbus DBUS_FATAL_WARNINGS=1 DBUS_BLOCK_ON_ABORT=1 -TESTS=bus-test bus-test-system bus-test-launch-helper +TESTS=bus-test +if DBUS_UNIX +TESTS+=bus-test-system bus-test-launch-helper +endif else TESTS= endif ## we use noinst_PROGRAMS not check_PROGRAMS so that we build ## even when not doing "make check" -noinst_PROGRAMS=$(TESTS) dbus-daemon dbus-daemon-launch-helper-test dbus-daemon-launch-helper +noinst_PROGRAMS=$(TESTS) dbus-daemon +if DBUS_UNIX +noinst_PROGRAMS+=dbus-daemon-launch-helper-test dbus-daemon-launch-helper +endif bus_test_system_SOURCES= \ $(XML_SOURCES) \ @@ -186,11 +196,13 @@ install-data-hook: fi $(INSTALL_PROGRAM) dbus-daemon $(DESTDIR)$(DBUS_DAEMONDIR) $(mkinstalldirs) $(DESTDIR)$(localstatedir)/run/dbus +if DBUS_UNIX $(mkinstalldirs) $(DESTDIR)$(configdir)/system.d +endif $(mkinstalldirs) $(DESTDIR)$(configdir)/session.d $(mkinstalldirs) $(DESTDIR)$(datadir)/dbus-1/services +if DBUS_UNIX $(mkinstalldirs) $(DESTDIR)$(datadir)/dbus-1/system-services - $(mkinstalldirs) $(DESTDIR)$(libexecdir)/dbus-1 $(INSTALL_PROGRAM) dbus-daemon-launch-helper $(DESTDIR)$(libexecdir) if test `id -u` -eq 0; then \ chown root:$(DBUS_USER) $(DESTDIR)$(libexecdir)/dbus-daemon-launch-helper; \ @@ -199,6 +211,7 @@ install-data-hook: echo "Not installing $(DESTDIR)$(libexecdir)/dbus-daemon-launch-helper binary setuid!"; \ echo "You'll need to manually set permissions to root:$(DBUS_USER) and permissions 4750"; \ fi +endif #### Init scripts fun SCRIPT_IN_FILES=messagebus.in \ diff --git a/bus/main.c b/bus/main.c index 161de19..cd1f7c8 100644 --- a/bus/main.c +++ b/bus/main.c @@ -44,7 +44,6 @@ static void close_reload_pipe (void); static void signal_handler (int sig) { - DBusString str; switch (sig) { @@ -52,16 +51,20 @@ signal_handler (int sig) case SIGIO: /* explicit fall-through */ #endif /* DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX */ +#ifdef SIGHUP case SIGHUP: - _dbus_string_init_const (&str, "foo"); - if ((reload_pipe[RELOAD_WRITE_END] > 0) && - !_dbus_write_socket (reload_pipe[RELOAD_WRITE_END], &str, 0, 1)) - { - _dbus_warn ("Unable to write to reload pipe.\n"); - close_reload_pipe (); - } + { + DBusString str; + _dbus_string_init_const (&str, "foo"); + if ((reload_pipe[RELOAD_WRITE_END] > 0) && + !_dbus_write_socket (reload_pipe[RELOAD_WRITE_END], &str, 0, 1)) + { + _dbus_warn ("Unable to write to reload pipe.\n"); + close_reload_pipe (); + } + } break; - +#endif case SIGTERM: _dbus_loop_quit (bus_context_get_loop (context)); break; @@ -254,6 +257,10 @@ main (int argc, char **argv) int i; dbus_bool_t print_address; dbus_bool_t print_pid; + dbus_bool_t is_session_bus; +#ifdef DBUS_WIN + dbus_bool_t publish_address; +#endif int force_fork; if (!_dbus_string_init (&config_file)) @@ -267,6 +274,8 @@ main (int argc, char **argv) print_address = FALSE; print_pid = FALSE; + is_session_bus = FALSE; + publish_address = FALSE; force_fork = FORK_FOLLOW_CONFIG_FILE; prev_arg = NULL; @@ -300,6 +309,8 @@ main (int argc, char **argv) if (!_dbus_append_session_config_file (&config_file)) exit (1); + + is_session_bus = TRUE; } else if (strstr (arg, "--config-file=") == arg) { @@ -375,6 +386,14 @@ main (int argc, char **argv) } else if (strcmp (arg, "--print-pid") == 0) print_pid = TRUE; /* and we'll get the next arg if appropriate */ + else if (strcmp (arg, "--publish-address") == 0) + { +#ifdef DBUS_UNIX + fprintf (stderr, "Ignoring --publish-address on UNIX.\n"); +#else + publish_address = TRUE; +#endif + } else usage (); @@ -452,13 +471,23 @@ main (int argc, char **argv) exit (1); } + if (publish_address) + { + if (!is_session_bus) + fprintf (stderr, "Ignoring --publish-address without --session.\n"); + else + _dbus_publish_session_bus_address (bus_context_get_address (context)); + } + /* bus_context_new() closes the print_addr_pipe and * print_pid_pipe */ setup_reload_pipe (bus_context_get_loop (context)); +#ifdef SIGHUP _dbus_set_signal_handler (SIGHUP, signal_handler); +#endif _dbus_set_signal_handler (SIGTERM, signal_handler); #ifdef DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX _dbus_set_signal_handler (SIGIO, signal_handler); diff --git a/bus/session.conf.in b/bus/session.conf.in index b2dee5b..c3f1cf3 100644 --- a/bus/session.conf.in +++ b/bus/session.conf.in @@ -8,7 +8,7 @@ session - unix:tmpdir=@DBUS_SESSION_SOCKET_DIR@ + @DBUS_SESSION_SOCKET@ diff --git a/configure.in b/configure.in index b833840..49811e6 100644 --- a/configure.in +++ b/configure.in @@ -90,7 +90,26 @@ AC_ARG_WITH(console-owner-file, AS_HELP_STRING([--with-console-owner-file=[filen AC_ARG_WITH(dbus_user, AS_HELP_STRING([--with-dbus-user=],[User for running the DBUS daemon (messagebus)])) AC_ARG_WITH(dbus_daemondir, AS_HELP_STRING([--with-dbus-daemondir=[dirname]],[Directory for installing the DBUS daemon])) -AC_DEFINE(DBUS_UNIX,1,[dbus on unix]) +AC_MSG_CHECKING([for Windows]) +case "$host" in + *-*-mingw*) + dbus_win=yes + SOCKET_LIBS=-lws2_32 + ;; + *) + dbus_win=no + ;; +esac +AC_MSG_RESULT([$dbus_win]) +AC_SUBST(SOCKET_LIBS) + +AM_CONDITIONAL(DBUS_UNIX, test x$dbus_win = xno) +AM_CONDITIONAL(DBUS_WIN, test x$dbus_win = xyes) +if test x$dbus_win = xyes; then + AC_DEFINE(DBUS_WIN,1,[Defined on Windows]) +else + AC_DEFINE(DBUS_UNIX,1,[Defined on UNIX and Linux systems and not on Windows]) +fi dnl DBUS_BUILD_TESTS controls unit tests built in to .c files dnl and also some stuff in the test/ subdir @@ -244,9 +263,11 @@ if test "x$GCC" = "xyes"; then case " $CFLAGS " in *[\ \ ]-fPIC[\ \ ]*) ;; *) if cc_supports_flag -fPIC; then - PIC_CFLAGS="-fPIC" - if ld_supports_flag -z,relro; then - PIC_LDFLAGS="-Wl,-z,relro" + if test x$dbus_win = xno; then + PIC_CFLAGS="-fPIC" + if ld_supports_flag -z,relro; then + PIC_LDFLAGS="-Wl,-z,relro" + fi fi fi ;; @@ -255,12 +276,14 @@ if test "x$GCC" = "xyes"; then case " $CFLAGS " in *[\ \ ]-fPIE[\ \ ]*) ;; *) if cc_supports_flag -fPIE; then - PIE_CFLAGS="-fPIE" - if ld_supports_flag -z,relro; then - PIE_LDFLAGS="-pie -Wl,-z,relro" - else - PIE_LDFLAGS="-pie" - fi + if test x$dbus_win = xno; then + PIE_CFLAGS="-fPIE" + if ld_supports_flag -z,relro; then + PIE_LDFLAGS="-pie -Wl,-z,relro" + else + PIE_LDFLAGS="-pie" + fi + fi fi ;; esac @@ -1256,7 +1279,9 @@ AC_SUBST(DBUS_DATADIR) AC_DEFINE_UNQUOTED(DBUS_DATADIR,"$DBUS_DATADIR", [Directory for installing DBUS data files]) #### Directory to install dbus-daemon -if test -z "$with_dbus_daemondir" ; then +if test x$dbus_win = xyes ; then + DBUS_DAEMONDIR='${prefix}/bin' +elif test -z "$with_dbus_daemondir" ; then DBUS_DAEMONDIR=$EXPANDED_BINDIR else DBUS_DAEMONDIR=$with_dbus_daemondir @@ -1331,8 +1356,12 @@ else fi AC_DEFINE_UNQUOTED(DBUS_SESSION_SOCKET_DIR, "$DBUS_SESSION_SOCKET_DIR", [Where per-session bus puts its sockets]) AC_SUBST(DBUS_SESSION_SOCKET_DIR) - -AC_DEFINE_UNQUOTED(DBUS_UNIX, "1", [Defined on UNIX and Linux systems and not on Windows]) +if test x$dbus_win = xno; then + DBUS_SESSION_SOCKET="unix:tmpdir=$DBUS_SESSION_SOCKET_DIR" +else + DBUS_SESSION_SOCKET="tcp:host=localhost" +fi +AC_SUBST(DBUS_SESSION_SOCKET) # darwin needs this to initialize the environment AC_CHECK_HEADERS(crt_externs.h) @@ -1362,6 +1391,7 @@ test/Makefile test/name-test/Makefile doc/Makefile dbus-1.pc +dbus-zip test/data/valid-config-files/debug-allow-all.conf test/data/valid-config-files/debug-allow-all-sha1.conf test/data/valid-config-files-system/debug-allow-all-pass.conf diff --git a/dbus-zip.in b/dbus-zip.in new file mode 100644 index 0000000..6dbbf41 --- /dev/null +++ b/dbus-zip.in @@ -0,0 +1,34 @@ +#!/bin/sh + +# Build zipfile distribution for dbus on Win32: Separate runtime and +# developer zipfiles. After running make install, run this. + +ZIP=/tmp/dbus-@DBUS_VERSION@.zip +DEVZIP=/tmp/dbus-dev-@DBUS_VERSION@.zip + +current_minus_age=`expr @LT_CURRENT@ - @LT_AGE@` + +cd @prefix@ + +rm $ZIP +zip $ZIP -@ <n_outgoing -= 1; - _dbus_verbose ("Message %p (%d %s %s %s '%s') removed from outgoing queue %p, %d left to send\n", + _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from outgoing queue %p, %d left to send\n", message, - dbus_message_get_type (message), + dbus_message_type_to_string (dbus_message_get_type (message)), dbus_message_get_path (message) ? dbus_message_get_path (message) : "no path", @@ -1928,9 +1928,9 @@ _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *con sig = dbus_message_get_signature (message); - _dbus_verbose ("Message %p (%d %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n", + _dbus_verbose ("Message %p (%s %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n", message, - dbus_message_get_type (message), + dbus_message_type_to_string (dbus_message_get_type (message)), dbus_message_get_path (message) ? dbus_message_get_path (message) : "no path", @@ -3715,9 +3715,9 @@ _dbus_connection_pop_message_link_unlocked (DBusConnection *connection) link = _dbus_list_pop_first_link (&connection->incoming_messages); connection->n_incoming -= 1; - _dbus_verbose ("Message %p (%d %s %s %s '%s') removed from incoming queue %p, %d incoming\n", + _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from incoming queue %p, %d incoming\n", link->data, - dbus_message_get_type (link->data), + dbus_message_type_to_string (dbus_message_get_type (link->data)), dbus_message_get_path (link->data) ? dbus_message_get_path (link->data) : "no path", @@ -3780,9 +3780,9 @@ _dbus_connection_putback_message_link_unlocked (DBusConnection *connection, message_link); connection->n_incoming += 1; - _dbus_verbose ("Message %p (%d %s %s '%s') put back into queue %p, %d incoming\n", + _dbus_verbose ("Message %p (%s %s %s '%s') put back into queue %p, %d incoming\n", message_link->data, - dbus_message_get_type (message_link->data), + dbus_message_type_to_string (dbus_message_get_type (message_link->data)), dbus_message_get_interface (message_link->data) ? dbus_message_get_interface (message_link->data) : "no interface", @@ -4323,9 +4323,9 @@ dbus_connection_dispatch (DBusConnection *connection) message = message_link->data; - _dbus_verbose (" dispatching message %p (%d %s %s '%s')\n", + _dbus_verbose (" dispatching message %p (%s %s %s '%s')\n", message, - dbus_message_get_type (message), + dbus_message_type_to_string (dbus_message_get_type (message)), dbus_message_get_interface (message) ? dbus_message_get_interface (message) : "no interface", @@ -4432,9 +4432,9 @@ dbus_connection_dispatch (DBusConnection *connection) /* We're still protected from dispatch() reentrancy here * since we acquired the dispatcher */ - _dbus_verbose (" running object path dispatch on message %p (%d %s %s '%s')\n", + _dbus_verbose (" running object path dispatch on message %p (%s %s %s '%s')\n", message, - dbus_message_get_type (message), + dbus_message_type_to_string (dbus_message_get_type (message)), dbus_message_get_interface (message) ? dbus_message_get_interface (message) : "no interface", @@ -4513,8 +4513,8 @@ dbus_connection_dispatch (DBusConnection *connection) result = DBUS_HANDLER_RESULT_HANDLED; } - _dbus_verbose (" done dispatching %p (%d %s %s '%s') on connection %p\n", message, - dbus_message_get_type (message), + _dbus_verbose (" done dispatching %p (%s %s %s '%s') on connection %p\n", message, + dbus_message_type_to_string (dbus_message_get_type (message)), dbus_message_get_interface (message) ? dbus_message_get_interface (message) : "no interface", diff --git a/dbus/dbus-internals.c b/dbus/dbus-internals.c index f3ca7c5..227fe8e 100644 --- a/dbus/dbus-internals.c +++ b/dbus/dbus-internals.c @@ -189,7 +189,7 @@ * making up a different string every time and wasting * space. */ -const char _dbus_no_memory_message[] = "Not enough memory"; +const char *_dbus_no_memory_message = "Not enough memory"; static dbus_bool_t warn_initted = FALSE; static dbus_bool_t fatal_warnings = FALSE; @@ -295,7 +295,7 @@ static dbus_bool_t verbose = TRUE; #include #endif -#ifdef DBUS_WIN +#ifdef _MSC_VER #define inline #endif @@ -797,9 +797,9 @@ _dbus_header_field_to_string (int header_field) #ifndef DBUS_DISABLE_CHECKS /** String used in _dbus_return_if_fail macro */ -const char _dbus_return_if_fail_warning_format[] = -"arguments to %s() were incorrect, assertion \"%s\" failed in file %s line %d.\n" -"This is normally a bug in some application using the D-Bus library.\n"; +const char *_dbus_return_if_fail_warning_format = + "arguments to %s() were incorrect, assertion \"%s\" failed in file %s line %d.\n" + "This is normally a bug in some application using the D-Bus library.\n"; #endif #ifndef DBUS_DISABLE_ASSERT diff --git a/dbus/dbus-internals.h b/dbus/dbus-internals.h index 3e5f989..93d70d9 100644 --- a/dbus/dbus-internals.h +++ b/dbus/dbus-internals.h @@ -131,7 +131,7 @@ void _dbus_real_assert_not_reached (const char *explanation, #define _dbus_return_if_fail(condition) #define _dbus_return_val_if_fail(condition, val) #else -extern const char _dbus_return_if_fail_warning_format[]; +extern const char *_dbus_return_if_fail_warning_format; #define _dbus_return_if_fail(condition) do { \ _dbus_assert ((*(const char*)_DBUS_FUNCTION_NAME) != '_'); \ @@ -245,7 +245,7 @@ void _dbus_verbose_bytes_of_string (const DBusString *str, const char* _dbus_header_field_to_string (int header_field); -extern const char _dbus_no_memory_message[]; +extern const char *_dbus_no_memory_message; #define _DBUS_SET_OOM(error) dbus_set_error_const ((error), DBUS_ERROR_NO_MEMORY, _dbus_no_memory_message) #ifdef DBUS_BUILD_TESTS diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index cd44798..bde42bc 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -3898,14 +3898,20 @@ dbus_message_type_from_string (const char *type_str) * DBUS_MESSAGE_TYPE_SIGNAL -> "signal" * DBUS_MESSAGE_TYPE_ERROR -> "error" * DBUS_MESSAGE_TYPE_INVALID -> "invalid" + * any other -> "%d" * @endcode * + * In the "any other" case, the return value points to a static buffer + * that will be overwritten next time this function is called with an + * "other" type. */ const char * dbus_message_type_to_string (int type) { switch (type) { + case DBUS_MESSAGE_TYPE_INVALID: + return "invalid"; case DBUS_MESSAGE_TYPE_METHOD_CALL: return "method_call"; case DBUS_MESSAGE_TYPE_METHOD_RETURN: @@ -3915,7 +3921,12 @@ dbus_message_type_to_string (int type) case DBUS_MESSAGE_TYPE_ERROR: return "error"; default: - return "invalid"; + { + static char buffer[50]; + + sprintf (buffer, "%d", type); + return buffer; + } } } diff --git a/dbus/dbus-sockets-win.h b/dbus/dbus-sockets-win.h deleted file mode 100644 index 371672e..0000000 --- a/dbus/dbus-sockets-win.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* dbus-sockets.h Wrappers around socket features (internal to D-BUS implementation) - * - * Copyright (C) 2005 Novell, Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef DBUS_SOCKETS_H -#define DBUS_SOCKETS_H - -#if defined(DBUS_WIN) || defined(DBUS_WINCE) - - - -#ifndef STRICT -#define STRICT -#include -#undef STRICT -#endif -#include - -#undef interface - -#include - -/* Make use of the fact that the WSAE* error codes don't - * overlap with errno E* codes. Wrapper functions store - * the return value from WSAGetLastError() in errno. - */ -#if defined(EPROTONOSUPPORT) || \ - defined(EAFNOSUPPORT) || \ - defined(EWOULDBLOCK) -#error This does not look like Win32 and the Microsoft C library -#endif - -#define EPROTONOSUPPORT WSAEPROTONOSUPPORT -#define EAFNOSUPPORT WSAEAFNOSUPPORT -#define EWOULDBLOCK WSAEWOULDBLOCK - -#define DBUS_SOCKET_IS_INVALID(s) ((SOCKET)(s) == INVALID_SOCKET) -#define DBUS_SOCKET_API_RETURNS_ERROR(n) ((n) == SOCKET_ERROR) -#define DBUS_SOCKET_SET_ERRNO() errno = WSAGetLastError() - -#define DBUS_CLOSE_SOCKET(s) closesocket(s) - -#else - -#include -#include -#include -#include -#include - -#define DBUS_SOCKET_IS_INVALID(s) ((s) < 0) -#define DBUS_SOCKET_API_RETURNS_ERROR(n) ((n) < 0) -#define DBUS_SOCKET_SET_ERRNO() /* empty */ - -#define DBUS_CLOSE_SOCKET(s) close(s) - -#endif /* !Win32 */ - -#endif /* DBUS_SOCKETS_H */ diff --git a/dbus/dbus-spawn-win.c b/dbus/dbus-spawn-win.c index c2ad16b..e0b51ee 100644 --- a/dbus/dbus-spawn-win.c +++ b/dbus/dbus-spawn-win.c @@ -268,6 +268,22 @@ _dbus_babysitter_get_child_exited (DBusBabysitter *sitter) return (sitter->child_handle == NULL); } +dbus_bool_t +_dbus_babysitter_get_child_exit_status (DBusBabysitter *sitter, + int *status) +{ + PING(); + + if (!_dbus_babysitter_get_child_exited (sitter)) + _dbus_assert_not_reached ("Child has not exited"); + + if (!sitter->have_child_status) + return FALSE; + + *status = sitter->child_status; + return TRUE; +} + /** * Sets the #DBusError with an explanation of why the spawned * child process exited (on a signal, or whatever). If diff --git a/dbus/dbus-sysdeps-thread-win.c b/dbus/dbus-sysdeps-thread-win.c index 34f0948..e40513e 100644 --- a/dbus/dbus-sysdeps-thread-win.c +++ b/dbus/dbus-sysdeps-thread-win.c @@ -36,6 +36,14 @@ struct DBusCondVar { static DWORD dbus_cond_event_tls = TLS_OUT_OF_INDEXES; +static HMODULE dbus_dll_hmodule; + +void * +_dbus_win_get_dll_hmodule (void) +{ + return dbus_dll_hmodule; +} + BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved); @@ -49,22 +57,25 @@ DllMain (HINSTANCE hinstDLL, HANDLE event; switch (fdwReason) { + case DLL_PROCESS_ATTACH: + dbus_dll_hmodule = hinstDLL; + break; case DLL_THREAD_DETACH: if (dbus_cond_event_tls != TLS_OUT_OF_INDEXES) { - event = TlsGetValue(dbus_cond_event_tls); + event = TlsGetValue (dbus_cond_event_tls); CloseHandle (event); - TlsSetValue(dbus_cond_event_tls, NULL); + TlsSetValue (dbus_cond_event_tls, NULL); } break; case DLL_PROCESS_DETACH: if (dbus_cond_event_tls != TLS_OUT_OF_INDEXES) { - event = TlsGetValue(dbus_cond_event_tls); + event = TlsGetValue (dbus_cond_event_tls); CloseHandle (event); - TlsSetValue(dbus_cond_event_tls, NULL); + TlsSetValue (dbus_cond_event_tls, NULL); - TlsFree(dbus_cond_event_tls); + TlsFree (dbus_cond_event_tls); } break; default: diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index 64d925d..a52ebeb 100644 --- a/dbus/dbus-sysdeps-unix.c +++ b/dbus/dbus-sysdeps-unix.c @@ -758,6 +758,7 @@ _dbus_connect_tcp_socket (const char *host, const char *family, DBusError *error) { + int saved_errno; int fd = -1, res; struct addrinfo hints; struct addrinfo *ai, *tmp; @@ -782,6 +783,7 @@ _dbus_connect_tcp_socket (const char *host, hints.ai_family = AF_INET6; else { + errno = EAFNOSUPPORT; dbus_set_error (error, _dbus_error_from_errno (errno), "Unknown address family %s", family); @@ -815,6 +817,7 @@ _dbus_connect_tcp_socket (const char *host, if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0) { + saved_errno = errno; _dbus_close(fd, NULL); fd = -1; tmp = tmp->ai_next; @@ -828,9 +831,9 @@ _dbus_connect_tcp_socket (const char *host, if (fd == -1) { dbus_set_error (error, - _dbus_error_from_errno (errno), + _dbus_error_from_errno (saved_errno), "Failed to connect to socket \"%s:%s\" %s", - host, port, _dbus_strerror(errno)); + host, port, _dbus_strerror(saved_errno)); return -1; } @@ -868,6 +871,7 @@ _dbus_listen_tcp_socket (const char *host, int **fds_p, DBusError *error) { + int saved_errno; int nlisten_fd = 0, *listen_fd = NULL, res, i; struct addrinfo hints; struct addrinfo *ai, *tmp; @@ -885,6 +889,7 @@ _dbus_listen_tcp_socket (const char *host, hints.ai_family = AF_INET6; else { + errno = EAFNOSUPPORT; dbus_set_error (error, _dbus_error_from_errno (errno), "Unknown address family %s", family); @@ -918,8 +923,9 @@ _dbus_listen_tcp_socket (const char *host, if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0) { + saved_errno = errno; _dbus_close(fd, NULL); - if (errno == EADDRINUSE) + if (saved_errno == EADDRINUSE) { /* Depending on kernel policy, it may or may not be neccessary to bind to both IPv4 & 6 addresses @@ -927,28 +933,30 @@ _dbus_listen_tcp_socket (const char *host, tmp = tmp->ai_next; continue; } - dbus_set_error (error, _dbus_error_from_errno (errno), + dbus_set_error (error, _dbus_error_from_errno (saved_errno), "Failed to bind socket \"%s:%s\": %s", - host ? host : "*", port, _dbus_strerror (errno)); + host ? host : "*", port, _dbus_strerror (saved_errno)); goto failed; } if (listen (fd, 30 /* backlog */) < 0) { + saved_errno = errno; _dbus_close (fd, NULL); - dbus_set_error (error, _dbus_error_from_errno (errno), + dbus_set_error (error, _dbus_error_from_errno (saved_errno), "Failed to listen on socket \"%s:%s\": %s", - host ? host : "*", port, _dbus_strerror (errno)); + host ? host : "*", port, _dbus_strerror (saved_errno)); goto failed; } newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1)); if (!newlisten_fd) { + saved_errno = errno; _dbus_close (fd, NULL); - dbus_set_error (error, _dbus_error_from_errno (errno), + dbus_set_error (error, _dbus_error_from_errno (saved_errno), "Failed to allocate file handle array: %s", - _dbus_strerror (errno)); + _dbus_strerror (saved_errno)); goto failed; } listen_fd = newlisten_fd; @@ -2789,6 +2797,30 @@ _dbus_get_tmpdir(void) } /** + * Make the address of the session bus discoverable by other programs + * running in the same session. Does anything only on Windows, where + * the session-bus address is stored in a (local to each session + * namespace) file mapping, i.e. shared memory segment. + * + * @param address the session bus address + */ +void +_dbus_publish_session_bus_address (const char *address) +{ +} + +/** + * Reverts what _dbus_publish_session_bus_address() did. Thus does + * anything only on Windows. + * + * @param address the session bus address + */ +void +_dbus_unpublish_session_bus_address (void) +{ +} + +/** * Determines the address of the session bus by querying a * platform-specific method. * @@ -3038,6 +3070,11 @@ _dbus_read_local_machine_uuid (DBusGUID *machine_id, * * DBUS_DATADIR * + * On Windows this should be the folders specified by: + * + * CSIDL_APPDATA/dbus + * CSIDL_PROGRAM_FILES_COMMON/dbus + * * @param dirs the directory list we are returning * @returns #FALSE on OOM */ diff --git a/dbus/dbus-sysdeps-util-win.c b/dbus/dbus-sysdeps-util-win.c index 8608ad0..7b01a47 100644 --- a/dbus/dbus-sysdeps-util-win.c +++ b/dbus/dbus-sysdeps-util-win.c @@ -22,56 +22,38 @@ * */ -#undef open +/* The order of functions in this file should be identical to that in + * dbus-sysdeps-util-unix.c. For each function that also exists in + * dbus-sysdeps-util-unix.c, the prototype should be identical. As all + * functions in this file are private to the dbus implementation, + * there is absolutely no need to implement Windows versions of + * functions not used by the rest of the d-bus code on Windows. + * + * doc comments should not be duplicated here. + */ #define STRSAFE_NO_DEPRECATE -#include "dbus-sysdeps.h" -#include "dbus-internals.h" -#include "dbus-protocol.h" -#include "dbus-string.h" -#include "dbus-sysdeps.h" -#include "dbus-sysdeps-win.h" -#include "dbus-memory.h" +#include +#include #include -#include -#include #include #include +#include #include #include +#include -#if defined __MINGW32__ || (defined _MSC_VER && _MSC_VER <= 1310) -/* save string functions version - using DBusString needs to much time because of uncommon api -*/ -#define errno_t int - -errno_t strcat_s(char *dest, size_t size, char *src) -{ - _dbus_assert(strlen(dest) + strlen(src) +1 <= size); - strcat(dest,src); - return 0; -} - -errno_t strcpy_s(char *dest, size_t size, char *src) -{ - _dbus_assert(strlen(src) +1 <= size); - strcpy(dest,src); - return 0; -} -#endif +#include "dbus-sysdeps.h" +#include "dbus-internals.h" +#include "dbus-protocol.h" +#include "dbus-string.h" +#include "dbus-sysdeps.h" +#include "dbus-sysdeps-win.h" +#include "dbus-memory.h" -/** - * Does the chdir, fork, setsid, etc. to become a daemon process. - * - * @param pidfile #NULL, or pidfile to create - * @param print_pid_fd file descriptor to print daemon's pid to, or -1 for none - * @param error return location for errors - * @returns #FALSE on failure - */ dbus_bool_t _dbus_become_daemon (const DBusString *pidfile, DBusPipe *print_pid_pipe, @@ -80,38 +62,32 @@ _dbus_become_daemon (const DBusString *pidfile, return TRUE; } -/** - * Creates a file containing the process ID. - * - * @param filename the filename to write to - * @param pid our process ID - * @param error return location for errors - * @returns #FALSE on failure - */ -dbus_bool_t +static dbus_bool_t _dbus_write_pid_file (const DBusString *filename, unsigned long pid, - DBusError *error) + DBusError *error) { const char *cfilename; - DBusFile file; + int fd; FILE *f; cfilename = _dbus_string_get_const_data (filename); - - if (!_dbus_file_open(&file, cfilename, O_WRONLY|O_CREAT|O_EXCL|O_BINARY, 0644)) + + fd = _open (cfilename, O_WRONLY|O_CREAT|O_EXCL|O_BINARY, 0644); + + if (fd < 0) { dbus_set_error (error, _dbus_error_from_errno (errno), "Failed to open \"%s\": %s", cfilename, - _dbus_strerror (errno)); + strerror (errno)); return FALSE; } - if ((f = fdopen (file.FDATA, "w")) == NULL) + if ((f = fdopen (fd, "w")) == NULL) { dbus_set_error (error, _dbus_error_from_errno (errno), - "Failed to fdopen fd %d: %s", file.FDATA, _dbus_strerror (errno)); - _dbus_file_close (&file, NULL); + "Failed to fdopen fd %d: %s", fd, strerror (errno)); + _close (fd); return FALSE; } @@ -119,7 +95,7 @@ _dbus_write_pid_file (const DBusString *filename, { dbus_set_error (error, _dbus_error_from_errno (errno), "Failed to write to \"%s\": %s", cfilename, - _dbus_strerror (errno)); + strerror (errno)); fclose (f); return FALSE; @@ -129,32 +105,86 @@ _dbus_write_pid_file (const DBusString *filename, { dbus_set_error (error, _dbus_error_from_errno (errno), "Failed to close \"%s\": %s", cfilename, - _dbus_strerror (errno)); + strerror (errno)); return FALSE; } + + return TRUE; +} + +dbus_bool_t +_dbus_write_pid_to_file_and_pipe (const DBusString *pidfile, + DBusPipe *print_pid_pipe, + dbus_pid_t pid_to_write, + DBusError *error) +{ + if (pidfile) + { + _dbus_verbose ("writing pid file %s\n", _dbus_string_get_const_data (pidfile)); + if (!_dbus_write_pid_file (pidfile, + pid_to_write, + error)) + { + _dbus_verbose ("pid file write failed\n"); + _DBUS_ASSERT_ERROR_IS_SET(error); + return FALSE; + } + } + else + { + _dbus_verbose ("No pid file requested\n"); + } + + if (print_pid_pipe != NULL && _dbus_pipe_is_valid (print_pid_pipe)) + { + DBusString pid; + int bytes; + + _dbus_verbose ("writing our pid to pipe %d\n", print_pid_pipe->fd_or_handle); + + if (!_dbus_string_init (&pid)) + { + _DBUS_SET_OOM (error); + return FALSE; + } + + if (!_dbus_string_append_int (&pid, pid_to_write) || + !_dbus_string_append (&pid, "\n")) + { + _dbus_string_free (&pid); + _DBUS_SET_OOM (error); + return FALSE; + } + + bytes = _dbus_string_get_length (&pid); + if (_dbus_pipe_write (print_pid_pipe, &pid, 0, bytes, error) != bytes) + { + /* _dbus_pipe_write sets error only on failure, not short write */ + if (error != NULL && !dbus_error_is_set(error)) + { + dbus_set_error (error, DBUS_ERROR_FAILED, + "Printing message bus PID: did not write enough bytes\n"); + } + _dbus_string_free (&pid); + return FALSE; + } + + _dbus_string_free (&pid); + } + else + { + _dbus_verbose ("No pid pipe to write to\n"); + } return TRUE; } -/** - * Verify that after the fork we can successfully change to this user. - * - * @param user the username given in the daemon configuration - * @returns #TRUE if username is valid - */ dbus_bool_t _dbus_verify_daemon_user (const char *user) { return TRUE; } -/** - * Changes the user and group the bus is running as. - * - * @param user the user to become - * @param error return location for errors - * @returns #FALSE on failure - */ dbus_bool_t _dbus_change_to_daemon_user (const char *user, DBusError *error) @@ -162,34 +192,58 @@ _dbus_change_to_daemon_user (const char *user, return TRUE; } +void +_dbus_set_signal_handler (int sig, + DBusSignalHandler handler) +{ +} + + /** - * Changes the user and group the bus is running as. - * - * @param uid the new user ID - * @param gid the new group ID - * @param error return location for errors - * @returns #FALSE on failure + * Removes a directory; Directory must be empty + * + * @param filename directory filename + * @param error initialized error object + * @returns #TRUE on success */ dbus_bool_t -_dbus_change_identity (dbus_uid_t uid, - dbus_gid_t gid, - DBusError *error) +_dbus_delete_directory (const DBusString *filename, + DBusError *error) { + const char *filename_c; + + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + + filename_c = _dbus_string_get_const_data (filename); + + if (_rmdir (filename_c) != 0) + { + dbus_set_error (error, DBUS_ERROR_FAILED, + "Failed to remove directory %s: %s\n", + filename_c, strerror (errno)); + return FALSE; + } + return TRUE; } -/** Checks if user is at the console -* -* @param username user to check -* @param error return location for errors -* @returns #TRUE is the user is at the consolei and there are no errors -*/ +dbus_bool_t +_dbus_file_exists (const char *file) +{ + DWORD attributes = GetFileAttributes (file); + + if (attributes != INVALID_FILE_ATTRIBUTES && GetLastError() != ERROR_PATH_NOT_FOUND) + return TRUE; + else + return FALSE; +} + dbus_bool_t _dbus_user_at_console(const char *username, DBusError *error) { #ifdef DBUS_WINCE - return TRUE; + return TRUE; #else dbus_bool_t retval = FALSE; wchar_t *wusername; @@ -201,7 +255,7 @@ _dbus_user_at_console(const char *username, if (!wusername) return FALSE; - // TODO remove + /* TODO remove */ if (!_dbus_win_account_to_sid (wusername, &user_sid, error)) goto out0; @@ -264,103 +318,32 @@ out0: #endif //DBUS_WINCE } -/** - * Removes a directory; Directory must be empty - * - * @param filename directory filename - * @param error initialized error object - * @returns #TRUE on success - */ dbus_bool_t -_dbus_delete_directory (const DBusString *filename, - DBusError *error) -{ - const char *filename_c; - - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - - filename_c = _dbus_string_get_const_data (filename); - - if (rmdir (filename_c) != 0) - { - dbus_set_error (error, DBUS_ERROR_FAILED, - "Failed to remove directory %s: %s\n", - filename_c, _dbus_strerror (errno)); - return FALSE; - } - - return TRUE; -} - -/** Installs a signal handler - * - * @param sig the signal to handle - * @param handler the handler - */ -void -_dbus_set_signal_handler (int sig, - DBusSignalHandler handler) -{ - _dbus_verbose ("_dbus_set_signal_handler() has to be implemented\n"); -} - -/** Checks if a file exists -* -* @param file full path to the file -* @returns #TRUE if file exists -*/ -dbus_bool_t -_dbus_file_exists (const char *file) +_dbus_path_is_absolute (const DBusString *filename) { - HANDLE h = CreateFile( - file, /* LPCTSTR lpFileName*/ - 0, /* DWORD dwDesiredAccess */ - 0, /* DWORD dwShareMode*/ - NULL, /* LPSECURITY_ATTRIBUTES lpSecurityAttributes */ - OPEN_EXISTING, /* DWORD dwCreationDisposition */ - FILE_ATTRIBUTE_NORMAL, /* DWORD dwFlagsAndAttributes */ - NULL /* HANDLE hTemplateFile */ - ); - - /* file not found, use local copy of session.conf */ - if (h != INVALID_HANDLE_VALUE && GetLastError() != ERROR_PATH_NOT_FOUND) - { - CloseHandle(h); - return TRUE; - } - else - return FALSE; + if (_dbus_string_get_length (filename) > 0) + return _dbus_string_get_byte (filename, 1) == ':' + || _dbus_string_get_byte (filename, 0) == '\\' + || _dbus_string_get_byte (filename, 0) == '/'; + else + return FALSE; } -/** - * stat() wrapper. - * - * @param filename the filename to stat - * @param statbuf the stat info to fill in - * @param error return location for error - * @returns #FALSE if error was set - */ dbus_bool_t _dbus_stat(const DBusString *filename, DBusStat *statbuf, DBusError *error) { #ifdef DBUS_WINCE - return TRUE; - //TODO + /* TODO */ + return TRUE; #else const char *filename_c; -#if !defined(DBUS_WIN) && !defined(DBUS_WINCE) - - struct stat sb; -#else - WIN32_FILE_ATTRIBUTE_DATA wfad; char *lastdot; DWORD rc; PSID owner_sid, group_sid; PSECURITY_DESCRIPTOR sd; -#endif _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -592,13 +575,6 @@ struct DBusDirIter }; -/** - * Open a directory to iterate over. - * - * @param filename the directory name - * @param error exception return object or #NULL - * @returns new iterator, or #NULL on error - */ DBusDirIter* _dbus_directory_open (const DBusString *filename, DBusError *error) @@ -617,7 +593,7 @@ _dbus_directory_open (const DBusString *filename, dbus_set_error (error, _dbus_error_from_errno (errno), "Failed to read directory \"%s\": %s", filename_c, - _dbus_strerror (errno)); + strerror (errno)); return NULL; } iter = dbus_new0 (DBusDirIter, 1); @@ -634,19 +610,6 @@ _dbus_directory_open (const DBusString *filename, return iter; } -/** - * Get next file in the directory. Will not return "." or ".." on - * UNIX. If an error occurs, the contents of "filename" are - * undefined. The error is never set if the function succeeds. - * - * @todo for thread safety, I think we have to use - * readdir_r(). (GLib has the same issue, should file a bug.) - * - * @param iter the iterator - * @param filename string to be set to the next file in the dir - * @param error return location for error - * @returns #TRUE if filename was filled in with a new filename - */ dbus_bool_t _dbus_directory_get_next_file (DBusDirIter *iter, DBusString *filename, @@ -664,7 +627,7 @@ again: if (errno != 0) dbus_set_error (error, _dbus_error_from_errno (errno), - "%s", _dbus_strerror (errno)); + "%s", strerror (errno)); return FALSE; } else if (ent->d_name[0] == '.' && @@ -685,9 +648,6 @@ again: } } -/** - * Closes a directory iteration. - */ void _dbus_directory_close (DBusDirIter *iter) { @@ -695,36 +655,49 @@ _dbus_directory_close (DBusDirIter *iter) dbus_free (iter); } -/** - * Checks whether the filename is an absolute path - * - * @param filename the filename - * @returns #TRUE if an absolute path - */ dbus_bool_t -_dbus_path_is_absolute (const DBusString *filename) +_dbus_parse_unix_group_from_config (const DBusString *groupname, + dbus_gid_t *gid_p) { - if (_dbus_string_get_length (filename) > 0) - return _dbus_string_get_byte (filename, 1) == ':' - || _dbus_string_get_byte (filename, 0) == '\\' - || _dbus_string_get_byte (filename, 0) == '/'; - else - return FALSE; + return FALSE; +} + +dbus_bool_t +_dbus_parse_unix_user_from_config (const DBusString *username, + dbus_uid_t *uid_p) +{ + return FALSE; } -/** @} */ /* End of DBusInternalsUtils functions */ -/** - * @addtogroup DBusString - * - * @{ - */ -/** - * Get the directory name from a complete filename - * @param filename the filename - * @param dirname string to append directory name to - * @returns #FALSE if no memory - */ +dbus_bool_t +_dbus_unix_groups_from_uid (dbus_uid_t uid, + dbus_gid_t **group_ids, + int *n_group_ids) +{ + return FALSE; +} + +dbus_bool_t +_dbus_unix_user_is_at_console (dbus_uid_t uid, + DBusError *error) +{ + dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, "Not UNIX"); + + return FALSE; +} + +dbus_bool_t +_dbus_unix_user_is_process_owner (dbus_uid_t uid) +{ + return FALSE; +} + +dbus_bool_t _dbus_windows_user_is_process_owner (const char *windows_sid) +{ + return TRUE; +} + dbus_bool_t _dbus_string_get_dirname(const DBusString *filename, DBusString *dirname) @@ -785,927 +758,3 @@ _dbus_string_get_dirname(const DBusString *filename, dirname, _dbus_string_get_length (dirname)); } - -/** - * Checks to see if the UNIX user ID matches the UID of - * the process. Should always return #FALSE on Windows. - * - * @param uid the UNIX user ID - * @returns #TRUE if this uid owns the process. - */ -dbus_bool_t -_dbus_unix_user_is_process_owner (dbus_uid_t uid) -{ - return FALSE; -} - -/*===================================================================== - unix emulation functions - should be removed sometime in the future - =====================================================================*/ - -/** - * Checks to see if the UNIX user ID is at the console. - * Should always fail on Windows (set the error to - * #DBUS_ERROR_NOT_SUPPORTED). - * - * @param uid UID of person to check - * @param error return location for errors - * @returns #TRUE if the UID is the same as the console user and there are no errors - */ -dbus_bool_t -_dbus_unix_user_is_at_console (dbus_uid_t uid, - DBusError *error) -{ - return FALSE; -} - - -/** - * Parse a UNIX group from the bus config file. On Windows, this should - * simply always fail (just return #FALSE). - * - * @param groupname the groupname text - * @param gid_p place to return the gid - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_parse_unix_group_from_config (const DBusString *groupname, - dbus_gid_t *gid_p) -{ - return FALSE; -} - -/** - * Parse a UNIX user from the bus config file. On Windows, this should - * simply always fail (just return #FALSE). - * - * @param username the username text - * @param uid_p place to return the uid - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_parse_unix_user_from_config (const DBusString *username, - dbus_uid_t *uid_p) -{ - return FALSE; -} - - -/** - * Gets all groups corresponding to the given UNIX user ID. On UNIX, - * just calls _dbus_groups_from_uid(). On Windows, should always - * fail since we don't know any UNIX groups. - * - * @param uid the UID - * @param group_ids return location for array of group IDs - * @param n_group_ids return location for length of returned array - * @returns #TRUE if the UID existed and we got some credentials - */ -dbus_bool_t -_dbus_unix_groups_from_uid (dbus_uid_t uid, - dbus_gid_t **group_ids, - int *n_group_ids) -{ - return FALSE; -} - - - -/** @} */ /* DBusString stuff */ - -/************************************************************************ - - error handling - - ************************************************************************/ - - -/** - * Assigns an error name and message corresponding to a Win32 error - * code to a DBusError. Does nothing if error is #NULL. - * - * @param error the error. - * @param code the Win32 error code - */ -void -_dbus_win_set_error_from_win_error (DBusError *error, - int code) -{ - char *msg; - - /* As we want the English message, use the A API */ - FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_IGNORE_INSERTS | - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, code, MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US), - (LPTSTR) &msg, 0, NULL); - if (msg) - { - char *msg_copy; - - msg_copy = dbus_malloc (strlen (msg)); - strcpy (msg_copy, msg); - LocalFree (msg); - - dbus_set_error (error, "win32.error", "%s", msg_copy); - } - else - dbus_set_error (error, "win32.error", "Unknown error code %d or FormatMessage failed", code); -} - -void -_dbus_win_warn_win_error (const char *message, - int code) -{ - DBusError error = DBUS_ERROR_INIT; - - _dbus_win_set_error_from_win_error (&error, code); - _dbus_warn ("%s: %s\n", message, error.message); - dbus_error_free (&error); -} - -/** - * A wrapper around strerror() because some platforms - * may be lame and not have strerror(). - * - * @param error_number errno. - * @returns error description. - */ -const char* -_dbus_strerror (int error_number) -{ -#ifdef DBUS_WINCE - // TODO - return "unknown"; -#else - const char *msg; - - switch (error_number) - { - case WSAEINTR: - return "Interrupted function call"; - case WSAEACCES: - return "Permission denied"; - case WSAEFAULT: - return "Bad address"; - case WSAEINVAL: - return "Invalid argument"; - case WSAEMFILE: - return "Too many open files"; - case WSAEWOULDBLOCK: - return "Resource temporarily unavailable"; - case WSAEINPROGRESS: - return "Operation now in progress"; - case WSAEALREADY: - return "Operation already in progress"; - case WSAENOTSOCK: - return "Socket operation on nonsocket"; - case WSAEDESTADDRREQ: - return "Destination address required"; - case WSAEMSGSIZE: - return "Message too long"; - case WSAEPROTOTYPE: - return "Protocol wrong type for socket"; - case WSAENOPROTOOPT: - return "Bad protocol option"; - case WSAEPROTONOSUPPORT: - return "Protocol not supported"; - case WSAESOCKTNOSUPPORT: - return "Socket type not supported"; - case WSAEOPNOTSUPP: - return "Operation not supported"; - case WSAEPFNOSUPPORT: - return "Protocol family not supported"; - case WSAEAFNOSUPPORT: - return "Address family not supported by protocol family"; - case WSAEADDRINUSE: - return "Address already in use"; - case WSAEADDRNOTAVAIL: - return "Cannot assign requested address"; - case WSAENETDOWN: - return "Network is down"; - case WSAENETUNREACH: - return "Network is unreachable"; - case WSAENETRESET: - return "Network dropped connection on reset"; - case WSAECONNABORTED: - return "Software caused connection abort"; - case WSAECONNRESET: - return "Connection reset by peer"; - case WSAENOBUFS: - return "No buffer space available"; - case WSAEISCONN: - return "Socket is already connected"; - case WSAENOTCONN: - return "Socket is not connected"; - case WSAESHUTDOWN: - return "Cannot send after socket shutdown"; - case WSAETIMEDOUT: - return "Connection timed out"; - case WSAECONNREFUSED: - return "Connection refused"; - case WSAEHOSTDOWN: - return "Host is down"; - case WSAEHOSTUNREACH: - return "No route to host"; - case WSAEPROCLIM: - return "Too many processes"; - case WSAEDISCON: - return "Graceful shutdown in progress"; - case WSATYPE_NOT_FOUND: - return "Class type not found"; - case WSAHOST_NOT_FOUND: - return "Host not found"; - case WSATRY_AGAIN: - return "Nonauthoritative host not found"; - case WSANO_RECOVERY: - return "This is a nonrecoverable error"; - case WSANO_DATA: - return "Valid name, no data record of requested type"; - case WSA_INVALID_HANDLE: - return "Specified event object handle is invalid"; - case WSA_INVALID_PARAMETER: - return "One or more parameters are invalid"; - case WSA_IO_INCOMPLETE: - return "Overlapped I/O event object not in signaled state"; - case WSA_IO_PENDING: - return "Overlapped operations will complete later"; - case WSA_NOT_ENOUGH_MEMORY: - return "Insufficient memory available"; - case WSA_OPERATION_ABORTED: - return "Overlapped operation aborted"; -#ifdef WSAINVALIDPROCTABLE - - case WSAINVALIDPROCTABLE: - return "Invalid procedure table from service provider"; -#endif -#ifdef WSAINVALIDPROVIDER - - case WSAINVALIDPROVIDER: - return "Invalid service provider version number"; -#endif -#ifdef WSAPROVIDERFAILEDINIT - - case WSAPROVIDERFAILEDINIT: - return "Unable to initialize a service provider"; -#endif - - case WSASYSCALLFAILURE: - return "System call failure"; - } - msg = strerror (error_number); - if (msg == NULL) - msg = "unknown"; - - return msg; -#endif //DBUS_WINCE -} - - - -/* lan manager error codes */ -const char* -_dbus_lm_strerror(int error_number) -{ -#ifdef DBUS_WINCE - // TODO - return "unknown"; -#else - const char *msg; - switch (error_number) - { - case NERR_NetNotStarted: - return "The workstation driver is not installed."; - case NERR_UnknownServer: - return "The server could not be located."; - case NERR_ShareMem: - return "An internal error occurred. The network cannot access a shared memory segment."; - case NERR_NoNetworkResource: - return "A network resource shortage occurred."; - case NERR_RemoteOnly: - return "This operation is not supported on workstations."; - case NERR_DevNotRedirected: - return "The device is not connected."; - case NERR_ServerNotStarted: - return "The Server service is not started."; - case NERR_ItemNotFound: - return "The queue is empty."; - case NERR_UnknownDevDir: - return "The device or directory does not exist."; - case NERR_RedirectedPath: - return "The operation is invalid on a redirected resource."; - case NERR_DuplicateShare: - return "The name has already been shared."; - case NERR_NoRoom: - return "The server is currently out of the requested resource."; - case NERR_TooManyItems: - return "Requested addition of items exceeds the maximum allowed."; - case NERR_InvalidMaxUsers: - return "The Peer service supports only two simultaneous users."; - case NERR_BufTooSmall: - return "The API return buffer is too small."; - case NERR_RemoteErr: - return "A remote API error occurred."; - case NERR_LanmanIniError: - return "An error occurred when opening or reading the configuration file."; - case NERR_NetworkError: - return "A general network error occurred."; - case NERR_WkstaInconsistentState: - return "The Workstation service is in an inconsistent state. Restart the computer before restarting the Workstation service."; - case NERR_WkstaNotStarted: - return "The Workstation service has not been started."; - case NERR_BrowserNotStarted: - return "The requested information is not available."; - case NERR_InternalError: - return "An internal error occurred."; - case NERR_BadTransactConfig: - return "The server is not configured for transactions."; - case NERR_InvalidAPI: - return "The requested API is not supported on the remote server."; - case NERR_BadEventName: - return "The event name is invalid."; - case NERR_DupNameReboot: - return "The computer name already exists on the network. Change it and restart the computer."; - case NERR_CfgCompNotFound: - return "The specified component could not be found in the configuration information."; - case NERR_CfgParamNotFound: - return "The specified parameter could not be found in the configuration information."; - case NERR_LineTooLong: - return "A line in the configuration file is too long."; - case NERR_QNotFound: - return "The printer does not exist."; - case NERR_JobNotFound: - return "The print job does not exist."; - case NERR_DestNotFound: - return "The printer destination cannot be found."; - case NERR_DestExists: - return "The printer destination already exists."; - case NERR_QExists: - return "The printer queue already exists."; - case NERR_QNoRoom: - return "No more printers can be added."; - case NERR_JobNoRoom: - return "No more print jobs can be added."; - case NERR_DestNoRoom: - return "No more printer destinations can be added."; - case NERR_DestIdle: - return "This printer destination is idle and cannot accept control operations."; - case NERR_DestInvalidOp: - return "This printer destination request contains an invalid control function."; - case NERR_ProcNoRespond: - return "The print processor is not responding."; - case NERR_SpoolerNotLoaded: - return "The spooler is not running."; - case NERR_DestInvalidState: - return "This operation cannot be performed on the print destination in its current state."; - case NERR_QInvalidState: - return "This operation cannot be performed on the printer queue in its current state."; - case NERR_JobInvalidState: - return "This operation cannot be performed on the print job in its current state."; - case NERR_SpoolNoMemory: - return "A spooler memory allocation failure occurred."; - case NERR_DriverNotFound: - return "The device driver does not exist."; - case NERR_DataTypeInvalid: - return "The data type is not supported by the print processor."; - case NERR_ProcNotFound: - return "The print processor is not installed."; - case NERR_ServiceTableLocked: - return "The service database is locked."; - case NERR_ServiceTableFull: - return "The service table is full."; - case NERR_ServiceInstalled: - return "The requested service has already been started."; - case NERR_ServiceEntryLocked: - return "The service does not respond to control actions."; - case NERR_ServiceNotInstalled: - return "The service has not been started."; - case NERR_BadServiceName: - return "The service name is invalid."; - case NERR_ServiceCtlTimeout: - return "The service is not responding to the control function."; - case NERR_ServiceCtlBusy: - return "The service control is busy."; - case NERR_BadServiceProgName: - return "The configuration file contains an invalid service program name."; - case NERR_ServiceNotCtrl: - return "The service could not be controlled in its present state."; - case NERR_ServiceKillProc: - return "The service ended abnormally."; - case NERR_ServiceCtlNotValid: - return "The requested pause or stop is not valid for this service."; - case NERR_NotInDispatchTbl: - return "The service control dispatcher could not find the service name in the dispatch table."; - case NERR_BadControlRecv: - return "The service control dispatcher pipe read failed."; - case NERR_ServiceNotStarting: - return "A thread for the new service could not be created."; - case NERR_AlreadyLoggedOn: - return "This workstation is already logged on to the local-area network."; - case NERR_NotLoggedOn: - return "The workstation is not logged on to the local-area network."; - case NERR_BadUsername: - return "The user name or group name parameter is invalid."; - case NERR_BadPassword: - return "The password parameter is invalid."; - case NERR_UnableToAddName_W: - return "@W The logon processor did not add the message alias."; - case NERR_UnableToAddName_F: - return "The logon processor did not add the message alias."; - case NERR_UnableToDelName_W: - return "@W The logoff processor did not delete the message alias."; - case NERR_UnableToDelName_F: - return "The logoff processor did not delete the message alias."; - case NERR_LogonsPaused: - return "Network logons are paused."; - case NERR_LogonServerConflict: - return "A centralized logon-server conflict occurred."; - case NERR_LogonNoUserPath: - return "The server is configured without a valid user path."; - case NERR_LogonScriptError: - return "An error occurred while loading or running the logon script."; - case NERR_StandaloneLogon: - return "The logon server was not specified. Your computer will be logged on as STANDALONE."; - case NERR_LogonServerNotFound: - return "The logon server could not be found."; - case NERR_LogonDomainExists: - return "There is already a logon domain for this computer."; - case NERR_NonValidatedLogon: - return "The logon server could not validate the logon."; - case NERR_ACFNotFound: - return "The security database could not be found."; - case NERR_GroupNotFound: - return "The group name could not be found."; - case NERR_UserNotFound: - return "The user name could not be found."; - case NERR_ResourceNotFound: - return "The resource name could not be found."; - case NERR_GroupExists: - return "The group already exists."; - case NERR_UserExists: - return "The user account already exists."; - case NERR_ResourceExists: - return "The resource permission list already exists."; - case NERR_NotPrimary: - return "This operation is only allowed on the primary domain controller of the domain."; - case NERR_ACFNotLoaded: - return "The security database has not been started."; - case NERR_ACFNoRoom: - return "There are too many names in the user accounts database."; - case NERR_ACFFileIOFail: - return "A disk I/O failure occurred."; - case NERR_ACFTooManyLists: - return "The limit of 64 entries per resource was exceeded."; - case NERR_UserLogon: - return "Deleting a user with a session is not allowed."; - case NERR_ACFNoParent: - return "The parent directory could not be located."; - case NERR_CanNotGrowSegment: - return "Unable to add to the security database session cache segment."; - case NERR_SpeGroupOp: - return "This operation is not allowed on this special group."; - case NERR_NotInCache: - return "This user is not cached in user accounts database session cache."; - case NERR_UserInGroup: - return "The user already belongs to this group."; - case NERR_UserNotInGroup: - return "The user does not belong to this group."; - case NERR_AccountUndefined: - return "This user account is undefined."; - case NERR_AccountExpired: - return "This user account has expired."; - case NERR_InvalidWorkstation: - return "The user is not allowed to log on from this workstation."; - case NERR_InvalidLogonHours: - return "The user is not allowed to log on at this time."; - case NERR_PasswordExpired: - return "The password of this user has expired."; - case NERR_PasswordCantChange: - return "The password of this user cannot change."; - case NERR_PasswordHistConflict: - return "This password cannot be used now."; - case NERR_PasswordTooShort: - return "The password does not meet the password policy requirements. Check the minimum password length, password complexity and password history requirements."; - case NERR_PasswordTooRecent: - return "The password of this user is too recent to change."; - case NERR_InvalidDatabase: - return "The security database is corrupted."; - case NERR_DatabaseUpToDate: - return "No updates are necessary to this replicant network/local security database."; - case NERR_SyncRequired: - return "This replicant database is outdated; synchronization is required."; - case NERR_UseNotFound: - return "The network connection could not be found."; - case NERR_BadAsgType: - return "This asg_type is invalid."; - case NERR_DeviceIsShared: - return "This device is currently being shared."; - case NERR_NoComputerName: - return "The computer name could not be added as a message alias. The name may already exist on the network."; - case NERR_MsgAlreadyStarted: - return "The Messenger service is already started."; - case NERR_MsgInitFailed: - return "The Messenger service failed to start."; - case NERR_NameNotFound: - return "The message alias could not be found on the network."; - case NERR_AlreadyForwarded: - return "This message alias has already been forwarded."; - case NERR_AddForwarded: - return "This message alias has been added but is still forwarded."; - case NERR_AlreadyExists: - return "This message alias already exists locally."; - case NERR_TooManyNames: - return "The maximum number of added message aliases has been exceeded."; - case NERR_DelComputerName: - return "The computer name could not be deleted."; - case NERR_LocalForward: - return "Messages cannot be forwarded back to the same workstation."; - case NERR_GrpMsgProcessor: - return "An error occurred in the domain message processor."; - case NERR_PausedRemote: - return "The message was sent, but the recipient has paused the Messenger service."; - case NERR_BadReceive: - return "The message was sent but not received."; - case NERR_NameInUse: - return "The message alias is currently in use. Try again later."; - case NERR_MsgNotStarted: - return "The Messenger service has not been started."; - case NERR_NotLocalName: - return "The name is not on the local computer."; - case NERR_NoForwardName: - return "The forwarded message alias could not be found on the network."; - case NERR_RemoteFull: - return "The message alias table on the remote station is full."; - case NERR_NameNotForwarded: - return "Messages for this alias are not currently being forwarded."; - case NERR_TruncatedBroadcast: - return "The broadcast message was truncated."; - case NERR_InvalidDevice: - return "This is an invalid device name."; - case NERR_WriteFault: - return "A write fault occurred."; - case NERR_DuplicateName: - return "A duplicate message alias exists on the network."; - case NERR_DeleteLater: - return "@W This message alias will be deleted later."; - case NERR_IncompleteDel: - return "The message alias was not successfully deleted from all networks."; - case NERR_MultipleNets: - return "This operation is not supported on computers with multiple networks."; - case NERR_NetNameNotFound: - return "This shared resource does not exist."; - case NERR_DeviceNotShared: - return "This device is not shared."; - case NERR_ClientNameNotFound: - return "A session does not exist with that computer name."; - case NERR_FileIdNotFound: - return "There is not an open file with that identification number."; - case NERR_ExecFailure: - return "A failure occurred when executing a remote administration command."; - case NERR_TmpFile: - return "A failure occurred when opening a remote temporary file."; - case NERR_TooMuchData: - return "The data returned from a remote administration command has been truncated to 64K."; - case NERR_DeviceShareConflict: - return "This device cannot be shared as both a spooled and a non-spooled resource."; - case NERR_BrowserTableIncomplete: - return "The information in the list of servers may be incorrect."; - case NERR_NotLocalDomain: - return "The computer is not active in this domain."; -#ifdef NERR_IsDfsShare - - case NERR_IsDfsShare: - return "The share must be removed from the Distributed File System before it can be deleted."; -#endif - - case NERR_DevInvalidOpCode: - return "The operation is invalid for this device."; - case NERR_DevNotFound: - return "This device cannot be shared."; - case NERR_DevNotOpen: - return "This device was not open."; - case NERR_BadQueueDevString: - return "This device name list is invalid."; - case NERR_BadQueuePriority: - return "The queue priority is invalid."; - case NERR_NoCommDevs: - return "There are no shared communication devices."; - case NERR_QueueNotFound: - return "The queue you specified does not exist."; - case NERR_BadDevString: - return "This list of devices is invalid."; - case NERR_BadDev: - return "The requested device is invalid."; - case NERR_InUseBySpooler: - return "This device is already in use by the spooler."; - case NERR_CommDevInUse: - return "This device is already in use as a communication device."; - case NERR_InvalidComputer: - return "This computer name is invalid."; - case NERR_MaxLenExceeded: - return "The string and prefix specified are too long."; - case NERR_BadComponent: - return "This path component is invalid."; - case NERR_CantType: - return "Could not determine the type of input."; - case NERR_TooManyEntries: - return "The buffer for types is not big enough."; - case NERR_ProfileFileTooBig: - return "Profile files cannot exceed 64K."; - case NERR_ProfileOffset: - return "The start offset is out of range."; - case NERR_ProfileCleanup: - return "The system cannot delete current connections to network resources."; - case NERR_ProfileUnknownCmd: - return "The system was unable to parse the command line in this file."; - case NERR_ProfileLoadErr: - return "An error occurred while loading the profile file."; - case NERR_ProfileSaveErr: - return "@W Errors occurred while saving the profile file. The profile was partially saved."; - case NERR_LogOverflow: - return "Log file %1 is full."; - case NERR_LogFileChanged: - return "This log file has changed between reads."; - case NERR_LogFileCorrupt: - return "Log file %1 is corrupt."; - case NERR_SourceIsDir: - return "The source path cannot be a directory."; - case NERR_BadSource: - return "The source path is illegal."; - case NERR_BadDest: - return "The destination path is illegal."; - case NERR_DifferentServers: - return "The source and destination paths are on different servers."; - case NERR_RunSrvPaused: - return "The Run server you requested is paused."; - case NERR_ErrCommRunSrv: - return "An error occurred when communicating with a Run server."; - case NERR_ErrorExecingGhost: - return "An error occurred when starting a background process."; - case NERR_ShareNotFound: - return "The shared resource you are connected to could not be found."; - case NERR_InvalidLana: - return "The LAN adapter number is invalid."; - case NERR_OpenFiles: - return "There are open files on the connection."; - case NERR_ActiveConns: - return "Active connections still exist."; - case NERR_BadPasswordCore: - return "This share name or password is invalid."; - case NERR_DevInUse: - return "The device is being accessed by an active process."; - case NERR_LocalDrive: - return "The drive letter is in use locally."; - case NERR_AlertExists: - return "The specified client is already registered for the specified event."; - case NERR_TooManyAlerts: - return "The alert table is full."; - case NERR_NoSuchAlert: - return "An invalid or nonexistent alert name was raised."; - case NERR_BadRecipient: - return "The alert recipient is invalid."; - case NERR_AcctLimitExceeded: - return "A user's session with this server has been deleted."; - case NERR_InvalidLogSeek: - return "The log file does not contain the requested record number."; - case NERR_BadUasConfig: - return "The user accounts database is not configured correctly."; - case NERR_InvalidUASOp: - return "This operation is not permitted when the Netlogon service is running."; - case NERR_LastAdmin: - return "This operation is not allowed on the last administrative account."; - case NERR_DCNotFound: - return "Could not find domain controller for this domain."; - case NERR_LogonTrackingError: - return "Could not set logon information for this user."; - case NERR_NetlogonNotStarted: - return "The Netlogon service has not been started."; - case NERR_CanNotGrowUASFile: - return "Unable to add to the user accounts database."; - case NERR_TimeDiffAtDC: - return "This server's clock is not synchronized with the primary domain controller's clock."; - case NERR_PasswordMismatch: - return "A password mismatch has been detected."; - case NERR_NoSuchServer: - return "The server identification does not specify a valid server."; - case NERR_NoSuchSession: - return "The session identification does not specify a valid session."; - case NERR_NoSuchConnection: - return "The connection identification does not specify a valid connection."; - case NERR_TooManyServers: - return "There is no space for another entry in the table of available servers."; - case NERR_TooManySessions: - return "The server has reached the maximum number of sessions it supports."; - case NERR_TooManyConnections: - return "The server has reached the maximum number of connections it supports."; - case NERR_TooManyFiles: - return "The server cannot open more files because it has reached its maximum number."; - case NERR_NoAlternateServers: - return "There are no alternate servers registered on this server."; - case NERR_TryDownLevel: - return "Try down-level (remote admin protocol) version of API instead."; - case NERR_UPSDriverNotStarted: - return "The UPS driver could not be accessed by the UPS service."; - case NERR_UPSInvalidConfig: - return "The UPS service is not configured correctly."; - case NERR_UPSInvalidCommPort: - return "The UPS service could not access the specified Comm Port."; - case NERR_UPSSignalAsserted: - return "The UPS indicated a line fail or low battery situation. Service not started."; - case NERR_UPSShutdownFailed: - return "The UPS service failed to perform a system shut down."; - case NERR_BadDosRetCode: - return "The program below returned an MS-DOS error code:"; - case NERR_ProgNeedsExtraMem: - return "The program below needs more memory:"; - case NERR_BadDosFunction: - return "The program below called an unsupported MS-DOS function:"; - case NERR_RemoteBootFailed: - return "The workstation failed to boot."; - case NERR_BadFileCheckSum: - return "The file below is corrupt."; - case NERR_NoRplBootSystem: - return "No loader is specified in the boot-block definition file."; - case NERR_RplLoadrNetBiosErr: - return "NetBIOS returned an error: The NCB and SMB are dumped above."; - case NERR_RplLoadrDiskErr: - return "A disk I/O error occurred."; - case NERR_ImageParamErr: - return "Image parameter substitution failed."; - case NERR_TooManyImageParams: - return "Too many image parameters cross disk sector boundaries."; - case NERR_NonDosFloppyUsed: - return "The image was not generated from an MS-DOS diskette formatted with /S."; - case NERR_RplBootRestart: - return "Remote boot will be restarted later."; - case NERR_RplSrvrCallFailed: - return "The call to the Remoteboot server failed."; - case NERR_CantConnectRplSrvr: - return "Cannot connect to the Remoteboot server."; - case NERR_CantOpenImageFile: - return "Cannot open image file on the Remoteboot server."; - case NERR_CallingRplSrvr: - return "Connecting to the Remoteboot server..."; - case NERR_StartingRplBoot: - return "Connecting to the Remoteboot server..."; - case NERR_RplBootServiceTerm: - return "Remote boot service was stopped; check the error log for the cause of the problem."; - case NERR_RplBootStartFailed: - return "Remote boot startup failed; check the error log for the cause of the problem."; - case NERR_RPL_CONNECTED: - return "A second connection to a Remoteboot resource is not allowed."; - case NERR_BrowserConfiguredToNotRun: - return "The browser service was configured with MaintainServerList=No."; - case NERR_RplNoAdaptersStarted: - return "Service failed to start since none of the network adapters started with this service."; - case NERR_RplBadRegistry: - return "Service failed to start due to bad startup information in the registry."; - case NERR_RplBadDatabase: - return "Service failed to start because its database is absent or corrupt."; - case NERR_RplRplfilesShare: - return "Service failed to start because RPLFILES share is absent."; - case NERR_RplNotRplServer: - return "Service failed to start because RPLUSER group is absent."; - case NERR_RplCannotEnum: - return "Cannot enumerate service records."; - case NERR_RplWkstaInfoCorrupted: - return "Workstation record information has been corrupted."; - case NERR_RplWkstaNotFound: - return "Workstation record was not found."; - case NERR_RplWkstaNameUnavailable: - return "Workstation name is in use by some other workstation."; - case NERR_RplProfileInfoCorrupted: - return "Profile record information has been corrupted."; - case NERR_RplProfileNotFound: - return "Profile record was not found."; - case NERR_RplProfileNameUnavailable: - return "Profile name is in use by some other profile."; - case NERR_RplProfileNotEmpty: - return "There are workstations using this profile."; - case NERR_RplConfigInfoCorrupted: - return "Configuration record information has been corrupted."; - case NERR_RplConfigNotFound: - return "Configuration record was not found."; - case NERR_RplAdapterInfoCorrupted: - return "Adapter ID record information has been corrupted."; - case NERR_RplInternal: - return "An internal service error has occurred."; - case NERR_RplVendorInfoCorrupted: - return "Vendor ID record information has been corrupted."; - case NERR_RplBootInfoCorrupted: - return "Boot block record information has been corrupted."; - case NERR_RplWkstaNeedsUserAcct: - return "The user account for this workstation record is missing."; - case NERR_RplNeedsRPLUSERAcct: - return "The RPLUSER local group could not be found."; - case NERR_RplBootNotFound: - return "Boot block record was not found."; - case NERR_RplIncompatibleProfile: - return "Chosen profile is incompatible with this workstation."; - case NERR_RplAdapterNameUnavailable: - return "Chosen network adapter ID is in use by some other workstation."; - case NERR_RplConfigNotEmpty: - return "There are profiles using this configuration."; - case NERR_RplBootInUse: - return "There are workstations, profiles, or configurations using this boot block."; - case NERR_RplBackupDatabase: - return "Service failed to backup Remoteboot database."; - case NERR_RplAdapterNotFound: - return "Adapter record was not found."; - case NERR_RplVendorNotFound: - return "Vendor record was not found."; - case NERR_RplVendorNameUnavailable: - return "Vendor name is in use by some other vendor record."; - case NERR_RplBootNameUnavailable: - return "(boot name, vendor ID) is in use by some other boot block record."; - case NERR_RplConfigNameUnavailable: - return "Configuration name is in use by some other configuration."; - case NERR_DfsInternalCorruption: - return "The internal database maintained by the Dfs service is corrupt."; - case NERR_DfsVolumeDataCorrupt: - return "One of the records in the internal Dfs database is corrupt."; - case NERR_DfsNoSuchVolume: - return "There is no DFS name whose entry path matches the input Entry Path."; - case NERR_DfsVolumeAlreadyExists: - return "A root or link with the given name already exists."; - case NERR_DfsAlreadyShared: - return "The server share specified is already shared in the Dfs."; - case NERR_DfsNoSuchShare: - return "The indicated server share does not support the indicated DFS namespace."; - case NERR_DfsNotALeafVolume: - return "The operation is not valid on this portion of the namespace."; - case NERR_DfsLeafVolume: - return "The operation is not valid on this portion of the namespace."; - case NERR_DfsVolumeHasMultipleServers: - return "The operation is ambiguous because the link has multiple servers."; - case NERR_DfsCantCreateJunctionPoint: - return "Unable to create a link."; - case NERR_DfsServerNotDfsAware: - return "The server is not Dfs Aware."; - case NERR_DfsBadRenamePath: - return "The specified rename target path is invalid."; - case NERR_DfsVolumeIsOffline: - return "The specified DFS link is offline."; - case NERR_DfsNoSuchServer: - return "The specified server is not a server for this link."; - case NERR_DfsCyclicalName: - return "A cycle in the Dfs name was detected."; - case NERR_DfsNotSupportedInServerDfs: - return "The operation is not supported on a server-based Dfs."; - case NERR_DfsDuplicateService: - return "This link is already supported by the specified server-share."; - case NERR_DfsCantRemoveLastServerShare: - return "Can't remove the last server-share supporting this root or link."; - case NERR_DfsVolumeIsInterDfs: - return "The operation is not supported for an Inter-DFS link."; - case NERR_DfsInconsistent: - return "The internal state of the Dfs Service has become inconsistent."; - case NERR_DfsServerUpgraded: - return "The Dfs Service has been installed on the specified server."; - case NERR_DfsDataIsIdentical: - return "The Dfs data being reconciled is identical."; - case NERR_DfsCantRemoveDfsRoot: - return "The DFS root cannot be deleted. Uninstall DFS if required."; - case NERR_DfsChildOrParentInDfs: - return "A child or parent directory of the share is already in a Dfs."; - case NERR_DfsInternalError: - return "Dfs internal error."; - /* the following are not defined in mingw */ -#if 0 - - case NERR_SetupAlreadyJoined: - return "This machine is already joined to a domain."; - case NERR_SetupNotJoined: - return "This machine is not currently joined to a domain."; - case NERR_SetupDomainController: - return "This machine is a domain controller and cannot be unjoined from a domain."; - case NERR_DefaultJoinRequired: - return "The destination domain controller does not support creating machine accounts in OUs."; - case NERR_InvalidWorkgroupName: - return "The specified workgroup name is invalid."; - case NERR_NameUsesIncompatibleCodePage: - return "The specified computer name is incompatible with the default language used on the domain controller."; - case NERR_ComputerAccountNotFound: - return "The specified computer account could not be found."; - case NERR_PersonalSku: - return "This version of Windows cannot be joined to a domain."; - case NERR_PasswordMustChange: - return "The password must change at the next logon."; - case NERR_AccountLockedOut: - return "The account is locked out."; - case NERR_PasswordTooLong: - return "The password is too long."; - case NERR_PasswordNotComplexEnough: - return "The password does not meet the complexity policy."; - case NERR_PasswordFilterError: - return "The password does not meet the requirements of the password filter DLLs."; -#endif - - } - msg = strerror (error_number); - if (msg == NULL) - msg = "unknown"; - - return msg; -#endif //DBUS_WINCE -} diff --git a/dbus/dbus-sysdeps-win.c b/dbus/dbus-sysdeps-win.c index a67e502..391d90a 100644 --- a/dbus/dbus-sysdeps-win.c +++ b/dbus/dbus-sysdeps-win.c @@ -1,15 +1,15 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* dbus-sysdeps.c Wrappers around system/libc features (internal to D-BUS implementation) - * +/* dbus-sysdeps-win.c Wrappers around system/libc features (internal to D-BUS implementation) + * * Copyright (C) 2002, 2003 Red Hat, Inc. * Copyright (C) 2003 CodeFactory AB - * Copyright (C) 2005 Novell, Inc. + * Copyright (C) 2005, 2008 Novell, Inc. * Copyright (C) 2006 Ralf Habacker * Copyright (C) 2006 Peter Kümmel * Copyright (C) 2006 Christian Ehrlicher * * Licensed under the Academic Free License version 2.1 - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -19,21 +19,53 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#undef open +/* The order of functions in this file should be identical to that in + * dbus-sysdeps-unix.c. For each function that also exists in + * dbus-sysdeps-unix.c, the prototype should be identical. As all + * functions in this file are private to the dbus implementation, + * there is absolutely no need to implement Windows versions of + * functions not used by the rest of the dbus code on Windows. + * + * doc comments should not be duplicated here. + */ #define STRSAFE_NO_DEPRECATE #ifndef DBUS_WINCE -#define _WIN32_WINNT 0x0500 +#define _WIN32_WINNT 0x0501 +#endif + +#include +#include +#include +#include + +#ifndef AI_ADDRCONFIG +#define AI_ADDRCONFIG 0x00000400 #endif +extern BOOL WINAPI ConvertStringSidToSidA (LPCSTR StringSid, PSID *Sid); +extern BOOL WINAPI ConvertSidToStringSidA (PSID Sid, LPSTR *StringSid); + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + #include "dbus-internals.h" #include "dbus-sysdeps.h" #include "dbus-threads.h" @@ -42,241 +74,131 @@ #include "dbus-sysdeps-win.h" #include "dbus-protocol.h" #include "dbus-hash.h" -#include "dbus-sockets-win.h" #include "dbus-list.h" #include "dbus-credentials.h" -#include -#include - -#include -#include -#include +typedef int socklen_t; -#ifndef O_BINARY -#define O_BINARY 0 -#endif +static dbus_bool_t _dbus_getsid (char **sid); -#ifndef HAVE_SOCKLEN_T -#define socklen_t int -#endif - -/** - * File interface - * - */ -dbus_bool_t -_dbus_file_open (DBusFile *file, - const char *filename, - int oflag, - int pmode) +static char* +_dbus_win_error_string (int error_number) { - if (pmode!=-1) - file->FDATA = _open (filename, oflag, pmode); - else - file->FDATA = _open (filename, oflag); - if (file->FDATA >= 0) - return TRUE; - else - { - file->FDATA = -1; - return FALSE; - } -} + char *msg; -dbus_bool_t -_dbus_file_close (DBusFile *file, - DBusError *error) -{ - const int fd = file->FDATA; - - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - - _dbus_assert (fd >= 0); - - if (_close (fd) == -1) - { - dbus_set_error (error, _dbus_error_from_errno (errno), - "Could not close fd %d: %s", fd, - _dbus_strerror (errno)); - return FALSE; - } + FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, error_number, 0, + (LPSTR) &msg, 0, NULL); - file->FDATA = -1; - _dbus_verbose ("closed C file descriptor %d:\n",fd); + if (msg[strlen (msg) - 1] == '\n') + msg[strlen (msg) - 1] = '\0'; + if (msg[strlen (msg) - 1] == '\r') + msg[strlen (msg) - 1] = '\0'; - return TRUE; + return msg; } -int -_dbus_file_read(DBusFile *file, - DBusString *buffer, - int count) +static void +_dbus_win_free_error_string (char *string) { - const int fd = file->FDATA; - int bytes_read; - int start; - char *data; - _dbus_assert (count >= 0); - - start = _dbus_string_get_length (buffer); + LocalFree (string); +} - if (!_dbus_string_lengthen (buffer, count)) - { - errno = ENOMEM; - return -1; - } +static void +_dbus_win_startup_winsock (void) +{ + /* Straight from MSDN, deuglified */ - data = _dbus_string_get_data_len (buffer, start, count); + static dbus_bool_t beenhere = FALSE; - _dbus_assert (fd >= 0); + WORD wVersionRequested; + WSADATA wsaData; + int err; - _dbus_verbose ("read: count=%d fd=%d\n", count, fd); - bytes_read = read (fd, data, count); + if (beenhere) + return; - if (bytes_read == -1) - _dbus_verbose ("read: failed: %s\n", _dbus_strerror (errno)); - else - _dbus_verbose ("read: = %d\n", bytes_read); + wVersionRequested = MAKEWORD (2, 0); - if (bytes_read < 0) + err = WSAStartup (wVersionRequested, &wsaData); + if (err != 0) { - /* put length back (note that this doesn't actually realloc anything) */ - _dbus_string_set_length (buffer, start); - return -1; + _dbus_assert_not_reached ("Could not initialize WinSock"); + _dbus_abort (); } - else - { - /* put length back (doesn't actually realloc) */ - _dbus_string_set_length (buffer, start + bytes_read); - -#if 0 - - if (bytes_read > 0) - _dbus_verbose_bytes_of_string (buffer, start, bytes_read); -#endif - return bytes_read; + /* Confirm that the WinSock DLL supports 2.0. Note that if the DLL + * supports versions greater than 2.0 in addition to 2.0, it will + * still return 2.0 in wVersion since that is the version we + * requested. + */ + if (LOBYTE (wsaData.wVersion) != 2 || + HIBYTE (wsaData.wVersion) != 0) + { + _dbus_assert_not_reached ("No usable WinSock found"); + _dbus_abort (); } + + beenhere = TRUE; } -int -_dbus_file_write (DBusFile *file, - const DBusString *buffer, - int start, - int len) +static dbus_bool_t +_dbus_open_socket (int *fd_p, + int domain, + int type, + int protocol, + DBusError *error) { - const int fd = file->FDATA; - const char *data; - int bytes_written; - - data = _dbus_string_get_const_data_len (buffer, start, len); - - _dbus_assert (fd >= 0); - - _dbus_verbose ("write: len=%d fd=%d\n", len, fd); - bytes_written = write (fd, data, len); - - if (bytes_written == -1) - _dbus_verbose ("write: failed: %s\n", _dbus_strerror (errno)); + *fd_p = socket (domain, type, protocol); + if (*fd_p >= 0) + { + _dbus_verbose ("socket %d opened\n", *fd_p); + return TRUE; + } else - _dbus_verbose ("write: = %d\n", bytes_written); - -#if 0 + { + int wsaerrno = WSAGetLastError (); + char *emsg = _dbus_win_error_string (wsaerrno); - if (bytes_written > 0) - _dbus_verbose_bytes_of_string (buffer, start, bytes_written); -#endif + dbus_set_error (error, + _dbus_error_from_wsaerror (wsaerrno), + "Failed to open socket: %s", + emsg); + _dbus_win_free_error_string (emsg); - return bytes_written; + return FALSE; + } } dbus_bool_t -_dbus_is_valid_file (DBusFile* file) +_dbus_open_tcp_socket (int *fd, + DBusError *error) { - return file->FDATA >= 0; + return _dbus_open_socket (fd, AF_INET, SOCK_STREAM, 0, error); } -dbus_bool_t _dbus_fstat (DBusFile *file, - struct stat *sb) +dbus_bool_t +_dbus_close_socket (int fd, + DBusError *error) { - return fstat(file->FDATA, sb) >= 0; -} + _dbus_verbose ("_dbus_close_socket: socket=%d\n", fd); -/** - * write data to a pipe. - * - * @param pipe the pipe instance - * @param buffer the buffer to write data from - * @param start the first byte in the buffer to write - * @param len the number of bytes to try to write - * @param error error return - * @returns the number of bytes written or -1 on error - */ -int -_dbus_pipe_write (DBusPipe *pipe, - const DBusString *buffer, - int start, - int len, - DBusError *error) -{ - int written; - DBusFile file; - file.FDATA = pipe->fd_or_handle; - written = _dbus_file_write (&file, buffer, start, len); - if (written < 0) + if (closesocket (fd) == SOCKET_ERROR) { - dbus_set_error (error, DBUS_ERROR_FAILED, - "Writing to pipe: %s\n", - _dbus_strerror (errno)); - } - return written; -} + int wsaerrno = WSAGetLastError (); + char *emsg = _dbus_win_error_string (wsaerrno); -/** - * close a pipe. - * - * @param pipe the pipe instance - * @param error return location for an error - * @returns #FALSE if error is set - */ -int -_dbus_pipe_close (DBusPipe *pipe, - DBusError *error) -{ - DBusFile file; - file.FDATA = pipe->fd_or_handle; - if (_dbus_file_close (&file, error) < 0) - { - return -1; - } - else - { - _dbus_pipe_invalidate (pipe); - return 0; + dbus_set_error (error, _dbus_error_from_wsaerror (wsaerrno), + "Could not close socket: socket=%d: %s", + fd, emsg); + _dbus_win_free_error_string (emsg); + return FALSE; } + return TRUE; } -#undef FDATA - -/** - * Socket interface - * - */ - -/** - * Thin wrapper around the read() system call that appends - * the data it reads to the DBusString buffer. It appends - * up to the given count, and returns the same value - * and same errno as read(). The only exception is that - * _dbus_read() handles EINTR for you. _dbus_read() can - * return ENOMEM, even though regular UNIX read doesn't. - * - * @param fd the file descriptor to read from - * @param buffer the buffer to append data to - * @param count the amount of data to read - * @returns the number of bytes read or -1 - */ int _dbus_read_socket (int fd, DBusString *buffer, @@ -298,55 +220,36 @@ _dbus_read_socket (int fd, data = _dbus_string_get_data_len (buffer, start, count); - again: - _dbus_verbose ("recv: count=%d fd=%d\n", count, fd); bytes_read = recv (fd, data, count, 0); - - if (bytes_read == SOCKET_ERROR) - { - DBUS_SOCKET_SET_ERRNO(); - _dbus_verbose ("recv: failed: %s\n", _dbus_strerror (errno)); - bytes_read = -1; - } - else - _dbus_verbose ("recv: = %d\n", bytes_read); - if (bytes_read < 0) + if (bytes_read == SOCKET_ERROR) { - if (errno == EINTR) - goto again; - else - { - /* put length back (note that this doesn't actually realloc anything) */ - _dbus_string_set_length (buffer, start); - return -1; - } + int wsaerrno = WSAGetLastError (); + char *emsg = _dbus_win_error_string (wsaerrno); + + errno = wsaerrno; + _dbus_verbose ("recv: failed: %s\n", emsg); + _dbus_win_free_error_string (emsg); + _dbus_string_set_length (buffer, start); + + return -1; } - else - { - /* put length back (doesn't actually realloc) */ - _dbus_string_set_length (buffer, start + bytes_read); + + _dbus_assert (bytes_read >= 0); + _dbus_verbose ("recv: = %d\n", bytes_read); + + /* put length back (doesn't actually realloc) */ + _dbus_string_set_length (buffer, start + bytes_read); #if 0 - if (bytes_read > 0) - _dbus_verbose_bytes_of_string (buffer, start, bytes_read); + if (bytes_read > 0) + _dbus_verbose_bytes_of_string (buffer, start, bytes_read); #endif - return bytes_read; - } + return bytes_read; } -/** - * Thin wrapper around the write() system call that writes a part of a - * DBusString and handles EINTR for you. - * - * @param fd the file descriptor to write - * @param buffer the buffer to write data from - * @param start the first byte in the buffer to write - * @param len the number of bytes to try to write - * @returns the number of bytes written or -1 on error - */ int _dbus_write_socket (int fd, const DBusString *buffer, @@ -358,23 +261,19 @@ _dbus_write_socket (int fd, data = _dbus_string_get_const_data_len (buffer, start, len); - again: - _dbus_verbose ("send: len=%d fd=%d\n", len, fd); bytes_written = send (fd, data, len, 0); if (bytes_written == SOCKET_ERROR) { - DBUS_SOCKET_SET_ERRNO(); - _dbus_verbose ("send: failed: %s\n", _dbus_strerror (errno)); - bytes_written = -1; + errno = WSAGetLastError (); + _dbus_verbose ("send: failed: %d\n", errno); + return -1; } - else - _dbus_verbose ("send: = %d\n", bytes_written); - if (bytes_written < 0 && errno == EINTR) - goto again; - + _dbus_assert (bytes_written >= 0); + _dbus_verbose ("send: = %d\n", bytes_written); + #if 0 if (bytes_written > 0) _dbus_verbose_bytes_of_string (buffer, start, bytes_written); @@ -383,122 +282,45 @@ _dbus_write_socket (int fd, return bytes_written; } - -/** - * Closes a file descriptor. - * - * @param fd the file descriptor - * @param error error object - * @returns #FALSE if error set - */ -dbus_bool_t -_dbus_close_socket (int fd, - DBusError *error) +int +_dbus_pipe_write (DBusPipe *pipe, + const DBusString *buffer, + int start, + int len, + DBusError *error) { - _DBUS_ASSERT_ERROR_IS_CLEAR (error); + int written; + const char *buffer_c = _dbus_string_get_const_data (buffer); - again: - if (closesocket (fd) == SOCKET_ERROR) + written = _write (pipe->fd_or_handle, buffer_c + start, len); + if (written < 0) { - DBUS_SOCKET_SET_ERRNO (); - - if (errno == EINTR) - goto again; - - dbus_set_error (error, _dbus_error_from_errno (errno), - "Could not close socket: socket=%d, , %s", - fd, _dbus_strerror (errno)); - return FALSE; + dbus_set_error (error, DBUS_ERROR_FAILED, + "Writing to pipe: %s\n", + strerror (errno)); } - _dbus_verbose ("_dbus_close_socket: socket=%d, \n", fd); - - return TRUE; -} - -/** - * Sets the file descriptor to be close - * on exec. Should be called for all file - * descriptors in D-Bus code. - * - * @param fd the file descriptor - */ -void -_dbus_fd_set_close_on_exec (int handle) -{ -#ifdef ENABLE_DBUSSOCKET - DBusSocket *s; - if (handle < 0) - return; - - _dbus_lock_sockets(); - - _dbus_handle_to_socket_unlocked (handle, &s); - s->close_on_exec = TRUE; - - _dbus_unlock_sockets(); -#else - /* TODO unic code. - int val; - - val = fcntl (fd, F_GETFD, 0); - - if (val < 0) - return; - - val |= FD_CLOEXEC; - - fcntl (fd, F_SETFD, val); - */ -#endif + return written; } -/** - * Sets a file descriptor to be nonblocking. - * - * @param fd the file descriptor. - * @param error address of error location. - * @returns #TRUE on success. - */ -dbus_bool_t -_dbus_set_fd_nonblocking (int handle, - DBusError *error) +int +_dbus_pipe_close (DBusPipe *pipe, + DBusError *error) { - u_long one = 1; - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - if (ioctlsocket (handle, FIONBIO, &one) == SOCKET_ERROR) + if (_close (pipe->fd_or_handle) < 0) { - dbus_set_error (error, _dbus_error_from_errno (WSAGetLastError ()), - "Failed to set socket %d:%d to nonblocking: %s", handle, - _dbus_strerror (WSAGetLastError ())); - return FALSE; + dbus_set_error (error, _dbus_error_from_errno (errno), + "Could not close pipe %d: %s", pipe->fd_or_handle, strerror (errno)); + return -1; + } + else + { + _dbus_pipe_invalidate (pipe); + return 0; } - - return TRUE; } - -/** - * Like _dbus_write() but will use writev() if possible - * to write both buffers in sequence. The return value - * is the number of bytes written in the first buffer, - * plus the number written in the second. If the first - * buffer is written successfully and an error occurs - * writing the second, the number of bytes in the first - * is returned (i.e. the error is ignored), on systems that - * don't have writev. Handles EINTR for you. - * The second buffer may be #NULL. - * - * @param fd the file descriptor - * @param buffer1 first buffer - * @param start1 first byte to write in first buffer - * @param len1 number of bytes to write from first buffer - * @param buffer2 second buffer, or #NULL - * @param start2 first byte to write in second buffer - * @param len2 number of bytes to write in second buffer - * @returns total bytes written from both buffers, or -1 on error - */ int _dbus_write_socket_two (int fd, const DBusString *buffer1, @@ -513,7 +335,6 @@ _dbus_write_socket_two (int fd, const char *data2; int rc; DWORD bytes_written; - int ret1; _dbus_assert (buffer1 != NULL); _dbus_assert (start1 >= 0); @@ -521,7 +342,6 @@ _dbus_write_socket_two (int fd, _dbus_assert (len1 >= 0); _dbus_assert (len2 >= 0); - data1 = _dbus_string_get_const_data_len (buffer1, start1, len1); if (buffer2 != NULL) @@ -538,596 +358,590 @@ _dbus_write_socket_two (int fd, vectors[1].buf = (char*) data2; vectors[1].len = len2; - again: - _dbus_verbose ("WSASend: len1+2=%d+%d fd=%d\n", len1, len2, fd); - rc = WSASend (fd, - vectors, - data2 ? 2 : 1, - &bytes_written, - 0, - NULL, - NULL); - + + rc = WSASend (fd, vectors, data2 ? 2 : 1, &bytes_written, 0, NULL, NULL); + if (rc < 0) { - DBUS_SOCKET_SET_ERRNO (); - _dbus_verbose ("WSASend: failed: %s\n", _dbus_strerror (errno)); + int wsaerrno = WSAGetLastError (); + char *emsg = _dbus_win_error_string (wsaerrno); + + errno = wsaerrno; + _dbus_verbose ("WSASend: failed: %s\n", emsg); + _dbus_win_free_error_string (emsg); bytes_written = -1; } else - _dbus_verbose ("WSASend: = %ld\n", bytes_written); - - if (bytes_written < 0 && errno == EINTR) - goto again; - + { + _dbus_assert (bytes_written >= 0); + _dbus_verbose ("WSASend: = %ld\n", bytes_written); + } + return bytes_written; } -#if 0 - -/** - * Opens the client side of a Windows named pipe. The connection D-BUS - * file descriptor index is returned. It is set up as nonblocking. - * - * @param path the path to named pipe socket - * @param error return location for error code - * @returns connection D-BUS file descriptor or -1 on error +/* _dbus_read() is static on Windows, only used below in this file. */ -int -_dbus_connect_named_pipe (const char *path, - DBusError *error) +static int +_dbus_read (int fd, + DBusString *buffer, + int count) { - _dbus_assert_not_reached ("not implemented"); -} - -#endif - + int bytes_read; + int start; + char *data; + _dbus_assert (count >= 0); -void -_dbus_win_startup_winsock (void) -{ - /* Straight from MSDN, deuglified */ + start = _dbus_string_get_length (buffer); - static dbus_bool_t beenhere = FALSE; + if (!_dbus_string_lengthen (buffer, count)) + { + errno = ENOMEM; + return -1; + } - WORD wVersionRequested; - WSADATA wsaData; - int err; + data = _dbus_string_get_data_len (buffer, start, count); - if (beenhere) - return; + again: - wVersionRequested = MAKEWORD (2, 0); + bytes_read = _read (fd, data, count); - err = WSAStartup (wVersionRequested, &wsaData); - if (err != 0) + if (bytes_read < 0) { - _dbus_assert_not_reached ("Could not initialize WinSock"); - _dbus_abort (); + if (errno == EINTR) + goto again; + else + { + /* put length back (note that this doesn't actually realloc anything) */ + _dbus_string_set_length (buffer, start); + return -1; + } } - - /* Confirm that the WinSock DLL supports 2.0. Note that if the DLL - * supports versions greater than 2.0 in addition to 2.0, it will - * still return 2.0 in wVersion since that is the version we - * requested. - */ - if (LOBYTE (wsaData.wVersion) != 2 || - HIBYTE (wsaData.wVersion) != 0) + else { - _dbus_assert_not_reached ("No usable WinSock found"); - _dbus_abort (); - } - - beenhere = TRUE; -} - - - - - - - - + /* put length back (doesn't actually realloc) */ + _dbus_string_set_length (buffer, start + bytes_read); -/************************************************************************ - - UTF / string code - - ************************************************************************/ +#if 0 + if (bytes_read > 0) + _dbus_verbose_bytes_of_string (buffer, start, bytes_read); +#endif -/** - * Measure the message length without terminating nul - */ -int _dbus_printf_string_upper_bound (const char *format, - va_list args) -{ - /* MSVCRT's vsnprintf semantics are a bit different */ - /* The C library source in the Platform SDK indicates that this - * would work, but alas, it doesn't. At least not on Windows - * 2000. Presumably those sources correspond to the C library on - * some newer or even future Windows version. - * - len = _vsnprintf (NULL, _DBUS_INT_MAX, format, args); - */ - char p[1024]; - int len; - len = _vsnprintf (p, sizeof(p)-1, format, args); - if (len == -1) // try again - { - char *p; - p = malloc (strlen(format)*3); - len = _vsnprintf (p, sizeof(p)-1, format, args); - free(p); + return bytes_read; } - return len; } - -/** - * Returns the UTF-16 form of a UTF-8 string. The result should be - * freed with dbus_free() when no longer needed. - * - * @param str the UTF-8 string - * @param error return location for error code - */ -wchar_t * -_dbus_win_utf8_to_utf16 (const char *str, - DBusError *error) +int +_dbus_connect_tcp_socket (const char *host, + const char *port, + const char *family, + DBusError *error) { - DBusString s; - int n; - wchar_t *retval; - - _dbus_string_init_const (&s, str); + int saved_wsaerrno; + int fd = -1, res; + struct addrinfo hints; + struct addrinfo *ai, *tmp; - if (!_dbus_string_validate_utf8 (&s, 0, _dbus_string_get_length (&s))) - { - dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid UTF-8"); - return NULL; - } + _DBUS_ASSERT_ERROR_IS_CLEAR (error); - n = MultiByteToWideChar (CP_UTF8, 0, str, -1, NULL, 0); + _dbus_win_startup_winsock (); - if (n == 0) + if (!_dbus_open_tcp_socket (&fd, error)) { - _dbus_win_set_error_from_win_error (error, GetLastError ()); - return NULL; + _DBUS_ASSERT_ERROR_IS_SET (error); + return -1; } - retval = dbus_new (wchar_t, n); + _DBUS_ASSERT_ERROR_IS_CLEAR (error); - if (!retval) + _DBUS_ZERO (hints); + + if (!family) + hints.ai_family = AF_UNSPEC; + else if (!strcmp (family, "ipv4")) + hints.ai_family = AF_INET; + else if (!strcmp (family, "ipv6")) + hints.ai_family = AF_INET6; + else { - _DBUS_SET_OOM (error); - return NULL; + WSASetLastError (WSAEAFNOSUPPORT); + dbus_set_error (error, + _dbus_error_from_wsaerror (WSAGetLastError ()); + "Unknown address family %s", family); + return -1; } + fprintf (stderr, "Family %s\n", family ? family : "none"); + hints.ai_protocol = IPPROTO_TCP; + hints.ai_socktype = SOCK_STREAM; + /* Quote from Windows SDK WS2tcpip.h: + * - AI_ADDRCONFIG is supported starting with Vista + * - default is AI_ADDRCONFIG ON whether the flag is set or not + * because the performance penalty in not having ADDRCONFIG in + * the multi-protocol stack environment is severe; + * this defaulting may be disabled by specifying the AI_ALL flag, + * in that case AI_ADDRCONFIG must be EXPLICITLY specified to + * enable ADDRCONFIG behavior + * + * So, we can use zero for ai_flags. + */ + hints.ai_flags = 0; - if (MultiByteToWideChar (CP_UTF8, 0, str, -1, retval, n) != n) + if ((res = getaddrinfo (host, port, &hints, &ai)) != 0) { - dbus_free (retval); - dbus_set_error_const (error, DBUS_ERROR_FAILED, "MultiByteToWideChar inconsistency"); - return NULL; + char *emsg = _dbus_win_error_string (res); + dbus_set_error (error, + _dbus_error_from_wsaerror (res), + "Failed to lookup host/port: \"%s:%s\": %s", + host, port, emsg); + _dbus_win_free_error_string (emsg); + closesocket (fd); + return -1; } - return retval; -} + tmp = ai; + while (tmp) + { + if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error)) + { + freeaddrinfo (ai); + _DBUS_ASSERT_ERROR_IS_SET (error); + return -1; + } + _DBUS_ASSERT_ERROR_IS_CLEAR (error); -/** - * Returns the UTF-8 form of a UTF-16 string. The result should be - * freed with dbus_free() when no longer needed. - * - * @param str the UTF-16 string - * @param error return location for error code - */ -char * -_dbus_win_utf16_to_utf8 (const wchar_t *str, - DBusError *error) -{ - int n; - char *retval; + if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0) + { + closesocket (fd); + fd = -1; + tmp = tmp->ai_next; + saved_wsaerrno = WSAGetLastError (); + continue; + } - n = WideCharToMultiByte (CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL); + break; + } + freeaddrinfo (ai); - if (n == 0) + if (fd == -1) { - _dbus_win_set_error_from_win_error (error, GetLastError ()); - return NULL; + char *emsg = _dbus_win_error_string (saved_wsaerrno); + dbus_set_error (error, + _dbus_error_from_wsaerror (saved_wsaerrno), + "Failed to connect to socket \"%s:%s\" %s", + host, port, emsg); + _dbus_win_free_error_string (emsg); + return -1; } - retval = dbus_malloc (n); - if (!retval) + if (!_dbus_set_fd_nonblocking (fd, error)) { - _DBUS_SET_OOM (error); - return NULL; - } + closesocket (fd); + fd = -1; - if (WideCharToMultiByte (CP_UTF8, 0, str, -1, retval, n, NULL, NULL) != n) - { - dbus_free (retval); - dbus_set_error_const (error, DBUS_ERROR_FAILED, "WideCharToMultiByte inconsistency"); - return NULL; + return -1; } - return retval; + return fd; } - - - - - -/************************************************************************ - - - ************************************************************************/ - -dbus_bool_t -_dbus_win_account_to_sid (const wchar_t *waccount, - void **ppsid, - DBusError *error) +int +_dbus_listen_tcp_socket (const char *host, + const char *port, + const char *family, + DBusString *retport, + int **fds_p, + DBusError *error) { - dbus_bool_t retval = FALSE; - DWORD sid_length, wdomain_length; - SID_NAME_USE use; - wchar_t *wdomain; + int nlisten_fd = 0, *listen_fd = NULL, res, i; + struct addrinfo hints; + struct addrinfo *ai, *tmp; - *ppsid = NULL; + _dbus_win_startup_winsock (); - sid_length = 0; - wdomain_length = 0; - if (!LookupAccountNameW (NULL, waccount, NULL, &sid_length, - NULL, &wdomain_length, &use) && - GetLastError () != ERROR_INSUFFICIENT_BUFFER) - { - _dbus_win_set_error_from_win_error (error, GetLastError ()); - return FALSE; - } + *fds_p = NULL; + _DBUS_ASSERT_ERROR_IS_CLEAR (error); - *ppsid = dbus_malloc (sid_length); - if (!*ppsid) - { - _DBUS_SET_OOM (error); - return FALSE; - } + _DBUS_ZERO (hints); - wdomain = dbus_new (wchar_t, wdomain_length); - if (!wdomain) + if (!family) + hints.ai_family = AF_UNSPEC; + else if (!strcmp (family, "ipv4")) + hints.ai_family = AF_INET; + else if (!strcmp (family, "ipv6")) + hints.ai_family = AF_INET6; + else { - _DBUS_SET_OOM (error); - goto out1; + WSASetLastError (WSAEAFNOSUPPORT); + dbus_set_error (error, + _dbus_error_from_wsaerror (WSAGetLastError ()); + "Unknown address family %s", family); + return -1; } - if (!LookupAccountNameW (NULL, waccount, (PSID) *ppsid, &sid_length, - wdomain, &wdomain_length, &use)) - { - _dbus_win_set_error_from_win_error (error, GetLastError ()); - goto out2; - } + hints.ai_protocol = IPPROTO_TCP; + hints.ai_socktype = SOCK_STREAM; + /* See comment in _dbus_connect_tcp_socket() about AI_ADDRCONFIG */ + hints.ai_flags = AI_PASSIVE; - if (!IsValidSid ((PSID) *ppsid)) + redo_lookup_with_port: + if ((res = getaddrinfo (host, port, &hints, &ai)) != 0 || !ai) { - dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid SID"); - goto out2; + char *emsg = _dbus_win_error_string (res); + dbus_set_error (error, + _dbus_error_from_wsaerror (res), + "Failed to lookup host/port: \"%s:%s\": %s", + host ? host : "*", port, + emsg); + _dbus_win_free_error_string (emsg); + return -1; } - retval = TRUE; - -out2: - dbus_free (wdomain); -out1: - if (!retval) + tmp = ai; + while (tmp) { - dbus_free (*ppsid); - *ppsid = NULL; - } + int fd = -1, *newlisten_fd; + if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error)) + { + _DBUS_ASSERT_ERROR_IS_SET (error); + goto failed; + } + _DBUS_ASSERT_ERROR_IS_CLEAR (error); - return retval; -} + if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0) + { + int wsaerrno = WSAGetLastError (); + char *emsg; -/** @} end of sysdeps-win */ + closesocket (fd); + if (wsaerrno == WSAEADDRINUSE) + { + /* Comment from UNIX version: Depending on kernel + policy, it may or may not be neccessary to bind to + both IPv4 & 6 addresses so ignore EADDRINUSE here + No idea what the case on Windows is. */ + tmp = tmp->ai_next; + continue; + } + emsg = _dbus_win_error_string (wsaerrno); + dbus_set_error (error, _dbus_error_from_wsaerror (wsaerrno), + "Failed to bind socket \"%s:%s\": %s", + host ? host : "*", port, emsg); + _dbus_win_free_error_string (emsg); + goto failed; + } -/** Gets our UID - * @returns process UID - */ -dbus_uid_t -_dbus_getuid (void) -{ - return DBUS_UID_UNSET; -} + if (listen (fd, 30 /* backlog */) < 0) + { + int wsaerrno = WSAGetLastError (); + char *emsg = _dbus_win_error_string (wsaerrno); + + closesocket (fd); + dbus_set_error (error, _dbus_error_from_wsaerror (wsaerrno), + "Failed to listen on socket \"%s:%s\": %s", + host ? host : "*", port, emsg); + _dbus_win_free_error_string (emsg); + goto failed; + } -/** Gets our effective UID - * @returns process effective UID - */ -dbus_uid_t -_dbus_geteuid (void) -{ - return DBUS_UID_UNSET; -} + newlisten_fd = dbus_realloc (listen_fd, sizeof (int)*(nlisten_fd+1)); + if (!newlisten_fd) + { + closesocket (fd); + dbus_set_error (error, + DBUS_ERROR_NO_MEMORY, + "Failed to allocate file handle array"); + goto failed; + } + listen_fd = newlisten_fd; + listen_fd[nlisten_fd] = fd; + nlisten_fd++; -/** - * The only reason this is separate from _dbus_getpid() is to allow it - * on Windows for logging but not for other purposes. - * - * @returns process ID to put in log messages - */ -unsigned long -_dbus_pid_for_log (void) -{ - return _dbus_getpid (); -} + if (!_dbus_string_get_length (retport)) + { + /* If the user didn't specify a port, or used 0, then + the kernel chooses a port. After the first address + is bound to, we need to force all remaining addresses + to use the same port */ + if (!port || !strcmp (port, "0")) + { + struct sockaddr_storage addr; + socklen_t addrlen; + char portbuf[50]; + + addrlen = sizeof (addr); + getsockname (fd, (struct sockaddr*) &addr, &addrlen); + + if ((res = getnameinfo ((struct sockaddr*)&addr, addrlen, + NULL, 0, + portbuf, sizeof (portbuf), + NI_NUMERICSERV)) != 0) + { + char *emsg = _dbus_win_error_string (res); + dbus_set_error (error, _dbus_error_from_wsaerror (res), + "Failed to resolve port \"%s:%s\": %s", + host ? host : "*", port, emsg); + _dbus_win_free_error_string (emsg); + goto failed; + } + if (!_dbus_string_append (retport, portbuf)) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + goto failed; + } + + /* Release current address list & redo lookup */ + port = _dbus_string_get_const_data (retport); + freeaddrinfo (ai); + goto redo_lookup_with_port; + } + else + { + if (!_dbus_string_append (retport, port)) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + goto failed; + } + } + } -/** Gets our SID - * @param points to sid buffer, need to be freed with LocalFree() - * @returns process sid - */ -dbus_bool_t -_dbus_getsid(char **sid) -{ - HANDLE process_token = NULL; - TOKEN_USER *token_user = NULL; - DWORD n; - PSID psid; - int retval = FALSE; - - if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &process_token)) - { - _dbus_win_warn_win_error ("OpenProcessToken failed", GetLastError ()); - goto failed; - } - if ((!GetTokenInformation (process_token, TokenUser, NULL, 0, &n) - && GetLastError () != ERROR_INSUFFICIENT_BUFFER) - || (token_user = alloca (n)) == NULL - || !GetTokenInformation (process_token, TokenUser, token_user, n, &n)) - { - _dbus_win_warn_win_error ("GetTokenInformation failed", GetLastError ()); - goto failed; + tmp = tmp->ai_next; } - psid = token_user->User.Sid; - if (!IsValidSid (psid)) + freeaddrinfo (ai); + ai = NULL; + + if (!nlisten_fd) { - _dbus_verbose("%s invalid sid\n",__FUNCTION__); - goto failed; + char *emsg = _dbus_win_error_string (WSAEADDRINUSE); + dbus_set_error (error, _dbus_error_from_wsaerror (WSAEADDRINUSE), + "Failed to bind socket \"%s:%s\": %s", + host ? host : "*", port, emsg); + _dbus_win_free_error_string (emsg); + return -1; } - if (!ConvertSidToStringSidA (psid, sid)) + + for (i = 0 ; i < nlisten_fd ; i++) { - _dbus_verbose("%s invalid sid\n",__FUNCTION__); - goto failed; + if (!_dbus_set_fd_nonblocking (listen_fd[i], error)) + { + goto failed; + } } -//okay: - retval = TRUE; -failed: - if (process_token != NULL) - CloseHandle (process_token); + *fds_p = listen_fd; - _dbus_verbose("_dbus_getsid() returns %d\n",retval); - return retval; -} + return nlisten_fd; + failed: + if (ai) + freeaddrinfo (ai); + for (i = 0 ; i < nlisten_fd ; i++) + closesocket (listen_fd[i]); + dbus_free (listen_fd); -#ifdef DBUS_BUILD_TESTS -/** Gets our GID - * @returns process GID - */ -dbus_gid_t -_dbus_getgid (void) -{ - return DBUS_GID_UNSET; + return -1; } -#if 0 dbus_bool_t -_dbus_domain_test (const char *test_data_dir) +_dbus_read_credentials_socket (int client_fd, + DBusCredentials *credentials, + DBusError *error) { - if (!_dbus_test_oom_handling ("spawn_nonexistent", - check_spawn_nonexistent, - NULL)) - return FALSE; -} + int bytes_read = 0; + char buf[1]; -#endif + _DBUS_ASSERT_ERROR_IS_CLEAR (error); -#endif //DBUS_BUILD_TESTS + bytes_read = recv (client_fd, buf, 1, 0); -/************************************************************************ - - pipes - - ************************************************************************/ + if (bytes_read > 0) + _dbus_verbose ("got credentials byte from client\n"); + + _dbus_verbose ("FIXME: get faked credentials from client\n"); + + return TRUE; +} -/** - * Creates a full-duplex pipe (as in socketpair()). - * Sets both ends of the pipe nonblocking. - * - * @todo libdbus only uses this for the debug-pipe server, so in - * principle it could be in dbus-sysdeps-util.c, except that - * dbus-sysdeps-util.c isn't in libdbus when tests are enabled and the - * debug-pipe server is used. - * - * @param fd1 return location for one end - * @param fd2 return location for the other end - * @param blocking #TRUE if pipe should be blocking - * @param error error return - * @returns #FALSE on failure (if error is set) - */ dbus_bool_t -_dbus_full_duplex_pipe (int *fd1, - int *fd2, - dbus_bool_t blocking, - DBusError *error) +_dbus_send_credentials_socket (int server_fd, + DBusError *error) { - SOCKET temp, socket1 = -1, socket2 = -1; - struct sockaddr_in saddr; - int len; - u_long arg; - fd_set read_set, write_set; - struct timeval tv; + /* FIXME: for the session bus credentials shouldn't matter (?), but + * for the system bus they are presumably essential. A rough outline + * of a way to implement the credential transfer would be this: + * + * Client waits to *read* a byte. + * + * Server creates a named pipe with a random name, sends a byte + * contining its length, and its name. + * + * Client reads the name, connects to it (using Win32 API). + * + * Server waits for connection to the named pipe, then calls + * ImpersonateNamedPipeClient(), notes its now-current credentials, + * calls RevertToSelf(), closes its handles to the named pipe, and + * is done. (Maybe there is some other way to get the SID of a named + * pipe client without having to use impersonation?) + * + * Client closes its handles and is done. + * + * Ralf: Why not sending credentials over the given this connection ? + * Using named pipes makes it impossible to be connected from a unix client. + */ - _dbus_win_startup_winsock (); + int bytes_written; - temp = socket (AF_INET, SOCK_STREAM, 0); - if (temp == INVALID_SOCKET) - { - DBUS_SOCKET_SET_ERRNO (); - goto out0; - } + bytes_written = send (server_fd, "", 1, 0); - arg = 1; - if (ioctlsocket (temp, FIONBIO, &arg) == SOCKET_ERROR) + if (bytes_written == SOCKET_ERROR) { - DBUS_SOCKET_SET_ERRNO (); - goto out0; - } - - _DBUS_ZERO (saddr); - saddr.sin_family = AF_INET; - saddr.sin_port = 0; - saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); + int wsaerrno = WSAGetLastError (); + char *emsg = _dbus_win_error_string (wsaerrno); - if (bind (temp, (struct sockaddr *)&saddr, sizeof (saddr))) - { - DBUS_SOCKET_SET_ERRNO (); - goto out0; + dbus_set_error (error, _dbus_error_from_wsaerror (wsaerrno), + "Failed to write credentials byte: %s", + emsg); + _dbus_win_free_error_string (emsg); + return FALSE; } - - if (listen (temp, 1) == SOCKET_ERROR) + else if (bytes_written == 0) { - DBUS_SOCKET_SET_ERRNO (); - goto out0; + dbus_set_error (error, DBUS_ERROR_IO_ERROR, + "Wrote zero bytes writing credentials byte"); + return FALSE; } - - len = sizeof (saddr); - if (getsockname (temp, (struct sockaddr *)&saddr, &len)) + else { - DBUS_SOCKET_SET_ERRNO (); - goto out0; + _dbus_assert (bytes_written == 1); + _dbus_verbose ("Wrote credentials byte, actual credential sending isn't implemented yet\n"); + return TRUE; } + return TRUE; +} - socket1 = socket (AF_INET, SOCK_STREAM, 0); - if (socket1 == INVALID_SOCKET) - { - DBUS_SOCKET_SET_ERRNO (); - goto out0; - } +int +_dbus_accept (int listen_fd) +{ + int client_fd; + struct sockaddr addr; + socklen_t addrlen; - arg = 1; - if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR) - { - DBUS_SOCKET_SET_ERRNO (); - goto out1; - } + addrlen = sizeof (addr); - if (connect (socket1, (struct sockaddr *)&saddr, len) != SOCKET_ERROR || - WSAGetLastError () != WSAEWOULDBLOCK) + client_fd = accept (listen_fd, &addr, &addrlen); + + if ((SOCKET) client_fd == INVALID_SOCKET) { - DBUS_SOCKET_SET_ERRNO (); - goto out1; + errno = WSAGetLastError (); + return -1; } - FD_ZERO (&read_set); - FD_SET (temp, &read_set); + _dbus_verbose ("client fd %d accepted\n", client_fd); - tv.tv_sec = 0; - tv.tv_usec = 0; + return client_fd; +} - if (select (0, &read_set, NULL, NULL, NULL) == SOCKET_ERROR) - { - DBUS_SOCKET_SET_ERRNO (); - goto out1; - } +dbus_bool_t +_dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error) +{ + _DBUS_ASSERT_ERROR_IS_CLEAR (error); - _dbus_assert (FD_ISSET (temp, &read_set)); + _dbus_verbose ("FIXME: _dbus_check_dir_is_private_to_user() is not implemented yet\n"); - socket2 = accept (temp, (struct sockaddr *) &saddr, &len); - if (socket2 == INVALID_SOCKET) - { - DBUS_SOCKET_SET_ERRNO (); - goto out1; - } + return TRUE; +} - FD_ZERO (&write_set); - FD_SET (socket1, &write_set); +dbus_bool_t +_dbus_credentials_add_from_current_process (DBusCredentials *credentials) +{ + dbus_bool_t retval = FALSE; + char *sid = NULL; - tv.tv_sec = 0; - tv.tv_usec = 0; + if (!_dbus_getsid (&sid)) + goto failed; - if (select (0, NULL, &write_set, NULL, NULL) == SOCKET_ERROR) - { - DBUS_SOCKET_SET_ERRNO (); - goto out2; - } + if (!_dbus_credentials_add_unix_pid (credentials, _dbus_getpid ())) + goto failed; - _dbus_assert (FD_ISSET (socket1, &write_set)); + if (!_dbus_credentials_add_windows_sid (credentials, sid)) + goto failed; - if (blocking) - { - arg = 0; - if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR) - { - DBUS_SOCKET_SET_ERRNO (); - goto out2; - } + retval = TRUE; + goto end; +failed: + retval = FALSE; +end: + if (sid) + LocalFree (sid); - arg = 0; - if (ioctlsocket (socket2, FIONBIO, &arg) == SOCKET_ERROR) - { - DBUS_SOCKET_SET_ERRNO (); - goto out2; - } - } - else - { - arg = 1; - if (ioctlsocket (socket2, FIONBIO, &arg) == SOCKET_ERROR) - { - DBUS_SOCKET_SET_ERRNO (); - goto out2; - } - } + return retval; +} - *fd1 = socket1; - *fd2 = socket2; +dbus_bool_t +_dbus_append_user_from_current_process (DBusString *str) +{ + dbus_bool_t retval = FALSE; + char *sid = NULL; - _dbus_verbose ("full-duplex pipe %d:%d <-> %d:%d\n", - *fd1, socket1, *fd2, socket2); + if (!_dbus_getsid (&sid)) + return FALSE; - closesocket (temp); + retval = _dbus_string_append (str, sid); - return TRUE; + LocalFree (sid); -out2: - closesocket (socket2); -out1: - closesocket (socket1); -out0: - closesocket (temp); + return retval; +} - dbus_set_error (error, _dbus_error_from_errno (errno), - "Could not setup socket pair: %s", - _dbus_strerror (errno)); +dbus_pid_t +_dbus_getpid (void) +{ + return GetCurrentProcessId (); +} - return FALSE; +unsigned long +_dbus_pid_for_log (void) +{ + return _dbus_getpid (); +} + +_DBUS_DEFINE_GLOBAL_LOCK (atomic); + +dbus_int32_t +_dbus_atomic_inc (DBusAtomic *atomic) +{ + /* +/- 1 is needed here! */ +#ifdef _MSC_VER + return InterlockedIncrement (&atomic->value) - 1; +#else + /* No volatile in InterlockedIncrement's prototype in the w32api headers */ + return InterlockedIncrement ((LPLONG) &atomic->value) - 1; +#endif +} + +dbus_int32_t +_dbus_atomic_dec (DBusAtomic *atomic) +{ + /* +/- 1 is needed here! */ +#ifdef _MSC_VER + return InterlockedDecrement (&atomic->value) + 1; +#else + return InterlockedDecrement ((LPLONG) &atomic->value) + 1; +#endif } -/** - * Wrapper for poll(). - * - * @param fds the file descriptors to poll - * @param n_fds number of descriptors in the array - * @param timeout_milliseconds timeout or -1 for infinite - * @returns numbers of fds with revents, or <0 on error - */ -#define USE_CHRIS_IMPL 0 -#if USE_CHRIS_IMPL int _dbus_poll (DBusPollFD *fds, int n_fds, int timeout_milliseconds) { +#define USE_CHRIS_IMPL 0 + +#if USE_CHRIS_IMPL + #define DBUS_POLL_CHAR_BUFFER_SIZE 2000 char msg[DBUS_POLL_CHAR_BUFFER_SIZE]; char *msgp; @@ -1141,38 +955,35 @@ _dbus_poll (DBusPollFD *fds, WSAEVENT eventsOnStack[DBUS_STACK_WSAEVENTS]; WSAEVENT *pEvents = NULL; if (n_fds > DBUS_STACK_WSAEVENTS) - pEvents = calloc(sizeof(WSAEVENT), n_fds); + pEvents = calloc (sizeof (WSAEVENT), n_fds); else pEvents = eventsOnStack; #ifdef DBUS_ENABLE_VERBOSE_MODE msgp = msg; - msgp += sprintf (msgp, "WSAEventSelect: to=%d\n\t", timeout_milliseconds); + msgp += sprintf (msgp, "WSAEventSelect: to=%d ", timeout_milliseconds); for (i = 0; i < n_fds; i++) { - static dbus_bool_t warned = FALSE; DBusPollFD *fdp = &fds[i]; - if (fdp->events & _DBUS_POLLIN) msgp += sprintf (msgp, "R:%d ", fdp->fd); if (fdp->events & _DBUS_POLLOUT) msgp += sprintf (msgp, "W:%d ", fdp->fd); - msgp += sprintf (msgp, "E:%d\n\t", fdp->fd); + msgp += sprintf (msgp, "E:%d ", fdp->fd); - // FIXME: more robust code for long msg - // create on heap when msg[] becomes too small + /* FIXME: more robust code for long msg + * create on heap when msg[] becomes too small */ if (msgp >= msg + DBUS_POLL_CHAR_BUFFER_SIZE) { _dbus_assert_not_reached ("buffer overflow in _dbus_poll"); } } - msgp += sprintf (msgp, "\n"); - _dbus_verbose ("%s",msg); + _dbus_verbose ("%s\n",msg); #endif for (i = 0; i < n_fds; i++) { @@ -1180,7 +991,7 @@ _dbus_poll (DBusPollFD *fds, WSAEVENT ev; long lNetworkEvents = FD_OOB; - ev = WSACreateEvent(); + ev = WSACreateEvent (); if (fdp->events & _DBUS_POLLIN) lNetworkEvents |= FD_READ | FD_ACCEPT | FD_CLOSE; @@ -1188,7 +999,7 @@ _dbus_poll (DBusPollFD *fds, if (fdp->events & _DBUS_POLLOUT) lNetworkEvents |= FD_WRITE | FD_CONNECT; - WSAEventSelect(fdp->fd, ev, lNetworkEvents); + WSAEventSelect (fdp->fd, ev, lNetworkEvents); pEvents[i] = ev; } @@ -1200,7 +1011,7 @@ _dbus_poll (DBusPollFD *fds, { DBUS_SOCKET_SET_ERRNO (); if (errno != EWOULDBLOCK) - _dbus_verbose ("WSAWaitForMultipleEvents: failed: %s\n", _dbus_strerror (errno)); + _dbus_verbose ("WSAWaitForMultipleEvents: failed: %s\n", strerror (errno)); ret = -1; } else if (ready == WSA_WAIT_TIMEOUT) @@ -1211,7 +1022,7 @@ _dbus_poll (DBusPollFD *fds, else if (ready >= WSA_WAIT_EVENT_0 && ready < (int)(WSA_WAIT_EVENT_0 + n_fds)) { msgp = msg; - msgp += sprintf (msgp, "WSAWaitForMultipleEvents: =%d\n\t", ready); + msgp += sprintf (msgp, "WSAWaitForMultipleEvents: = %d", ready); for (i = 0; i < n_fds; i++) { @@ -1220,7 +1031,7 @@ _dbus_poll (DBusPollFD *fds, fdp->revents = 0; - WSAEnumNetworkEvents(fdp->fd, pEvents[i], &ne); + WSAEnumNetworkEvents (fdp->fd, pEvents[i], &ne); if (ne.lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE)) fdp->revents |= _DBUS_POLLIN; @@ -1242,39 +1053,32 @@ _dbus_poll (DBusPollFD *fds, msgp += sprintf (msgp, "lNetworkEvents:%d ", ne.lNetworkEvents); - if(ne.lNetworkEvents) + if (ne.lNetworkEvents) ret++; - WSAEventSelect(fdp->fd, pEvents[i], 0); + WSAEventSelect (fdp->fd, pEvents[i], 0); } - msgp += sprintf (msgp, "\n"); - _dbus_verbose ("%s",msg); + _dbus_verbose ("%s\n",msg); } else { - _dbus_verbose ("WSAWaitForMultipleEvents: failed for unknown reason!"); + _dbus_verbose ("WSAWaitForMultipleEvents: failed for unknown reason!\n"); ret = -1; } - for(i = 0; i < n_fds; i++) + for (i = 0; i < n_fds; i++) { - WSACloseEvent(pEvents[i]); + WSACloseEvent (pEvents[i]); } if (n_fds > DBUS_STACK_WSAEVENTS) - free(pEvents); + free (pEvents); return ret; -} -#else // USE_CHRIS_IMPL +#else /* USE_CHRIS_IMPL */ -int -_dbus_poll (DBusPollFD *fds, - int n_fds, - int timeout_milliseconds) -{ #define DBUS_POLL_CHAR_BUFFER_SIZE 2000 char msg[DBUS_POLL_CHAR_BUFFER_SIZE]; char *msgp; @@ -1292,43 +1096,40 @@ _dbus_poll (DBusPollFD *fds, #ifdef DBUS_ENABLE_VERBOSE_MODE msgp = msg; - msgp += sprintf (msgp, "select: to=%d\n\t", timeout_milliseconds); + msgp += sprintf (msgp, "select: to=%d ", timeout_milliseconds); for (i = 0; i < n_fds; i++) { - static dbus_bool_t warned = FALSE; DBusPollFD *fdp = &fds[i]; - if (fdp->events & _DBUS_POLLIN) msgp += sprintf (msgp, "R:%d ", fdp->fd); if (fdp->events & _DBUS_POLLOUT) msgp += sprintf (msgp, "W:%d ", fdp->fd); - msgp += sprintf (msgp, "E:%d\n\t", fdp->fd); + msgp += sprintf (msgp, "E:%d ", fdp->fd); - // FIXME: more robust code for long msg - // create on heap when msg[] becomes too small + /* FIXME: more robust code for long msg + * create on heap when msg[] becomes too small */ if (msgp >= msg + DBUS_POLL_CHAR_BUFFER_SIZE) { _dbus_assert_not_reached ("buffer overflow in _dbus_poll"); } } - msgp += sprintf (msgp, "\n"); - _dbus_verbose ("%s",msg); + _dbus_verbose ("%s\n",msg); #endif for (i = 0; i < n_fds; i++) { - DBusPollFD *fdp = &fds[i]; + DBusPollFD *fdp = &fds[i]; if (fdp->events & _DBUS_POLLIN) - FD_SET (fdp->fd, &read_set); + FD_SET ((SOCKET) fdp->fd, &read_set); if (fdp->events & _DBUS_POLLOUT) - FD_SET (fdp->fd, &write_set); + FD_SET ((SOCKET) fdp->fd, &write_set); - FD_SET (fdp->fd, &err_set); + FD_SET ((SOCKET) fdp->fd, &err_set); max_fd = MAX (max_fd, fdp->fd); } @@ -1340,631 +1141,62 @@ _dbus_poll (DBusPollFD *fds, ready = select (max_fd + 1, &read_set, &write_set, &err_set, timeout_milliseconds < 0 ? NULL : &tv); - if (DBUS_SOCKET_API_RETURNS_ERROR (ready)) + if (ready == SOCKET_ERROR) { - DBUS_SOCKET_SET_ERRNO (); - if (errno != EWOULDBLOCK) - _dbus_verbose ("select: failed: %s\n", _dbus_strerror (errno)); + int wsaerrno = WSAGetLastError (); + + errno = wsaerrno; + if (wsaerrno != WSAEWOULDBLOCK) + { + char *emsg = _dbus_win_error_string (wsaerrno); + _dbus_verbose ("select: failed: %s\n", emsg); + _dbus_win_free_error_string (emsg); + } } else if (ready == 0) _dbus_verbose ("select: = 0\n"); - else - if (ready > 0) - { + else if (ready > 0) + { #ifdef DBUS_ENABLE_VERBOSE_MODE - msgp = msg; - msgp += sprintf (msgp, "select: = %d:\n\t", ready); + msgp = msg; + msgp += sprintf (msgp, "select: = %d: ", ready); - for (i = 0; i < n_fds; i++) - { - DBusPollFD *fdp = &fds[i]; + for (i = 0; i < n_fds; i++) + { + DBusPollFD *fdp = &fds[i]; - if (FD_ISSET (fdp->fd, &read_set)) - msgp += sprintf (msgp, "R:%d ", fdp->fd); + if (FD_ISSET (fdp->fd, &read_set)) + msgp += sprintf (msgp, "R:%d ", fdp->fd); - if (FD_ISSET (fdp->fd, &write_set)) - msgp += sprintf (msgp, "W:%d ", fdp->fd); + if (FD_ISSET (fdp->fd, &write_set)) + msgp += sprintf (msgp, "W:%d ", fdp->fd); - if (FD_ISSET (fdp->fd, &err_set)) - msgp += sprintf (msgp, "E:%d\n\t", fdp->fd); - } - msgp += sprintf (msgp, "\n"); - _dbus_verbose ("%s",msg); + if (FD_ISSET (fdp->fd, &err_set)) + msgp += sprintf (msgp, "E:%d ", fdp->fd); + } + _dbus_verbose ("%s\n",msg); #endif - for (i = 0; i < n_fds; i++) - { - DBusPollFD *fdp = &fds[i]; - - fdp->revents = 0; - - if (FD_ISSET (fdp->fd, &read_set)) - fdp->revents |= _DBUS_POLLIN; - - if (FD_ISSET (fdp->fd, &write_set)) - fdp->revents |= _DBUS_POLLOUT; - - if (FD_ISSET (fdp->fd, &err_set)) - fdp->revents |= _DBUS_POLLERR; - } - } - return ready; -} - -#endif // USE_CHRIS_IMPL - - - - -/****************************************************************************** - -Original CVS version of dbus-sysdeps.c - -******************************************************************************/ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* dbus-sysdeps.c Wrappers around system/libc features (internal to D-Bus implementation) - * - * Copyright (C) 2002, 2003 Red Hat, Inc. - * Copyright (C) 2003 CodeFactory AB - * Copyright (C) 2005 Novell, Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - - -/** - * @addtogroup DBusInternalsUtils - * @{ - */ - -int _dbus_mkdir (const char *path, - mode_t mode) -{ - return _mkdir(path); -} - -/** - * Exit the process, returning the given value. - * - * @param code the exit code - */ -void -_dbus_exit (int code) -{ - _exit (code); -} - -/** - * Creates a socket and connects to a socket at the given host - * and port. The connection fd is returned, and is set up as - * nonblocking. - * - * @param host the host name to connect to, NULL for loopback - * @param port the prot to connect to - * @param error return location for error code - * @returns connection file descriptor or -1 on error - */ -int -_dbus_connect_tcp_socket (const char *host, - dbus_uint32_t port, - DBusError *error) -{ - int fd; - struct sockaddr_in addr; - struct hostent *he; - struct in_addr *haddr; - struct in_addr ina; - - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - - _dbus_win_startup_winsock (); - - fd = socket (AF_INET, SOCK_STREAM, 0); - - if (DBUS_SOCKET_IS_INVALID (fd)) - { - DBUS_SOCKET_SET_ERRNO (); - dbus_set_error (error, - _dbus_error_from_errno (errno), - "Failed to create socket: %s", - _dbus_strerror (errno)); - - return -1; - } - - if (host == NULL) - { - host = "localhost"; - ina.s_addr = htonl (INADDR_LOOPBACK); - haddr = &ina; - } - - he = gethostbyname (host); - if (he == NULL) - { - DBUS_SOCKET_SET_ERRNO (); - dbus_set_error (error, - _dbus_error_from_errno (errno), - "Failed to lookup hostname: %s", - host); - DBUS_CLOSE_SOCKET (fd); - return -1; - } - - haddr = ((struct in_addr *) (he->h_addr_list)[0]); - - _DBUS_ZERO (addr); - memcpy (&addr.sin_addr, haddr, sizeof(struct in_addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons (port); - - if (DBUS_SOCKET_API_RETURNS_ERROR - (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0)) - { - DBUS_SOCKET_SET_ERRNO (); - dbus_set_error (error, - _dbus_error_from_errno (errno), - "Failed to connect to socket %s:%d %s", - host, port, _dbus_strerror (errno)); - - DBUS_CLOSE_SOCKET (fd); - fd = -1; - - return -1; - } - - if (!_dbus_set_fd_nonblocking (fd, error)) - { - _dbus_close_socket (fd, NULL); - fd = -1; - - return -1; - } - - return fd; -} - -void -_dbus_daemon_init(const char *host, dbus_uint32_t port); -/** - * Creates a socket and binds it to the given port, - * then listens on the socket. The socket is - * set to be nonblocking. - * In case of port=0 a random free port is used and - * returned in the port parameter. - * - * @param host the interface to listen on, NULL for loopback, empty for any - * @param port the port to listen on, if zero a free port will be used - * @param error return location for errors - * @returns the listening file descriptor or -1 on error - */ - -int -_dbus_listen_tcp_socket (const char *host, - dbus_uint32_t *port, - dbus_bool_t inaddr_any, - DBusError *error) -{ - int fd; - struct sockaddr_in addr; - struct hostent *he; - struct in_addr *haddr; - socklen_t len = (socklen_t) sizeof (struct sockaddr); - struct in_addr ina; - - - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - - _dbus_win_startup_winsock (); - - fd = socket (AF_INET, SOCK_STREAM, 0); - - if (DBUS_SOCKET_IS_INVALID (fd)) - { - DBUS_SOCKET_SET_ERRNO (); - dbus_set_error (error, _dbus_error_from_errno (errno), - "Failed to create socket \"%s:%d\": %s", - host, port, _dbus_strerror (errno)); - return -1; - } - if (host == NULL) - { - host = "localhost"; - ina.s_addr = htonl (INADDR_LOOPBACK); - haddr = &ina; - } - else if (!host[0]) - { - ina.s_addr = htonl (INADDR_ANY); - haddr = &ina; - } - else - { - he = gethostbyname (host); - if (he == NULL) + for (i = 0; i < n_fds; i++) { - DBUS_SOCKET_SET_ERRNO (); - dbus_set_error (error, - _dbus_error_from_errno (errno), - "Failed to lookup hostname: %s", - host); - DBUS_CLOSE_SOCKET (fd); - return -1; - } - - haddr = ((struct in_addr *) (he->h_addr_list)[0]); - } - - _DBUS_ZERO (addr); - memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons (*port); - - if (bind (fd, (struct sockaddr*) &addr, sizeof (struct sockaddr))) - { - DBUS_SOCKET_SET_ERRNO (); - dbus_set_error (error, _dbus_error_from_errno (errno), - "Failed to bind socket \"%s:%d\": %s", - host, *port, _dbus_strerror (errno)); - DBUS_CLOSE_SOCKET (fd); - return -1; - } - - if (DBUS_SOCKET_API_RETURNS_ERROR (listen (fd, 30 /* backlog */))) - { - DBUS_SOCKET_SET_ERRNO (); - dbus_set_error (error, _dbus_error_from_errno (errno), - "Failed to listen on socket \"%s:%d\": %s", - host, *port, _dbus_strerror (errno)); - DBUS_CLOSE_SOCKET (fd); - return -1; - } - - getsockname(fd, (struct sockaddr*) &addr, &len); - *port = (dbus_uint32_t) ntohs(addr.sin_port); - - _dbus_daemon_init(host, ntohs(addr.sin_port)); - - if (!_dbus_set_fd_nonblocking (fd, error)) - { - _dbus_close_socket (fd, NULL); - return -1; - } - - return fd; -} - - -/** - * Accepts a connection on a listening socket. - * Handles EINTR for you. - * - * @param listen_fd the listen file descriptor - * @returns the connection fd of the client, or -1 on error - */ -int -_dbus_accept (int listen_fd) -{ - int client_fd; - struct sockaddr addr; - socklen_t addrlen; - - addrlen = sizeof (addr); - - retry: - client_fd = accept (listen_fd, &addr, &addrlen); - - if (DBUS_SOCKET_IS_INVALID (client_fd)) - { - DBUS_SOCKET_SET_ERRNO (); - if (errno == EINTR) - goto retry; - } - - _dbus_verbose ("client fd %d accepted\n", client_fd); - - return client_fd; -} - - - - -dbus_bool_t -_dbus_send_credentials_socket (int handle, - DBusError *error) -{ -/* FIXME: for the session bus credentials shouldn't matter (?), but - * for the system bus they are presumably essential. A rough outline - * of a way to implement the credential transfer would be this: - * - * client waits to *read* a byte. - * - * server creates a named pipe with a random name, sends a byte - * contining its length, and its name. - * - * client reads the name, connects to it (using Win32 API). - * - * server waits for connection to the named pipe, then calls - * ImpersonateNamedPipeClient(), notes its now-current credentials, - * calls RevertToSelf(), closes its handles to the named pipe, and - * is done. (Maybe there is some other way to get the SID of a named - * pipe client without having to use impersonation?) - * - * client closes its handles and is done. - * - * Ralf: Why not sending credentials over the given this connection ? - * Using named pipes makes it impossible to be connected from a unix client. - * - */ - int bytes_written; - DBusString buf; - - _dbus_string_init_const_len (&buf, "\0", 1); -again: - bytes_written = _dbus_write_socket (handle, &buf, 0, 1 ); - - if (bytes_written < 0 && errno == EINTR) - goto again; - - if (bytes_written < 0) - { - dbus_set_error (error, _dbus_error_from_errno (errno), - "Failed to write credentials byte: %s", - _dbus_strerror (errno)); - return FALSE; - } - else if (bytes_written == 0) - { - dbus_set_error (error, DBUS_ERROR_IO_ERROR, - "wrote zero bytes writing credentials byte"); - return FALSE; - } - else - { - _dbus_assert (bytes_written == 1); - _dbus_verbose ("wrote 1 zero byte, credential sending isn't implemented yet\n"); - return TRUE; - } - return TRUE; -} - -/** - * Reads a single byte which must be nul (an error occurs otherwise), - * and reads unix credentials if available. Fills in pid/uid/gid with - * -1 if no credentials are available. Return value indicates whether - * a byte was read, not whether we got valid credentials. On some - * systems, such as Linux, reading/writing the byte isn't actually - * required, but we do it anyway just to avoid multiple codepaths. - * - * Fails if no byte is available, so you must select() first. - * - * The point of the byte is that on some systems we have to - * use sendmsg()/recvmsg() to transmit credentials. - * - * @param client_fd the client file descriptor - * @param credentials struct to fill with credentials of client - * @param error location to store error code - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_read_credentials_socket (int handle, - DBusCredentials *credentials, - DBusError *error) -{ - int bytes_read = 0; - DBusString buf; - - // could fail due too OOM - if (_dbus_string_init(&buf)) - { - bytes_read = _dbus_read_socket(handle, &buf, 1 ); - - if (bytes_read > 0) - _dbus_verbose("got one zero byte from server"); - - _dbus_string_free(&buf); - } - - _dbus_credentials_add_from_current_process (credentials); - _dbus_verbose("FIXME: get faked credentials from current process"); - - return TRUE; -} - -/** -* Checks to make sure the given directory is -* private to the user -* -* @param dir the name of the directory -* @param error error return -* @returns #FALSE on failure -**/ -dbus_bool_t -_dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error) -{ - const char *directory; - struct stat sb; - - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - - return TRUE; -} - - -/** - * Appends the given filename to the given directory. - * - * @todo it might be cute to collapse multiple '/' such as "foo//" - * concat "//bar" - * - * @param dir the directory name - * @param next_component the filename - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_concat_dir_and_file (DBusString *dir, - const DBusString *next_component) -{ - dbus_bool_t dir_ends_in_slash; - dbus_bool_t file_starts_with_slash; + DBusPollFD *fdp = &fds[i]; - if (_dbus_string_get_length (dir) == 0 || - _dbus_string_get_length (next_component) == 0) - return TRUE; + fdp->revents = 0; - dir_ends_in_slash = - ('/' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1) || - '\\' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1)); + if (FD_ISSET (fdp->fd, &read_set)) + fdp->revents |= _DBUS_POLLIN; - file_starts_with_slash = - ('/' == _dbus_string_get_byte (next_component, 0) || - '\\' == _dbus_string_get_byte (next_component, 0)); + if (FD_ISSET (fdp->fd, &write_set)) + fdp->revents |= _DBUS_POLLOUT; - if (dir_ends_in_slash && file_starts_with_slash) - { - _dbus_string_shorten (dir, 1); - } - else if (!(dir_ends_in_slash || file_starts_with_slash)) - { - if (!_dbus_string_append_byte (dir, '\\')) - return FALSE; + if (FD_ISSET (fdp->fd, &err_set)) + fdp->revents |= _DBUS_POLLERR; + } } - - return _dbus_string_copy (next_component, 0, dir, - _dbus_string_get_length (dir)); -} - -/*---------------- DBusCredentials ---------------------------------- - -/** - * Adds the credentials corresponding to the given username. - * - * @param credentials credentials to fill in - * @param username the username - * @returns #TRUE if the username existed and we got some credentials - */ -dbus_bool_t -_dbus_credentials_add_from_user (DBusCredentials *credentials, - const DBusString *username) -{ - return _dbus_credentials_add_windows_sid (credentials, - _dbus_string_get_const_data(username)); -} - -/** - * Adds the credentials of the current process to the - * passed-in credentials object. - * - * @param credentials credentials to add to - * @returns #FALSE if no memory; does not properly roll back on failure, so only some credentials may have been added - */ - -dbus_bool_t -_dbus_credentials_add_from_current_process (DBusCredentials *credentials) -{ - dbus_bool_t retval = FALSE; - char *sid = NULL; - - if (!_dbus_getsid(&sid)) - goto failed; - - if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid())) - goto failed; - - if (!_dbus_credentials_add_windows_sid (credentials,sid)) - goto failed; - - retval = TRUE; - goto end; -failed: - retval = FALSE; -end: - if (sid) - LocalFree(sid); - - return retval; -} - -/** - * Append to the string the identity we would like to have when we - * authenticate, on UNIX this is the current process UID and on - * Windows something else, probably a Windows SID string. No escaping - * is required, that is done in dbus-auth.c. The username here - * need not be anything human-readable, it can be the machine-readable - * form i.e. a user id. - * - * @param str the string to append to - * @returns #FALSE on no memory - * @todo to which class belongs this - */ -dbus_bool_t -_dbus_append_user_from_current_process (DBusString *str) -{ - dbus_bool_t retval = FALSE; - char *sid = NULL; - - if (!_dbus_getsid(&sid)) - return FALSE; - - retval = _dbus_string_append (str,sid); - - LocalFree(sid); - return retval; -} - -/** - * Gets our process ID - * @returns process ID - */ -unsigned long -_dbus_getpid (void) -{ - return GetCurrentProcessId (); -} - -/** nanoseconds in a second */ -#define NANOSECONDS_PER_SECOND 1000000000 -/** microseconds in a second */ -#define MICROSECONDS_PER_SECOND 1000000 -/** milliseconds in a second */ -#define MILLISECONDS_PER_SECOND 1000 -/** nanoseconds in a millisecond */ -#define NANOSECONDS_PER_MILLISECOND 1000000 -/** microseconds in a millisecond */ -#define MICROSECONDS_PER_MILLISECOND 1000 - -/** - * Sleeps the given number of milliseconds. - * @param milliseconds number of milliseconds - */ -void -_dbus_sleep_milliseconds (int milliseconds) -{ - Sleep (milliseconds); + return ready; +#endif /* USE_CHRIS_IMPL */ } - -/** - * Get current time, as in gettimeofday(). - * - * @param tv_sec return location for number of seconds - * @param tv_usec return location for number of microseconds - */ void _dbus_get_current_time (long *tv_sec, long *tv_usec) @@ -1987,34 +1219,13 @@ _dbus_get_current_time (long *tv_sec, *tv_usec = *time64 % 1000000; } - -/** - * signal (SIGPIPE, SIG_IGN); - */ -void -_dbus_disable_sigpipe (void) -{ - _dbus_verbose("FIXME: implement _dbus_disable_sigpipe (void)\n"); -} - - -/** - * Appends the contents of the given file to the string, - * returning error code. At the moment, won't open a file - * more than a megabyte in size. - * - * @param str the string to append to - * @param filename filename to load - * @param error place to set an error - * @returns #FALSE if error was set - */ dbus_bool_t _dbus_file_get_contents (DBusString *str, const DBusString *filename, DBusError *error) { - DBusFile file; - struct stat sb; + int fd; + struct _stati64 sb; int orig_len; int total; const char *filename_c; @@ -2023,27 +1234,29 @@ _dbus_file_get_contents (DBusString *str, filename_c = _dbus_string_get_const_data (filename); - /* O_BINARY useful on Cygwin and Win32 */ - if (!_dbus_file_open (&file, filename_c, O_RDONLY | O_BINARY, -1)) + fd = _open (filename_c, O_RDONLY | O_BINARY); + if (fd < 0) { dbus_set_error (error, _dbus_error_from_errno (errno), "Failed to open \"%s\": %s", filename_c, - _dbus_strerror (errno)); + strerror (errno)); return FALSE; } - if (!_dbus_fstat (&file, &sb)) + _dbus_verbose ("file %s fd %d opened\n", filename_c, fd); + + if (_fstati64 (fd, &sb) < 0) { dbus_set_error (error, _dbus_error_from_errno (errno), "Failed to stat \"%s\": %s", filename_c, - _dbus_strerror (errno)); + strerror (errno)); _dbus_verbose ("fstat() failed: %s", - _dbus_strerror (errno)); + strerror (errno)); - _dbus_file_close (&file, NULL); + _close (fd); return FALSE; } @@ -2053,7 +1266,7 @@ _dbus_file_get_contents (DBusString *str, dbus_set_error (error, DBUS_ERROR_FAILED, "File size %lu of \"%s\" is too large.", (unsigned long) sb.st_size, filename_c); - _dbus_file_close (&file, NULL); + _close (fd); return FALSE; } @@ -2065,19 +1278,18 @@ _dbus_file_get_contents (DBusString *str, while (total < (int) sb.st_size) { - bytes_read = _dbus_file_read (&file, str, - sb.st_size - total); + bytes_read = _dbus_read (fd, str, sb.st_size - total); if (bytes_read <= 0) { dbus_set_error (error, _dbus_error_from_errno (errno), "Error reading \"%s\": %s", filename_c, - _dbus_strerror (errno)); + strerror (errno)); _dbus_verbose ("read() failed: %s", - _dbus_strerror (errno)); + strerror (errno)); - _dbus_file_close (&file, NULL); + _close (fd); _dbus_string_set_length (str, orig_len); return FALSE; } @@ -2085,50 +1297,43 @@ _dbus_file_get_contents (DBusString *str, total += bytes_read; } - _dbus_file_close (&file, NULL); + _close (fd); return TRUE; } else if (sb.st_size != 0) { - _dbus_verbose ("Can only open regular files at the moment.\n"); + _dbus_verbose ("can only open regular files at the moment.\n"); dbus_set_error (error, DBUS_ERROR_FAILED, "\"%s\" is not a regular file", filename_c); - _dbus_file_close (&file, NULL); + _close (fd); return FALSE; } else { - _dbus_file_close (&file, NULL); + _close (fd); return TRUE; } } -/** - * Writes a string out to a file. If the file exists, - * it will be atomically overwritten by the new data. - * - * @param str the string to write out - * @param filename the file to save string to - * @param error error to be filled in on failure - * @returns #FALSE on failure - */ dbus_bool_t _dbus_string_save_to_file (const DBusString *str, const DBusString *filename, DBusError *error) { - DBusFile file; + int fd; int bytes_to_write; const char *filename_c; DBusString tmp_filename; const char *tmp_filename_c; int total; + const char *str_c; dbus_bool_t need_unlink; dbus_bool_t retval; _DBUS_ASSERT_ERROR_IS_CLEAR (error); + fd = -1; retval = FALSE; need_unlink = FALSE; @@ -2145,7 +1350,7 @@ _dbus_string_save_to_file (const DBusString *str, return FALSE; } - if (!_dbus_string_append (&tmp_filename, ".")) + if (!_dbus_string_append (&tmp_filename, ".~")) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); _dbus_string_free (&tmp_filename); @@ -2163,56 +1368,60 @@ _dbus_string_save_to_file (const DBusString *str, filename_c = _dbus_string_get_const_data (filename); tmp_filename_c = _dbus_string_get_const_data (&tmp_filename); - if (!_dbus_file_open (&file, tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT, - 0600)) + fd = _open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT, + 0600); + if (fd < 0) { dbus_set_error (error, _dbus_error_from_errno (errno), "Could not create %s: %s", tmp_filename_c, - _dbus_strerror (errno)); + strerror (errno)); goto out; } + _dbus_verbose ("tmp file %s fd %d opened\n", tmp_filename_c, fd); + need_unlink = TRUE; total = 0; bytes_to_write = _dbus_string_get_length (str); + str_c = _dbus_string_get_const_data (str); while (total < bytes_to_write) { int bytes_written; - bytes_written = _dbus_file_write (&file, str, total, - bytes_to_write - total); + bytes_written = _write (fd, str_c + total, bytes_to_write - total); if (bytes_written <= 0) { dbus_set_error (error, _dbus_error_from_errno (errno), "Could not write to %s: %s", tmp_filename_c, - _dbus_strerror (errno)); - + strerror (errno)); goto out; } total += bytes_written; } - if (!_dbus_file_close (&file, NULL)) + if (_close (fd) < 0) { dbus_set_error (error, _dbus_error_from_errno (errno), "Could not close file %s: %s", - tmp_filename_c, _dbus_strerror (errno)); - + tmp_filename_c, strerror (errno)); goto out; } + fd = -1; - if ((unlink (filename_c) == -1 && errno != ENOENT) || - rename (tmp_filename_c, filename_c) < 0) + /* Unlike rename(), MoveFileEx() can replace existing files */ + if (MoveFileExA (tmp_filename_c, filename_c, MOVEFILE_REPLACE_EXISTING) < 0) { - dbus_set_error (error, _dbus_error_from_errno (errno), + char *emsg = _dbus_win_error_string (GetLastError ()); + dbus_set_error (error, DBUS_ERROR_FAILED, "Could not rename %s to %s: %s", tmp_filename_c, filename_c, - _dbus_strerror (errno)); + emsg); + _dbus_win_free_error_string (emsg); goto out; } @@ -2221,17 +1430,15 @@ _dbus_string_save_to_file (const DBusString *str, retval = TRUE; -out: - /* close first, then unlink, to prevent ".nfs34234235" garbage - * files - */ + out: + /* close first, then unlink */ - if (_dbus_is_valid_file(&file)) - _dbus_file_close (&file, NULL); + if (fd >= 0) + _close (fd); - if (need_unlink && unlink (tmp_filename_c) < 0) - _dbus_verbose ("Failed to unlink temp file %s: %s\n", - tmp_filename_c, _dbus_strerror (errno)); + if (need_unlink && _unlink (tmp_filename_c) < 0) + _dbus_verbose ("failed to unlink temp file %s: %s\n", + tmp_filename_c, strerror (errno)); _dbus_string_free (&tmp_filename); @@ -2241,57 +1448,73 @@ out: return retval; } +dbus_bool_t +_dbus_make_file_world_readable (const DBusString *filename, + DBusError *error) +{ + /* TODO */ + return TRUE; +} -/** Creates the given file, failing if the file already exists. - * - * @param filename the filename - * @param error error location - * @returns #TRUE if we created the file and it didn't exist - */ dbus_bool_t _dbus_create_file_exclusively (const DBusString *filename, DBusError *error) { - DBusFile file; + int fd; const char *filename_c; _DBUS_ASSERT_ERROR_IS_CLEAR (error); filename_c = _dbus_string_get_const_data (filename); - if (!_dbus_file_open (&file, filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT, - 0600)) + fd = _open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT, + 0600); + if (fd < 0) { dbus_set_error (error, DBUS_ERROR_FAILED, "Could not create file %s: %s\n", filename_c, - _dbus_strerror (errno)); + strerror (errno)); return FALSE; } - if (!_dbus_file_close (&file, NULL)) + _dbus_verbose ("exclusive file %s fd %d opened\n", filename_c, fd); + + if (_close (fd) < 0) { dbus_set_error (error, DBUS_ERROR_FAILED, "Could not close file %s: %s\n", filename_c, - _dbus_strerror (errno)); + strerror (errno)); return FALSE; } return TRUE; } +dbus_bool_t +_dbus_delete_file (const DBusString *filename, + DBusError *error) +{ + const char *filename_c; + + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + + filename_c = _dbus_string_get_const_data (filename); + + if (_unlink (filename_c) < 0) + { + dbus_set_error (error, DBUS_ERROR_FAILED, + "Failed to delete file %s: %s\n", + filename_c, strerror (errno)); + return FALSE; + } + else + return TRUE; +} -/** - * Creates a directory; succeeds if the directory - * is created or already existed. - * - * @param filename directory filename - * @param error initialized error object - * @returns #TRUE on success - */ dbus_bool_t _dbus_create_directory (const DBusString *filename, DBusError *error) @@ -2302,56 +1525,66 @@ _dbus_create_directory (const DBusString *filename, filename_c = _dbus_string_get_const_data (filename); - if (_dbus_mkdir (filename_c, 0700) < 0) + if (_mkdir (filename_c) < 0) { if (errno == EEXIST) return TRUE; dbus_set_error (error, DBUS_ERROR_FAILED, "Failed to create directory %s: %s\n", - filename_c, _dbus_strerror (errno)); + filename_c, strerror (errno)); return FALSE; } else return TRUE; } - -static void -pseudorandom_generate_random_bytes_buffer (char *buffer, - int n_bytes) +dbus_bool_t +_dbus_concat_dir_and_file (DBusString *dir, + const DBusString *next_component) { - long tv_usec; - int i; + dbus_bool_t dir_ends_in_slash; + dbus_bool_t file_starts_with_slash; + + if (_dbus_string_get_length (dir) == 0 || + _dbus_string_get_length (next_component) == 0) + return TRUE; - /* fall back to pseudorandom */ - _dbus_verbose ("Falling back to pseudorandom for %d bytes\n", - n_bytes); + dir_ends_in_slash = + ('/' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1) || + '\\' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1)); - _dbus_get_current_time (NULL, &tv_usec); - srand (tv_usec); + file_starts_with_slash = + ('/' == _dbus_string_get_byte (next_component, 0) || + '\\' == _dbus_string_get_byte (next_component, 0)); - i = 0; - while (i < n_bytes) + if (dir_ends_in_slash && file_starts_with_slash) { - double r; - unsigned int b; - - r = rand (); - b = (r / (double) RAND_MAX) * 255.0; + _dbus_string_shorten (dir, 1); + } + else if (!(dir_ends_in_slash || file_starts_with_slash)) + { + if (!_dbus_string_append_byte (dir, '\\')) + return FALSE; + } - buffer[i] = b; + return _dbus_string_copy (next_component, 0, dir, + _dbus_string_get_length (dir)); +} - ++i; - } +void +_dbus_sleep_milliseconds (int milliseconds) +{ + Sleep (milliseconds); } -static dbus_bool_t -pseudorandom_generate_random_bytes (DBusString *str, - int n_bytes) +dbus_bool_t +_dbus_generate_random_bytes (DBusString *str, + int n_bytes) { int old_len; char *p; + HCRYPTPROV hprov; old_len = _dbus_string_get_length (str); @@ -2360,92 +1593,153 @@ pseudorandom_generate_random_bytes (DBusString *str, p = _dbus_string_get_data_len (str, old_len, n_bytes); - pseudorandom_generate_random_bytes_buffer (p, n_bytes); + if (!CryptAcquireContext (&hprov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) + return FALSE; + + if (!CryptGenRandom (hprov, n_bytes, p)) + { + CryptReleaseContext (hprov, 0); + return FALSE; + } + + CryptReleaseContext (hprov, 0); return TRUE; } -/** - * Gets the temporary files directory by inspecting the environment variables - * TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned - * - * @returns location of temp directory - */ +void +_dbus_exit (int code) +{ + _exit (code); +} + const char* -_dbus_get_tmpdir(void) +_dbus_strerror (int error_number) { - static const char* tmpdir = NULL; + static char buf[1000]; + char *emsg; - if (tmpdir == NULL) + /* errno values overlap with common Windows error codes, sigh. In + * dbus we store in errnno of non-errno values only WinSock error + * codes which are higher up, though, so it shouldn't matter. + */ + if (error_number > 100) { - if (tmpdir == NULL) - tmpdir = getenv("TMP"); - if (tmpdir == NULL) - tmpdir = getenv("TEMP"); - if (tmpdir == NULL) - tmpdir = getenv("TMPDIR"); - if (tmpdir == NULL) - tmpdir = "C:\\Temp"; + emsg = _dbus_win_error_string (error_number); + if (strlen (emsg) < sizeof (buf)) + strcpy (buf, emsg); + else + strcpy (buf, "unknown"); + _dbus_win_free_error_string (emsg); + return buf; } - _dbus_assert(tmpdir != NULL); + return strerror (error_number); +} - return tmpdir; +void +_dbus_win_set_error_from_win_error (DBusError *error, + int code) +{ + char *msg; + + /* As we want the English message, we can use the A API */ + FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, code, MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US), + (LPSTR) &msg, 0, NULL); + if (msg) + { + char *msg_copy; + + msg_copy = dbus_malloc (strlen (msg)); + strcpy (msg_copy, msg); + LocalFree (msg); + + dbus_set_error (error, "win32.error", "%s", msg_copy); + } + else + dbus_set_error (error, "win32.error", "Unknown error code %d or FormatMessage failed", code); } +void +_dbus_win_warn_win_error (const char *message, + int code) +{ + DBusError error = DBUS_ERROR_INIT; -/** - * Deletes the given file. - * - * @param filename the filename - * @param error error location - * - * @returns #TRUE if unlink() succeeded - */ -dbus_bool_t -_dbus_delete_file (const DBusString *filename, - DBusError *error) + _dbus_win_set_error_from_win_error (&error, code); + _dbus_warn ("%s: %s\n", message, error.message); + dbus_error_free (&error); +} + +const char* +_dbus_error_from_wsaerror (int error_number) { - const char *filename_c; + return DBUS_ERROR_FAILED; +} - _DBUS_ASSERT_ERROR_IS_CLEAR (error); +void +_dbus_disable_sigpipe (void) +{ +} - filename_c = _dbus_string_get_const_data (filename); +void +_dbus_fd_set_close_on_exec (int handle) +{ + BOOL rc; - if (unlink (filename_c) < 0) + rc = SetHandleInformation ((HANDLE) handle, HANDLE_FLAG_INHERIT, 0); + + if (!rc) { - dbus_set_error (error, DBUS_ERROR_FAILED, - "Failed to delete file %s: %s\n", - filename_c, _dbus_strerror (errno)); - return FALSE; + char *emsg = _dbus_win_error_string (GetLastError ()); + _dbus_verbose ("SetHandleInformation handle=%d failed: %s", + handle, emsg); + _dbus_win_free_error_string (emsg); } - else - return TRUE; } -/** - * Generates the given number of random bytes, - * using the best mechanism we can come up with. - * - * @param str the string - * @param n_bytes the number of random bytes to append to string - * @returns #TRUE on success, #FALSE if no memory - */ dbus_bool_t -_dbus_generate_random_bytes (DBusString *str, - int n_bytes) +_dbus_set_fd_nonblocking (int handle, + DBusError *error) { - return pseudorandom_generate_random_bytes (str, n_bytes); + u_long one = 1; + + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + + if (ioctlsocket (handle, FIONBIO, &one) == SOCKET_ERROR) + { + int wsaerrno = WSAGetLastError (); + char *emsg = _dbus_win_error_string (wsaerrno); + + dbus_set_error (error, _dbus_error_from_wsaerror (wsaerrno), + "Failed to set socket %d:%d to nonblocking: %s", handle, + emsg); + _dbus_win_free_error_string (emsg); + return FALSE; + } + + return TRUE; } -#if !defined (DBUS_DISABLE_ASSERT) || defined(DBUS_BUILD_TESTS) +#if !defined (DBUS_DISABLE_ASSERT) || defined (DBUS_BUILD_TESTS) #ifdef _MSC_VER # ifdef BACKTRACES + /* The windbus people undefine BACKTRACES when dbus is built with + * MSC, so apparently it hasn't proved that useful for them + * then? + */ # undef BACKTRACES # endif #else -# define BACKTRACES + /* And it definitely isn't especially useful when dbus is built with gcc, + * as the backtrace code below doesn't understand stabs anyway. So don't + * compile in the BACKTRACES code here either, I'd say. --tml + */ +# undef BACKTRACES #endif #ifdef BACKTRACES @@ -2482,14 +1776,6 @@ _dbus_generate_random_bytes (DBusString *str, #define __i386__ #endif -//#define MAKE_FUNCPTR(f) static typeof(f) * p##f - -//MAKE_FUNCPTR(StackWalk); -//MAKE_FUNCPTR(SymGetModuleBase); -//MAKE_FUNCPTR(SymFunctionTableAccess); -//MAKE_FUNCPTR(SymInitialize); -//MAKE_FUNCPTR(SymGetSymFromAddr); -//MAKE_FUNCPTR(SymGetModuleInfo); static BOOL (WINAPI *pStackWalk)( DWORD MachineType, HANDLE hProcess, @@ -2530,7 +1816,8 @@ static DWORD (WINAPI *pSymSetOptions)( ); -static BOOL init_backtrace() +static BOOL +init_backtrace() { HMODULE hmodDbgHelp = LoadLibraryA("dbghelp"); /* @@ -2553,15 +1840,15 @@ static BOOL init_backtrace() #define FUNC(x) #x pStackWalk = (BOOL (WINAPI *)( -DWORD MachineType, -HANDLE hProcess, -HANDLE hThread, -LPSTACKFRAME StackFrame, -PVOID ContextRecord, -PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine, -PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine, -PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine, -PTRANSLATE_ADDRESS_ROUTINE TranslateAddress + DWORD MachineType, + HANDLE hProcess, + HANDLE hThread, + LPSTACKFRAME StackFrame, + PVOID ContextRecord, + PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine, + PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine, + PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine, + PTRANSLATE_ADDRESS_ROUTINE TranslateAddress ))GetProcAddress (hmodDbgHelp, FUNC(StackWalk)); pSymGetModuleBase=(DWORD (WINAPI *)( HANDLE hProcess, @@ -2599,7 +1886,8 @@ DWORD SymOptions return TRUE; } -static void dump_backtrace_for_thread(HANDLE hThread) +static void +dump_backtrace_for_thread(HANDLE hThread) { STACKFRAME sf; CONTEXT context; @@ -2673,7 +1961,8 @@ static void dump_backtrace_for_thread(HANDLE hThread) ResumeThread(hThread); } -static DWORD WINAPI dump_thread_proc(LPVOID lpParameter) +static DWORD WINAPI +dump_thread_proc(LPVOID lpParameter) { dump_backtrace_for_thread((HANDLE)lpParameter); return 0; @@ -2681,7 +1970,8 @@ static DWORD WINAPI dump_thread_proc(LPVOID lpParameter) /* cannot get valid context from current thread, so we have to execute * backtrace from another thread */ -static void dump_backtrace() +static void +dump_backtrace() { HANDLE hCurrentThread; HANDLE hThread; @@ -2695,114 +1985,245 @@ static void dump_backtrace() CloseHandle(hCurrentThread); } -void _dbus_print_backtrace(void) +void +_dbus_print_backtrace (void) { - init_backtrace(); - dump_backtrace(); + init_backtrace (); + dump_backtrace (); } #else -void _dbus_print_backtrace(void) +void +_dbus_print_backtrace (void) { - _dbus_verbose (" D-Bus not compiled with backtrace support\n"); + if (IsDebuggerPresent ()) + DebugBreak (); + _dbus_verbose ("D-Bus not compiled with backtrace support\n"); } #endif -static dbus_uint32_t fromAscii(char ascii) +#endif + +dbus_bool_t +_dbus_full_duplex_pipe (int *fd1, + int *fd2, + dbus_bool_t blocking, + DBusError *error) { - if(ascii >= '0' && ascii <= '9') - return ascii - '0'; - if(ascii >= 'A' && ascii <= 'F') - return ascii - 'A' + 10; - if(ascii >= 'a' && ascii <= 'f') - return ascii - 'a' + 10; - return 0; + SOCKET temp, socket1 = -1, socket2 = -1; + struct sockaddr_in saddr; + int len; + u_long arg; + fd_set read_set, write_set; + struct timeval tv; + int wsaerrno; + char *emsg; + + _dbus_win_startup_winsock (); + + temp = socket (AF_INET, SOCK_STREAM, 0); + if (temp == INVALID_SOCKET) + { + wsaerrno = WSAGetLastError (); + goto out0; + } + + arg = 1; + if (ioctlsocket (temp, FIONBIO, &arg) == SOCKET_ERROR) + { + wsaerrno = WSAGetLastError (); + goto out0; + } + + _DBUS_ZERO (saddr); + saddr.sin_family = AF_INET; + saddr.sin_port = 0; + saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); + + if (bind (temp, (struct sockaddr *)&saddr, sizeof (saddr))) + { + wsaerrno = WSAGetLastError (); + goto out0; + } + + if (listen (temp, 1) == SOCKET_ERROR) + { + wsaerrno = WSAGetLastError (); + goto out0; + } + + len = sizeof (saddr); + if (getsockname (temp, (struct sockaddr *)&saddr, &len)) + { + wsaerrno = WSAGetLastError (); + goto out0; + } + + socket1 = socket (AF_INET, SOCK_STREAM, 0); + if (socket1 == INVALID_SOCKET) + { + wsaerrno = WSAGetLastError (); + goto out0; + } + + arg = 1; + if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR) + { + wsaerrno = WSAGetLastError (); + goto out1; + } + + if (connect (socket1, (struct sockaddr *)&saddr, len) != SOCKET_ERROR || + WSAGetLastError () != WSAEWOULDBLOCK) + { + wsaerrno = WSAGetLastError (); + goto out1; + } + + FD_ZERO (&read_set); + FD_SET (temp, &read_set); + + tv.tv_sec = 0; + tv.tv_usec = 0; + + if (select (0, &read_set, NULL, NULL, NULL) == SOCKET_ERROR) + { + wsaerrno = WSAGetLastError (); + goto out1; + } + + _dbus_assert (FD_ISSET (temp, &read_set)); + + socket2 = accept (temp, (struct sockaddr *) &saddr, &len); + if (socket2 == INVALID_SOCKET) + { + wsaerrno = WSAGetLastError (); + goto out1; + } + + FD_ZERO (&write_set); + FD_SET (socket1, &write_set); + + tv.tv_sec = 0; + tv.tv_usec = 0; + + if (select (0, NULL, &write_set, NULL, NULL) == SOCKET_ERROR) + { + wsaerrno = WSAGetLastError (); + goto out2; + } + + _dbus_assert (FD_ISSET (socket1, &write_set)); + + if (blocking) + { + arg = 0; + if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR) + { + wsaerrno = WSAGetLastError (); + goto out2; + } + + arg = 0; + if (ioctlsocket (socket2, FIONBIO, &arg) == SOCKET_ERROR) + { + wsaerrno = WSAGetLastError (); + goto out2; + } + } + else + { + arg = 1; + if (ioctlsocket (socket2, FIONBIO, &arg) == SOCKET_ERROR) + { + wsaerrno = WSAGetLastError (); + goto out2; + } + } + + *fd1 = socket1; + *fd2 = socket2; + + _dbus_verbose ("full-duplex pipe %d:%d <-> %d:%d\n", + *fd1, socket1, *fd2, socket2); + + closesocket (temp); + + return TRUE; + +out2: + closesocket (socket2); +out1: + closesocket (socket1); +out0: + closesocket (temp); + + emsg = _dbus_win_error_string (wsaerrno); + dbus_set_error (error, _dbus_error_from_wsaerror (wsaerrno), + "Could not setup socket pair: %s", + emsg); + _dbus_win_free_error_string (emsg); + + return FALSE; } -dbus_bool_t _dbus_read_local_machine_uuid (DBusGUID *machine_id, - dbus_bool_t create_if_not_found, - DBusError *error) +int +_dbus_printf_string_upper_bound (const char *format, + va_list args) { -#ifdef DBUS_WINCE - return TRUE; - // TODO -#else - HW_PROFILE_INFOA info; - char *lpc = &info.szHwProfileGuid[0]; - dbus_uint32_t u; + /* MSVCRT's vsnprintf semantics are a bit different */ + /* The C library source in the Platform SDK indicates that this + * would work, but alas, it doesn't. At least not on Windows + * 2000. Presumably those sources correspond to the C library on + * some newer or even future Windows version. + * + len = _vsnprintf (NULL, _DBUS_INT_MAX, format, args); + */ + char p[1024]; + int len; + len = _vsnprintf (p, sizeof (p)-1, format, args); + if (len == -1) /* try again */ + { + char *p; + p = malloc (strlen (format)*3); + len = _vsnprintf (p, sizeof (p)-1, format, args); + free (p); + } + return len; +} - // the hw-profile guid lives long enough - if(!GetCurrentHwProfileA(&info)) - { - dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); // FIXME - return FALSE; - } +const char* +_dbus_get_tmpdir (void) +{ + static const char* tmpdir = NULL; + static char buf[1000]; - // Form: {12340001-4980-1920-6788-123456789012} - lpc++; - // 12340001 - u = ((fromAscii(lpc[0]) << 0) | - (fromAscii(lpc[1]) << 4) | - (fromAscii(lpc[2]) << 8) | - (fromAscii(lpc[3]) << 12) | - (fromAscii(lpc[4]) << 16) | - (fromAscii(lpc[5]) << 20) | - (fromAscii(lpc[6]) << 24) | - (fromAscii(lpc[7]) << 28)); - machine_id->as_uint32s[0] = u; - - lpc += 9; - // 4980-1920 - u = ((fromAscii(lpc[0]) << 0) | - (fromAscii(lpc[1]) << 4) | - (fromAscii(lpc[2]) << 8) | - (fromAscii(lpc[3]) << 12) | - (fromAscii(lpc[5]) << 16) | - (fromAscii(lpc[6]) << 20) | - (fromAscii(lpc[7]) << 24) | - (fromAscii(lpc[8]) << 28)); - machine_id->as_uint32s[1] = u; - - lpc += 10; - // 6788-1234 - u = ((fromAscii(lpc[0]) << 0) | - (fromAscii(lpc[1]) << 4) | - (fromAscii(lpc[2]) << 8) | - (fromAscii(lpc[3]) << 12) | - (fromAscii(lpc[5]) << 16) | - (fromAscii(lpc[6]) << 20) | - (fromAscii(lpc[7]) << 24) | - (fromAscii(lpc[8]) << 28)); - machine_id->as_uint32s[2] = u; - - lpc += 9; - // 56789012 - u = ((fromAscii(lpc[0]) << 0) | - (fromAscii(lpc[1]) << 4) | - (fromAscii(lpc[2]) << 8) | - (fromAscii(lpc[3]) << 12) | - (fromAscii(lpc[4]) << 16) | - (fromAscii(lpc[5]) << 20) | - (fromAscii(lpc[6]) << 24) | - (fromAscii(lpc[7]) << 28)); - machine_id->as_uint32s[3] = u; -#endif - return TRUE; + if (tmpdir == NULL) + { + if (!GetTempPath (sizeof (buf), buf)) + strcpy (buf, "\\"); + + tmpdir = buf; + } + + _dbus_assert (tmpdir != NULL); + + return tmpdir; } -static -HANDLE _dbus_global_lock (const char *mutexname) +static HANDLE +_dbus_global_lock (const char *mutexname) { HANDLE mutex; DWORD gotMutex; - mutex = CreateMutex( NULL, FALSE, mutexname ); - if( !mutex ) + mutex = CreateMutex (NULL, FALSE, mutexname); + if (!mutex) { return FALSE; } - gotMutex = WaitForSingleObject( mutex, INFINITE ); - switch( gotMutex ) + gotMutex = WaitForSingleObject (mutex, INFINITE); + switch (gotMutex) { case WAIT_ABANDONED: ReleaseMutex (mutex); @@ -2816,300 +2237,396 @@ HANDLE _dbus_global_lock (const char *mutexname) return mutex; } -static -void _dbus_global_unlock (HANDLE mutex) +static void +_dbus_global_unlock (HANDLE mutex) { ReleaseMutex (mutex); - CloseHandle (mutex); + CloseHandle (mutex); } -// for proper cleanup in dbus-daemon +/* for proper cleanup in dbus-daemon */ static HANDLE hDBusDaemonMutex = NULL; static HANDLE hDBusSharedMem = NULL; -// sync _dbus_daemon_init, _dbus_daemon_uninit and _dbus_daemon_already_runs +/* Sync _dbus_publish_session_bus_address(), + * _dbus_unpublish_session_bus_address() and + * _dbus_daemon_already_runs() */ static const char *cUniqueDBusInitMutex = "UniqueDBusInitMutex"; -// sync _dbus_get_autolaunch_address +/* sync _dbus_get_autolaunch_address */ static const char *cDBusAutolaunchMutex = "DBusAutolaunchMutex"; -// mutex to determine if dbus-daemon is already started (per user) + +/* Note that Mutexes and File Mappings are in a per-session kernel + * namespace (unless explicitly put in the global namespace by + * prefixing their name with "Global\") so the use of the username in + * their names below is misguided and not needed. + * + * (And actually, *if* the names were global, we would need specify + * the session id in them, not the user name. A user can have several + * sessions. It's not easy (if possible at all) to achieve that with + * "normal" XP or Vista, but using Remote Desktop to a Windows Server + * it can easily happen either accidentally or on purpose.) + * + * So, we could use fixed names. But in order to interoperate with + * earlier builds of windbus keep using the same names. + */ + +/* Mutex to determine if dbus-daemon is already started. */ static const char *cDBusDaemonMutex = "DBusDaemonMutex"; -// named shm for dbus adress info (per user) + +/* Named shared file mapping for dbus adress info */ static const char *cDBusDaemonAddressInfo = "DBusDaemonAddressInfo"; void -_dbus_daemon_init(const char *host, dbus_uint32_t port) +_dbus_publish_session_bus_address (const char *address) { HANDLE lock; - const char *adr = NULL; + char *addr = NULL; char szUserName[64]; - DWORD dwUserNameSize = sizeof(szUserName); + DWORD dwUserNameSize = sizeof (szUserName); char szDBusDaemonMutex[128]; char szDBusDaemonAddressInfo[128]; - char szAddress[128]; - - _dbus_assert(host); - _dbus_assert(port); - _snprintf(szAddress, sizeof(szAddress) - 1, "tcp:host=%s,port=%d", host, port); + _dbus_assert (GetUserName (szUserName, &dwUserNameSize) != 0); - _dbus_assert( GetUserName(szUserName, &dwUserNameSize) != 0); - _snprintf(szDBusDaemonMutex, sizeof(szDBusDaemonMutex) - 1, "%s:%s", - cDBusDaemonMutex, szUserName); - _snprintf(szDBusDaemonAddressInfo, sizeof(szDBusDaemonAddressInfo) - 1, "%s:%s", - cDBusDaemonAddressInfo, szUserName); + _snprintf (szDBusDaemonMutex, sizeof (szDBusDaemonMutex) - 1, "%s:%s", + cDBusDaemonMutex, szUserName); + _snprintf (szDBusDaemonAddressInfo, sizeof (szDBusDaemonAddressInfo) - 1, "%s:%s", + cDBusDaemonAddressInfo, szUserName); - // before _dbus_global_lock to keep correct lock/release order - hDBusDaemonMutex = CreateMutex( NULL, FALSE, szDBusDaemonMutex ); + /* before _dbus_global_lock to keep correct lock/release order */ + hDBusDaemonMutex = CreateMutex (NULL, FALSE, szDBusDaemonMutex); - _dbus_assert(WaitForSingleObject( hDBusDaemonMutex, 1000 ) == WAIT_OBJECT_0); + _dbus_assert (WaitForSingleObject (hDBusDaemonMutex, 1000) == WAIT_OBJECT_0); - // sync _dbus_daemon_init, _dbus_daemon_uninit and _dbus_daemon_already_runs - lock = _dbus_global_lock( cUniqueDBusInitMutex ); + lock = _dbus_global_lock (cUniqueDBusInitMutex); - // create shm - hDBusSharedMem = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, - 0, strlen( szAddress ) + 1, szDBusDaemonAddressInfo ); - _dbus_assert( hDBusSharedMem ); + /* create shm */ + hDBusSharedMem = CreateFileMapping (INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, + 0, strlen (address) + 1, szDBusDaemonAddressInfo); + _dbus_assert (hDBusSharedMem); - adr = MapViewOfFile( hDBusSharedMem, FILE_MAP_WRITE, 0, 0, 0 ); + addr = MapViewOfFile (hDBusSharedMem, FILE_MAP_WRITE, 0, 0, 0); - _dbus_assert( adr ); + _dbus_assert (addr); - strcpy( (char*) adr, szAddress); + strcpy (addr, address); - // cleanup - UnmapViewOfFile( (char*) adr ); + UnmapViewOfFile (addr); - _dbus_global_unlock( lock ); + _dbus_global_unlock (lock); } void -_dbus_daemon_release() +_dbus_unpublish_session_bus_address (void) { HANDLE lock; - // sync _dbus_daemon_init, _dbus_daemon_uninit and _dbus_daemon_already_runs - lock = _dbus_global_lock( cUniqueDBusInitMutex ); + lock = _dbus_global_lock (cUniqueDBusInitMutex); - CloseHandle( hDBusSharedMem ); + CloseHandle (hDBusSharedMem); hDBusSharedMem = NULL; - ReleaseMutex( hDBusDaemonMutex ); + ReleaseMutex (hDBusDaemonMutex); - CloseHandle( hDBusDaemonMutex ); + CloseHandle (hDBusDaemonMutex); hDBusDaemonMutex = NULL; - _dbus_global_unlock( lock ); + _dbus_global_unlock (lock); } static dbus_bool_t -_dbus_get_autolaunch_shm(DBusString *adress) +_dbus_get_autolaunch_shm (DBusString *address) { HANDLE sharedMem; - const char *adr; + char *addr; char szUserName[64]; - DWORD dwUserNameSize = sizeof(szUserName); + DWORD dwUserNameSize = sizeof (szUserName); char szDBusDaemonAddressInfo[128]; - if( !GetUserName(szUserName, &dwUserNameSize) ) - return FALSE; - _snprintf(szDBusDaemonAddressInfo, sizeof(szDBusDaemonAddressInfo) - 1, "%s:%s", - cDBusDaemonAddressInfo, szUserName); + if (!GetUserName (szUserName, &dwUserNameSize)) + return FALSE; - // read shm - do { - // we know that dbus-daemon is available, so we wait until shm is available - sharedMem = OpenFileMapping( FILE_MAP_READ, FALSE, szDBusDaemonAddressInfo ); - if( sharedMem == 0 ) - Sleep( 100 ); - } while( sharedMem == 0 ); + _snprintf (szDBusDaemonAddressInfo, sizeof (szDBusDaemonAddressInfo)-1, "%s:%s", + cDBusDaemonAddressInfo, szUserName); - if( sharedMem == 0 ) - return FALSE; + do { + /* we know that dbus-daemon is available, so we wait until shm is available */ + sharedMem = OpenFileMapping (FILE_MAP_READ, FALSE, szDBusDaemonAddressInfo); + if (sharedMem == NULL) + Sleep (100); + } while (sharedMem == NULL); - adr = MapViewOfFile( sharedMem, FILE_MAP_READ, 0, 0, 0 ); + addr = MapViewOfFile (sharedMem, FILE_MAP_READ, 0, 0, 0); - if( adr == 0 ) - return FALSE; + if (addr == NULL) + return FALSE; - _dbus_string_init( adress ); + _dbus_string_init (address); - _dbus_string_append( adress, adr ); + _dbus_string_append (address, addr); - // cleanup - UnmapViewOfFile( (char*) adr ); + UnmapViewOfFile (addr); - CloseHandle( sharedMem ); + CloseHandle (sharedMem); return TRUE; } static dbus_bool_t -_dbus_daemon_already_runs (DBusString *adress) +_dbus_daemon_already_runs (DBusString *address) { HANDLE lock; HANDLE daemon; dbus_bool_t bRet = TRUE; char szUserName[64]; - DWORD dwUserNameSize = sizeof(szUserName); + DWORD dwUserNameSize = sizeof (szUserName); char szDBusDaemonMutex[128]; - // sync _dbus_daemon_init, _dbus_daemon_uninit and _dbus_daemon_already_runs - lock = _dbus_global_lock( cUniqueDBusInitMutex ); + lock = _dbus_global_lock (cUniqueDBusInitMutex); - if( !GetUserName(szUserName, &dwUserNameSize) ) - return FALSE; - _snprintf(szDBusDaemonMutex, sizeof(szDBusDaemonMutex) - 1, "%s:%s", - cDBusDaemonMutex, szUserName); + if (!GetUserName (szUserName, &dwUserNameSize)) + return FALSE; + + _snprintf (szDBusDaemonMutex, sizeof (szDBusDaemonMutex)-1, "%s:%s", + cDBusDaemonMutex, szUserName); - // do checks - daemon = CreateMutex( NULL, FALSE, szDBusDaemonMutex ); - if(WaitForSingleObject( daemon, 10 ) != WAIT_TIMEOUT) + daemon = CreateMutex (NULL, FALSE, szDBusDaemonMutex); + if (WaitForSingleObject (daemon, 10) != WAIT_TIMEOUT) { ReleaseMutex (daemon); CloseHandle (daemon); - _dbus_global_unlock( lock ); + _dbus_global_unlock (lock); return FALSE; } - // read shm - bRet = _dbus_get_autolaunch_shm( adress ); + bRet = _dbus_get_autolaunch_shm (address); - // cleanup - CloseHandle ( daemon ); + CloseHandle (daemon); - _dbus_global_unlock( lock ); + _dbus_global_unlock (lock); return bRet; } +static dbus_bool_t +_dbus_get_install_root (char *s, int len) +{ + char *p = NULL; + int ret = GetModuleFileName (_dbus_win_get_dll_hmodule (), s, len); + if (ret == 0 || + (ret == len && GetLastError () == ERROR_INSUFFICIENT_BUFFER)) + { + *s = '\0'; + return FALSE; + } + p = _mbsrchr (s, '\\'); + if (!p) + return FALSE; + *p = '\0'; + p = _mbsrchr (s, '\\'); + if (!p) + return FALSE; + if (strcmp (p+1, "bin") == 0) + { + *p = '\0'; + return TRUE; + } + else + { + *s = '\0'; + return FALSE; + } +} + dbus_bool_t -_dbus_get_autolaunch_address (DBusString *address, +_dbus_get_autolaunch_address (DBusString *address, DBusError *error) { HANDLE mutex; STARTUPINFOA si; PROCESS_INFORMATION pi; dbus_bool_t retval = FALSE; - LPSTR lpFile; - char dbus_exe_path[MAX_PATH]; + char dbus_daemon_path[MAX_PATH * 2]; char dbus_args[MAX_PATH * 2]; - mutex = _dbus_global_lock ( cDBusAutolaunchMutex ); + mutex = _dbus_global_lock (cDBusAutolaunchMutex); _DBUS_ASSERT_ERROR_IS_CLEAR (error); - if (_dbus_daemon_already_runs(address)) + if (_dbus_daemon_already_runs (address)) { - printf("dbus daemon already exists\n"); + _dbus_verbose ("dbus daemon already exists\n"); retval = TRUE; goto out; } - if (!SearchPathA(NULL, "dbus-daemon.exe", NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile)) - { - printf ("could not find dbus-daemon executable\n"); - goto out; - } + _dbus_get_install_root (dbus_daemon_path, MAX_PATH); + strcat (dbus_daemon_path, "\\bin\\dbus-daemon.exe"); - // Create process - ZeroMemory( &si, sizeof(si) ); - si.cb = sizeof(si); - ZeroMemory( &pi, sizeof(pi) ); + ZeroMemory (&si, sizeof (si)); + si.cb = sizeof (si); + ZeroMemory (&pi, sizeof (pi)); - _snprintf(dbus_args, sizeof(dbus_args) - 1, "\"%s\" %s", dbus_exe_path, " --session"); + _snprintf (dbus_args, sizeof (dbus_args) - 1, "\"%s\" %s", dbus_daemon_path, " --session --publish-address"); -// argv[i] = "--config-file=bus\\session.conf"; - printf("create process \"%s\" %s\n", dbus_exe_path, dbus_args); - if(CreateProcessA(dbus_exe_path, dbus_args, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) + _dbus_verbose ("CreateProcess %s\n", dbus_args); + if (CreateProcessA (dbus_daemon_path, dbus_args, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { retval = TRUE; - // Wait until started (see _dbus_get_autolaunch_shm()) - WaitForInputIdle(pi.hProcess, INFINITE); + /* Wait until started (see _dbus_get_autolaunch_shm()) */ + WaitForInputIdle (pi.hProcess, INFINITE); - retval = _dbus_get_autolaunch_shm( address ); - } else { + retval = _dbus_get_autolaunch_shm (address); + } + else + { retval = FALSE; } - + out: if (retval) _DBUS_ASSERT_ERROR_IS_CLEAR (error); else _DBUS_ASSERT_ERROR_IS_SET (error); - + _dbus_global_unlock (mutex); return retval; } +static dbus_uint32_t +fromAscii (char ascii) +{ + if (ascii >= '0' && ascii <= '9') + return ascii - '0'; + if (ascii >= 'A' && ascii <= 'F') + return ascii - 'A' + 10; + if (ascii >= 'a' && ascii <= 'f') + return ascii - 'a' + 10; + return 0; +} -/** Makes the file readable by every user in the system. - * - * @param filename the filename - * @param error error location - * @returns #TRUE if the file's permissions could be changed. - */ dbus_bool_t -_dbus_make_file_world_readable(const DBusString *filename, - DBusError *error) +_dbus_read_local_machine_uuid (DBusGUID *machine_id, + dbus_bool_t create_if_not_found, + DBusError *error) { - // TODO +#ifdef DBUS_WINCE + /* TODO */ return TRUE; -} +#else + HW_PROFILE_INFOA info; + char *lpc = &info.szHwProfileGuid[0]; + dbus_uint32_t u; + /* the hw-profile guid lives long enough */ + if (!GetCurrentHwProfileA (&info)) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); /* FIXME */ + return FALSE; + } -#define DBUS_STANDARD_SESSION_SERVICEDIR "/dbus-1/services" -#define DBUS_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services" + /* Form: {12340001-4980-1920-6788-123456789012} */ + lpc++; + /* 12340001 */ + u = ((fromAscii (lpc[0]) << 0) | + (fromAscii (lpc[1]) << 4) | + (fromAscii (lpc[2]) << 8) | + (fromAscii (lpc[3]) << 12) | + (fromAscii (lpc[4]) << 16) | + (fromAscii (lpc[5]) << 20) | + (fromAscii (lpc[6]) << 24) | + (fromAscii (lpc[7]) << 28)); + machine_id->as_uint32s[0] = u; + + lpc += 9; + /* 4980-1920 */ + u = ((fromAscii (lpc[0]) << 0) | + (fromAscii (lpc[1]) << 4) | + (fromAscii (lpc[2]) << 8) | + (fromAscii (lpc[3]) << 12) | + (fromAscii (lpc[5]) << 16) | + (fromAscii (lpc[6]) << 20) | + (fromAscii (lpc[7]) << 24) | + (fromAscii (lpc[8]) << 28)); + machine_id->as_uint32s[1] = u; + + lpc += 10; + /* 6788-1234 */ + u = ((fromAscii (lpc[0]) << 0) | + (fromAscii (lpc[1]) << 4) | + (fromAscii (lpc[2]) << 8) | + (fromAscii (lpc[3]) << 12) | + (fromAscii (lpc[5]) << 16) | + (fromAscii (lpc[6]) << 20) | + (fromAscii (lpc[7]) << 24) | + (fromAscii (lpc[8]) << 28)); + machine_id->as_uint32s[2] = u; + + lpc += 9; + /* 56789012 */ + u = ((fromAscii (lpc[0]) << 0) | + (fromAscii (lpc[1]) << 4) | + (fromAscii (lpc[2]) << 8) | + (fromAscii (lpc[3]) << 12) | + (fromAscii (lpc[4]) << 16) | + (fromAscii (lpc[5]) << 20) | + (fromAscii (lpc[6]) << 24) | + (fromAscii (lpc[7]) << 28)); + machine_id->as_uint32s[3] = u; +#endif + return TRUE; +} -/** - * Returns the standard directories for a session bus to look for service - * activation files - * - * On Windows this should be data directories: - * - * %CommonProgramFiles%/dbus - * - * and - * - * DBUS_DATADIR - * - * @param dirs the directory list we are returning - * @returns #FALSE on OOM - */ +#define DBUS_STANDARD_SESSION_SERVICEDIR "\\dbus-1\\services" -dbus_bool_t +dbus_bool_t _dbus_get_standard_session_servicedirs (DBusList **dirs) { + const char *app_data; const char *common_progs; DBusString servicedir_path; if (!_dbus_string_init (&servicedir_path)) return FALSE; - if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR _DBUS_PATH_SEPARATOR)) + app_data = _dbus_getenv ("APPDATA"); + + if (app_data != NULL) + { + DBusString dbus; + + if (!_dbus_string_append (&servicedir_path, app_data)) goto oom; - common_progs = _dbus_getenv ("CommonProgramFiles"); + _dbus_string_init_const (&dbus, "dbus"); - if (common_progs != NULL) - { - if (!_dbus_string_append (&servicedir_path, common_progs)) + if (!_dbus_concat_dir_and_file (&servicedir_path, &dbus)) goto oom; + _dbus_string_free (&dbus); + if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR)) goto oom; } - if (!_dbus_split_paths_and_append (&servicedir_path, - DBUS_STANDARD_SESSION_SERVICEDIR, - dirs)) + common_progs = _dbus_getenv ("COMMONPROGRAMFILES"); + + if (common_progs != NULL) + { + if (!_dbus_string_append (&servicedir_path, common_progs)) + goto oom; + } + + if (!_dbus_split_paths_and_append (&servicedir_path, + DBUS_STANDARD_SESSION_SERVICEDIR, + dirs)) goto oom; - _dbus_string_free (&servicedir_path); + _dbus_string_free (&servicedir_path); return TRUE; oom: @@ -3117,248 +2634,297 @@ _dbus_get_standard_session_servicedirs (DBusList **dirs) return FALSE; } -_DBUS_DEFINE_GLOBAL_LOCK (atomic); - -/** - * Atomically increments an integer - * - * @param atomic pointer to the integer to increment - * @returns the value before incrementing - * - */ -dbus_int32_t -_dbus_atomic_inc (DBusAtomic *atomic) -{ - // +/- 1 is needed here! - // no volatile argument with mingw - return InterlockedIncrement (&atomic->value) - 1; -} - -/** - * Atomically decrement an integer - * - * @param atomic pointer to the integer to decrement - * @returns the value before decrementing - * - */ -dbus_int32_t -_dbus_atomic_dec (DBusAtomic *atomic) -{ - // +/- 1 is needed here! - // no volatile argument with mingw - return InterlockedDecrement (&atomic->value) + 1; -} - -#endif /* asserts or tests enabled */ - -/** - * Called when the bus daemon is signaled to reload its configuration; any - * caches should be nuked. Of course any caches that need explicit reload - * are probably broken, but c'est la vie. - * - * - */ -void -_dbus_flush_caches (void) -{ - -} - -dbus_bool_t _dbus_windows_user_is_process_owner (const char *windows_sid) +dbus_bool_t +_dbus_get_standard_system_servicedirs (DBusList **dirs) { - return TRUE; + return FALSE; } -/** - * See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently - * for Winsock so is abstracted) - * - * @returns #TRUE if errno == EAGAIN or errno == EWOULDBLOCK - */ dbus_bool_t -_dbus_get_is_errno_eagain_or_ewouldblock (void) +_dbus_append_system_config_file (DBusString *str) { - return errno == EAGAIN || errno == EWOULDBLOCK; + return FALSE; } /** - * return the absolute path of the dbus installation - * - * @param s buffer for installation path - * @param len length of buffer - * @returns #FALSE on failure - */ -dbus_bool_t -_dbus_get_install_root(char *s, int len) -{ - char *p = NULL; - int ret = GetModuleFileName(NULL,s,len); - if ( ret == 0 - || ret == len && GetLastError() == ERROR_INSUFFICIENT_BUFFER) - { - *s = '\0'; - return FALSE; - } - else if ((p = strstr(s,"\\bin\\"))) - { - *(p+1)= '\0'; - return TRUE; - } - else - { - *s = '\0'; - return FALSE; - } -} - -/** - find config file either from installation or build root according to - the following path layout + find config file from installation root according to + the following path layout install-root/ bin/dbus-daemon[d].exe - etc/.conf - - build-root/ - bin/dbus-daemon[d].exe - bus/.conf + etc/.conf */ -dbus_bool_t -_dbus_get_config_file_name(DBusString *config_file, char *s) +static dbus_bool_t +_dbus_get_config_file_name (DBusString *config_file, char *s) { - char path[MAX_PATH*2]; - int path_size = sizeof(path); + char config_file_path[MAX_PATH * 2]; - if (!_dbus_get_install_root(path,path_size)) + if (!_dbus_get_install_root (config_file_path, sizeof (config_file_path) - strlen ("\\etc\\dbus-1\\") - strlen (s) - 1)) + return FALSE; + + strcat (config_file_path, "\\etc\\dbus-1\\"); + strcat (config_file_path, s); + + if (!_dbus_string_append (config_file, config_file_path)) return FALSE; - strcat_s(path,path_size,"etc\\"); - strcat_s(path,path_size,s); - if (_dbus_file_exists(path)) - { - // find path from executable - if (!_dbus_string_append (config_file, path)) - return FALSE; - } - else - { - if (!_dbus_get_install_root(path,path_size)) - return FALSE; - strcat_s(path,path_size,"bus\\"); - strcat_s(path,path_size,s); - - if (_dbus_file_exists(path)) - { - if (!_dbus_string_append (config_file, path)) - return FALSE; - } - } return TRUE; -} +} -/** - * Append the absolute path of the system.conf file - * (there is no system bus on Windows so this can just - * return FALSE and print a warning or something) - * - * @param str the string to append to - * @returns #FALSE if no memory - */ dbus_bool_t -_dbus_append_system_config_file (DBusString *str) +_dbus_append_session_config_file (DBusString *str) { - return _dbus_get_config_file_name(str, "system.conf"); + return _dbus_get_config_file_name (str, "session.conf"); } -/** - * Append the absolute path of the session.conf file. - * - * @param str the string to append to - * @returns #FALSE if no memory - */ -dbus_bool_t -_dbus_append_session_config_file (DBusString *str) +void +_dbus_flush_caches (void) { - return _dbus_get_config_file_name(str, "session.conf"); } -/** - * Appends the directory in which a keyring for the given credentials - * should be stored. The credentials should have either a Windows or - * UNIX user in them. The directory should be an absolute path. - * - * On UNIX the directory is ~/.dbus-keyrings while on Windows it should probably - * be something else, since the dotfile convention is not normal on Windows. - * - * @param directory string to append directory to - * @param credentials credentials the directory should be for - * - * @returns #FALSE on no memory - */ dbus_bool_t _dbus_append_keyring_directory_for_credentials (DBusString *directory, DBusCredentials *credentials) { - DBusString homedir; - DBusString dotdir; - dbus_uid_t uid; - const char *homepath; + DBusString dir; + DBusString keyringsdir; + const char *app_data; _dbus_assert (credentials != NULL); _dbus_assert (!_dbus_credentials_are_anonymous (credentials)); - - if (!_dbus_string_init (&homedir)) + + if (!_dbus_string_init (&dir)) return FALSE; - homepath = _dbus_getenv("HOMEPATH"); - if (homepath != NULL && *homepath != '\0') + app_data = _dbus_getenv ("APPDATA"); + if (app_data != NULL && *app_data != '\0') { - _dbus_string_append(&homedir,homepath); + _dbus_string_append (&dir, app_data); } - + #ifdef DBUS_BUILD_TESTS { const char *override; - + override = _dbus_getenv ("DBUS_TEST_HOMEDIR"); if (override != NULL && *override != '\0') { - _dbus_string_set_length (&homedir, 0); - if (!_dbus_string_append (&homedir, override)) + _dbus_string_set_length (&dir, 0); + if (!_dbus_string_append (&dir, override)) goto failed; - _dbus_verbose ("Using fake homedir for testing: %s\n", - _dbus_string_get_const_data (&homedir)); + _dbus_verbose ("using fake homedir for testing: %s\n", + _dbus_string_get_const_data (&dir)); } else { static dbus_bool_t already_warned = FALSE; if (!already_warned) { - _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n"); + _dbus_warn ("Using your real profile folder for testing, set DBUS_TEST_HOMEDIR to avoid\n"); already_warned = TRUE; } } } #endif - _dbus_string_init_const (&dotdir, ".dbus-keyrings"); - if (!_dbus_concat_dir_and_file (&homedir, - &dotdir)) + _dbus_string_init_const (&keyringsdir, "dbus"); + + if (!_dbus_concat_dir_and_file (&dir, &keyringsdir)) goto failed; - - if (!_dbus_string_copy (&homedir, 0, - directory, _dbus_string_get_length (directory))) { + + if (!_dbus_create_directory (&dir, NULL)) goto failed; - } - _dbus_string_free (&homedir); + _dbus_string_free (&keyringsdir); + _dbus_string_init_const (&keyringsdir, "keyrings"); + + if (!_dbus_concat_dir_and_file (&dir, &keyringsdir)) + goto failed; + + if (!_dbus_string_copy (&dir, 0, directory, _dbus_string_get_length (directory))) + goto failed; + + _dbus_string_free (&dir); + _dbus_string_free (&keyringsdir); return TRUE; - - failed: - _dbus_string_free (&homedir); + + failed: + _dbus_string_free (&dir); + _dbus_string_free (&keyringsdir); return FALSE; } -/** @} end of sysdeps-win */ -/* tests in dbus-sysdeps-util.c */ +dbus_bool_t +_dbus_get_is_errno_eagain_or_ewouldblock (void) +{ + return errno == EAGAIN || errno == WSAEWOULDBLOCK; +} + +/** + * Returns the UTF-16 form of a UTF-8 string. The result should be + * freed with dbus_free() when no longer needed. + * + * @param str the UTF-8 string + * @param error return location for error code + */ +wchar_t * +_dbus_win_utf8_to_utf16 (const char *str, + DBusError *error) +{ + DBusString s; + int n; + wchar_t *retval; + + _dbus_string_init_const (&s, str); + + if (!_dbus_string_validate_utf8 (&s, 0, _dbus_string_get_length (&s))) + { + dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid UTF-8"); + return NULL; + } + + n = MultiByteToWideChar (CP_UTF8, 0, str, -1, NULL, 0); + + if (n == 0) + { + _dbus_win_set_error_from_win_error (error, GetLastError ()); + return NULL; + } + + retval = dbus_new (wchar_t, n); + + if (!retval) + { + _DBUS_SET_OOM (error); + return NULL; + } + + if (MultiByteToWideChar (CP_UTF8, 0, str, -1, retval, n) != n) + { + dbus_free (retval); + dbus_set_error_const (error, DBUS_ERROR_FAILED, "MultiByteToWideChar inconsistency"); + return NULL; + } + + return retval; +} + +dbus_bool_t +_dbus_win_account_to_sid (const wchar_t *waccount, + void **ppsid, + DBusError *error) +{ + dbus_bool_t retval = FALSE; + DWORD sid_length, wdomain_length; + SID_NAME_USE use; + wchar_t *wdomain; + + *ppsid = NULL; + + sid_length = 0; + wdomain_length = 0; + if (!LookupAccountNameW (NULL, waccount, NULL, &sid_length, + NULL, &wdomain_length, &use) && + GetLastError () != ERROR_INSUFFICIENT_BUFFER) + { + _dbus_win_set_error_from_win_error (error, GetLastError ()); + return FALSE; + } + + *ppsid = dbus_malloc (sid_length); + if (!*ppsid) + { + _DBUS_SET_OOM (error); + return FALSE; + } + + wdomain = dbus_new (wchar_t, wdomain_length); + if (!wdomain) + { + _DBUS_SET_OOM (error); + goto out1; + } + + if (!LookupAccountNameW (NULL, waccount, (PSID) *ppsid, &sid_length, + wdomain, &wdomain_length, &use)) + { + _dbus_win_set_error_from_win_error (error, GetLastError ()); + goto out2; + } + + if (!IsValidSid ((PSID) *ppsid)) + { + dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid SID"); + goto out2; + } + + retval = TRUE; + +out2: + dbus_free (wdomain); +out1: + if (!retval) + { + dbus_free (*ppsid); + *ppsid = NULL; + } + + return retval; +} + +/** Gets our SID + * @param points to sid buffer, need to be freed with LocalFree() + * @returns process sid + */ +static dbus_bool_t +_dbus_getsid (char **sid) +{ + HANDLE process_token = NULL; + TOKEN_USER *token_user = NULL; + DWORD n; + PSID psid; + int retval = FALSE; + + if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &process_token)) + { + _dbus_win_warn_win_error ("OpenProcessToken failed", GetLastError ()); + goto failed; + } + if ((!GetTokenInformation (process_token, TokenUser, NULL, 0, &n) + && GetLastError () != ERROR_INSUFFICIENT_BUFFER) + || (token_user = alloca (n)) == NULL + || !GetTokenInformation (process_token, TokenUser, token_user, n, &n)) + { + _dbus_win_warn_win_error ("GetTokenInformation failed", GetLastError ()); + goto failed; + } + psid = token_user->User.Sid; + if (!IsValidSid (psid)) + { + _dbus_verbose ("%s invalid sid\n", __FUNCTION__); + goto failed; + } + if (!ConvertSidToStringSidA (psid, sid)) + { + _dbus_verbose ("%s invalid sid\n", __FUNCTION__); + goto failed; + } + retval = TRUE; + +failed: + if (process_token != NULL) + CloseHandle (process_token); + + _dbus_verbose ("_dbus_getsid() returns %d\n", retval); + return retval; +} +dbus_bool_t +_dbus_credentials_add_from_user (DBusCredentials *credentials, + const DBusString *username) +{ + return _dbus_credentials_add_windows_sid (credentials, + _dbus_string_get_const_data (username)); +} + +/* tests in dbus-sysdeps-util.c */ diff --git a/dbus/dbus-sysdeps-win.h b/dbus/dbus-sysdeps-win.h index d2ce08a..5c2ecf8 100644 --- a/dbus/dbus-sysdeps-win.h +++ b/dbus/dbus-sysdeps-win.h @@ -26,42 +26,16 @@ #ifndef DBUS_SYSDEPS_WIN_H #define DBUS_SYSDEPS_WIN_H -#define _WINSOCKAPI_ +extern void *_dbus_win_get_dll_hmodule (void); -#include "dbus-hash.h" -#include "dbus-string.h" -#include -#include -#include -#undef interface +void _dbus_daemon_publish_address (const char *address); -#include -#include -#include -#include -#include +void _dbus_daemon_release (void); -#define mkdir(path, mode) _mkdir (path) - -#ifndef DBUS_WINCE -#ifndef S_ISREG -#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) -#endif -#endif - -/* Declarations missing in mingw's headers */ -extern BOOL WINAPI ConvertStringSidToSidA (LPCSTR StringSid, PSID *Sid); -extern BOOL WINAPI ConvertSidToStringSidA (PSID Sid, LPSTR *StringSid); - - -#define DBUS_CONSOLE_DIR "/var/run/console/" - - -void _dbus_win_startup_winsock (void); void _dbus_win_warn_win_error (const char *message, int code); -extern const char* _dbus_lm_strerror (int error_number); +const char* _dbus_error_from_wsaerror (int error_number); dbus_bool_t _dbus_win_account_to_sid (const wchar_t *waccount, void **ppsid, @@ -73,56 +47,15 @@ _dbus_win32_sid_to_name_and_domain (dbus_uid_t uid, wchar_t **wdomain, DBusError *error); - -/* Don't define DBUS_CONSOLE_DIR on Win32 */ - wchar_t *_dbus_win_utf8_to_utf16 (const char *str, DBusError *error); -char *_dbus_win_utf16_to_utf8 (const wchar_t *str, - DBusError *error); void _dbus_win_set_error_from_win_error (DBusError *error, int code); -dbus_bool_t -_dbus_win_sid_to_name_and_domain (dbus_uid_t uid, - wchar_t **wname, - wchar_t **wdomain, - DBusError *error); - -typedef struct DBusFile DBusFile; - -dbus_bool_t _dbus_file_open (DBusFile *file, - const char *filename, - int oflag, - int pmode); - -dbus_bool_t _dbus_file_close (DBusFile *file, - DBusError *error); - - -int _dbus_file_read (DBusFile *file, - DBusString *buffer, - int count); - -int _dbus_file_write (DBusFile *file, - const DBusString *buffer, - int start, - int len); - -dbus_bool_t _dbus_file_exists (const char *filename); - - -#define FDATA private_data -struct DBusFile - { - int FDATA; - }; - - -dbus_bool_t _dbus_get_config_file_name(DBusString *config_file, - char *s); - - +dbus_bool_t _dbus_win_sid_to_name_and_domain (dbus_uid_t uid, + wchar_t **wname, + wchar_t **wdomain, + DBusError *error); #endif diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c index d740f87..937a139 100644 --- a/dbus/dbus-sysdeps.c +++ b/dbus/dbus-sysdeps.c @@ -191,7 +191,9 @@ _dbus_clearenv (void) if (clearenv () != 0) rc = FALSE; #else +#ifndef DBUS_WIN extern char **environ; +#endif if (environ != NULL) environ[0] = NULL; @@ -210,7 +212,9 @@ char ** _dbus_get_environment (void) { int i, length; +#ifndef DBUS_WIN extern char **environ; +#endif char **environment; _dbus_assert (environ != NULL); diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index 80236f0..b5bf730 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -411,6 +411,9 @@ dbus_bool_t _dbus_write_pid_to_file_and_pipe (const DBusString *pidfile, dbus_pid_t pid_to_write, DBusError *error); +void _dbus_publish_session_bus_address (const char *address); +void _dbus_unpublish_session_bus_address (void); + /** A UNIX signal handler */ typedef void (* DBusSignalHandler) (int sig); diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c index 9029198..d276927 100644 --- a/dbus/dbus-transport.c +++ b/dbus/dbus-transport.c @@ -635,7 +635,7 @@ auth_via_default_rules (DBusTransport *transport) { if (_dbus_credentials_include(our_identity,DBUS_CREDENTIAL_WINDOWS_SID)) _dbus_verbose ("Client authorized as SID '%s'" - "matching our SID '%s'\n", + " matching our SID '%s'\n", _dbus_credentials_get_windows_sid(auth_identity), _dbus_credentials_get_windows_sid(our_identity)); else @@ -651,12 +651,14 @@ auth_via_default_rules (DBusTransport *transport) if (_dbus_credentials_include(our_identity,DBUS_CREDENTIAL_WINDOWS_SID)) _dbus_verbose ("Client authorized as SID '%s'" " but our SID is '%s', disconnecting\n", - _dbus_credentials_get_windows_sid(our_identity), - _dbus_credentials_get_windows_sid(our_identity)); + (_dbus_credentials_get_windows_sid(auth_identity) ? + _dbus_credentials_get_windows_sid(auth_identity) : ""), + (_dbus_credentials_get_windows_sid(our_identity) ? + _dbus_credentials_get_windows_sid(our_identity) : "")); else _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT " but our UID is "DBUS_UID_FORMAT", disconnecting\n", - _dbus_credentials_get_unix_uid(our_identity), + _dbus_credentials_get_unix_uid(auth_identity), _dbus_credentials_get_unix_uid(our_identity)); _dbus_transport_disconnect (transport); allow = FALSE; diff --git a/test/test-sleep-forever.c b/test/test-sleep-forever.c index ff0d8e2..7f56b60 100644 --- a/test/test-sleep-forever.c +++ b/test/test-sleep-forever.c @@ -5,12 +5,21 @@ #ifdef HAVE_UNISTD_H #include #endif +#ifdef _WIN32 +#include +#endif int main (int argc, char **argv) { while (1) - sleep (10000000); + { +#ifdef _WIN32 + Sleep (10000000); +#else + sleep (10000000); +#endif + } return 1; } diff --git a/tools/Makefile.am b/tools/Makefile.am index 9fad7a7..be6277f 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -2,7 +2,10 @@ configdir=$(sysconfdir)/dbus-1 INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_X_CFLAGS) -DDBUS_LOCALEDIR=\"@EXPANDED_DATADIR@/locale\" -DDBUS_COMPILATION -DDBUS_DAEMONDIR=\"@DBUS_DAEMONDIR@\" -DDBUS_MACHINE_UUID_FILE=\""$(localstatedir)/lib/dbus/machine-id"\" -bin_PROGRAMS=dbus-send dbus-monitor dbus-launch dbus-cleanup-sockets dbus-uuidgen +bin_PROGRAMS=dbus-send dbus-monitor dbus-launch +if DBUS_UNIX +bin_PROGRAMS+=dbus-cleanup-sockets dbus-uuidgen +endif dbus_send_SOURCES= \ dbus-print-message.c \ @@ -14,10 +17,17 @@ dbus_monitor_SOURCES= \ dbus-print-message.c \ dbus-print-message.h +if DBUS_UNIX dbus_launch_SOURCES= \ dbus-launch.c \ dbus-launch-x11.c \ dbus-launch.h +endif + +if DBUS_WIN +dbus_launch_SOURCES= \ + dbus-launch-win.c +endif dbus_cleanup_sockets_SOURCES= \ dbus-cleanup-sockets.c diff --git a/tools/dbus-launch-win.c b/tools/dbus-launch-win.c index 4d56319..103ba10 100644 --- a/tools/dbus-launch-win.c +++ b/tools/dbus-launch-win.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #if defined __MINGW32__ || (defined _MSC_VER && _MSC_VER <= 1310) @@ -30,22 +31,36 @@ */ #define errno_t int -errno_t strcat_s(char *dest, size_t size, char *src) +errno_t +strcat_s (char *dest, size_t size, char *src) { - assert(strlen(dest) + strlen(src) +1 <= size); - strcat(dest,src); + assert (strlen (dest) + strlen (src) +1 <= size); + strcat (dest,src); return 0; } -errno_t strcpy_s(char *dest, size_t size, char *src) +errno_t +strcpy_s (char *dest, size_t size, char *src) { - assert(strlen(src) +1 <= size); - strcpy(dest,src); + assert (strlen (src) +1 <= size); + strcpy (dest,src); return 0; } #endif -/* TODO: use unicode version as suggested by Tor Lillqvist */ +/* TODO: Use Unicode APIs */ + +/* TODO: This Windows version of dbus-launch is curretly rather + * pointless as it doesn't take the same command-line options as the + * UNIX dbus-launch does. A main point of the dbus-launch command is + * to pass it for instance a --config-file option to make the started + * dbus-daemon use that config file. + * + * This version also doesn't print out any information, which is a + * main point of the UNIX one. It should at least support the + * --sh-syntax option, and maybe also a --cmd-syntax to print out the + * variable settings in cmd.exe syntax? + */ #define AUTO_ACTIVATE_CONSOLE_WHEN_VERBOSE_MODE 1 @@ -67,16 +82,16 @@ int main(int argc,char **argv) if (verbose) showConsole = 1; #endif - GetModuleFileName(NULL,dbusDaemonPath,sizeof(dbusDaemonPath)); + GetModuleFileName (NULL, dbusDaemonPath, sizeof (dbusDaemonPath)); /* check for debug version */ - if (strstr(dbusDaemonPath,"dbus-launchd.exe")) + if (strstr (dbusDaemonPath, "dbus-launchd.exe")) daemon_name = "dbus-daemond.exe"; else daemon_name = "dbus-daemon.exe"; - if ((p = strrchr(dbusDaemonPath,'\\'))) + if ((p = _mbsrchr (dbusDaemonPath, '\\'))) { *(p+1)= '\0'; - strcat_s(dbusDaemonPath,sizeof(dbusDaemonPath),daemon_name); + strcat_s (dbusDaemonPath, sizeof (dbusDaemonPath), daemon_name); } else { @@ -85,33 +100,34 @@ int main(int argc,char **argv) return 1; } - strcpy_s(command,sizeof(command),dbusDaemonPath); - strcat_s(command,sizeof(command)," --session"); + strcpy_s (command, sizeof (command), dbusDaemonPath); + strcat_s (command, sizeof(command), " --session"); + if (verbose) fprintf(stderr,"%s\n",command); - memset(&si, 0, sizeof(si)); - memset(&pi, 0, sizeof(pi)); - si.cb = sizeof(si); + memset (&si, 0, sizeof (si)); + memset (&pi, 0, sizeof (pi)); + si.cb = sizeof (si); - result = CreateProcess(NULL, - command, - 0, - 0, - TRUE, - (showConsole ? CREATE_NEW_CONSOLE : 0) | NORMAL_PRIORITY_CLASS, - 0, - 0, - &si, - &pi); + result = CreateProcess (NULL, + command, + 0, + 0, + TRUE, + (showConsole ? CREATE_NEW_CONSOLE : 0) | NORMAL_PRIORITY_CLASS, + 0, + 0, + &si, + &pi); - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); + CloseHandle (pi.hProcess); + CloseHandle (pi.hThread); if (result == 0) { if (verbose) - fprintf(stderr,"could not start dbus-daemon error=%d",GetLastError()); + fprintf(stderr, "Could not start dbus-daemon error=%d",GetLastError()); return 4; } diff --git a/tools/dbus-launch.c b/tools/dbus-launch.c index 216f743..139d0aa 100644 --- a/tools/dbus-launch.c +++ b/tools/dbus-launch.c @@ -402,7 +402,9 @@ signal_handler (int sig) { switch (sig) { +#ifdef SIGHUP case SIGHUP: +#endif case SIGTERM: got_sighup = TRUE; break;