Commit 7793e774 authored by Alban Crequy's avatar Alban Crequy Committed by Simon McVittie

Implement GetAllMatchRules on the Stats interface

Usage:

$ dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus \
      org.freedesktop.DBus.Debug.Stats.GetAllMatchRules
method return sender=org.freedesktop.DBus -> dest=:1.13 reply_serial=2
   array [
      dict entry(
         string ":1.4"
         array [
         ]
      )
      dict entry(
         string ":1.9"
         array [
            string "type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged'"
         ]
      )
      dict entry(
         string ":1.11"
         array [
            string "eavesdrop='true'"
         ]
      )
   ]

Bug: https://bugs.freedesktop.org/show_bug.cgi?id=24307Reviewed-by: default avatarSimon McVittie <simon.mcvittie@collabora.co.uk>
parent 15f9e7bb
......@@ -1789,6 +1789,7 @@ static const MessageHandler introspectable_message_handlers[] = {
static const MessageHandler stats_message_handlers[] = {
{ "GetStats", "", "a{sv}", bus_stats_handle_get_stats },
{ "GetConnectionStats", "s", "a{sv}", bus_stats_handle_get_connection_stats },
{ "GetAllMatchRules", "", "a{sas}", bus_stats_handle_get_all_match_rules },
{ NULL, NULL, NULL, NULL }
};
#endif
......
......@@ -118,7 +118,7 @@ bus_match_rule_unref (BusMatchRule *rule)
}
}
#ifdef DBUS_ENABLE_VERBOSE_MODE
#if defined(DBUS_ENABLE_VERBOSE_MODE) || defined(DBUS_ENABLE_STATS)
/* Note this function does not do escaping, so it's only
* good for debug spew at the moment
*/
......@@ -279,7 +279,7 @@ match_rule_to_string (BusMatchRule *rule)
return s;
}
}
#endif /* DBUS_ENABLE_VERBOSE_MODE */
#endif /* defined(DBUS_ENABLE_VERBOSE_MODE) || defined(DBUS_ENABLE_STATS) */
dbus_bool_t
bus_match_rule_set_message_type (BusMatchRule *rule,
......@@ -1141,6 +1141,74 @@ struct BusMatchmaker
RulePool rules_by_type[DBUS_NUM_MESSAGE_TYPES];
};
#ifdef DBUS_ENABLE_STATS
dbus_bool_t
bus_match_rule_dump (BusMatchmaker *matchmaker,
DBusConnection *conn_filter,
DBusMessageIter *arr_iter)
{
int i;
for (i = 0 ; i < DBUS_NUM_MESSAGE_TYPES ; i++)
{
DBusHashIter iter;
DBusList **list;
DBusList *link;
_dbus_hash_iter_init (matchmaker->rules_by_type[i].rules_by_iface, &iter);
while (_dbus_hash_iter_next (&iter))
{
list = _dbus_hash_iter_get_value (&iter);
for (link = _dbus_list_get_first_link (list);
link != NULL;
link = _dbus_list_get_next_link (list, link))
{
BusMatchRule *rule = link->data;
if (rule->matches_go_to == conn_filter)
{
char *s = match_rule_to_string (rule);
if (s == NULL)
return FALSE;
if (!dbus_message_iter_append_basic (arr_iter, DBUS_TYPE_STRING, &s))
{
dbus_free (s);
return FALSE;
}
dbus_free (s);
}
}
}
list = &matchmaker->rules_by_type[i].rules_without_iface;
for (link = _dbus_list_get_first_link (list);
link != NULL;
link = _dbus_list_get_next_link (list, link))
{
BusMatchRule *rule = link->data;
if (rule->matches_go_to == conn_filter)
{
char *s = match_rule_to_string (rule);
if (s == NULL)
return FALSE;
if (!dbus_message_iter_append_basic (arr_iter, DBUS_TYPE_STRING, &s))
{
dbus_free (s);
return FALSE;
}
dbus_free (s);
}
}
}
return TRUE;
}
#endif
static void
rule_list_free (DBusList **rules)
{
......
......@@ -77,6 +77,12 @@ BusMatchRule* bus_match_rule_parse (DBusConnection *matches_go_to,
const DBusString *rule_text,
DBusError *error);
#ifdef DBUS_ENABLE_STATS
dbus_bool_t bus_match_rule_dump (BusMatchmaker *matchmaker,
DBusConnection *conn_filter,
DBusMessageIter *arr_iter);
#endif
BusMatchmaker* bus_matchmaker_new (void);
BusMatchmaker* bus_matchmaker_ref (BusMatchmaker *matchmaker);
void bus_matchmaker_unref (BusMatchmaker *matchmaker);
......
......@@ -30,6 +30,7 @@
#include "connection.h"
#include "services.h"
#include "signals.h"
#include "utils.h"
#ifdef DBUS_ENABLE_STATS
......@@ -217,4 +218,120 @@ oom:
return FALSE;
}
dbus_bool_t
bus_stats_handle_get_all_match_rules (DBusConnection *caller_connection,
BusTransaction *transaction,
DBusMessage *message,
DBusError *error)
{
BusContext *context;
DBusString bus_name_str;
DBusMessage *reply = NULL;
DBusMessageIter iter, hash_iter, entry_iter, arr_iter;
BusRegistry *registry;
char **services = NULL;
int services_len;
DBusConnection *conn_filter = NULL;
BusMatchmaker *matchmaker;
int i;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
registry = bus_connection_get_registry (caller_connection);
context = bus_transaction_get_context (transaction);
matchmaker = bus_context_get_matchmaker (context);
if (!bus_registry_list_services (registry, &services, &services_len))
return FALSE;
reply = dbus_message_new_method_return (message);
if (reply == NULL)
goto oom;
dbus_message_iter_init_append (reply, &iter);
if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "{sas}",
&hash_iter))
goto oom;
for (i = 0 ; i < services_len ; i++)
{
BusService *service;
/* To avoid duplicate entries, only look for unique names */
if (services[i][0] != ':')
continue;
_dbus_string_init_const (&bus_name_str, services[i]);
service = bus_registry_lookup (registry, &bus_name_str);
_dbus_assert (service != NULL);
conn_filter = bus_service_get_primary_owners_connection (service);
_dbus_assert (conn_filter != NULL);
if (!dbus_message_iter_open_container (&hash_iter, DBUS_TYPE_DICT_ENTRY, NULL,
&entry_iter))
{
dbus_message_iter_abandon_container (&iter, &hash_iter);
goto oom;
}
if (!dbus_message_iter_append_basic (&entry_iter, DBUS_TYPE_STRING, &services[i]))
{
dbus_message_iter_abandon_container (&hash_iter, &entry_iter);
dbus_message_iter_abandon_container (&iter, &hash_iter);
goto oom;
}
if (!dbus_message_iter_open_container (&entry_iter, DBUS_TYPE_ARRAY, "s",
&arr_iter))
{
dbus_message_iter_abandon_container (&hash_iter, &entry_iter);
dbus_message_iter_abandon_container (&iter, &hash_iter);
goto oom;
}
if (!bus_match_rule_dump (matchmaker, conn_filter, &arr_iter))
{
dbus_message_iter_abandon_container (&entry_iter, &arr_iter);
dbus_message_iter_abandon_container (&hash_iter, &entry_iter);
dbus_message_iter_abandon_container (&iter, &hash_iter);
goto oom;
}
if (!dbus_message_iter_close_container (&entry_iter, &arr_iter))
{
dbus_message_iter_abandon_container (&hash_iter, &entry_iter);
dbus_message_iter_abandon_container (&iter, &hash_iter);
goto oom;
}
if (!dbus_message_iter_close_container (&hash_iter, &entry_iter))
{
dbus_message_iter_abandon_container (&iter, &hash_iter);
goto oom;
}
}
if (!dbus_message_iter_close_container (&iter, &hash_iter))
goto oom;
if (!bus_transaction_send_from_driver (transaction, caller_connection,
reply))
goto oom;
dbus_message_unref (reply);
dbus_free_string_array (services);
return TRUE;
oom:
if (reply != NULL)
dbus_message_unref (reply);
dbus_free_string_array (services);
BUS_SET_OOM (error);
return FALSE;
}
#endif
......@@ -35,4 +35,9 @@ dbus_bool_t bus_stats_handle_get_connection_stats (DBusConnection *connection,
DBusMessage *message,
DBusError *error);
dbus_bool_t bus_stats_handle_get_all_match_rules (DBusConnection *caller_connection,
BusTransaction *transaction,
DBusMessage *message,
DBusError *error);
#endif /* multiple-inclusion guard */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment