Exemplo n.º 1
0
static dbus_bool_t
test_command_line (const char *arg1, ...)
{
  int i, original_argc, shell_argc;
  char **shell_argv;
  char **original_argv;
  char *command_line, *tmp;
  DBusString str;
  DBusList *list = NULL, *node;
  va_list var_args;
  DBusError error;

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

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

  dbus_error_init (&error);
  if (!_dbus_shell_parse_argv (command_line, &shell_argc, &shell_argv, &error))
    {
      fprintf (stderr, "Error parsing command line: %s\n", error.message ? error.message : "");
      return FALSE;
    }
  else
    {
      if (shell_argc != original_argc)
        {
          printf ("Number of arguments returned (%d) don't match original (%d)\n",
                  shell_argc, original_argc);
          return FALSE;
        } 
      printf ("Number of arguments: %d\n", shell_argc);
      for (i = 0; i < shell_argc; i++)
        {
          char *unquoted;
          
          unquoted = _dbus_shell_unquote (original_argv[i]);
          if (strcmp (unquoted ? unquoted : "",
                      shell_argv[i] ? shell_argv[i] : ""))
            {
              printf ("Position %d, returned argument (%s) does not match original (%s)\n",
                      i, shell_argv[i], unquoted);
              dbus_free (unquoted);
              return FALSE;
            }
          dbus_free (unquoted);
          if (shell_argv[i])
            printf ("Argument %d = %s\n", i, shell_argv[i]);
        }
      
      dbus_free_string_array (shell_argv);
    }
  
  _dbus_string_free (&str);
  
  return TRUE;
}
static dbus_bool_t
bus_driver_handle_list_services (DBusConnection *connection,
                                 BusTransaction *transaction,
                                 DBusMessage    *message,
                                 DBusError      *error)
{
  DBusMessage *reply;
  int len;
  char **services;
  BusRegistry *registry;
  int i;
  DBusMessageIter iter;
  DBusMessageIter sub;

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
  
  registry = bus_connection_get_registry (connection);
  
  reply = dbus_message_new_method_return (message);
  if (reply == NULL)
    {
      BUS_SET_OOM (error);
      return FALSE;
    }

  if (!bus_registry_list_services (registry, &services, &len))
    {
      dbus_message_unref (reply);
      BUS_SET_OOM (error);
      return FALSE;
    }

  dbus_message_iter_init_append (reply, &iter);
  
  if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
                                         DBUS_TYPE_STRING_AS_STRING,
                                         &sub))
    {
      dbus_free_string_array (services);
      dbus_message_unref (reply);
      BUS_SET_OOM (error);
      return FALSE;
    }

  {
    /* Include the bus driver in the list */
    const char *v_STRING = DBUS_SERVICE_DBUS;
    if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
                                         &v_STRING))
      {
        dbus_free_string_array (services);
        dbus_message_unref (reply);
        BUS_SET_OOM (error);
        return FALSE;
      }
  }
  
  i = 0;
  while (i < len)
    {
      if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
                                           &services[i]))
        {
          dbus_free_string_array (services);
          dbus_message_unref (reply);
          BUS_SET_OOM (error);
          return FALSE;
        }
      ++i;
    }

  if (!dbus_message_iter_close_container (&iter, &sub))
    {
      dbus_free_string_array (services);
      dbus_message_unref (reply);
      BUS_SET_OOM (error);
      return FALSE;
    }
  
  dbus_free_string_array (services);
  
  if (!bus_transaction_send_from_driver (transaction, connection, reply))
    {
      dbus_message_unref (reply);
      BUS_SET_OOM (error);
      return FALSE;
    }
  else
    {
      dbus_message_unref (reply);
      return TRUE;
    }
}
Exemplo n.º 3
0
static dbus_bool_t
check_connection (DBusConnection *conn, 
                  int iteration, 
                  DBusConnection *uniq_conn[NUM_CONN])
{
  DBusMessage *reply;
  DBusMessage *method;
  DBusError error;
  char **list;
  int len, i;
  const char *name;

  reply = NULL;
  method = NULL;
  list = NULL;

  dbus_error_init (&error);

  name = TEST_NAME;
  method = dbus_message_new_method_call (DBUS_SERVICE_DBUS, 
                                         DBUS_PATH_DBUS,
                                         DBUS_INTERFACE_DBUS,
                                         "ListQueuedOwners");

  if (method == NULL)
    goto out;

  if (!dbus_message_append_args (method, 
                                 DBUS_TYPE_STRING, &name, 
                                 DBUS_TYPE_INVALID))
    {
      fprintf (stderr, "Error appending args\n") ;
      goto out;
    }

  reply = dbus_connection_send_with_reply_and_block (conn,
                                                     method,
                                                     -1,
                                                     &error);

  if (reply == NULL)
    {
      fprintf (stderr, "Error calling ListQueuedOwners: %s\n", error.message);
      dbus_error_free (&error);
      goto out;
    }


 
  if (!dbus_message_get_args (reply, 
                              &error, 
                              DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, 
                              &list, &len,
                              DBUS_TYPE_INVALID))
    {
      fprintf (stderr, "Error getting args: %s\n", error.message);
      dbus_error_free (&error);
      goto out;
    }

  printf ("Iteration %i: ", iteration);

  if (len > NUM_CONN)
    {
      fprintf (stderr, "There are %i connections in the queue,"
                       " we are only expecting up to %i connections!\n",
		       len,
		       NUM_CONN);
      goto out;
    }
  
  for (i = 0; i < len; i++)
    {
      int expected_conn_num;
      const char *expected_uname;

      if (i > 0)
        printf (", ");

      printf ("%s", list[i]);

      expected_conn_num = test_data[iteration].expected_queue[i];

      if (expected_conn_num == -1)
        {
          fprintf (stderr, 
                   "\nDid not expect this last connection" 
                   " to be in the queue!\n");
          goto out;
        }

      expected_uname = 
             dbus_bus_get_unique_name (uniq_conn[expected_conn_num]);

      if (strcmp (list[i], expected_uname) != 0)
        {
          fprintf (stderr, 
                   "\n%s expected but %s is in the queue!\n",
                   expected_uname, 
                   list[i]);

          goto out;
        }
    }
  
  printf ("\n");

  dbus_message_unref (method);
  dbus_message_unref (reply);
  dbus_free_string_array (list);
  return TRUE;
 
 out:
  if (method != NULL)
    dbus_message_unref (method);

  if (reply != NULL)
    dbus_message_unref (reply);

  if (list != NULL)
    dbus_free_string_array (list);
  
  return FALSE;
}
/**
 * @ingroup DBusMessageInternals
 * Unit test for DBusMessage.
 *
 * @returns #TRUE on success.
 */
