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;