ruby-dbus 0.7.2 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/NEWS +19 -0
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/dbus.rb +1 -0
- data/lib/dbus/auth.rb +9 -2
- data/lib/dbus/bus.rb +12 -3
- data/lib/dbus/introspect.rb +0 -79
- data/lib/dbus/marshall.rb +2 -2
- data/lib/dbus/message.rb +2 -2
- data/lib/dbus/type.rb +4 -1
- data/lib/dbus/xml.rb +156 -0
- data/test/bus_and_xml_backend_test.rb +42 -0
- data/test/server_test.rb +1 -1
- data/test/signal_test.rb +1 -0
- metadata +7 -5
data/NEWS
CHANGED
@@ -5,6 +5,25 @@ Note about bug numbers:
|
|
5
5
|
Issue#1 - http://github.com/mvidner/ruby-dbus/issues#issue/1
|
6
6
|
bnc#1 - https://bugzilla.novell.com/show_bug.cgi?id=1
|
7
7
|
|
8
|
+
== Ruby D-Bus 0.8.0 - 2012-09-20
|
9
|
+
|
10
|
+
Features:
|
11
|
+
* Add Anonymous authentication (Issue#27, by Walter Brebels).
|
12
|
+
* Use Nokogiri for XML parsing when available (Issue#24, by Geoff Youngs).
|
13
|
+
|
14
|
+
Bug fixes:
|
15
|
+
* Use SCM_CREDS authentication only on FreeBSD, not on OpenBSD (Issue#21,
|
16
|
+
reported by Adde Nilsson).
|
17
|
+
* Recognize signature "h" (UNIX_FD) used eg. by Upstart (Issue#23,
|
18
|
+
by Bernd Ahlers).
|
19
|
+
* Find the session bus also via launchd, on OS X (Issue#20, reported
|
20
|
+
by Paul Sturgess).
|
21
|
+
|
22
|
+
Other:
|
23
|
+
* Now doing continuous integration with Travis:
|
24
|
+
http://travis-ci.org/#!/mvidner/ruby-dbus
|
25
|
+
|
26
|
+
|
8
27
|
== Ruby D-Bus 0.7.2 - 2012-04-05
|
9
28
|
|
10
29
|
A brown-paper-bag release.
|
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.8.0
|
data/lib/dbus.rb
CHANGED
data/lib/dbus/auth.rb
CHANGED
@@ -23,6 +23,13 @@ module DBus
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
+
# = Anonymous authentication class
|
27
|
+
class Anonymous < Authenticator
|
28
|
+
def authenticate
|
29
|
+
'527562792044427573' # Hex encoded version of "Ruby DBus"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
26
33
|
# = External authentication class
|
27
34
|
#
|
28
35
|
# Class for 'external' type authentication.
|
@@ -115,12 +122,12 @@ module DBus
|
|
115
122
|
def initialize(socket)
|
116
123
|
@socket = socket
|
117
124
|
@state = nil
|
118
|
-
@auth_list = [External,DBusCookieSHA1]
|
125
|
+
@auth_list = [External,DBusCookieSHA1,Anonymous]
|
119
126
|
end
|
120
127
|
|
121
128
|
# Start the authentication process.
|
122
129
|
def authenticate
|
123
|
-
if (RbConfig::CONFIG["target_os"] =~ /
|
130
|
+
if (RbConfig::CONFIG["target_os"] =~ /freebsd/)
|
124
131
|
@socket.sendmsg(0.chr, 0, nil, [:SOCKET, :SCM_CREDS, ""])
|
125
132
|
else
|
126
133
|
@socket.write(0.chr)
|
data/lib/dbus/bus.rb
CHANGED
@@ -225,6 +225,8 @@ module DBus
|
|
225
225
|
connect_to_unix kv_hash
|
226
226
|
when "tcp"
|
227
227
|
connect_to_tcp kv_hash
|
228
|
+
when "launchd"
|
229
|
+
connect_to_launchd kv_hash
|
228
230
|
else
|
229
231
|
# ignore, report?
|
230
232
|
end
|
@@ -271,6 +273,12 @@ module DBus
|
|
271
273
|
init_connection
|
272
274
|
end
|
273
275
|
|
276
|
+
def connect_to_launchd(params)
|
277
|
+
socket_var = params['env']
|
278
|
+
socket = `launchctl getenv #{socket_var}`.chomp
|
279
|
+
connect_to_unix 'path' => socket
|
280
|
+
end
|
281
|
+
|
274
282
|
# Send the buffer _buf_ to the bus using Connection#writel.
|
275
283
|
def send(buf)
|
276
284
|
@socket.write(buf) unless @socket.nil?
|
@@ -510,7 +518,7 @@ module DBus
|
|
510
518
|
begin
|
511
519
|
ret, size = Message.new.unmarshall_buffer(@buffer)
|
512
520
|
@buffer.slice!(0, size)
|
513
|
-
rescue IncompleteBufferException
|
521
|
+
rescue IncompleteBufferException
|
514
522
|
# fall through, let ret be null
|
515
523
|
end
|
516
524
|
ret
|
@@ -531,7 +539,6 @@ module DBus
|
|
531
539
|
# Update the buffer and retrieve all messages using Connection#messages.
|
532
540
|
# Return the messages.
|
533
541
|
def poll_messages
|
534
|
-
ret = nil
|
535
542
|
r, d, d = IO.select([@socket], nil, nil, 0)
|
536
543
|
if r and r.size > 0
|
537
544
|
update_buffer
|
@@ -719,7 +726,7 @@ module DBus
|
|
719
726
|
class ASessionBus < Connection
|
720
727
|
# Get the the default session bus.
|
721
728
|
def initialize
|
722
|
-
super(ENV["DBUS_SESSION_BUS_ADDRESS"] || address_from_file)
|
729
|
+
super(ENV["DBUS_SESSION_BUS_ADDRESS"] || address_from_file || "launchd:env=DBUS_LAUNCHD_SESSION_BUS_SOCKET")
|
723
730
|
connect
|
724
731
|
send_hello
|
725
732
|
end
|
@@ -734,6 +741,8 @@ module DBus
|
|
734
741
|
return $1
|
735
742
|
end
|
736
743
|
end
|
744
|
+
rescue Errno::ENOENT
|
745
|
+
nil
|
737
746
|
end
|
738
747
|
end
|
739
748
|
|
data/lib/dbus/introspect.rb
CHANGED
@@ -8,9 +8,6 @@
|
|
8
8
|
# License, version 2.1 as published by the Free Software Foundation.
|
9
9
|
# See the file "COPYING" for the exact licensing terms.
|
10
10
|
|
11
|
-
# TODO check if it is slow, make replaceable
|
12
|
-
require 'rexml/document'
|
13
|
-
|
14
11
|
module DBus
|
15
12
|
# Regular expressions that should match all method names.
|
16
13
|
MethodSignalRE = /^[A-Za-z][A-Za-z0-9_]*$/
|
@@ -219,82 +216,6 @@ module DBus
|
|
219
216
|
end
|
220
217
|
end # class Signal
|
221
218
|
|
222
|
-
# = D-Bus introspect XML parser class
|
223
|
-
#
|
224
|
-
# This class parses introspection XML of an object and constructs a tree
|
225
|
-
# of Node, Interface, Method, Signal instances.
|
226
|
-
class IntrospectXMLParser
|
227
|
-
# Creates a new parser for XML data in string _xml_.
|
228
|
-
def initialize(xml)
|
229
|
-
@xml = xml
|
230
|
-
end
|
231
|
-
|
232
|
-
# return the names of direct subnodes
|
233
|
-
def parse_subnodes
|
234
|
-
subnodes = Array.new
|
235
|
-
d = REXML::Document.new(@xml)
|
236
|
-
d.elements.each("node/node") do |e|
|
237
|
-
subnodes << e.attributes["name"]
|
238
|
-
end
|
239
|
-
subnodes
|
240
|
-
end
|
241
|
-
|
242
|
-
# return a pair: [list of Interfaces, list of direct subnode names]
|
243
|
-
def parse
|
244
|
-
interfaces = Array.new
|
245
|
-
subnodes = Array.new
|
246
|
-
t = Time.now
|
247
|
-
d = REXML::Document.new(@xml)
|
248
|
-
d.elements.each("node/node") do |e|
|
249
|
-
subnodes << e.attributes["name"]
|
250
|
-
end
|
251
|
-
d.elements.each("node/interface") do |e|
|
252
|
-
i = Interface.new(e.attributes["name"])
|
253
|
-
e.elements.each("method") do |me|
|
254
|
-
m = Method.new(me.attributes["name"])
|
255
|
-
parse_methsig(me, m)
|
256
|
-
i << m
|
257
|
-
end
|
258
|
-
e.elements.each("signal") do |se|
|
259
|
-
s = Signal.new(se.attributes["name"])
|
260
|
-
parse_methsig(se, s)
|
261
|
-
i << s
|
262
|
-
end
|
263
|
-
interfaces << i
|
264
|
-
end
|
265
|
-
d = Time.now - t
|
266
|
-
if d > 2
|
267
|
-
puts "Some XML took more that two secs to parse. Optimize me!" if $DEBUG
|
268
|
-
end
|
269
|
-
[interfaces, subnodes]
|
270
|
-
end
|
271
|
-
|
272
|
-
######################################################################
|
273
|
-
private
|
274
|
-
|
275
|
-
# Parses a method signature XML element _e_ and initialises
|
276
|
-
# method/signal _m_.
|
277
|
-
def parse_methsig(e, m)
|
278
|
-
e.elements.each("arg") do |ae|
|
279
|
-
name = ae.attributes["name"]
|
280
|
-
dir = ae.attributes["direction"]
|
281
|
-
sig = ae.attributes["type"]
|
282
|
-
if m.is_a?(DBus::Signal)
|
283
|
-
m.add_fparam(name, sig)
|
284
|
-
elsif m.is_a?(DBus::Method)
|
285
|
-
case dir
|
286
|
-
when "in"
|
287
|
-
m.add_fparam(name, sig)
|
288
|
-
when "out"
|
289
|
-
m.add_return(name, sig)
|
290
|
-
end
|
291
|
-
else
|
292
|
-
raise NotImplementedError, dir
|
293
|
-
end
|
294
|
-
end
|
295
|
-
end
|
296
|
-
end # class IntrospectXMLParser
|
297
|
-
|
298
219
|
# = D-Bus proxy object interface class
|
299
220
|
#
|
300
221
|
# A class similar to the normal Interface used as a proxy for remote
|
data/lib/dbus/marshall.rb
CHANGED
@@ -146,7 +146,7 @@ module DBus
|
|
146
146
|
if (packet & 0x8000) != 0
|
147
147
|
packet -= 0x10000
|
148
148
|
end
|
149
|
-
when Type::UINT32
|
149
|
+
when Type::UINT32, Type::UNIX_FD
|
150
150
|
align(4)
|
151
151
|
packet = get(4).unpack(@uint32)[0]
|
152
152
|
when Type::INT32
|
@@ -317,7 +317,7 @@ module DBus
|
|
317
317
|
case type.sigtype
|
318
318
|
when Type::BYTE
|
319
319
|
@packet += val.chr
|
320
|
-
when Type::UINT32
|
320
|
+
when Type::UINT32, Type::UNIX_FD
|
321
321
|
align(4)
|
322
322
|
@packet += [val].pack("L")
|
323
323
|
when Type::UINT64
|
data/lib/dbus/message.rb
CHANGED
@@ -240,7 +240,7 @@ module DBus
|
|
240
240
|
end
|
241
241
|
pu = PacketUnmarshaller.new(buf, endianness)
|
242
242
|
mdata = pu.unmarshall(MESSAGE_SIGNATURE)
|
243
|
-
|
243
|
+
_, @message_type, @flags, @protocol, @body_length, @serial,
|
244
244
|
headers = mdata
|
245
245
|
|
246
246
|
headers.each do |struct|
|
@@ -274,7 +274,7 @@ module DBus
|
|
274
274
|
# Message#unmarshall_buf.
|
275
275
|
# Return the message.
|
276
276
|
def unmarshall(buf)
|
277
|
-
ret,
|
277
|
+
ret, _ = unmarshall_buffer(buf)
|
278
278
|
ret
|
279
279
|
end
|
280
280
|
end # class Message
|
data/lib/dbus/type.rb
CHANGED
@@ -33,6 +33,7 @@ module Type
|
|
33
33
|
STRING = ?s
|
34
34
|
SIGNATURE = ?g
|
35
35
|
DICT_ENTRY = ?e
|
36
|
+
UNIX_FD = ?h
|
36
37
|
|
37
38
|
# Mapping from type number to name.
|
38
39
|
TypeName = {
|
@@ -52,7 +53,8 @@ module Type
|
|
52
53
|
OBJECT_PATH => "OBJECT_PATH",
|
53
54
|
STRING => "STRING",
|
54
55
|
SIGNATURE => "SIGNATURE",
|
55
|
-
DICT_ENTRY => "DICT_ENTRY"
|
56
|
+
DICT_ENTRY => "DICT_ENTRY",
|
57
|
+
UNIX_FD => "UNIX_FD"
|
56
58
|
}
|
57
59
|
|
58
60
|
# Exception raised when an unknown/incorrect type is encountered.
|
@@ -96,6 +98,7 @@ module Type
|
|
96
98
|
OBJECT_PATH => 4,
|
97
99
|
STRING => 4,
|
98
100
|
SIGNATURE => 1,
|
101
|
+
UNIX_FD => 4,
|
99
102
|
}[@sigtype]
|
100
103
|
end
|
101
104
|
|
data/lib/dbus/xml.rb
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
# dbus/xml.rb - introspection parser, rexml/nokogiri abstraction
|
2
|
+
#
|
3
|
+
# This file is part of the ruby-dbus project
|
4
|
+
# Copyright (C) 2007 Arnaud Cornet and Paul van Tilburg
|
5
|
+
# Copyright (C) 2012 Geoff Youngs
|
6
|
+
#
|
7
|
+
# This library is free software; you can redistribute it and/or
|
8
|
+
# modify it under the terms of the GNU Lesser General Public
|
9
|
+
# License, version 2.1 as published by the Free Software Foundation.
|
10
|
+
# See the file "COPYING" for the exact licensing terms.
|
11
|
+
|
12
|
+
# TODO check if it is slow, make replaceable
|
13
|
+
require 'rexml/document'
|
14
|
+
begin
|
15
|
+
require 'nokogiri'
|
16
|
+
rescue LoadError
|
17
|
+
end
|
18
|
+
|
19
|
+
module DBus
|
20
|
+
# = D-Bus introspect XML parser class
|
21
|
+
#
|
22
|
+
# This class parses introspection XML of an object and constructs a tree
|
23
|
+
# of Node, Interface, Method, Signal instances.
|
24
|
+
class IntrospectXMLParser
|
25
|
+
class << self
|
26
|
+
attr_accessor :backend
|
27
|
+
end
|
28
|
+
# Creates a new parser for XML data in string _xml_.
|
29
|
+
def initialize(xml)
|
30
|
+
@xml = xml
|
31
|
+
end
|
32
|
+
|
33
|
+
class AbstractXML
|
34
|
+
def self.have_nokogiri?
|
35
|
+
Object.const_defined?('Nokogiri')
|
36
|
+
end
|
37
|
+
class Node
|
38
|
+
def initialize(node)
|
39
|
+
@node = node
|
40
|
+
end
|
41
|
+
# required methods
|
42
|
+
# returns node attribute value
|
43
|
+
def [](key)
|
44
|
+
end
|
45
|
+
# yields child nodes which match xpath of type AbstractXML::Node
|
46
|
+
def each(xpath)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
# required methods
|
50
|
+
# initialize parser with xml string
|
51
|
+
def initialize(xml)
|
52
|
+
end
|
53
|
+
# yields nodes which match xpath of type AbstractXML::Node
|
54
|
+
def each(xpath)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class NokogiriParser < AbstractXML
|
59
|
+
class NokogiriNode < AbstractXML::Node
|
60
|
+
def [](key)
|
61
|
+
@node[key]
|
62
|
+
end
|
63
|
+
def each(path, &block)
|
64
|
+
@node.search(path).each { |node| block.call NokogiriNode.new(node) }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
def initialize(xml)
|
68
|
+
@doc = Nokogiri.XML(xml)
|
69
|
+
end
|
70
|
+
def each(path, &block)
|
71
|
+
@doc.search("//#{path}").each { |node| block.call NokogiriNode.new(node) }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
class REXMLParser < AbstractXML
|
76
|
+
class REXMLNode < AbstractXML::Node
|
77
|
+
def [](key)
|
78
|
+
@node.attributes[key]
|
79
|
+
end
|
80
|
+
def each(path, &block)
|
81
|
+
@node.elements.each(path) { |node| block.call REXMLNode.new(node) }
|
82
|
+
end
|
83
|
+
end
|
84
|
+
def initialize(xml)
|
85
|
+
@doc = REXML::Document.new(xml)
|
86
|
+
end
|
87
|
+
def each(path, &block)
|
88
|
+
@doc.elements.each(path) { |node| block.call REXMLNode.new(node) }
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
if AbstractXML.have_nokogiri?
|
93
|
+
@backend = NokogiriParser
|
94
|
+
else
|
95
|
+
@backend = REXMLParser
|
96
|
+
end
|
97
|
+
|
98
|
+
# return a pair: [list of Interfaces, list of direct subnode names]
|
99
|
+
def parse
|
100
|
+
interfaces = Array.new
|
101
|
+
subnodes = Array.new
|
102
|
+
t = Time.now
|
103
|
+
|
104
|
+
|
105
|
+
d = IntrospectXMLParser.backend.new(@xml)
|
106
|
+
d.each("node/node") do |e|
|
107
|
+
subnodes << e["name"]
|
108
|
+
end
|
109
|
+
d.each("node/interface") do |e|
|
110
|
+
i = Interface.new(e["name"])
|
111
|
+
e.each("method") do |me|
|
112
|
+
m = Method.new(me["name"])
|
113
|
+
parse_methsig(me, m)
|
114
|
+
i << m
|
115
|
+
end
|
116
|
+
e.each("signal") do |se|
|
117
|
+
s = Signal.new(se["name"])
|
118
|
+
parse_methsig(se, s)
|
119
|
+
i << s
|
120
|
+
end
|
121
|
+
interfaces << i
|
122
|
+
end
|
123
|
+
d = Time.now - t
|
124
|
+
if d > 2
|
125
|
+
puts "Some XML took more that two secs to parse. Optimize me!" if $DEBUG
|
126
|
+
end
|
127
|
+
[interfaces, subnodes]
|
128
|
+
end
|
129
|
+
|
130
|
+
######################################################################
|
131
|
+
private
|
132
|
+
|
133
|
+
# Parses a method signature XML element _e_ and initialises
|
134
|
+
# method/signal _m_.
|
135
|
+
def parse_methsig(e, m)
|
136
|
+
e.each("arg") do |ae|
|
137
|
+
name = ae["name"]
|
138
|
+
dir = ae["direction"]
|
139
|
+
sig = ae["type"]
|
140
|
+
if m.is_a?(DBus::Signal)
|
141
|
+
m.add_fparam(name, sig)
|
142
|
+
elsif m.is_a?(DBus::Method)
|
143
|
+
case dir
|
144
|
+
when "in"
|
145
|
+
m.add_fparam(name, sig)
|
146
|
+
when "out"
|
147
|
+
m.add_return(name, sig)
|
148
|
+
end
|
149
|
+
else
|
150
|
+
raise NotImplementedError, dir
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end # class IntrospectXMLParser
|
155
|
+
end # module DBus
|
156
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Test the bus class
|
3
|
+
require "test/unit"
|
4
|
+
require 'rubygems'
|
5
|
+
require 'nokogiri'
|
6
|
+
require "dbus"
|
7
|
+
|
8
|
+
class BusAndXmlBackendTest < Test::Unit::TestCase
|
9
|
+
def setup
|
10
|
+
@bus = DBus::ASessionBus.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_introspection_reading_rexml
|
14
|
+
DBus::IntrospectXMLParser.backend = DBus::IntrospectXMLParser::REXMLParser
|
15
|
+
@svc = @bus.service("org.ruby.service")
|
16
|
+
obj = @svc.object("/org/ruby/MyInstance")
|
17
|
+
obj.default_iface = 'org.ruby.SampleInterface'
|
18
|
+
obj.introspect
|
19
|
+
assert_nothing_raised do
|
20
|
+
assert_equal 42, obj.the_answer[0], "should respond to :the_answer"
|
21
|
+
end
|
22
|
+
assert_nothing_raised do
|
23
|
+
assert_equal "oof", obj["org.ruby.AnotherInterface"].Reverse('foo')[0], "should work with multiple interfaces"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_introspection_reading_nokogiri
|
28
|
+
# peek inside the object to see if a cleanup step worked or not
|
29
|
+
DBus::IntrospectXMLParser.backend = DBus::IntrospectXMLParser::NokogiriParser
|
30
|
+
@svc = @bus.service("org.ruby.service")
|
31
|
+
obj = @svc.object("/org/ruby/MyInstance")
|
32
|
+
obj.default_iface = 'org.ruby.SampleInterface'
|
33
|
+
obj.introspect
|
34
|
+
assert_nothing_raised do
|
35
|
+
assert_equal 42, obj.the_answer[0], "should respond to :the_answer"
|
36
|
+
end
|
37
|
+
assert_nothing_raised do
|
38
|
+
assert_equal "oof", obj["org.ruby.AnotherInterface"].Reverse('foo')[0], "should work with multiple interfaces"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
data/test/server_test.rb
CHANGED
data/test/signal_test.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-dbus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 63
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 8
|
9
|
+
- 0
|
10
|
+
version: 0.8.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Ruby DBus Team
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-
|
18
|
+
date: 2012-09-20 00:00:00 Z
|
19
19
|
dependencies: []
|
20
20
|
|
21
21
|
description:
|
@@ -54,9 +54,11 @@ files:
|
|
54
54
|
- lib/dbus/matchrule.rb
|
55
55
|
- lib/dbus/message.rb
|
56
56
|
- lib/dbus/type.rb
|
57
|
+
- lib/dbus/xml.rb
|
57
58
|
- ruby-dbus.gemspec
|
58
59
|
- test/async_test.rb
|
59
60
|
- test/binding_test.rb
|
61
|
+
- test/bus_and_xml_backend_test.rb
|
60
62
|
- test/bus_driver_test.rb
|
61
63
|
- test/bus_test.rb
|
62
64
|
- test/dbus-launch-simple
|