Beispiel #1
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,
				DBusError       *error)
{
  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;

  /* 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.
   */
  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))
	{
	  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;
	}
    }
  
  /* keep around the pid filename so we can delete it later */
  context->pidfile = _dbus_strdup (pidfile);

  /* 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)
	{
	  BUS_SET_OOM (error);
	  goto failed;
	}
      
      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)
	    {
	      BUS_SET_OOM (error);
	      goto failed;
	    }
          link = _dbus_list_get_next_link (auth_mechanisms_list, link);
        }
    }
int
main (int argc, char **argv)
{
#ifdef DBUS_BUILD_TESTS
  const char *dir;
  DBusString test_data_dir;

  progname = argv[0];

  if (argc > 1)
    dir = argv[1];
  else
    dir = _dbus_getenv ("DBUS_TEST_DATA");

  if (dir == NULL)
    {
      fprintf (stderr, "Must specify test data directory as argv[1] or in DBUS_TEST_DATA env variable\n");
      return 1;
    }

  _dbus_string_init_const (&test_data_dir, dir);

  if (!_dbus_threads_init_debug ())
    die ("initializing debug threads");
 
  test_pre_hook ();
  printf ("%s: Running expire list test\n", argv[0]);
  if (!bus_expire_list_test (&test_data_dir))
    die ("expire list");
  test_post_hook ();
 
  test_pre_hook ();
  printf ("%s: Running config file parser test\n", argv[0]);
  if (!bus_config_parser_test (&test_data_dir))
    die ("parser");
  test_post_hook ();

  test_pre_hook ();
  printf ("%s: Running policy test\n", argv[0]);
  if (!bus_policy_test (&test_data_dir))
    die ("policy");
  test_post_hook ();

  test_pre_hook ();
  printf ("%s: Running signals test\n", argv[0]);
  if (!bus_signals_test (&test_data_dir))
    die ("signals");
  test_post_hook ();

  test_pre_hook ();
  printf ("%s: Running SHA1 connection test\n", argv[0]);
  if (!bus_dispatch_sha1_test (&test_data_dir))
    die ("sha1");
  test_post_hook ();

  test_pre_hook ();
  printf ("%s: Running message dispatch test\n", argv[0]);
  if (!bus_dispatch_test (&test_data_dir)) 
    die ("dispatch");
  test_post_hook ();

  test_pre_hook ();
  printf ("%s: Running service files reloading test\n", argv[0]);
  if (!bus_activation_service_reload_test (&test_data_dir))
    die ("service reload");
  test_post_hook ();

  printf ("%s: Success\n", argv[0]);

  
  return 0;
#else /* DBUS_BUILD_TESTS */

  printf ("Not compiled with test support\n");
  
  return 0;
#endif
}
/**
 * Unit test for dbus-sysdeps.c.
 * 
 * @returns #TRUE on success.
 */
dbus_bool_t
_dbus_sysdeps_test (void)
{
  DBusString str;
  double val;
  int pos;

#ifdef DBUS_WIN
  check_dirname ("foo\\bar", "foo");
  check_dirname ("foo\\\\bar", "foo");
  check_dirname ("foo/\\/bar", "foo");
  check_dirname ("foo\\bar/", "foo");
  check_dirname ("foo//bar\\", "foo");
  check_dirname ("foo\\bar/", "foo");
  check_dirname ("foo/bar\\\\", "foo");
  check_dirname ("\\foo", "\\");
  check_dirname ("\\\\foo", "\\");
  check_dirname ("\\", "\\");
  check_dirname ("\\\\", "\\");
  check_dirname ("\\/", "\\");
  check_dirname ("/\\/", "/");
  check_dirname ("c:\\foo\\bar", "c:\\foo");
  check_dirname ("c:\\foo", "c:\\");
  check_dirname ("c:/foo", "c:/");
  check_dirname ("c:\\", "c:\\");
  check_dirname ("c:/", "c:/");
  check_dirname ("", ".");  
#else  
  check_dirname ("foo", ".");
  check_dirname ("foo/bar", "foo");
  check_dirname ("foo//bar", "foo");
  check_dirname ("foo///bar", "foo");
  check_dirname ("foo/bar/", "foo");
  check_dirname ("foo//bar/", "foo");
  check_dirname ("foo///bar/", "foo");
  check_dirname ("foo/bar//", "foo");
  check_dirname ("foo//bar////", "foo");
  check_dirname ("foo///bar///////", "foo");
  check_dirname ("/foo", "/");
  check_dirname ("////foo", "/");
  check_dirname ("/foo/bar", "/foo");
  check_dirname ("/foo//bar", "/foo");
  check_dirname ("/foo///bar", "/foo");
  check_dirname ("/", "/");
  check_dirname ("///", "/");
  check_dirname ("", ".");  
#endif

  _dbus_string_init_const (&str, "3.5");
  if (!_dbus_string_parse_double (&str,
				  0, &val, &pos))
    {
      _dbus_warn ("Failed to parse double");
      exit (1);
    }
  if (ABS(3.5 - val) > 1e-6)
    {
      _dbus_warn ("Failed to parse 3.5 correctly, got: %f", val);
      exit (1);
    }
  if (pos != 3)
    {
      _dbus_warn ("_dbus_string_parse_double of \"3.5\" returned wrong position %d", pos);
      exit (1);
    }

  _dbus_string_init_const (&str, "0xff");
  if (_dbus_string_parse_double (&str,
                                 0, &val, &pos))
    {
      _dbus_warn ("Should not have parsed hex as double\n");
      exit (1);
    }

#ifdef DBUS_WIN
  check_path_absolute ("c:/", TRUE);
  check_path_absolute ("c:/foo", TRUE);
  check_path_absolute ("", FALSE);
  check_path_absolute ("foo", FALSE);
  check_path_absolute ("foo/bar", FALSE);
  check_path_absolute ("", FALSE);
  check_path_absolute ("foo\\bar", FALSE);
  check_path_absolute ("c:\\", TRUE);
  check_path_absolute ("c:\\foo", TRUE);
  check_path_absolute ("c:", TRUE);
  check_path_absolute ("c:\\foo\\bar", TRUE);
  check_path_absolute ("\\", TRUE);
  check_path_absolute ("/", TRUE);
#else  
  check_path_absolute ("/", TRUE);
  check_path_absolute ("/foo", TRUE);
  check_path_absolute ("", FALSE);
  check_path_absolute ("foo", FALSE);
  check_path_absolute ("foo/bar", FALSE);
#endif
  
  return TRUE;
}
Beispiel #4
0
int
main (int argc, char **argv)
{
#ifdef DBUS_ENABLE_EMBEDDED_TESTS
  const char *dir;
  const char *only;
  DBusString test_data_dir;

  progname = argv[0];

  if (argc > 1 && strcmp (argv[1], "--tap") != 0)
    dir = argv[1];
  else
    dir = _dbus_getenv ("DBUS_TEST_DATA");

  if (argc > 2)
    only = argv[2];
  else
    only = NULL;

  if (dir == NULL)
    {
      fprintf (stderr, "Must specify test data directory as argv[1] or in DBUS_TEST_DATA env variable\n");
      return 1;
    }

  _dbus_string_init_const (&test_data_dir, dir);

#ifdef DBUS_UNIX
  /* close any inherited fds so dbus-spawn's check for close-on-exec works */
  _dbus_close_all ();
#endif

  if (!_dbus_threads_init_debug ())
    die ("initializing debug threads");

  if (only == NULL || strcmp (only, "expire-list") == 0)
    {
      test_pre_hook ();
      printf ("%s: Running expire list test\n", argv[0]);
      if (!bus_expire_list_test (&test_data_dir))
        die ("expire list");
      test_post_hook ();
    }

  if (only == NULL || strcmp (only, "config-parser") == 0)
    {
      test_pre_hook ();
      printf ("%s: Running config file parser test\n", argv[0]);
      if (!bus_config_parser_test (&test_data_dir))
        die ("parser");
      test_post_hook ();
    }

  if (only == NULL || strcmp (only, "signals") == 0)
    {
      test_pre_hook ();
      printf ("%s: Running signals test\n", argv[0]);
      if (!bus_signals_test (&test_data_dir))
        die ("signals");
      test_post_hook ();
    }

  if (only == NULL || strcmp (only, "dispatch-sha1") == 0)
    {
      test_pre_hook ();
      printf ("%s: Running SHA1 connection test\n", argv[0]);
      if (!bus_dispatch_sha1_test (&test_data_dir))
        die ("sha1");
      test_post_hook ();
    }

  if (only == NULL || strcmp (only, "dispatch") == 0)
    {
      test_pre_hook ();
      printf ("%s: Running message dispatch test\n", argv[0]);
      if (!bus_dispatch_test (&test_data_dir)) 
        die ("dispatch");
      test_post_hook ();
    }

  if (only == NULL || strcmp (only, "activation-service-reload") == 0)
    {
      test_pre_hook ();
      printf ("%s: Running service files reloading test\n", argv[0]);
      if (!bus_activation_service_reload_test (&test_data_dir))
        die ("service reload");
      test_post_hook ();
    }

#ifdef HAVE_UNIX_FD_PASSING
  if (only == NULL || strcmp (only, "unix-fds-passing") == 0)
    {
      test_pre_hook ();
      printf ("%s: Running unix fd passing test\n", argv[0]);
      if (!bus_unix_fds_passing_test (&test_data_dir))
        die ("unix fd passing");
      test_post_hook ();
    }
#endif

  printf ("%s: Success\n", argv[0]);

  
  return 0;
#else /* DBUS_ENABLE_EMBEDDED_TESTS */

  printf ("Not compiled with test support\n");
  
  return 0;
#endif
}
Beispiel #5
0
/**
 * @ingroup DBusStringInternals
 * Unit test for DBusString.
 *
 * @todo Need to write tests for _dbus_string_copy() and
 * _dbus_string_move() moving to/from each of start/middle/end of a
 * string. Also need tests for _dbus_string_move_len ()
 * 
 * @returns #TRUE on success.
 */
