/**
 * Runs the given function on every message file in the test suite.
 * The function should return #FALSE on test failure or fatal error.
 *
 * @param test_data_dir root dir of the test suite data files (top_srcdir/test/data)
 * @param func the function to run
 * @param user_data data for function
 * @returns #FALSE if there's a failure
 */
dbus_bool_t
dbus_internal_do_not_use_foreach_message_file (const char                *test_data_dir,
                                               DBusForeachMessageFileFunc func,
                                               void                      *user_data)
{
  DBusString test_directory;
  dbus_bool_t retval;

  retval = FALSE;

  _dbus_string_init_const (&test_directory, test_data_dir);
  
  if (!process_test_subdir (&test_directory, "valid-messages",
                            DBUS_VALID, func, user_data))
    goto failed;

  check_memleaks ();
  
  if (!process_test_subdir (&test_directory, "invalid-messages",
                            DBUS_INVALID_FOR_UNKNOWN_REASON, func, user_data))
    goto failed;

  check_memleaks ();
  
  if (!process_test_subdir (&test_directory, "incomplete-messages",
                            DBUS_VALID_BUT_INCOMPLETE, func, user_data))
    goto failed;

  check_memleaks ();
  
  retval = TRUE;
  
 failed:

  _dbus_string_free (&test_directory);

  return retval;
}
Exemple #2
0
static char *
get_test_exec (const char *exe,
               DBusString *scratch_space)
{
  const char *dbus_test_exec;

  dbus_test_exec = _dbus_getenv ("DBUS_TEST_EXEC");

  if (dbus_test_exec == NULL)
    dbus_test_exec = DBUS_TEST_EXEC;

  if (!_dbus_string_init (scratch_space))
    return NULL;

  if (!_dbus_string_append_printf (scratch_space, "%s/%s%s",
                                   dbus_test_exec, exe, DBUS_EXEEXT))
    {
      _dbus_string_free (scratch_space);
      return NULL;
    }

  return _dbus_string_get_data (scratch_space);
}
Exemple #3
0
static void
introspect (void)
{
  DBusString xml;
  const char *v_STRING;

  if (!_dbus_string_init (&xml))
    goto oom;

  if (!bus_driver_generate_introspect_string (&xml))
    {
      _dbus_string_free (&xml);
      goto oom;
    }

  v_STRING = _dbus_string_get_const_data (&xml);
  printf ("%s\n", v_STRING);

  exit (0);

 oom:
  _dbus_warn ("Can not introspect - Out of memory\n");
  exit (1);
}
Exemple #4
0
static dbus_bool_t
handle_reload_watch (DBusWatch    *watch,
		     unsigned int  flags,
		     void         *data)
{
  DBusError error;
  DBusString str;

  while (!_dbus_string_init (&str))
    _dbus_wait_for_memory ();

  if ((reload_pipe[RELOAD_READ_END] > 0) &&
      _dbus_read_socket (reload_pipe[RELOAD_READ_END], &str, 1) != 1)
    {
      _dbus_warn ("Couldn't read from reload pipe.\n");
      close_reload_pipe ();
      return TRUE;
    }
  _dbus_string_free (&str);

  /* this can only fail if we don't understand the config file
   * or OOM.  Either way we should just stick with the currently
   * loaded config.
   */
  dbus_error_init (&error);
  if (! bus_context_reload_config (context, &error))
    {
      _DBUS_ASSERT_ERROR_IS_SET (&error);
      _dbus_assert (dbus_error_has_name (&error, DBUS_ERROR_FAILED) ||
		    dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY));
      _dbus_warn ("Unable to reload configuration: %s\n",
		  error.message);
      dbus_error_free (&error);
    }
  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_user_at_console (const char *username,
                       DBusError  *error)
{

  DBusString u, f;
  dbus_bool_t result;

  result = FALSE;
  if (!_dbus_string_init (&f))
    {
      _DBUS_SET_OOM (error);
      return FALSE;
    }

  if (!_dbus_string_append (&f, DBUS_CONSOLE_AUTH_DIR))
    {
      _DBUS_SET_OOM (error);
      goto out;
    }

  _dbus_string_init_const (&u, username);

  if (!_dbus_concat_dir_and_file (&f, &u))
    {
      _DBUS_SET_OOM (error);
      goto out;
    }

  result = _dbus_file_exists (_dbus_string_get_const_data (&f));

 out:
  _dbus_string_free (&f);

  return result;
}
/**
 * Split paths into a list of char strings
 * 
 * @param dirs string with pathes 
 * @param suffix string concated to each path in dirs
 * @param dir_list contains a list of splitted pathes
 * return #TRUE is pathes could be splittes,#FALSE in oom case 
 */
dbus_bool_t
_dbus_split_paths_and_append (DBusString *dirs, 
                              const char *suffix, 
                              DBusList  **dir_list)
{
   int start;
   int i;
   int len;
   char *cpath;
   DBusString file_suffix;

   start = 0;
   i = 0;

   _dbus_string_init_const (&file_suffix, suffix);

   len = _dbus_string_get_length (dirs);

   while (_dbus_string_find (dirs, start, _DBUS_PATH_SEPARATOR, &i))
     {
       DBusString path;

       if (!_dbus_string_init (&path))
          goto oom;

       if (!_dbus_string_copy_len (dirs,
                                   start,
                                   i - start,
                                   &path,
                                   0))
          {
            _dbus_string_free (&path);
            goto oom;
          }

        _dbus_string_chop_white (&path);

        /* check for an empty path */
        if (_dbus_string_get_length (&path) == 0)
          goto next;

        if (!_dbus_concat_dir_and_file (&path,
                                        &file_suffix))
          {
            _dbus_string_free (&path);
            goto oom;
          }

        if (!_dbus_string_copy_data(&path, &cpath))
          {
            _dbus_string_free (&path);
            goto oom;
          }

        if (!_dbus_list_append (dir_list, cpath))
          {
            _dbus_string_free (&path);              
            dbus_free (cpath);
            goto oom;
          }

       next:
        _dbus_string_free (&path);
        start = i + 1;
    } 
      
  if (start != len)
    { 
      DBusString path;

      if (!_dbus_string_init (&path))
        goto oom;

      if (!_dbus_string_copy_len (dirs,
                                  start,
                                  len - start,
                                  &path,
                                  0))
        {
          _dbus_string_free (&path);
          goto oom;
        }

      if (!_dbus_concat_dir_and_file (&path,
                                      &file_suffix))
        {
          _dbus_string_free (&path);
          goto oom;
        }

      if (!_dbus_string_copy_data(&path, &cpath))
        {
          _dbus_string_free (&path);
          goto oom;
        }

      if (!_dbus_list_append (dir_list, cpath))
        {
          _dbus_string_free (&path);              
          dbus_free (cpath);
          goto oom;
        }

      _dbus_string_free (&path); 
    }

  return TRUE;

 oom:
  _dbus_list_foreach (dir_list, (DBusForeachFunction)dbus_free, NULL); 
  _dbus_list_clear (dir_list);
  return FALSE;
}
Exemple #7
0
/**
 * Tries to interpret the address entry in a platform-specific
 * way, creating a platform-specific server type if appropriate.
 * Sets error if the result is not OK.
 *
 * @param entry an address entry
 * @param server_p location to store a new DBusServer, or #NULL on failure.
 * @param error location to store rationale for failure on bad address
 * @returns the outcome
 *
 */
