From 68a3c593b9e77b33614726363c7b6fd85d113021 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Mon, 18 Aug 2003 22:43:30 +0000 Subject: 2003-08-18 Havoc Pennington * dbus/dbus-hash.c (_dbus_hash_table_insert_two_strings): fix * dbus/dbus-message.c (_dbus_message_loader_queue_messages): fix dumb bug created earlier (wrong order of args to decode_header_data()) * tools/dbus-send.c: port * tools/dbus-print-message.c (print_message): port * test/data/*messages: port all messages over * dbus/dbus-message-builder.c: support including message type * bus/driver.c: port over * bus/dispatch.c: port over to new stuff * dbus/dbus-connection.c (_dbus_connection_new_for_transport): rename disconnect signal to "Disconnected" --- dbus/dbus-connection.c | 2 +- dbus/dbus-hash.c | 29 ++++++---- dbus/dbus-message-builder.c | 42 +++++++++++++- dbus/dbus-message.c | 130 +++++++++++++++++++++++++++++++++----------- dbus/dbus-message.h | 14 +++-- dbus/dbus-protocol.h | 14 ----- dbus/dbus-string.c | 9 +++ 7 files changed, 175 insertions(+), 65 deletions(-) (limited to 'dbus') diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 7be35b4c..45bbb42d 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -826,7 +826,7 @@ _dbus_connection_new_for_transport (DBusTransport *transport) goto error; disconnect_message = dbus_message_new_signal (DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL, - "Disconnect"); + "Disconnected"); if (disconnect_message == NULL) goto error; diff --git a/dbus/dbus-hash.c b/dbus/dbus-hash.c index f4547815..044dc534 100644 --- a/dbus/dbus-hash.c +++ b/dbus/dbus-hash.c @@ -1423,17 +1423,24 @@ _dbus_hash_table_insert_two_strings (DBusHashTable *table, char *key, void *value) { - DBusPreallocatedHash *preallocated; - + DBusHashEntry *entry; + _dbus_assert (table->key_type == DBUS_HASH_TWO_STRINGS); + + entry = (* table->find_function) (table, key, TRUE, NULL, NULL); - preallocated = _dbus_hash_table_preallocate_entry (table); - if (preallocated == NULL) - return FALSE; + if (entry == NULL) + return FALSE; /* no memory */ - _dbus_hash_table_insert_string_preallocated (table, preallocated, - key, value); + if (table->free_key_function && entry->key != key) + (* table->free_key_function) (entry->key); + + if (table->free_value_function && entry->value != value) + (* table->free_value_function) (entry->value); + entry->key = key; + entry->value = value; + return TRUE; } @@ -1811,8 +1818,8 @@ _dbus_hash_test (void) if (value == NULL) goto out; - if (!_dbus_hash_table_insert_string (table4, - key, value)) + if (!_dbus_hash_table_insert_two_strings (table4, + key, value)) goto out; _dbus_assert (count_entries (table1) == i + 1); @@ -1832,9 +1839,9 @@ _dbus_hash_test (void) _dbus_assert (value != NULL); _dbus_assert (strcmp (value, keys[i]) == 0); - value = _dbus_hash_table_lookup_ulong (table4, i); + value = _dbus_hash_table_lookup_two_strings (table4, keys[i]); _dbus_assert (value != NULL); - _dbus_assert (strcmp (value, keys[i]) == 0); + _dbus_assert (strcmp (value, "Value!") == 0); ++i; } diff --git a/dbus/dbus-message-builder.c b/dbus/dbus-message-builder.c index fc85fc32..958e57a0 100644 --- a/dbus/dbus-message-builder.c +++ b/dbus/dbus-message-builder.c @@ -265,6 +265,29 @@ append_saved_length (DBusString *dest, return TRUE; } +static int +message_type_from_string (const DBusString *str, + int start) +{ + const char *s; + + s = _dbus_string_get_const_data_len (str, start, + _dbus_string_get_length (str) - start); + + if (strncmp (s, "method_call", strlen ("method_call")) == 0) + return DBUS_MESSAGE_TYPE_METHOD_CALL; + else if (strncmp (s, "method_return", strlen ("method_return")) == 0) + return DBUS_MESSAGE_TYPE_METHOD_RETURN; + else if (strncmp (s, "signal", strlen ("signal")) == 0) + return DBUS_MESSAGE_TYPE_SIGNAL; + else if (strncmp (s, "error", strlen ("error")) == 0) + return DBUS_MESSAGE_TYPE_ERROR; + else if (strncmp (s, "invalid", strlen ("invalid")) == 0) + return DBUS_MESSAGE_TYPE_INVALID; + else + return -1; +} + /** * Reads the given filename, which should be in "message description * language" (look at some examples), and builds up the message data @@ -274,7 +297,7 @@ append_saved_length (DBusString *dest, * * The file format is: * @code - * VALID_HEADER normal header; byte order, padding, header len, body len, serial + * VALID_HEADER normal header; byte order, type, padding, header len, body len, serial * BIG_ENDIAN switch to big endian * LITTLE_ENDIAN switch to little endian * OPPOSITE_ENDIAN switch to opposite endian @@ -386,6 +409,13 @@ _dbus_message_data_load (DBusString *dest, { int i; DBusString name; + int message_type; + + if (_dbus_string_get_length (&line) < strlen ("VALID_HEADER ")) + { + _dbus_warn ("no args to VALID_HEADER\n"); + goto parse_failed; + } if (!_dbus_string_append_byte (dest, endian)) { @@ -393,7 +423,15 @@ _dbus_message_data_load (DBusString *dest, goto parse_failed; } - if (!_dbus_string_append_byte (dest, DBUS_MESSAGE_TYPE_METHOD_CALL)) + message_type = message_type_from_string (&line, + strlen ("VALID_HEADER ")); + if (message_type < 0) + { + _dbus_warn ("VALID_HEADER not followed by space then known message type\n"); + goto parse_failed; + } + + if (!_dbus_string_append_byte (dest, message_type)) { _dbus_warn ("could not append message type\n"); goto parse_failed; diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index e5bbcab1..c062c934 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -4049,55 +4049,115 @@ dbus_message_get_sender (DBusMessage *message) return get_string_field (message, FIELD_SENDER, NULL); } +static dbus_bool_t +_dbus_message_has_type_interface_member (DBusMessage *message, + int type, + const char *interface, + const char *method) +{ + const char *n; + + _dbus_assert (message != NULL); + _dbus_assert (interface != NULL); + _dbus_assert (method != NULL); + + if (dbus_message_get_type (message) != type) + return FALSE; + + /* Optimize by checking the short method name first + * instead of the longer interface name + */ + + n = dbus_message_get_member (message); + + if (n && strcmp (n, method) == 0) + { + n = dbus_message_get_interface (message); + + if (n && strcmp (n, interface) == 0) + return TRUE; + } + + return FALSE; +} + /** - * Checks whether the message has the given interface field. If the - * message has no interface field or has a different one, returns - * #FALSE. + * Checks whether the message is a method call with the given + * interface and member fields. If the message is not + * #DBUS_MESSAGE_TYPE_METHOD_CALL, or has a different interface or member field, + * returns #FALSE. * * @param message the message * @param interface the name to check (must not be #NULL) + * @param method the name to check (must not be #NULL) * - * @returns #TRUE if the message has the given name + * @returns #TRUE if the message is the specified method call */ dbus_bool_t -dbus_message_has_interface (DBusMessage *message, - const char *interface) +dbus_message_is_method_call (DBusMessage *message, + const char *interface, + const char *method) { - const char *n; - _dbus_return_val_if_fail (message != NULL, FALSE); _dbus_return_val_if_fail (interface != NULL, FALSE); - - n = dbus_message_get_interface (message); + _dbus_return_val_if_fail (method != NULL, FALSE); - if (n && strcmp (n, interface) == 0) - return TRUE; - else - return FALSE; + return _dbus_message_has_type_interface_member (message, + DBUS_MESSAGE_TYPE_METHOD_CALL, + interface, method); } +/** + * Checks whether the message is a signal with the given + * interface and member fields. If the message is not + * #DBUS_MESSAGE_TYPE_SIGNAL, or has a different interface or member field, + * returns #FALSE. + * + * @param message the message + * @param interface the name to check (must not be #NULL) + * @param signal_name the name to check (must not be #NULL) + * + * @returns #TRUE if the message is the specified signal + */ +dbus_bool_t +dbus_message_is_signal (DBusMessage *message, + const char *interface, + const char *signal_name) +{ + _dbus_return_val_if_fail (message != NULL, FALSE); + _dbus_return_val_if_fail (interface != NULL, FALSE); + _dbus_return_val_if_fail (signal_name != NULL, FALSE); + + return _dbus_message_has_type_interface_member (message, + DBUS_MESSAGE_TYPE_SIGNAL, + interface, signal_name); +} /** - * Checks whether the message has the given member field. If the - * message has no member field or has a different one, returns #FALSE. + * Checks whether the message is an error reply with the given error + * name. If the message is not #DBUS_MESSAGE_TYPE_ERROR, or has a + * different name, returns #FALSE. * * @param message the message - * @param member the name to check (must not be #NULL) + * @param error_name the name to check (must not be #NULL) * - * @returns #TRUE if the message has the given name + * @returns #TRUE if the message is the specified error */ dbus_bool_t -dbus_message_has_member (DBusMessage *message, - const char *member) +dbus_message_is_error (DBusMessage *message, + const char *error_name) { const char *n; - - _dbus_return_val_if_fail (message != NULL, FALSE); - _dbus_return_val_if_fail (member != NULL, FALSE); + _dbus_return_val_if_fail (message != NULL, FALSE); + _dbus_return_val_if_fail (error_name != NULL, FALSE); + + if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR) + return FALSE; + n = dbus_message_get_member (message); - if (n && strcmp (n, member) == 0) + if (n && strcmp (n, error_name) == 0) return TRUE; else return FALSE; @@ -4507,7 +4567,10 @@ decode_header_data (const DBusString *data, int type; if (header_len < 16) - return FALSE; + { + _dbus_verbose ("Header length %d is too short\n", header_len); + return FALSE; + } i = 0; while (i < FIELD_LAST) @@ -4532,7 +4595,10 @@ decode_header_data (const DBusString *data, pos = _DBUS_ALIGN_VALUE (pos, 4); if ((pos + 4) > header_len) - return FALSE; + { + _dbus_verbose ("not enough space remains in header for header field value\n"); + return FALSE; + } field =_dbus_string_get_const_data_len (data, pos, 4); pos += 4; @@ -4809,8 +4875,9 @@ _dbus_message_loader_queue_messages (DBusMessageLoader *loader) #if 0 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len + body_len); #endif - if (!decode_header_data (&loader->data, message_type, + if (!decode_header_data (&loader->data, header_len, byte_order, + message_type, fields, &header_padding)) { _dbus_verbose ("Header was invalid\n"); @@ -5919,10 +5986,11 @@ process_test_subdir (const DBusString *test_base_dir, printf (" %s\n", _dbus_string_get_const_data (&filename)); - _dbus_verbose (" expecting %s\n", + _dbus_verbose (" expecting %s for %s\n", validity == _DBUS_MESSAGE_VALID ? "valid" : (validity == _DBUS_MESSAGE_INVALID ? "invalid" : - (validity == _DBUS_MESSAGE_INCOMPLETE ? "incomplete" : "unknown"))); + (validity == _DBUS_MESSAGE_INCOMPLETE ? "incomplete" : "unknown")), + _dbus_string_get_const_data (&filename)); if (! (*function) (&full_path, is_raw, validity, user_data)) { @@ -6245,8 +6313,8 @@ _dbus_message_test (const char *test_data_dir) "TestMethod", "org.freedesktop.DBus.TestService"); _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService")); - _dbus_assert (dbus_message_has_interface (message, "Foo.TestInterface")); - _dbus_assert (dbus_message_has_member (message, "TestMethod")); + _dbus_assert (dbus_message_is_method_call (message, "Foo.TestInterface", + "TestMethod")); _dbus_message_set_serial (message, 1234); dbus_message_set_sender (message, "org.foo.bar"); _dbus_assert (dbus_message_has_sender (message, "org.foo.bar")); diff --git a/dbus/dbus-message.h b/dbus/dbus-message.h index dc204585..526cf971 100644 --- a/dbus/dbus-message.h +++ b/dbus/dbus-message.h @@ -91,12 +91,14 @@ const char* dbus_message_get_sender (DBusMessage *message); void dbus_message_set_no_reply (DBusMessage *message, dbus_bool_t no_reply); dbus_bool_t dbus_message_get_no_reply (DBusMessage *message); -dbus_bool_t dbus_message_has_interface (DBusMessage *message, - const char *interface); -dbus_bool_t dbus_message_has_member (DBusMessage *message, - const char *member); -dbus_bool_t dbus_message_has_error_name (DBusMessage *message, - const char *name); +dbus_bool_t dbus_message_is_method_call (DBusMessage *message, + const char *interface, + const char *method); +dbus_bool_t dbus_message_is_signal (DBusMessage *message, + const char *interface, + const char *signal_name); +dbus_bool_t dbus_message_is_error (DBusMessage *message, + const char *error_name); dbus_bool_t dbus_message_has_destination (DBusMessage *message, const char *service); dbus_bool_t dbus_message_has_sender (DBusMessage *message, diff --git a/dbus/dbus-protocol.h b/dbus/dbus-protocol.h index a1f4a722..21c06a76 100644 --- a/dbus/dbus-protocol.h +++ b/dbus/dbus-protocol.h @@ -106,20 +106,6 @@ extern "C" { * allowed to specify this interface). */ #define DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL "org.freedesktop.Local" - -#if 0 - /* these are a bad idea, FIXME */ -#define DBUS_METHOD_ORG_FREEDESKTOP_DBUS_ACTIVATE_SERVICE "ActivateService" -#define DBUS_METHOD_ORG_FREEDESKTOP_DBUS_SERVICE_EXISTS "ServiceExists" -#define DBUS_METHOD_ORG_FREEDESKTOP_DBUS_HELLO "Hello" -#define DBUS_METHOD_ORG_FREEDESKTOP_DBUS_LIST_SERVICES "ListServices" -#define DBUS_METHOD_ORG_FREEDESKTOP_DBUS_ACQUIRE_SERVICE "AcquireService" - -#define DBUS_SIGNAL_ORG_FREEDESKTOP_DBUS_SERVICE_ACQUIRED "ServiceAcquired" -#define DBUS_SIGNAL_ORG_FREEDESKTOP_DBUS_SERVICE_CREATED "ServiceCreated" -#define DBUS_SIGNAL_ORG_FREEDESKTOP_DBUS_SERVICE_DELETED "ServiceDeleted" -#define DBUS_SIGNAL_ORG_FREEDESKTOP_DBUS_SERVICE_LOST "ServiceLost" -#endif /* #if 0 */ #ifdef __cplusplus } diff --git a/dbus/dbus-string.c b/dbus/dbus-string.c index 848135fc..98b4c60e 100644 --- a/dbus/dbus-string.c +++ b/dbus/dbus-string.c @@ -2853,6 +2853,9 @@ _dbus_string_validate_nul (const DBusString *str, * * @todo this is inconsistent with most of DBusString in that * it allows a start,len range that isn't in the string. + * + * @todo change spec to disallow more things, such as spaces in the + * interface name * * @param str the string * @param start first byte index to check @@ -2911,6 +2914,9 @@ _dbus_string_validate_interface (const DBusString *str, * @todo this is inconsistent with most of DBusString in that * it allows a start,len range that isn't in the string. * + * @todo change spec to disallow more things, such as spaces in the + * member name + * * @param str the string * @param start first byte index to check * @param len number of bytes to check @@ -2991,6 +2997,9 @@ _dbus_string_validate_error_name (const DBusString *str, * * @todo this is inconsistent with most of DBusString in that * it allows a start,len range that isn't in the string. + * + * @todo change spec to disallow more things, such as spaces in the + * service name * * @param str the string * @param start first byte index to check -- cgit