dbus_bool_t
_dbus_message_test (const char *test_data_dir)
{
  DBusMessage *message, *message_without_unix_fds;
  DBusMessageLoader *loader;
  int i;
  const char *data;
  DBusMessage *copy;
  const char *name1;
  const char *name2;
  const dbus_uint32_t our_uint32_array[] =
    { 0x12345678, 0x23456781, 0x34567812, 0x45678123 };
  const dbus_int32_t our_int32_array[] =
    { 0x12345678, -0x23456781, 0x34567812, -0x45678123 };
  const dbus_uint32_t *v_ARRAY_UINT32 = our_uint32_array;
  const dbus_int32_t *v_ARRAY_INT32 = our_int32_array;
#ifdef DBUS_HAVE_INT64
  const dbus_uint64_t our_uint64_array[] =
    { 0x12345678, 0x23456781, 0x34567812, 0x45678123 };
  const dbus_int64_t our_int64_array[] =
    { 0x12345678, -0x23456781, 0x34567812, -0x45678123 };
  const dbus_uint64_t *v_ARRAY_UINT64 = our_uint64_array;
  const dbus_int64_t *v_ARRAY_INT64 = our_int64_array;
#endif
  const char *our_string_array[] = { "Foo", "bar", "", "woo woo woo woo" };
  const char **v_ARRAY_STRING = our_string_array;
  const double our_double_array[] = { 0.1234, 9876.54321, -300.0 };
  const double *v_ARRAY_DOUBLE = our_double_array;
  const unsigned char our_byte_array[] = { 'a', 'b', 'c', 234 };
  const unsigned char *v_ARRAY_BYTE = our_byte_array;
  const dbus_bool_t our_boolean_array[] = { TRUE, FALSE, TRUE, TRUE, FALSE };
  const dbus_bool_t *v_ARRAY_BOOLEAN = our_boolean_array;
  char sig[64];
  const char *s;
  const char *v_STRING;
  double v_DOUBLE;
  dbus_int16_t v_INT16;
  dbus_uint16_t v_UINT16;
  dbus_int32_t v_INT32;
  dbus_uint32_t v_UINT32;
#ifdef DBUS_HAVE_INT64
  dbus_int64_t v_INT64;
  dbus_uint64_t v_UINT64;
#endif
  unsigned char v_BYTE;
  unsigned char v2_BYTE;
  dbus_bool_t v_BOOLEAN;
  DBusMessageIter iter, array_iter, struct_iter;
#ifdef HAVE_UNIX_FD_PASSING
  int v_UNIX_FD;
#endif
  char **decomposed;
  DBusInitialFDs *initial_fds;

  initial_fds = _dbus_check_fdleaks_enter ();

  message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
                                          "/org/freedesktop/TestPath",
                                          "Foo.TestInterface",
                                          "TestMethod");
  _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService"));
  _dbus_assert (dbus_message_is_method_call (message, "Foo.TestInterface",
                                             "TestMethod"));
  _dbus_assert (strcmp (dbus_message_get_path (message),
                        "/org/freedesktop/TestPath") == 0);
  dbus_message_set_serial (message, 1234);

  /* string length including nul byte not a multiple of 4 */
  if (!dbus_message_set_sender (message, "org.foo.bar1"))
    _dbus_assert_not_reached ("out of memory");

  _dbus_assert (dbus_message_has_sender (message, "org.foo.bar1"));
  dbus_message_set_reply_serial (message, 5678);

  _dbus_verbose_bytes_of_string (&message->header.data, 0,
                                 _dbus_string_get_length (&message->header.data));
  _dbus_verbose_bytes_of_string (&message->body, 0,
                                 _dbus_string_get_length (&message->body));

  if (!dbus_message_set_sender (message, NULL))
    _dbus_assert_not_reached ("out of memory");


  _dbus_verbose_bytes_of_string (&message->header.data, 0,
                                 _dbus_string_get_length (&message->header.data));
  _dbus_verbose_bytes_of_string (&message->body, 0,
                                 _dbus_string_get_length (&message->body));


  _dbus_assert (!dbus_message_has_sender (message, "org.foo.bar1"));
  _dbus_assert (dbus_message_get_serial (message) == 1234);
  _dbus_assert (dbus_message_get_reply_serial (message) == 5678);
  _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService"));

  _dbus_assert (dbus_message_get_no_reply (message) == FALSE);
  dbus_message_set_no_reply (message, TRUE);
  _dbus_assert (dbus_message_get_no_reply (message) == TRUE);
  dbus_message_set_no_reply (message, FALSE);
  _dbus_assert (dbus_message_get_no_reply (message) == FALSE);

  /* Set/get some header fields */

  if (!dbus_message_set_path (message, "/foo"))
    _dbus_assert_not_reached ("out of memory");
  _dbus_assert (strcmp (dbus_message_get_path (message),
                        "/foo") == 0);

  if (!dbus_message_set_interface (message, "org.Foo"))
    _dbus_assert_not_reached ("out of memory");
  _dbus_assert (strcmp (dbus_message_get_interface (message),
                        "org.Foo") == 0);

  if (!dbus_message_set_member (message, "Bar"))
    _dbus_assert_not_reached ("out of memory");
  _dbus_assert (strcmp (dbus_message_get_member (message),
                        "Bar") == 0);

  /* Set/get them with longer values */
  if (!dbus_message_set_path (message, "/foo/bar"))
    _dbus_assert_not_reached ("out of memory");
  _dbus_assert (strcmp (dbus_message_get_path (message),
                        "/foo/bar") == 0);

  if (!dbus_message_set_interface (message, "org.Foo.Bar"))
    _dbus_assert_not_reached ("out of memory");
  _dbus_assert (strcmp (dbus_message_get_interface (message),
                        "org.Foo.Bar") == 0);

  if (!dbus_message_set_member (message, "BarFoo"))
    _dbus_assert_not_reached ("out of memory");
  _dbus_assert (strcmp (dbus_message_get_member (message),
                        "BarFoo") == 0);

  /* Realloc shorter again */

  if (!dbus_message_set_path (message, "/foo"))
    _dbus_assert_not_reached ("out of memory");
  _dbus_assert (strcmp (dbus_message_get_path (message),
                        "/foo") == 0);

  if (!dbus_message_set_interface (message, "org.Foo"))
    _dbus_assert_not_reached ("out of memory");
  _dbus_assert (strcmp (dbus_message_get_interface (message),
                        "org.Foo") == 0);

  if (!dbus_message_set_member (message, "Bar"))
    _dbus_assert_not_reached ("out of memory");
  _dbus_assert (strcmp (dbus_message_get_member (message),
                        "Bar") == 0);

  /* Path decomposing */
  dbus_message_set_path (message, NULL);
  dbus_message_get_path_decomposed (message, &decomposed);
  _dbus_assert (decomposed == NULL);
  dbus_free_string_array (decomposed);

  dbus_message_set_path (message, "/");
  dbus_message_get_path_decomposed (message, &decomposed);
  _dbus_assert (decomposed != NULL);
  _dbus_assert (decomposed[0] == NULL);
  dbus_free_string_array (decomposed);

  dbus_message_set_path (message, "/a/b");
  dbus_message_get_path_decomposed (message, &decomposed);
  _dbus_assert (decomposed != NULL);
  _dbus_assert (strcmp (decomposed[0], "a") == 0);
  _dbus_assert (strcmp (decomposed[1], "b") == 0);
  _dbus_assert (decomposed[2] == NULL);
  dbus_free_string_array (decomposed);

  dbus_message_set_path (message, "/spam/eggs");
  dbus_message_get_path_decomposed (message, &decomposed);
  _dbus_assert (decomposed != NULL);
  _dbus_assert (strcmp (decomposed[0], "spam") == 0);
  _dbus_assert (strcmp (decomposed[1], "eggs") == 0);
  _dbus_assert (decomposed[2] == NULL);
  dbus_free_string_array (decomposed);

  dbus_message_unref (message);

  /* Test the vararg functions */
  message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
                                          "/org/freedesktop/TestPath",
                                          "Foo.TestInterface",
                                          "TestMethod");
  dbus_message_set_serial (message, 1);
  dbus_message_set_reply_serial (message, 5678);

  v_INT16 = -0x123;
  v_UINT16 = 0x123;
  v_INT32 = -0x12345678;
  v_UINT32 = 0x12300042;
#ifdef DBUS_HAVE_INT64
  v_INT64 = DBUS_INT64_CONSTANT (-0x123456789abcd);
  v_UINT64 = DBUS_UINT64_CONSTANT (0x123456789abcd);
#endif
  v_STRING = "Test string";
  v_DOUBLE = 3.14159;
  v_BOOLEAN = TRUE;
  v_BYTE = 42;
  v2_BYTE = 24;
#ifdef HAVE_UNIX_FD_PASSING
  v_UNIX_FD = 1;
#endif

  dbus_message_append_args (message,
                            DBUS_TYPE_INT16, &v_INT16,
                            DBUS_TYPE_UINT16, &v_UINT16,
			    DBUS_TYPE_INT32, &v_INT32,
                            DBUS_TYPE_UINT32, &v_UINT32,
#ifdef DBUS_HAVE_INT64
                            DBUS_TYPE_INT64, &v_INT64,
                            DBUS_TYPE_UINT64, &v_UINT64,
#endif
			    DBUS_TYPE_STRING, &v_STRING,
			    DBUS_TYPE_DOUBLE, &v_DOUBLE,
			    DBUS_TYPE_BOOLEAN, &v_BOOLEAN,
			    DBUS_TYPE_BYTE, &v_BYTE,
			    DBUS_TYPE_BYTE, &v2_BYTE,
			    DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &v_ARRAY_UINT32,
                            _DBUS_N_ELEMENTS (our_uint32_array),
                            DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &v_ARRAY_INT32,
                            _DBUS_N_ELEMENTS (our_int32_array),
#ifdef DBUS_HAVE_INT64
                            DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, &v_ARRAY_UINT64,
                            _DBUS_N_ELEMENTS (our_uint64_array),
                            DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, &v_ARRAY_INT64,
                            _DBUS_N_ELEMENTS (our_int64_array),
#endif
                            DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &v_ARRAY_DOUBLE,
                            _DBUS_N_ELEMENTS (our_double_array),
                            DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &v_ARRAY_BYTE,
                            _DBUS_N_ELEMENTS (our_byte_array),
                            DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, &v_ARRAY_BOOLEAN,
                            _DBUS_N_ELEMENTS (our_boolean_array),
                            DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v_ARRAY_STRING,
                            _DBUS_N_ELEMENTS (our_string_array),

			    DBUS_TYPE_INVALID);

  i = 0;
  sig[i++] = DBUS_TYPE_INT16;
  sig[i++] = DBUS_TYPE_UINT16;
  sig[i++] = DBUS_TYPE_INT32;
  sig[i++] = DBUS_TYPE_UINT32;
#ifdef DBUS_HAVE_INT64
  sig[i++] = DBUS_TYPE_INT64;
  sig[i++] = DBUS_TYPE_UINT64;
#endif
  sig[i++] = DBUS_TYPE_STRING;
  sig[i++] = DBUS_TYPE_DOUBLE;
  sig[i++] = DBUS_TYPE_BOOLEAN;
  sig[i++] = DBUS_TYPE_BYTE;
  sig[i++] = DBUS_TYPE_BYTE;
  sig[i++] = DBUS_TYPE_ARRAY;
  sig[i++] = DBUS_TYPE_UINT32;
  sig[i++] = DBUS_TYPE_ARRAY;
  sig[i++] = DBUS_TYPE_INT32;
#ifdef DBUS_HAVE_INT64
  sig[i++] = DBUS_TYPE_ARRAY;
  sig[i++] = DBUS_TYPE_UINT64;
  sig[i++] = DBUS_TYPE_ARRAY;
  sig[i++] = DBUS_TYPE_INT64;
#endif
  sig[i++] = DBUS_TYPE_ARRAY;
  sig[i++] = DBUS_TYPE_DOUBLE;
  sig[i++] = DBUS_TYPE_ARRAY;
  sig[i++] = DBUS_TYPE_BYTE;
  sig[i++] = DBUS_TYPE_ARRAY;
  sig[i++] = DBUS_TYPE_BOOLEAN;
  sig[i++] = DBUS_TYPE_ARRAY;
  sig[i++] = DBUS_TYPE_STRING;

  message_without_unix_fds = dbus_message_copy(message);
  _dbus_assert(message_without_unix_fds);
#ifdef HAVE_UNIX_FD_PASSING
  dbus_message_append_args (message,
                            DBUS_TYPE_UNIX_FD, &v_UNIX_FD,
			    DBUS_TYPE_INVALID);
  sig[i++] = DBUS_TYPE_UNIX_FD;
#endif
  sig[i++] = DBUS_TYPE_INVALID;

  _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig));

  _dbus_verbose ("HEADER\n");
  _dbus_verbose_bytes_of_string (&message->header.data, 0,
                                 _dbus_string_get_length (&message->header.data));
  _dbus_verbose ("BODY\n");
  _dbus_verbose_bytes_of_string (&message->body, 0,
                                 _dbus_string_get_length (&message->body));

  _dbus_verbose ("Signature expected \"%s\" actual \"%s\"\n",
                 sig, dbus_message_get_signature (message));

  s = dbus_message_get_signature (message);

  _dbus_assert (dbus_message_has_signature (message, sig));
  _dbus_assert (strcmp (s, sig) == 0);

  verify_test_message (message);

  copy = dbus_message_copy (message);

  _dbus_assert (dbus_message_get_reply_serial (message) ==
                dbus_message_get_reply_serial (copy));
  _dbus_assert (message->header.padding == copy->header.padding);

  _dbus_assert (_dbus_string_get_length (&message->header.data) ==
                _dbus_string_get_length (&copy->header.data));

  _dbus_assert (_dbus_string_get_length (&message->body) ==
                _dbus_string_get_length (&copy->body));

  verify_test_message (copy);

  name1 = dbus_message_get_interface (message);
  name2 = dbus_message_get_interface (copy);

  _dbus_assert (strcmp (name1, name2) == 0);

  name1 = dbus_message_get_member (message);
  name2 = dbus_message_get_member (copy);

  _dbus_assert (strcmp (name1, name2) == 0);

  dbus_message_unref (copy);

  /* Message loader test */
  dbus_message_lock (message);
  loader = _dbus_message_loader_new ();
  
  /* check ref/unref */
  _dbus_message_loader_ref (loader);
  _dbus_message_loader_unref (loader);

  /* Write the header data one byte at a time */
  data = _dbus_string_get_const_data (&message->header.data);
  for (i = 0; i < _dbus_string_get_length (&message->header.data); i++)
    {
      DBusString *buffer;

      _dbus_message_loader_get_buffer (loader, &buffer);
      _dbus_string_append_byte (buffer, data[i]);
      _dbus_message_loader_return_buffer (loader, buffer, 1);
    }

  /* Write the body data one byte at a time */
  data = _dbus_string_get_const_data (&message->body);
  for (i = 0; i < _dbus_string_get_length (&message->body); i++)
    {
      DBusString *buffer;

      _dbus_message_loader_get_buffer (loader, &buffer);
      _dbus_string_append_byte (buffer, data[i]);
      _dbus_message_loader_return_buffer (loader, buffer, 1);
    }