DBusServerListenResult
_dbus_server_listen_platform_specific (DBusAddressEntry *entry,
                                       DBusServer      **server_p,
                                       DBusError        *error)
{
  const char *method;

  *server_p = NULL;

  method = dbus_address_entry_get_method (entry);

  if (strcmp (method, "unix") == 0)
    {
      const char *path = dbus_address_entry_get_value (entry, "path");
      const char *tmpdir = dbus_address_entry_get_value (entry, "tmpdir");
      const char *abstract = dbus_address_entry_get_value (entry, "abstract");

      if (path == NULL && tmpdir == NULL && abstract == NULL)
        {
          _dbus_set_bad_address(error, "unix",
                                "path or tmpdir or abstract",
                                NULL);
          return DBUS_SERVER_LISTEN_BAD_ADDRESS;
        }

      if ((path && tmpdir) ||
          (path && abstract) ||
          (tmpdir && abstract))
        {
          _dbus_set_bad_address(error, NULL, NULL,
                                "cannot specify two of \"path\" and \"tmpdir\" and \"abstract\" at the same time");
          return DBUS_SERVER_LISTEN_BAD_ADDRESS;
        }

      if (tmpdir != NULL)
        {
          DBusString full_path;
          DBusString filename;

          if (!_dbus_string_init (&full_path))
            {
              dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
              return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
            }

          if (!_dbus_string_init (&filename))
            {
              _dbus_string_free (&full_path);
              dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
              return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
            }

          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);
              return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
            }

          /* Always use abstract namespace if possible with tmpdir */

          *server_p =
            _dbus_server_new_for_domain_socket (_dbus_string_get_const_data (&full_path),
#ifdef HAVE_ABSTRACT_SOCKETS
                                                TRUE,
#else
                                                FALSE,
#endif
                                                error);

          _dbus_string_free (&full_path);
          _dbus_string_free (&filename);
        }
      else
        {
          if (path)
            *server_p = _dbus_server_new_for_domain_socket (path, FALSE, error);
          else
            *server_p = _dbus_server_new_for_domain_socket (abstract, TRUE, error);
        }

      if (*server_p != NULL)
        {
          _DBUS_ASSERT_ERROR_IS_CLEAR(error);
          return DBUS_SERVER_LISTEN_OK;
        }
      else
        {
          _DBUS_ASSERT_ERROR_IS_SET(error);
          return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
        }
    }
  else if (strcmp (method, "systemd") == 0)
    {
      int i, n, *fds;
      DBusString address;

      n = _dbus_listen_systemd_sockets (&fds, error);
      if (n < 0)
        {
          _DBUS_ASSERT_ERROR_IS_SET (error);
          return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
        }

      if(!_dbus_string_init(&address))
          goto oom;

      for (i = 0; i < n; i++)
        {
          if ( i > 0)
            {
              if(!_dbus_string_append (&address, ";"))
                goto oom;
            }
          if(!_dbus_append_address_from_socket (fds[i], &address))
            goto oom;
        }

      *server_p = _dbus_server_new_for_socket (fds, n, &address, NULL);
      if (*server_p == NULL)
        goto oom;

      dbus_free (fds);

      return DBUS_SERVER_LISTEN_OK;
  oom:
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      for (i = 0; i < n; i++)
        {
          _dbus_close_socket (fds[i], NULL);
        }
      dbus_free (fds);
      _dbus_string_free (&address);

      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
    }
#ifdef DBUS_ENABLE_LAUNCHD
  else if (strcmp (method, "launchd") == 0)
    {
      const char *launchd_env_var = dbus_address_entry_get_value (entry, "env");
      if (launchd_env_var == NULL)
        {
          _dbus_set_bad_address (error, "launchd", "env", NULL);
          return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
        }
      *server_p = _dbus_server_new_for_launchd (launchd_env_var, error);

      if (*server_p != NULL)
        {
          _DBUS_ASSERT_ERROR_IS_CLEAR(error);
          return DBUS_SERVER_LISTEN_OK;
        }
      else
        {
          _DBUS_ASSERT_ERROR_IS_SET(error);
          return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
        }
    }
#endif
  else
    {
      /* If we don't handle the method, we return NULL with the
       * error unset
       */
      _DBUS_ASSERT_ERROR_IS_CLEAR(error);
      return DBUS_SERVER_LISTEN_NOT_HANDLED;
    }
}
Exemple #8
0
/**
 * Creates a new server listening on the given Unix domain socket.
 *
 * @param path the path for the domain socket.
 * @param abstract #TRUE to use abstract socket namespace
 * @param error location to store reason for failure.
 * @returns the new server, or #NULL on failure.
 */
DBusServer*
_dbus_server_new_for_domain_socket (const char     *path,
                                    dbus_bool_t     abstract,
                                    DBusError      *error)
{
  DBusServer *server;
  int listen_fd;
  DBusString address;
  char *path_copy;
  DBusString path_str;

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);

  if (!_dbus_string_init (&address))
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      return NULL;
    }

  _dbus_string_init_const (&path_str, path);
  if ((abstract &&
       !_dbus_string_append (&address, "unix:abstract=")) ||
      (!abstract &&
       !_dbus_string_append (&address, "unix:path=")) ||
      !_dbus_address_append_escaped (&address, &path_str))
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      goto failed_0;
    }

  if (abstract)
    {
      path_copy = NULL;
    }
  else
    {
      path_copy = _dbus_strdup (path);
      if (path_copy == NULL)
        {
          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
          goto failed_0;
        }
    }

  listen_fd = _dbus_listen_unix_socket (path, abstract, error);

  if (listen_fd < 0)
    {
      _DBUS_ASSERT_ERROR_IS_SET (error);
      goto failed_1;
    }

  server = _dbus_server_new_for_socket (&listen_fd, 1, &address, 0);
  if (server == NULL)
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      goto failed_2;
    }

  if (path_copy != NULL)
    _dbus_server_socket_own_filename(server, path_copy);

  _dbus_string_free (&address);

  return server;

 failed_2:
  _dbus_close_socket (listen_fd, NULL);
 failed_1:
  dbus_free (path_copy);
 failed_0:
  _dbus_string_free (&address);

  return NULL;
}
/**
 * Writes the given pid_to_write to a pidfile (if non-NULL) and/or to a
 * pipe (if non-NULL). Does nothing if pidfile and print_pid_pipe are both
 * NULL.
 *
 * @param pidfile the file to write to or #NULL
 * @param print_pid_pipe the pipe to write to or #NULL
 * @param pid_to_write the pid to write out
 * @param error error on failure
 * @returns FALSE if error is set
 */
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);
      
      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;
}
/**
 * Unquotes a string as the shell (/bin/sh) would. Only handles
 * quotes; if a string contains file globs, arithmetic operators,
 * variables, backticks, redirections, or other special-to-the-shell
 * features, the result will be different from the result a real shell
 * would produce (the variables, backticks, etc. will be passed
 * through literally instead of being expanded). This function is
 * guaranteed to succeed if applied to the result of
 * _dbus_shell_quote(). If it fails, it returns %NULL.
 * The @quoted_string need not actually contain quoted or
 * escaped text; _dbus_shell_unquote() simply goes through the string and
 * unquotes/unescapes anything that the shell would. Both single and
 * double quotes are handled, as are escapes including escaped
 * newlines. The return value must be freed with dbus_free().
 *
 * Shell quoting rules are a bit strange. Single quotes preserve the
 * literal string exactly. escape sequences are not allowed; not even
 * \' - if you want a ' in the quoted text, you have to do something
 * like 'foo'\''bar'.  Double quotes allow $, `, ", \, and newline to
 * be escaped with backslash. Otherwise double quotes preserve things
 * literally.
 *
 * @quoted_string: shell-quoted string
 **/
char*
_dbus_shell_unquote (const char *quoted_string)
{
    char *unquoted;
    char *end;
    char *start;
    char *ret;
    DBusString retval;

    unquoted = _dbus_strdup (quoted_string);
    if (unquoted == NULL)
        return NULL;

    start = unquoted;
    end = unquoted;
    if (!_dbus_string_init (&retval))
    {
        dbus_free (unquoted);
        return NULL;
    }

    /* The loop allows cases such as
     * "foo"blah blah'bar'woo foo"baz"la la la\'\''foo'
     */
    while (*start)
    {
        /* Append all non-quoted chars, honoring backslash escape
         */

        while (*start && !(*start == '"' || *start == '\''))
        {
            if (*start == '\\')
            {
                /* all characters can get escaped by backslash,
                 * except newline, which is removed if it follows
                 * a backslash outside of quotes
                 */

                ++start;
                if (*start)
                {
                    if (*start != '\n')
                    {
                        if (!_dbus_string_append_byte (&retval, *start))
                            goto error;
                    }
                    ++start;
                }
            }
            else
            {
                if (!_dbus_string_append_byte (&retval, *start))
                    goto error;
                ++start;
            }
        }

        if (*start)
        {
            if (!unquote_string_inplace (start, &end))
                goto error;
            else
            {
                if (!_dbus_string_append (&retval, start))
                    goto error;
                start = end;
            }
        }
    }

    ret = _dbus_strdup (_dbus_string_get_data (&retval));
    if (!ret)
        goto error;

    dbus_free (unquoted);
    _dbus_string_free (&retval);

    return ret;

error:
    dbus_free (unquoted);
    _dbus_string_free (&retval);
    return NULL;
}
Exemple #11
0
static dbus_bool_t
do_noncefile_create (DBusNonceFile *noncefile,
                     DBusError *error,
                     dbus_bool_t use_subdir)
{
    dbus_bool_t ret;
    DBusString randomStr;

    _DBUS_ASSERT_ERROR_IS_CLEAR (error);

    _dbus_assert (noncefile);

    if (!_dbus_string_init (&randomStr))
      {
        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
        goto on_error;
      }

    if (!_dbus_generate_random_ascii (&randomStr, 8))
      {
        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
        goto on_error;
      }

    if (!_dbus_string_init (&noncefile->dir)
        || !_dbus_string_append (&noncefile->dir, _dbus_get_tmpdir()))
      {
        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
        goto on_error;
      }
    if (use_subdir)
      {
        if (!_dbus_string_append (&noncefile->dir, "/dbus_nonce-")
            || !_dbus_string_append (&noncefile->dir, _dbus_string_get_const_data (&randomStr)) )
          {
            dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
            goto on_error;
          }
        if (!_dbus_string_init (&noncefile->path)
            || !_dbus_string_copy (&noncefile->dir, 0, &noncefile->path, 0)
            || !_dbus_string_append (&noncefile->dir, "/nonce"))
          {
            dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
            goto on_error;
          }
        if (!_dbus_create_directory (&noncefile->dir, error))
          {
            _DBUS_ASSERT_ERROR_IS_SET (error);
            goto on_error;
          }
        _DBUS_ASSERT_ERROR_IS_CLEAR (error);

      }
    else
      {
        if (!_dbus_string_init (&noncefile->path)
            || !_dbus_string_copy (&noncefile->dir, 0, &noncefile->path, 0)
            || !_dbus_string_append (&noncefile->path, "/dbus_nonce-")
            || !_dbus_string_append (&noncefile->path, _dbus_string_get_const_data (&randomStr)))
          {
            dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
            goto on_error;
          }

      }

    if (!generate_and_write_nonce (&noncefile->path, error))
      {
        _DBUS_ASSERT_ERROR_IS_SET (error);
        if (use_subdir)
          _dbus_delete_directory (&noncefile->dir, NULL); //we ignore possible errors deleting the dir and return the write error instead
        goto on_error;
      }
    _DBUS_ASSERT_ERROR_IS_CLEAR (error);

    _dbus_string_free (&randomStr);

    return TRUE;
  on_error:
    if (use_subdir)
      _dbus_delete_directory (&noncefile->dir, NULL);
    _dbus_string_free (&noncefile->dir);
    _dbus_string_free (&noncefile->path);
    _dbus_string_free (&randomStr);
    return FALSE;
}
/**
 * Creates a new transport for the given socket file descriptor.  The file
 * descriptor must be nonblocking (use _dbus_set_fd_nonblocking() to
 * make it so). This function is shared by various transports that
 * boil down to a full duplex file descriptor.
 *
 * @param fd the file descriptor.
 * @param server_guid non-#NULL if this transport is on the server side of a connection
 * @param address the transport's address
 * @returns the new transport, or #NULL if no memory.
 */
DBusTransport*
_dbus_transport_new_for_socket (DBusSocket        fd,
                                const DBusString *server_guid,
                                const DBusString *address)
{
  DBusTransportSocket *socket_transport;
  
  socket_transport = dbus_new0 (DBusTransportSocket, 1);
  if (socket_transport == NULL)
    return NULL;

  if (!_dbus_string_init (&socket_transport->encoded_outgoing))
    goto failed_0;

  if (!_dbus_string_init (&socket_transport->encoded_incoming))
    goto failed_1;
  
  socket_transport->write_watch = _dbus_watch_new (_dbus_socket_get_pollable (fd),
                                                 DBUS_WATCH_WRITABLE,
                                                 FALSE,
                                                 NULL, NULL, NULL);
  if (socket_transport->write_watch == NULL)
    goto failed_2;
  
  socket_transport->read_watch = _dbus_watch_new (_dbus_socket_get_pollable (fd),
                                                DBUS_WATCH_READABLE,
                                                FALSE,
                                                NULL, NULL, NULL);
  if (socket_transport->read_watch == NULL)
    goto failed_3;

  if (!_dbus_transport_init_base (&socket_transport->base,
                                  &socket_vtable,
                                  server_guid, address))
    goto failed_4;

#ifdef HAVE_UNIX_FD_PASSING
  _dbus_auth_set_unix_fd_possible(socket_transport->base.auth, _dbus_socket_can_pass_unix_fd(fd));
#endif

  socket_transport->fd = fd;
  socket_transport->message_bytes_written = 0;
  
  /* These values should probably be tunable or something. */     
  socket_transport->max_bytes_read_per_iteration = 2048;
  socket_transport->max_bytes_written_per_iteration = 2048;
  
  return (DBusTransport*) socket_transport;

 failed_4:
  _dbus_watch_invalidate (socket_transport->read_watch);
  _dbus_watch_unref (socket_transport->read_watch);
 failed_3:
  _dbus_watch_invalidate (socket_transport->write_watch);
  _dbus_watch_unref (socket_transport->write_watch);
 failed_2:
  _dbus_string_free (&socket_transport->encoded_incoming);
 failed_1:
  _dbus_string_free (&socket_transport->encoded_outgoing);
 failed_0:
  dbus_free (socket_transport);
  return NULL;
}
static dbus_bool_t
bus_driver_handle_hello (DBusConnection *connection,
                         BusTransaction *transaction,
                         DBusMessage    *message,
                         DBusError      *error)
{
  DBusString unique_name;
  BusService *service;
  dbus_bool_t retval;
  BusRegistry *registry;
  BusConnections *connections;

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);

  if (bus_connection_is_active (connection))
    {
      /* We already handled an Hello message for this connection. */
      dbus_set_error (error, DBUS_ERROR_FAILED,
                      "Already handled an Hello message");
      return FALSE;
    }

  /* Note that when these limits are exceeded we don't disconnect the
   * connection; we just sort of leave it hanging there until it times
   * out or disconnects itself or is dropped due to the max number of
   * incomplete connections. It's even OK if the connection wants to
   * retry the hello message, we support that.
   */
  connections = bus_connection_get_connections (connection);
  if (!bus_connections_check_limits (connections, connection,
                                     error))
    {
      _DBUS_ASSERT_ERROR_IS_SET (error);
      return FALSE;
    }
  
  if (!_dbus_string_init (&unique_name))
    {
      BUS_SET_OOM (error);
      return FALSE;
    }

  retval = FALSE;

  registry = bus_connection_get_registry (connection);
  
  if (!create_unique_client_name (registry, &unique_name))
    {
      BUS_SET_OOM (error);
      goto out_0;
    }

  if (!bus_connection_complete (connection, &unique_name, error))
    {
      _DBUS_ASSERT_ERROR_IS_SET (error);
      goto out_0;
    }
  
  if (!dbus_message_set_sender (message,
                                bus_connection_get_name (connection)))
    {
      BUS_SET_OOM (error);
      goto out_0;
    }
  
  if (!bus_driver_send_welcome_message (connection, message, transaction, error))
    goto out_0;

  /* Create the service */
  service = bus_registry_ensure (registry,
                                 &unique_name, connection, 0, transaction, error);
  if (service == NULL)
    goto out_0;
  
  _dbus_assert (bus_connection_is_active (connection));
  retval = TRUE;
  
 out_0:
  _dbus_string_free (&unique_name);
  return retval;
}
static dbus_bool_t
bus_driver_handle_introspect (DBusConnection *connection,
                              BusTransaction *transaction,
                              DBusMessage    *message,
                              DBusError      *error)
{
  DBusString xml;
  DBusMessage *reply;
  const char *v_STRING;
  int i;

  _dbus_verbose ("Introspect() on bus driver\n");
  
  _DBUS_ASSERT_ERROR_IS_CLEAR (error);

  reply = NULL;

  if (! dbus_message_get_args (message, error,
			       DBUS_TYPE_INVALID))
    {
      _DBUS_ASSERT_ERROR_IS_SET (error);
      return FALSE;
    }

  if (!_dbus_string_init (&xml))
    {
      BUS_SET_OOM (error);
      return FALSE;
    }

  if (!_dbus_string_append (&xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE))
    goto oom;
  if (!_dbus_string_append (&xml, "<node>\n"))
    goto oom;
  if (!_dbus_string_append_printf (&xml, "  <interface name=\"%s\">\n", DBUS_INTERFACE_INTROSPECTABLE))
    goto oom;
  if (!_dbus_string_append (&xml, "    <method name=\"Introspect\">\n"))
    goto oom;
  if (!_dbus_string_append_printf (&xml, "      <arg name=\"data\" direction=\"out\" type=\"%s\"/>\n", DBUS_TYPE_STRING_AS_STRING))
    goto oom;
  if (!_dbus_string_append (&xml, "    </method>\n"))
    goto oom;
  if (!_dbus_string_append (&xml, "  </interface>\n"))
    goto oom;

  if (!_dbus_string_append_printf (&xml, "  <interface name=\"%s\">\n",
                                   DBUS_INTERFACE_DBUS))
    goto oom;

  i = 0;
  while (i < _DBUS_N_ELEMENTS (message_handlers))
    {
	  
      if (!_dbus_string_append_printf (&xml, "    <method name=\"%s\">\n",
                                       message_handlers[i].name))
        goto oom;

      if (!write_args_for_direction (&xml, message_handlers[i].in_args, TRUE))
	goto oom;

      if (!write_args_for_direction (&xml, message_handlers[i].out_args, FALSE))
	goto oom;

      if (!_dbus_string_append (&xml, "    </method>\n"))
	goto oom;
      
      ++i;
    }

  if (!_dbus_string_append_printf (&xml, "    <signal name=\"NameOwnerChanged\">\n"))
    goto oom;
  
  if (!_dbus_string_append_printf (&xml, "      <arg type=\"s\"/>\n"))
    goto oom;
  
  if (!_dbus_string_append_printf (&xml, "      <arg type=\"s\"/>\n"))
    goto oom;
  
  if (!_dbus_string_append_printf (&xml, "      <arg type=\"s\"/>\n"))
    goto oom;
  
  if (!_dbus_string_append_printf (&xml, "    </signal>\n"))
    goto oom;



  if (!_dbus_string_append_printf (&xml, "    <signal name=\"NameLost\">\n"))
    goto oom;
  
  if (!_dbus_string_append_printf (&xml, "      <arg type=\"s\"/>\n"))
    goto oom;
  
  if (!_dbus_string_append_printf (&xml, "    </signal>\n"))
    goto oom;



  if (!_dbus_string_append_printf (&xml, "    <signal name=\"NameAcquired\">\n"))
    goto oom;
  
  if (!_dbus_string_append_printf (&xml, "      <arg type=\"s\"/>\n"))
    goto oom;
  
  if (!_dbus_string_append_printf (&xml, "    </signal>\n"))
    goto oom;


  
  if (!_dbus_string_append (&xml, "  </interface>\n"))
    goto oom;
  
  if (!_dbus_string_append (&xml, "</node>\n"))
    goto oom;

  reply = dbus_message_new_method_return (message);
  if (reply == NULL)
    goto oom;

  v_STRING = _dbus_string_get_const_data (&xml);
  if (! dbus_message_append_args (reply,
                                  DBUS_TYPE_STRING, &v_STRING,
                                  DBUS_TYPE_INVALID))
    goto oom;

  if (! bus_transaction_send_from_driver (transaction, connection, reply))
    goto oom;

  dbus_message_unref (reply);
  _dbus_string_free (&xml);

  return TRUE;

 oom:
  BUS_SET_OOM (error);

  if (reply)
    dbus_message_unref (reply);

  _dbus_string_free (&xml);
  
  return FALSE;
}
dbus_bool_t
_dbus_become_daemon (const DBusString *pidfile,
		     int               print_pid_fd,
                     DBusError        *error)
{
  const char *s;
  pid_t child_pid;
  int dev_null_fd;

  _dbus_verbose ("Becoming a daemon...\n");

  _dbus_verbose ("chdir to /\n");
  if (chdir ("/") < 0)
    {
      dbus_set_error (error, DBUS_ERROR_FAILED,
                      "Could not chdir() to root directory");
      return FALSE;
    }

  _dbus_verbose ("forking...\n");
  switch ((child_pid = fork ()))
    {
    case -1:
      _dbus_verbose ("fork failed\n");
      dbus_set_error (error, _dbus_error_from_errno (errno),
                      "Failed to fork daemon: %s", _dbus_strerror (errno));
      return FALSE;
      break;

    case 0:
      _dbus_verbose ("in child, closing std file descriptors\n");

      /* silently ignore failures here, if someone
       * doesn't have /dev/null we may as well try
       * to continue anyhow
       */
      
      dev_null_fd = open ("/dev/null", O_RDWR);
      if (dev_null_fd >= 0)
        {
          dup2 (dev_null_fd, 0);
          dup2 (dev_null_fd, 1);
          
          s = _dbus_getenv ("DBUS_DEBUG_OUTPUT");
          if (s == NULL || *s == '\0')
            dup2 (dev_null_fd, 2);
          else
            _dbus_verbose ("keeping stderr open due to DBUS_DEBUG_OUTPUT\n");
        }

      /* Get a predictable umask */
      _dbus_verbose ("setting umask\n");
      umask (022);
      break;

    default:
      if (pidfile)
        {
          _dbus_verbose ("parent writing pid file\n");
          if (!_dbus_write_pid_file (pidfile,
                                     child_pid,
                                     error))
            {
              _dbus_verbose ("pid file write failed, killing child\n");
              kill (child_pid, SIGTERM);
              return FALSE;
            }
        }

      /* Write PID if requested */
      if (print_pid_fd >= 0)
	{
	  DBusString pid;
	  int bytes;
	  
	  if (!_dbus_string_init (&pid))
	    {
	      _DBUS_SET_OOM (error);
              kill (child_pid, SIGTERM);
	      return FALSE;
	    }
	  
	  if (!_dbus_string_append_int (&pid, child_pid) ||
	      !_dbus_string_append (&pid, "\n"))
	    {
	      _dbus_string_free (&pid);
	      _DBUS_SET_OOM (error);
              kill (child_pid, SIGTERM);
	      return FALSE;
	    }
	  
	  bytes = _dbus_string_get_length (&pid);
	  if (_dbus_write_socket (print_pid_fd, &pid, 0, bytes) != bytes)
	    {
	      dbus_set_error (error, DBUS_ERROR_FAILED,
			      "Printing message bus PID: %s\n",
			      _dbus_strerror (errno));
	      _dbus_string_free (&pid);
              kill (child_pid, SIGTERM);
	      return FALSE;
	    }
	  
	  _dbus_string_free (&pid);
	}
      _dbus_verbose ("parent exiting\n");
      _exit (0);
      break;
    }

  _dbus_verbose ("calling setsid()\n");
  if (setsid () == -1)
    _dbus_assert_not_reached ("setsid() failed");
  
  return TRUE;
}
Exemple #16
0
static BusDesktopFile *
desktop_file_for_name (BusConfigParser *parser,
                       const char *name,
                       DBusError  *error)
{
  BusDesktopFile *desktop_file;
  DBusList **service_dirs;
  DBusList *link;
  DBusError tmp_error;
  DBusString full_path;
  DBusString filename;
  const char *dir;

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);

  desktop_file = NULL;

  if (!_dbus_string_init (&filename))
    {
      BUS_SET_OOM (error);
      goto out_all;
    }

  if (!_dbus_string_init (&full_path))
    {
      BUS_SET_OOM (error);
      goto out_filename;
    }

  if (!_dbus_string_append (&filename, name) ||
      !_dbus_string_append (&filename, ".service"))
    {
      BUS_SET_OOM (error);
      goto out;
    }

  service_dirs = bus_config_parser_get_service_dirs (parser);
  for (link = _dbus_list_get_first_link (service_dirs);
       link != NULL;
       link = _dbus_list_get_next_link (service_dirs, link))
    {
      dir = link->data;
      _dbus_verbose ("Looking at '%s'\n", dir);

      dbus_error_init (&tmp_error);

      /* clear the path from last time */
      _dbus_string_set_length (&full_path, 0);

      /* build the full path */
      if (!_dbus_string_append (&full_path, dir) ||
          !_dbus_concat_dir_and_file (&full_path, &filename))
        {
          BUS_SET_OOM (error);
          goto out;
        }

      _dbus_verbose ("Trying to load file '%s'\n", _dbus_string_get_data (&full_path));
      desktop_file = bus_desktop_file_load (&full_path, &tmp_error);
      if (desktop_file == NULL)
        {
          _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
          _dbus_verbose ("Could not load %s: %s: %s\n",
                         _dbus_string_get_const_data (&full_path),
                         tmp_error.name, tmp_error.message);

          /* we may have failed if the file is not found; this is not fatal */
          if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
            {
              dbus_move_error (&tmp_error, error);
              /* we only bail out on OOM */
              goto out;
            }
          dbus_error_free (&tmp_error);
        }

      /* did we find the desktop file we want? */
      if (desktop_file != NULL)
        break;
    }

  /* Didn't find desktop file; set error */
  if (desktop_file == NULL)
    {
      dbus_set_error (error, DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND,
                      "The name %s was not provided by any .service files",
                      name);
    }

out:
  _dbus_string_free (&full_path);
out_filename:
  _dbus_string_free (&filename);
out_all:
  return desktop_file;
}
Exemple #17
0
static dbus_bool_t
get_correct_parser (BusConfigParser **parser, DBusError *error)
{
  DBusString config_file;
  dbus_bool_t retval;
#ifdef ACTIVATION_LAUNCHER_TEST
  const char *test_config_file;
#endif

  retval = FALSE;

#ifdef ACTIVATION_LAUNCHER_TEST
  test_config_file = NULL;

  /* there is no _way_ we should be setuid if this define is set.
   * but we should be doubly paranoid and check... */
  if (getuid() != geteuid())
    _dbus_assert_not_reached ("dbus-daemon-launch-helper-test binary is setuid!");

  /* this is not a security hole. The environment variable is only passed in the
   * dbus-daemon-lauch-helper-test NON-SETUID launcher */
  test_config_file = _dbus_getenv ("TEST_LAUNCH_HELPER_CONFIG");
  if (test_config_file == NULL)
    {
      dbus_set_error (error, DBUS_ERROR_SPAWN_SETUP_FAILED,
                      "the TEST_LAUNCH_HELPER_CONFIG env variable is not set");
      goto out;
    }
#endif

  /* we _only_ use the predefined system config file */
  if (!_dbus_string_init (&config_file))
    {
      BUS_SET_OOM (error);
      goto out;
    }
#ifndef ACTIVATION_LAUNCHER_TEST
  if (!_dbus_string_append (&config_file, DBUS_SYSTEM_CONFIG_FILE))
    {
      BUS_SET_OOM (error);
      goto out_free_config;
    }
#else
  if (!_dbus_string_append (&config_file, test_config_file))
    {
      BUS_SET_OOM (error);
      goto out_free_config;
    }
#endif

  /* where are we pointing.... */
  _dbus_verbose ("dbus-daemon-activation-helper: using config file: %s\n",
                 _dbus_string_get_const_data (&config_file));

  /* get the dbus user */
  *parser = bus_config_load (&config_file, TRUE, NULL, error);
  if (*parser == NULL)
    {
      goto out_free_config;
    }

  /* woot */
  retval = TRUE;

out_free_config:
  _dbus_string_free (&config_file);
out:
  return retval;
}
Exemple #18
0
static dbus_bool_t
test_command_line (const char *arg1, ...)
{
  int i, original_argc, shell_argc;
  char **shell_argv;
  char **original_argv;
  char *command_line, *tmp;
  DBusString str;
  DBusList *list = NULL, *node;
  va_list var_args;
  DBusError error;

  va_start (var_args, arg1);
  _dbus_list_append (&list, (char *)arg1);
  do
    {
      tmp = va_arg (var_args, char *);
      if (!tmp)
        break;
      _dbus_list_append (&list, tmp);
    } while (tmp);
  va_end (var_args);

  original_argc = _dbus_list_get_length (&list);
  original_argv = dbus_new (char *, original_argc);
  _dbus_string_init (&str);
  for (i = 0, node = _dbus_list_get_first_link (&list); i < original_argc && node;
       i++, node = _dbus_list_get_next_link (&list, node))
    {
      original_argv[i] = node->data;
      if (i > 0)
        _dbus_string_append_byte (&str, ' ');
      _dbus_string_append (&str, original_argv[i]);
    }
  
  _dbus_list_clear (&list);
  command_line = _dbus_string_get_data (&str);
  printf ("\n\nTesting command line '%s'\n", command_line);

  dbus_error_init (&error);
  if (!_dbus_shell_parse_argv (command_line, &shell_argc, &shell_argv, &error))
    {
      fprintf (stderr, "Error parsing command line: %s\n", error.message ? error.message : "");
      return FALSE;
    }
  else
    {
      if (shell_argc != original_argc)
        {
          printf ("Number of arguments returned (%d) don't match original (%d)\n",
                  shell_argc, original_argc);
          return FALSE;
        } 
      printf ("Number of arguments: %d\n", shell_argc);
      for (i = 0; i < shell_argc; i++)
        {
          char *unquoted;
          
          unquoted = _dbus_shell_unquote (original_argv[i]);
          if (strcmp (unquoted ? unquoted : "",
                      shell_argv[i] ? shell_argv[i] : ""))
            {
              printf ("Position %d, returned argument (%s) does not match original (%s)\n",
                      i, shell_argv[i], unquoted);
              dbus_free (unquoted);
              return FALSE;
            }
          dbus_free (unquoted);
          if (shell_argv[i])
            printf ("Argument %d = %s\n", i, shell_argv[i]);
        }
      
      dbus_free_string_array (shell_argv);
    }
  
  _dbus_string_free (&str);
  
  return TRUE;
}
static dbus_bool_t
init_system_db (void)
{
  _dbus_assert (database_locked);
    
  if (system_db == NULL)
    {
      DBusError error;
      const DBusUserInfo *info;
      
      system_db = _dbus_user_database_new ();
      if (system_db == NULL)
        return FALSE;

      dbus_error_init (&error);

      if (!_dbus_user_database_get_uid (system_db,
                                        _dbus_getuid (),
                                        &info,
                                        &error))
        {
          _dbus_user_database_unref (system_db);
          system_db = NULL;
          
          if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
            {
              dbus_error_free (&error);
              return FALSE;
            }
          else
            {
              /* This really should not happen. */
              _dbus_warn ("Could not get password database information for UID of current process: %s\n",
                          error.message);
              dbus_error_free (&error);
              return FALSE;
            }
        }

      if (!_dbus_string_init (&process_username))
        {
          _dbus_user_database_unref (system_db);
          system_db = NULL;
          return FALSE;
        }

      if (!_dbus_string_init (&process_homedir))
        {
          _dbus_string_free (&process_username);
          _dbus_user_database_unref (system_db);
          system_db = NULL;
          return FALSE;
        }

      if (!_dbus_string_append (&process_username,
                                info->username) ||
          !_dbus_string_append (&process_homedir,
                                info->homedir) ||
          !_dbus_register_shutdown_func (shutdown_system_db, NULL))
        {
          _dbus_string_free (&process_username);
          _dbus_string_free (&process_homedir);
          _dbus_user_database_unref (system_db);
          system_db = NULL;
          return FALSE;
        }
    }

  return TRUE;
}
dbus_bool_t
_dbus_misc_test (void)
{
  int major, minor, micro;
  DBusString str;

  /* make sure we don't crash on NULL */
  dbus_get_version (NULL, NULL, NULL);

  /* Now verify that all the compile-time version stuff
   * is right and matches the runtime. These tests
   * are mostly intended to catch various kinds of
   * typo (mixing up major and minor, that sort of thing).
   */
  dbus_get_version (&major, &minor, &micro);

  _dbus_assert (major == DBUS_MAJOR_VERSION);
  _dbus_assert (minor == DBUS_MINOR_VERSION);
  _dbus_assert (micro == DBUS_MICRO_VERSION);

#define MAKE_VERSION(x, y, z) (((x) << 16) | ((y) << 8) | (z))

  /* check that MAKE_VERSION works and produces the intended ordering */
  _dbus_assert (MAKE_VERSION (1, 0, 0) > MAKE_VERSION (0, 0, 0));
  _dbus_assert (MAKE_VERSION (1, 1, 0) > MAKE_VERSION (1, 0, 0));
  _dbus_assert (MAKE_VERSION (1, 1, 1) > MAKE_VERSION (1, 1, 0));

  _dbus_assert (MAKE_VERSION (2, 0, 0) > MAKE_VERSION (1, 1, 1));
  _dbus_assert (MAKE_VERSION (2, 1, 0) > MAKE_VERSION (1, 1, 1));
  _dbus_assert (MAKE_VERSION (2, 1, 1) > MAKE_VERSION (1, 1, 1));

  /* check DBUS_VERSION */
  _dbus_assert (MAKE_VERSION (major, minor, micro) == DBUS_VERSION);

  /* check that ordering works with DBUS_VERSION */
  _dbus_assert (MAKE_VERSION (major - 1, minor, micro) < DBUS_VERSION);
  _dbus_assert (MAKE_VERSION (major, minor - 1, micro) < DBUS_VERSION);
  _dbus_assert (MAKE_VERSION (major, minor, micro - 1) < DBUS_VERSION);
  
  _dbus_assert (MAKE_VERSION (major + 1, minor, micro) > DBUS_VERSION);
  _dbus_assert (MAKE_VERSION (major, minor + 1, micro) > DBUS_VERSION);
  _dbus_assert (MAKE_VERSION (major, minor, micro + 1) > DBUS_VERSION);

  /* Check DBUS_VERSION_STRING */

  if (!_dbus_string_init (&str))
    _dbus_assert_not_reached ("no memory");

  if (!(_dbus_string_append_int (&str, major) &&
        _dbus_string_append_byte (&str, '.') &&
        _dbus_string_append_int (&str, minor) &&
        _dbus_string_append_byte (&str, '.') &&
        _dbus_string_append_int (&str, micro)))
    _dbus_assert_not_reached ("no memory");

  _dbus_assert (_dbus_string_equal_c_str (&str, DBUS_VERSION_STRING));

  _dbus_string_free (&str);
   
  return TRUE;
}
/**
 * Checks to see if the UID sent in is the console user
 *
 * @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_is_console_user (dbus_uid_t uid,
		       DBusError *error)
{

  DBusUserDatabase *db;
  const DBusUserInfo *info;
  dbus_bool_t result = FALSE; 

#ifdef HAVE_CONSOLE_OWNER_FILE

  DBusString f;
  DBusStat st;

  if (!_dbus_string_init (&f))
    {
      _DBUS_SET_OOM (error);
      return FALSE;
    }

  if (!_dbus_string_append(&f, DBUS_CONSOLE_OWNER_FILE))
    {
      _dbus_string_free(&f);
      _DBUS_SET_OOM (error);
      return FALSE;
    }

  if (_dbus_stat(&f, &st, NULL) && (st.uid == uid))
    {
      _dbus_string_free(&f);
      return TRUE;
    }

  _dbus_string_free(&f);

#endif /* HAVE_CONSOLE_OWNER_FILE */

  _dbus_user_database_lock_system ();

  db = _dbus_user_database_get_system ();
  if (db == NULL)
    {
      dbus_set_error (error, DBUS_ERROR_FAILED, "Could not get system database.");
      _dbus_user_database_unlock_system ();
      return FALSE;
    }

  /* TPTD: this should be cache-safe, we've locked the DB and
    _dbus_user_at_console doesn't pass it on. */
  info = _dbus_user_database_lookup (db, uid, NULL, error);

  if (info == NULL)
    {
      _dbus_user_database_unlock_system ();
       return FALSE;
    }

  result = _dbus_user_at_console (info->username, error);

  _dbus_user_database_unlock_system ();

  return result;
}
Exemple #22
0
static dbus_bool_t
handle_reload_watch (DBusWatch    *watch,
		     unsigned int  flags,
		     void         *data)
{
  DBusError error;
  DBusString str;
  char *action_str;
  char action = '\0';

  while (!_dbus_string_init (&str))
    _dbus_wait_for_memory ();

  if ((reload_pipe[RELOAD_READ_END] > 0) &&
      _dbus_read_socket (reload_pipe[RELOAD_READ_END], &str, 1) != 1)
    {
      _dbus_warn ("Couldn't read from reload pipe.\n");
      close_reload_pipe (&watch);
      return TRUE;
    }

  action_str = _dbus_string_get_data (&str);
  if (action_str != NULL)
    {
      action = action_str[0];
    }
  _dbus_string_free (&str);

  /* this can only fail if we don't understand the config file
   * or OOM.  Either way we should just stick with the currently
   * loaded config.
   */
  dbus_error_init (&error);

  switch (action)
    {
    case ACTION_RELOAD:
      if (! bus_context_reload_config (context, &error))
        {
          _DBUS_ASSERT_ERROR_IS_SET (&error);
          _dbus_assert (dbus_error_has_name (&error, DBUS_ERROR_FAILED) ||
                        dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY));
          _dbus_warn ("Unable to reload configuration: %s\n",
                      error.message);
          dbus_error_free (&error);
        }
      break;

    case ACTION_QUIT:
      {
        DBusLoop *loop;
        /*
         * On OSs without abstract sockets, we want to quit
         * gracefully rather than being killed by SIGTERM,
         * so that DBusServer gets a chance to clean up the
         * sockets from the filesystem. fd.o #38656
         */
        loop = bus_context_get_loop (context);
        if (loop != NULL)
          {
            _dbus_loop_quit (loop);
          }
      }
      break;

    default:
      break;
    }

  return TRUE;
}
/**
 * Creates a new transport for the given hostname and port.
 * If host is NULL, it will default to localhost
 *
 * @param host the host to connect to
 * @param port the port to connect to
 * @param family the address family to connect to
 * @param noncefile path to nonce file
 * @param error location to store reason for failure.
 * @returns a new transport, or #NULL on failure.
 */