dbus_bool_t
_dbus_string_test (void)
{
  DBusString str;
  DBusString other;
  int i, a, end;
  long v;
  int lens[] = { 0, 1, 2, 3, 4, 5, 10, 16, 17, 18, 25, 31, 32, 33, 34, 35, 63, 64, 65, 66, 67, 68, 69, 70, 71, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136 };
  char *s;

  /* Test shortening and setting length */
  i = 0;
  while (i < _DBUS_N_ELEMENTS (lens))
    {
      int j;
      
      if (!_dbus_string_init (&str))
        _dbus_assert_not_reached ("failed to init string");

      if (!_dbus_string_set_length (&str, lens[i]))
        _dbus_assert_not_reached ("failed to set string length");

      j = lens[i];
      while (j > 0)
        {
          _dbus_assert (_dbus_string_get_length (&str) == j);
          if (j > 0)
            {
              _dbus_string_shorten (&str, 1);
              _dbus_assert (_dbus_string_get_length (&str) == (j - 1));
            }
          --j;
        }
      
      _dbus_string_free (&str);

      ++i;
    }

  /* Test equality */
  if (!_dbus_string_init (&str))
    _dbus_assert_not_reached ("oom");

  if (!_dbus_string_append (&str, "Hello World"))
    _dbus_assert_not_reached ("oom");

  _dbus_string_init_const (&other, "H");
  _dbus_assert (_dbus_string_equal_substring (&str, 0, 1, &other, 0));
  _dbus_assert (_dbus_string_equal_substring (&str, 1, 0, &other, 1));
  _dbus_string_init_const (&other, "Hello");
  _dbus_assert (_dbus_string_equal_substring (&str, 0, 5, &other, 0));
  _dbus_assert (_dbus_string_equal_substring (&str, 1, 4, &other, 1));
  _dbus_assert (_dbus_string_equal_substring (&str, 2, 3, &other, 2));
  _dbus_assert (_dbus_string_equal_substring (&str, 3, 2, &other, 3));
  _dbus_assert (_dbus_string_equal_substring (&str, 4, 1, &other, 4));
  _dbus_assert (_dbus_string_equal_substring (&str, 5, 0, &other, 5));

  _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 0));
  _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 1));
  _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 2));
  _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 3));
  _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 4));
  _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 5));

  
  _dbus_string_init_const (&other, "World");
  _dbus_assert (_dbus_string_equal_substring (&str, 6,  5, &other, 0));
  _dbus_assert (_dbus_string_equal_substring (&str, 7,  4, &other, 1));
  _dbus_assert (_dbus_string_equal_substring (&str, 8,  3, &other, 2));
  _dbus_assert (_dbus_string_equal_substring (&str, 9,  2, &other, 3));
  _dbus_assert (_dbus_string_equal_substring (&str, 10, 1, &other, 4));
  _dbus_assert (_dbus_string_equal_substring (&str, 11, 0, &other, 5));

  _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 6));
  _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 7));
  _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 8));
  _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 9));
  _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 10));
  _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 11));
  
  _dbus_string_free (&str);
  
  /* Test appending data */
  if (!_dbus_string_init (&str))
    _dbus_assert_not_reached ("failed to init string");

  i = 0;
  while (i < 10)
    {
      if (!_dbus_string_append (&str, "a"))
        _dbus_assert_not_reached ("failed to append string to string\n");

      _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 1);

      if (!_dbus_string_append_byte (&str, 'b'))
        _dbus_assert_not_reached ("failed to append byte to string\n");

      _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 2);
                    
      ++i;
    }

  _dbus_string_free (&str);

  /* Check steal_data */
  
  if (!_dbus_string_init (&str))
    _dbus_assert_not_reached ("failed to init string");

  if (!_dbus_string_append (&str, "Hello World"))
    _dbus_assert_not_reached ("could not append to string");

  i = _dbus_string_get_length (&str);
  
  if (!_dbus_string_steal_data (&str, &s))
    _dbus_assert_not_reached ("failed to steal data");

  _dbus_assert (_dbus_string_get_length (&str) == 0);
  _dbus_assert (((int)strlen (s)) == i);

  dbus_free (s);

  /* Check move */
  
  if (!_dbus_string_append (&str, "Hello World"))
    _dbus_assert_not_reached ("could not append to string");

  i = _dbus_string_get_length (&str);

  if (!_dbus_string_init (&other))
    _dbus_assert_not_reached ("could not init string");
  
  if (!_dbus_string_move (&str, 0, &other, 0))
    _dbus_assert_not_reached ("could not move");

  _dbus_assert (_dbus_string_get_length (&str) == 0);
  _dbus_assert (_dbus_string_get_length (&other) == i);

  if (!_dbus_string_append (&str, "Hello World"))
    _dbus_assert_not_reached ("could not append to string");
  
  if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other)))
    _dbus_assert_not_reached ("could not move");

  _dbus_assert (_dbus_string_get_length (&str) == 0);
  _dbus_assert (_dbus_string_get_length (&other) == i * 2);

    if (!_dbus_string_append (&str, "Hello World"))
    _dbus_assert_not_reached ("could not append to string");
  
  if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other) / 2))
    _dbus_assert_not_reached ("could not move");

  _dbus_assert (_dbus_string_get_length (&str) == 0);
  _dbus_assert (_dbus_string_get_length (&other) == i * 3);
  
  _dbus_string_free (&other);

  /* Check copy */
  
  if (!_dbus_string_append (&str, "Hello World"))
    _dbus_assert_not_reached ("could not append to string");

  i = _dbus_string_get_length (&str);
  
  if (!_dbus_string_init (&other))
    _dbus_assert_not_reached ("could not init string");
  
  if (!_dbus_string_copy (&str, 0, &other, 0))
    _dbus_assert_not_reached ("could not copy");

  _dbus_assert (_dbus_string_get_length (&str) == i);
  _dbus_assert (_dbus_string_get_length (&other) == i);

  if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other)))
    _dbus_assert_not_reached ("could not copy");

  _dbus_assert (_dbus_string_get_length (&str) == i);
  _dbus_assert (_dbus_string_get_length (&other) == i * 2);
  _dbus_assert (_dbus_string_equal_c_str (&other,
                                          "Hello WorldHello World"));

  if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other) / 2))
    _dbus_assert_not_reached ("could not copy");

  _dbus_assert (_dbus_string_get_length (&str) == i);
  _dbus_assert (_dbus_string_get_length (&other) == i * 3);
  _dbus_assert (_dbus_string_equal_c_str (&other,
                                          "Hello WorldHello WorldHello World"));
  
  _dbus_string_free (&str);
  _dbus_string_free (&other);

  /* Check replace */

  if (!_dbus_string_init (&str))
    _dbus_assert_not_reached ("failed to init string");
  
  if (!_dbus_string_append (&str, "Hello World"))
    _dbus_assert_not_reached ("could not append to string");

  i = _dbus_string_get_length (&str);
  
  if (!_dbus_string_init (&other))
    _dbus_assert_not_reached ("could not init string");
  
  if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
                                 &other, 0, _dbus_string_get_length (&other)))
    _dbus_assert_not_reached ("could not replace");

  _dbus_assert (_dbus_string_get_length (&str) == i);
  _dbus_assert (_dbus_string_get_length (&other) == i);
  _dbus_assert (_dbus_string_equal_c_str (&other, "Hello World"));
  
  if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
                                 &other, 5, 1))
    _dbus_assert_not_reached ("could not replace center space");

  _dbus_assert (_dbus_string_get_length (&str) == i);
  _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
  _dbus_assert (_dbus_string_equal_c_str (&other,
                                          "HelloHello WorldWorld"));

  
  if (!_dbus_string_replace_len (&str, 1, 1,
                                 &other,
                                 _dbus_string_get_length (&other) - 1,
                                 1))
    _dbus_assert_not_reached ("could not replace end character");
  
  _dbus_assert (_dbus_string_get_length (&str) == i);
  _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
  _dbus_assert (_dbus_string_equal_c_str (&other,
                                          "HelloHello WorldWorle"));

  _dbus_string_free (&str);
  _dbus_string_free (&other);

  /* Different tests are provided because different behaviours are
   * implemented in _dbus_string_replace_len() in function of replacing and
   * replaced lengths
   */

  if (!_dbus_string_init (&str))
    _dbus_assert_not_reached ("failed to init string");
  
  if (!_dbus_string_append (&str, "Hello World"))
    _dbus_assert_not_reached ("could not append to string");

  i = _dbus_string_get_length (&str);
  
  if (!_dbus_string_init (&other))
    _dbus_assert_not_reached ("could not init string");

  if (!_dbus_string_append (&other, "Foo String"))
    _dbus_assert_not_reached ("could not append to string");

  a = _dbus_string_get_length (&other);

  if (!_dbus_string_replace_len (&str, 0, 6,
                                 &other, 4, 0))
    _dbus_assert_not_reached ("could not replace 0 length");

  _dbus_assert (_dbus_string_get_length (&str) == i);
  _dbus_assert (_dbus_string_get_length (&other) == a + 6);
  _dbus_assert (_dbus_string_equal_c_str (&other,
                                          "Foo Hello String"));

  if (!_dbus_string_replace_len (&str, 5, 6,
                                 &other,
                                 _dbus_string_get_length (&other),
                                 0))
    _dbus_assert_not_reached ("could not replace at the end");

  _dbus_assert (_dbus_string_get_length (&str) == i);
  _dbus_assert (_dbus_string_get_length (&other) == a + 6 + 6);
  _dbus_assert (_dbus_string_equal_c_str (&other,
                                          "Foo Hello String World"));

  if (!_dbus_string_replace_len (&str, 0, 5,
                                 &other,
                                 _dbus_string_get_length (&other) - 5,
                                 5))
    _dbus_assert_not_reached ("could not replace same length");

  _dbus_assert (_dbus_string_get_length (&str) == i);
  _dbus_assert (_dbus_string_get_length (&other) == a + 6 + 6);
  _dbus_assert (_dbus_string_equal_c_str (&other,
                                          "Foo Hello String Hello"));

  if (!_dbus_string_replace_len (&str, 6, 5,
                                 &other, 4, 12))
    _dbus_assert_not_reached ("could not replace with shorter string");

  _dbus_assert (_dbus_string_get_length (&str) == i);
  _dbus_assert (_dbus_string_get_length (&other) == a + 5);
  _dbus_assert (_dbus_string_equal_c_str (&other,
                                          "Foo World Hello"));

  if (!_dbus_string_replace_len (&str, 0, 1,
                                 &other, 0, 3))
    _dbus_assert_not_reached ("could not replace at the beginning");

  _dbus_assert (_dbus_string_get_length (&str) == i);
  _dbus_assert (_dbus_string_get_length (&other) == a + 3);
  _dbus_assert (_dbus_string_equal_c_str (&other,
                                          "H World Hello"));

  if (!_dbus_string_replace_len (&str, 6, 5,
                                 &other,
                                 _dbus_string_get_length (&other) - 5,
                                 5))
    _dbus_assert_not_reached ("could not replace same length");

  _dbus_assert (_dbus_string_get_length (&str) == i);
  _dbus_assert (_dbus_string_get_length (&other) == a + 3);
  _dbus_assert (_dbus_string_equal_c_str (&other,
                                          "H World World"));

  _dbus_string_free (&str);
  _dbus_string_free (&other);

  /* Check insert/set/get byte */
  
  if (!_dbus_string_init (&str))
    _dbus_assert_not_reached ("failed to init string");

  if (!_dbus_string_append (&str, "Hello"))
    _dbus_assert_not_reached ("failed to append Hello");

  _dbus_assert (_dbus_string_get_byte (&str, 0) == 'H');
  _dbus_assert (_dbus_string_get_byte (&str, 1) == 'e');
  _dbus_assert (_dbus_string_get_byte (&str, 2) == 'l');
  _dbus_assert (_dbus_string_get_byte (&str, 3) == 'l');
  _dbus_assert (_dbus_string_get_byte (&str, 4) == 'o');

  _dbus_string_set_byte (&str, 1, 'q');
  _dbus_assert (_dbus_string_get_byte (&str, 1) == 'q');

  if (!_dbus_string_insert_bytes (&str, 0, 1, 255))
    _dbus_assert_not_reached ("can't insert byte");

  if (!_dbus_string_insert_bytes (&str, 2, 4, 'Z'))
    _dbus_assert_not_reached ("can't insert byte");

  if (!_dbus_string_insert_bytes (&str, _dbus_string_get_length (&str), 1, 'W'))
    _dbus_assert_not_reached ("can't insert byte");
  
  _dbus_assert (_dbus_string_get_byte (&str, 0) == 255);
  _dbus_assert (_dbus_string_get_byte (&str, 1) == 'H');
  _dbus_assert (_dbus_string_get_byte (&str, 2) == 'Z');
  _dbus_assert (_dbus_string_get_byte (&str, 3) == 'Z');
  _dbus_assert (_dbus_string_get_byte (&str, 4) == 'Z');
  _dbus_assert (_dbus_string_get_byte (&str, 5) == 'Z');
  _dbus_assert (_dbus_string_get_byte (&str, 6) == 'q');
  _dbus_assert (_dbus_string_get_byte (&str, 7) == 'l');
  _dbus_assert (_dbus_string_get_byte (&str, 8) == 'l');
  _dbus_assert (_dbus_string_get_byte (&str, 9) == 'o');
  _dbus_assert (_dbus_string_get_byte (&str, 10) == 'W');

  _dbus_string_free (&str);
  
  /* Check append/parse int/double */
  
  if (!_dbus_string_init (&str))
    _dbus_assert_not_reached ("failed to init string");

  if (!_dbus_string_append_int (&str, 27))
    _dbus_assert_not_reached ("failed to append int");

  i = _dbus_string_get_length (&str);

  if (!_dbus_string_parse_int (&str, 0, &v, &end))
    _dbus_assert_not_reached ("failed to parse int");

  _dbus_assert (v == 27);
  _dbus_assert (end == i);

  _dbus_string_free (&str);

  /* Test find */
  if (!_dbus_string_init (&str))
    _dbus_assert_not_reached ("failed to init string");

  if (!_dbus_string_append (&str, "Hello"))
    _dbus_assert_not_reached ("couldn't append to string");
  
  if (!_dbus_string_find (&str, 0, "He", &i))
    _dbus_assert_not_reached ("didn't find 'He'");
  _dbus_assert (i == 0);

  if (!_dbus_string_find (&str, 0, "Hello", &i))
    _dbus_assert_not_reached ("didn't find 'Hello'");
  _dbus_assert (i == 0);
  
  if (!_dbus_string_find (&str, 0, "ello", &i))
    _dbus_assert_not_reached ("didn't find 'ello'");
  _dbus_assert (i == 1);

  if (!_dbus_string_find (&str, 0, "lo", &i))
    _dbus_assert_not_reached ("didn't find 'lo'");
  _dbus_assert (i == 3);

  if (!_dbus_string_find (&str, 2, "lo", &i))
    _dbus_assert_not_reached ("didn't find 'lo'");
  _dbus_assert (i == 3);

  if (_dbus_string_find (&str, 4, "lo", &i))
    _dbus_assert_not_reached ("did find 'lo'");
  
  if (!_dbus_string_find (&str, 0, "l", &i))
    _dbus_assert_not_reached ("didn't find 'l'");
  _dbus_assert (i == 2);

  if (!_dbus_string_find (&str, 0, "H", &i))
    _dbus_assert_not_reached ("didn't find 'H'");
  _dbus_assert (i == 0);

  if (!_dbus_string_find (&str, 0, "", &i))
    _dbus_assert_not_reached ("didn't find ''");
  _dbus_assert (i == 0);
  
  if (_dbus_string_find (&str, 0, "Hello!", NULL))
    _dbus_assert_not_reached ("Did find 'Hello!'");

  if (_dbus_string_find (&str, 0, "Oh, Hello", NULL))
    _dbus_assert_not_reached ("Did find 'Oh, Hello'");
  
  if (_dbus_string_find (&str, 0, "ill", NULL))
    _dbus_assert_not_reached ("Did find 'ill'");

  if (_dbus_string_find (&str, 0, "q", NULL))
    _dbus_assert_not_reached ("Did find 'q'");

  if (!_dbus_string_find_to (&str, 0, 2, "He", NULL))
    _dbus_assert_not_reached ("Didn't find 'He'");

  if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL))
    _dbus_assert_not_reached ("Did find 'Hello'");

  if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i))
    _dbus_assert_not_reached ("Did not find 'H'");
  _dbus_assert (i == 0);

  if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i))
    _dbus_assert_not_reached ("Did not find 'o'");
  _dbus_assert (i == _dbus_string_get_length (&str) - 1);

  if (_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str) - 1, 'o', &i))
    _dbus_assert_not_reached ("Did find 'o'");
  _dbus_assert (i == -1);

  if (_dbus_string_find_byte_backward (&str, 1, 'e', &i))
    _dbus_assert_not_reached ("Did find 'e'");
  _dbus_assert (i == -1);

  if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i))
    _dbus_assert_not_reached ("Didn't find 'e'");
  _dbus_assert (i == 1);
  
  _dbus_string_free (&str);

  /* Hex encoding */
  _dbus_string_init_const (&str, "cafebabe, this is a bogus hex string");
  if (!_dbus_string_init (&other))
    _dbus_assert_not_reached ("could not init string");

  if (!_dbus_string_hex_decode (&str, 0, &end, &other, 0))
    _dbus_assert_not_reached ("deccoded bogus hex string with no error");

  _dbus_assert (end == 8);

  _dbus_string_free (&other);

  test_roundtrips (test_hex_roundtrip);
  
  _dbus_string_free (&str);

  {                                                                                           
    int found, found_len;  

    _dbus_string_init_const (&str, "012\r\n567\n90");
    
    if (!_dbus_string_find_eol (&str, 0, &found, &found_len) || found != 3 || found_len != 2)
      _dbus_assert_not_reached ("Did not find '\\r\\n'");                                       
    if (found != 3 || found_len != 2)                                                           
      _dbus_assert_not_reached ("invalid return values");                                       
    
    if (!_dbus_string_find_eol (&str, 5, &found, &found_len))                                    
      _dbus_assert_not_reached ("Did not find '\\n'");                                          
    if (found != 8 || found_len != 1)                                                           
      _dbus_assert_not_reached ("invalid return values");                                       
    
    if (_dbus_string_find_eol (&str, 9, &found, &found_len))                                     
      _dbus_assert_not_reached ("Found not expected '\\n'");                                    
    else if (found != 11 || found_len != 0)                                                     
      _dbus_assert_not_reached ("invalid return values '\\n'");                                 

    found = -1;
    found_len = -1;
    _dbus_string_init_const (&str, "");
    if (_dbus_string_find_eol (&str, 0, &found, &found_len))
      _dbus_assert_not_reached ("found an eol in an empty string");
    _dbus_assert (found == 0);
    _dbus_assert (found_len == 0);
    
    found = -1;
    found_len = -1;
    _dbus_string_init_const (&str, "foobar");
    if (_dbus_string_find_eol (&str, 0, &found, &found_len))
      _dbus_assert_not_reached ("found eol in string that lacks one");
    _dbus_assert (found == 6);
    _dbus_assert (found_len == 0);

    found = -1;
    found_len = -1;
    _dbus_string_init_const (&str, "foobar\n");
    if (!_dbus_string_find_eol (&str, 0, &found, &found_len))
      _dbus_assert_not_reached ("did not find eol in string that has one at end");
    _dbus_assert (found == 6);
    _dbus_assert (found_len == 1);
  }

  {
    DBusString line;

#define FIRST_LINE "this is a line"
#define SECOND_LINE "this is a second line"
    /* third line is empty */
#define THIRD_LINE ""
#define FOURTH_LINE "this is a fourth line"
    
    if (!_dbus_string_init (&str))
      _dbus_assert_not_reached ("no memory");

    if (!_dbus_string_append (&str, FIRST_LINE "\n" SECOND_LINE "\r\n" THIRD_LINE "\n" FOURTH_LINE))
      _dbus_assert_not_reached ("no memory");
    
    if (!_dbus_string_init (&line))
      _dbus_assert_not_reached ("no memory");
    
    if (!_dbus_string_pop_line (&str, &line))
      _dbus_assert_not_reached ("failed to pop first line");

    _dbus_assert (_dbus_string_equal_c_str (&line, FIRST_LINE));
    
    if (!_dbus_string_pop_line (&str, &line))
      _dbus_assert_not_reached ("failed to pop second line");

    _dbus_assert (_dbus_string_equal_c_str (&line, SECOND_LINE));
    
    if (!_dbus_string_pop_line (&str, &line))
      _dbus_assert_not_reached ("failed to pop third line");

    _dbus_assert (_dbus_string_equal_c_str (&line, THIRD_LINE));
    
    if (!_dbus_string_pop_line (&str, &line))
      _dbus_assert_not_reached ("failed to pop fourth line");

    _dbus_assert (_dbus_string_equal_c_str (&line, FOURTH_LINE));
    
    _dbus_string_free (&str);
    _dbus_string_free (&line);
  }

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

    for (i = 0; i < 10000; i++)
      if (!_dbus_string_append (&str, "abcdefghijklmnopqrstuvwxyz"))
        _dbus_assert_not_reached ("no memory");

    if (!_dbus_string_set_length (&str, 10))
      _dbus_assert_not_reached ("failed to set length");

    /* actually compact */
    if (!_dbus_string_compact (&str, 2048))
      _dbus_assert_not_reached ("failed to compact after set_length");

    /* peek inside to make sure it worked */
    if (((DBusRealString *)&str)->allocated > 30)
      _dbus_assert_not_reached ("compacting string didn't do anything");

    if (!_dbus_string_equal_c_str (&str, "abcdefghij"))
      _dbus_assert_not_reached ("unexpected content after compact");

    /* compact nothing */
    if (!_dbus_string_compact (&str, 2048))
      _dbus_assert_not_reached ("failed to compact 2nd time");

    if (!_dbus_string_equal_c_str (&str, "abcdefghij"))
      _dbus_assert_not_reached ("unexpected content after 2nd compact");

    /* and make sure it still works...*/
    if (!_dbus_string_append (&str, "123456"))
      _dbus_assert_not_reached ("failed to append after compact");

    if (!_dbus_string_equal_c_str (&str, "abcdefghij123456"))
      _dbus_assert_not_reached ("unexpected content after append");

    /* after growing automatically, this should do nothing */
    if (!_dbus_string_compact (&str, 20000))
      _dbus_assert_not_reached ("failed to compact after grow");

    /* but this one will do something */
    if (!_dbus_string_compact (&str, 0))
      _dbus_assert_not_reached ("failed to compact after grow");

    if (!_dbus_string_equal_c_str (&str, "abcdefghij123456"))
      _dbus_assert_not_reached ("unexpected content");

    if (!_dbus_string_append (&str, "!@#$%"))
      _dbus_assert_not_reached ("failed to append after compact");

    if (!_dbus_string_equal_c_str (&str, "abcdefghij123456!@#$%"))
      _dbus_assert_not_reached ("unexpected content");

    _dbus_string_free (&str);
  }

  {
    const char two_strings[] = "one\ttwo";

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

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

    if (!_dbus_string_append (&str, two_strings))
      _dbus_assert_not_reached ("no memory");

    if (!_dbus_string_split_on_byte (&str, '\t', &other))
      _dbus_assert_not_reached ("no memory or delimiter not found");

    if (strcmp (_dbus_string_get_data (&str), "one") != 0)
      _dbus_assert_not_reached ("left side after split on tab is wrong");

    if (strcmp (_dbus_string_get_data (&other), "two") != 0)
      _dbus_assert_not_reached ("right side after split on tab is wrong");

    _dbus_string_free (&str);
    _dbus_string_free (&other);
  }

  {
    const char upper_string[] = "TOUPPERSTRING";
    const char lower_string[] = "toupperstring";
    const char lower2_string[] = "toupperSTRING";

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

    if (!_dbus_string_append (&str, upper_string))
      _dbus_assert_not_reached ("no memory");

    _dbus_string_tolower_ascii (&str, 0, _dbus_string_get_length(&str));

    if (!_dbus_string_equal_c_str (&str, lower_string))
      _dbus_assert_not_reached ("_dbus_string_tolower_ascii failed");

    _dbus_string_free (&str);

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

    if (!_dbus_string_append (&str, upper_string))
      _dbus_assert_not_reached ("no memory");

    _dbus_string_tolower_ascii (&str, 0, 7);

    if (!_dbus_string_equal_c_str (&str, lower2_string))
      _dbus_assert_not_reached ("_dbus_string_tolower_ascii failed in partial conversion");

    _dbus_string_free (&str);
  }

  {
    const char lower_string[] = "toupperstring";
    const char upper_string[] = "TOUPPERSTRING";
    const char upper2_string[] = "TOUPPERstring";

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

    if (!_dbus_string_append (&str, lower_string))
      _dbus_assert_not_reached ("no memory");

    _dbus_string_toupper_ascii (&str, 0, _dbus_string_get_length(&str));

    if (!_dbus_string_equal_c_str (&str, upper_string))
      _dbus_assert_not_reached ("_dbus_string_toupper_ascii failed");

    _dbus_string_free (&str);

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

    if (!_dbus_string_append (&str, lower_string))
      _dbus_assert_not_reached ("no memory");

    _dbus_string_toupper_ascii (&str, 0, 7);

    if (!_dbus_string_equal_c_str (&str, upper2_string))
      _dbus_assert_not_reached ("_dbus_string_toupper_ascii failed in partial conversion");

    _dbus_string_free (&str);
  }

  return TRUE;
}
BusConfigParser*
bus_config_load (const DBusString      *file,
                 dbus_bool_t            is_toplevel,
                 const BusConfigParser *parent,
                 DBusError             *error)

