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