#ifdef HAVE_UNIX_FD_PASSING
  {
    int *unix_fds;
    unsigned n_unix_fds;
    /* Write unix fd */
    _dbus_message_loader_get_unix_fds(loader, &unix_fds, &n_unix_fds);
    _dbus_assert(n_unix_fds > 0);
    _dbus_assert(message->n_unix_fds == 1);
    unix_fds[0] = _dbus_dup(message->unix_fds[0], NULL);
    _dbus_assert(unix_fds[0] >= 0);
    _dbus_message_loader_return_unix_fds(loader, unix_fds, 1);
  }
#endif

  dbus_message_unref (message);

  /* Now pop back the message */
  if (!_dbus_message_loader_queue_messages (loader))
    _dbus_assert_not_reached ("no memory to queue messages");

  if (_dbus_message_loader_get_is_corrupted (loader))
    _dbus_assert_not_reached ("message loader corrupted");

  message = _dbus_message_loader_pop_message (loader);
  if (!message)
    _dbus_assert_not_reached ("received a NULL message");

  if (dbus_message_get_reply_serial (message) != 5678)
    _dbus_assert_not_reached ("reply serial fields differ");

  dbus_message_unref (message);

  /* ovveride the serial, since it was reset by dbus_message_copy() */
  dbus_message_set_serial(message_without_unix_fds, 8901);

  dbus_message_lock (message_without_unix_fds);

  verify_test_message (message_without_unix_fds);

    {
      /* Marshal and demarshal the message. */

      DBusMessage *message2;
      DBusError error = DBUS_ERROR_INIT;
      char *marshalled = NULL;
      int len = 0;
      char garbage_header[DBUS_MINIMUM_HEADER_SIZE] = "xxx";

      if (!dbus_message_marshal (message_without_unix_fds, &marshalled, &len))
        _dbus_assert_not_reached ("failed to marshal message");

      _dbus_assert (len != 0);
      _dbus_assert (marshalled != NULL);

      _dbus_assert (dbus_message_demarshal_bytes_needed (marshalled, len) == len);
      message2 = dbus_message_demarshal (marshalled, len, &error);

      _dbus_assert (message2 != NULL);
      _dbus_assert (!dbus_error_is_set (&error));
      verify_test_message (message2);

      dbus_message_unref (message2);
      dbus_free (marshalled);

      /* Demarshal invalid message. */

      message2 = dbus_message_demarshal ("invalid", 7, &error);
      _dbus_assert (message2 == NULL);
      _dbus_assert (dbus_error_is_set (&error));
      dbus_error_free (&error);

      /* Demarshal invalid (empty) message. */

      message2 = dbus_message_demarshal ("", 0, &error);
      _dbus_assert (message2 == NULL);
      _dbus_assert (dbus_error_is_set (&error));
      dbus_error_free (&error);

      /* Bytes needed to demarshal empty message: 0 (more) */

      _dbus_assert (dbus_message_demarshal_bytes_needed ("", 0) == 0);
      
      /* Bytes needed to demarshal invalid message: -1 (error). */

      _dbus_assert (dbus_message_demarshal_bytes_needed (garbage_header, DBUS_MINIMUM_HEADER_SIZE) == -1);
    }

  dbus_message_unref (message_without_unix_fds);
  _dbus_message_loader_unref (loader);

  check_memleaks ();
  _dbus_check_fdleaks_leave (initial_fds);
  initial_fds = _dbus_check_fdleaks_enter ();

  /* Check that we can abandon a container */
  message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
		  			  "/org/freedesktop/TestPath",
					  "Foo.TestInterface",
					  "Method");

  dbus_message_iter_init_append (message, &iter);

  _dbus_assert (dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
			  			  (DBUS_STRUCT_BEGIN_CHAR_AS_STRING
						   DBUS_TYPE_STRING_AS_STRING
						   DBUS_TYPE_STRING_AS_STRING
						   DBUS_STRUCT_END_CHAR_AS_STRING),
						  &array_iter));
  _dbus_assert (dbus_message_iter_open_container (&array_iter, DBUS_TYPE_STRUCT,
			  			  NULL, &struct_iter));

  s = "peaches";
  _dbus_assert (dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING,
			  			&s));

  /* uh-oh, error, try and unwind */

  dbus_message_iter_abandon_container (&array_iter, &struct_iter);
  dbus_message_iter_abandon_container (&array_iter, &iter);

  dbus_message_unref (message);

  /* Load all the sample messages from the message factory */
  {
    DBusMessageDataIter diter;
    DBusMessageData mdata;
    int count;

    reset_validities_seen ();
    
    count = 0;
    _dbus_message_data_iter_init (&diter);
    
    while (_dbus_message_data_iter_get_and_next (&diter,
                                                 &mdata))
      {
        if (!dbus_internal_do_not_use_try_message_data (&mdata.data,
                                                        mdata.expected_validity))
          {
            _dbus_warn ("expected validity %d and did not get it\n",
                        mdata.expected_validity);
            _dbus_assert_not_reached ("message data failed");
          }

        _dbus_message_data_free (&mdata);

        count += 1;
      }

    printf ("%d sample messages tested\n", count);

    print_validities_seen (FALSE);
    print_validities_seen (TRUE);
  }

  check_memleaks ();
  _dbus_check_fdleaks_leave (initial_fds);

  /* Now load every message in test_data_dir if we have one */
  if (test_data_dir == NULL)
    return TRUE;

  initial_fds = _dbus_check_fdleaks_enter ();

  if (!dbus_internal_do_not_use_foreach_message_file (test_data_dir,
                                                        (DBusForeachMessageFileFunc)
                                                        dbus_internal_do_not_use_try_message_file,
                                                        NULL))
    _dbus_assert_not_reached ("foreach_message_file test failed");

  _dbus_check_fdleaks_leave (initial_fds);

  return TRUE;
}
Exemplo n.º 5
0
int main(int argc, char *argv[])
{
  DBusError err;
  DBusConnection *conn;
  DBusMessage *msg;
  DBusMessageIter args;
  DBusPendingCall *pending;
  char **hosts;
  int num_hosts;
  int ret;
  int i;

  dbus_error_init(&err);
  conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
  if (dbus_error_is_set(&err)) {
     fprintf(stderr, "Connection Error (%s)\n", err.message);
     dbus_error_free(&err);
     }
  if (NULL == conn)
     exit(1); 

  msg = dbus_message_new_method_call("de.yavdr.hostwakeup", "/Hosts", "de.yavdr.hostwakeup", "List");
  if (NULL == msg) {
     fprintf(stderr, "Message Null\n");
     exit(1);
     }

  if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) {
     fprintf(stderr, "Out Of Memory!\n");
     exit(1);
     }
  if (NULL == pending) {
     fprintf(stderr, "Pending Call Null\n");
     exit(1);
     }
  dbus_connection_flush(conn);
  dbus_message_unref(msg);

  dbus_pending_call_block(pending);
  msg = dbus_pending_call_steal_reply(pending);
  if (NULL == msg) {
     fprintf(stderr, "Reply Null\n");
     exit(1);
     }
  dbus_pending_call_unref(pending);
  if (!dbus_message_iter_init(msg, &args))
     fprintf(stderr, "Message has no arguments!\n");
  else if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &hosts, &num_hosts, DBUS_TYPE_INVALID)) {
     if (hosts != NULL)
        dbus_free_string_array(hosts);
     fprintf(stderr, "Argument is not a string array!\n");
     exit(1);
     }
  if (hosts != NULL) {
     printf("found %d host%s\n", num_hosts, (num_hosts == 1 ? "" : "s"));
     for (i = 0; i < num_hosts; i++)
         printf("host %d: %s\n", i + 1, hosts[i]);
     dbus_free_string_array(hosts);
     }
  dbus_message_unref(msg);
  return 0;
}
/**
 * _dbus_shell_parse_argv:
 *
 * Parses a command line into an argument vector, in much the same way
 * the shell would, but without many of the expansions the shell would
 * perform (variable expansion, globs, operators, filename expansion,
 * etc. are not supported). The results are defined to be the same as
 * those you would get from a UNIX98 /bin/sh, as long as the input
 * contains none of the unsupported shell expansions. If the input
 * does contain such expansions, they are passed through
 * literally. Free the returned vector with dbus_free_string_array().
 *
 * @command_line: command line to parse
 * @argcp: return location for number of args
 * @argvp: return location for array of args
 * @error: error information
 **/