{
  xmlTextReader *reader;
  BusConfigParser *parser;
  DBusString dirname, data;
  DBusError tmp_error;
  int ret;
  
  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
  
  parser = NULL;
  reader = NULL;

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

  if (!_dbus_string_init (&data))
    {
      _DBUS_SET_OOM (error);
      _dbus_string_free (&dirname);
      return NULL;
    }

  if (is_toplevel)
    {
      /* xmlMemSetup only fails if one of the functions is NULL */
    /*
      xmlMemSetup (dbus_free,
                   dbus_malloc,
                   dbus_realloc,
                   _dbus_strdup);
     */              
      xmlInitParser ();
      xmlSetGenericErrorFunc (NULL, xml_shut_up);
    }

  if (!_dbus_string_get_dirname (file, &dirname))
    {
      _DBUS_SET_OOM (error);
      goto failed;
    }
  
  parser = bus_config_parser_new (&dirname, is_toplevel, parent);
  if (parser == NULL)
    {
      _DBUS_SET_OOM (error);
      goto failed;
    }
  
  if (!_dbus_file_get_contents (&data, file, error))
    goto failed;

  reader = xmlReaderForMemory (_dbus_string_get_const_data (&data), 
                               _dbus_string_get_length (&data),
			       NULL, NULL, 0);
  if (reader == NULL)
    {
      _DBUS_SET_OOM (error);
      goto failed;
    }

  xmlTextReaderSetParserProp (reader, XML_PARSER_SUBST_ENTITIES, 1);

  dbus_error_init (&tmp_error);
  xmlTextReaderSetStructuredErrorHandler (reader, xml_text_reader_error, &tmp_error);

  while ((ret = xmlTextReaderRead (reader)) == 1)
    {
      int type;
      
      if (dbus_error_is_set (&tmp_error))
        goto reader_out;

      type = xmlTextReaderNodeType (reader);
      if (type == -1)
        {
          _DBUS_MAYBE_SET_OOM (&tmp_error);
          goto reader_out;
        }

      switch ((xmlReaderTypes) type) {
      case XML_READER_TYPE_ELEMENT:
	xml_text_start_element (parser, reader, &tmp_error);
	break;

      case XML_READER_TYPE_TEXT:
      case XML_READER_TYPE_CDATA:
	{
	  DBusString content;
	  const char *value;
#ifdef __SYMBIAN32__
	  value = (const char *) xmlTextReaderConstValue (reader);
#else
	  value = xmlTextReaderConstValue (reader);
#endif
	  if (value != NULL)
	    {
	      _dbus_string_init_const (&content, value);
	      bus_config_parser_content (parser, &content, &tmp_error);
	    }
          else
            _DBUS_MAYBE_SET_OOM (&tmp_error);
	  break;
	}

      case XML_READER_TYPE_DOCUMENT_TYPE:
	{
	  const char *name;
#ifdef __SYMBIAN32__
	  name = (const char *) xmlTextReaderConstName (reader);
#else
	  name = xmlTextReaderConstName (reader);
#endif
	  if (name != NULL)
	    bus_config_parser_check_doctype (parser, name, &tmp_error);
          else
            _DBUS_MAYBE_SET_OOM (&tmp_error);
	  break;
	}

      case XML_READER_TYPE_END_ELEMENT:
	{
	  const char *name;
#ifdef __SYMBIAN32__
	  name = (const char *) xmlTextReaderConstName (reader);
#else
	  name = xmlTextReaderConstName (reader);
#endif
	  if (name != NULL)
	    bus_config_parser_end_element (parser, name, &tmp_error);
          else
            _DBUS_MAYBE_SET_OOM (&tmp_error);
	  break;
	}

      case XML_READER_TYPE_DOCUMENT:
      case XML_READER_TYPE_DOCUMENT_FRAGMENT:
      case XML_READER_TYPE_PROCESSING_INSTRUCTION:
      case XML_READER_TYPE_COMMENT:
      case XML_READER_TYPE_ENTITY:
      case XML_READER_TYPE_NOTATION:
      case XML_READER_TYPE_WHITESPACE:
      case XML_READER_TYPE_SIGNIFICANT_WHITESPACE:
      case XML_READER_TYPE_END_ENTITY:
      case XML_READER_TYPE_XML_DECLARATION:
	/* nothing to do, just read on */
	break;

      case XML_READER_TYPE_NONE:
      case XML_READER_TYPE_ATTRIBUTE:
      case XML_READER_TYPE_ENTITY_REFERENCE:
	_dbus_assert_not_reached ("unexpected nodes in XML");
      }

      if (dbus_error_is_set (&tmp_error))
        goto reader_out;
    }

  if (ret == -1)
    _DBUS_MAYBE_SET_OOM (&tmp_error);

 reader_out:
  xmlFreeTextReader (reader);
  reader = NULL;
  if (dbus_error_is_set (&tmp_error))
    {
      dbus_move_error (&tmp_error, error);
      goto failed;
    }
  
  if (!bus_config_parser_finished (parser, error))
    goto failed;
  _dbus_string_free (&dirname);
  _dbus_string_free (&data);
  if (is_toplevel)
    xmlCleanupParser();
  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
  return parser;
  
 failed:
  _DBUS_ASSERT_ERROR_IS_SET (error);
  _dbus_string_free (&dirname);
  _dbus_string_free (&data);
  if (is_toplevel)
    xmlCleanupParser();
  if (parser)
    bus_config_parser_unref (parser);
  _dbus_assert (reader == NULL); /* must go to reader_out first */
  return NULL;
}
/**
 * Creates a new server listening on TCP.
 * If host is NULL, it will default to localhost.
 * If bind is NULL, it will default to the value for the host
 * parameter, and if that is NULL, then localhost
 * If bind is a hostname, it will be resolved and will listen
 * on all returned addresses.
 * If family is NULL, hostname resolution will try all address
 * families, otherwise it can be ipv4 or ipv6 to restrict the
 * addresses considered.
 *
 * @param host the hostname to report for the listen address
 * @param bind the hostname to listen on
 * @param port the port to listen on or 0 to let the OS choose
 * @param family
 * @param error location to store reason for failure.
 * @param use_nonce whether to use a nonce for low-level authentication (nonce-tcp transport) or not (tcp transport)
 * @returns the new server, or #NULL on failure.
 */
