summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2003-08-18 15:27:33 +0000
committerHavoc Pennington <hp@redhat.com>2003-08-18 15:27:33 +0000
commit95717a938b237d12211935f6a7467ef610288fe5 (patch)
tree9182521c86f31e74ad642eb19b431a433859c85f
parent7c3693a53b4eba0db1aebe1edab5ded21eb7757f (diff)
downloaddbus-95717a938b237d12211935f6a7467ef610288fe5.tar.gz
2003-08-17 Havoc Pennington <hp@pobox.com>
This doesn't compile yet, but syncing up so I can hack on it from work. What are branches for if not broken code? ;-) * dbus/dbus-protocol.h: remove DBUS_HEADER_FIELD_NAME, add DBUS_HEADER_FIELD_INTERFACE, DBUS_HEADER_FIELD_MEMBER, DBUS_HEADER_FIELD_ERROR_NAME * dbus/dbus-hash.c: Introduce DBUS_HASH_TWO_STRINGS as hack to use for the interface+member pairs (string_hash): change to use g_str_hash algorithm (find_direct_function, find_string_function): refactor these to share most code. * dbus/dbus-message.c: port all of this over to support interface/member fields instead of name field * dbus/dbus-object-registry.c: port over * dbus/dbus-string.c (_dbus_string_validate_interface): rename from _dbus_string_validate_name * bus/dbus-daemon-1.1: change file format for the <deny>/<allow> stuff to match new message naming scheme * bus/policy.c: port over * bus/config-parser.c: parse new format
-rw-r--r--ChangeLog30
-rw-r--r--bus/bus.c33
-rw-r--r--bus/config-parser.c188
-rw-r--r--bus/connection.c26
-rw-r--r--bus/dispatch.c47
-rw-r--r--bus/policy.c76
-rw-r--r--bus/policy.h12
-rw-r--r--dbus/dbus-bus.c25
-rw-r--r--dbus/dbus-connection.c54
-rw-r--r--dbus/dbus-hash.c378
-rw-r--r--dbus/dbus-hash.h115
-rw-r--r--dbus/dbus-message.c386
-rw-r--r--dbus/dbus-message.h22
-rw-r--r--dbus/dbus-object-registry.c89
-rw-r--r--dbus/dbus-object-registry.h6
-rw-r--r--dbus/dbus-protocol.h55
-rw-r--r--dbus/dbus-string.c88
-rw-r--r--dbus/dbus-string.h8
18 files changed, 1224 insertions, 414 deletions
diff --git a/ChangeLog b/ChangeLog
index b2f71f14..e22c0de0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+2003-08-17 Havoc Pennington <hp@pobox.com>
+
+ This doesn't compile yet, but syncing up so I can hack on it from
+ work. What are branches for if not broken code? ;-)
+
+ * dbus/dbus-protocol.h: remove DBUS_HEADER_FIELD_NAME, add
+ DBUS_HEADER_FIELD_INTERFACE, DBUS_HEADER_FIELD_MEMBER,
+ DBUS_HEADER_FIELD_ERROR_NAME
+
+ * dbus/dbus-hash.c: Introduce DBUS_HASH_TWO_STRINGS as hack to use
+ for the interface+member pairs
+ (string_hash): change to use g_str_hash algorithm
+ (find_direct_function, find_string_function): refactor these to
+ share most code.
+
+ * dbus/dbus-message.c: port all of this over to support
+ interface/member fields instead of name field
+
+ * dbus/dbus-object-registry.c: port over
+
+ * dbus/dbus-string.c (_dbus_string_validate_interface): rename
+ from _dbus_string_validate_name
+
+ * bus/dbus-daemon-1.1: change file format for the
+ <deny>/<allow> stuff to match new message naming scheme
+
+ * bus/policy.c: port over
+
+ * bus/config-parser.c: parse new format
+
2003-08-16 Havoc Pennington <hp@pobox.com>
* dbus/dbus-object-registry.c (add_and_remove_objects): remove
diff --git a/bus/bus.c b/bus/bus.c
index a5530974..58a10967 100644
--- a/bus/bus.c
+++ b/bus/bus.c
@@ -870,20 +870,21 @@ bus_context_check_security_policy (BusContext *context,
* the hello message to the bus driver
*/
if (recipient == NULL &&
- dbus_message_has_name (message, DBUS_MESSAGE_HELLO))
+ dbus_message_has_interface (message, DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS) &&
+ dbus_message_has_member (message, "Hello"))
{
_dbus_verbose ("security check allowing %s message\n",
- DBUS_MESSAGE_HELLO);
+ "Hello");
return TRUE;
}
else
{
_dbus_verbose ("security check disallowing non-%s message\n",
- DBUS_MESSAGE_HELLO);
+ "Hello");
dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
"Client tried to send a message other than %s without being registered",
- DBUS_MESSAGE_HELLO);
+ "Hello");
return FALSE;
}
@@ -934,9 +935,14 @@ bus_context_check_security_policy (BusContext *context,
"A security policy in place prevents this sender "
"from sending this message to this recipient, "
"see message bus configuration file (rejected message "
- "had name \"%s\" destination \"%s\")",
- dbus_message_get_name (message),
- dest ? dest : DBUS_SERVICE_DBUS);
+ "had interface \"%s\" member \"%s\" error name \"%s\" destination \"%s\")",
+ dbus_message_get_interface (message) ?
+ dbus_message_get_interface (message) : "(unset)",
+ dbus_message_get_member (message) ?
+ dbus_message_get_member (message) : "(unset)",
+ dbus_message_get_error_name (message) ?
+ dbus_message_get_error_name (message) : "(unset)",
+ dest ? dest : DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
_dbus_verbose ("security policy disallowing message due to sender policy\n");
return FALSE;
}
@@ -951,9 +957,14 @@ bus_context_check_security_policy (BusContext *context,
"A security policy in place prevents this recipient "
"from receiving this message from this sender, "
"see message bus configuration file (rejected message "
- "had name \"%s\" destination \"%s\")",
- dbus_message_get_name (message),
- dest ? dest : DBUS_SERVICE_DBUS);
+ "had interface \"%s\" member \"%s\" error name \"%s\" destination \"%s\")",
+ dbus_message_get_interface (message) ?
+ dbus_message_get_interface (message) : "(unset)",
+ dbus_message_get_member (message) ?
+ dbus_message_get_member (message) : "(unset)",
+ dbus_message_get_error_name (message) ?
+ dbus_message_get_error_name (message) : "(unset)",
+ dest ? dest : DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
_dbus_verbose ("security policy disallowing message due to recipient policy\n");
return FALSE;
}
@@ -966,7 +977,7 @@ bus_context_check_security_policy (BusContext *context,
const char *dest = dbus_message_get_destination (message);
dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
"The destination service \"%s\" has a full message queue",
- dest ? dest : DBUS_SERVICE_DBUS);
+ dest ? dest : DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
_dbus_verbose ("security policy disallowing message due to full message queue\n");
return FALSE;
}
diff --git a/bus/config-parser.c b/bus/config-parser.c
index c42278e1..471c67d8 100644
--- a/bus/config-parser.c
+++ b/bus/config-parser.c
@@ -816,11 +816,15 @@ append_rule_from_element (BusConfigParser *parser,
dbus_bool_t allow,
DBusError *error)
{
- const char *send;
- const char *receive;
+ const char *send_interface;
+ const char *send_member;
+ const char *send_error;
+ const char *send_service;
+ const char *receive_interface;
+ const char *receive_member;
+ const char *receive_error;
+ const char *receive_service;
const char *own;
- const char *send_to;
- const char *receive_from;
const char *user;
const char *group;
BusPolicyRule *rule;
@@ -829,57 +833,112 @@ append_rule_from_element (BusConfigParser *parser,
attribute_names,
attribute_values,
error,
- "send", &send,
- "receive", &receive,
+ "send_interface", &send_interface,
+ "send_member", &send_member,
+ "send_error", &send_error,
+ "send_service", &send_service,
+ "receive_interface", &receive_interface,
+ "receive_member", &receive_member,
+ "receive_error", &receive_error,
+ "receive_service", &receive_service,
"own", &own,
- "send_to", &send_to,
- "receive_from", &receive_from,
"user", &user,
"group", &group,
NULL))
return FALSE;
- if (!(send || receive || own || send_to || receive_from ||
- user || group))
+ if (!(send_interface || send_member || send_error || send_service ||
+ receive_interface || receive_member || receive_error || receive_service ||
+ own || user || group))
{
dbus_set_error (error, DBUS_ERROR_FAILED,
"Element <%s> must have one or more attributes",
element_name);
return FALSE;
}
-
- if (((send && own) ||
- (send && receive) ||
- (send && receive_from) ||
- (send && user) ||
- (send && group)) ||
-
- ((receive && own) ||
- (receive && send_to) ||
- (receive && user) ||
- (receive && group)) ||
-
- ((own && send_to) ||
- (own && receive_from) ||
- (own && user) ||
- (own && group)) ||
- ((send_to && receive_from) ||
- (send_to && user) ||
- (send_to && group)) ||
+ if ((send_member && send_interface == NULL) ||
+ (receive_member && receive_interface == NULL))
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "On element <%s>, if you specify a member you must specify an interface",
+ element_name);
+ return FALSE;
+ }
+
+ /* Allowed combinations of elements are:
+ *
+ * base, must be all send or all receive:
+ * interface
+ * interface + member
+ * error
+ *
+ * base send_ can combine with send_service,
+ * base receive_ with receive_service
+ *
+ * user, group, own must occur alone
+ */
- ((receive_from && user) ||
- (receive_from && group)) ||
+ if (((send_interface && send_error) ||
+ (send_interface && receive_interface) ||
+ (send_interface && receive_member) ||
+ (send_interface && receive_error) ||
+ (send_interface && receive_service) ||
+ (send_interface && own) ||
+ (send_interface && user) ||
+ (send_interface && group)) ||
+
+ ((send_member && send_error) ||
+ (send_member && receive_interface) ||
+ (send_member && receive_member) ||
+ (send_member && receive_error) ||
+ (send_member && receive_service) ||
+ (send_member && own) ||
+ (send_member && user) ||
+ (send_member && group)) ||
+
+ ((send_error && receive_interface) ||
+ (send_error && receive_member) ||
+ (send_error && receive_error) ||
+ (send_error && receive_service) ||
+ (send_error && own) ||
+ (send_error && user) ||
+ (send_error && group)) ||
+
+ ((send_service && receive_interface) ||
+ (send_service && receive_member) ||
+ (send_service && receive_error) ||
+ (send_service && receive_service) ||
+ (send_service && own) ||
+ (send_service && user) ||
+ (send_service && group)) ||
+
+ ((receive_interface && receive_error) ||
+ (receive_interface && own) ||
+ (receive_interface && user) ||
+ (receive_interface && group)) ||
+
+ ((receive_member && receive_error) ||
+ (receive_member && own) ||
+ (receive_member && user) ||
+ (receive_member && group)) ||
+
+ ((receive_error && own) ||
+ (receive_error && user) ||
+ (receive_error && group)) ||
+
+ ((own && user) ||
+ (own && group)) ||
- (user && group))
+ ((user && group)))
{
dbus_set_error (error, DBUS_ERROR_FAILED,
"Invalid combination of attributes on element <%s>, "
- "only send/send_to or receive/receive_from may be paired",
+ "only send_foo/send_service or receive_foo/receive_service may be paired",
element_name);
return FALSE;
}
-
+
rule = NULL;
/* In BusPolicyRule, NULL represents wildcard.
@@ -887,41 +946,60 @@ append_rule_from_element (BusConfigParser *parser,
*/
#define IS_WILDCARD(str) ((str) && ((str)[0]) == '*' && ((str)[1]) == '\0')
- if (send || send_to)
+ if (send_interface || send_member || send_error || send_service)
{
rule = bus_policy_rule_new (BUS_POLICY_RULE_SEND, allow);
if (rule == NULL)
goto nomem;
-
- if (IS_WILDCARD (send))
- send = NULL;
- if (IS_WILDCARD (send_to))
- send_to = NULL;
- rule->d.send.message_name = _dbus_strdup (send);
- rule->d.send.destination = _dbus_strdup (send_to);
- if (send && rule->d.send.message_name == NULL)
+ if (IS_WILDCARD (send_interface))
+ send_interface = NULL;
+ if (IS_WILDCARD (send_member))
+ send_member = NULL;
+ if (IS_WILDCARD (send_error))
+ send_error = NULL;
+ if (IS_WILDCARD (send_service))
+ send_service = NULL;
+
+ rule->d.send.interface = _dbus_strdup (send_interface);
+ rule->d.send.member = _dbus_strdup (send_member);
+ rule->d.send.error = _dbus_strdup (send_error);
+ rule->d.send.destination = _dbus_strdup (send_service);
+ if (send_interface && rule->d.send.interface == NULL)
+ goto nomem;
+ if (send_member && rule->d.send.member == NULL)
goto nomem;
- if (send_to && rule->d.send.destination == NULL)
+ if (send_error && rule->d.send.error == NULL)
+ goto nomem;
+ if (send_service && rule->d.send.destination == NULL)
goto nomem;
}
- else if (receive || receive_from)
+ else if (receive_interface || receive_member || receive_error || receive_service)
{
rule = bus_policy_rule_new (BUS_POLICY_RULE_RECEIVE, allow);
if (rule == NULL)
goto nomem;
-
- if (IS_WILDCARD (receive))
- receive = NULL;
-
- if (IS_WILDCARD (receive_from))
- receive_from = NULL;
- rule->d.receive.message_name = _dbus_strdup (receive);
- rule->d.receive.origin = _dbus_strdup (receive_from);
- if (receive && rule->d.receive.message_name == NULL)
+ if (IS_WILDCARD (receive_interface))
+ receive_interface = NULL;
+ if (IS_WILDCARD (receive_member))
+ receive_member = NULL;
+ if (IS_WILDCARD (receive_error))
+ receive_error = NULL;
+ if (IS_WILDCARD (receive_service))
+ receive_service = NULL;
+
+ rule->d.receive.interface = _dbus_strdup (receive_interface);
+ rule->d.receive.member = _dbus_strdup (receive_member);
+ rule->d.receive.error = _dbus_strdup (receive_error);
+ rule->d.receive.origin = _dbus_strdup (receive_service);
+ if (receive_interface && rule->d.receive.interface == NULL)
+ goto nomem;
+ if (receive_member && rule->d.receive.member == NULL)
+ goto nomem;
+ if (receive_error && rule->d.receive.error == NULL)
goto nomem;
- if (receive_from && rule->d.receive.origin == NULL)
+ if (receive_service && rule->d.receive.origin == NULL)
goto nomem;
}
else if (own)
diff --git a/bus/connection.c b/bus/connection.c
index e588039e..4df00bfd 100644
--- a/bus/connection.c
+++ b/bus/connection.c
@@ -972,10 +972,10 @@ bus_connection_preallocate_oom_error (DBusConnection *connection)
}
/* d->name may be NULL, but that is OK */
- if (!dbus_message_set_name (message, DBUS_ERROR_NO_MEMORY) ||
+ if (!dbus_message_set_error_name (message, DBUS_ERROR_NO_MEMORY) ||
!dbus_message_set_destination (message, d->name) ||
!dbus_message_set_sender (message,
- DBUS_SERVICE_DBUS))
+ DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
{
dbus_connection_free_preallocated_send (connection, preallocated);
dbus_message_unref (message);
@@ -1312,10 +1312,15 @@ bus_transaction_send_from_driver (BusTransaction *transaction,
* to check security policy since it was not done in
* dispatch.c
*/
- _dbus_verbose ("Sending %s from driver\n",
- dbus_message_get_name (message));
-
- if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS))
+ _dbus_verbose ("Sending %s %s %s from driver\n",
+ dbus_message_get_interface (message) ?
+ dbus_message_get_interface (message) : "(no interface)",
+ dbus_message_get_member (message) ?
+ dbus_message_get_member (message) : "(no member)",
+ dbus_message_get_error_name (message) ?
+ dbus_message_get_error_name (message) : "(no error name)");
+
+ if (!dbus_message_set_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
return FALSE;
/* If security policy doesn't allow the message, we silently
@@ -1337,11 +1342,16 @@ bus_transaction_send (BusTransaction *transaction,
BusConnectionData *d;
DBusList *link;
- _dbus_verbose (" trying to add %s %s to transaction%s\n",
+ _dbus_verbose (" trying to add %s interface=%s member=%s error=%s to transaction%s\n",
dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR ? "error" :
dbus_message_get_reply_serial (message) != 0 ? "reply" :
"message",
- dbus_message_get_name (message),
+ dbus_message_get_interface (message) ?
+ dbus_message_get_interface (message) : "(unset)",
+ dbus_message_get_member (message) ?
+ dbus_message_get_member (message) : "(unset)",
+ dbus_message_get_error_name (message) ?
+ dbus_message_get_error_name (message) : "(unset)",
dbus_connection_get_is_connected (connection) ?
"" : " (disconnected)");
diff --git a/bus/dispatch.c b/bus/dispatch.c
index e8f0c9ba..934619f1 100644
--- a/bus/dispatch.c
+++ b/bus/dispatch.c
@@ -104,7 +104,7 @@ static DBusHandlerResult
bus_dispatch (DBusConnection *connection,
DBusMessage *message)
{
- const char *sender, *service_name, *message_name;
+ const char *sender, *service_name;
DBusError error;
BusTransaction *transaction;
BusContext *context;
@@ -126,14 +126,24 @@ bus_dispatch (DBusConnection *connection,
/* Ref connection in case we disconnect it at some point in here */
dbus_connection_ref (connection);
-
+
service_name = dbus_message_get_destination (message);
- message_name = dbus_message_get_name (message);
-
- _dbus_assert (message_name != NULL); /* DBusMessageLoader is supposed to check this */
- _dbus_verbose ("DISPATCH: %s to %s\n",
- message_name, service_name ? service_name : "peer");
+#ifdef DBUS_ENABLE_VERBOSE_MODE
+ {
+ const char *interface_name, *member_name, *error_name;
+
+ interface_name = dbus_message_get_interface (message);
+ member_name = dbus_message_get_member (message);
+ error_name = dbus_message_get_error_name (message);
+
+ _dbus_verbose ("DISPATCH: %s %s %s to %s\n",
+ interface_name ? interface_name : "(no interface)",
+ member_name ? member_name : "(no member)",
+ error_name ? error_name : "(no error name)",
+ service_name ? service_name : "peer");
+ }
+#endif /* DBUS_ENABLE_VERBOSE_MODE */
/* If service_name is NULL, this is a message to the bus daemon, not
* intended to actually go "on the bus"; e.g. a peer-to-peer
@@ -142,7 +152,8 @@ bus_dispatch (DBusConnection *connection,
*/
if (service_name == NULL)
{
- if (strcmp (message_name, DBUS_MESSAGE_LOCAL_DISCONNECT) == 0)
+ if (dbus_message_has_interface (message, DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL) &&
+ dbus_message_has_member (message, "Disconnect"))
bus_connection_disconnected (connection);
/* DBusConnection also handles some of these automatically, we leave
@@ -182,7 +193,7 @@ bus_dispatch (DBusConnection *connection,
service_name = dbus_message_get_destination (message);
}
- if (strcmp (service_name, DBUS_SERVICE_DBUS) == 0) /* to bus driver */
+ if (strcmp (service_name, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS) == 0) /* to bus driver */
{
if (!bus_context_check_security_policy (context,
connection, NULL, message, &error))
@@ -191,7 +202,7 @@ bus_dispatch (DBusConnection *connection,
goto out;
}
- _dbus_verbose ("Giving message to %s\n", DBUS_SERVICE_DBUS);
+ _dbus_verbose ("Giving message to %s\n", DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
if (!bus_driver_handle_message (connection, transaction, message, &error))
goto out;
}
@@ -679,7 +690,7 @@ check_hello_message (BusContext *context,
message = NULL;
message = dbus_message_new_method_call (DBUS_MESSAGE_HELLO,
- DBUS_SERVICE_DBUS);
+ DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
if (message == NULL)
return TRUE;
@@ -721,7 +732,7 @@ check_hello_message (BusContext *context,
_dbus_verbose ("Received %s on %p\n",
dbus_message_get_name (message), connection);
- if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
+ if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
{
_dbus_warn ("Message has wrong sender %s\n",
dbus_message_get_sender (message) ?
@@ -911,7 +922,7 @@ check_nonexistent_service_activation (BusContext *context,
dbus_error_init (&error);
message = dbus_message_new_method_call (DBUS_MESSAGE_ACTIVATE_SERVICE,
- DBUS_SERVICE_DBUS);
+ DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
if (message == NULL)
return TRUE;
@@ -959,7 +970,7 @@ check_nonexistent_service_activation (BusContext *context,
if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
{
- if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
+ if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
{
_dbus_warn ("Message has wrong sender %s\n",
dbus_message_get_sender (message) ?
@@ -1465,7 +1476,7 @@ check_existent_service_activation (BusContext *context,
dbus_error_init (&error);
message = dbus_message_new_method_call (DBUS_MESSAGE_ACTIVATE_SERVICE,
- DBUS_SERVICE_DBUS);
+ DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
if (message == NULL)
return TRUE;
@@ -1519,7 +1530,7 @@ check_existent_service_activation (BusContext *context,
if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
{
- if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
+ if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
{
_dbus_warn ("Message has wrong sender %s\n",
dbus_message_get_sender (message) ?
@@ -1673,7 +1684,7 @@ check_segfault_service_activation (BusContext *context,
dbus_error_init (&error);
message = dbus_message_new_method_call (DBUS_MESSAGE_ACTIVATE_SERVICE,
- DBUS_SERVICE_DBUS);
+ DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
if (message == NULL)
return TRUE;
@@ -1722,7 +1733,7 @@ check_segfault_service_activation (BusContext *context,
if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
{
- if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
+ if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
{
_dbus_warn ("Message has wrong sender %s\n",
dbus_message_get_sender (message) ?
diff --git a/bus/policy.c b/bus/policy.c
index 2f8e2ca3..3b3ceb4e 100644
--- a/bus/policy.c
+++ b/bus/policy.c
@@ -80,11 +80,15 @@ bus_policy_rule_unref (BusPolicyRule *rule)
switch (rule->type)
{
case BUS_POLICY_RULE_SEND:
- dbus_free (rule->d.send.message_name);
+ dbus_free (rule->d.send.interface);
+ dbus_free (rule->d.send.member);
+ dbus_free (rule->d.send.error);
dbus_free (rule->d.send.destination);
break;
case BUS_POLICY_RULE_RECEIVE:
- dbus_free (rule->d.receive.message_name);
+ dbus_free (rule->d.receive.interface);
+ dbus_free (rule->d.receive.member);
+ dbus_free (rule->d.receive.error);
dbus_free (rule->d.receive.origin);
break;
case BUS_POLICY_RULE_OWN:
@@ -680,8 +684,8 @@ bus_client_policy_optimize (BusClientPolicy *policy)
/* The idea here is that if we have:
*
- * <allow send="foo"/>
- * <deny send="*"/>
+ * <allow send_interface="foo.bar"/>
+ * <deny send_interface="*"/>
*
* (for example) the deny will always override the allow. So we
* delete the allow. Ditto for deny followed by allow, etc. This is
@@ -713,12 +717,16 @@ bus_client_policy_optimize (BusClientPolicy *policy)
{
case BUS_POLICY_RULE_SEND:
remove_preceding =
- rule->d.send.message_name == NULL &&
+ rule->d.send.interface == NULL &&
+ rule->d.send.member == NULL &&
+ rule->d.send.error == NULL &&
rule->d.send.destination == NULL;
break;
case BUS_POLICY_RULE_RECEIVE:
remove_preceding =
- rule->d.receive.message_name == NULL &&
+ rule->d.receive.interface == NULL &&
+ rule->d.receive.member == NULL &&
+ rule->d.receive.error == NULL &&
rule->d.receive.origin == NULL;
break;
case BUS_POLICY_RULE_OWN:
@@ -791,16 +799,34 @@ bus_client_policy_check_can_send (BusClientPolicy *policy,
continue;
}
- if (rule->d.send.message_name != NULL)
+ if (rule->d.send.interface != NULL)
{
- if (!dbus_message_has_name (message,
- rule->d.send.message_name))
+ if (!dbus_message_has_interface (message,
+ rule->d.send.interface))
{
- _dbus_verbose (" (policy) skipping rule for different message name\n");
+ _dbus_verbose (" (policy) skipping rule for different interface\n");
continue;
}
}
-
+ else if (rule->d.send.member != NULL)
+ {
+ if (!dbus_message_has_member (message,
+ rule->d.send.member))
+ {
+ _dbus_verbose (" (policy) skipping rule for different member\n");
+ continue;
+ }
+ }
+ else if (rule->d.send.error != NULL)
+ {
+ if (!dbus_message_has_error_name (message,
+ rule->d.send.error))
+ {
+ _dbus_verbose (" (policy) skipping rule for different error name\n");
+ continue;
+ }
+ }
+
if (rule->d.send.destination != NULL)
{
/* receiver can be NULL for messages that are sent to the
@@ -886,16 +912,34 @@ bus_client_policy_check_can_receive (BusClientPolicy *policy,
continue;
}
- if (rule->d.receive.message_name != NULL)
+ if (rule->d.receive.interface != NULL)
{
- if (!dbus_message_has_name (message,
- rule->d.receive.message_name))
+ if (!dbus_message_has_interface (message,
+ rule->d.receive.interface))
{
- _dbus_verbose (" (policy) skipping rule for different message name\n");
+ _dbus_verbose (" (policy) skipping rule for different interface\n");
continue;
}
}
-
+ else if (rule->d.receive.member != NULL)
+ {
+ if (!dbus_message_has_member (message,
+ rule->d.receive.member))
+ {
+ _dbus_verbose (" (policy) skipping rule for different member\n");
+ continue;
+ }
+ }
+ else if (rule->d.receive.error != NULL)
+ {
+ if (!dbus_message_has_error_name (message,
+ rule->d.receive.error))
+ {
+ _dbus_verbose (" (policy) skipping rule for different error name\n");
+ continue;
+ }
+ }
+
if (rule->d.receive.origin != NULL)
{
/* sender can be NULL for messages that originate from the
diff --git a/bus/policy.h b/bus/policy.h
index 940085ee..2aa69aaf 100644
--- a/bus/policy.h
+++ b/bus/policy.h
@@ -54,15 +54,19 @@ struct BusPolicyRule
{
struct
{
- /* either can be NULL meaning "any" */
- char *message_name;
+ /* any of these can be NULL meaning "any" */
+ char *interface;
+ char *member;
+ char *error;
char *destination;
} send;
struct
{
- /* either can be NULL meaning "any" */
- char *message_name;
+ /* any of these can be NULL meaning "any" */
+ char *interface;
+ char *member;
+ char *error;
char *origin;
} receive;
diff --git a/dbus/dbus-bus.c b/dbus/dbus-bus.c
index 214978da..445606e2 100644
--- a/dbus/dbus-bus.c
+++ b/dbus/dbus-bus.c
@@ -32,6 +32,10 @@
* @ingroup DBus
* @brief Functions for communicating with the message bus
*
+ *
+ * @todo get rid of most of these; they should be done
+ * with DBusGProxy and the Qt equivalent, i.e. the same
+ * way any other interface would be used.
*/
@@ -398,8 +402,9 @@ dbus_bus_register (DBusConnection *connection,
return TRUE;
}
- message = dbus_message_new_method_call (DBUS_MESSAGE_HELLO,
- DBUS_SERVICE_DBUS);
+ message = dbus_message_new_method_call (DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
+ "Hello",
+ DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
if (!message)
@@ -516,9 +521,9 @@ dbus_bus_acquire_service (DBusConnection *connection,
_dbus_return_val_if_fail (service_name != NULL, 0);
_dbus_return_val_if_error_is_set (error, 0);
- message = dbus_message_new_method_call (DBUS_MESSAGE_ACQUIRE_SERVICE,
- DBUS_SERVICE_DBUS);
-
+ message = dbus_message_new_method_call (DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
+ "AcquireService",
+ DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
if (message == NULL)
{
@@ -590,8 +595,9 @@ dbus_bus_service_exists (DBusConnection *connection,
_dbus_return_val_if_fail (service_name != NULL, FALSE);
_dbus_return_val_if_error_is_set (error, FALSE);
- message = dbus_message_new_method_call (DBUS_MESSAGE_SERVICE_EXISTS,
- DBUS_SERVICE_DBUS);
+ message = dbus_message_new_method_call (DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
+ "ServiceExists",
+ DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
if (message == NULL)
{
_DBUS_SET_OOM (error);
@@ -652,8 +658,9 @@ dbus_bus_activate_service (DBusConnection *connection,
DBusMessage *msg;
DBusMessage *reply;
- msg = dbus_message_new_method_call (DBUS_MESSAGE_ACTIVATE_SERVICE,
- DBUS_SERVICE_DBUS);
+ msg = dbus_message_new_method_call (DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
+ "ActivateService",
+ DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, service_name,
DBUS_TYPE_UINT32, flags, DBUS_TYPE_INVALID))
diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
index bc26a3ec..7be35b4c 100644
--- a/dbus/dbus-connection.c
+++ b/dbus/dbus-connection.c
@@ -296,9 +296,11 @@ _dbus_connection_queue_received_message_link (DBusConnection *connection,
_dbus_connection_wakeup_mainloop (connection);
- _dbus_assert (dbus_message_get_name (message) != NULL);
_dbus_verbose ("Message %p (%s) added to incoming queue %p, %d incoming\n",
- message, dbus_message_get_name (message),
+ message,
+ dbus_message_get_interface (message) ?
+ dbus_message_get_interface (message) :
+ "no interface",
connection,
connection->n_incoming);
}
@@ -381,7 +383,10 @@ _dbus_connection_message_sent (DBusConnection *connection,
connection->n_outgoing -= 1;
_dbus_verbose ("Message %p (%s) removed from outgoing queue %p, %d left to send\n",
- message, dbus_message_get_name (message),
+ message,
+ dbus_message_get_interface (message) ?
+ dbus_message_get_interface (message) :
+ "no interface",
connection, connection->n_outgoing);
/* Save this link in the link cache also */
@@ -820,7 +825,9 @@ _dbus_connection_new_for_transport (DBusTransport *transport)
if (io_path_cond == NULL)
goto error;
- disconnect_message = dbus_message_new_signal (DBUS_MESSAGE_LOCAL_DISCONNECT);
+ disconnect_message = dbus_message_new_signal (DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
+ "Disconnect");
+
if (disconnect_message == NULL)
goto error;
@@ -1482,7 +1489,9 @@ _dbus_connection_send_preallocated_unlocked (DBusConnection *connection,
_dbus_verbose ("Message %p (%s) added to outgoing queue %p, %d pending to send\n",
message,
- dbus_message_get_name (message),
+ dbus_message_get_interface (message) ?
+ dbus_message_get_interface (message) :
+ "no interface",
connection,
connection->n_outgoing);
@@ -1530,7 +1539,12 @@ dbus_connection_send_preallocated (DBusConnection *connection,
_dbus_return_if_fail (preallocated != NULL);
_dbus_return_if_fail (message != NULL);
_dbus_return_if_fail (preallocated->connection == connection);
- _dbus_return_if_fail (dbus_message_get_name (message) != NULL);
+ _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
+ (dbus_message_get_interface (message) != NULL &&
+ dbus_message_get_member (message) != NULL));
+ _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
+ (dbus_message_get_interface (message) != NULL &&
+ dbus_message_get_member (message) != NULL));
CONNECTION_LOCK (connection);
_dbus_connection_send_preallocated_unlocked (connection,
@@ -1854,8 +1868,7 @@ _dbus_connection_block_for_reply (DBusConnection *connection,
{
status = _dbus_connection_get_dispatch_status_unlocked (connection);
- _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply %s\n",
- dbus_message_get_name (reply));
+ _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");
/* Unlocks, and calls out to user code */
_dbus_connection_update_dispatch_status_and_unlock (connection, status);
@@ -2148,7 +2161,10 @@ _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
connection->n_incoming -= 1;
_dbus_verbose ("Message %p (%s) removed from incoming queue %p, %d incoming\n",
- link->data, dbus_message_get_name (link->data),
+ link->data,
+ dbus_message_get_interface (link->data) ?
+ dbus_message_get_interface (link->data) :
+ "no interface",
connection, connection->n_incoming);
return link;
@@ -2194,7 +2210,10 @@ _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
connection->n_incoming += 1;
_dbus_verbose ("Message %p (%s) put back into queue %p, %d incoming\n",
- message_link->data, dbus_message_get_name (message_link->data),
+ message_link->data,
+ dbus_message_get_interface (message_link->data) ?
+ dbus_message_get_interface (message_link->data) :
+ "no interface",
connection, connection->n_incoming);
}
@@ -2523,7 +2542,10 @@ dbus_connection_dispatch (DBusConnection *connection)
* since we acquired the dispatcher
*/
_dbus_verbose (" running object handler on message %p (%s)\n",
- message, dbus_message_get_name (message));
+ message,
+ dbus_message_get_interface (message) ?
+ dbus_message_get_interface (message) :
+ "no interface");
result = _dbus_object_registry_handle_and_unlock (connection->objects,
message);
@@ -2549,8 +2571,9 @@ dbus_connection_dispatch (DBusConnection *connection)
}
if (!_dbus_string_append_printf (&str,
- "Method \"%s\" doesn't exist\n",
- dbus_message_get_name (message)))
+ "Method \"%s\" on interface \"%s\" doesn't exist\n",
+ dbus_message_get_member (message),
+ dbus_message_get_interface (message)))
{
_dbus_string_free (&str);
result = DBUS_HANDLER_RESULT_NEED_MEMORY;
@@ -2586,7 +2609,10 @@ dbus_connection_dispatch (DBusConnection *connection)
}
_dbus_verbose (" done dispatching %p (%s) on connection %p\n", message,
- dbus_message_get_name (message), connection);
+ dbus_message_get_interface (message) ?
+ dbus_message_get_interface (message) :
+ "no interface",
+ connection);
out:
if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
diff --git a/dbus/dbus-hash.c b/dbus/dbus-hash.c
index 2c410010..f4547815 100644
--- a/dbus/dbus-hash.c
+++ b/dbus/dbus-hash.c
@@ -221,26 +221,32 @@ typedef struct
int n_entries_on_init; /**< used to detect table resize since initialization */
} DBusRealHashIter;
-static DBusHashEntry* find_direct_function (DBusHashTable *table,
- void *key,
- dbus_bool_t create_if_not_found,
- DBusHashEntry ***bucket,
- DBusPreallocatedHash *preallocated);
-static DBusHashEntry* find_string_function (DBusHashTable *table,
- void *key,
- dbus_bool_t create_if_not_found,
- DBusHashEntry ***bucket,
- DBusPreallocatedHash *preallocated);
-static unsigned int string_hash (const char *str);
-static void rebuild_table (DBusHashTable *table);
-static DBusHashEntry* alloc_entry (DBusHashTable *table);
-static void remove_entry (DBusHashTable *table,
- DBusHashEntry **bucket,
- DBusHashEntry *entry);
-static void free_entry (DBusHashTable *table,
- DBusHashEntry *entry);
-static void free_entry_data (DBusHashTable *table,
- DBusHashEntry *entry);
+static DBusHashEntry* find_direct_function (DBusHashTable *table,
+ void *key,
+ dbus_bool_t create_if_not_found,
+ DBusHashEntry ***bucket,
+ DBusPreallocatedHash *preallocated);
+static DBusHashEntry* find_string_function (DBusHashTable *table,
+ void *key,
+ dbus_bool_t create_if_not_found,
+ DBusHashEntry ***bucket,
+ DBusPreallocatedHash *preallocated);
+static DBusHashEntry* find_two_strings_function (DBusHashTable *table,
+ void *key,
+ dbus_bool_t create_if_not_found,
+ DBusHashEntry ***bucket,
+ DBusPreallocatedHash *preallocated);
+static unsigned int string_hash (const char *str);
+static unsigned int two_strings_hash (const char *str);
+static void rebuild_table (DBusHashTable *table);
+static DBusHashEntry* alloc_entry (DBusHashTable *table);
+static void remove_entry (DBusHashTable *table,
+ DBusHashEntry **bucket,
+ DBusHashEntry *entry);
+static void free_entry (DBusHashTable *table,
+ DBusHashEntry *entry);
+static void free_entry_data (DBusHashTable *table,
+ DBusHashEntry *entry);
/** @} */
@@ -323,6 +329,9 @@ _dbus_hash_table_new (DBusHashType type,
case DBUS_HASH_STRING:
table->find_function = find_string_function;
break;
+ case DBUS_HASH_TWO_STRINGS:
+ table->find_function = find_two_strings_function;
+ break;
default:
_dbus_assert_not_reached ("Unknown hash table type");
break;
@@ -685,6 +694,24 @@ _dbus_hash_iter_get_string_key (DBusHashIter *iter)
}
/**
+ * Gets the key for the current entry.
+ * Only works for hash tables of type #DBUS_HASH_TWO_STRINGS
+ * @param iter the hash table iterator.
+ */
+const char*
+_dbus_hash_iter_get_two_strings_key (DBusHashIter *iter)
+{
+ DBusRealHashIter *real;
+
+ real = (DBusRealHashIter*) iter;
+
+ _dbus_assert (real->table != NULL);
+ _dbus_assert (real->entry != NULL);
+
+ return real->entry->key;
+}
+
+/**
* A low-level but efficient interface for manipulating the hash
* table. It's efficient because you can get, set, and optionally
* create the hash entry while only running the hash function one
@@ -803,64 +830,63 @@ add_entry (DBusHashTable *table,
return entry;
}
+/* This is g_str_hash from GLib which was
+ * extensively discussed/tested/profiled
+ */
static unsigned int
string_hash (const char *str)
{
- register unsigned int result;
- register int c;
+ const char *p = str;
+ unsigned int h = *p;
- /*
- * I tried a zillion different hash functions and asked many other
- * people for advice. Many people had their own favorite functions,
- * all different, but no-one had much idea why they were good ones.
- * I chose the one below (multiply by 9 and add new character)
- * because of the following reasons:
- *
- * 1. Multiplying by 10 is perfect for keys that are decimal strings,
- * and multiplying by 9 is just about as good.
- * 2. Times-9 is (shift-left-3) plus (old). This means that each
- * character's bits hang around in the low-order bits of the
- * hash value for ever, plus they spread fairly rapidly up to
- * the high-order bits to fill out the hash value. This seems
- * works well both for decimal and non-decimal strings.
- */
+ if (h)
+ for (p += 1; *p != '\0'; p++)
+ h = (h << 5) - h + *p;
- /* FIXME the hash function in GLib is better than this one */
-
- result = 0;
- while (TRUE)
- {
- c = *str;
- str++;
- if (c == 0)
- break;
-
- result += (result << 3) + c;
- }
+ return h;
+}
+
+/* This hashes a memory block with two nul-terminated strings
+ * in it, used in dbus-object-registry.c at the moment.
+ */
+static unsigned int
+two_strings_hash (const char *str)
+{
+ const char *p = str;
+ unsigned int h = *p;
+
+ if (h)
+ for (p += 1; *p != '\0'; p++)
+ h = (h << 5) - h + *p;
+
+ for (p += 1; *p != '\0'; p++)
+ h = (h << 5) - h + *p;
- return result;
+ return h;
}
+typedef int (* KeyCompareFunc) (const void *key_a, const void *key_b);
+
static DBusHashEntry*
-find_string_function (DBusHashTable *table,
- void *key,
- dbus_bool_t create_if_not_found,
- DBusHashEntry ***bucket,
- DBusPreallocatedHash *preallocated)
+find_generic_function (DBusHashTable *table,
+ void *key,
+ unsigned int idx,
+ KeyCompareFunc compare_func,
+ dbus_bool_t create_if_not_found,
+ DBusHashEntry ***bucket,
+ DBusPreallocatedHash *preallocated)
{
DBusHashEntry *entry;
- unsigned int idx;
if (bucket)
*bucket = NULL;
-
- idx = string_hash (key) & table->mask;
/* Search all of the entries in this bucket. */
entry = table->buckets[idx];
while (entry != NULL)
{
- if (strcmp (key, entry->key) == 0)
+ if ((compare_func == NULL && key == entry->key) ||
+ (compare_func != NULL && (* compare_func) (key, entry->key) == 0))
{
if (bucket)
*bucket = &(table->buckets[idx]);
@@ -878,50 +904,75 @@ find_string_function (DBusHashTable *table,
entry = add_entry (table, idx, key, bucket, preallocated);
else if (preallocated)
_dbus_hash_table_free_preallocated_entry (table, preallocated);
-
+
return entry;
}
static DBusHashEntry*
-find_direct_function (DBusHashTable *table,
+find_string_function (DBusHashTable *table,
void *key,
dbus_bool_t create_if_not_found,
DBusHashEntry ***bucket,
DBusPreallocatedHash *preallocated)
{
- DBusHashEntry *entry;
unsigned int idx;
+
+ idx = string_hash (key) & table->mask;
- if (bucket)
- *bucket = NULL;
+ return find_generic_function (table, key, idx,
+ (KeyCompareFunc) strcmp, create_if_not_found, bucket,
+ preallocated);
+}
+
+static int
+two_strings_cmp (const char *a,
+ const char *b)
+{
+ size_t len_a;
+ size_t len_b;
+ int res;
- idx = RANDOM_INDEX (table, key) & table->mask;
+ res = strcmp (a, b);
+ if (res != 0)
+ return res;
- /* Search all of the entries in this bucket. */
- entry = table->buckets[idx];
- while (entry != NULL)
- {
- if (key == entry->key)
- {
- if (bucket)
- *bucket = &(table->buckets[idx]);
+ len_a = strlen (a);
+ len_b = strlen (b);
- if (preallocated)
- _dbus_hash_table_free_preallocated_entry (table, preallocated);
-
- return entry;
- }
-
- entry = entry->next;
- }
+ return strcmp (a + len_a + 1, b + len_b + 1);
+}
- /* Entry not found. Add a new one to the bucket. */
- if (create_if_not_found)
- entry = add_entry (table, idx, key, bucket, preallocated);
- else if (preallocated)
- _dbus_hash_table_free_preallocated_entry (table, preallocated);
+static DBusHashEntry*
+find_two_strings_function (DBusHashTable *table,
+ void *key,
+ dbus_bool_t create_if_not_found,
+ DBusHashEntry ***bucket,
+ DBusPreallocatedHash *preallocated)
+{
+ unsigned int idx;
+
+ idx = two_strings_hash (key) & table->mask;
- return entry;
+ return find_generic_function (table, key, idx,
+ (KeyCompareFunc) two_strings_cmp, create_if_not_found, bucket,
+ preallocated);
+}
+
+static DBusHashEntry*
+find_direct_function (DBusHashTable *table,
+ void *key,
+ dbus_bool_t create_if_not_found,
+ DBusHashEntry ***bucket,
+ DBusPreallocatedHash *preallocated)
+{
+ unsigned int idx;
+
+ idx = RANDOM_INDEX (table, key) & table->mask;
+
+
+ return find_generic_function (table, key, idx,
+ NULL, create_if_not_found, bucket,
+ preallocated);
}
static void
@@ -1021,6 +1072,9 @@ rebuild_table (DBusHashTable *table)
case DBUS_HASH_STRING:
idx = string_hash (entry->key) & table->mask;
break;
+ case DBUS_HASH_TWO_STRINGS:
+ idx = two_strings_hash (entry->key) & table->mask;
+ break;
case DBUS_HASH_INT:
case DBUS_HASH_ULONG:
case DBUS_HASH_POINTER:
@@ -1070,6 +1124,31 @@ _dbus_hash_table_lookup_string (DBusHashTable *table,
}
/**
+ * Looks up the value for a given string in a hash table
+ * of type #DBUS_HASH_TWO_STRINGS. Returns %NULL if the value
+ * is not present. (A not-present entry is indistinguishable
+ * from an entry with a value of %NULL.)
+ * @param table the hash table.
+ * @param key the string to look up.
+ * @returns the value of the hash entry.
+ */
+void*
+_dbus_hash_table_lookup_two_strings (DBusHashTable *table,
+ const char *key)
+{
+ DBusHashEntry *entry;
+
+ _dbus_assert (table->key_type == DBUS_HASH_TWO_STRINGS);
+
+ entry = (* table->find_function) (table, (char*) key, FALSE, NULL, NULL);
+
+ if (entry)
+ return entry->value;
+ else
+ return NULL;
+}
+
+/**
* Looks up the value for a given integer in a hash table
* of type #DBUS_HASH_INT. Returns %NULL if the value
* is not present. (A not-present entry is indistinguishable
@@ -1184,6 +1263,34 @@ _dbus_hash_table_remove_string (DBusHashTable *table,
* @returns #TRUE if the entry existed
*/
dbus_bool_t
+_dbus_hash_table_remove_two_strings (DBusHashTable *table,
+ const char *key)
+{
+ DBusHashEntry *entry;
+ DBusHashEntry **bucket;
+
+ _dbus_assert (table->key_type == DBUS_HASH_TWO_STRINGS);
+
+ entry = (* table->find_function) (table, (char*) key, FALSE, &bucket, NULL);
+
+ if (entry)
+ {
+ remove_entry (table, bucket, entry);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+/**
+ * Removes the hash entry for the given key. If no hash entry
+ * for the key exists, does nothing.
+ *
+ * @param table the hash table.
+ * @param key the hash key.
+ * @returns #TRUE if the entry existed
+ */
+dbus_bool_t
_dbus_hash_table_remove_int (DBusHashTable *table,
int key)
{
@@ -1312,6 +1419,40 @@ _dbus_hash_table_insert_string (DBusHashTable *table,
* @param value the hash entry value.
*/
dbus_bool_t
+_dbus_hash_table_insert_two_strings (DBusHashTable *table,
+ char *key,
+ void *value)
+{
+ DBusPreallocatedHash *preallocated;
+
+ _dbus_assert (table->key_type == DBUS_HASH_TWO_STRINGS);
+
+ preallocated = _dbus_hash_table_preallocate_entry (table);
+ if (preallocated == NULL)
+ return FALSE;
+
+ _dbus_hash_table_insert_string_preallocated (table, preallocated,
+ key, value);
+
+ return TRUE;
+}
+
+/**
+ * Creates a hash entry with the given key and value.
+ * The key and value are not copied; they are stored
+ * in the hash table by reference. If an entry with the
+ * given key already exists, the previous key and value
+ * are overwritten (and freed if the hash table has
+ * a key_free_function and/or value_free_function).
+ *
+ * Returns #FALSE if memory for the new hash entry
+ * can't be allocated.
+ *
+ * @param table the hash table.
+ * @param key the hash entry key.
+ * @param value the hash entry value.
+ */
+dbus_bool_t
_dbus_hash_table_insert_int (DBusHashTable *table,
int key,
void *value)
@@ -1536,6 +1677,28 @@ count_entries (DBusHashTable *table)
return count;
}
+/* Copy the foo\0bar\0 double string thing */
+static char*
+_dbus_strdup2 (const char *str)
+{
+ size_t len;
+ char *copy;
+
+ if (str == NULL)
+ return NULL;
+
+ len = strlen (str);
+ len += strlen ((str + len + 1));
+
+ copy = dbus_malloc (len + 2);
+ if (copy == NULL)
+ return NULL;
+
+ memcpy (copy, str, len + 2);
+
+ return copy;
+}
+
/**
* @ingroup DBusHashTableInternals
* Unit test for DBusHashTable
@@ -1548,6 +1711,7 @@ _dbus_hash_test (void)
DBusHashTable *table1;
DBusHashTable *table2;
DBusHashTable *table3;
+ DBusHashTable *table4;
DBusHashIter iter;
#define N_HASH_KEYS 5000
char **keys;
@@ -1569,7 +1733,16 @@ _dbus_hash_test (void)
i = 0;
while (i < N_HASH_KEYS)
{
- sprintf (keys[i], "Hash key %d", i);
+ int len;
+
+ /* all the hash keys are TWO_STRINGS, but
+ * then we can also use those as regular strings.
+ */
+
+ len = sprintf (keys[i], "Hash key %d", i);
+ sprintf (keys[i] + len + 1, "Two string %d", i);
+ _dbus_assert (*(keys[i] + len) == '\0');
+ _dbus_assert (*(keys[i] + len + 1) != '\0');
++i;
}
printf ("... done.\n");
@@ -1588,6 +1761,12 @@ _dbus_hash_test (void)
NULL, dbus_free);
if (table3 == NULL)
goto out;
+
+ table4 = _dbus_hash_table_new (DBUS_HASH_TWO_STRINGS,
+ dbus_free, dbus_free);
+ if (table4 == NULL)
+ goto out;
+
/* Insert and remove a bunch of stuff, counting the table in between
* to be sure it's not broken and that iteration works
@@ -1624,10 +1803,22 @@ _dbus_hash_test (void)
if (!_dbus_hash_table_insert_ulong (table3,
i, value))
goto out;
+
+ key = _dbus_strdup2 (keys[i]);
+ if (key == NULL)
+ goto out;
+ value = _dbus_strdup ("Value!");
+ if (value == NULL)
+ goto out;
+
+ if (!_dbus_hash_table_insert_string (table4,
+ key, value))
+ goto out;
_dbus_assert (count_entries (table1) == i + 1);
_dbus_assert (count_entries (table2) == i + 1);
_dbus_assert (count_entries (table3) == i + 1);
+ _dbus_assert (count_entries (table4) == i + 1);
value = _dbus_hash_table_lookup_string (table1, keys[i]);
_dbus_assert (value != NULL);
@@ -1640,6 +1831,10 @@ _dbus_hash_test (void)
value = _dbus_hash_table_lookup_ulong (table3, i);
_dbus_assert (value != NULL);
_dbus_assert (strcmp (value, keys[i]) == 0);
+
+ value = _dbus_hash_table_lookup_ulong (table4, i);
+ _dbus_assert (value != NULL);
+ _dbus_assert (strcmp (value, keys[i]) == 0);
++i;
}
@@ -1654,9 +1849,13 @@ _dbus_hash_test (void)
_dbus_hash_table_remove_ulong (table3, i);
+ _dbus_hash_table_remove_two_strings (table4,
+ keys[i]);
+
_dbus_assert (count_entries (table1) == i);
_dbus_assert (count_entries (table2) == i);
_dbus_assert (count_entries (table3) == i);
+ _dbus_assert (count_entries (table4) == i);
--i;
}
@@ -1664,12 +1863,15 @@ _dbus_hash_test (void)
_dbus_hash_table_ref (table1);
_dbus_hash_table_ref (table2);
_dbus_hash_table_ref (table3);
+ _dbus_hash_table_ref (table4);
_dbus_hash_table_unref (table1);
_dbus_hash_table_unref (table2);
_dbus_hash_table_unref (table3);
+ _dbus_hash_table_unref (table4);
_dbus_hash_table_unref (table1);
_dbus_hash_table_unref (table2);
_dbus_hash_table_unref (table3);
+ _dbus_hash_table_unref (table4);
table3 = NULL;
/* Insert a bunch of stuff then check
diff --git a/dbus/dbus-hash.h b/dbus/dbus-hash.h
index 566d4021..25b81dd6 100644
--- a/dbus/dbus-hash.h
+++ b/dbus/dbus-hash.h
@@ -52,61 +52,68 @@ typedef struct DBusHashIter DBusHashIter;
*/
typedef enum
{
- DBUS_HASH_STRING, /**< Hash keys are strings. */
- DBUS_HASH_INT, /**< Hash keys are integers. */
- DBUS_HASH_POINTER, /**< Hash keys are pointers. */
- DBUS_HASH_ULONG /**< Hash keys are unsigned long. */
+ DBUS_HASH_STRING, /**< Hash keys are strings. */
+ DBUS_HASH_TWO_STRINGS, /**< Hash key is two strings in one memory block, i.e. foo\0bar\0 */
+ DBUS_HASH_INT, /**< Hash keys are integers. */
+ DBUS_HASH_POINTER, /**< Hash keys are pointers. */
+ DBUS_HASH_ULONG /**< Hash keys are unsigned long. */
} DBusHashType;
-
-DBusHashTable* _dbus_hash_table_new (DBusHashType type,
- DBusFreeFunction key_free_function,
- DBusFreeFunction value_free_function);
-void _dbus_hash_table_ref (DBusHashTable *table);
-void _dbus_hash_table_unref (DBusHashTable *table);
-void _dbus_hash_iter_init (DBusHashTable *table,
- DBusHashIter *iter);
-dbus_bool_t _dbus_hash_iter_next (DBusHashIter *iter);
-void _dbus_hash_iter_remove_entry (DBusHashIter *iter);
-void* _dbus_hash_iter_get_value (DBusHashIter *iter);
-void _dbus_hash_iter_set_value (DBusHashIter *iter,
- void *value);
-int _dbus_hash_iter_get_int_key (DBusHashIter *iter);
-const char* _dbus_hash_iter_get_string_key (DBusHashIter *iter);
-unsigned long _dbus_hash_iter_get_ulong_key (DBusHashIter *iter);
-dbus_bool_t _dbus_hash_iter_lookup (DBusHashTable *table,
- void *key,
- dbus_bool_t create_if_not_found,
- DBusHashIter *iter);
-void* _dbus_hash_table_lookup_string (DBusHashTable *table,
- const char *key);
-void* _dbus_hash_table_lookup_int (DBusHashTable *table,
- int key);
-void* _dbus_hash_table_lookup_pointer (DBusHashTable *table,
- void *key);
-void* _dbus_hash_table_lookup_ulong (DBusHashTable *table,
- unsigned long key);
-dbus_bool_t _dbus_hash_table_remove_string (DBusHashTable *table,
- const char *key);
-dbus_bool_t _dbus_hash_table_remove_int (DBusHashTable *table,
- int key);
-dbus_bool_t _dbus_hash_table_remove_pointer (DBusHashTable *table,
- void *key);
-dbus_bool_t _dbus_hash_table_remove_ulong (DBusHashTable *table,
- unsigned long key);
-dbus_bool_t _dbus_hash_table_insert_string (DBusHashTable *table,
- char *key,
- void *value);
-dbus_bool_t _dbus_hash_table_insert_int (DBusHashTable *table,
- int key,
- void *value);
-dbus_bool_t _dbus_hash_table_insert_pointer (DBusHashTable *table,
- void *key,
- void *value);
-dbus_bool_t _dbus_hash_table_insert_ulong (DBusHashTable *table,
- unsigned long key,
- void *value);
-int _dbus_hash_table_get_n_entries (DBusHashTable *table);
-
+DBusHashTable* _dbus_hash_table_new (DBusHashType type,
+ DBusFreeFunction key_free_function,
+ DBusFreeFunction value_free_function);
+void _dbus_hash_table_ref (DBusHashTable *table);
+void _dbus_hash_table_unref (DBusHashTable *table);
+void _dbus_hash_iter_init (DBusHashTable *table,
+ DBusHashIter *iter);
+dbus_bool_t _dbus_hash_iter_next (DBusHashIter *iter);
+void _dbus_hash_iter_remove_entry (DBusHashIter *iter);
+void* _dbus_hash_iter_get_value (DBusHashIter *iter);
+void _dbus_hash_iter_set_value (DBusHashIter *iter,
+ void *value);
+int _dbus_hash_iter_get_int_key (DBusHashIter *iter);
+const char* _dbus_hash_iter_get_string_key (DBusHashIter *iter);
+const char* _dbus_hash_iter_get_two_strings_key (DBusHashIter *iter);
+unsigned long _dbus_hash_iter_get_ulong_key (DBusHashIter *iter);
+dbus_bool_t _dbus_hash_iter_lookup (DBusHashTable *table,
+ void *key,
+ dbus_bool_t create_if_not_found,
+ DBusHashIter *iter);
+void* _dbus_hash_table_lookup_string (DBusHashTable *table,
+ const char *key);
+void* _dbus_hash_table_lookup_two_strings (DBusHashTable *table,
+ const char *key);
+void* _dbus_hash_table_lookup_int (DBusHashTable *table,
+ int key);
+void* _dbus_hash_table_lookup_pointer (DBusHashTable *table,
+ void *key);
+void* _dbus_hash_table_lookup_ulong (DBusHashTable *table,
+ unsigned long key);
+dbus_bool_t _dbus_hash_table_remove_string (DBusHashTable *table,
+ const char *key);
+dbus_bool_t _dbus_hash_table_remove_two_strings (DBusHashTable *table,
+ const char *key);
+dbus_bool_t _dbus_hash_table_remove_int (DBusHashTable *table,
+ int key);
+dbus_bool_t _dbus_hash_table_remove_pointer (DBusHashTable *table,
+ void *key);
+dbus_bool_t _dbus_hash_table_remove_ulong (DBusHashTable *table,
+ unsigned long key);
+dbus_bool_t _dbus_hash_table_insert_string (DBusHashTable *table,
+ char *key,
+ void *value);
+dbus_bool_t _dbus_hash_table_insert_two_strings (DBusHashTable *table,
+ char *key,
+ void *value);
+dbus_bool_t _dbus_hash_table_insert_int (DBusHashTable *table,
+ int key,
+ void *value);
+dbus_bool_t _dbus_hash_table_insert_pointer (DBusHashTable *table,
+ void *key,
+ void *value);
+dbus_bool_t _dbus_hash_table_insert_ulong (DBusHashTable *table,
+ unsigned long key,
+ void *value);
+int _dbus_hash_table_get_n_entries (DBusHashTable *table);
/* Preallocation */
typedef struct DBusPreallocatedHash DBusPreallocatedHash;
diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c
index 5f3d01e0..e5bbcab1 100644
--- a/dbus/dbus-message.c
+++ b/dbus/dbus-message.c
@@ -47,7 +47,9 @@ enum
FIELD_HEADER_LENGTH,
FIELD_BODY_LENGTH,
FIELD_CLIENT_SERIAL,
- FIELD_NAME,
+ FIELD_INTERFACE,
+ FIELD_MEMBER,
+ FIELD_ERROR_NAME,
FIELD_SERVICE,
FIELD_SENDER,
FIELD_REPLY_SERIAL,
@@ -60,7 +62,9 @@ static dbus_bool_t field_is_named[FIELD_LAST] =
FALSE, /* FIELD_HEADER_LENGTH */
FALSE, /* FIELD_BODY_LENGTH */
FALSE, /* FIELD_CLIENT_SERIAL */
- TRUE, /* FIELD_NAME */
+ TRUE, /* FIELD_INTERFACE */
+ TRUE, /* FIELD_MEMBER */
+ TRUE, /* FIELD_ERROR_NAME */
TRUE, /* FIELD_SERVICE */
TRUE, /* FIELD_SENDER */
TRUE /* FIELD_REPLY_SERIAL */
@@ -593,9 +597,17 @@ set_string_field (DBusMessage *message,
return append_string_field (message, field,
DBUS_HEADER_FIELD_SENDER,
value);
- case FIELD_NAME:
+ case FIELD_INTERFACE:
return append_string_field (message, field,
- DBUS_HEADER_FIELD_NAME,
+ DBUS_HEADER_FIELD_INTERFACE,
+ value);
+ case FIELD_MEMBER:
+ return append_string_field (message, field,
+ DBUS_HEADER_FIELD_MEMBER,
+ value);
+ case FIELD_ERROR_NAME:
+ return append_string_field (message, field,
+ DBUS_HEADER_FIELD_ERROR_NAME,
value);
case FIELD_SERVICE:
return append_string_field (message, field,
@@ -817,10 +829,16 @@ _dbus_message_remove_size_counter (DBusMessage *message,
static dbus_bool_t
dbus_message_create_header (DBusMessage *message,
int type,
- const char *name,
+ const char *interface,
+ const char *member,
+ const char *error_name,
const char *service)
{
unsigned int flags;
+
+ _dbus_assert ((interface && member) ||
+ (error_name) ||
+ !(interface || member || error_name));
if (!_dbus_string_append_byte (&message->header, message->byte_order))
return FALSE;
@@ -857,12 +875,30 @@ dbus_message_create_header (DBusMessage *message,
return FALSE;
}
- if (name != NULL)
+ if (interface != NULL)
+ {
+ if (!append_string_field (message,
+ FIELD_INTERFACE,
+ DBUS_HEADER_FIELD_INTERFACE,
+ interface))
+ return FALSE;
+ }
+
+ if (member != NULL)
{
if (!append_string_field (message,
- FIELD_NAME,
- DBUS_HEADER_FIELD_NAME,
- name))
+ FIELD_MEMBER,
+ DBUS_HEADER_FIELD_MEMBER,
+ member))
+ return FALSE;
+ }
+
+ if (error_name != NULL)
+ {
+ if (!append_string_field (message,
+ FIELD_ERROR_NAME,
+ DBUS_HEADER_FIELD_ERROR_NAME,
+ error_name))
return FALSE;
}
@@ -979,7 +1015,7 @@ dbus_message_new (int message_type)
if (!dbus_message_create_header (message,
message_type,
- NULL, NULL))
+ NULL, NULL, NULL, NULL))
{
dbus_message_unref (message);
return NULL;
@@ -995,18 +1031,21 @@ dbus_message_new (int message_type)
* this is appropriate when using D-BUS in a peer-to-peer context (no
* message bus).
*
- * @param name name of the message
+ * @param interface interface to invoke method on
+ * @param method method to invoke
* @param destination_service service that the message should be sent to or #NULL
* @returns a new DBusMessage, free with dbus_message_unref()
* @see dbus_message_unref()
*/
DBusMessage*
-dbus_message_new_method_call (const char *name,
+dbus_message_new_method_call (const char *interface,
+ const char *method,
const char *destination_service)
{
DBusMessage *message;
- _dbus_return_val_if_fail (name != NULL, NULL);
+ _dbus_return_val_if_fail (interface != NULL, NULL);
+ _dbus_return_val_if_fail (method != NULL, NULL);
message = dbus_message_new_empty_header ();
if (message == NULL)
@@ -1014,7 +1053,7 @@ dbus_message_new_method_call (const char *name,
if (!dbus_message_create_header (message,
DBUS_MESSAGE_TYPE_METHOD_CALL,
- name, destination_service))
+ interface, method, NULL, destination_service))
{
dbus_message_unref (message);
return NULL;
@@ -1036,14 +1075,12 @@ DBusMessage*
dbus_message_new_method_return (DBusMessage *method_call)
{
DBusMessage *message;
- const char *sender, *name;
+ const char *sender;
_dbus_return_val_if_fail (method_call != NULL, NULL);
sender = get_string_field (method_call,
FIELD_SENDER, NULL);
- name = get_string_field (method_call,
- FIELD_NAME, NULL);
/* sender is allowed to be null here in peer-to-peer case */
@@ -1053,7 +1090,7 @@ dbus_message_new_method_return (DBusMessage *method_call)
if (!dbus_message_create_header (message,
DBUS_MESSAGE_TYPE_METHOD_RETURN,
- name, sender))
+ NULL, NULL, NULL, sender))
{
dbus_message_unref (message);
return NULL;
@@ -1071,15 +1108,18 @@ dbus_message_new_method_return (DBusMessage *method_call)
/**
* Constructs a new message representing a signal emission. Returns
- * #NULL if memory can't be allocated for the message. The name
- * passed in is the name of the signal.
+ * #NULL if memory can't be allocated for the message.
+ * A signal is identified by its originating interface, and
+ * the name of the signal.
*
+ * @param interface the interface the signal is emitted from
* @param name name of the signal
* @returns a new DBusMessage, free with dbus_message_unref()
* @see dbus_message_unref()
*/
DBusMessage*
-dbus_message_new_signal (const char *name)
+dbus_message_new_signal (const char *interface,
+ const char *name)
{
DBusMessage *message;
@@ -1091,7 +1131,7 @@ dbus_message_new_signal (const char *name)
if (!dbus_message_create_header (message,
DBUS_MESSAGE_TYPE_SIGNAL,
- name, NULL))
+ interface, name, NULL, NULL))
{
dbus_message_unref (message);
return NULL;
@@ -1134,7 +1174,7 @@ dbus_message_new_error (DBusMessage *reply_to,
if (!dbus_message_create_header (message,
DBUS_MESSAGE_TYPE_ERROR,
- error_name, sender))
+ NULL, NULL, error_name, sender))
{
dbus_message_unref (message);
return NULL;
@@ -1312,46 +1352,139 @@ dbus_message_get_type (DBusMessage *message)
return type;
}
+/**
+ * Sets the interface this message is being sent to
+ * (for DBUS_MESSAGE_TYPE_METHOD_CALL) or
+ * the interface a signal is being emitted from
+ * (for DBUS_MESSAGE_TYPE_SIGNAL).
+ *
+ * @param message the message
+ * @param interface the interface
+ * @returns #FALSE if not enough memory
+ */
+dbus_bool_t
+dbus_message_set_interface (DBusMessage *message,
+ const char *interface)
+{
+ _dbus_return_val_if_fail (message != NULL, FALSE);
+ _dbus_return_val_if_fail (!message->locked, FALSE);
+
+ if (interface == NULL)
+ {
+ delete_string_field (message, FIELD_INTERFACE);
+ return TRUE;
+ }
+ else
+ {
+ return set_string_field (message,
+ FIELD_INTERFACE,
+ interface);
+ }
+}
/**
- * Sets the message name.
+ * Gets the interface this message is being sent to
+ * (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitted
+ * from (for DBUS_MESSAGE_TYPE_SIGNAL).
+ * The interface name is fully-qualified (namespaced).
*
* @param message the message
- * @param name the name
+ * @returns the message interface (should not be freed)
+ */
+const char*
+dbus_message_get_interface (DBusMessage *message)
+{
+ _dbus_return_val_if_fail (message != NULL, NULL);
+
+ return get_string_field (message, FIELD_INTERFACE, NULL);
+}
+
+/**
+ * Sets the interface member being invoked
+ * (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted
+ * (DBUS_MESSAGE_TYPE_SIGNAL).
+ * The interface name is fully-qualified (namespaced).
+ *
+ * @param message the message
+ * @param member the member
* @returns #FALSE if not enough memory
*/
dbus_bool_t
-dbus_message_set_name (DBusMessage *message,
- const char *name)
+dbus_message_set_member (DBusMessage *message,
+ const char *member)
{
_dbus_return_val_if_fail (message != NULL, FALSE);
_dbus_return_val_if_fail (!message->locked, FALSE);
- if (name == NULL)
+ if (member == NULL)
{
- delete_string_field (message, FIELD_NAME);
+ delete_string_field (message, FIELD_MEMBER);
return TRUE;
}
else
{
return set_string_field (message,
- FIELD_NAME,
- name);
+ FIELD_MEMBER,
+ member);
}
}
/**
- * Gets the name of a message.
+ * Gets the interface member being invoked
+ * (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted
+ * (DBUS_MESSAGE_TYPE_SIGNAL).
+ *
+ * @param message the message
+ * @returns the member name (should not be freed)
+ */
+const char*
+dbus_message_get_member (DBusMessage *message)
+{
+ _dbus_return_val_if_fail (message != NULL, NULL);
+
+ return get_string_field (message, FIELD_MEMBER, NULL);
+}
+
+/**
+ * Sets the name of the error (DBUS_MESSAGE_TYPE_ERROR).
+ * The name is fully-qualified (namespaced).
*
* @param message the message
- * @returns the message name (should not be freed)
+ * @param name the name
+ * @returns #FALSE if not enough memory
+ */
+dbus_bool_t
+dbus_message_set_error_name (DBusMessage *message,
+ const char *error_name)
+{
+ _dbus_return_val_if_fail (message != NULL, FALSE);
+ _dbus_return_val_if_fail (!message->locked, FALSE);
+
+ if (error_name == NULL)
+ {
+ delete_string_field (message, FIELD_ERROR_NAME);
+ return TRUE;
+ }
+ else
+ {
+ return set_string_field (message,
+ FIELD_ERROR_NAME,
+ error_name);
+ }
+}
+
+/**
+ * Gets the error name (DBUS_MESSAGE_TYPE_ERROR only).
+ *
+ * @param message the message
+ * @returns the error name (should not be freed)
*/
const char*
-dbus_message_get_name (DBusMessage *message)
+dbus_message_get_error_name (DBusMessage *message)
{
_dbus_return_val_if_fail (message != NULL, NULL);
- return get_string_field (message, FIELD_NAME, NULL);
+ return get_string_field (message, FIELD_ERROR_NAME, NULL);
}
/**
@@ -3917,27 +4050,54 @@ dbus_message_get_sender (DBusMessage *message)
}
/**
- * Checks whether the message has the given name.
- * If the message has no name or has a different
- * name, returns #FALSE.
+ * Checks whether the message has the given interface field. If the
+ * message has no interface field or has a different one, returns
+ * #FALSE.
+ *
+ * @param message the message
+ * @param interface the name to check (must not be #NULL)
+ *
+ * @returns #TRUE if the message has the given name
+ */
+dbus_bool_t
+dbus_message_has_interface (DBusMessage *message,
+ const char *interface)
+{
+ 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);
+
+ if (n && strcmp (n, interface) == 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+
+/**
+ * Checks whether the message has the given member field. If the
+ * message has no member field or has a different one, returns #FALSE.
*
* @param message the message
- * @param name the name to check (must not be #NULL)
+ * @param member the name to check (must not be #NULL)
*
* @returns #TRUE if the message has the given name
*/
dbus_bool_t
-dbus_message_has_name (DBusMessage *message,
- const char *name)
+dbus_message_has_member (DBusMessage *message,
+ const char *member)
{
const char *n;
_dbus_return_val_if_fail (message != NULL, FALSE);
- _dbus_return_val_if_fail (name != NULL, FALSE);
+ _dbus_return_val_if_fail (member != NULL, FALSE);
- n = dbus_message_get_name (message);
+ n = dbus_message_get_member (message);
- if (n && strcmp (n, name) == 0)
+ if (n && strcmp (n, member) == 0)
return TRUE;
else
return FALSE;
@@ -4034,7 +4194,7 @@ dbus_set_error_from_message (DBusError *error,
DBUS_TYPE_STRING, &str,
DBUS_TYPE_INVALID);
- dbus_set_error (error, dbus_message_get_name (message),
+ dbus_set_error (error, dbus_message_get_error_name (message),
str ? "%s" : NULL, str);
dbus_free (str);
@@ -4216,9 +4376,17 @@ _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
(((dbus_uint32_t)c) << 8) | \
((dbus_uint32_t)d))
-/** DBUS_HEADER_FIELD_NAME packed into a dbus_uint32_t */
-#define DBUS_HEADER_FIELD_NAME_AS_UINT32 \
- FOUR_CHARS_TO_UINT32 ('n', 'a', 'm', 'e')
+/** DBUS_HEADER_FIELD_INTERFACE packed into a dbus_uint32_t */
+#define DBUS_HEADER_FIELD_INTERFACE_AS_UINT32 \
+ FOUR_CHARS_TO_UINT32 ('i', 'f', 'c', 'e')
+
+/** DBUS_HEADER_FIELD_MEMBER packed into a dbus_uint32_t */
+#define DBUS_HEADER_FIELD_MEMBER_AS_UINT32 \
+ FOUR_CHARS_TO_UINT32 ('m', 'e', 'b', 'r')
+
+/** DBUS_HEADER_FIELD_ERROR_NAME packed into a dbus_uint32_t */
+#define DBUS_HEADER_FIELD_ERROR_NAME_AS_UINT32 \
+ FOUR_CHARS_TO_UINT32 ('e', 'r', 'n', 'm')
/** DBUS_HEADER_FIELD_SERVICE packed into a dbus_uint32_t */
#define DBUS_HEADER_FIELD_SERVICE_AS_UINT32 \
@@ -4267,23 +4435,41 @@ decode_string_field (const DBusString *data,
_dbus_string_init_const (&tmp,
_dbus_string_get_const_data (data) + string_data_pos);
- if (field == FIELD_NAME)
+ if (field == FIELD_INTERFACE)
{
- if (!_dbus_string_validate_name (&tmp, 0, _dbus_string_get_length (&tmp)))
+ if (!_dbus_string_validate_interface (&tmp, 0, _dbus_string_get_length (&tmp)))
{
_dbus_verbose ("%s field has invalid content \"%s\"\n",
field_name, _dbus_string_get_const_data (&tmp));
return FALSE;
}
- if (_dbus_string_starts_with_c_str (&tmp,
- DBUS_NAMESPACE_LOCAL_MESSAGE))
+ if (_dbus_string_equal_c_str (&tmp,
+ DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL))
{
- _dbus_verbose ("Message is in the local namespace\n");
+ _dbus_verbose ("Message is on the local interface\n");
return FALSE;
}
}
- else
+ else if (field == FIELD_MEMBER)
+ {
+ if (!_dbus_string_validate_member (&tmp, 0, _dbus_string_get_length (&tmp)))
+ {
+ _dbus_verbose ("%s field has invalid content \"%s\"\n",
+ field_name, _dbus_string_get_const_data (&tmp));
+ return FALSE;
+ }
+ }
+ else if (field == FIELD_ERROR_NAME)
+ {
+ if (!_dbus_string_validate_error_name (&tmp, 0, _dbus_string_get_length (&tmp)))
+ {
+ _dbus_verbose ("%s field has invalid content \"%s\"\n",
+ field_name, _dbus_string_get_const_data (&tmp));
+ return FALSE;
+ }
+ }
+ else if (field == FIELD_SERVICE)
{
if (!_dbus_string_validate_service (&tmp, 0, _dbus_string_get_length (&tmp)))
{
@@ -4292,6 +4478,10 @@ decode_string_field (const DBusString *data,
return FALSE;
}
}
+ else
+ {
+ _dbus_assert_not_reached ("Unknown field\n");
+ }
fields[field].offset = _DBUS_ALIGN_VALUE (pos, 4);
@@ -4307,6 +4497,7 @@ static dbus_bool_t
decode_header_data (const DBusString *data,
int header_len,
int byte_order,
+ int message_type,
HeaderField fields[FIELD_LAST],
int *message_padding)
{
@@ -4375,13 +4566,27 @@ decode_header_data (const DBusString *data,
return FALSE;
break;
- case DBUS_HEADER_FIELD_NAME_AS_UINT32:
+ case DBUS_HEADER_FIELD_INTERFACE_AS_UINT32:
+ if (!decode_string_field (data, fields, pos, type,
+ FIELD_INTERFACE,
+ DBUS_HEADER_FIELD_INTERFACE))
+ return FALSE;
+ break;
+
+ case DBUS_HEADER_FIELD_MEMBER_AS_UINT32:
if (!decode_string_field (data, fields, pos, type,
- FIELD_NAME,
- DBUS_HEADER_FIELD_NAME))
+ FIELD_MEMBER,
+ DBUS_HEADER_FIELD_MEMBER))
return FALSE;
break;
+ case DBUS_HEADER_FIELD_ERROR_NAME_AS_UINT32:
+ if (!decode_string_field (data, fields, pos, type,
+ FIELD_ERROR_NAME,
+ DBUS_HEADER_FIELD_ERROR_NAME))
+ return FALSE;
+ break;
+
case DBUS_HEADER_FIELD_SENDER_AS_UINT32:
if (!decode_string_field (data, fields, pos, type,
FIELD_SENDER,
@@ -4430,12 +4635,37 @@ decode_header_data (const DBusString *data,
}
}
- /* Name field is mandatory */
- if (fields[FIELD_NAME].offset < 0)
+ /* Depending on message type, enforce presence of certain fields. */
+ switch (message_type)
{
- _dbus_verbose ("No %s field provided\n",
- DBUS_HEADER_FIELD_NAME);
- return FALSE;
+ case DBUS_MESSAGE_TYPE_SIGNAL:
+ case DBUS_MESSAGE_TYPE_METHOD_CALL:
+ if (fields[FIELD_INTERFACE].offset < 0)
+ {
+ _dbus_verbose ("No %s field provided\n",
+ DBUS_HEADER_FIELD_INTERFACE);
+ return FALSE;
+ }
+ if (fields[FIELD_MEMBER].offset < 0)
+ {
+ _dbus_verbose ("No %s field provided\n",
+ DBUS_HEADER_FIELD_MEMBER);
+ return FALSE;
+ }
+ break;
+ case DBUS_MESSAGE_TYPE_ERROR:
+ if (fields[FIELD_ERROR_NAME].offset < 0)
+ {
+ _dbus_verbose ("No %s field provided\n",
+ DBUS_HEADER_FIELD_ERROR_NAME);
+ return FALSE;
+ }
+ break;
+ case DBUS_MESSAGE_TYPE_METHOD_RETURN:
+ break;
+ default:
+ /* An unknown type, spec requires us to ignore it */
+ break;
}
if (message_padding)
@@ -4579,7 +4809,8 @@ _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, header_len, byte_order,
+ if (!decode_header_data (&loader->data, message_type,
+ header_len, byte_order,
fields, &header_padding))
{
_dbus_verbose ("Header was invalid\n");
@@ -6010,15 +6241,19 @@ _dbus_message_test (const char *test_data_dir)
_dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
- message = dbus_message_new_method_call ("test.Message", "org.freedesktop.DBus.Test");
- _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.Test"));
+ message = dbus_message_new_method_call ("Foo.TestInterface",
+ "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_message_set_serial (message, 1234);
dbus_message_set_sender (message, "org.foo.bar");
_dbus_assert (dbus_message_has_sender (message, "org.foo.bar"));
dbus_message_set_sender (message, NULL);
_dbus_assert (!dbus_message_has_sender (message, "org.foo.bar"));
_dbus_assert (dbus_message_get_serial (message) == 1234);
- _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.Test"));
+ _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);
@@ -6029,7 +6264,9 @@ _dbus_message_test (const char *test_data_dir)
dbus_message_unref (message);
/* Test the vararg functions */
- message = dbus_message_new_method_call ("test.Message", "org.freedesktop.DBus.Test");
+ message = dbus_message_new_method_call ("Foo.TestInterface",
+ "TestMethod",
+ "org.freedesktop.DBus.TestService");
_dbus_message_set_serial (message, 1);
dbus_message_append_args (message,
DBUS_TYPE_INT32, -0x12345678,
@@ -6087,15 +6324,22 @@ _dbus_message_test (const char *test_data_dir)
verify_test_message (copy);
- name1 = dbus_message_get_name (message);
- name2 = dbus_message_get_name (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 (message);
dbus_message_unref (copy);
-
- message = dbus_message_new_method_call ("test.Message", "org.freedesktop.DBus.Test");
+
+ message = dbus_message_new_method_call ("Foo.TestInterface",
+ "TestMethod",
+ "org.freedesktop.DBus.TestService");
_dbus_message_set_serial (message, 1);
dbus_message_set_reply_serial (message, 0x12345678);
diff --git a/dbus/dbus-message.h b/dbus/dbus-message.h
index 1b61c8d1..dc204585 100644
--- a/dbus/dbus-message.h
+++ b/dbus/dbus-message.h
@@ -58,10 +58,12 @@ struct DBusMessageIter
};
DBusMessage* dbus_message_new (int message_type);
-DBusMessage* dbus_message_new_method_call (const char *name,
+DBusMessage* dbus_message_new_method_call (const char *interface,
+ const char *method,
const char *destination_service);
DBusMessage* dbus_message_new_method_return (DBusMessage *method_call);
-DBusMessage* dbus_message_new_signal (const char *name);
+DBusMessage* dbus_message_new_signal (const char *interface,
+ const char *name);
DBusMessage* dbus_message_new_error (DBusMessage *reply_to,
const char *error_name,
const char *error_message);
@@ -71,9 +73,15 @@ DBusMessage *dbus_message_copy (const DBusMessage *message);
void dbus_message_ref (DBusMessage *message);
void dbus_message_unref (DBusMessage *message);
int dbus_message_get_type (DBusMessage *message);
-dbus_bool_t dbus_message_set_name (DBusMessage *message,
+dbus_bool_t dbus_message_set_interface (DBusMessage *message,
+ const char *interface);
+const char* dbus_message_get_interface (DBusMessage *message);
+dbus_bool_t dbus_message_set_member (DBusMessage *message,
+ const char *member);
+const char* dbus_message_get_member (DBusMessage *message);
+dbus_bool_t dbus_message_set_error_name (DBusMessage *message,
const char *name);
-const char* dbus_message_get_name (DBusMessage *message);
+const char* dbus_message_get_error_name (DBusMessage *message);
dbus_bool_t dbus_message_set_destination (DBusMessage *message,
const char *destination);
const char* dbus_message_get_destination (DBusMessage *message);
@@ -83,7 +91,11 @@ 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_name (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_has_destination (DBusMessage *message,
const char *service);
diff --git a/dbus/dbus-object-registry.c b/dbus/dbus-object-registry.c
index d3d175d8..e5a81315 100644
--- a/dbus/dbus-object-registry.c
+++ b/dbus/dbus-object-registry.c
@@ -63,7 +63,7 @@ struct DBusSignalEntry
dbus_uint16_t *connections; /**< Index of each object connected (can have dups for multiple
* connections)
*/
- char name[4]; /**< Name of signal (actually allocated larger) */
+ char name[4]; /**< Interface of signal, nul, then name of signal (actually allocated larger) */
};
/* 14 bits for object index, 32K objects */
@@ -144,8 +144,8 @@ _dbus_object_registry_new (DBusConnection *connection)
if (interface_table == NULL)
goto oom;
- signal_table = _dbus_hash_table_new (DBUS_HASH_STRING,
- NULL, free_signal_entry);
+ signal_table = _dbus_hash_table_new (DBUS_HASH_TWO_STRINGS,
+ NULL, free_signal_entry);
if (signal_table == NULL)
goto oom;
@@ -431,32 +431,45 @@ object_remove_from_interfaces (DBusObjectRegistry *registry,
static DBusSignalEntry*
lookup_signal (DBusObjectRegistry *registry,
- const char *name,
+ const char *signal_interface,
+ const char *signal_name,
dbus_bool_t create_if_not_found)
{
DBusSignalEntry *entry;
int sz;
- int len;
+ size_t len_interface, len_name;
+ char buf[2 * DBUS_MAXIMUM_NAME_LENGTH + 2];
+
+ /* This is all a little scary and maybe we shouldn't jump
+ * through these hoops just to save some bytes.
+ */
- entry = _dbus_hash_table_lookup_string (registry->signal_table,
- name);
+ len_interface = strlen (signal_interface);
+ len_name = strlen (signal_name);
+
+ _dbus_assert (len_interface + len_name + 2 <= sizeof (buf));
+
+ memcpy (buf, signal_interface, len_interface + 1);
+ memcpy (buf + len_interface + 1, signal_name, len_name + 1);
+
+ entry = _dbus_hash_table_lookup_two_strings (registry->signal_table,
+ buf);
if (entry != NULL || !create_if_not_found)
return entry;
_dbus_assert (create_if_not_found);
- len = strlen (name);
- sz = _DBUS_STRUCT_OFFSET (DBusSignalEntry, name) + len + 1;
+ sz = _DBUS_STRUCT_OFFSET (DBusSignalEntry, name) + len_interface + len_name + 2;
entry = dbus_malloc (sz);
if (entry == NULL)
return NULL;
entry->n_connections = 0;
entry->n_allocated = 0;
entry->connections = NULL;
- memcpy (entry->name, name, len + 1);
+ memcpy (entry->name, buf, len_interface + len_name + 2);
- if (!_dbus_hash_table_insert_string (registry->signal_table,
- entry->name, entry))
+ if (!_dbus_hash_table_insert_two_strings (registry->signal_table,
+ entry->name, entry))
{
dbus_free (entry);
return NULL;
@@ -469,8 +482,8 @@ static void
delete_signal (DBusObjectRegistry *registry,
DBusSignalEntry *entry)
{
- _dbus_hash_table_remove_string (registry->signal_table,
- entry->name);
+ _dbus_hash_table_remove_two_strings (registry->signal_table,
+ entry->name);
}
static dbus_bool_t
@@ -553,11 +566,11 @@ object_remove_from_signals (DBusObjectRegistry *registry,
i = 0;
while (entry->signals[i] != NULL)
{
- DBusSignalEntry *iface = entry->signals[i];
+ DBusSignalEntry *signal = entry->signals[i];
- signal_entry_remove_object (iface, entry->id_index);
- if (iface->n_connections == 0)
- delete_signal (registry, iface);
+ signal_entry_remove_object (signal, entry->id_index);
+ if (signal->n_connections == 0)
+ delete_signal (registry, signal);
++i;
}
}
@@ -573,19 +586,24 @@ object_remove_from_signals (DBusObjectRegistry *registry,
*
* @param registry the object registry
* @param object_id object that would like to see the signal
- * @param signal signal name
+ * @param signal_interface signal interface name
+ * @param signal_name signal member name
*
* @returns #FALSE if no memory
*/
dbus_bool_t
_dbus_object_registry_connect_locked (DBusObjectRegistry *registry,
const DBusObjectID *object_id,
+ const char *signal_interface,
const char *signal_name)
{
DBusSignalEntry **new_signals;
DBusSignalEntry *signal;
DBusObjectEntry *entry;
int i;
+
+ _dbus_assert (signal_interface != NULL);
+ _dbus_assert (signal_name != NULL);
entry = validate_id (registry, object_id);
if (entry == NULL)
@@ -617,7 +635,7 @@ _dbus_object_registry_connect_locked (DBusObjectRegistry *registry,
entry->signals = new_signals;
- signal = lookup_signal (registry, signal_name, TRUE);
+ signal = lookup_signal (registry, signal_interface, signal_name, TRUE);
if (signal == NULL)
goto oom;
@@ -642,30 +660,35 @@ _dbus_object_registry_connect_locked (DBusObjectRegistry *registry,
*
* @param registry the object registry
* @param object_id object that would like to see the signal
- * @param signal signal name
+ * @param signal_interface signal interface
+ * @param signal_name signal name
*/
void
_dbus_object_registry_disconnect_locked (DBusObjectRegistry *registry,
const DBusObjectID *object_id,
+ const char *signal_interface,
const char *signal_name)
{
DBusObjectEntry *entry;
DBusSignalEntry *signal;
+
+ _dbus_assert (signal_interface != NULL);
+ _dbus_assert (signal_name != NULL);
entry = validate_id (registry, object_id);
if (entry == NULL)
{
- _dbus_warn ("Tried to disconnect signal \"%s\" from a nonexistent D-BUS object ID\n",
- signal_name);
+ _dbus_warn ("Tried to disconnect signal \"%s\"::\"%s\" from a nonexistent D-BUS object ID\n",
+ signal_interface, signal_name);
return;
}
- signal = lookup_signal (registry, signal_name, FALSE);
+ signal = lookup_signal (registry, signal_interface, signal_name, FALSE);
if (signal == NULL)
{
- _dbus_warn ("Tried to disconnect signal \"%s\" but no such signal is connected\n",
- signal_name);
+ _dbus_warn ("Tried to disconnect signal \"%s\"::\"%s\" but no such signal is connected\n",
+ signal_interface, signal_name);
return;
}
@@ -695,7 +718,7 @@ handle_method_call_and_unlock (DBusObjectRegistry *registry,
* it to the first object that supports the given interface.
*/
iface_entry = lookup_interface (registry,
- dbus_message_get_name (message),
+ dbus_message_get_interface (message),
FALSE);
if (iface_entry == NULL)
@@ -750,7 +773,8 @@ handle_signal_and_unlock (DBusObjectRegistry *registry,
_dbus_assert (message != NULL);
signal_entry = lookup_signal (registry,
- dbus_message_get_name (message),
+ dbus_message_get_interface (message),
+ dbus_message_get_member (message),
FALSE);
if (signal_entry == NULL)
@@ -1291,7 +1315,8 @@ add_and_remove_objects (DBusObjectRegistry *registry)
++i;
}
- message = dbus_message_new_method_call ("org.freedesktop.Test.Foo", NULL);
+ message = dbus_message_new_method_call ("org.freedesktop.Test.Foo",
+ "Bar", NULL);
if (message != NULL)
{
if (_dbus_object_registry_handle_and_unlock (registry, message) !=
@@ -1300,7 +1325,8 @@ add_and_remove_objects (DBusObjectRegistry *registry)
dbus_message_unref (message);
}
- message = dbus_message_new_method_call ("org.freedesktop.Test.Blah", NULL);
+ message = dbus_message_new_method_call ("org.freedesktop.Test.Blah",
+ "Baz", NULL);
if (message != NULL)
{
if (_dbus_object_registry_handle_and_unlock (registry, message) !=
@@ -1309,7 +1335,8 @@ add_and_remove_objects (DBusObjectRegistry *registry)
dbus_message_unref (message);
}
- message = dbus_message_new_method_call ("org.freedesktop.Test.NotRegisteredIface", NULL);
+ message = dbus_message_new_method_call ("org.freedesktop.Test.NotRegisteredIface",
+ "Boo", NULL);
if (message != NULL)
{
if (_dbus_object_registry_handle_and_unlock (registry, message) !=
diff --git a/dbus/dbus-object-registry.h b/dbus/dbus-object-registry.h
index bcbd0f84..29c92b9c 100644
--- a/dbus/dbus-object-registry.h
+++ b/dbus/dbus-object-registry.h
@@ -45,10 +45,12 @@ DBusHandlerResult _dbus_object_registry_handle_and_unlock (DBusObjectRegistry
void _dbus_object_registry_free_all_unlocked (DBusObjectRegistry *registry);
dbus_bool_t _dbus_object_registry_connect_locked (DBusObjectRegistry *registry,
const DBusObjectID *object_id,
- const char *signal);
+ const char *signal_interface,
+ const char *signal_name);
void _dbus_object_registry_disconnect_locked (DBusObjectRegistry *registry,
const DBusObjectID *object_id,
- const char *signal);
+ const char *signal_interface,
+ const char *signal_name);
DBUS_END_DECLS;
diff --git a/dbus/dbus-protocol.h b/dbus/dbus-protocol.h
index e027cf56..a1f4a722 100644
--- a/dbus/dbus-protocol.h
+++ b/dbus/dbus-protocol.h
@@ -57,7 +57,7 @@ extern "C" {
#define DBUS_TYPE_LAST DBUS_TYPE_OBJECT_ID
-/* Max length in bytes of a service or message name */
+/* Max length in bytes of a service or interface or member name */
#define DBUS_MAXIMUM_NAME_LENGTH 256
/* Types of message */
@@ -71,14 +71,16 @@ extern "C" {
#define DBUS_HEADER_FLAG_NO_REPLY_EXPECTED 0x1
/* Header fields */
-#define DBUS_HEADER_FIELD_NAME "name"
-#define DBUS_HEADER_FIELD_SERVICE "srvc"
-#define DBUS_HEADER_FIELD_REPLY "rply"
-#define DBUS_HEADER_FIELD_SENDER "sndr"
+#define DBUS_HEADER_FIELD_INTERFACE "ifce"
+#define DBUS_HEADER_FIELD_MEMBER "mebr"
+#define DBUS_HEADER_FIELD_ERROR_NAME "ernm"
+#define DBUS_HEADER_FIELD_SERVICE "srvc"
+#define DBUS_HEADER_FIELD_REPLY "rply"
+#define DBUS_HEADER_FIELD_SENDER "sndr"
/* Services */
-#define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
-#define DBUS_SERVICE_BROADCAST "org.freedesktop.DBus.Broadcast"
+#define DBUS_SERVICE_ORG_FREEDESKTOP_DBUS "org.freedesktop.DBus"
+#define DBUS_SERVICE_ORG_FREEDESKTOP_BROADCAST "org.freedesktop.Broadcast"
/* Service owner flags */
#define DBUS_SERVICE_FLAG_PROHIBIT_REPLACEMENT 0x1
@@ -94,23 +96,30 @@ extern "C" {
#define DBUS_ACTIVATION_REPLY_ACTIVATED 0x0
#define DBUS_ACTIVATION_REPLY_ALREADY_ACTIVE 0x1
-/* Messages */
-#define DBUS_MESSAGE_ACTIVATE_SERVICE "org.freedesktop.DBus.ActivateService"
-#define DBUS_MESSAGE_SERVICE_EXISTS "org.freedesktop.DBus.ServiceExists"
-#define DBUS_MESSAGE_HELLO "org.freedesktop.DBus.Hello"
-#define DBUS_MESSAGE_LIST_SERVICES "org.freedesktop.DBus.ListServices"
-#define DBUS_MESSAGE_ACQUIRE_SERVICE "org.freedesktop.DBus.AcquireService"
-#define DBUS_MESSAGE_SERVICE_ACQUIRED "org.freedesktop.DBus.ServiceAcquired"
-#define DBUS_MESSAGE_SERVICE_CREATED "org.freedesktop.DBus.ServiceCreated"
-#define DBUS_MESSAGE_SERVICE_DELETED "org.freedesktop.DBus.ServiceDeleted"
-#define DBUS_MESSAGE_SERVICE_LOST "org.freedesktop.DBus.ServiceLost"
-
-
-/* This namespace is reserved for locally-synthesized messages, you can't
- * send messages that have this namespace.
+/* Interfaces, these #define don't do much other than
+ * catch typos at compile time
*/
-#define DBUS_NAMESPACE_LOCAL_MESSAGE "org.freedesktop.Local."
-#define DBUS_MESSAGE_LOCAL_DISCONNECT DBUS_NAMESPACE_LOCAL_MESSAGE"Disconnect"
+#define DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS "org.freedesktop.DBus"
+
+/* This is a special interface whose methods can only be invoked
+ * by the local implementation (messages from remote apps aren't
+ * 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 f4f7a2ad..848135fc 100644
--- a/dbus/dbus-string.c
+++ b/dbus/dbus-string.c
@@ -2846,7 +2846,7 @@ _dbus_string_validate_nul (const DBusString *str,
}
/**
- * Checks that the given range of the string is a valid message name
+ * Checks that the given range of the string is a valid interface name
* in the D-BUS protocol. This includes a length restriction, etc.,
* see the specification. It does not validate UTF-8, that has to be
* done separately for now.
@@ -2860,9 +2860,9 @@ _dbus_string_validate_nul (const DBusString *str,
* @returns #TRUE if the byte range exists and is a valid name
*/
dbus_bool_t
-_dbus_string_validate_name (const DBusString *str,
- int start,
- int len)
+_dbus_string_validate_interface (const DBusString *str,
+ int start,
+ int len)
{
const unsigned char *s;
const unsigned char *end;
@@ -2902,6 +2902,86 @@ _dbus_string_validate_name (const DBusString *str,
return TRUE;
}
+/**
+ * Checks that the given range of the string is a valid member name
+ * in the D-BUS protocol. This includes a length restriction, etc.,
+ * see the specification. It does not validate UTF-8, that has to be
+ * done separately for now.
+ *
+ * @todo this is inconsistent with most of DBusString in that
+ * it allows a start,len range that isn't in the string.
+ *
+ * @param str the string
+ * @param start first byte index to check
+ * @param len number of bytes to check
+ * @returns #TRUE if the byte range exists and is a valid name
+ */
+dbus_bool_t
+_dbus_string_validate_member (const DBusString *str,
+ int start,
+ int len)
+{
+ const unsigned char *s;
+ const unsigned char *end;
+ dbus_bool_t saw_dot;
+
+ DBUS_CONST_STRING_PREAMBLE (str);
+ _dbus_assert (start >= 0);
+ _dbus_assert (len >= 0);
+ _dbus_assert (start <= real->len);
+
+ if (len > real->len - start)
+ return FALSE;
+
+ if (len > DBUS_MAXIMUM_NAME_LENGTH)
+ return FALSE;
+
+ if (len == 0)
+ return FALSE;
+
+ saw_dot = FALSE;
+ s = real->str + start;
+ end = s + len;
+ while (s != end)
+ {
+ if (*s == '.')
+ {
+ saw_dot = TRUE;
+ break;
+ }
+
+ ++s;
+ }
+
+ /* No dot allowed in member names */
+ if (saw_dot)
+ return FALSE;
+
+ return TRUE;
+}
+
+/**
+ * Checks that the given range of the string is a valid error name
+ * in the D-BUS protocol. This includes a length restriction, etc.,
+ * see the specification. It does not validate UTF-8, that has to be
+ * done separately for now.
+ *
+ * @todo this is inconsistent with most of DBusString in that
+ * it allows a start,len range that isn't in the string.
+ *
+ * @param str the string
+ * @param start first byte index to check
+ * @param len number of bytes to check
+ * @returns #TRUE if the byte range exists and is a valid name
+ */
+dbus_bool_t
+_dbus_string_validate_error_name (const DBusString *str,
+ int start,
+ int len)
+{
+ /* Same restrictions as interface name at the moment */
+ return _dbus_string_validate_interface (str, start, len);
+}
/**
* Checks that the given range of the string is a valid service name
diff --git a/dbus/dbus-string.h b/dbus/dbus-string.h
index 732359a0..6f164be6 100644
--- a/dbus/dbus-string.h
+++ b/dbus/dbus-string.h
@@ -223,7 +223,13 @@ dbus_bool_t _dbus_string_validate_utf8 (const DBusString *str,
dbus_bool_t _dbus_string_validate_nul (const DBusString *str,
int start,
int len);
-dbus_bool_t _dbus_string_validate_name (const DBusString *str,
+dbus_bool_t _dbus_string_validate_interface (const DBusString *str,
+ int start,
+ int len);
+dbus_bool_t _dbus_string_validate_member (const DBusString *str,
+ int start,
+ int len);
+dbus_bool_t _dbus_string_validate_error_name (const DBusString *str,
int start,
int len);
dbus_bool_t _dbus_string_validate_service (const DBusString *str,