dbus_bool_t
_dbus_shell_parse_argv (const char *command_line,
                        int        *argcp,
                        char     ***argvp,
                        DBusError  *error)
{
    /* Code based on poptParseArgvString() from libpopt */
    int argc = 0;
    char **argv = NULL;
    DBusList *tokens = NULL;
    int i;
    DBusList *tmp_list;

    if (!command_line)
    {
        _dbus_verbose ("Command line is NULL\n");
        return FALSE;
    }

    tokens = tokenize_command_line (command_line, error);
    if (tokens == NULL)
    {
        _dbus_verbose ("No tokens for command line '%s'\n", command_line);
        return FALSE;
    }

    /* Because we can't have introduced any new blank space into the
     * tokens (we didn't do any new expansions), we don't need to
     * perform field splitting. If we were going to honor IFS or do any
     * expansions, we would have to do field splitting on each word
     * here. Also, if we were going to do any expansion we would need to
     * remove any zero-length words that didn't contain quotes
     * originally; but since there's no expansion we know all words have
     * nonzero length, unless they contain quotes.
     *
     * So, we simply remove quotes, and don't do any field splitting or
     * empty word removal, since we know there was no way to introduce
     * such things.
     */

    argc = _dbus_list_get_length (&tokens);
    argv = dbus_new (char *, argc + 1);
    if (!argv)
    {
        _DBUS_SET_OOM (error);
        goto error;
    }

    i = 0;
    tmp_list = tokens;
    while (tmp_list)
    {
        argv[i] = _dbus_shell_unquote (tmp_list->data);

        if (!argv[i])
        {
            int j;
            for (j = 0; j < i; j++)
                dbus_free(argv[j]);

            dbus_free (argv);
            _DBUS_SET_OOM (error);
            goto error;
        }

        tmp_list = _dbus_list_get_next_link (&tokens, tmp_list);
        ++i;
    }
    argv[argc] = NULL;

    _dbus_list_foreach (&tokens, (DBusForeachFunction) dbus_free, NULL);
    _dbus_list_clear (&tokens);

    if (argcp)
        *argcp = argc;

    if (argvp)
        *argvp = argv;
    else
        dbus_free_string_array (argv);

    return TRUE;

error:
    _dbus_list_foreach (&tokens, (DBusForeachFunction) dbus_free, NULL);
    _dbus_list_clear (&tokens);

    return FALSE;

}
Exemplo n.º 7
0
static Tcl_Obj *DBus_ListListeners(Tcl_Interp *interp,
	Tcl_DBusBus *dbus, const char *path, int flags)
{
   Tcl_Obj *list, *sublist;
   char **entries, **entry, *newpath, *pathentry, *s;
   Tcl_DBusHandlerData *data;
   Tcl_DBusSignalData *signal;
   Tcl_DBusMethodData *method;
   Tcl_HashTable *interps;
   Tcl_HashEntry *memberPtr, *interpPtr;
   Tcl_HashSearch search;

   list = Tcl_NewObj();
   
   /* Check if the specified path has a handler defined */
   if (*path == '\0')
     data = dbus->fallback;
   else
     dbus_connection_get_object_path_data(dbus->conn, path, (void **)&data);
   if (data != NULL) {
      if ((flags & DBUS_METHODFLAG) == 0 && data->signal != NULL) {
	 for (memberPtr = Tcl_FirstHashEntry(data->signal, &search);
	      memberPtr != NULL; memberPtr = Tcl_NextHashEntry(&search)) {
	    interps = Tcl_GetHashValue(memberPtr);
	    interpPtr = Tcl_FindHashEntry(interps, (char *) interp);
	    if (interpPtr != NULL) {
	       signal = Tcl_GetHashValue(interpPtr);
	       /* Report both the path and the script configured for the path */
	       Tcl_ListObjAppendElement(NULL, list, Tcl_NewStringObj(path, -1));
	       s = Tcl_GetHashKey(data->signal, memberPtr);
	       Tcl_ListObjAppendElement(NULL, list, Tcl_NewStringObj(s, -1));
	       Tcl_ListObjAppendElement(NULL, list, signal->script);
	    }
	 }
      } else if ((flags & DBUS_METHODFLAG) != 0 && data->method != NULL) {
	 for (memberPtr = Tcl_FirstHashEntry(data->method, &search);
	      memberPtr != NULL; memberPtr = Tcl_NextHashEntry(&search)) {
	    method = Tcl_GetHashValue(memberPtr);
	    if (method->interp == interp) {
	       s = Tcl_GetHashKey(data->method, memberPtr);
	       /* Normally skip unknown handlers. But when listing */
	       /* unknown handlers, skip all named handlers. */
	       if (!(flags & DBUS_UNKNOWNFLAG) == (*s == '\0')) continue;
	       /* Report both the path and the script configured for the path */
	       Tcl_ListObjAppendElement(NULL, list, Tcl_NewStringObj(path, -1));
	       /* There is no method name for unknown handlers */
	       if (!(flags & DBUS_UNKNOWNFLAG))
		  Tcl_ListObjAppendElement(NULL, list, Tcl_NewStringObj(s, -1));
	       Tcl_ListObjAppendElement(NULL, list, method->script);
	    }
	 }
      }
   }
   if (flags & DBUS_RECURSEFLAG) {
      /* Get a list of children of the current path */
      dbus_connection_list_registered(dbus->conn, path, &entries);
      /* Allocate space for concatenating the path and a childs name */
      newpath = ckalloc(strlen(path) + 256);
      /* Copy the path in the allocated space, making sure it ends with a / */
      strcpy(newpath, path);
      pathentry = newpath + strlen(path) - 1;
      if (*pathentry++ != '/') *pathentry++ = '/';
      /* Append each childs name to the path in turn */
      for (entry = entries; *entry != NULL; entry++) {
	 strncpy(pathentry, *entry, 255);
	 /* Get a list of descendents from the child */
	 sublist = DBus_ListListeners(interp, dbus, newpath, flags);
	 /* Append the sublist entries to the total list */
	 Tcl_ListObjAppendList(NULL, list, sublist);
	 /* Release the temporary sublist */
	 Tcl_DecrRefCount(sublist);
      }
      /* Release the entries array */
      dbus_free_string_array(entries);
      ckfree(newpath);
   }
   return list;
}
Exemplo n.º 8
0
/**
 * Spawns a new process.
 *
 * On Unix platforms, the child_setup function is passed the given
 * user_data and is run in the child after fork() but before calling exec().
 * This can be used to change uid, resource limits and so on.
 * On Windows, this functionality does not fit the multi-processing model
 * (Windows does the equivalent of fork() and exec() in a single API call),
 * and the child_setup function and its user_data are ignored.
 *
 * Also creates a "babysitter" which tracks the status of the
 * child process, advising the parent if the child exits.
 * If the spawn fails, no babysitter is created.
 * If sitter_p is #NULL, no babysitter is kept.
 *
 * @param sitter_p return location for babysitter or #NULL
 * @param log_name the name under which to log messages about this process being spawned
 * @param argv the executable and arguments
 * @param env the environment, or #NULL to copy the parent's
 * @param child_setup function to call in child pre-exec()
 * @param user_data user data for setup function
 * @param error error object to be filled in if function fails
 * @returns #TRUE on success, #FALSE if error is filled in
 */
dbus_bool_t
_dbus_spawn_async_with_babysitter (DBusBabysitter          **sitter_p,
                                   const char               *log_name,
                                   char             * const *argv,
                                   char                    **env,
                                   DBusSpawnFlags            flags,
                                   DBusSpawnChildSetupFunc   child_setup,
                                   void                     *user_data,
                                   DBusError                *error)
{
  DBusBabysitter *sitter;
  int child_err_report_pipe[2] = { -1, -1 };
  DBusSocket babysitter_pipe[2] = { DBUS_SOCKET_INIT, DBUS_SOCKET_INIT };
  pid_t pid;
#ifdef HAVE_SYSTEMD
  int fd_out = -1;
  int fd_err = -1;
#endif
  
  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
  _dbus_assert (argv[0] != NULL);

  if (sitter_p != NULL)
    *sitter_p = NULL;

  sitter = NULL;

  sitter = _dbus_babysitter_new ();
  if (sitter == NULL)
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      return FALSE;
    }

  sitter->log_name = _dbus_strdup (log_name);
  if (sitter->log_name == NULL && log_name != NULL)
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      goto cleanup_and_fail;
    }

  if (sitter->log_name == NULL)
    sitter->log_name = _dbus_strdup (argv[0]);

  if (sitter->log_name == NULL)
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      goto cleanup_and_fail;
    }
  
  if (!make_pipe (child_err_report_pipe, error))
    goto cleanup_and_fail;

  if (!_dbus_socketpair (&babysitter_pipe[0], &babysitter_pipe[1], TRUE, error))
    goto cleanup_and_fail;

  /* Setting up the babysitter is only useful in the parent,
   * but we don't want to run out of memory and fail
   * after we've already forked, since then we'd leak
   * child processes everywhere.
   */
  sitter->error_watch = _dbus_watch_new (child_err_report_pipe[READ_END],
                                         DBUS_WATCH_READABLE,
                                         TRUE, handle_watch, sitter, NULL);
  if (sitter->error_watch == NULL)
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      goto cleanup_and_fail;
    }
        
  if (!_dbus_watch_list_add_watch (sitter->watches,  sitter->error_watch))
    {
      /* we need to free it early so the destructor won't try to remove it
       * without it having been added, which DBusLoop doesn't allow */
      _dbus_watch_invalidate (sitter->error_watch);
      _dbus_watch_unref (sitter->error_watch);
      sitter->error_watch = NULL;

      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      goto cleanup_and_fail;
    }
      
  sitter->sitter_watch = _dbus_watch_new (babysitter_pipe[0].fd,
                                          DBUS_WATCH_READABLE,
                                          TRUE, handle_watch, sitter, NULL);
  if (sitter->sitter_watch == NULL)
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      goto cleanup_and_fail;
    }
      
  if (!_dbus_watch_list_add_watch (sitter->watches,  sitter->sitter_watch))
    {
      /* we need to free it early so the destructor won't try to remove it
       * without it having been added, which DBusLoop doesn't allow */
      _dbus_watch_invalidate (sitter->sitter_watch);
      _dbus_watch_unref (sitter->sitter_watch);
      sitter->sitter_watch = NULL;

      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      goto cleanup_and_fail;
    }

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);

#ifdef HAVE_SYSTEMD
  if (flags & DBUS_SPAWN_REDIRECT_OUTPUT)
    {
      /* This may fail, but it's not critical.
       * In particular, if we were compiled with journald support but are now
       * running on a non-systemd system, this is going to fail, so we
       * have to cope gracefully. */
      fd_out = sd_journal_stream_fd (sitter->log_name, LOG_INFO, FALSE);
      fd_err = sd_journal_stream_fd (sitter->log_name, LOG_WARNING, FALSE);
    }