DBusServer*
_dbus_server_new_for_tcp_socket (const char     *host,
                                 const char     *bind,
                                 const char     *port,
                                 const char     *family,
                                 DBusError      *error,
                                 dbus_bool_t    use_nonce)
{
  DBusServer *server;
  int *listen_fds = NULL;
  int nlisten_fds = 0, i;
  DBusString address;
  DBusString host_str;
  DBusString port_str;
  DBusNonceFile *noncefile;
  
  _DBUS_ASSERT_ERROR_IS_CLEAR (error);

  noncefile = NULL;

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

  if (!_dbus_string_init (&port_str))
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      goto failed_0;
    }

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

  if (port == NULL)
    port = "0";

  if (bind == NULL)
    bind = host;
  else if (strcmp (bind, "*") == 0)
    bind = NULL;

  nlisten_fds =_dbus_listen_tcp_socket (bind, port, family,
                                        &port_str,
                                        &listen_fds, error);
  if (nlisten_fds <= 0)
    {
      _DBUS_ASSERT_ERROR_IS_SET(error);
      goto failed_1;
    }

  _dbus_string_init_const (&host_str, host);
  if (!_dbus_string_append (&address, use_nonce ? "nonce-tcp:host=" : "tcp:host=") ||
      !_dbus_address_append_escaped (&address, &host_str) ||
      !_dbus_string_append (&address, ",port=") ||
      !_dbus_string_append (&address, _dbus_string_get_const_data(&port_str)))
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      goto failed_2;
    }
  if (family &&
      (!_dbus_string_append (&address, ",family=") ||
       !_dbus_string_append (&address, family)))
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      goto failed_2;
    }

  if (use_nonce)
    {
      noncefile = dbus_new0 (DBusNonceFile, 1);
      if (noncefile == NULL)
        {
          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
          goto failed_2;
        }

      if (!_dbus_noncefile_create (noncefile, error))
          goto failed_3;

      if (!_dbus_string_append (&address, ",noncefile=") ||
          !_dbus_address_append_escaped (&address, _dbus_noncefile_get_path (noncefile)))
        {
          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
          goto failed_4;
        }

    }

  server = _dbus_server_new_for_socket (listen_fds, nlisten_fds, &address, noncefile);
  if (server == NULL)
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      goto failed_4;
    }

  _dbus_string_free (&port_str);
  _dbus_string_free (&address);
  dbus_free(listen_fds);

  return server;

 failed_4:
  _dbus_noncefile_delete (noncefile, NULL);

 failed_3:
  dbus_free (noncefile);

 failed_2:
  for (i = 0 ; i < nlisten_fds ; i++)
    _dbus_close_socket (listen_fds[i], NULL);
  dbus_free(listen_fds);

 failed_1:
  _dbus_string_free (&port_str);

 failed_0:
  _dbus_string_free (&address);

  return NULL;
}
Beispiel #8
0
Datei: bus.c Projekt: mirsal/dbus
/* 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,
                                dbus_bool_t      systemd_activation,
				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;

  _dbus_init_system_log ();

  context->systemd_activation = systemd_activation;

  /* 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.
   */
  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);
        }
    }
/**
 * Creates a new debug server using an in-process pipe
 *
 * @param server_name the name of the server.
 * @param error address where an error can be returned.
 * @returns a new server, or #NULL on failure.
 */
DBusServer*
_dbus_server_debug_pipe_new (const char     *server_name,
                             DBusError      *error)
{
    DBusServerDebugPipe *debug_server;
    DBusString address;
    DBusString name_str;

    _DBUS_ASSERT_ERROR_IS_CLEAR (error);

    if (!pipe_hash_ref ())
        return NULL;

    if (_dbus_hash_table_lookup_string (server_pipe_hash, server_name) != NULL)
    {
        dbus_set_error (error, DBUS_ERROR_ADDRESS_IN_USE, NULL);
        pipe_hash_unref ();
        return NULL;
    }

    debug_server = dbus_new0 (DBusServerDebugPipe, 1);
    if (debug_server == NULL)
        goto nomem_0;

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

    _dbus_string_init_const (&name_str, server_name);
    if (!_dbus_string_append (&address, "debug-pipe:name=") ||
            !_dbus_address_append_escaped (&address, &name_str))
        goto nomem_2;

    debug_server->name = _dbus_strdup (server_name);
    if (debug_server->name == NULL)
        goto nomem_2;

    if (!_dbus_server_init_base (&debug_server->base,
                                 &debug_vtable, &address))
        goto nomem_3;

    if (!_dbus_hash_table_insert_string (server_pipe_hash,
                                         debug_server->name,
                                         debug_server))
        goto nomem_4;

    _dbus_string_free (&address);

    /* server keeps the pipe hash ref */

    return (DBusServer *)debug_server;

nomem_4:
    _dbus_server_finalize_base (&debug_server->base);
nomem_3:
    dbus_free (debug_server->name);
nomem_2:
    _dbus_string_free (&address);
nomem_1:
    dbus_free (debug_server);
nomem_0:
    pipe_hash_unref ();
    dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
    return NULL;
}
static dbus_bool_t
process_test_valid_subdir (const DBusString *test_base_dir,
                           const char       *subdir,
                           Validity          validity)
{
  DBusString test_directory;
  DBusString filename;
  DBusDirIter *dir;
  dbus_bool_t retval;
  DBusError error;

  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");

  dbus_error_init (&error);
  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;
    }

  if (validity == VALID)
    printf ("Testing valid files:\n");
  else if (validity == INVALID)
    printf ("Testing invalid files:\n");
  else
    printf ("Testing unknown files:\n");

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

      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 (&full_path, ".conf"))
        {
          _dbus_verbose ("Skipping non-.conf 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));

      _dbus_verbose (" expecting %s\n",
                     validity == VALID ? "valid" :
                     (validity == INVALID ? "invalid" :
                      (validity == UNKNOWN ? "unknown" : "???")));

      d.full_path = &full_path;
      d.validity = validity;

      /* FIXME hackaround for an expat problem, see
       * https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=124747
       * http://freedesktop.org/pipermail/dbus/2004-May/001153.html
       */
      /* if (!_dbus_test_oom_handling ("config-loader", check_loader_oom_func, &d)) */
      if (!check_loader_oom_func (&d))
        _dbus_assert_not_reached ("test failed");
      
      _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;
}
/**
 * Runs an "auth script" which is a script for testing the
 * authentication protocol. Scripts send and receive data, and then
 * include assertions about the state of both ends of the connection
 * after processing the data. A script succeeds if these assertions
 * hold.
 *
 * @param filename the file containing the script to run
 * @returns #TRUE if the script succeeds, #FALSE otherwise
 */
dbus_bool_t
_dbus_auth_script_run (const DBusString *filename)
{
  DBusString file;
  DBusError error = DBUS_ERROR_INIT;
  DBusString line;
  dbus_bool_t retval;
  int line_no;
  DBusAuth *auth;
  DBusString from_auth;
  DBusAuthState state;
  DBusString context;
  DBusString guid;
  
  retval = FALSE;
  auth = NULL;

  _dbus_string_init_const (&guid, "5fa01f4202cd837709a3274ca0df9d00");
  _dbus_string_init_const (&context, "org_freedesktop_test");
  
  if (!_dbus_string_init (&file))
    return FALSE;

  if (!_dbus_string_init (&line))
    {
      _dbus_string_free (&file);
      return FALSE;
    }

  if (!_dbus_string_init (&from_auth))
    {
      _dbus_string_free (&file);
      _dbus_string_free (&line);
      return FALSE;
    }

  if (!_dbus_file_get_contents (&file, filename, &error))    {
      _dbus_warn ("Getting contents of %s failed: %s\n",
                  _dbus_string_get_const_data (filename), error.message);
      dbus_error_free (&error);
      goto out;
    }

  state = DBUS_AUTH_STATE_NEED_DISCONNECT;
  line_no = 0;

 next_iteration:
  while (_dbus_string_pop_line (&file, &line))
    {      
      line_no += 1;

      /* _dbus_warn ("%s\n", _dbus_string_get_const_data (&line)); */
      
      _dbus_string_delete_leading_blanks (&line);

      if (auth != NULL)
        {
          while ((state = _dbus_auth_do_work (auth)) ==
                 DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
            {
              const DBusString *tmp;
              if (_dbus_auth_get_bytes_to_send (auth, &tmp))
                {
                  int count = _dbus_string_get_length (tmp);

                  if (_dbus_string_copy (tmp, 0, &from_auth,
                                         _dbus_string_get_length (&from_auth)))
                    _dbus_auth_bytes_sent (auth, count);
                }
            }
        }
      
      if (_dbus_string_get_length (&line) == 0)
        {
          /* empty line */
          goto next_iteration;
        }
      else if (_dbus_string_starts_with_c_str (&line,
                                               "#"))
        {
          /* Ignore this comment */
          goto next_iteration;
        }
#ifdef DBUS_WIN
      else if (_dbus_string_starts_with_c_str (&line,
                                               "WIN_ONLY"))
        {
          /* Ignore this line */
          goto next_iteration;
        }
      else if (_dbus_string_starts_with_c_str (&line,
                                               "UNIX_ONLY"))
        {
          /* skip this file */
          _dbus_warn ("skipping unix only auth script\n");
          retval = TRUE;
          goto out;
        }
#endif
#ifdef DBUS_UNIX
      else if (_dbus_string_starts_with_c_str (&line,
                                               "UNIX_ONLY"))
        {
          /* Ignore this line */
          goto next_iteration;
        }
      else if (_dbus_string_starts_with_c_str (&line,
                                               "WIN_ONLY"))
        {
          /* skip this file */
          _dbus_warn ("skipping windows only auth script\n");
          retval = TRUE;
          goto out;
        }
#endif
      else if (_dbus_string_starts_with_c_str (&line,
                                               "CLIENT"))
        {
          DBusCredentials *creds;
          
          if (auth != NULL)
            {
              _dbus_warn ("already created a DBusAuth (CLIENT or SERVER given twice)\n");
              goto out;
            }

          auth = _dbus_auth_client_new ();
          if (auth == NULL)
            {
              _dbus_warn ("no memory to create DBusAuth\n");
              goto out;
            }

          /* test ref/unref */
          _dbus_auth_ref (auth);
          _dbus_auth_unref (auth);

          creds = _dbus_credentials_new_from_current_process ();
          if (creds == NULL)
            {
              _dbus_warn ("no memory for credentials\n");
              _dbus_auth_unref (auth);
              auth = NULL;
              goto out;
            }
              
          if (!_dbus_auth_set_credentials (auth, creds))
            {
              _dbus_warn ("no memory for setting credentials\n");
              _dbus_auth_unref (auth);
              auth = NULL;
              _dbus_credentials_unref (creds);
              goto out;
            }
          
          _dbus_credentials_unref (creds);
        }
      else if (_dbus_string_starts_with_c_str (&line,
                                               "SERVER"))
        {
          DBusCredentials *creds;
          
          if (auth != NULL)
            {
              _dbus_warn ("already created a DBusAuth (CLIENT or SERVER given twice)\n");
              goto out;
            }

          auth = _dbus_auth_server_new (&guid);
          if (auth == NULL)
            {
              _dbus_warn ("no memory to create DBusAuth\n");
              goto out;
            }

          /* test ref/unref */
          _dbus_auth_ref (auth);
          _dbus_auth_unref (auth);

          creds = _dbus_credentials_new_from_current_process ();
          if (creds == NULL)
            {
              _dbus_warn ("no memory for credentials\n");
              _dbus_auth_unref (auth);
              auth = NULL;
              goto out;
            }
              
          if (!_dbus_auth_set_credentials (auth, creds))
            {
              _dbus_warn ("no memory for setting credentials\n");
              _dbus_auth_unref (auth);
              auth = NULL;
              _dbus_credentials_unref (creds);
              goto out;
            }
          
          _dbus_credentials_unref (creds);

          _dbus_auth_set_context (auth, &context);
        }
      else if (auth == NULL)
        {
          _dbus_warn ("must specify CLIENT or SERVER\n");
          goto out;

        }
      else if (_dbus_string_starts_with_c_str (&line,
                                               "NO_CREDENTIALS"))
        {
          auth_set_unix_credentials (auth, DBUS_UID_UNSET, DBUS_PID_UNSET);
        }
      else if (_dbus_string_starts_with_c_str (&line,
                                               "ROOT_CREDENTIALS"))
        {
          auth_set_unix_credentials (auth, 0, DBUS_PID_UNSET);
        }
      else if (_dbus_string_starts_with_c_str (&line,
                                               "SILLY_CREDENTIALS"))
        {
          auth_set_unix_credentials (auth, 4312, DBUS_PID_UNSET);
        }
      else if (_dbus_string_starts_with_c_str (&line,
                                               "ALLOWED_MECHS"))
        {
          char **mechs;

          _dbus_string_delete_first_word (&line);
          mechs = split_string (&line);
          _dbus_auth_set_mechanisms (auth, (const char **) mechs);
          dbus_free_string_array (mechs);
        }
      else if (_dbus_string_starts_with_c_str (&line,
                                               "SEND"))
        {
          DBusString to_send;
          
          _dbus_string_delete_first_word (&line);

          if (!_dbus_string_init (&to_send))
            {
              _dbus_warn ("no memory to allocate string\n");
              goto out;
            }

          if (!append_quoted_string (&to_send, &line))
            {
              _dbus_warn ("failed to append quoted string line %d\n",
                          line_no);
              _dbus_string_free (&to_send);
              goto out;
            }

          _dbus_verbose ("Sending '%s'\n", _dbus_string_get_const_data (&to_send));
          
          if (!_dbus_string_append (&to_send, "\r\n"))
            {
              _dbus_warn ("failed to append \r\n from line %d\n",
                          line_no);
              _dbus_string_free (&to_send);
              goto out;
            }

          /* Replace USERID_HEX with our username in hex */
          {
            int where;
            
            if (_dbus_string_find (&to_send, 0,
                                   "USERID_HEX", &where))
              {
                DBusString username;

                if (!_dbus_string_init (&username))
                  {
                    _dbus_warn ("no memory for userid\n");
                    _dbus_string_free (&to_send);
                    goto out;
                  }

                if (!_dbus_append_user_from_current_process (&username))
                  {
                    _dbus_warn ("no memory for userid\n");
                    _dbus_string_free (&username);
                    _dbus_string_free (&to_send);
                    goto out;
                  }

                _dbus_string_delete (&to_send, where, (int) strlen ("USERID_HEX"));
                
                if (!_dbus_string_hex_encode (&username, 0,
					      &to_send, where))
                  {
                    _dbus_warn ("no memory to subst USERID_HEX\n");
                    _dbus_string_free (&username);
                    _dbus_string_free (&to_send);
                    goto out;
                  }

                _dbus_string_free (&username);
              }
            else if (_dbus_string_find (&to_send, 0,
                                        "USERNAME_HEX", &where))
              {
                DBusString username;
                
                if (!_dbus_string_init (&username))
                  {
                    _dbus_warn ("no memory for username\n");
                    _dbus_string_free (&to_send);
                    goto out;
                  }

                if (!_dbus_append_user_from_current_process (&username))
                  {
                    _dbus_warn ("no memory for username\n");
                    _dbus_string_free (&username);
                    _dbus_string_free (&to_send);
                    goto out;
                  }

                _dbus_string_delete (&to_send, where, (int) strlen ("USERNAME_HEX"));
                
                if (!_dbus_string_hex_encode (&username, 0,
					      &to_send, where))
                  {
                    _dbus_warn ("no memory to subst USERNAME_HEX\n");
                    _dbus_string_free (&username);
                    _dbus_string_free (&to_send);
                    goto out;
                  }

                _dbus_string_free (&username);
              }
          }

          {
            DBusString *buffer;

            _dbus_auth_get_buffer (auth, &buffer);
            if (!_dbus_string_copy (&to_send, 0,
                                    buffer, _dbus_string_get_length (buffer)))
              {
                _dbus_warn ("not enough memory to call bytes_received, or can't add bytes to auth object already in end state\n");
                _dbus_string_free (&to_send);
                _dbus_auth_return_buffer (auth, buffer);
                goto out;
              }

            _dbus_auth_return_buffer (auth, buffer);
          }
          
          _dbus_string_free (&to_send);
        }
      else if (_dbus_string_starts_with_c_str (&line,
                                               "EXPECT_STATE"))
        {
          DBusAuthState expected;
          
          _dbus_string_delete_first_word (&line);

          expected = auth_state_from_string (&line);
          if (expected < 0)
            {
              _dbus_warn ("bad auth state given to EXPECT_STATE\n");
              goto parse_failed;
            }

          if (expected != state)
            {
              _dbus_warn ("expected auth state %s but got %s on line %d\n",
                          auth_state_to_string (expected),
                          auth_state_to_string (state),
                          line_no);
              goto out;
            }
        }
      else if (_dbus_string_starts_with_c_str (&line,
                                               "EXPECT_COMMAND"))
        {
          DBusString received;
          
          _dbus_string_delete_first_word (&line);

          if (!_dbus_string_init (&received))
            {
              _dbus_warn ("no mem to allocate string received\n");
              goto out;
            }

          if (!_dbus_string_pop_line (&from_auth, &received))
            {
              _dbus_warn ("no line popped from the DBusAuth being tested, expected command %s on line %d\n",
                          _dbus_string_get_const_data (&line), line_no);
              _dbus_string_free (&received);
              goto out;
            }

          if (!same_first_word (&received, &line))
            {
              _dbus_warn ("line %d expected command '%s' and got '%s'\n",
                          line_no,
                          _dbus_string_get_const_data (&line),
                          _dbus_string_get_const_data (&received));
              _dbus_string_free (&received);
              goto out;
            }
          
          _dbus_string_free (&received);
        }
      else if (_dbus_string_starts_with_c_str (&line,
                                               "EXPECT_UNUSED"))
        {
          DBusString expected;
          const DBusString *unused;
          
          _dbus_string_delete_first_word (&line);

          if (!_dbus_string_init (&expected))
            {
              _dbus_warn ("no mem to allocate string expected\n");
              goto out;
            }

          if (!append_quoted_string (&expected, &line))
            {
              _dbus_warn ("failed to append quoted string line %d\n",
                          line_no);
              _dbus_string_free (&expected);
              goto out;
            }

          _dbus_auth_get_unused_bytes (auth, &unused);
          
          if (_dbus_string_equal (&expected, unused))
            {
              _dbus_auth_delete_unused_bytes (auth);
              _dbus_string_free (&expected);
            }
          else
            {
              _dbus_warn ("Expected unused bytes '%s' and have '%s'\n",
                          _dbus_string_get_const_data (&expected),
                          _dbus_string_get_const_data (unused));
              _dbus_string_free (&expected);
              goto out;
            }
        }
      else if (_dbus_string_starts_with_c_str (&line,
                                               "EXPECT_HAVE_NO_CREDENTIALS"))
        {
          DBusCredentials *authorized_identity;
          
          authorized_identity = _dbus_auth_get_identity (auth);
          if (!_dbus_credentials_are_anonymous (authorized_identity))
            {
              _dbus_warn ("Expected anonymous login or failed login, but some credentials were authorized\n");
              goto out;
            }
        }
      else if (_dbus_string_starts_with_c_str (&line,
                                               "EXPECT_HAVE_SOME_CREDENTIALS"))
        {
          DBusCredentials *authorized_identity;
          
          authorized_identity = _dbus_auth_get_identity (auth);
          if (_dbus_credentials_are_anonymous (authorized_identity))
            {
              _dbus_warn ("Expected to have some credentials, but we don't\n");
              goto out;
            }
        }
      else if (_dbus_string_starts_with_c_str (&line,
                                               "EXPECT"))
        {
          DBusString expected;
          
          _dbus_string_delete_first_word (&line);

          if (!_dbus_string_init (&expected))
            {
              _dbus_warn ("no mem to allocate string expected\n");
              goto out;
            }

          if (!append_quoted_string (&expected, &line))
            {
              _dbus_warn ("failed to append quoted string line %d\n",
                          line_no);
              _dbus_string_free (&expected);
              goto out;
            }

          if (_dbus_string_equal_len (&expected, &from_auth,
                                      _dbus_string_get_length (&expected)))
            {
              _dbus_string_delete (&from_auth, 0,
                                   _dbus_string_get_length (&expected));
              _dbus_string_free (&expected);
            }
          else
            {
              _dbus_warn ("Expected exact string '%s' and have '%s'\n",
                          _dbus_string_get_const_data (&expected),
                          _dbus_string_get_const_data (&from_auth));
              _dbus_string_free (&expected);
              goto out;
            }
        }
      else
        goto parse_failed;

      goto next_iteration; /* skip parse_failed */
      
    parse_failed:
      {
        _dbus_warn ("couldn't process line %d \"%s\"\n",
                    line_no, _dbus_string_get_const_data (&line));
        goto out;
      }
    }

  if (auth == NULL)
    {
      _dbus_warn ("Auth script is bogus, did not even have CLIENT or SERVER\n");
      goto out;
    }
  else if (state == DBUS_AUTH_STATE_AUTHENTICATED)
    {
      const DBusString *unused;

      _dbus_auth_get_unused_bytes (auth, &unused);

      if (_dbus_string_get_length (unused) > 0)
        {
          _dbus_warn ("did not expect unused bytes (scripts must specify explicitly if they are expected)\n");
          goto out;
        }
    }

  if (_dbus_string_get_length (&from_auth) > 0)
    {
      _dbus_warn ("script did not have EXPECT_ statements for all the data received from the DBusAuth\n");
      _dbus_warn ("Leftover data: %s\n", _dbus_string_get_const_data (&from_auth));
      goto out;
    }
  
  retval = TRUE;
  
 out:
  if (auth)
    _dbus_auth_unref (auth);

  _dbus_string_free (&file);
  _dbus_string_free (&line);
  _dbus_string_free (&from_auth);
  
  return retval;
}
dbus_bool_t
_dbus_marshal_validate_test (void)
{
  DBusString str;
  int i;

  const char *valid_paths[] = {
    "/",
    "/foo/bar",
    "/foo",
    "/foo/bar/baz"
  };
  const char *invalid_paths[] = {
    "bar",
    "bar/baz",
    "/foo/bar/",
    "/foo/"
    "foo/",
    "boo//blah",
    "//",
    "///",
    "foo///blah/",
    "Hello World",
    "",
    "   ",
    "foo bar"
  };

  const char *valid_interfaces[] = {
    "org.freedesktop.Foo",
    "Bar.Baz",
    "Blah.Blah.Blah.Blah.Blah",
    "a.b",
    "a.b.c.d.e.f.g",
    "a0.b1.c2.d3.e4.f5.g6",
    "abc123.foo27"
  };
  const char *invalid_interfaces[] = {
    ".",
    "",
    "..",
    ".Foo.Bar",
    "..Foo.Bar",
    "Foo.Bar.",
    "Foo.Bar..",
    "Foo",
    "9foo.bar.baz",
    "foo.bar..baz",
    "foo.bar...baz",
    "foo.bar.b..blah",
    ":",
    ":0-1",
    "10",
    ":11.34324",
    "0.0.0",
    "0..0",
    "foo.Bar.%",
    "foo.Bar!!",
    "!Foo.bar.bz",
    "foo.$.blah",
    "",
    "   ",
    "foo bar"
  };

  const char *valid_unique_names[] = {
    ":0",
    ":a",
    ":",
    ":.a",
    ":.1",
    ":0.1",
    ":000.2222",
    ":.blah",
    ":abce.freedesktop.blah"
  };
  const char *invalid_unique_names[] = {
    //":-",
    ":!",
    //":0-10",
    ":blah.",
    ":blah.",
    ":blah..org",
    ":blah.org..",
    ":..blah.org",
    "",
    "   ",
    "foo bar"
  };

  const char *valid_members[] = {
    "Hello",
    "Bar",
    "foobar",
    "_foobar",
    "foo89"
  };

  const char *invalid_members[] = {
    "9Hello",
    "10",
    "1",
    "foo-bar",
    "blah.org",
    ".blah",
    "blah.",
    "Hello.",
    "!foo",
    "",
    "   ",
    "foo bar"
  };

  const char *valid_signatures[] = {
    "",
    "sss",
    "i",
    "b"
  };

  const char *invalid_signatures[] = {
    " ",
    "not a valid signature",
    "123",
    ".",
    "(",
    "a{(ii)i}" /* https://bugs.freedesktop.org/show_bug.cgi?id=17803 */
  };

  /* Signature with reason */

  run_validity_tests (signature_tests, _DBUS_N_ELEMENTS (signature_tests),
                      _dbus_validate_signature_with_reason);

  /* Path validation */
  i = 0;
  while (i < (int) _DBUS_N_ELEMENTS (valid_paths))
    {
      _dbus_string_init_const (&str, valid_paths[i]);

      if (!_dbus_validate_path (&str, 0,
                                _dbus_string_get_length (&str)))
        {
          _dbus_warn ("Path \"%s\" should have been valid\n", valid_paths[i]);
          _dbus_assert_not_reached ("invalid path");
        }

      ++i;
    }

  i = 0;
  while (i < (int) _DBUS_N_ELEMENTS (invalid_paths))
    {
      _dbus_string_init_const (&str, invalid_paths[i]);

      if (_dbus_validate_path (&str, 0,
                               _dbus_string_get_length (&str)))
        {
          _dbus_warn ("Path \"%s\" should have been invalid\n", invalid_paths[i]);
          _dbus_assert_not_reached ("valid path");
        }

      ++i;
    }

  /* Interface validation */
  i = 0;
  while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces))
    {
      _dbus_string_init_const (&str, valid_interfaces[i]);

      if (!_dbus_validate_interface (&str, 0,
                                     _dbus_string_get_length (&str)))
        {
          _dbus_warn ("Interface \"%s\" should have been valid\n", valid_interfaces[i]);
          _dbus_assert_not_reached ("invalid interface");
        }

      ++i;
    }

  i = 0;
  while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces))
    {
      _dbus_string_init_const (&str, invalid_interfaces[i]);

      if (_dbus_validate_interface (&str, 0,
                                    _dbus_string_get_length (&str)))
        {
          _dbus_warn ("Interface \"%s\" should have been invalid\n", invalid_interfaces[i]);
          _dbus_assert_not_reached ("valid interface");
        }

      ++i;
    }

  /* Bus name validation (check that valid interfaces are valid bus names,
   * and invalid interfaces are invalid services except if they start with ':')
   */
  i = 0;
  while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces))
    {
      _dbus_string_init_const (&str, valid_interfaces[i]);

      if (!_dbus_validate_bus_name (&str, 0,
                                   _dbus_string_get_length (&str)))
        {
          _dbus_warn ("Bus name \"%s\" should have been valid\n", valid_interfaces[i]);
          _dbus_assert_not_reached ("invalid bus name");
        }

      ++i;
    }

  i = 0;
  while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces))
    {
      if (invalid_interfaces[i][0] != ':')
        {
          _dbus_string_init_const (&str, invalid_interfaces[i]);

          if (_dbus_validate_bus_name (&str, 0,
                                       _dbus_string_get_length (&str)))
            {
              _dbus_warn ("Bus name \"%s\" should have been invalid\n", invalid_interfaces[i]);
              _dbus_assert_not_reached ("valid bus name");
            }
        }

      ++i;
    }

  /* unique name validation */
  i = 0;
  while (i < (int) _DBUS_N_ELEMENTS (valid_unique_names))
    {
      _dbus_string_init_const (&str, valid_unique_names[i]);

      if (!_dbus_validate_bus_name (&str, 0,
                                    _dbus_string_get_length (&str)))
        {
          _dbus_warn ("Bus name \"%s\" should have been valid\n", valid_unique_names[i]);
          _dbus_assert_not_reached ("invalid unique name");
        }

      ++i;
    }

  i = 0;
  while (i < (int) _DBUS_N_ELEMENTS (invalid_unique_names))
    {
      _dbus_string_init_const (&str, invalid_unique_names[i]);

      if (_dbus_validate_bus_name (&str, 0,
                                   _dbus_string_get_length (&str)))
        {
          _dbus_warn ("Bus name \"%s\" should have been invalid\n", invalid_unique_names[i]);
          _dbus_assert_not_reached ("valid unique name");
        }

      ++i;
    }


  /* Error name validation (currently identical to interfaces)
   */
  i = 0;
  while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces))
    {
      _dbus_string_init_const (&str, valid_interfaces[i]);

      if (!_dbus_validate_error_name (&str, 0,
                                      _dbus_string_get_length (&str)))
        {
          _dbus_warn ("Error name \"%s\" should have been valid\n", valid_interfaces[i]);
          _dbus_assert_not_reached ("invalid error name");
        }

      ++i;
    }

  i = 0;
  while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces))
    {
      if (invalid_interfaces[i][0] != ':')
        {
          _dbus_string_init_const (&str, invalid_interfaces[i]);

          if (_dbus_validate_error_name (&str, 0,
                                         _dbus_string_get_length (&str)))
            {
              _dbus_warn ("Error name \"%s\" should have been invalid\n", invalid_interfaces[i]);
              _dbus_assert_not_reached ("valid error name");
            }
        }

      ++i;
    }

  /* Member validation */
  i = 0;
  while (i < (int) _DBUS_N_ELEMENTS (valid_members))
    {
      _dbus_string_init_const (&str, valid_members[i]);

      if (!_dbus_validate_member (&str, 0,
                                  _dbus_string_get_length (&str)))
        {
          _dbus_warn ("Member \"%s\" should have been valid\n", valid_members[i]);
          _dbus_assert_not_reached ("invalid member");
        }

      ++i;
    }

  i = 0;
  while (i < (int) _DBUS_N_ELEMENTS (invalid_members))
    {
      _dbus_string_init_const (&str, invalid_members[i]);

      if (_dbus_validate_member (&str, 0,
                                 _dbus_string_get_length (&str)))
        {
          _dbus_warn ("Member \"%s\" should have been invalid\n", invalid_members[i]);
          _dbus_assert_not_reached ("valid member");
        }

      ++i;
    }

  /* Signature validation */
  i = 0;
  while (i < (int) _DBUS_N_ELEMENTS (valid_signatures))
    {
      _dbus_string_init_const (&str, valid_signatures[i]);

      if (!_dbus_validate_signature (&str, 0,
                                     _dbus_string_get_length (&str)))
        {
          _dbus_warn ("Signature \"%s\" should have been valid\n", valid_signatures[i]);
          _dbus_assert_not_reached ("invalid signature");
        }

      ++i;
    }

  i = 0;
  while (i < (int) _DBUS_N_ELEMENTS (invalid_signatures))
    {
      _dbus_string_init_const (&str, invalid_signatures[i]);

      if (_dbus_validate_signature (&str, 0,
                                    _dbus_string_get_length (&str)))
        {
          _dbus_warn ("Signature \"%s\" should have been invalid\n", invalid_signatures[i]);
          _dbus_assert_not_reached ("valid signature");
        }

      ++i;
    }

  /* Validate claimed length longer than real length */
  _dbus_string_init_const (&str, "abc.efg");
  if (_dbus_validate_bus_name (&str, 0, 8))
    _dbus_assert_not_reached ("validated too-long string");
  if (_dbus_validate_interface (&str, 0, 8))
    _dbus_assert_not_reached ("validated too-long string");
  if (_dbus_validate_error_name (&str, 0, 8))
    _dbus_assert_not_reached ("validated too-long string");

  _dbus_string_init_const (&str, "abc");
  if (_dbus_validate_member (&str, 0, 4))
    _dbus_assert_not_reached ("validated too-long string");

  _dbus_string_init_const (&str, "sss");
  if (_dbus_validate_signature (&str, 0, 4))
    _dbus_assert_not_reached ("validated too-long signature");

  /* Validate string exceeding max name length */
  if (!_dbus_string_init (&str))
    _dbus_assert_not_reached ("no memory");

  while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH)
    if (!_dbus_string_append (&str, "abc.def"))
      _dbus_assert_not_reached ("no memory");

  if (_dbus_validate_bus_name (&str, 0, _dbus_string_get_length (&str)))
    _dbus_assert_not_reached ("validated overmax string");
  if (_dbus_validate_interface (&str, 0, _dbus_string_get_length (&str)))
    _dbus_assert_not_reached ("validated overmax string");
  if (_dbus_validate_error_name (&str, 0, _dbus_string_get_length (&str)))
    _dbus_assert_not_reached ("validated overmax string");

  /* overlong member */
  _dbus_string_set_length (&str, 0);
  while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH)
    if (!_dbus_string_append (&str, "abc"))
      _dbus_assert_not_reached ("no memory");

  if (_dbus_validate_member (&str, 0, _dbus_string_get_length (&str)))
    _dbus_assert_not_reached ("validated overmax string");

  /* overlong unique name */
  _dbus_string_set_length (&str, 0);
  _dbus_string_append (&str, ":");
  while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH)
    if (!_dbus_string_append (&str, "abc"))
      _dbus_assert_not_reached ("no memory");

  if (_dbus_validate_bus_name (&str, 0, _dbus_string_get_length (&str)))
    _dbus_assert_not_reached ("validated overmax string");

  _dbus_string_free (&str);

  /* Body validation; test basic validation of valid bodies for both endian */
  
  {
    int sequence;
    DBusString signature;
    DBusString body;

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

    sequence = 0;
    while (dbus_internal_do_not_use_generate_bodies (sequence,
                                                     DBUS_LITTLE_ENDIAN,
                                                     &signature, &body))
      {
        DBusValidity validity;

        validity = _dbus_validate_body_with_reason (&signature, 0,
                                                    DBUS_LITTLE_ENDIAN,
                                                    NULL, &body, 0,
                                                    _dbus_string_get_length (&body));
        if (validity != DBUS_VALID)
          {
            _dbus_warn ("invalid code %d expected valid on sequence %d little endian\n",
                        validity, sequence);
            _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_assert_not_reached ("test failed");
          }

        _dbus_string_set_length (&signature, 0);
        _dbus_string_set_length (&body, 0);
        ++sequence;
      }
                                                     
    sequence = 0;
    while (dbus_internal_do_not_use_generate_bodies (sequence,
                                                     DBUS_BIG_ENDIAN,
                                                     &signature, &body))
      {
        DBusValidity validity;

        validity = _dbus_validate_body_with_reason (&signature, 0,
                                                    DBUS_BIG_ENDIAN,
                                                    NULL, &body, 0,
                                                    _dbus_string_get_length (&body));
        if (validity != DBUS_VALID)
          {
            _dbus_warn ("invalid code %d expected valid on sequence %d big endian\n",
                        validity, sequence);
            _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_assert_not_reached ("test failed");
          }

        _dbus_string_set_length (&signature, 0);
        _dbus_string_set_length (&body, 0);
        ++sequence;
      }

    _dbus_string_free (&signature);
    _dbus_string_free (&body);
  }
  
  return TRUE;
}
/**
 * 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;
}
Beispiel #14
0
static void
signal_handler (int sig)
{
  switch (sig)
    {
    case SIGHUP:
      {
        DBusString str;
        char action[2] = { ACTION_RELOAD, '\0' };

        _dbus_string_init_const (&str, action);
        if ((reload_pipe[RELOAD_WRITE_END].fd > 0) &&
            !_dbus_write_socket (reload_pipe[RELOAD_WRITE_END], &str, 0, 1))
          {
            /* If we receive SIGHUP often enough to fill the pipe buffer (4096
             * times on old Linux, 65536 on modern Linux) before it can be
             * drained, let's just warn and ignore. The configuration will be
             * reloaded while draining the pipe buffer, which is what we
             * wanted. It's harmless that it will be reloaded fewer times than
             * we asked for, since the reload is delayed anyway, so new changes
             * will be picked up.
             *
             * We use write() because _dbus_warn uses vfprintf, which isn't
             * async-signal-safe.
             *
             * This is necessarily Unix-specific, but so are POSIX signals,
             * so... */
            static const char message[] =
              "Unable to write to reload pipe - buffer full?\n";

            if (write (STDERR_FILENO, message, strlen (message)) !=
                (ssize_t) strlen (message))
              {
                /* ignore failure to write out a warning */
              }
          }
      }
      break;

    case SIGTERM:
      {
        DBusString str;
        char action[2] = { ACTION_QUIT, '\0' };
        _dbus_string_init_const (&str, action);
        if ((reload_pipe[RELOAD_WRITE_END].fd < 0) ||
            !_dbus_write_socket (reload_pipe[RELOAD_WRITE_END], &str, 0, 1))
          {
            /* If we can't write to the socket, dying seems a more
             * important response to SIGTERM than cleaning up sockets,
             * so we exit. We'd use exit(), but that's not async-signal-safe,
             * so we'll have to resort to _exit(). */
            static const char message[] =
              "Unable to write termination signal to pipe - buffer full?\n"
              "Will exit instead.\n";

            if (write (STDERR_FILENO, message, strlen (message)) !=
                (ssize_t) strlen (message))
              {
                /* ignore failure to write out a warning */
              }
            _exit (1);
          }
      }
      break;
    }
}
Beispiel #15
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;
    }

  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;
    }

  _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;
}
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;

  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");

  dbus_error_init (&error);
  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;
}