summaryrefslogtreecommitdiff
path: root/tools/dbus-monitor.c
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2015-02-02 20:08:07 +0000
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2015-02-04 17:15:31 +0000
commit8a621b8f77706d2ce4feb7b0ffa946b4b95326c8 (patch)
tree3179ee501a8065f22051568b96e0e46e4875b31a /tools/dbus-monitor.c
parent81e9e4e07806fe69738efb928106d8e58c4c8883 (diff)
downloaddbus-8a621b8f77706d2ce4feb7b0ffa946b4b95326c8.tar.gz
dbus-monitor: add support for using BecomeMonitor to be a read-only monitor
Move the dbus_connection_add_filter() call further up as a precaution, because it isn't safe for a monitor to not have a filter that swallows all messages. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=46787 Reviewed-by: Philip Withnall <philip.withnall@collabora.co.uk>
Diffstat (limited to 'tools/dbus-monitor.c')
-rw-r--r--tools/dbus-monitor.c84
1 files changed, 75 insertions, 9 deletions
diff --git a/tools/dbus-monitor.c b/tools/dbus-monitor.c
index c15589a4..5792112c 100644
--- a/tools/dbus-monitor.c
+++ b/tools/dbus-monitor.c
@@ -90,10 +90,9 @@ monitor_filter_func (DBusConnection *connection,
DBUS_INTERFACE_LOCAL,
"Disconnected"))
exit (0);
-
- /* Conceptually we want this to be
- * DBUS_HANDLER_RESULT_NOT_YET_HANDLED, but this raises
- * some problems. See bug 1719.
+
+ /* Monitors must not allow libdbus to reply to messages, so we eat
+ * the message. See bug 1719.
*/
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -236,6 +235,66 @@ only_one_type (dbus_bool_t *seen_bus_type,
}
}
+static dbus_bool_t
+become_monitor (DBusConnection *connection,
+ int numFilters,
+ const char * const *filters)
+{
+ DBusError error = DBUS_ERROR_INIT;
+ DBusMessage *m;
+ DBusMessage *r;
+ int i;
+ dbus_uint32_t zero = 0;
+ DBusMessageIter appender, array_appender;
+
+ m = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS, DBUS_INTERFACE_MONITORING, "BecomeMonitor");
+
+ if (m == NULL)
+ tool_oom ("becoming a monitor");
+
+ dbus_message_iter_init_append (m, &appender);
+
+ if (!dbus_message_iter_open_container (&appender, DBUS_TYPE_ARRAY, "s",
+ &array_appender))
+ tool_oom ("opening string array");
+
+ for (i = 0; i < numFilters; i++)
+ {
+ if (!dbus_message_iter_append_basic (&array_appender, DBUS_TYPE_STRING,
+ &filters[i]))
+ tool_oom ("adding filter to array");
+ }
+
+ if (!dbus_message_iter_close_container (&appender, &array_appender) ||
+ !dbus_message_iter_append_basic (&appender, DBUS_TYPE_UINT32, &zero))
+ tool_oom ("finishing arguments");
+
+ r = dbus_connection_send_with_reply_and_block (connection, m, -1, &error);
+
+ if (r != NULL)
+ {
+ dbus_message_unref (r);
+ }
+ else if (dbus_error_has_name (&error, DBUS_ERROR_UNKNOWN_INTERFACE))
+ {
+ fprintf (stderr, "dbus-monitor: unable to enable new-style monitoring, "
+ "your dbus-daemon is too old. Falling back to eavesdropping.\n");
+ dbus_error_free (&error);
+ }
+ else
+ {
+ fprintf (stderr, "dbus-monitor: unable to enable new-style monitoring: "
+ "%s: \"%s\". Falling back to eavesdropping.\n",
+ error.name, error.message);
+ dbus_error_free (&error);
+ }
+
+ dbus_message_unref (m);
+
+ return (r != NULL);
+}
+
int
main (int argc, char *argv[])
{
@@ -359,7 +418,18 @@ main (int argc, char *argv[])
exit (1);
}
- if (numFilters)
+ if (!dbus_connection_add_filter (connection, filter_func, NULL, NULL))
+ {
+ fprintf (stderr, "Couldn't add filter!\n");
+ exit (1);
+ }
+
+ if (become_monitor (connection, numFilters,
+ (const char * const *) filters))
+ {
+ /* no more preparation needed */
+ }
+ else if (numFilters)
{
size_t offset = 0;
for (i = 0; i < j; i++)
@@ -402,10 +472,6 @@ main (int argc, char *argv[])
}
}
- if (!dbus_connection_add_filter (connection, filter_func, NULL, NULL)) {
- fprintf (stderr, "Couldn't add filter!\n");
- exit (1);
- }
while (dbus_connection_read_write_dispatch(connection, -1))
;