#endif

  pid = fork ();
  
  if (pid < 0)
    {
      dbus_set_error (error,
		      DBUS_ERROR_SPAWN_FORK_FAILED,
		      "Failed to fork (%s)",
		      _dbus_strerror (errno));
      goto cleanup_and_fail;
    }
  else if (pid == 0)
    {
      /* Immediate child, this is the babysitter process. */
      int grandchild_pid;
      
      /* Be sure we crash if the parent exits
       * and we write to the err_report_pipe
       */
      signal (SIGPIPE, SIG_DFL);

      /* Close the parent's end of the pipes. */
      close_and_invalidate (&child_err_report_pipe[READ_END]);
      close_and_invalidate (&babysitter_pipe[0].fd);
      
      /* Create the child that will exec () */
      grandchild_pid = fork ();
      
      if (grandchild_pid < 0)
	{
	  write_err_and_exit (babysitter_pipe[1].fd,
			      CHILD_FORK_FAILED);
          _dbus_assert_not_reached ("Got to code after write_err_and_exit()");
	}
      else if (grandchild_pid == 0)
      {
#ifdef __linux__
          int fd = -1;

#ifdef O_CLOEXEC
          fd = open ("/proc/self/oom_score_adj", O_WRONLY | O_CLOEXEC);
#endif

          if (fd < 0)
            {
              fd = open ("/proc/self/oom_score_adj", O_WRONLY);
              _dbus_fd_set_close_on_exec (fd);
            }

          if (fd >= 0)
            {
              if (write (fd, "0", sizeof (char)) < 0)
                _dbus_warn ("writing oom_score_adj error: %s", strerror (errno));
              _dbus_close (fd, NULL);
            }
#endif
          /* Go back to ignoring SIGPIPE, since it's evil
           */
          signal (SIGPIPE, SIG_IGN);

          close_and_invalidate (&babysitter_pipe[1].fd);
#ifdef HAVE_SYSTEMD
	  /* log to systemd journal if possible */
	  if (fd_out >= 0)
            dup2 (fd_out, STDOUT_FILENO);
	  if (fd_err >= 0)
            dup2 (fd_err, STDERR_FILENO);
          close_and_invalidate (&fd_out);
          close_and_invalidate (&fd_err);
#endif
	  do_exec (child_err_report_pipe[WRITE_END],
		   argv,
		   env,
		   child_setup, user_data);
          _dbus_assert_not_reached ("Got to code after exec() - should have exited on error");
	}
      else
	{
          close_and_invalidate (&child_err_report_pipe[WRITE_END]);
#ifdef HAVE_SYSTEMD
          close_and_invalidate (&fd_out);
          close_and_invalidate (&fd_err);
#endif
          babysit (grandchild_pid, babysitter_pipe[1].fd);
          _dbus_assert_not_reached ("Got to code after babysit()");
	}
    }
  else
    {      
      /* Close the uncared-about ends of the pipes */
      close_and_invalidate (&child_err_report_pipe[WRITE_END]);
      close_and_invalidate (&babysitter_pipe[1].fd);
#ifdef HAVE_SYSTEMD
      close_and_invalidate (&fd_out);
      close_and_invalidate (&fd_err);
#endif

      sitter->socket_to_babysitter = babysitter_pipe[0];
      babysitter_pipe[0].fd = -1;
      
      sitter->error_pipe_from_child = child_err_report_pipe[READ_END];
      child_err_report_pipe[READ_END] = -1;

      sitter->sitter_pid = pid;

      if (sitter_p != NULL)
        *sitter_p = sitter;
      else
        _dbus_babysitter_unref (sitter);

      dbus_free_string_array (env);

      _DBUS_ASSERT_ERROR_IS_CLEAR (error);
      
      return TRUE;
    }

 cleanup_and_fail:

  _DBUS_ASSERT_ERROR_IS_SET (error);
  
  close_and_invalidate (&child_err_report_pipe[READ_END]);
  close_and_invalidate (&child_err_report_pipe[WRITE_END]);
  close_and_invalidate (&babysitter_pipe[0].fd);
  close_and_invalidate (&babysitter_pipe[1].fd);
#ifdef HAVE_SYSTEMD
  close_and_invalidate (&fd_out);
  close_and_invalidate (&fd_err);