DBusTransport*
_dbus_transport_new_for_tcp_socket (const char     *host,
                                    const char     *port,
                                    const char     *family,
                                    const char     *noncefile,
                                    DBusError      *error)
{
  DBusSocket fd;
  DBusTransport *transport;
  DBusString address;
  
  _DBUS_ASSERT_ERROR_IS_CLEAR (error);

  if (!_dbus_string_init (&address))
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      return NULL;
    }

  if (host == NULL)
    host = "localhost";

  if (!_dbus_string_append (&address, noncefile ? "nonce-tcp:" : "tcp:"))
    goto error;

  if (!_dbus_string_append (&address, "host=") ||
      !_dbus_string_append (&address, host))
    goto error;

  if (!_dbus_string_append (&address, ",port=") ||
      !_dbus_string_append (&address, port))
    goto error;

  if (family != NULL &&
      (!_dbus_string_append (&address, ",family=") ||
       !_dbus_string_append (&address, family)))
    goto error;

  if (noncefile != NULL &&
      (!_dbus_string_append (&address, ",noncefile=") ||
       !_dbus_string_append (&address, noncefile)))
    goto error;

  fd = _dbus_connect_tcp_socket_with_nonce (host, port, family, noncefile, error);
  if (!_dbus_socket_is_valid (fd))
    {
      _DBUS_ASSERT_ERROR_IS_SET (error);
      _dbus_string_free (&address);
      return NULL;
    }

  _dbus_verbose ("Successfully connected to tcp socket %s:%s\n",
                 host, port);
  
  transport = _dbus_transport_new_for_socket (fd, NULL, &address);
  _dbus_string_free (&address);
  if (transport == NULL)
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      _dbus_close_socket (fd, NULL);
      _dbus_socket_invalidate (&fd);
    }

  return transport;

error:
  _dbus_string_free (&address);
  dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
  return NULL;
}
static DBusList*
tokenize_command_line (const char *command_line, DBusError *error)
{
    char current_quote;
    const char *p;
    DBusString current_token;
    DBusList *retval = NULL;
    dbus_bool_t quoted;;

    current_quote = '\0';
    quoted = FALSE;
    p = command_line;

    if (!_dbus_string_init (&current_token))
    {
        _DBUS_SET_OOM (error);
        return NULL;
    }

    while (*p)
    {
        if (current_quote == '\\')
        {
            if (*p == '\n')
            {
                /* we append nothing; backslash-newline become nothing */
            }
            else
            {
                if (!_dbus_string_append_byte (&current_token, '\\') ||
                        !_dbus_string_append_byte (&current_token, *p))
                {
                    _DBUS_SET_OOM (error);
                    goto error;
                }
            }

            current_quote = '\0';
        }
        else if (current_quote == '#')
        {
            /* Discard up to and including next newline */
            while (*p && *p != '\n')
                ++p;

            current_quote = '\0';

            if (*p == '\0')
                break;
        }
        else if (current_quote)
        {
            if (*p == current_quote &&
                    /* check that it isn't an escaped double quote */
                    !(current_quote == '"' && quoted))
            {
                /* close the quote */
                current_quote = '\0';
            }

            /* Everything inside quotes, and the close quote,
             * gets appended literally.
             */

            if (!_dbus_string_append_byte (&current_token, *p))
            {
                _DBUS_SET_OOM (error);
                goto error;
            }
        }
        else
        {
            switch (*p)
            {
            case '\n':
                if (!delimit_token (&current_token, &retval, error))
                    goto error;

                _dbus_string_free (&current_token);

                if (!_dbus_string_init (&current_token))
                {
                    _DBUS_SET_OOM (error);
                    goto init_error;
                }

                break;

            case ' ':
            case '\t':
                /* If the current token contains the previous char, delimit
                 * the current token. A nonzero length
                 * token should always contain the previous char.
                 */
                if (_dbus_string_get_length (&current_token) > 0)
                {
                    if (!delimit_token (&current_token, &retval, error))
                        goto error;

                    _dbus_string_free (&current_token);

                    if (!_dbus_string_init (&current_token))
                    {
                        _DBUS_SET_OOM (error);
                        goto init_error;
                    }

                }

                /* discard all unquoted blanks (don't add them to a token) */
                break;


            /* single/double quotes are appended to the token,
             * escapes are maybe appended next time through the loop,
             * comment chars are never appended.
             */

            case '\'':
            case '"':
                if (!_dbus_string_append_byte (&current_token, *p))
                {
                    _DBUS_SET_OOM (error);
                    goto error;
                }

            /* FALL THRU */

            case '#':
            case '\\':
                current_quote = *p;
                break;

            default:
                /* Combines rules 4) and 6) - if we have a token, append to it,
                 * otherwise create a new token.
                 */
                if (!_dbus_string_append_byte (&current_token, *p))
                {
                    _DBUS_SET_OOM (error);
                    goto error;
                }
                break;
            }
        }

        /* We need to count consecutive backslashes mod 2,
         * to detect escaped doublequotes.
         */
        if (*p != '\\')
            quoted = FALSE;
        else
            quoted = !quoted;

        ++p;
    }

    if (!delimit_token (&current_token, &retval, error))
        goto error;

    if (current_quote)
    {
        dbus_set_error_const (error, DBUS_ERROR_INVALID_ARGS, "Unclosed quotes in command line");
        goto error;
    }

    if (retval == NULL)
    {
        dbus_set_error_const (error, DBUS_ERROR_INVALID_ARGS, "No tokens found in command line");
        goto error;
    }

    _dbus_string_free (&current_token);

    return retval;

error:
    _dbus_string_free (&current_token);

init_error:
    if (retval)
    {
        _dbus_list_foreach (&retval, (DBusForeachFunction) dbus_free, NULL);
        _dbus_list_clear (&retval);
    }

    return NULL;
}
static dbus_bool_t
process_test_subdir (const DBusString          *test_base_dir,
                     const char                *subdir,
                     DBusValidity               expected_validity,
                     DBusForeachMessageFileFunc function,
                     void                      *user_data)
{
  DBusString test_directory;
  DBusString filename;
  DBusDirIter *dir;
  dbus_bool_t retval;
  DBusError error = DBUS_ERROR_INIT;

  retval = FALSE;
  dir = NULL;

  if (!_dbus_string_init (&test_directory))
    _dbus_assert_not_reached ("didn't allocate test_directory\n");

  _dbus_string_init_const (&filename, subdir);

  if (!_dbus_string_copy (test_base_dir, 0,
                          &test_directory, 0))
    _dbus_assert_not_reached ("couldn't copy test_base_dir to test_directory");

  if (!_dbus_concat_dir_and_file (&test_directory, &filename))
    _dbus_assert_not_reached ("couldn't allocate full path");

  _dbus_string_free (&filename);
  if (!_dbus_string_init (&filename))
    _dbus_assert_not_reached ("didn't allocate filename string\n");

  dir = _dbus_directory_open (&test_directory, &error);
  if (dir == NULL)
    {
      _dbus_warn ("Could not open %s: %s\n",
                  _dbus_string_get_const_data (&test_directory),
                  error.message);
      dbus_error_free (&error);
      goto failed;
    }

  printf ("Testing %s:\n", subdir);

 next:
  while (_dbus_directory_get_next_file (dir, &filename, &error))
    {
      DBusString full_path;

      if (!_dbus_string_init (&full_path))
        _dbus_assert_not_reached ("couldn't init string");

      if (!_dbus_string_copy (&test_directory, 0, &full_path, 0))
        _dbus_assert_not_reached ("couldn't copy dir to full_path");

      if (!_dbus_concat_dir_and_file (&full_path, &filename))
        _dbus_assert_not_reached ("couldn't concat file to dir");

      if (_dbus_string_ends_with_c_str (&filename, ".message-raw"))
        ;
      else
        {
          if (_dbus_string_ends_with_c_str (&filename, ".message"))
            {
              _dbus_warn ("Could not load %s, message builder language no longer supported\n",
                          _dbus_string_get_const_data (&filename));
            }
          
          _dbus_verbose ("Skipping non-.message file %s\n",
                         _dbus_string_get_const_data (&filename));
	  _dbus_string_free (&full_path);
          goto next;
        }

      printf ("    %s\n",
              _dbus_string_get_const_data (&filename));

      if (! (*function) (&full_path,
                         expected_validity, user_data))
        {
          _dbus_string_free (&full_path);
          goto failed;
        }
      else
        _dbus_string_free (&full_path);
    }

  if (dbus_error_is_set (&error))
    {
      _dbus_warn ("Could not get next file in %s: %s\n",
                  _dbus_string_get_const_data (&test_directory),
                  error.message);
      dbus_error_free (&error);
      goto failed;
    }

  retval = TRUE;

 failed:

  if (dir)
    _dbus_directory_close (dir);
  _dbus_string_free (&test_directory);
  _dbus_string_free (&filename);

  return retval;
}
void
_dbus_message_data_free (DBusMessageData *data)
{
  _dbus_string_free (&data->data);
}
Exemple #27
0
/* This code only gets executed the first time the
 * config files are parsed.  It is not executed
 * when config files are reloaded.
 */
static dbus_bool_t
process_config_first_time_only (BusContext       *context,
				BusConfigParser  *parser,
                                const DBusString *address,
                                BusContextFlags   flags,
				DBusError        *error)
{
  DBusString log_prefix;
  DBusList *link;
  DBusList **addresses;
  const char *user, *pidfile;
  char **auth_mechanisms;
  DBusList **auth_mechanisms_list;
  int len;
  dbus_bool_t retval;

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);

  retval = FALSE;
  auth_mechanisms = NULL;
  pidfile = NULL;

  _dbus_init_system_log (TRUE);

  if (flags & BUS_CONTEXT_FLAG_SYSTEMD_ACTIVATION)
    context->systemd_activation = TRUE;
  else
    context->systemd_activation = FALSE;

  /* Check for an existing pid file. Of course this is a race;
   * we'd have to use fcntl() locks on the pid file to
   * avoid that. But we want to check for the pid file
   * before overwriting any existing sockets, etc.
   */

  if (flags & BUS_CONTEXT_FLAG_WRITE_PID_FILE)
    pidfile = bus_config_parser_get_pidfile (parser);

  if (pidfile != NULL)
    {
      DBusString u;
      DBusStat stbuf;

      _dbus_string_init_const (&u, pidfile);

      if (_dbus_stat (&u, &stbuf, NULL))
        {
#ifdef DBUS_CYGWIN
          DBusString p;
          long /* int */ pid;

          _dbus_string_init (&p);
          _dbus_file_get_contents(&p, &u, NULL);
          _dbus_string_parse_int(&p, 0, &pid, NULL);
          _dbus_string_free(&p);

          if ((kill((int)pid, 0))) {
            dbus_set_error(NULL, DBUS_ERROR_FILE_EXISTS,
                           "pid %ld not running, removing stale pid file\n",
                           pid);
            _dbus_delete_file(&u, NULL);
          } else {
#endif
          dbus_set_error (error, DBUS_ERROR_FAILED,
		                  "The pid file \"%s\" exists, if the message bus is not running, remove this file",
                          pidfile);
	      goto failed;
#ifdef DBUS_CYGWIN
          }
#endif
        }
    }

  /* keep around the pid filename so we can delete it later */
  context->pidfile = _dbus_strdup (pidfile);

  /* note that type may be NULL */
  context->type = _dbus_strdup (bus_config_parser_get_type (parser));
  if (bus_config_parser_get_type (parser) != NULL && context->type == NULL)
    goto oom;

  user = bus_config_parser_get_user (parser);
  if (user != NULL)
    {
      context->user = _dbus_strdup (user);
      if (context->user == NULL)
        goto oom;
    }

  /* Set up the prefix for syslog messages */
  if (!_dbus_string_init (&log_prefix))
    goto oom;
  if (context->type && !strcmp (context->type, "system"))
    {
      if (!_dbus_string_append (&log_prefix, "[system] "))
        goto oom;
    }
  else if (context->type && !strcmp (context->type, "session"))
    {
      DBusCredentials *credentials;

      credentials = _dbus_credentials_new_from_current_process ();
      if (!credentials)
        goto oom;
      if (!_dbus_string_append (&log_prefix, "[session "))
        {
          _dbus_credentials_unref (credentials);
          goto oom;
        }
      if (!_dbus_credentials_to_string_append (credentials, &log_prefix))
        {
          _dbus_credentials_unref (credentials);
          goto oom;
        }
      if (!_dbus_string_append (&log_prefix, "] "))
        {
          _dbus_credentials_unref (credentials);
          goto oom;
        }
      _dbus_credentials_unref (credentials);
    }
  if (!_dbus_string_steal_data (&log_prefix, &context->log_prefix))
    goto oom;
  _dbus_string_free (&log_prefix);

  /* Build an array of auth mechanisms */

  auth_mechanisms_list = bus_config_parser_get_mechanisms (parser);
  len = _dbus_list_get_length (auth_mechanisms_list);

  if (len > 0)
    {
      int i;

      auth_mechanisms = dbus_new0 (char*, len + 1);
      if (auth_mechanisms == NULL)
        goto oom;

      i = 0;
      link = _dbus_list_get_first_link (auth_mechanisms_list);
      while (link != NULL)
        {
          auth_mechanisms[i] = _dbus_strdup (link->data);
          if (auth_mechanisms[i] == NULL)
            goto oom;
          link = _dbus_list_get_next_link (auth_mechanisms_list, link);
          i += 1;
        }
    }
/**
 * Get a printable string describing the command used to execute
 * the process with pid.  This string should only be used for
 * informative purposes such as logging; it may not be trusted.
 * 
 * The command is guaranteed to be printable ASCII and no longer
 * than max_len.
 * 
 * @param pid Process id
 * @param str Append command to this string
 * @param max_len Maximum length of returned command
 * @param error return location for errors
 * @returns #FALSE on error
 */
