summaryrefslogtreecommitdiffstats
path: root/dbus
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2003-04-06 18:03:03 +0000
committerHavoc Pennington <hp@redhat.com>2003-04-06 18:03:03 +0000
commite45e4382274149ca60c11f068ccca719f3598074 (patch)
tree5fda8d67759828cd7b8e2f1c9a8f4d66f63b737f /dbus
parent2618e1a973b816ab59422035046111360ab5aa74 (diff)
2003-04-06 Havoc Pennington <hp@pobox.com>
* bus/bus.c (bus_context_new): fix wrong handling of server_data_slot_unref() in the error case. * dbus/dbus-internals.h (_dbus_assert): change so it passes "(condition) != 0" to _dbus_real_assert so that "_dbus_assert (pointer)" doesn't cause a warning * bus/main.c (main): accept --print-address option to print out the message bus address * dbus/dbus-sysdeps.c (_dbus_generate_random_ascii): export this * dbus/dbus-transport.c (_dbus_transport_open): special error for "tmpdir" option to unix: address on client side * dbus/dbus-server.c (dbus_server_listen): handle "tmpdir" option to unix: address * configure.in (TEST_SOCKET_DIR): locate a temporary directory we can use to create sockets in the test suite. * bus/main.c (signal_handler): on SIGTERM, exit the daemon cleanly. To be used for testing. * dbus/dbus-spawn.c (babysit): use _dbus_set_signal_handler() * dbus/dbus-sysdeps.c (_dbus_set_signal_handler): new * dbus/dbus-server-debug-pipe.c (_dbus_transport_debug_pipe_new): handle trying to call this when there's no servers active
Diffstat (limited to 'dbus')
-rw-r--r--dbus/dbus-errors.c2
-rw-r--r--dbus/dbus-internals.h4
-rw-r--r--dbus/dbus-server-debug-pipe.c8
-rw-r--r--dbus/dbus-server.c73
-rw-r--r--dbus/dbus-spawn.c12
-rw-r--r--dbus/dbus-sysdeps.c186
-rw-r--r--dbus/dbus-sysdeps.h8
-rw-r--r--dbus/dbus-transport.c11
8 files changed, 205 insertions, 99 deletions
diff --git a/dbus/dbus-errors.c b/dbus/dbus-errors.c
index 7e3aa69b..0f70bcb1 100644
--- a/dbus/dbus-errors.c
+++ b/dbus/dbus-errors.c
@@ -93,7 +93,7 @@ message_from_error (const char *error)
else if (strcmp (error, DBUS_ERROR_AUTH_FAILED) == 0)
return "Could not authenticate to server";
else if (strcmp (error, DBUS_ERROR_NO_SERVER) == 0)
- return "No server";
+ return "No server available at address";
else if (strcmp (error, DBUS_ERROR_TIMEOUT) == 0)
return "Connection timed out";
else if (strcmp (error, DBUS_ERROR_NO_NETWORK) == 0)
diff --git a/dbus/dbus-internals.h b/dbus/dbus-internals.h
index dbfd0681..f37009b9 100644
--- a/dbus/dbus-internals.h
+++ b/dbus/dbus-internals.h
@@ -1,7 +1,7 @@
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-internals.h random utility stuff (internal to D-BUS implementation)
*
- * Copyright (C) 2002 Red Hat, Inc.
+ * Copyright (C) 2002, 2003 Red Hat, Inc.
*
* Licensed under the Academic Free License version 1.2
*
@@ -81,7 +81,7 @@ void _dbus_real_assert (dbus_bool_t condition,
const char *file,
int line);
#define _dbus_assert(condition) \
- _dbus_real_assert ((condition), #condition, __FILE__, __LINE__)
+ _dbus_real_assert ((condition) != 0, #condition, __FILE__, __LINE__)
#endif /* !DBUS_DISABLE_ASSERT */
#ifdef DBUS_DISABLE_ASSERT
diff --git a/dbus/dbus-server-debug-pipe.c b/dbus/dbus-server-debug-pipe.c
index 905349be..151e32b8 100644
--- a/dbus/dbus-server-debug-pipe.c
+++ b/dbus/dbus-server-debug-pipe.c
@@ -220,13 +220,19 @@ _dbus_transport_debug_pipe_new (const char *server_name,
DBusString address;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+ if (server_pipe_hash == NULL)
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_SERVER, NULL);
+ return NULL;
+ }
server = _dbus_hash_table_lookup_string (server_pipe_hash,
server_name);
if (server == NULL ||
((DBusServerDebugPipe*)server)->disconnected)
{
- dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, NULL);
+ dbus_set_error (error, DBUS_ERROR_NO_SERVER, NULL);
return NULL;
}
diff --git a/dbus/dbus-server.c b/dbus/dbus-server.c
index 566e9178..3f877a0f 100644
--- a/dbus/dbus-server.c
+++ b/dbus/dbus-server.c
@@ -305,18 +305,68 @@ dbus_server_listen (const char *address,
if (strcmp (method, "unix") == 0)
{
const char *path = dbus_address_entry_get_value (entries[i], "path");
-
- if (path == NULL)
+ const char *tmpdir = dbus_address_entry_get_value (entries[i], "tmpdir");
+
+ if (path == NULL && tmpdir == NULL)
{
address_problem_type = "unix";
- address_problem_field = "path";
+ address_problem_field = "path or tmpdir";
goto bad_address;
}
- server = _dbus_server_new_for_domain_socket (path, error);
+ if (path && tmpdir)
+ {
+ address_problem_other = "cannot specify both \"path\" and \"tmpdir\" at the same time";
+ goto bad_address;
+ }
- if (server)
- break;
+ if (tmpdir != NULL)
+ {
+ DBusString full_path;
+ DBusString filename;
+
+ if (!_dbus_string_init (&full_path))
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ goto out;
+ }
+
+ if (!_dbus_string_init (&filename))
+ {
+ _dbus_string_free (&full_path);
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ goto out;
+ }
+
+ if (!_dbus_string_append (&filename,
+ "dbus-") ||
+ !_dbus_generate_random_ascii (&filename, 10) ||
+ !_dbus_string_append (&full_path, tmpdir) ||
+ !_dbus_concat_dir_and_file (&full_path, &filename))
+ {
+ _dbus_string_free (&full_path);
+ _dbus_string_free (&filename);
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ goto out;
+ }
+
+ /* FIXME - we will unconditionally unlink() the path.
+ * unlink() does not follow symlinks, but would like
+ * independent confirmation this is safe enough. See
+ * also _dbus_listen_unix_socket() and comments therein.
+ */
+
+ server =
+ _dbus_server_new_for_domain_socket (_dbus_string_get_const_data (&full_path),
+ error);
+
+ _dbus_string_free (&full_path);
+ _dbus_string_free (&filename);
+ }
+ else
+ {
+ server = _dbus_server_new_for_domain_socket (path, error);
+ }
}
else if (strcmp (method, "tcp") == 0)
{
@@ -361,9 +411,6 @@ dbus_server_listen (const char *address,
}
server = _dbus_server_debug_new (name, error);
-
- if (server)
- break;
}
else if (strcmp (method, "debug-pipe") == 0)
{
@@ -377,9 +424,6 @@ dbus_server_listen (const char *address,
}
server = _dbus_server_debug_pipe_new (name, error);
-
- if (server)
- break;
}
#endif
else
@@ -387,7 +431,12 @@ dbus_server_listen (const char *address,
address_problem_other = "Unknown address type (examples of valid types are \"unix\" and \"tcp\")";
goto bad_address;
}
+
+ if (server)
+ break;
}
+
+ out:
dbus_address_entries_free (entries);
return server;
diff --git a/dbus/dbus-spawn.c b/dbus/dbus-spawn.c
index 2273a4e3..87e1ffc2 100644
--- a/dbus/dbus-spawn.c
+++ b/dbus/dbus-spawn.c
@@ -916,9 +916,7 @@ babysit_signal_handler (int signo)
static void
babysit (pid_t grandchild_pid,
int parent_pipe)
-{
- struct sigaction act;
- sigset_t empty_mask;
+{
int sigchld_pipe[2];
/* I thought SIGCHLD would just wake up the poll, but
@@ -933,12 +931,8 @@ babysit (pid_t grandchild_pid,
}
babysit_sigchld_pipe = sigchld_pipe[WRITE_END];
-
- sigemptyset (&empty_mask);
- act.sa_handler = babysit_signal_handler;
- act.sa_mask = empty_mask;
- act.sa_flags = 0;
- sigaction (SIGCHLD, &act, 0);
+
+ _dbus_set_signal_handler (SIGCHLD, babysit_signal_handler);
write_pid (parent_pipe, grandchild_pid);
diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c
index 3588f762..7a389956 100644
--- a/dbus/dbus-sysdeps.c
+++ b/dbus/dbus-sysdeps.c
@@ -2007,36 +2007,6 @@ _dbus_file_get_contents (DBusString *str,
}
}
-static dbus_bool_t
-append_unique_chars (DBusString *str)
-{
- static const char letters[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
- int i;
- int len;
-
-#define N_UNIQUE_CHARS 8
-
- if (!_dbus_generate_random_bytes (str, N_UNIQUE_CHARS))
- return FALSE;
-
- len = _dbus_string_get_length (str);
- i = len - N_UNIQUE_CHARS;
- while (i < len)
- {
- _dbus_string_set_byte (str, i,
- letters[_dbus_string_get_byte (str, i) %
- (sizeof (letters) - 1)]);
-
- ++i;
- }
-
- _dbus_assert (_dbus_string_validate_ascii (str, len - N_UNIQUE_CHARS,
- N_UNIQUE_CHARS));
-
- return TRUE;
-}
-
/**
* Writes a string out to a file. If the file exists,
* it will be atomically overwritten by the new data.
@@ -2083,8 +2053,9 @@ _dbus_string_save_to_file (const DBusString *str,
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
return FALSE;
}
-
- if (!append_unique_chars (&tmp_filename))
+
+#define N_TMP_FILENAME_RANDOM_BYTES 8
+ if (!_dbus_generate_random_ascii (&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES))
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
return FALSE;
@@ -2487,13 +2458,52 @@ _dbus_directory_close (DBusDirIter *iter)
dbus_free (iter);
}
+static dbus_bool_t
+pseudorandom_generate_random_bytes (DBusString *str,
+ int n_bytes)
+{
+ int old_len;
+ unsigned long tv_usec;
+ int i;
+
+ old_len = _dbus_string_get_length (str);
+
+ /* fall back to pseudorandom */
+ _dbus_verbose ("Falling back to pseudorandom for %d bytes\n",
+ n_bytes);
+
+ _dbus_get_current_time (NULL, &tv_usec);
+ srand (tv_usec);
+
+ i = 0;
+ while (i < n_bytes)
+ {
+ double r;
+ unsigned int b;
+
+ r = rand ();
+ b = (r / (double) RAND_MAX) * 255.0;
+
+ if (!_dbus_string_append_byte (str, b))
+ goto failed;
+
+ ++i;
+ }
+
+ return TRUE;
+
+ failed:
+ _dbus_string_set_length (str, old_len);
+ return FALSE;
+}
+
/**
* 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 or other failure
+ * @returns #TRUE on success, #FALSE if no memory
*/
dbus_bool_t
_dbus_generate_random_bytes (DBusString *str,
@@ -2501,6 +2511,12 @@ _dbus_generate_random_bytes (DBusString *str,
{
int old_len;
int fd;
+
+ /* FALSE return means "no memory", if it could
+ * mean something else then we'd need to return
+ * a DBusError. So we always fall back to pseudorandom
+ * if the I/O fails.
+ */
old_len = _dbus_string_get_length (str);
fd = -1;
@@ -2508,52 +2524,58 @@ _dbus_generate_random_bytes (DBusString *str,
/* note, urandom on linux will fall back to pseudorandom */
fd = open ("/dev/urandom", O_RDONLY);
if (fd < 0)
+ return pseudorandom_generate_random_bytes (str, n_bytes);
+
+ if (_dbus_read (fd, str, n_bytes) != n_bytes)
{
- unsigned long tv_usec;
- int i;
+ close (fd);
+ _dbus_string_set_length (str, old_len);
+ return pseudorandom_generate_random_bytes (str, n_bytes);
+ }
- /* fall back to pseudorandom */
- _dbus_verbose ("Falling back to pseudorandom for %d bytes\n",
- n_bytes);
-
- _dbus_get_current_time (NULL, &tv_usec);
- srand (tv_usec);
-
- i = 0;
- while (i < n_bytes)
- {
- double r;
- unsigned int b;
-
- r = rand ();
- b = (r / (double) RAND_MAX) * 255.0;
-
- if (!_dbus_string_append_byte (str, b))
- goto failed;
-
- ++i;
- }
+ _dbus_verbose ("Read %d bytes from /dev/urandom\n",
+ n_bytes);
+
+ close (fd);
+
+ return TRUE;
+}
- return TRUE;
- }
- else
+/**
+ * Generates the given number of random bytes, where the bytes are
+ * chosen from the alphanumeric ASCII subset.
+ *
+ * @param str the string
+ * @param n_bytes the number of random ASCII bytes to append to string
+ * @returns #TRUE on success, #FALSE if no memory or other failure
+ */
+dbus_bool_t
+_dbus_generate_random_ascii (DBusString *str,
+ int n_bytes)
+{
+ static const char letters[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
+ int i;
+ int len;
+
+ if (!_dbus_generate_random_bytes (str, n_bytes))
+ return FALSE;
+
+ len = _dbus_string_get_length (str);
+ i = len - n_bytes;
+ while (i < len)
{
- if (_dbus_read (fd, str, n_bytes) != n_bytes)
- goto failed;
-
- _dbus_verbose ("Read %d bytes from /dev/urandom\n",
- n_bytes);
-
- close (fd);
+ _dbus_string_set_byte (str, i,
+ letters[_dbus_string_get_byte (str, i) %
+ (sizeof (letters) - 1)]);
- return TRUE;
+ ++i;
}
- failed:
- _dbus_string_set_length (str, old_len);
- if (fd >= 0)
- close (fd);
- return FALSE;
+ _dbus_assert (_dbus_string_validate_ascii (str, len - n_bytes,
+ n_bytes));
+
+ return TRUE;
}
/**
@@ -3005,6 +3027,26 @@ _dbus_change_identity (unsigned long uid,
return TRUE;
}
+/** Installs a UNIX signal handler
+ *
+ * @param sig the signal to handle
+ * @param handler the handler
+ */
+void
+_dbus_set_signal_handler (int sig,
+ DBusSignalHandler handler)
+{
+ struct sigaction act;
+ sigset_t empty_mask;
+
+ sigemptyset (&empty_mask);
+ act.sa_handler = handler;
+ act.sa_mask = empty_mask;
+ act.sa_flags = 0;
+ sigaction (sig, &act, 0);
+}
+
+
#ifdef DBUS_BUILD_TESTS
#include <stdlib.h>
static void
diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h
index 77d54c8c..933e2775 100644
--- a/dbus/dbus-sysdeps.h
+++ b/dbus/dbus-sysdeps.h
@@ -180,6 +180,8 @@ void _dbus_directory_close (DBusDirIter *iter);
dbus_bool_t _dbus_generate_random_bytes (DBusString *str,
int n_bytes);
+dbus_bool_t _dbus_generate_random_ascii (DBusString *str,
+ int n_bytes);
const char *_dbus_errno_to_string (int errnum);
const char* _dbus_error_from_errno (int error_number);
@@ -220,6 +222,12 @@ dbus_bool_t _dbus_change_identity (unsigned long uid,
unsigned long gid,
DBusError *error);
+typedef void (* DBusSignalHandler) (int sig);
+
+void _dbus_set_signal_handler (int sig,
+ DBusSignalHandler handler);
+
+
DBUS_END_DECLS;
#endif /* DBUS_SYSDEPS_H */
diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c
index e56c8b0c..d074480a 100644
--- a/dbus/dbus-transport.c
+++ b/dbus/dbus-transport.c
@@ -235,7 +235,14 @@ _dbus_transport_open (const char *address,
if (strcmp (method, "unix") == 0)
{
const char *path = dbus_address_entry_get_value (entries[i], "path");
+ const char *tmpdir = dbus_address_entry_get_value (entries[i], "tmpdir");
+ if (tmpdir != NULL)
+ {
+ address_problem_other = "cannot use the \"tmpdir\" option for an address to connect to, only in an address to listen on";
+ goto bad_address;
+ }
+
if (path == NULL)
{
address_problem_type = "unix";
@@ -243,7 +250,7 @@ _dbus_transport_open (const char *address,
goto bad_address;
}
- transport = _dbus_transport_new_for_domain_socket (path, error);
+ transport = _dbus_transport_new_for_domain_socket (path, error);
}
else if (strcmp (method, "tcp") == 0)
{
@@ -309,7 +316,7 @@ _dbus_transport_open (const char *address,
if (transport)
break;
}
-
+
dbus_address_entries_free (entries);
return transport;