示例#1
0
/*
 * Open a new entry in an a{sv} (map from string to variant).
 *
 * This must be paired with a call to either _dbus_asv_close_entry()
 * or _dbus_asv_abandon_entry().
 *
 * If this function fails, the a{sv} must be abandoned, for instance
 * with _dbus_asv_abandon().
 *
 * @param arr_iter the iterator which is appending to the array
 * @param entry_iter will be initialized to append to the dict-entry
 * @param key a UTF-8 key for the map
 * @param type the type of the variant value, e.g. DBUS_TYPE_STRING_AS_STRING
 * @param var_iter will be initialized to append (i.e. write) to the variant
 * @returns #TRUE on success, or #FALSE if not enough memory
 */
static dbus_bool_t
_dbus_asv_open_entry (DBusMessageIter *arr_iter,
                      DBusMessageIter *entry_iter,
                      const char      *key,
                      const char      *type,
                      DBusMessageIter *var_iter)
{
  if (!dbus_message_iter_open_container (arr_iter, DBUS_TYPE_DICT_ENTRY,
                                         NULL, entry_iter))
    return FALSE;

  if (!dbus_message_iter_append_basic (entry_iter, DBUS_TYPE_STRING, &key))
    {
      dbus_message_iter_abandon_container (arr_iter, entry_iter);
      return FALSE;
    }

  if (!dbus_message_iter_open_container (entry_iter, DBUS_TYPE_VARIANT,
                                         type, var_iter))
    {
      dbus_message_iter_abandon_container (arr_iter, entry_iter);
      return FALSE;
    }

  return TRUE;
}
示例#2
0
/*
 * Closes an a{sv} entry after unsuccessfully appending a value.
 * You must also abandon the a{sv} itself (for instance with
 * _dbus_asv_abandon()), and abandon whatever larger data structure
 * the a{sv} was embedded in.
 *
 * @param iter the iterator which is appending to the message or other data structure containing the a{sv}
 * @param arr_iter the iterator appending to the array, will be closed
 * @returns #TRUE on success, or #FALSE if not enough memory
 */
static void
_dbus_asv_abandon_entry (DBusMessageIter *arr_iter,
                         DBusMessageIter *entry_iter,
                         DBusMessageIter *var_iter)
{
  dbus_message_iter_abandon_container (entry_iter, var_iter);
  dbus_message_iter_abandon_container (arr_iter, entry_iter);
}
示例#3
0
/**
 * PropertiesChangedSignal() synthetizes and sends the
 * org.freedesktop.DBus.Properties.PropertiesChanged signal
 */
static DBusHandlerResult
PropertiesChangedSignal( intf_thread_t    *p_intf,
                         vlc_dictionary_t *p_changed_properties )
{
    DBusConnection  *p_conn = p_intf->p_sys->p_conn;
    DBusMessageIter changed_properties, invalidated_properties;
    const char *psz_interface_name = DBUS_MPRIS_PLAYER_INTERFACE;
    char **ppsz_properties = NULL;

    SIGNAL_INIT( DBUS_INTERFACE_PROPERTIES,
                 DBUS_MPRIS_OBJECT_PATH,
                 "PropertiesChanged" );

    OUT_ARGUMENTS;
    ADD_STRING( &psz_interface_name );

    if( !dbus_message_iter_open_container( &args, DBUS_TYPE_ARRAY, "{sv}",
                                           &changed_properties ) )
        return DBUS_HANDLER_RESULT_NEED_MEMORY;

    ppsz_properties = vlc_dictionary_all_keys( p_changed_properties );

    if( unlikely(!ppsz_properties) )
    {
        dbus_message_iter_abandon_container( &args, &changed_properties );
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
    }

    for( int i = 0; ppsz_properties[i]; i++ )
    {
        PROPERTY_MAPPING_BEGIN
        PROPERTY_ENTRY( Metadata,       "a{sv}" )
        PROPERTY_ENTRY( PlaybackStatus, "s"     )
        PROPERTY_ENTRY( LoopStatus,     "s"     )
        PROPERTY_ENTRY( Rate,           "d"     )
        PROPERTY_ENTRY( Shuffle,        "b"     )
        PROPERTY_ENTRY( Volume,         "d"     )
        PROPERTY_ENTRY( CanSeek,        "b"     )
        PROPERTY_ENTRY( CanPlay,        "b"     )
        PROPERTY_ENTRY( CanPause,       "b"     )
        PROPERTY_MAPPING_END

        free( ppsz_properties[i] );
    }

    free( ppsz_properties );

    if( !dbus_message_iter_close_container( &args, &changed_properties ) )
        return DBUS_HANDLER_RESULT_NEED_MEMORY;

    if( !dbus_message_iter_open_container( &args, DBUS_TYPE_ARRAY, "s",
                                           &invalidated_properties ) )
        return DBUS_HANDLER_RESULT_NEED_MEMORY;

    if( !dbus_message_iter_close_container( &args, &invalidated_properties ) )
        return DBUS_HANDLER_RESULT_NEED_MEMORY;

    SIGNAL_SEND;
}
示例#4
0
/**
 * PropertiesChangedSignal: synthetizes and sends the
 * org.freedesktop.DBus.Properties.PropertiesChanged signal
 */