#endif

  if (sitter != NULL)
    _dbus_babysitter_unref (sitter);
  
  return FALSE;
}
Exemplo n.º 9
0
static int array_arg_destructor(struct array_arg *arg)
{
    dbus_free_string_array(arg->dbus_array);
    return 0;
}
Exemplo n.º 10
0
static int
run_session (const char *dbus_daemon,
             const char *config_file,
             char       *bus_address,
             char      **argv,
             int         prog_arg)
{
  char *dbus_daemon_argv[3];
  int ret = 127;
  HANDLE server_handle = NULL;
  HANDLE app_handle = NULL;
  DWORD exit_code;
  DBusString argv_strings[4];
  DBusString address;
  char **env = NULL;
  DBusHashTable *env_table = NULL;
  long sec,usec;
  dbus_bool_t result = TRUE;
  char *key = NULL;
  char *value = NULL;

  if (!_dbus_string_init (&argv_strings[0]))
    result = FALSE;
  if (!_dbus_string_init (&argv_strings[1]))
    result = FALSE;
  if (!_dbus_string_init (&argv_strings[2]))
    result = FALSE;
  if (!_dbus_string_init (&address))
    result = FALSE;
  if (!result)
    goto out;

  /* run dbus daemon */
  _dbus_get_real_time (&sec, &usec);
  /* On Windows it's difficult to make use of --print-address to
   * convert a listenable address into a connectable address, so instead
   * we tell the temporary dbus-daemon to use the Windows autolaunch
   * mechanism, with a unique scope that is shared by this dbus-daemon,
   * the app process that defines its lifetime, and any other child
   * processes they might have. */
  _dbus_string_append_printf (&address, "autolaunch:scope=dbus-tmp-session-%ld%ld-" DBUS_PID_FORMAT, sec, usec, _dbus_getpid ());
  _dbus_string_append_printf (&argv_strings[0], "%s", dbus_daemon);
  if (config_file != NULL)
    _dbus_string_append_printf (&argv_strings[1], "--config-file=%s", config_file);
  else
    _dbus_string_append_printf (&argv_strings[1], "--session");
  _dbus_string_append_printf (&argv_strings[2], "--address=%s", _dbus_string_get_const_data (&address));
  dbus_daemon_argv[0] = _dbus_string_get_data (&argv_strings[0]);
  dbus_daemon_argv[1] = _dbus_string_get_data (&argv_strings[1]);
  dbus_daemon_argv[2] = _dbus_string_get_data (&argv_strings[2]);
  dbus_daemon_argv[3] = NULL;

  server_handle = _dbus_spawn_program (dbus_daemon, dbus_daemon_argv, NULL);
  if (!server_handle)
    {
      _dbus_win_stderr_win_error (me, "Could not start dbus daemon", GetLastError ());
      goto out;
    }

  /* run app */
  env = _dbus_get_environment ();
  env_table = _dbus_hash_table_new (DBUS_HASH_STRING,
                                    dbus_free,
                                    dbus_free);
  if (!_dbus_hash_table_from_array (env_table, env, '='))
    {
      goto out;
    }

  /* replace DBUS_SESSION_BUS_ADDRESS in environment */
  if (!_dbus_string_steal_data (&address, &value))
    goto out;

  key = _dbus_strdup ("DBUS_SESSION_BUS_ADDRESS");

  if (key == NULL)
    goto out;

  if (_dbus_hash_table_insert_string (env_table, key, value))
    {
      /* env_table took ownership, do not free separately */
      key = NULL;
      value = NULL;
    }
  else
    {
      /* we still own key and value, the cleanup code will free them */
      goto out;
    }

  _dbus_hash_table_remove_string (env_table, "DBUS_STARTER_ADDRESS");
  _dbus_hash_table_remove_string (env_table, "DBUS_STARTER_BUS_TYPE");
  _dbus_hash_table_remove_string (env_table, "DBUS_SESSION_BUS_PID");
  _dbus_hash_table_remove_string (env_table, "DBUS_SESSION_BUS_WINDOWID");

  dbus_free_string_array (env);
  env = _dbus_hash_table_to_array (env_table, '=');
  if (!env)
    goto out;

  app_handle = _dbus_spawn_program (argv[prog_arg], argv + prog_arg, env);
  if (!app_handle)
    {
      _dbus_win_stderr_win_error (me, "unable to start child process", GetLastError ());
      goto out;
    }

  WaitForSingleObject (app_handle, INFINITE);
  if (!GetExitCodeProcess (app_handle, &exit_code))
    {
      _dbus_win_stderr_win_error (me, "could not fetch exit code", GetLastError ());
      goto out;
    }
  ret = exit_code;

out:
  TerminateProcess (server_handle, 0);
  if (server_handle != NULL)
    CloseHandle (server_handle);
  if (app_handle != NULL)
    CloseHandle (app_handle);
  _dbus_string_free (&argv_strings[0]);
  _dbus_string_free (&argv_strings[1]);
  _dbus_string_free (&argv_strings[2]);
  _dbus_string_free (&address);
  dbus_free_string_array (env);
  if (env_table != NULL)
    _dbus_hash_table_unref (env_table);
  dbus_free (key);
  dbus_free (value);
  return ret;
}
Exemplo n.º 11
0
char *
battstat_hal_initialise (void (*callback) (void))
{
  DBusConnection *connection;
  LibHalContext *ctx;
  DBusError error;
  char *error_str;
  char **devices;
  int i, num;

  status_updated_callback = callback;

  if( battstat_hal_ctx != NULL )
    return g_strdup( "Already initialised!" );

  dbus_error_init( &error );

  if( (connection = dbus_bus_get( DBUS_BUS_SYSTEM, &error )) == NULL )
    goto error_out;

  dbus_connection_setup_with_g_main( connection, g_main_context_default() );

  if( (ctx = libhal_ctx_new()) == NULL )
  {
    dbus_set_error( &error, _("HAL error"), _("Could not create libhal_ctx") );
    goto error_out;
  }

  libhal_ctx_set_device_property_modified( ctx, property_callback );
  libhal_ctx_set_device_added( ctx, device_added_callback );
  libhal_ctx_set_device_removed( ctx, device_removed_callback );
  libhal_ctx_set_dbus_connection( ctx, connection );

  if( libhal_ctx_init( ctx, &error ) == 0 )
    goto error_freectx;
  
  devices = libhal_find_device_by_capability( ctx, "battery", &num, &error );

  if( devices == NULL )
    goto error_shutdownctx;

  /* FIXME: for now, if 0 battery devices are present on first scan, then fail.
   * This allows fallover to the legacy (ACPI, APM, etc) backends if the
   * installed version of HAL doesn't know about batteries.  This check should
   * be removed at some point in the future (maybe circa MATE 2.13..).
   */
  if( num == 0 )
  {
    dbus_free_string_array( devices );
    dbus_set_error( &error, _("HAL error"), _("No batteries found") );
    goto error_shutdownctx;
  }

  for( i = 0; i < num; i++ )
  {
    char *type = libhal_device_get_property_string( ctx, devices[i],
                                                    "battery.type",
                                                    &error );

    if( type )
    {
      /* We only track 'primary' batteries (ie: to avoid monitoring
       * batteries in cordless mice or UPSes etc.)
       */
      if( !strcmp( type, "primary" ) )
        add_to_list( ctx, &batteries, devices[i],
                     sizeof (struct battery_info) );

      libhal_free_string( type );
    }
  }
  dbus_free_string_array( devices );

  devices = libhal_find_device_by_capability( ctx, "ac_adapter", &num, &error );

  if( devices == NULL )
  {
    batteries = free_entire_list( batteries );
    goto error_shutdownctx;
  }

  for( i = 0; i < num; i++ )
    add_to_list( ctx, &adaptors, devices[i], sizeof (struct adaptor_info) );
  dbus_free_string_array( devices );

  dbus_error_free( &error );

  battstat_hal_ctx = ctx;

  return NULL;

error_shutdownctx:
  libhal_ctx_shutdown( ctx, NULL );

error_freectx:
  libhal_ctx_free( ctx );

error_out:
  error_str = g_strdup_printf( _("Unable to initialise HAL: %s: %s"),
                               error.name, error.message );
  dbus_error_free( &error );
  return error_str;
}
Exemplo n.º 12
0
DBusHandlerResult handle_dbus_message( DBusConnection *connection, DBusMessage *message, void *data )
{
  int eax;
  int esi;
  int msg_type;
  switch ( msg_type )
  {
  default:
    break;
  case 4:
    break;
  case 3:
    break;
  case 2:
    break;
  case 1:
  {
    char *method_name;
    char *interface_name;
    if ( dbus_message_get_member( &message ) )
    {
      if ( interface_name )
      {
        /* phantom */ size_t __s1_len;
        /* phantom */ size_t __s2_len;
        strcmp( "org.seul.geda.pcb", interface_name );
        if ( 1 )
        {
          /* phantom */ size_t __s1_len;
          /* phantom */ size_t __s2_len;
          method_name[0] = dbus_message_get_member( &message );
          strcmp( "GetFilename", dbus_message_get_member( &message ) );
          if ( !1 )
          {
            __fprintf_chk( stderr, 1, "pcb_dbus: Interface '%s' has no method '%s'\n", dbus_message_get_interface( &message ), ebp_184 );
            return 1;
          }
          else
          {
            if ( dbus_message_new_method_return( &message ) )
            {
              dbus_message_iter_init_append( dbus_message_new_method_return( &message ), ebp_112 );
              if ( PCB->Filename )
              {
                if ( lrealpath( &PCB->Filename ) == 0 )
                  goto B38;
                else
                {
                  if ( dbus_message_iter_append_basic( ebp_112, 115, ebp_32 ) )
                  {
                    free( ebp_32 );
                  }
                  else
                  {
                    __fprintf_chk( stderr, 1, "pcb_dbus: Couldn't append return filename string to message reply, Out Of Memory!\n" );
                    free( ebp_32 );
                    dbus_message_unref( &ebx );
                    return 0;
                  }
                }
              }
              else
              {
              }
B38:;
              if ( calloc( 1, 1 ) )
              {
              }
              else
              {
                __fprintf_chk( stderr, 1, ebp_192, ebp_192 );
              }
            }
            else
            {
            }
          }
        }
        else
        {
          /* phantom */ size_t __s1_len;
          /* phantom */ size_t __s2_len;
          strcmp( "org.seul.geda.pcb.actions", interface_name );
          if ( 1 )
          {
            /* phantom */ size_t __s1_len;
            /* phantom */ size_t __s2_len;
            method_name[0] = ebp_140;
            strcmp( "ExecAction", ebp_140 );
            if ( !1 )
            {
              __fprintf_chk( stderr, 1, "pcb_dbus: Interface '%s' has no method '%s'\n", dbus_message_get_interface( &message ), ebp_184 );
            }
            else
            {
              dbus_error_init( ebp_56 );
              if ( dbus_message_get_args( &message, ebp_56, 115, ebp_32, 97, (long long)115, (long long)( ebp_40 ) ) )
              {
                hid_actionv( (char*)calloc( 1, 1 ), ebp_40, ebp_36 );
                dbus_free_string_array( 0 );
                if ( dbus_message_new_method_return( &message ) )
                {
                  dbus_message_iter_init_append( dbus_message_new_method_return( &message ), ebp_112 );
                  if ( dbus_message_iter_append_basic( ebp_112, 117, ebp_28 ) )
                  {
                  }
                  else
                  {
                  }
                }
              }
              else
              {
                __fprintf_chk( stderr, 1, "Failed to read method arguments\n" );
                if ( 0 )
                {
                  dbus_free_string_array( 0 );
                }
              }
            }
          }
          else
          {
            /* phantom */ size_t __s1_len;
            /* phantom */ size_t __s2_len;
            strcmp( "org.freedesktop.DBus.Introspectable", interface_name );
            if ( !1 )
            {
              __fprintf_chk( stderr, 1, "pcb_dbus: Interface '%s' was not recognised\n", dbus_message_iter_append_basic( ebp_112, 117, ebp_28 ) );
            }
          {
            /* phantom */ size_t __s1_len;
            /* phantom */ size_t __s2_len;
            method_name[0] = dbus_message_get_member( &message );
            strcmp( "Introspect", dbus_message_get_member( &message ) );
            if ( !1 )
            {
              __fprintf_chk( stderr, 1, "pcb_dbus: Interface '%s' has no method '%s'\n", dbus_message_get_interface( &message ), ebp_184 );
            }
            else
            {
              if ( dbus_message_new_method_return( &message ) )
              {
                dbus_message_iter_init_append( dbus_message_new_method_return( &message ), ebp_112 );
                if ( dbus_message_iter_append_basic( ebp_112, 115, pcb_dbus_introspect_xml ) )
                {
                  if ( dbus_connection_send( &pcb_dbus_conn, (DBusMessage*)dbus_message_get_interface( &message ), 0 ) )
                  {
                    dbus_message_unref( &ebx );
                    return 0;
                  }
                }
                else
                {
                }
              }
            }
          }
          }
        }
        if ( dbus_connection_send( ebp_200, ebp_200, ebp_196 ) )
        {
          dbus_message_unref( &ebx );
          return 0;
        }
      }
      else
      {
      }
    }
    else
    {
    }
  }
    break;
  }
  __fprintf_chk( stderr, 1, ebp_192, ebp_192 );
}
/**
 * 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;
}
Exemplo n.º 14
0
static DBusHandlerResult
wsnamesDbusHandleMessage (DBusConnection *connection,
                          DBusMessage    *message,
                          void           *userData)
{
	char **path;

	if (!dbus_message_get_path_decomposed (message, &path))
		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

	if (!path[0] || !path[1] || !path[2])
	{
		dbus_free_string_array (path);
		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
	}

	if (!path[3]) //message to /org/fusilli/wsnames
	{
		if (dbus_message_is_method_call (message,
		                                 DBUS_INTERFACE_INTROSPECTABLE,
		                                 "Introspect"))
		{
			dbus_free_string_array (path);
			return DBUS_HANDLER_RESULT_HANDLED;
		}
		else if (dbus_message_is_method_call (message,
		                                      "org.fusilli",
		                                      "getNames"))
		{
			DBusMessage *reply = NULL;

			DBusMessageIter param_iter;
			CompScreen *s;
			int screenNum = -1;

			//read the parameter
			if (dbus_message_iter_init (message, &param_iter))
				if (dbus_message_iter_get_arg_type (&param_iter) == 
				                                            DBUS_TYPE_INT32)
					dbus_message_iter_get_basic (&param_iter, &screenNum);

			s = getScreenFromScreenNum (screenNum);

			if (!s)
			{
				reply = dbus_message_new_error (message,
				        DBUS_ERROR_FAILED,
				        "Invalid or missing parameter");

				dbus_connection_send (connection, reply, NULL);
				dbus_connection_flush (connection);
				dbus_message_unref (reply);
				dbus_free_string_array (path);

				return DBUS_HANDLER_RESULT_HANDLED;
			}

			//give the reply
			reply = dbus_message_new_method_return (message);

			dbusComposeNamesList (s, reply);

			dbus_connection_send (connection, reply, NULL);
			dbus_connection_flush (connection);
			dbus_message_unref (reply);
			dbus_free_string_array (path);

			return DBUS_HANDLER_RESULT_HANDLED;
		}
	}

	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
Exemplo n.º 15
0
static DBusHandlerResult
handle_exec_action (DBusConnection * connection, DBusMessage * message,
		    void *data)
{
  DBusMessage *reply;
  DBusMessageIter iter;
  DBusHandlerResult result;
  DBusError err;
  dbus_uint32_t retval;
  char *action_name;
  char **argv;
  int argc;
#ifdef DEBUG
  int i;
#endif

  result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

  // TODO: Should check the message signature matches what we expect?

  // initialise the error struct
  dbus_error_init (&err);

  /* DON'T FREE action_name, as it belongs to DBUS,
   * DO    FREE argv, using dbus_free_string_array()
   */
  argv = NULL;
  if (!dbus_message_get_args (message,
			      &err,
			      DBUS_TYPE_STRING, &action_name,
			      DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &argv, &argc,
			      DBUS_TYPE_INVALID))
    {
      fprintf (stderr, "Failed to read method arguments\n");
      if (argv)
	dbus_free_string_array (argv);
      return result;
    }

#ifdef DEBUG
  fprintf (stderr, "pcb_dbus: DEBUG: Executing action: %s(", action_name);
  if (argc > 0)
    fprintf (stderr, " \"%s\"", argv[0]);
  for (i = 1; i < argc; i++)
    fprintf (stderr, ", \"%s\"", argv[i]);
  fprintf (stderr, " )\n");
