1+ // Source: https://github.com/diwic/dbus-rs/blob/master/dbus/examples/monitor.rs
2+
3+ use std:: time:: Duration ;
4+
5+ use dbus:: blocking:: Connection ;
6+ use dbus:: channel:: MatchingReceiver ;
7+ use dbus:: message:: MatchRule ;
8+ use dbus:: Message ;
9+
10+ // This programs implements the equivalent of running the "dbus-monitor" tool
11+ fn main ( ) {
12+ // Very simple argument parsing.
13+ let use_system_bus = std:: env:: args ( ) . into_iter ( ) . any ( |a| a == "--system" ) ;
14+
15+ // First open up a connection to the desired bus.
16+ let conn = ( if use_system_bus { Connection :: new_system ( ) } else { Connection :: new_session ( ) } ) . expect ( "D-Bus connection failed" ) ;
17+
18+ // Second create a rule to match messages we want to receive; in this example we add no
19+ // further requirements, so all messages will match
20+ let rule = MatchRule :: new ( ) ;
21+
22+ // Try matching using new scheme
23+ let proxy = conn. with_proxy ( "org.freedesktop.DBus" , "/org/freedesktop/DBus" , Duration :: from_millis ( 5000 ) ) ;
24+ let result: Result < ( ) , dbus:: Error > =
25+ proxy. method_call ( "org.freedesktop.DBus.Monitoring" , "BecomeMonitor" , ( vec ! [ rule. match_str( ) ] , 0u32 ) ) ;
26+
27+ match result {
28+ // BecomeMonitor was successful, start listening for messages
29+ Ok ( _) => {
30+ conn. start_receive (
31+ rule,
32+ Box :: new ( |msg, _| {
33+ handle_message ( & msg) ;
34+ true
35+ } ) ,
36+ ) ;
37+ }
38+ // BecomeMonitor failed, fallback to using the old scheme
39+ Err ( e) => {
40+ eprintln ! ( "Failed to BecomeMonitor: '{}', falling back to eavesdrop" , e) ;
41+
42+ // First, we'll try "eavesdrop", which as the name implies lets us receive
43+ // *all* messages, not just ours.
44+ let rule_with_eavesdrop = {
45+ let mut rule = rule. clone ( ) ;
46+ rule. eavesdrop = true ;
47+ rule
48+ } ;
49+
50+ let result = conn. add_match ( rule_with_eavesdrop, |_: ( ) , _, msg| {
51+ handle_message ( & msg) ;
52+ true
53+ } ) ;
54+
55+ match result {
56+ Ok ( _) => {
57+ // success, we're now listening
58+ }
59+ // This can sometimes fail, for example when listening to the system bus as a non-root user.
60+ // So, just like `dbus-monitor`, we attempt to fallback without `eavesdrop=true`:
61+ Err ( e) => {
62+ eprintln ! ( "Failed to eavesdrop: '{}', trying without it" , e) ;
63+ conn. add_match ( rule, |_: ( ) , _, msg| {
64+ handle_message ( & msg) ;
65+ true
66+ } )
67+ . expect ( "add_match failed" ) ;
68+ }
69+ }
70+ }
71+ }
72+
73+ // Loop and print out all messages received (using handle_message()) as they come.
74+ // Some can be quite large, e.g. if they contain embedded images..
75+ loop {
76+ conn. process ( Duration :: from_millis ( 1000 ) ) . unwrap ( ) ;
77+ }
78+ }
79+
80+ fn handle_message ( msg : & Message ) {
81+ println ! ( "Got message: {:?}" , msg) ;
82+ }
0 commit comments