static DBusHandlerResult
PropertiesChangedSignal( intf_thread_t    *p_intf,
                         vlc_dictionary_t *p_changed_properties )
{
    DBusConnection  *p_conn = p_intf->p_sys->p_conn;
    DBusMessageIter changed_properties, invalidated_properties;
    const char *psz_interface_name = DBUS_MPRIS_TRACKLIST_INTERFACE;
    char **ppsz_properties = NULL;
    int i_properties = 0;

    SIGNAL_INIT( DBUS_INTERFACE_PROPERTIES,
                 DBUS_MPRIS_OBJECT_PATH,
                 "PropertiesChanged" );

    OUT_ARGUMENTS;
    ADD_STRING( &psz_interface_name );

    if( unlikely(!dbus_message_iter_open_container( &args,
                                                    DBUS_TYPE_ARRAY, "{sv}",
                                                    &changed_properties )) )
        return DBUS_HANDLER_RESULT_NEED_MEMORY;

    if( unlikely(!dbus_message_iter_close_container( &args,
                                                     &changed_properties )) )
        return DBUS_HANDLER_RESULT_NEED_MEMORY;

    if( unlikely(!dbus_message_iter_open_container( &args, DBUS_TYPE_ARRAY, "s",
                                                    &invalidated_properties )) )
        return DBUS_HANDLER_RESULT_NEED_MEMORY;

    i_properties    = vlc_dictionary_keys_count( p_changed_properties );
    ppsz_properties = vlc_dictionary_all_keys( p_changed_properties );

    if( unlikely(!ppsz_properties) )
    {
        dbus_message_iter_abandon_container( &args, &invalidated_properties );
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
    }

    for( int i = 0; i < i_properties; i++ )
    {
        if( !strcmp( ppsz_properties[i], "Tracks" ) )
            dbus_message_iter_append_basic( &invalidated_properties,
                                            DBUS_TYPE_STRING,
                                            &ppsz_properties[i] );

        free( ppsz_properties[i] );
    }

    free( ppsz_properties );

    if( unlikely(!dbus_message_iter_close_container( &args,
                    &invalidated_properties )) )
        return DBUS_HANDLER_RESULT_NEED_MEMORY;

    SIGNAL_SEND;
}
示例#5
0
/*
 * Closes an a{sv} entry after successfully appending the value.
 *
 * If this function fails, the a{sv} must be abandoned, for instance
 * with _dbus_asv_abandon().
 *
 * @param arr_iter the iterator which is appending to the array
 * @param entry_iter the iterator appending to the dict-entry, will be closed
 * @param var_iter the iterator appending to the variant, will be closed
 * @returns #TRUE on success, or #FALSE if not enough memory
 */