dbus_bool_t 
_dbus_command_for_pid (unsigned long  pid,
                       DBusString    *str,
                       int            max_len,
                       DBusError     *error)
{
  /* This is all Linux-specific for now */
  DBusString path;
  DBusString cmdline;
  int fd;
  
  if (!_dbus_string_init (&path)) 
    {
      _DBUS_SET_OOM (error);
      return FALSE;
    }
  
  if (!_dbus_string_init (&cmdline))
    {
      _DBUS_SET_OOM (error);
      _dbus_string_free (&path);
      return FALSE;
    }
  
  if (!_dbus_string_append_printf (&path, "/proc/%ld/cmdline", pid))
    goto oom;
  
  fd = open (_dbus_string_get_const_data (&path), O_RDONLY);
  if (fd < 0) 
    {
      dbus_set_error (error,
                      _dbus_error_from_errno (errno),
                      "Failed to open \"%s\": %s",
                      _dbus_string_get_const_data (&path),
                      _dbus_strerror (errno));
      goto fail;
    }
  
  if (!_dbus_read (fd, &cmdline, max_len))
    {
      dbus_set_error (error,
                      _dbus_error_from_errno (errno),
                      "Failed to read from \"%s\": %s",
                      _dbus_string_get_const_data (&path),
                      _dbus_strerror (errno));      
      goto fail;
    }
  
  if (!_dbus_close (fd, error))
    goto fail;
  
  string_squash_nonprintable (&cmdline);  

  if (!_dbus_string_copy (&cmdline, 0, str, _dbus_string_get_length (str)))
    goto oom;

  _dbus_string_free (&cmdline);  
  _dbus_string_free (&path);
  return TRUE;
oom:
  _DBUS_SET_OOM (error);
fail:
  _dbus_string_free (&cmdline);
  _dbus_string_free (&path);
  return FALSE;
}
Exemple #29
0
int
main (int argc, char **argv)
{
  DBusError error;
  DBusString config_file;
  DBusString address;
  DBusString addr_fd;
  DBusString pid_fd;
  const char *prev_arg;
  DBusPipe print_addr_pipe;
  DBusPipe print_pid_pipe;
  int i;
  dbus_bool_t print_address;
  dbus_bool_t print_pid;
  BusContextFlags flags;

  if (!_dbus_string_init (&config_file))
    return 1;

  if (!_dbus_string_init (&address))
    return 1;

  if (!_dbus_string_init (&addr_fd))
    return 1;

  if (!_dbus_string_init (&pid_fd))
    return 1;

  print_address = FALSE;
  print_pid = FALSE;

  flags = BUS_CONTEXT_FLAG_WRITE_PID_FILE;

  prev_arg = NULL;
  i = 1;
  while (i < argc)
    {
      const char *arg = argv[i];

      if (strcmp (arg, "--help") == 0 ||
          strcmp (arg, "-h") == 0 ||
          strcmp (arg, "-?") == 0)
        {
          usage ();
        }
      else if (strcmp (arg, "--version") == 0)
        {
          version ();
        }
      else if (strcmp (arg, "--introspect") == 0)
        {
          introspect ();
        }
      else if (strcmp (arg, "--nofork") == 0)
        {
          flags &= ~BUS_CONTEXT_FLAG_FORK_ALWAYS;
          flags |= BUS_CONTEXT_FLAG_FORK_NEVER;
        }
#ifdef DBUS_UNIX
      else if (strcmp (arg, "--fork") == 0)
        {
          flags &= ~BUS_CONTEXT_FLAG_FORK_NEVER;
          flags |= BUS_CONTEXT_FLAG_FORK_ALWAYS;
        }
      else if (strcmp (arg, "--systemd-activation") == 0)
        {
          flags |= BUS_CONTEXT_FLAG_SYSTEMD_ACTIVATION;
        }
#endif
      else if (strcmp (arg, "--nopidfile") == 0)
        {
          flags &= ~BUS_CONTEXT_FLAG_WRITE_PID_FILE;
        }
      else if (strcmp (arg, "--system") == 0)
        {
          check_two_config_files (&config_file, "system");

          if (!_dbus_append_system_config_file (&config_file))
            exit (1);
        }
      else if (strcmp (arg, "--session") == 0)
        {
          check_two_config_files (&config_file, "session");

          if (!_dbus_append_session_config_file (&config_file))
            exit (1);
        }
      else if (strstr (arg, "--config-file=") == arg)
        {
          const char *file;

          check_two_config_files (&config_file, "config-file");

          file = strchr (arg, '=');
          ++file;

          if (!_dbus_string_append (&config_file, file))
            exit (1);
        }
      else if (prev_arg &&
               strcmp (prev_arg, "--config-file") == 0)
        {
          check_two_config_files (&config_file, "config-file");

          if (!_dbus_string_append (&config_file, arg))
            exit (1);
        }
      else if (strcmp (arg, "--config-file") == 0)
        {
          /* wait for next arg */
        }
      else if (strstr (arg, "--address=") == arg)
        {
          const char *file;

          check_two_addresses (&address, "address");

          file = strchr (arg, '=');
          ++file;

          if (!_dbus_string_append (&address, file))
            exit (1);
        }
      else if (prev_arg &&
               strcmp (prev_arg, "--address") == 0)
        {
          check_two_addresses (&address, "address");

          if (!_dbus_string_append (&address, arg))
            exit (1);
        }
      else if (strcmp (arg, "--address") == 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 if (strstr (arg, "--print-pid=") == arg)
        {
          const char *desc;

          check_two_pid_descriptors (&pid_fd, "print-pid");

          desc = strchr (arg, '=');
          ++desc;

          if (!_dbus_string_append (&pid_fd, desc))
            exit (1);

          print_pid = TRUE;
        }
      else if (prev_arg &&
               strcmp (prev_arg, "--print-pid") == 0)
        {
          check_two_pid_descriptors (&pid_fd, "print-pid");

          if (!_dbus_string_append (&pid_fd, arg))
            exit (1);

          print_pid = TRUE;
        }
      else if (strcmp (arg, "--print-pid") == 0)
        {
          print_pid = TRUE; /* and we'll get the next arg if appropriate */
        }
      else
        {
          usage ();
        }

      prev_arg = arg;

      ++i;
    }

  if (_dbus_string_get_length (&config_file) == 0)
    {
      fprintf (stderr, "No configuration file specified.\n");
      usage ();
    }

  _dbus_pipe_invalidate (&print_addr_pipe);
  if (print_address)
    {
      _dbus_pipe_init_stdout (&print_addr_pipe);
      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);
            }

          _dbus_pipe_init (&print_addr_pipe, val);
        }
    }
  _dbus_string_free (&addr_fd);

  _dbus_pipe_invalidate (&print_pid_pipe);
  if (print_pid)
    {
      _dbus_pipe_init_stdout (&print_pid_pipe);
      if (_dbus_string_get_length (&pid_fd) > 0)
        {
          long val;
          int end;
          if (!_dbus_string_parse_int (&pid_fd, 0, &val, &end) ||
              end != _dbus_string_get_length (&pid_fd) ||
              val < 0 || val > _DBUS_INT_MAX)
            {
              fprintf (stderr, "Invalid file descriptor: \"%s\"\n",
                       _dbus_string_get_const_data (&pid_fd));
              exit (1);
            }

          _dbus_pipe_init (&print_pid_pipe, val);
        }
    }
  _dbus_string_free (&pid_fd);

  if (!bus_selinux_pre_init ())
    {
      _dbus_warn ("SELinux pre-initialization failed\n");
      exit (1);
    }

  dbus_error_init (&error);
  context = bus_context_new (&config_file, flags,
                             &print_addr_pipe, &print_pid_pipe,
                             _dbus_string_get_length(&address) > 0 ? &address : NULL,
                             &error);
  _dbus_string_free (&config_file);
  if (context == NULL)
    {
      _dbus_warn ("Failed to start message bus: %s\n",
                  error.message);
      dbus_error_free (&error);
      exit (1);
    }

  /* bus_context_new() closes the print_addr_pipe and
   * print_pid_pipe
   */

#ifdef DBUS_UNIX
  setup_reload_pipe (bus_context_get_loop (context));

  /* POSIX signals are Unix-specific, and _dbus_set_signal_handler is
   * unimplemented (and probably unimplementable) on Windows, so there's
   * no point in trying to make the handler portable to non-Unix. */

  _dbus_set_signal_handler (SIGTERM, signal_handler);
  _dbus_set_signal_handler (SIGHUP, signal_handler);
#endif /* DBUS_UNIX */

  _dbus_verbose ("We are on D-Bus...\n");
  _dbus_loop_run (bus_context_get_loop (context));

  bus_context_shutdown (context);
  bus_context_unref (context);
  bus_selinux_shutdown ();

  return 0;
}
static void
do_byteswap_test (int byte_order)
{
  int sequence;
  DBusString signature;
  DBusString body;
  int opposite_order;

  if (!_dbus_string_init (&signature) || !_dbus_string_init (&body))
    _dbus_assert_not_reached ("oom");

  opposite_order = byte_order == DBUS_LITTLE_ENDIAN ? DBUS_BIG_ENDIAN : DBUS_LITTLE_ENDIAN;
  
  sequence = 0;
  while (dbus_internal_do_not_use_generate_bodies (sequence,
                                                   byte_order,
                                                   &signature, &body))
    {
      DBusString copy;
      DBusTypeReader body_reader;
      DBusTypeReader copy_reader;

      if (!_dbus_string_init (&copy))
        _dbus_assert_not_reached ("oom");

      if (!_dbus_string_copy (&body, 0, &copy, 0))
        _dbus_assert_not_reached ("oom");

      _dbus_marshal_byteswap (&signature, 0,
                              byte_order,
                              opposite_order,
                              &copy, 0);

      _dbus_type_reader_init (&body_reader, byte_order, &signature, 0,
                              &body, 0);
      _dbus_type_reader_init (&copy_reader, opposite_order, &signature, 0,
                              &copy, 0);
      
      if (!_dbus_type_reader_equal_values (&body_reader, &copy_reader))
        {
          _dbus_verbose_bytes_of_string (&signature, 0,
                                         _dbus_string_get_length (&signature));
          _dbus_verbose_bytes_of_string (&body, 0,
                                         _dbus_string_get_length (&body));
          _dbus_verbose_bytes_of_string (&copy, 0,
                                         _dbus_string_get_length (&copy));

          _dbus_warn ("Byte-swapped data did not have same values as original data");
          _dbus_assert_not_reached ("test failed");
        }
      
      _dbus_string_free (&copy);
      
      _dbus_string_set_length (&signature, 0);
      _dbus_string_set_length (&body, 0);
      ++sequence;
    }

  _dbus_string_free (&signature);
  _dbus_string_free (&body);

  printf ("  %d blocks swapped from order '%c' to '%c'\n",
          sequence, byte_order, opposite_order);
}