#define STRSAFE_NO_DEPRECATE
#ifndef DBUS_WINCE
-#define _WIN32_WINNT 0x0500
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0501
+#endif
#endif
#include "dbus-internals.h"
#include "dbus-credentials.h"
#include <windows.h>
+#include <ws2tcpip.h>
#include <fcntl.h>
#include <process.h>
+#include <stdio.h>
+#include <io.h>
+
+#include <string.h>
+#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#define O_BINARY 0
#endif
-#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)
-{
- 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;
- }
-}
-
-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;
- }
-
- file->FDATA = -1;
- _dbus_verbose ("closed C file descriptor %d:\n",fd);
-
- return TRUE;
-}
-
-int
-_dbus_file_read(DBusFile *file,
- DBusString *buffer,
- int count)
-{
- const int fd = file->FDATA;
- int bytes_read;
- int start;
- char *data;
- _dbus_assert (count >= 0);
-
- start = _dbus_string_get_length (buffer);
-
- if (!_dbus_string_lengthen (buffer, count))
- {
- errno = ENOMEM;
- return -1;
- }
-
- data = _dbus_string_get_data_len (buffer, start, count);
-
- _dbus_assert (fd >= 0);
-
- _dbus_verbose ("read: count=%d fd=%d\n", count, fd);
- bytes_read = read (fd, data, count);
-
- if (bytes_read == -1)
- _dbus_verbose ("read: failed: %s\n", _dbus_strerror (errno));
- else
- _dbus_verbose ("read: = %d\n", bytes_read);
-
- if (bytes_read < 0)
- {
- /* put length back (note that this doesn't actually realloc anything) */
- _dbus_string_set_length (buffer, start);
- return -1;
- }
- 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;
- }
-}
-
-int
-_dbus_file_write (DBusFile *file,
- const DBusString *buffer,
- int start,
- int len)
-{
- 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));
- else
- _dbus_verbose ("write: = %d\n", bytes_written);
-
-#if 0
-
- if (bytes_written > 0)
- _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
-#endif
-
- return bytes_written;
-}
-
-dbus_bool_t
-_dbus_is_valid_file (DBusFile* file)
-{
- return file->FDATA >= 0;
-}
-
-dbus_bool_t _dbus_fstat (DBusFile *file,
- struct stat *sb)
-{
- return fstat(file->FDATA, sb) >= 0;
-}
+typedef int socklen_t;
/**
* write data to a pipe.
DBusError *error)
{
int written;
- DBusFile file;
- file.FDATA = pipe->fd_or_handle;
- written = _dbus_file_write (&file, buffer, start, len);
+ const char *buffer_c = _dbus_string_get_const_data (buffer);
+
+ written = _write (pipe->fd_or_handle, buffer_c + start, len);
if (written < 0)
{
dbus_set_error (error, DBUS_ERROR_FAILED,
"Writing to pipe: %s\n",
- _dbus_strerror (errno));
+ strerror (errno));
}
return written;
}
_dbus_pipe_close (DBusPipe *pipe,
DBusError *error)
{
- DBusFile file;
- file.FDATA = pipe->fd_or_handle;
- if (_dbus_file_close (&file, error) < 0)
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+ if (_close (pipe->fd_or_handle) < 0)
{
return -1;
}
}
}
-#undef FDATA
-
/**
* Socket interface
*
const char *data2;
int rc;
DWORD bytes_written;
- int ret1;
_dbus_assert (buffer1 != NULL);
_dbus_assert (start1 >= 0);
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];
+ char buf[1024];
+ int bufsize;
int len;
- len = _vsnprintf (p, sizeof(p)-1, format, args);
- if (len == -1) // try again
+
+ bufsize = sizeof (buf);
+ len = _vsnprintf (buf, bufsize - 1, format, args);
+
+ while (len == -1) /* try again */
{
char *p;
- p = malloc (strlen(format)*3);
- len = _vsnprintf (p, sizeof(p)-1, format, args);
- free(p);
+
+ bufsize *= 2;
+
+ p = malloc (bufsize);
+ len = _vsnprintf (p, bufsize - 1, format, args);
+ free (p);
}
+
return len;
}
return DBUS_UID_UNSET;
}
-/** Gets our effective UID
- * @returns process effective UID
- */
-dbus_uid_t
-_dbus_geteuid (void)
-{
- return DBUS_UID_UNSET;
-}
-
/**
* The only reason this is separate from _dbus_getpid() is to allow it
* on Windows for logging but not for other purposes.
{
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)
/**
- * @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
* 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 host the host name to connect to
+ * @param port the port to connect to
+ * @param family the address family to listen on, NULL for all
* @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,
+ const char *port,
+ const char *family,
DBusError *error)
{
- int fd;
- struct sockaddr_in addr;
- struct hostent *he;
- struct in_addr *haddr;
- struct in_addr ina;
+ int fd = -1, res;
+ struct addrinfo hints;
+ struct addrinfo *ai, *tmp;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
return -1;
}
- if (host == NULL)
+ _DBUS_ASSERT_ERROR_IS_CLEAR(error);
+
+ _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
{
- host = "localhost";
- ina.s_addr = htonl (INADDR_LOOPBACK);
- haddr = &ina;
+ dbus_set_error (error,
+ _dbus_error_from_errno (errno),
+ "Unknown address family %s", family);
+ return -1;
}
+ hints.ai_protocol = IPPROTO_TCP;
+ hints.ai_socktype = SOCK_STREAM;
+#ifdef AI_ADDRCONFIG
+ hints.ai_flags = AI_ADDRCONFIG;
+#else
+ hints.ai_flags = 0;
+#endif
- he = gethostbyname (host);
- if (he == NULL)
+ if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
{
- DBUS_SOCKET_SET_ERRNO ();
dbus_set_error (error,
_dbus_error_from_errno (errno),
- "Failed to lookup hostname: %s",
- host);
- DBUS_CLOSE_SOCKET (fd);
+ "Failed to lookup host/port: \"%s:%s\": %s (%d)",
+ host, port, gai_strerror(res), res);
+ closesocket (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))
+ tmp = ai;
+ while (tmp)
{
- DBUS_SOCKET_SET_ERRNO ();
+ if ((fd = socket (tmp->ai_family, SOCK_STREAM, 0)) < 0)
+ {
+ freeaddrinfo(ai);
dbus_set_error (error,
_dbus_error_from_errno (errno),
- "Failed to connect to socket %s:%d %s",
- host, port, _dbus_strerror (errno));
+ "Failed to open socket: %s",
+ _dbus_strerror (errno));
+ return -1;
+ }
+ _DBUS_ASSERT_ERROR_IS_CLEAR(error);
- DBUS_CLOSE_SOCKET (fd);
+ if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
+ {
+ closesocket(fd);
fd = -1;
+ tmp = tmp->ai_next;
+ continue;
+ }
+
+ break;
+ }
+ freeaddrinfo(ai);
+ if (fd == -1)
+ {
+ dbus_set_error (error,
+ _dbus_error_from_errno (errno),
+ "Failed to connect to socket \"%s:%s\" %s",
+ host, port, _dbus_strerror(errno));
return -1;
}
+
if (!_dbus_set_fd_nonblocking (fd, error))
{
- _dbus_close_socket (fd, NULL);
+ closesocket (fd);
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.
+ * Creates a socket and binds it to the given path, 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.
+ * If inaddr_any is specified, the hostname is ignored.
*
- * @param host the interface to listen on, NULL for loopback, empty for any
+ * @param host the host name to listen on
* @param port the port to listen on, if zero a free port will be used
+ * @param family the address family to listen on, NULL for all
+ * @param retport string to return the actual port listened on
+ * @param fds_p location to store returned file descriptors
* @param error return location for errors
- * @returns the listening file descriptor or -1 on error
+ * @returns the number of listening file descriptors or -1 on error
*/
int
_dbus_listen_tcp_socket (const char *host,
- dbus_uint32_t *port,
- dbus_bool_t inaddr_any,
+ const char *port,
+ const char *family,
+ DBusString *retport,
+ int **fds_p,
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;
-
+ int nlisten_fd = 0, *listen_fd = NULL, res, i, port_num = -1;
+ struct addrinfo hints;
+ struct addrinfo *ai, *tmp;
+ *fds_p = NULL;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
_dbus_win_startup_winsock ();
- fd = socket (AF_INET, SOCK_STREAM, 0);
+ _DBUS_ZERO (hints);
- if (DBUS_SOCKET_IS_INVALID (fd))
+ 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_SOCKET_SET_ERRNO ();
- dbus_set_error (error, _dbus_error_from_errno (errno),
- "Failed to create socket \"%s:%d\": %s",
- host, port, _dbus_strerror (errno));
+ dbus_set_error (error,
+ _dbus_error_from_errno (errno),
+ "Unknown address family %s", family);
return -1;
}
- if (host == NULL)
- {
- host = "localhost";
- ina.s_addr = htonl (INADDR_LOOPBACK);
- haddr = &ina;
- }
- else if (!host[0])
+
+ hints.ai_protocol = IPPROTO_TCP;
+ hints.ai_socktype = SOCK_STREAM;
+#ifdef AI_ADDRCONFIG
+ hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
+#else
+ hints.ai_flags = AI_PASSIVE;
+#endif
+
+ redo_lookup_with_port:
+ if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
{
- ina.s_addr = htonl (INADDR_ANY);
- haddr = &ina;
+ dbus_set_error (error,
+ _dbus_error_from_errno (errno),
+ "Failed to lookup host/port: \"%s:%s\": %s (%d)",
+ host ? host : "*", port, gai_strerror(res), res);
+ return -1;
}
- else
+
+ tmp = ai;
+ while (tmp)
{
- he = gethostbyname (host);
- if (he == NULL)
+ int fd = -1, *newlisten_fd;
+ if ((fd = socket (tmp->ai_family, SOCK_STREAM, 0)) < 0)
{
- 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;
+ "Failed to open socket: %s",
+ _dbus_strerror (errno));
+ goto failed;
}
+ _DBUS_ASSERT_ERROR_IS_CLEAR(error);
- haddr = ((struct in_addr *) (he->h_addr_list)[0]);
+ if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) == SOCKET_ERROR)
+ {
+ closesocket (fd);
+ dbus_set_error (error, _dbus_error_from_errno (errno),
+ "Failed to bind socket \"%s:%s\": %s",
+ host ? host : "*", port, _dbus_strerror (errno));
+ goto failed;
}
- _DBUS_ZERO (addr);
- memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons (*port);
+ if (listen (fd, 30 /* backlog */) == SOCKET_ERROR)
+ {
+ closesocket (fd);
+ dbus_set_error (error, _dbus_error_from_errno (errno),
+ "Failed to listen on socket \"%s:%s\": %s",
+ host ? host : "*", port, _dbus_strerror (errno));
+ goto failed;
+ }
- if (bind (fd, (struct sockaddr*) &addr, sizeof (struct sockaddr)))
+ newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
+ if (!newlisten_fd)
{
- DBUS_SOCKET_SET_ERRNO ();
+ closesocket (fd);
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;
+ "Failed to allocate file handle array: %s",
+ _dbus_strerror (errno));
+ goto failed;
}
+ listen_fd = newlisten_fd;
+ listen_fd[nlisten_fd] = fd;
+ nlisten_fd++;
- if (DBUS_SOCKET_API_RETURNS_ERROR (listen (fd, 30 /* backlog */)))
+ 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"))
+ {
+ sockaddr_gen addr;
+ socklen_t addrlen = sizeof(addr);
+ char portbuf[10];
+
+ if ((res = getsockname(fd, &addr.Address, &addrlen)) != 0)
{
- 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);
+ "Failed to resolve port \"%s:%s\": %s (%d)",
+ host ? host : "*", port, gai_strerror(res), res);
+ goto failed;
+ }
+ snprintf( portbuf, sizeof( portbuf ) - 1, "%d", addr.AddressIn.sin_port );
+ 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;
+ }
+ }
+ }
+
+ tmp = tmp->ai_next;
+ }
+ freeaddrinfo(ai);
+ ai = NULL;
+
+ if (!nlisten_fd)
+ {
+ errno = WSAEADDRINUSE;
+ dbus_set_error (error, _dbus_error_from_errno (errno),
+ "Failed to bind socket \"%s:%s\": %s",
+ host ? host : "*", port, _dbus_strerror (errno));
return -1;
}
- getsockname(fd, (struct sockaddr*) &addr, &len);
- *port = (dbus_uint32_t) ntohs(addr.sin_port);
-
- _dbus_daemon_init(host, ntohs(addr.sin_port));
+ sscanf(_dbus_string_get_const_data(retport), "%d", &port_num);
+ _dbus_daemon_init(host, port_num);
- if (!_dbus_set_fd_nonblocking (fd, error))
+ for (i = 0 ; i < nlisten_fd ; i++)
{
- _dbus_close_socket (fd, NULL);
- return -1;
+ if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
+ {
+ goto failed;
+ }
}
- return fd;
+ *fds_p = listen_fd;
+
+ return nlisten_fd;
+
+ failed:
+ if (ai)
+ freeaddrinfo(ai);
+ for (i = 0 ; i < nlisten_fd ; i++)
+ closesocket (listen_fd[i]);
+ dbus_free(listen_fd);
+ return -1;
}
_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);
+ client_fd = accept (listen_fd, NULL, NULL);
if (DBUS_SOCKET_IS_INVALID (client_fd))
{
void
_dbus_disable_sigpipe (void)
{
- _dbus_verbose("FIXME: implement _dbus_disable_sigpipe (void)\n");
}
+/* _dbus_read() is static on Windows, only used below in this file.
+ */
+static int
+_dbus_read (int fd,
+ DBusString *buffer,
+ int count)
+{
+ int bytes_read;
+ int start;
+ char *data;
+
+ _dbus_assert (count >= 0);
+
+ start = _dbus_string_get_length (buffer);
+
+ if (!_dbus_string_lengthen (buffer, count))
+ {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ data = _dbus_string_get_data_len (buffer, start, count);
+
+ again:
+
+ bytes_read = _read (fd, data, count);
+
+ if (bytes_read < 0)
+ {
+ 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;
+ }
+ }
+ 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;
+ }
+}
+
/**
* Appends the contents of the given file to the string,
* returning error code. At the moment, won't open a file
const DBusString *filename,
DBusError *error)
{
- DBusFile file;
- struct stat sb;
+ int fd;
+ struct _stati64 sb;
int orig_len;
int total;
const char *filename_c;
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;
}
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;
}
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;
}
total += bytes_read;
}
- _dbus_file_close (&file, NULL);
+ _close (fd);
return TRUE;
}
else if (sb.st_size != 0)
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;
}
}
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;
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)
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);
_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;
}
filename_c = _dbus_string_get_const_data (filename);
- if (_dbus_mkdir (filename_c, 0700) < 0)
+ if (!CreateDirectory (filename_c, NULL))
{
- if (errno == EEXIST)
+ if (GetLastError () == ERROR_ALREADY_EXISTS)
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
filename_c = _dbus_string_get_const_data (filename);
- if (unlink (filename_c) < 0)
+ if (_unlink (filename_c) < 0)
{
dbus_set_error (error, DBUS_ERROR_FAILED,
"Failed to delete file %s: %s\n",
- filename_c, _dbus_strerror (errno));
+ filename_c, strerror (errno));
return FALSE;
}
else
// mutex to determine if dbus-daemon is already started (per user)
static const char *cDBusDaemonMutex = "DBusDaemonMutex";
// named shm for dbus adress info (per user)
+#ifdef _DEBUG
+static const char *cDBusDaemonAddressInfo = "DBusDaemonAddressInfoDebug";
+#else
static const char *cDBusDaemonAddressInfo = "DBusDaemonAddressInfo";
+#endif
void
_dbus_daemon_init(const char *host, dbus_uint32_t port)
{
HANDLE lock;
- const char *adr = NULL;
+ char *adr = NULL;
char szUserName[64];
DWORD dwUserNameSize = sizeof(szUserName);
char szDBusDaemonMutex[128];
char szDBusDaemonAddressInfo[128];
char szAddress[128];
+ DWORD ret;
_dbus_assert(host);
_dbus_assert(port);
_snprintf(szAddress, sizeof(szAddress) - 1, "tcp:host=%s,port=%d", host, port);
-
- _dbus_assert( GetUserName(szUserName, &dwUserNameSize) != 0);
+ ret = GetUserName(szUserName, &dwUserNameSize);
+ _dbus_assert(ret != 0);
_snprintf(szDBusDaemonMutex, sizeof(szDBusDaemonMutex) - 1, "%s:%s",
cDBusDaemonMutex, szUserName);
_snprintf(szDBusDaemonAddressInfo, sizeof(szDBusDaemonAddressInfo) - 1, "%s:%s",
// before _dbus_global_lock to keep correct lock/release order
hDBusDaemonMutex = CreateMutex( NULL, FALSE, szDBusDaemonMutex );
-
- _dbus_assert(WaitForSingleObject( hDBusDaemonMutex, 1000 ) == WAIT_OBJECT_0);
+ ret = WaitForSingleObject( hDBusDaemonMutex, 1000 );
+ if ( ret != WAIT_OBJECT_0 ) {
+ _dbus_warn("Could not lock mutex %s (return code %d). daemon already running?\n", szDBusDaemonMutex, ret );
+ _dbus_assert( !"Could not lock mutex, daemon already running?" );
+ }
// sync _dbus_daemon_init, _dbus_daemon_uninit and _dbus_daemon_already_runs
lock = _dbus_global_lock( cUniqueDBusInitMutex );
_dbus_assert( adr );
- strcpy( (char*) adr, szAddress);
+ strcpy( adr, szAddress);
// cleanup
- UnmapViewOfFile( (char*) adr );
+ UnmapViewOfFile( adr );
_dbus_global_unlock( lock );
}
_dbus_get_autolaunch_shm(DBusString *adress)
{
HANDLE sharedMem;
- const char *adr;
+ char *adr;
char szUserName[64];
DWORD dwUserNameSize = sizeof(szUserName);
char szDBusDaemonAddressInfo[128];
+ int i;
if( !GetUserName(szUserName, &dwUserNameSize) )
return FALSE;
cDBusDaemonAddressInfo, szUserName);
// read shm
- do {
+ for(i=0;i<20;++i) {
// 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 );
+ if ( sharedMem != 0)
+ break;
+ }
if( sharedMem == 0 )
return FALSE;
_dbus_string_append( adress, adr );
// cleanup
- UnmapViewOfFile( (char*) adr );
+ UnmapViewOfFile( adr );
CloseHandle( sharedMem );
LPSTR lpFile;
char dbus_exe_path[MAX_PATH];
char dbus_args[MAX_PATH * 2];
+#ifdef _DEBUG
+ const char * daemon_name = "dbus-daemond.exe";
+#else
+ const char * daemon_name = "dbus-daemon.exe";
+#endif
mutex = _dbus_global_lock ( cDBusAutolaunchMutex );
if (_dbus_daemon_already_runs(address))
{
- printf("dbus daemon already exists\n");
+ _dbus_verbose("found already running dbus daemon\n");
retval = TRUE;
goto out;
}
- if (!SearchPathA(NULL, "dbus-daemon.exe", NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile))
+ if (!SearchPathA(NULL, daemon_name, NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile))
{
- printf ("could not find dbus-daemon executable\n");
+ printf ("please add the path to %s to your PATH environment variable\n", daemon_name);
+ printf ("or start the daemon manually\n\n");
+ printf ("");
goto out;
}
_snprintf(dbus_args, sizeof(dbus_args) - 1, "\"%s\" %s", dbus_exe_path, " --session");
// 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))
+// printf("create process \"%s\" %s\n", dbus_exe_path, dbus_args);
+ if(CreateProcessA(dbus_exe_path, dbus_args, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
{
- retval = TRUE;
-
- // Wait until started (see _dbus_get_autolaunch_shm())
- WaitForInputIdle(pi.hProcess, INFINITE);
retval = _dbus_get_autolaunch_shm( address );
- } else {
- retval = FALSE;
}
+ if (retval == FALSE)
+ dbus_set_error_const (error, DBUS_ERROR_FAILED, "Failed to launch dbus-daemon");
+
out:
if (retval)
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
return FALSE;
}
+/**
+ * Returns the standard directories for a system bus to look for service
+ * activation files
+ *
+ * On UNIX this should be the standard xdg freedesktop.org data directories:
+ *
+ * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
+ *
+ * and
+ *
+ * DBUS_DATADIR
+ *
+ * On Windows there is no system bus and this function can return nothing.
+ *
+ * @param dirs the directory list we are returning
+ * @returns #FALSE on OOM
+ */
+
+dbus_bool_t
+_dbus_get_standard_system_servicedirs (DBusList **dirs)
+{
+ *dirs = NULL;
+ return TRUE;
+}
+
_DBUS_DEFINE_GLOBAL_LOCK (atomic);
/**
{
char path[MAX_PATH*2];
int path_size = sizeof(path);
+ int len = 4 + strlen(s);
if (!_dbus_get_install_root(path,path_size))
return FALSE;
- strcat_s(path,path_size,"etc\\");
- strcat_s(path,path_size,s);
+ if(len > sizeof(path)-2)
+ return FALSE;
+ strcat(path,"etc\\");
+ strcat(path,s);
if (_dbus_file_exists(path))
{
// find path from executable
{
if (!_dbus_get_install_root(path,path_size))
return FALSE;
- strcat_s(path,path_size,"bus\\");
- strcat_s(path,path_size,s);
+ if(len + strlen(path) > sizeof(path)-2)
+ return FALSE;
+ strcat(path,"bus\\");
+ strcat(path,s);
if (_dbus_file_exists(path))
{