static dbus_bool_t
_dbus_asv_close_entry (DBusMessageIter *arr_iter,
                       DBusMessageIter *entry_iter,
                       DBusMessageIter *var_iter)
{
  if (!dbus_message_iter_close_container (entry_iter, var_iter))
    {
      dbus_message_iter_abandon_container (arr_iter, entry_iter);
      return FALSE;
    }

  if (!dbus_message_iter_close_container (arr_iter, entry_iter))
    return FALSE;

  return TRUE;
}
示例#6
0
文件: dbus_root.c 项目: mstorsjo/vlc
/**
 * PropertiesChangedSignal() synthetizes and sends the
 * org.freedesktop.DBus.Properties.PropertiesChanged signal
 */
static DBusHandlerResult
PropertiesChangedSignal( intf_thread_t    *p_intf,
                         vlc_dictionary_t *p_changed_properties )
{
    DBusConnection  *p_conn = p_intf->p_sys->p_conn;
    DBusMessageIter changed_properties, invalidated_properties;
    const char *psz_interface_name = DBUS_MPRIS_ROOT_INTERFACE;

    SIGNAL_INIT( DBUS_INTERFACE_PROPERTIES,
                 DBUS_MPRIS_OBJECT_PATH,
                 "PropertiesChanged" );

    OUT_ARGUMENTS;
    ADD_STRING( &psz_interface_name );

    if( !dbus_message_iter_open_container( &args, DBUS_TYPE_ARRAY, "{sv}",
                                           &changed_properties ) )
        return DBUS_HANDLER_RESULT_NEED_MEMORY;

    if( vlc_dictionary_has_key( p_changed_properties, "Fullscreen" ) )
    {
        if( AddProperty( p_intf, &changed_properties, "Fullscreen", "b",
                     MarshalFullscreen ) != VLC_SUCCESS )
        {
            dbus_message_iter_abandon_container( &args, &changed_properties );
            return DBUS_HANDLER_RESULT_NEED_MEMORY;
        }
    }

    if( !dbus_message_iter_close_container( &args, &changed_properties ) )
        return DBUS_HANDLER_RESULT_NEED_MEMORY;

    if( !dbus_message_iter_open_container( &args, DBUS_TYPE_ARRAY, "s",
                                           &invalidated_properties ) )
        return DBUS_HANDLER_RESULT_NEED_MEMORY;

    if( !dbus_message_iter_close_container( &args, &invalidated_properties ) )
        return DBUS_HANDLER_RESULT_NEED_MEMORY;

    SIGNAL_SEND;
}
示例#7
0
static int
MarshalTracks( intf_thread_t *p_intf, DBusMessageIter *container )
{
    DBusMessageIter tracks;
    char         *psz_track_id = NULL;
    playlist_t   *p_playlist   = p_intf->p_sys->p_playlist;
    input_item_t *p_input      = NULL;

    dbus_message_iter_open_container( container, DBUS_TYPE_ARRAY, "o",
                                      &tracks );

    PL_LOCK;

    for( int i = 0; i < playlist_CurrentSize( p_playlist ); i++ )
    {
        p_input = p_playlist->current.p_elems[i]->p_input;

        if( ( -1 == asprintf( &psz_track_id,
                              MPRIS_TRACKID_FORMAT,
                              p_input->i_id ) ) ||
            !dbus_message_iter_append_basic( &tracks,
                                             DBUS_TYPE_OBJECT_PATH,
                                             &psz_track_id ) )
        {
            PL_UNLOCK;
            dbus_message_iter_abandon_container( container, &tracks );
            return VLC_ENOMEM;
        }

        free( psz_track_id );
    }

    PL_UNLOCK;

    if( !dbus_message_iter_close_container( container, &tracks ) )
        return VLC_ENOMEM;

    return VLC_SUCCESS;
}
static int
my_com_netsplit_Nih_Test_size_get (NihDBusObject *  object,
                                   NihDBusMessage * message,
                                   DBusMessageIter *iter)
{
	DBusMessageIter variter;
	uint32_t        value;

	nih_assert (object != NULL);
	nih_assert (message != NULL);
	nih_assert (iter != NULL);

	/* Call the handler function */
	if (my_test_get_size (object->data, message, &value) < 0)
		return -1;

	/* Append a variant onto the message to contain the property value. */
	if (! dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "u", &variter)) {
		nih_error_raise_no_memory ();
		return -1;
	}

	/* Marshal a uint32_t onto the message */
	if (! dbus_message_iter_append_basic (&variter, DBUS_TYPE_UINT32, &value)) {
		dbus_message_iter_abandon_container (iter, &variter);
		nih_error_raise_no_memory ();
		return -1;
	}

	/* Finish the variant */
	if (! dbus_message_iter_close_container (iter, &variter)) {
		nih_error_raise_no_memory ();
		return -1;
	}

	return 0;
}
/**
 * @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;

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

  /* 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();

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

  return dbus_internal_do_not_use_foreach_message_file (test_data_dir,
                                                        (DBusForeachMessageFileFunc)
                                                        dbus_internal_do_not_use_try_message_file,
                                                        NULL);  
}
int
my_method_sync (const void *   parent,
                NihDBusProxy * proxy,
                const int32_t *value,
                size_t         value_len)
{
	DBusMessage *   method_call;
	DBusMessageIter iter;
	DBusError       error;
	DBusMessage *   reply;
	DBusMessageIter value_iter;

	nih_assert (proxy != NULL);
	nih_assert ((value_len == 0) || (value != NULL));

	/* Construct the method call message. */
	method_call = dbus_message_new_method_call (proxy->name, proxy->path, "com.netsplit.Nih.Test", "Method");
	if (! method_call)
		nih_return_no_memory_error (-1);

	dbus_message_set_auto_start (method_call, proxy->auto_start);

	dbus_message_iter_init_append (method_call, &iter);

	/* Marshal an array onto the message */
	if (! dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "i", &value_iter)) {
		dbus_message_unref (method_call);
		nih_return_no_memory_error (-1);
	}

	for (size_t value_i = 0; value_i < value_len; value_i++) {
		int32_t value_element;

		value_element = value[value_i];

		/* Marshal a int32_t onto the message */
		if (! dbus_message_iter_append_basic (&value_iter, DBUS_TYPE_INT32, &value_element)) {
			dbus_message_iter_abandon_container (&iter, &value_iter);
			dbus_message_unref (method_call);
			nih_return_no_memory_error (-1);
		}
	}

	if (! dbus_message_iter_close_container (&iter, &value_iter)) {
		dbus_message_unref (method_call);
		nih_return_no_memory_error (-1);
	}

	/* Send the message, and wait for the reply. */
	dbus_error_init (&error);

	reply = dbus_connection_send_with_reply_and_block (proxy->connection, method_call, -1, &error);
	if (! reply) {
		dbus_message_unref (method_call);

		if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) {
			nih_error_raise_no_memory ();
		} else {
			nih_dbus_error_raise (error.name, error.message);
		}

		dbus_error_free (&error);
		return -1;
	}

	dbus_message_unref (method_call);

	/* Iterate the arguments of the reply */
	dbus_message_iter_init (reply, &iter);

	if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INVALID) {
		dbus_message_unref (reply);
		nih_return_error (-1, NIH_DBUS_INVALID_ARGS,
		                  _(NIH_DBUS_INVALID_ARGS_STR));
	}

	dbus_message_unref (reply);

	return 0;
}
示例#11
0
/**
 * Closes an a{sv} after unsuccessfully appending a value.
 *
 * You must also abandon whatever larger data structure (message, etc.)
 * the a{sv} was embedded in.
 *
 * @param iter the iterator which is appending to the message or other data structure containing the a{sv}
 * @param arr_iter the iterator appending to the array, will be closed
 */
void
_dbus_asv_abandon (DBusMessageIter *iter,
                   DBusMessageIter *arr_iter)
{
  dbus_message_iter_abandon_container (iter, arr_iter);
}
示例#12
0
文件: mce-dbus.c 项目: Vesuri/mce
/** Helper for appending GConfValue to dbus message
 *
 * @param reply DBusMessage under construction
 * @param conf GConfValue to be added to the reply
 *
 * @return TRUE if the value was succesfully appended, or FALSE on failure
 */
static gboolean append_gconf_value_to_dbus_message(DBusMessage *reply, GConfValue *conf)
{
	const char *sig = 0;

	DBusMessageIter body, variant, array;

	if( !(sig = value_signature(conf)) ) {
		goto bailout_message;
	}

	dbus_message_iter_init_append(reply, &body);

	if( !dbus_message_iter_open_container(&body, DBUS_TYPE_VARIANT,
					      sig, &variant) ) {
		goto bailout_message;
	}

	switch( conf->type ) {
	case GCONF_VALUE_STRING:
		{
			const char *arg = gconf_value_get_string(conf) ?: "";
			dbus_message_iter_append_basic(&variant,
						       DBUS_TYPE_STRING,
						       &arg);
		}
		break;

	case GCONF_VALUE_INT:
		{
			dbus_int32_t arg = gconf_value_get_int(conf);
			dbus_message_iter_append_basic(&variant,
						       DBUS_TYPE_INT32,
						       &arg);
		}
		break;

	case GCONF_VALUE_FLOAT:
		{
			double arg = gconf_value_get_float(conf);
			dbus_message_iter_append_basic(&variant,
						       DBUS_TYPE_DOUBLE,
						       &arg);
		}
		break;

	case GCONF_VALUE_BOOL:
		{
			dbus_bool_t arg = gconf_value_get_bool(conf);
			dbus_message_iter_append_basic(&variant,
						       DBUS_TYPE_BOOLEAN,
						       &arg);
		}
		break;

	case GCONF_VALUE_LIST:
		if( !(sig = type_signature(gconf_value_get_list_type(conf))) ) {
			goto bailout_variant;
		}

		if( !dbus_message_iter_open_container(&variant,
						      DBUS_TYPE_ARRAY,
						      sig, &array) ) {
			goto bailout_variant;
		}

		switch( gconf_value_get_list_type(conf) ) {
		case GCONF_VALUE_STRING:
			{
				int          cnt = 0;
				const char **arg = string_array_from_gconf_value(conf, &cnt);
				for( int i = 0; i < cnt; ++i ) {
					const char *str = arg[i];
					dbus_message_iter_append_basic(&array,
								       DBUS_TYPE_STRING,
								       &str);
				}
				g_free(arg);
			}
			break;
		case GCONF_VALUE_INT:
			{
				int           cnt = 0;
				dbus_int32_t *arg = int_array_from_gconf_value(conf, &cnt);
				dbus_message_iter_append_fixed_array(&array,
								     DBUS_TYPE_INT32,
								     &arg, cnt);
				g_free(arg);
			}
			break;
		case GCONF_VALUE_FLOAT:
			{
				int     cnt = 0;
				double *arg = float_array_from_gconf_value(conf, &cnt);
				dbus_message_iter_append_fixed_array(&array,
								     DBUS_TYPE_DOUBLE,
								     &arg, cnt);
				g_free(arg);
			}
			break;
		case GCONF_VALUE_BOOL:
			{
				int          cnt = 0;
				dbus_bool_t *arg = bool_array_from_gconf_value(conf, &cnt);
				dbus_message_iter_append_fixed_array(&array,
								     DBUS_TYPE_BOOLEAN,
								     &arg, cnt);
				g_free(arg);
			}
			break;

		default:
			goto bailout_array;
		}

		if( !dbus_message_iter_close_container(&variant, &array) ) {
			goto bailout_variant;
		}
		break;

	default:
		goto bailout_variant;
	}

	if( !dbus_message_iter_close_container(&body, &variant) ) {
		goto bailout_message;
	}
	return TRUE;

bailout_array:
	dbus_message_iter_abandon_container(&variant, &array);

bailout_variant:
	dbus_message_iter_abandon_container(&body, &variant);

bailout_message:
	return FALSE;
}
DBusHandlerResult
my_com_netsplit_Nih_Test_Method_method (NihDBusObject * object,
                                        NihDBusMessage *message)
{
	DBusMessageIter    iter;
	DBusMessage *      reply;
	MyMethodStructure *structure;
	DBusMessageIter    structure_iter;
	const char *       structure_item0;
	uint32_t           structure_item1;

	nih_assert (object != NULL);
	nih_assert (message != NULL);

	/* Iterate the arguments to the message and demarshal into arguments
	 * for our own function call.
	 */
	dbus_message_iter_init (message->message, &iter);

	if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INVALID) {
		reply = dbus_message_new_error (message->message, DBUS_ERROR_INVALID_ARGS,
		                                "Invalid arguments to Method method");
		if (! reply)
			return DBUS_HANDLER_RESULT_NEED_MEMORY;

		if (! dbus_connection_send (message->connection, reply, NULL)) {
			dbus_message_unref (reply);
			return DBUS_HANDLER_RESULT_NEED_MEMORY;
		}

		dbus_message_unref (reply);
		return DBUS_HANDLER_RESULT_HANDLED;
	}

	/* Call the handler function */
	nih_error_push_context ();
	if (my_method (object->data, message, &structure) < 0) {
		NihError *err;

		err = nih_error_get ();
		if (err->number == ENOMEM) {
			nih_free (err);
			nih_error_pop_context ();

			return DBUS_HANDLER_RESULT_NEED_MEMORY;
		} else if (err->number == NIH_DBUS_ERROR) {
			NihDBusError *dbus_err = (NihDBusError *)err;

			reply = NIH_MUST (dbus_message_new_error (message->message, dbus_err->name, err->message));
			nih_free (err);
			nih_error_pop_context ();

			NIH_MUST (dbus_connection_send (message->connection, reply, NULL));

			dbus_message_unref (reply);
			return DBUS_HANDLER_RESULT_HANDLED;
		} else {
			reply = NIH_MUST (dbus_message_new_error (message->message, DBUS_ERROR_FAILED, err->message));
			nih_free (err);
			nih_error_pop_context ();

			NIH_MUST (dbus_connection_send (message->connection, reply, NULL));

			dbus_message_unref (reply);
			return DBUS_HANDLER_RESULT_HANDLED;
		}
	}
	nih_error_pop_context ();

	/* If the sender doesn't care about a reply, don't bother wasting
	 * effort constructing and sending one.
	 */
	if (dbus_message_get_no_reply (message->message))
		return DBUS_HANDLER_RESULT_HANDLED;

	do {
		__label__ enomem;

		/* Construct the reply message. */
		reply = dbus_message_new_method_return (message->message);
		if (! reply)
			goto enomem;

		dbus_message_iter_init_append (reply, &iter);

		/* Marshal a structure onto the message */
		if (! dbus_message_iter_open_container (&iter, DBUS_TYPE_STRUCT, NULL, &structure_iter)) {
			dbus_message_unref (reply);
			reply = NULL;
			goto enomem;
		}

		structure_item0 = structure->item0;

		/* Marshal a char * onto the message */
		if (! dbus_message_iter_append_basic (&structure_iter, DBUS_TYPE_STRING, &structure_item0)) {
			dbus_message_iter_abandon_container (&iter, &structure_iter);
			dbus_message_unref (reply);
			reply = NULL;
			goto enomem;
		}

		structure_item1 = structure->item1;

		/* Marshal a uint32_t onto the message */
		if (! dbus_message_iter_append_basic (&structure_iter, DBUS_TYPE_UINT32, &structure_item1)) {
			dbus_message_iter_abandon_container (&iter, &structure_iter);
			dbus_message_unref (reply);
			reply = NULL;
			goto enomem;
		}

		if (! dbus_message_iter_close_container (&iter, &structure_iter)) {
			dbus_message_unref (reply);
			reply = NULL;
			goto enomem;
		}
	enomem: __attribute__ ((unused));
	} while (! reply);

	/* Send the reply, appending it to the outgoing queue. */
	NIH_MUST (dbus_connection_send (message->connection, reply, NULL));

	dbus_message_unref (reply);

	return DBUS_HANDLER_RESULT_HANDLED;
}