diff options
| -rw-r--r-- | ChangeLog | 33 | ||||
| -rw-r--r-- | bus/bus.c | 20 | ||||
| -rw-r--r-- | bus/bus.h | 1 | ||||
| -rw-r--r-- | bus/main.c | 134 | ||||
| -rw-r--r-- | bus/session.conf.in | 14 | ||||
| -rw-r--r-- | configure.in | 68 | ||||
| -rw-r--r-- | dbus/dbus-errors.c | 2 | ||||
| -rw-r--r-- | dbus/dbus-internals.h | 4 | ||||
| -rw-r--r-- | dbus/dbus-server-debug-pipe.c | 8 | ||||
| -rw-r--r-- | dbus/dbus-server.c | 73 | ||||
| -rw-r--r-- | dbus/dbus-spawn.c | 12 | ||||
| -rw-r--r-- | dbus/dbus-sysdeps.c | 186 | ||||
| -rw-r--r-- | dbus/dbus-sysdeps.h | 8 | ||||
| -rw-r--r-- | dbus/dbus-transport.c | 11 | 
14 files changed, 439 insertions, 135 deletions
| @@ -1,3 +1,36 @@ +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 +  2003-04-05  Havoc Pennington  <hp@pobox.com>  	* NEWS: update @@ -107,7 +107,10 @@ server_get_context (DBusServer *server)    bd = BUS_SERVER_DATA (server);    if (bd == NULL) -    return NULL; +    { +      server_data_slot_unref (); +      return NULL; +    }    context = bd->context; @@ -314,7 +317,7 @@ bus_context_new (const DBusString *config_file,        BUS_SET_OOM (error);        return NULL;      } -   +    if (!server_data_slot_ref ())      {        BUS_SET_OOM (error); @@ -339,6 +342,12 @@ bus_context_new (const DBusString *config_file,    context->refcount = 1; +  /* we need another ref of the server data slot for the context +   * to own +   */ +  if (!server_data_slot_ref ()) +    _dbus_assert_not_reached ("second ref of server data slot failed"); +    #ifdef DBUS_BUILD_TESTS    context->activation_timeout = 6000;  /* 6 seconds */  #else @@ -542,6 +551,7 @@ bus_context_new (const DBusString *config_file,    bus_config_parser_unref (parser);    _dbus_string_free (&full_address);    dbus_free_string_array (auth_mechanisms); +  server_data_slot_unref ();    return context; @@ -678,6 +688,12 @@ bus_context_get_type (BusContext *context)    return context->type;  } +const char* +bus_context_get_address (BusContext *context) +{ +  return context->address; +} +  BusRegistry*  bus_context_get_registry (BusContext  *context)  { @@ -46,6 +46,7 @@ void            bus_context_shutdown                 (BusContext       *context)  void            bus_context_ref                      (BusContext       *context);  void            bus_context_unref                    (BusContext       *context);  const char*     bus_context_get_type                 (BusContext       *context); +const char*     bus_context_get_address              (BusContext       *context);  BusRegistry*    bus_context_get_registry             (BusContext       *context);  BusConnections* bus_context_get_connections          (BusContext       *context);  BusActivation*  bus_context_get_activation           (BusContext       *context); @@ -26,11 +26,29 @@  #include <stdio.h>  #include <stdlib.h>  #include <string.h> +#include <signal.h> +#include <errno.h> + +static BusContext *context; +static dbus_bool_t got_sighup = FALSE; + +static void +signal_handler (int sig) +{ +  switch (sig) +    { +    case SIGHUP: +      got_sighup = TRUE; +    case SIGTERM: +      bus_loop_quit (bus_context_get_loop (context)); +      break; +    } +}  static void  usage (void)  { -  fprintf (stderr, "dbus-daemon-1 [--session] [--system] [--config-file=FILE] [--version]\n"); +  fprintf (stderr, "dbus-daemon-1 [--version] [--session] [--system] [--config-file=FILE] [--print-address[=descriptor]]\n");    exit (1);  } @@ -57,17 +75,36 @@ check_two_config_files (const DBusString *config_file,      }  } +static void +check_two_addr_descriptors (const DBusString *addr_fd, +                            const char       *extra_arg) +{ +  if (_dbus_string_get_length (addr_fd) > 0) +    { +      fprintf (stderr, "--%s specified but printing address to %s already requested\n", +               extra_arg, _dbus_string_get_const_data (addr_fd)); +      exit (1); +    } +} +  int  main (int argc, char **argv)  { -  BusContext *context;    DBusError error;    DBusString config_file; +  DBusString addr_fd;    const char *prev_arg; +  int print_addr_fd;    int i; - +  dbus_bool_t print_address; +      if (!_dbus_string_init (&config_file))      return 1; + +  if (!_dbus_string_init (&addr_fd)) +    return 1; +   +  print_address = FALSE;    prev_arg = NULL;    i = 1; @@ -117,6 +154,32 @@ main (int argc, char **argv)          }        else if (strcmp (arg, "--config-file") == 0)          ; /* wait for next arg */ +      else if (strstr (arg, "--print-address=") == arg) +        { +          const char *desc; + +          check_two_addr_descriptors (&addr_fd, "print-address"); +           +          desc = strchr (arg, '='); +          ++desc; + +          if (!_dbus_string_append (&addr_fd, desc)) +            exit (1); + +          print_address = TRUE; +        } +      else if (prev_arg && +               strcmp (prev_arg, "--print-address") == 0) +        { +          check_two_addr_descriptors (&addr_fd, "print-address"); +           +          if (!_dbus_string_append (&addr_fd, arg)) +            exit (1); + +          print_address = TRUE; +        } +      else if (strcmp (arg, "--print-address") == 0) +        print_address = TRUE; /* and we'll get the next arg if appropriate */        else          usage (); @@ -130,6 +193,27 @@ main (int argc, char **argv)        fprintf (stderr, "No configuration file specified.\n");        usage ();      } + +  print_addr_fd = -1; +  if (print_address) +    { +      print_addr_fd = 1; /* stdout */ +      if (_dbus_string_get_length (&addr_fd) > 0) +        { +          long val; +          int end; +          if (!_dbus_string_parse_int (&addr_fd, 0, &val, &end) || +              end != _dbus_string_get_length (&addr_fd) || +              val < 0 || val > _DBUS_INT_MAX) +            { +              fprintf (stderr, "Invalid file descriptor: \"%s\"\n", +                       _dbus_string_get_const_data (&addr_fd)); +              exit (1); +            } + +          print_addr_fd = val; +        } +    }    dbus_error_init (&error);    context = bus_context_new (&config_file, &error); @@ -139,14 +223,56 @@ main (int argc, char **argv)        _dbus_warn ("Failed to start message bus: %s\n",                    error.message);        dbus_error_free (&error); -      return 1; +      exit (1);      } + +  /* Note that we don't know whether the print_addr_fd is +   * one of the sockets we're using to listen on, or some +   * other random thing. But I think the answer is "don't do +   * that then" +   */ +  if (print_addr_fd >= 0) +    { +      DBusString addr; +      const char *a = bus_context_get_address (context); +      int bytes; +       +      _dbus_assert (a != NULL); +      if (!_dbus_string_init (&addr) || +          !_dbus_string_append (&addr, a) || +          !_dbus_string_append (&addr, "\n")) +        exit (1); + +      bytes = _dbus_string_get_length (&addr); +      if (_dbus_write (print_addr_fd, &addr, 0, bytes) != bytes) +        { +          _dbus_warn ("Failed to print message bus address: %s\n", +                      _dbus_strerror (errno)); +          exit (1); +        } + +      if (print_addr_fd > 2) +        _dbus_close (print_addr_fd, NULL); + +      _dbus_string_free (&addr); +    } +   +  /* FIXME we have to handle this properly below _dbus_set_signal_handler (SIGHUP, signal_handler); */ +  _dbus_set_signal_handler (SIGTERM, signal_handler);    _dbus_verbose ("We are on D-Bus...\n");    bus_loop_run (bus_context_get_loop (context));    bus_context_shutdown (context);    bus_context_unref (context); + +  /* If we exited on TERM we just exit, if we exited on +   * HUP we restart the daemon. +   */ +  if (got_sighup) +    { +      /* FIXME execv (argv) basically */ +    }    return 0;  } diff --git a/bus/session.conf.in b/bus/session.conf.in index 28478955..d430d990 100644 --- a/bus/session.conf.in +++ b/bus/session.conf.in @@ -8,19 +8,7 @@    <!-- Our well-known bus type, don't change this -->    <type>session</type> -  <!-- FIXME - this is fairly complicated to fix. -       Propose the following: -         - add "unix:tmpdir=/tmp" which means unix domain transport  -           creates a socket with a random secure name  -         - add dbus_server_get_address() that gets the actual  -           server address  -         - add command line option or env variable to the daemon  -           causing it to print its list of addresses to a given  -           file descriptor -         - session manager or whatever launches the session bus  -           reads the address from there and sets the env variable -    --> -  <listen>unix:path=/tmp/foobar</listen> +  <listen>unix:tmpdir=@DBUS_SESSION_SOCKET_DIR@</listen>    <policy context="default">      <!-- Allow everything --> diff --git a/configure.in b/configure.in index 27483570..d37a7c4b 100644 --- a/configure.in +++ b/configure.in @@ -31,8 +31,10 @@ AC_ARG_ENABLE(verbose-mode, [  --enable-verbose-mode support verbose debug mode]  AC_ARG_ENABLE(asserts, [  --enable-asserts include assertion checks],enable_asserts=$enableval,enable_asserts=yes)  AC_ARG_ENABLE(gcov,    [  --enable-gcov compile with coverage profiling instrumentation (gcc only)],enable_gcov=$enableval,enable_gcov=no) -AC_ARG_WITH(xml,          [  --with-xml=[libxml/expat] XML library to use]) -AC_ARG_WITH(init-scripts, [  --with-init-scripts=[redhat] Style of init scripts to install]) +AC_ARG_WITH(xml,                [  --with-xml=[libxml/expat] XML library to use]) +AC_ARG_WITH(init-scripts,       [  --with-init-scripts=[redhat] Style of init scripts to install]) +AC_ARG_WITH(session-socket-dir, [  --with-session-socket-dir=[dirname] Where to put sockets for the per-login-session message bus]) +AC_ARG_WITH(test-socket-dir,    [  --with-test-socket-dir=[dirname] Where to put sockets for make check])  dnl DBUS_BUILD_TESTS controls unit tests built in to .c files   dnl and also some stuff in the test/ subdir @@ -123,6 +125,9 @@ else    fi  fi +# compress spaces in cflags +CFLAGS=`echo "$CFLAGS" | sed -e 's/ +/ /g'` +  if test x$enable_gcov = xyes; then       ## so that config.h changes when you toggle gcov support       AC_DEFINE_UNQUOTED(DBUS_GCOV_ENABLED, 1, [Defined if gcov is enabled to force a rebuild due to config.h changing]) @@ -160,6 +165,7 @@ AC_DEFINE_UNQUOTED(DBUS_INT64_TYPE, $dbusint64, [64-bit integer type])  ## byte order  AC_C_BIGENDIAN +#### Various functions  AC_CHECK_LIB(socket,socket)  AC_CHECK_LIB(nsl,gethostbyname) @@ -443,6 +449,32 @@ TEST_PATH(EXIT_BINARY, test-exit)  TEST_PATH(SEGFAULT_BINARY, test-segfault)  TEST_PATH(SLEEP_FOREVER_BINARY, test-sleep-forever) +#### Find socket directories +if ! test -z "$TMPDIR" ; then +   DEFAULT_SOCKET_DIR=$TMPDIR +elif ! test -z "$TEMP" ; then +   DEFAULT_SOCKET_DIR=$TEMP +elif ! test -z "$TMP" ; then +   DEFAULT_SOCKET_DIR=$TMP +else +   DEFAULT_SOCKET_DIR=/tmp +fi + +if ! test -z "$with_test_socket_dir" ; then +   TEST_SOCKET_DIR="$with_test_socket_dir" +else +   TEST_SOCKET_DIR=$DEFAULT_SOCKET_DIR +fi +AC_SUBST(TEST_SOCKET_DIR) + +if ! test -z "$with_session_socket_dir" ; then +   DBUS_SESSION_SOCKET_DIR="$with_session_socket_dir" +else +   DBUS_SESSION_SOCKET_DIR=$DEFAULT_SOCKET_DIR +fi +AC_SUBST(DBUS_SESSION_SOCKET_DIR) + +  AC_OUTPUT([  Doxyfile  bus/system.conf @@ -466,21 +498,23 @@ echo "                      D-BUS $VERSION                    ============== -	prefix:                 ${prefix} -	source code location:	${srcdir} -	compiler:		${CC} -	cflags:		        ${CFLAGS} - -        Maintainer mode:        ${USE_MAINTAINER_MODE} -        gcc coverage profiling: ${enable_gcov} -        Building unit tests:    ${enable_tests} -        Building verbose mode:  ${enable_verbose_mode} -        Building assertions:    ${enable_asserts} -        Building Qt bindings:   ${have_qt} -        Building GLib bindings: ${have_glib} -        Using XML parser:       ${with_xml} -        System bus socket:      ${EXPANDED_LOCALSTATEDIR}/${DBUS_SYSTEM_SOCKET} -        Init scripts style:     ${with_init_scripts} +	prefix:                   ${prefix} +	source code location:	  ${srcdir} +	compiler:		  ${CC} +	cflags:		          ${CFLAGS} + +        Maintainer mode:          ${USE_MAINTAINER_MODE} +        gcc coverage profiling:   ${enable_gcov} +        Building unit tests:      ${enable_tests} +        Building verbose mode:    ${enable_verbose_mode} +        Building assertions:      ${enable_asserts} +        Building Qt bindings:     ${have_qt} +        Building GLib bindings:   ${have_glib} +        Using XML parser:         ${with_xml} +        Init scripts style:       ${with_init_scripts} +        System bus socket:        ${EXPANDED_LOCALSTATEDIR}/${DBUS_SYSTEM_SOCKET} +        Session bus socket dir:   ${DBUS_SESSION_SOCKET_DIR} +        'make check' socket dir:  ${TEST_SOCKET_DIR}  "  if test x$enable_tests = xyes; then 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; | 