#endif

  // TODO: Proper return value from actions
  hid_actionv (action_name, argc, argv);
  retval = 0;

  dbus_free_string_array (argv);

  reply = dbus_message_new_method_return (message);
  if (reply == NULL)
    {
      fprintf (stderr, "pcb_dbus: Couldn't create reply message\n");
      return result;
    }
  dbus_message_iter_init_append (reply, &iter);
  if (!dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &retval))
    {
      fprintf (stderr, "pcb_dbus: Couldn't sent message, Out Of Memory!\n");
      goto out;
    }

  if (!dbus_connection_send (connection, reply, NULL))
    {
      fprintf (stderr, "pcb_dbus: Couldn't send message, Out Of Memory!\n");
      goto out;
    }

  result = DBUS_HANDLER_RESULT_HANDLED;
out:
  dbus_message_unref (reply);
  return result;
}
JNIEXPORT jobjectArray JNICALL
Java_net_java_sip_communicator_impl_galagonotification_GalagoNotification_getCapabilities(
    JNIEnv *env, jclass clazz, jlong connection)
{
    DBusMessage *message;
    jobjectArray jcapabilities = NULL;

    message
        = dbus_message_new_method_call(
            "org.freedesktop.Notifications",
            "/org/freedesktop/Notifications",
            "org.freedesktop.Notifications",
            "GetCapabilities");
    if (message)
    {
        DBusError error;
        DBusMessage *reply;

        dbus_error_init(&error);
        reply
            = dbus_connection_send_with_reply_and_block(
                (DBusConnection *) connection,
                message,
                -1,
                &error);
        if (reply)
        {
            char **capabilities;
            int capabilityCount;

            if (dbus_message_get_args(
                    reply,
                    &error,
                    DBUS_TYPE_ARRAY,
                    DBUS_TYPE_STRING,
                    &capabilities,
                    &capabilityCount,
                    DBUS_TYPE_INVALID))
            {
                jcapabilities
                    = GalagoNotification_stringArray2jstringArray(
                        env,
                        capabilities,
                        capabilityCount);
                dbus_free_string_array(capabilities);
            }
            else
            {
                GalagoNotification_throwException(env, &error);
                dbus_error_free(&error);
            }
            dbus_message_unref(reply);
        }
        else if (dbus_error_is_set(&error))
        {
            GalagoNotification_throwException(env, &error);
            dbus_error_free(&error);
        }
        dbus_message_unref(message);
    }
    return jcapabilities;
}
Exemplo n.º 17
0
/**
 * Spawns a new process. The executable name and argv[0]
 * are the same, both are provided in argv[0]. The child_setup
 * function is passed the given user_data and is run in the child
 * just before calling exec().
 *
 * Also creates a "babysitter" which tracks the status of the
 * child process, advising the parent if the child exits.
 * If the spawn fails, no babysitter is created.
 * If sitter_p is #NULL, no babysitter is kept.
 *
 * @param sitter_p return location for babysitter or #NULL
 * @param argv the executable and arguments
 * @param env the environment (not used on unix yet)
 * @param child_setup function to call in child pre-exec()
 * @param user_data user data for setup function
 * @param error error object to be filled in if function fails
 * @returns #TRUE on success, #FALSE if error is filled in
 */
dbus_bool_t
_dbus_spawn_async_with_babysitter (DBusBabysitter          **sitter_p,
                                   char                    **argv,
                                   char                    **env,
                                   DBusSpawnChildSetupFunc   child_setup,
                                   void                     *user_data,
                                   DBusError                *error)
{
    DBusBabysitter *sitter;
    int child_err_report_pipe[2] = { -1, -1 };
    int babysitter_pipe[2] = { -1, -1 };
    pid_t pid;

    _DBUS_ASSERT_ERROR_IS_CLEAR (error);

    if (sitter_p != NULL)
        *sitter_p = NULL;

    sitter = NULL;

    sitter = _dbus_babysitter_new ();
    if (sitter == NULL)
    {
        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
        return FALSE;
    }

    sitter->executable = _dbus_strdup (argv[0]);
    if (sitter->executable == NULL)
    {
        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
        goto cleanup_and_fail;
    }

    if (!make_pipe (child_err_report_pipe, error))
        goto cleanup_and_fail;

    if (!_dbus_full_duplex_pipe (&babysitter_pipe[0], &babysitter_pipe[1], TRUE, error))
        goto cleanup_and_fail;

    /* Setting up the babysitter is only useful in the parent,
     * but we don't want to run out of memory and fail
     * after we've already forked, since then we'd leak
     * child processes everywhere.
     */
    sitter->error_watch = _dbus_watch_new (child_err_report_pipe[READ_END],
                                           DBUS_WATCH_READABLE,
                                           TRUE, handle_watch, sitter, NULL);
    if (sitter->error_watch == NULL)
    {
        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
        goto cleanup_and_fail;
    }

    if (!_dbus_watch_list_add_watch (sitter->watches,  sitter->error_watch))
    {
        /* we need to free it early so the destructor won't try to remove it
         * without it having been added, which DBusLoop doesn't allow */
        _dbus_watch_invalidate (sitter->error_watch);
        _dbus_watch_unref (sitter->error_watch);
        sitter->error_watch = NULL;

        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
        goto cleanup_and_fail;
    }

    sitter->sitter_watch = _dbus_watch_new (babysitter_pipe[0],
                                            DBUS_WATCH_READABLE,
                                            TRUE, handle_watch, sitter, NULL);
    if (sitter->sitter_watch == NULL)
    {
        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
        goto cleanup_and_fail;
    }

    if (!_dbus_watch_list_add_watch (sitter->watches,  sitter->sitter_watch))
    {
        /* we need to free it early so the destructor won't try to remove it
         * without it having been added, which DBusLoop doesn't allow */
        _dbus_watch_invalidate (sitter->sitter_watch);
        _dbus_watch_unref (sitter->sitter_watch);
        sitter->sitter_watch = NULL;

        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
        goto cleanup_and_fail;
    }

    _DBUS_ASSERT_ERROR_IS_CLEAR (error);

    pid = fork ();

    if (pid < 0)
    {
        dbus_set_error (error,
                        DBUS_ERROR_SPAWN_FORK_FAILED,
                        "Failed to fork (%s)",
                        _dbus_strerror (errno));
        goto cleanup_and_fail;
    }
    else if (pid == 0)
    {
        /* Immediate child, this is the babysitter process. */
        int grandchild_pid;

        /* Be sure we crash if the parent exits
         * and we write to the err_report_pipe
         */
        signal (SIGPIPE, SIG_DFL);

        /* Close the parent's end of the pipes. */
        close_and_invalidate (&child_err_report_pipe[READ_END]);
        close_and_invalidate (&babysitter_pipe[0]);

        /* Create the child that will exec () */
        grandchild_pid = fork ();

        if (grandchild_pid < 0)
        {
            write_err_and_exit (babysitter_pipe[1],
                                CHILD_FORK_FAILED);
            _dbus_assert_not_reached ("Got to code after write_err_and_exit()");
        }
        else if (grandchild_pid == 0)
        {
            do_exec (child_err_report_pipe[WRITE_END],
                     argv,
                     env,
                     child_setup, user_data);
            _dbus_assert_not_reached ("Got to code after exec() - should have exited on error");
        }
        else
        {
            babysit (grandchild_pid, babysitter_pipe[1]);
            _dbus_assert_not_reached ("Got to code after babysit()");
        }
    }
    else
    {
        /* Close the uncared-about ends of the pipes */
        close_and_invalidate (&child_err_report_pipe[WRITE_END]);
        close_and_invalidate (&babysitter_pipe[1]);

        sitter->socket_to_babysitter = babysitter_pipe[0];
        babysitter_pipe[0] = -1;

        sitter->error_pipe_from_child = child_err_report_pipe[READ_END];
        child_err_report_pipe[READ_END] = -1;

        sitter->sitter_pid = pid;

        if (sitter_p != NULL)
            *sitter_p = sitter;
        else
            _dbus_babysitter_unref (sitter);

        dbus_free_string_array (env);

        _DBUS_ASSERT_ERROR_IS_CLEAR (error);

        return TRUE;
    }

cleanup_and_fail:

    _DBUS_ASSERT_ERROR_IS_SET (error);

    close_and_invalidate (&child_err_report_pipe[READ_END]);
    close_and_invalidate (&child_err_report_pipe[WRITE_END]);
    close_and_invalidate (&babysitter_pipe[0]);
    close_and_invalidate (&babysitter_pipe[1]);

    if (sitter != NULL)
        _dbus_babysitter_unref (sitter);

    return FALSE;
}
static void
verify_test_message (DBusMessage *message)
{
  DBusMessageIter iter;
  DBusError error = DBUS_ERROR_INIT;
  dbus_int16_t our_int16;
  dbus_uint16_t our_uint16;
  dbus_int32_t our_int;
  dbus_uint32_t our_uint;
  const char *our_str;
  double our_double;
  double v_DOUBLE;
  dbus_bool_t our_bool;
  unsigned char our_byte_1, our_byte_2;
  const dbus_uint32_t *our_uint32_array = (void*)0xdeadbeef;
  int our_uint32_array_len;
  dbus_int32_t *our_int32_array = (void*)0xdeadbeef;
  int our_int32_array_len;
#ifdef DBUS_HAVE_INT64
  dbus_int64_t our_int64;
  dbus_uint64_t our_uint64;
  dbus_int64_t *our_uint64_array = (void*)0xdeadbeef;
  int our_uint64_array_len;
  const dbus_int64_t *our_int64_array = (void*)0xdeadbeef;
  int our_int64_array_len;
#endif
  const double *our_double_array = (void*)0xdeadbeef;
  int our_double_array_len;
  const unsigned char *our_byte_array = (void*)0xdeadbeef;
  int our_byte_array_len;
  const dbus_bool_t *our_boolean_array = (void*)0xdeadbeef;
  int our_boolean_array_len;
  char **our_string_array;
  int our_string_array_len;

  dbus_message_iter_init (message, &iter);

  if (!dbus_message_iter_get_args (&iter, &error,
                                   DBUS_TYPE_INT16, &our_int16,
                                   DBUS_TYPE_UINT16, &our_uint16,
				   DBUS_TYPE_INT32, &our_int,
                                   DBUS_TYPE_UINT32, &our_uint,
#ifdef DBUS_HAVE_INT64
                                   DBUS_TYPE_INT64, &our_int64,
                                   DBUS_TYPE_UINT64, &our_uint64,
#endif
				   DBUS_TYPE_STRING, &our_str,
				   DBUS_TYPE_DOUBLE, &our_double,
				   DBUS_TYPE_BOOLEAN, &our_bool,
				   DBUS_TYPE_BYTE, &our_byte_1,
				   DBUS_TYPE_BYTE, &our_byte_2,
				   DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
                                   &our_uint32_array, &our_uint32_array_len,
                                   DBUS_TYPE_ARRAY, DBUS_TYPE_INT32,
                                   &our_int32_array, &our_int32_array_len,
#ifdef DBUS_HAVE_INT64
				   DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64,
                                   &our_uint64_array, &our_uint64_array_len,
                                   DBUS_TYPE_ARRAY, DBUS_TYPE_INT64,
                                   &our_int64_array, &our_int64_array_len,
#endif
                                   DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE,
                                   &our_double_array, &our_double_array_len,
                                   DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
                                   &our_byte_array, &our_byte_array_len,
                                   DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN,
                                   &our_boolean_array, &our_boolean_array_len,
                                   DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
                                   &our_string_array, &our_string_array_len,
				   0))
    {
      _dbus_warn ("error: %s - %s\n", error.name,
                  (error.message != NULL) ? error.message : "no message");
      _dbus_assert_not_reached ("Could not get arguments");
    }

  if (our_int16 != -0x123)
    _dbus_assert_not_reached ("16-bit integers differ!");

  if (our_uint16 != 0x123)
    _dbus_assert_not_reached ("16-bit uints differ!");
  
  if (our_int != -0x12345678)
    _dbus_assert_not_reached ("integers differ!");

  if (our_uint != 0x12300042)
    _dbus_assert_not_reached ("uints differ!");

#ifdef DBUS_HAVE_INT64
  if (our_int64 != DBUS_INT64_CONSTANT (-0x123456789abcd))
    _dbus_assert_not_reached ("64-bit integers differ!");
  if (our_uint64 != DBUS_UINT64_CONSTANT (0x123456789abcd))
    _dbus_assert_not_reached ("64-bit unsigned integers differ!");
#endif

  v_DOUBLE = 3.14159;
  if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double, v_DOUBLE))
    _dbus_assert_not_reached ("doubles differ!");

  if (strcmp (our_str, "Test string") != 0)
    _dbus_assert_not_reached ("strings differ!");

  if (!our_bool)
    _dbus_assert_not_reached ("booleans differ");

  if (our_byte_1 != 42)
    _dbus_assert_not_reached ("bytes differ!");

  if (our_byte_2 != 24)
    _dbus_assert_not_reached ("bytes differ!");

  if (our_uint32_array_len != 4 ||
      our_uint32_array[0] != 0x12345678 ||
      our_uint32_array[1] != 0x23456781 ||
      our_uint32_array[2] != 0x34567812 ||
      our_uint32_array[3] != 0x45678123)
    _dbus_assert_not_reached ("uint array differs");

  if (our_int32_array_len != 4 ||
      our_int32_array[0] != 0x12345678 ||
      our_int32_array[1] != -0x23456781 ||
      our_int32_array[2] != 0x34567812 ||
      our_int32_array[3] != -0x45678123)
    _dbus_assert_not_reached ("int array differs");

#ifdef DBUS_HAVE_INT64
  if (our_uint64_array_len != 4 ||
      our_uint64_array[0] != 0x12345678 ||
      our_uint64_array[1] != 0x23456781 ||
      our_uint64_array[2] != 0x34567812 ||
      our_uint64_array[3] != 0x45678123)
    _dbus_assert_not_reached ("uint64 array differs");

  if (our_int64_array_len != 4 ||
      our_int64_array[0] != 0x12345678 ||
      our_int64_array[1] != -0x23456781 ||
      our_int64_array[2] != 0x34567812 ||
      our_int64_array[3] != -0x45678123)
    _dbus_assert_not_reached ("int64 array differs");
#endif /* DBUS_HAVE_INT64 */

  if (our_double_array_len != 3)
    _dbus_assert_not_reached ("double array had wrong length");

  /* On all IEEE machines (i.e. everything sane) exact equality
   * should be preserved over the wire
   */
  v_DOUBLE = 0.1234;
  if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[0], v_DOUBLE))
    _dbus_assert_not_reached ("double array had wrong values");
  v_DOUBLE = 9876.54321;
  if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[1], v_DOUBLE))
    _dbus_assert_not_reached ("double array had wrong values");
  v_DOUBLE = -300.0;
  if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[2], v_DOUBLE))
    _dbus_assert_not_reached ("double array had wrong values");

  if (our_byte_array_len != 4)
    _dbus_assert_not_reached ("byte array had wrong length");

  if (our_byte_array[0] != 'a' ||
      our_byte_array[1] != 'b' ||
      our_byte_array[2] != 'c' ||
      our_byte_array[3] != 234)
    _dbus_assert_not_reached ("byte array had wrong values");

  if (our_boolean_array_len != 5)
    _dbus_assert_not_reached ("bool array had wrong length");

  if (our_boolean_array[0] != TRUE ||
      our_boolean_array[1] != FALSE ||
      our_boolean_array[2] != TRUE ||
      our_boolean_array[3] != TRUE ||
      our_boolean_array[4] != FALSE)
    _dbus_assert_not_reached ("bool array had wrong values");

  if (our_string_array_len != 4)
    _dbus_assert_not_reached ("string array was wrong length");

  if (strcmp (our_string_array[0], "Foo") != 0 ||
      strcmp (our_string_array[1], "bar") != 0 ||
      strcmp (our_string_array[2], "") != 0 ||
      strcmp (our_string_array[3], "woo woo woo woo") != 0)
    _dbus_assert_not_reached ("string array had wrong values");

  dbus_free_string_array (our_string_array);
  
  if (dbus_message_iter_next (&iter))
    _dbus_assert_not_reached ("Didn't reach end of arguments");
}
Exemplo n.º 19
0
DBusHandlerResult dbus_dbusmenu_filter(DBusConnection *connection,DBusMessage * msg,void * /*data*/){
  //GMAppStatusNotify * p = reinterpret_cast<GMAppStatusNotify*>(data);

  DEBUG_DBUS_MESSAGE(msg);

  DBusMessage *   reply;
  DBusMessageIter iter;
  DBusMessageIter item;
  DBusMessageIter list;
  FXuint serial;

  if (dbus_message_has_path(msg,APPLICATION_STATUS_ITEM_MENU_PATH)){
    if (dbus_message_has_interface(msg,DBUS_INTERFACE_INTROSPECTABLE)) {
      if (dbus_message_is_method_call(msg,DBUS_INTERFACE_INTROSPECTABLE,"Introspect")){
        return gm_dbus_reply_string(connection,msg,dbusmenu_xml);
        }
      }
    else if (dbus_message_has_interface(msg,DBUS_INTERFACE_PROPERTIES)) {
      if (dbus_message_is_method_call(msg,DBUS_INTERFACE_PROPERTIES,"Get")){
        }
      else if (dbus_message_is_method_call(msg,DBUS_INTERFACE_PROPERTIES,"GetAll")){
        }
      else if (dbus_message_is_method_call(msg,DBUS_INTERFACE_PROPERTIES,"Set")){
        }
      }
    else if (dbus_message_has_interface(msg,DBUS_MENU_INTERFACE)) {
      if (dbus_message_is_method_call(msg,DBUS_MENU_INTERFACE,"GetLayout")){
        FXint parent,depth;
        FXchar ** properties=NULL;
        FXint nprops;
        if (dbus_message_get_args(msg,NULL,DBUS_TYPE_INT32,&parent,DBUS_TYPE_INT32,&depth,DBUS_TYPE_ARRAY,DBUS_TYPE_STRING,&properties,&nprops,DBUS_TYPE_INVALID)) {
          if ((reply=dbus_message_new_method_return(msg))!=NULL) {
            FXuint revision=1;

            dbus_message_iter_init_append(reply,&iter);

            dbus_message_iter_append_basic(&iter,DBUS_TYPE_UINT32,&revision);

            gm_begin_menu(&iter,&item,ID_ROOT,"Goggles Music Manager","gogglesmm");
              gm_begin_menu_item_list(&item,&list);
                if (depth==-1 || depth==1) {
                  gm_make_menu_item(&list,ID_PLAY,"Play","media-playback-start",GMPlayerManager::instance()->can_play());
                  gm_make_menu_item(&list,ID_PAUSE,"Pause","media-playback-pause",GMPlayerManager::instance()->can_pause());
                  gm_make_menu_item(&list,ID_STOP,"Stop","media-playback-stop",GMPlayerManager::instance()->can_stop());
                  gm_make_menu_item(&list,ID_PREVIOUS,"Previous Track","media-skip-backward",GMPlayerManager::instance()->can_prev());
                  gm_make_menu_item(&list,ID_NEXT,"Next Track","media-skip-forward",GMPlayerManager::instance()->can_next());
                  }
              gm_end_menu_item_list(&item,&list);
            gm_end_menu(&iter,&item);
            dbus_connection_send(connection,reply,&serial);
            dbus_message_unref(reply);
            }
          dbus_free_string_array(properties);
          }
        return DBUS_HANDLER_RESULT_HANDLED;
        }
      else if (dbus_message_is_method_call(msg,DBUS_MENU_INTERFACE,"AboutToShow")) {
        FXint event_id;
        if (dbus_message_get_args(msg,NULL,DBUS_TYPE_INT32,&event_id,DBUS_TYPE_INVALID)) {
          gm_dbus_reply_bool(connection,msg,false);
          }
        return DBUS_HANDLER_RESULT_HANDLED;
        }
      else if (dbus_message_is_method_call(msg,DBUS_MENU_INTERFACE,"Event")) {
        FXint event_id;
        const FXchar * event_type=NULL;
        if (dbus_message_get_args(msg,NULL,DBUS_TYPE_INT32,&event_id,DBUS_TYPE_STRING,&event_type,DBUS_TYPE_INVALID)) {
          if (compare(event_type,"clicked")==0) {
            switch(event_id) {
              case ID_PLAY    : GMPlayerManager::instance()->cmd_play(); break;
              case ID_PAUSE   : GMPlayerManager::instance()->cmd_pause(); break;
              case ID_STOP    : GMPlayerManager::instance()->cmd_stop(); break;
              case ID_NEXT    : GMPlayerManager::instance()->cmd_next(); break;
              case ID_PREVIOUS: GMPlayerManager::instance()->cmd_prev(); break;
              }
            }
          return DBUS_HANDLER_RESULT_HANDLED;
          }
        }
      }
    }
  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
  }