pangdudu-ruby-dbus 0.2.2 → 0.2.3

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/README CHANGED
@@ -38,6 +38,7 @@ Ruby D-Bus currently supports the following features:
38
38
  * Rubyish D-Bus object and interface syntax support that automatically
39
39
  allows for introspection.
40
40
  * Emitting signals on exported objects.
41
+ * Connection to a local or remote bus over TCP/IP
41
42
 
42
43
  == Usage
43
44
 
data/lib/dbus/auth.rb CHANGED
@@ -33,8 +33,62 @@ module DBus
33
33
  return Process.uid.to_s.split(//).collect { |a| "%x" % a[0] }.join
34
34
  end
35
35
  end
36
+
37
+ # = Authentication class using SHA1 crypto algorithm
38
+ #
39
+ # Class for 'CookieSHA1' type authentication.
40
+ # Implements the AUTH DBUS_COOKIE_SHA1 mechanism.
41
+ class DBusCookieSHA1 < Authenticator
42
+
43
+ #the autenticate method (called in stage one of authentification)
44
+ def authenticate
45
+ require 'etc'
46
+ return "#{hex_encode(Etc.getlogin)}" #server expects it to be binary
47
+ end
36
48
 
37
- # Note: this following stuff is tested with External authenticator only!
49
+ #returns the modules name
50
+ def name
51
+ return 'DBUS_COOKIE_SHA1'
52
+ end
53
+
54
+ #handles the interesting crypto stuff, check the rbus-project for more info: http://rbus.rubyforge.org/
55
+ def data(hexdata)
56
+ require 'digest/sha1'
57
+ data = hex_decode(hexdata)
58
+ # name of cookie file, id of cookie in file, servers random challenge
59
+ context, id, s_challenge = data.split(' ')
60
+ # Random client challenge
61
+ c_challenge = Array.new(s_challenge.length/2).map{|obj|obj=rand(255).to_s}.join
62
+ # Search cookie file for id
63
+ path = File.join(ENV['HOME'], '.dbus-keyrings', context)
64
+ File.foreach(path) do |line|
65
+ if line.index(id) == 0
66
+ # Right line of file, read cookie
67
+ cookie = line.split(' ')[2].chomp
68
+ # Concatenate and encrypt
69
+ to_encrypt = [s_challenge, c_challenge, cookie].join(':')
70
+ sha = Digest::SHA1.hexdigest(to_encrypt)
71
+ #the almighty tcp server wants everything hex encoded
72
+ hex_response = hex_encode("#{c_challenge} #{sha}")
73
+ # Return response
74
+ response = [:AuthOk, hex_response]
75
+ return response
76
+ end
77
+ end
78
+ raise AuthException, 'Unable to locate cookie'
79
+ end
80
+
81
+ # encode plain to hex
82
+ def hex_encode(plain)
83
+ return nil if plain.nil?
84
+ plain.to_s.unpack('H*')[0]
85
+ end
86
+
87
+ # decode hex to plain
88
+ def hex_decode(encoded)
89
+ encoded.scan(/[[:xdigit:]]{2}/).map{|h|h.hex.chr}.join
90
+ end
91
+ end #DBusCookieSHA1 class ends here
38
92
 
39
93
  # = Authentication client class.
40
94
  #
@@ -44,7 +98,7 @@ module DBus
44
98
  def initialize(socket)
45
99
  @socket = socket
46
100
  @state = nil
47
- @auth_list = [External]
101
+ @auth_list = [External,DBusCookieSHA1]
48
102
  end
49
103
 
50
104
  # Start the authentication process.
@@ -81,7 +135,18 @@ module DBus
81
135
  # Read data (a buffer) from the bus until CR LF is encountered.
82
136
  # Return the buffer without the CR LF characters.
83
137
  def next_msg
84
- @socket.readline.chomp.split(" ")
138
+ data,crlf = "","\r\n"
139
+ left = 1024 #1024 byte, no idea if it's ever getting bigger
140
+ while left > 0
141
+ buf = @socket.read( left > 1 ? 1 : left )
142
+ break if buf.nil?
143
+ left -= buf.size
144
+ data += buf
145
+ break if data.include? crlf
146
+ end
147
+ readline = data.chomp.split(" ")
148
+ return readline
149
+ #return @socket.readline.chomp.split(" ")
85
150
  end
86
151
 
87
152
  # Try to reach the next state based on the current state.
@@ -89,10 +154,12 @@ module DBus
89
154
  msg = next_msg
90
155
  if @state == :Starting
91
156
  case msg[0]
157
+ when "OK"
158
+ @state = :WaitingForOk
92
159
  when "CONTINUE"
93
160
  @state = :WaitingForData
94
- when "OK"
95
- @state = :WaitingForOk
161
+ when "REJECTED" #needed by tcp, unix-path/abstract don't get here
162
+ @state = :WaitingForData
96
163
  end
97
164
  end
98
165
  case @state
@@ -152,5 +219,5 @@ module DBus
152
219
  end
153
220
  return true
154
221
  end # def next_state
155
- end # class Client
222
+ end # class Client
156
223
  end # module D-Bus
data/lib/dbus/bus.rb CHANGED
@@ -11,53 +11,11 @@
11
11
  require 'socket'
12
12
  require 'thread'
13
13
  require 'singleton'
14
- require 'connection' #outsourced connection module
15
14
 
16
15
  # = D-Bus main module
17
16
  #
18
17
  # Module containing all the D-Bus modules and classes.
19
18
  module DBus
20
-
21
- # = D-Bus session bus class
22
- #
23
- # The session bus is a session specific bus (mostly for desktop use).
24
- # This is a singleton class.
25
- class SessionBus < Connection
26
- include Singleton
27
-
28
- # Get the the default session bus.
29
- def initialize
30
- super(ENV["DBUS_SESSION_BUS_ADDRESS"])
31
- connect
32
- send_hello
33
- end
34
- end
35
-
36
- # = D-Bus system bus class
37
- #
38
- # The system bus is a system-wide bus mostly used for global or
39
- # system usages. This is a singleton class.
40
- class SystemBus < Connection
41
- include Singleton
42
-
43
- # Get the default system bus.
44
- def initialize
45
- super(SystemSocketName)
46
- connect
47
- send_hello
48
- end
49
- end
50
-
51
- # FIXME: we should get rid of these
52
-
53
- def DBus.system_bus
54
- SystemBus.instance
55
- end
56
-
57
- def DBus.session_bus
58
- SessionBus.instance
59
- end
60
-
61
19
  # This represents a remote service. It should not be instancied directly
62
20
  # Use Bus::service()
63
21
  class Service
@@ -201,6 +159,524 @@ module DBus
201
159
  end
202
160
  end # class Inspect
203
161
 
162
+ # FIXME: rename Connection to Bus?
163
+
164
+ # D-Bus main connection class
165
+ #
166
+ # Main class that maintains a connection to a bus and can handle incoming
167
+ # and outgoing messages.
168
+ class Connection
169
+ # The unique name (by specification) of the message.
170
+ attr_reader :unique_name
171
+ # The socket that is used to connect with the bus.
172
+ attr_reader :socket
173
+
174
+ # Create a new connection to the bus for a given connect _path_. _path_
175
+ # format is described in the D-Bus specification:
176
+ # http://dbus.freedesktop.org/doc/dbus-specification.html#addresses
177
+ # and is something like:
178
+ # "transport1:key1=value1,key2=value2;transport2:key1=value1,key2=value2"
179
+ # e.g. "unix:path=/tmp/dbus-test"
180
+ #
181
+ # Current implementation of ruby-dbus supports only a single server
182
+ # address and only "unix:path=...,guid=..." and
183
+ # "unix:abstract=...,guid=..." forms
184
+ def initialize(path)
185
+ @path = path
186
+ @unique_name = nil
187
+ @buffer = ""
188
+ @method_call_replies = Hash.new
189
+ @method_call_msgs = Hash.new
190
+ @signal_matchrules = Array.new
191
+ @proxy = nil
192
+ @object_root = Node.new("/")
193
+ end
194
+
195
+ # Connect to the bus and initialize the connection.
196
+ def connect
197
+ connect_to_tcp if @path.include? "tcp:" #testing
198
+ connect_to_unix_abstract if @path.include? "unix:" #supposed stable
199
+ end
200
+
201
+ # Connect to a bus over tcp and initialize the connection.
202
+ def connect_to_tcp
203
+ #check if the path is sufficient
204
+ if @path.include? "host=" and @path.include? "port="
205
+ host,port,family = "","",""
206
+ #get the parameters
207
+ @path.split(",").each do |para|
208
+ host = para.sub("tcp:","").sub("host=","") if para.include? "host="
209
+ port = para.sub("port=","").to_i if para.include? "port="
210
+ family = para.sub("family=","") if para.include? "family="
211
+ end
212
+ #puts "host,port,family : #{host},#{port},#{family}"
213
+ #initialize the tcp socket
214
+ @socket = TCPSocket.new(host,port)
215
+ init_connection
216
+ else
217
+ #Danger, Will Robinson: the specified "path" is not usable
218
+ puts "ERROR:dbus/bus.rb/Connection.connect_to_tcp: supplied path: #{@path}, unasable! sry" if $DEBUG
219
+ end
220
+ end
221
+
222
+ # Connect to an abstract unix bus and initialize the connection.
223
+ def connect_to_unix_abstract
224
+ @socket = Socket.new(Socket::Constants::PF_UNIX,Socket::Constants::SOCK_STREAM, 0)
225
+ parse_session_string
226
+ if @transport == "unix" and @type == "abstract"
227
+ if HOST_END == LIL_END
228
+ sockaddr = "\1\0\0#{@unix_abstract}"
229
+ else
230
+ sockaddr = "\0\1\0#{@unix_abstract}"
231
+ end
232
+ elsif @transport == "unix" and @type == "path"
233
+ sockaddr = Socket.pack_sockaddr_un(@unix)
234
+ end
235
+ @socket.connect(sockaddr)
236
+ init_connection
237
+ end
238
+
239
+ # Parse the session string (socket address).
240
+ def parse_session_string
241
+ path_parsed = /^([^:]*):([^;]*)$/.match(@path)
242
+ @transport = path_parsed[1]
243
+ adr = path_parsed[2]
244
+ if @transport == "unix"
245
+ adr.split(",").each do |eqstr|
246
+ idx, val = eqstr.split("=")
247
+ case idx
248
+ when "path"
249
+ @type = idx
250
+ @unix = val
251
+ when "abstract"
252
+ @type = idx
253
+ @unix_abstract = val
254
+ when "guid"
255
+ @guid = val
256
+ end
257
+ end
258
+ end
259
+ end
260
+
261
+ # Send the buffer _buf_ to the bus using Connection#writel.
262
+ def send(buf)
263
+ @socket.write(buf)
264
+ end
265
+
266
+ # Tell a bus to register itself on the glib main loop
267
+ def glibize
268
+ require 'glib2'
269
+ # Circumvent a ruby-glib bug
270
+ @channels ||= Array.new
271
+
272
+ gio = GLib::IOChannel.new(@socket.fileno)
273
+ @channels << gio
274
+ gio.add_watch(GLib::IOChannel::IN) do |c, ch|
275
+ update_buffer
276
+ messages.each do |msg|
277
+ process(msg)
278
+ end
279
+ true
280
+ end
281
+ end
282
+
283
+ # FIXME: describe the following names, flags and constants.
284
+ # See DBus spec for definition
285
+ NAME_FLAG_ALLOW_REPLACEMENT = 0x1
286
+ NAME_FLAG_REPLACE_EXISTING = 0x2
287
+ NAME_FLAG_DO_NOT_QUEUE = 0x4
288
+
289
+ REQUEST_NAME_REPLY_PRIMARY_OWNER = 0x1
290
+ REQUEST_NAME_REPLY_IN_QUEUE = 0x2
291
+ REQUEST_NAME_REPLY_EXISTS = 0x3
292
+ REQUEST_NAME_REPLY_ALREADY_OWNER = 0x4
293
+
294
+ DBUSXMLINTRO = '<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
295
+ "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
296
+ <node>
297
+ <interface name="org.freedesktop.DBus.Introspectable">
298
+ <method name="Introspect">
299
+ <arg name="data" direction="out" type="s"/>
300
+ </method>
301
+ </interface>
302
+ <interface name="org.freedesktop.DBus">
303
+ <method name="RequestName">
304
+ <arg direction="in" type="s"/>
305
+ <arg direction="in" type="u"/>
306
+ <arg direction="out" type="u"/>
307
+ </method>
308
+ <method name="ReleaseName">
309
+ <arg direction="in" type="s"/>
310
+ <arg direction="out" type="u"/>
311
+ </method>
312
+ <method name="StartServiceByName">
313
+ <arg direction="in" type="s"/>
314
+ <arg direction="in" type="u"/>
315
+ <arg direction="out" type="u"/>
316
+ </method>
317
+ <method name="Hello">
318
+ <arg direction="out" type="s"/>
319
+ </method>
320
+ <method name="NameHasOwner">
321
+ <arg direction="in" type="s"/>
322
+ <arg direction="out" type="b"/>
323
+ </method>
324
+ <method name="ListNames">
325
+ <arg direction="out" type="as"/>
326
+ </method>
327
+ <method name="ListActivatableNames">
328
+ <arg direction="out" type="as"/>
329
+ </method>
330
+ <method name="AddMatch">
331
+ <arg direction="in" type="s"/>
332
+ </method>
333
+ <method name="RemoveMatch">
334
+ <arg direction="in" type="s"/>
335
+ </method>
336
+ <method name="GetNameOwner">
337
+ <arg direction="in" type="s"/>
338
+ <arg direction="out" type="s"/>
339
+ </method>
340
+ <method name="ListQueuedOwners">
341
+ <arg direction="in" type="s"/>
342
+ <arg direction="out" type="as"/>
343
+ </method>
344
+ <method name="GetConnectionUnixUser">
345
+ <arg direction="in" type="s"/>
346
+ <arg direction="out" type="u"/>
347
+ </method>
348
+ <method name="GetConnectionUnixProcessID">
349
+ <arg direction="in" type="s"/>
350
+ <arg direction="out" type="u"/>
351
+ </method>
352
+ <method name="GetConnectionSELinuxSecurityContext">
353
+ <arg direction="in" type="s"/>
354
+ <arg direction="out" type="ay"/>
355
+ </method>
356
+ <method name="ReloadConfig">
357
+ </method>
358
+ <signal name="NameOwnerChanged">
359
+ <arg type="s"/>
360
+ <arg type="s"/>
361
+ <arg type="s"/>
362
+ </signal>
363
+ <signal name="NameLost">
364
+ <arg type="s"/>
365
+ </signal>
366
+ <signal name="NameAcquired">
367
+ <arg type="s"/>
368
+ </signal>
369
+ </interface>
370
+ </node>
371
+ '
372
+
373
+ def introspect_data(dest, path)
374
+ m = DBus::Message.new(DBus::Message::METHOD_CALL)
375
+ m.path = path
376
+ m.interface = "org.freedesktop.DBus.Introspectable"
377
+ m.destination = dest
378
+ m.member = "Introspect"
379
+ m.sender = unique_name
380
+ if not block_given?
381
+ # introspect in synchronous !
382
+ send_sync(m) do |rmsg|
383
+ if rmsg.is_a?(Error)
384
+ raise rmsg
385
+ else
386
+ return rmsg.params[0]
387
+ end
388
+ end
389
+ else
390
+ send(m.marshall)
391
+ on_return(m) do |rmsg|
392
+ if rmsg.is_a?(Error)
393
+ yield rmsg
394
+ else
395
+ yield rmsg.params[0]
396
+ end
397
+ end
398
+ end
399
+ nil
400
+ end
401
+
402
+ # Issues a call to the org.freedesktop.DBus.Introspectable.Introspect method
403
+ # _dest_ is the service and _path_ the object path you want to introspect
404
+ # If a code block is given, the introspect call in asynchronous. If not
405
+ # data is returned
406
+ #
407
+ # FIXME: link to ProxyObject data definition
408
+ # The returned object is a ProxyObject that has methods you can call to
409
+ # issue somme METHOD_CALL messages, and to setup to receive METHOD_RETURN
410
+ def introspect(dest, path)
411
+ if not block_given?
412
+ # introspect in synchronous !
413
+ data = introspect_data(dest, path)
414
+ pof = DBus::ProxyObjectFactory.new(data, self, dest, path)
415
+ return pof.build
416
+ else
417
+ introspect_data(dest, path) do |data|
418
+ yield(DBus::ProxyObjectFactory.new(data, self, dest, path).build)
419
+ end
420
+ end
421
+ end
422
+
423
+ # Exception raised when a service name is requested that is not available.
424
+ class NameRequestError < Exception
425
+ end
426
+
427
+ # Attempt to request a service _name_.
428
+ def request_service(name)
429
+ r = proxy.RequestName(name, NAME_FLAG_REPLACE_EXISTING)
430
+ raise NameRequestError if r[0] != REQUEST_NAME_REPLY_PRIMARY_OWNER
431
+ @service = Service.new(name, self)
432
+ @service
433
+ end
434
+
435
+ # Set up a ProxyObject for the bus itself, since the bus is introspectable.
436
+ # Returns the object.
437
+ def proxy
438
+ if @proxy == nil
439
+ path = "/org/freedesktop/DBus"
440
+ dest = "org.freedesktop.DBus"
441
+ pof = DBus::ProxyObjectFactory.new(DBUSXMLINTRO, self, dest, path)
442
+ @proxy = pof.build["org.freedesktop.DBus"]
443
+ end
444
+ @proxy
445
+ end
446
+
447
+ # Fill (append) the buffer from data that might be available on the
448
+ # socket.
449
+ def update_buffer
450
+ @buffer += @socket.read_nonblock(MSG_BUF_SIZE)
451
+ end
452
+
453
+ # Get one message from the bus and remove it from the buffer.
454
+ # Return the message.
455
+ def pop_message
456
+ ret = nil
457
+ begin
458
+ ret, size = Message.new.unmarshall_buffer(@buffer)
459
+ @buffer.slice!(0, size)
460
+ rescue IncompleteBufferException => e
461
+ # fall through, let ret be null
462
+ end
463
+ ret
464
+ end
465
+
466
+ # Retrieve all the messages that are currently in the buffer.
467
+ def messages
468
+ ret = Array.new
469
+ while msg = pop_message
470
+ ret << msg
471
+ end
472
+ ret
473
+ end
474
+
475
+ # The buffer size for messages.
476
+ MSG_BUF_SIZE = 4096
477
+
478
+ # Update the buffer and retrieve all messages using Connection#messages.
479
+ # Return the messages.
480
+ def poll_messages
481
+ ret = nil
482
+ r, d, d = IO.select([@socket], nil, nil, 0)
483
+ if r and r.size > 0
484
+ update_buffer
485
+ end
486
+ messages
487
+ end
488
+
489
+ # Wait for a message to arrive. Return it once it is available.
490
+ def wait_for_message
491
+ ret = pop_message
492
+ while ret == nil
493
+ r, d, d = IO.select([@socket])
494
+ if r and r[0] == @socket
495
+ update_buffer
496
+ ret = pop_message
497
+ end
498
+ end
499
+ ret
500
+ end
501
+
502
+ # Send a message _m_ on to the bus. This is done synchronously, thus
503
+ # the call will block until a reply message arrives.
504
+ def send_sync(m, &retc) # :yields: reply/return message
505
+ send(m.marshall)
506
+ @method_call_msgs[m.serial] = m
507
+ @method_call_replies[m.serial] = retc
508
+
509
+ retm = wait_for_message
510
+ process(retm)
511
+ until [DBus::Message::ERROR,
512
+ DBus::Message::METHOD_RETURN].include?(retm.message_type) and
513
+ retm.reply_serial == m.serial
514
+ retm = wait_for_message
515
+ process(retm)
516
+ end
517
+ end
518
+
519
+ # Specify a code block that has to be executed when a reply for
520
+ # message _m_ is received.
521
+ def on_return(m, &retc)
522
+ # Have a better exception here
523
+ if m.message_type != Message::METHOD_CALL
524
+ raise "on_return should only get method_calls"
525
+ end
526
+ @method_call_msgs[m.serial] = m
527
+ @method_call_replies[m.serial] = retc
528
+ end
529
+
530
+ # Asks bus to send us messages matching mr, and execute slot when
531
+ # received
532
+ def add_match(mr, &slot)
533
+ # check this is a signal.
534
+ @signal_matchrules << [mr, slot]
535
+ self.proxy.AddMatch(mr.to_s)
536
+ end
537
+
538
+ # Process a message _m_ based on its type.
539
+ # method call:: FIXME...
540
+ # method call return value:: FIXME...
541
+ # signal:: FIXME...
542
+ # error:: FIXME...
543
+ def process(m)
544
+ case m.message_type
545
+ when Message::ERROR, Message::METHOD_RETURN
546
+ raise InvalidPacketException if m.reply_serial == nil
547
+ mcs = @method_call_replies[m.reply_serial]
548
+ if not mcs
549
+ puts "no return code for #{mcs.inspect} (#{m.inspect})" if $DEBUG
550
+ else
551
+ if m.message_type == Message::ERROR
552
+ mcs.call(Error.new(m))
553
+ else
554
+ mcs.call(m)
555
+ end
556
+ @method_call_replies.delete(m.reply_serial)
557
+ @method_call_msgs.delete(m.reply_serial)
558
+ end
559
+ when DBus::Message::METHOD_CALL
560
+ if m.path == "/org/freedesktop/DBus"
561
+ puts "Got method call on /org/freedesktop/DBus" if $DEBUG
562
+ end
563
+ # handle introspectable as an exception:
564
+ if m.interface == "org.freedesktop.DBus.Introspectable" and
565
+ m.member == "Introspect"
566
+ reply = Message.new(Message::METHOD_RETURN).reply_to(m)
567
+ reply.sender = @unique_name
568
+ node = @service.get_node(m.path)
569
+ raise NotImplementedError if not node
570
+ reply.sender = @unique_name
571
+ reply.add_param(Type::STRING, @service.get_node(m.path).to_xml)
572
+ send(reply.marshall)
573
+ else
574
+ node = @service.get_node(m.path)
575
+ return if node.nil?
576
+ obj = node.object
577
+ return if obj.nil?
578
+ obj.dispatch(m) if obj
579
+ end
580
+ when DBus::Message::SIGNAL
581
+ @signal_matchrules.each do |elem|
582
+ mr, slot = elem
583
+ if mr.match(m)
584
+ slot.call(m)
585
+ return
586
+ end
587
+ end
588
+ else
589
+ puts "Unknown message type: #{m.message_type}" if $DEBUG
590
+ end
591
+ end
592
+
593
+ # Retrieves the service with the given _name_.
594
+ def service(name)
595
+ # The service might not exist at this time so we cannot really check
596
+ # anything
597
+ Service.new(name, self)
598
+ end
599
+ alias :[] :service
600
+
601
+ # Emit a signal event for the given _service_, object _obj_, interface
602
+ # _intf_ and signal _sig_ with arguments _args_.
603
+ def emit(service, obj, intf, sig, *args)
604
+ m = Message.new(DBus::Message::SIGNAL)
605
+ m.path = obj.path
606
+ m.interface = intf.name
607
+ m.member = sig.name
608
+ m.sender = service.name
609
+ i = 0
610
+ sig.params.each do |par|
611
+ m.add_param(par[1], args[i])
612
+ i += 1
613
+ end
614
+ send(m.marshall)
615
+ end
616
+
617
+ ###########################################################################
618
+ private
619
+
620
+ # Send a hello messages to the bus to let it know we are here.
621
+ def send_hello
622
+ m = Message.new(DBus::Message::METHOD_CALL)
623
+ m.path = "/org/freedesktop/DBus"
624
+ m.destination = "org.freedesktop.DBus"
625
+ m.interface = "org.freedesktop.DBus"
626
+ m.member = "Hello"
627
+ send_sync(m) do |rmsg|
628
+ @unique_name = rmsg.destination
629
+ puts "Got hello reply. Our unique_name is #{@unique_name}" if $DEBUG
630
+ end
631
+ end
632
+
633
+ # Initialize the connection to the bus.
634
+ def init_connection
635
+ @client = Client.new(@socket)
636
+ @client.authenticate
637
+ end
638
+ end # class Connection
639
+
640
+ # = D-Bus session bus class
641
+ #
642
+ # The session bus is a session specific bus (mostly for desktop use).
643
+ # This is a singleton class.
644
+ class SessionBus < Connection
645
+ include Singleton
646
+
647
+ # Get the the default session bus.
648
+ def initialize socket_name=SessionSocketName
649
+ super(socket_name)
650
+ connect
651
+ send_hello
652
+ end
653
+ end
654
+
655
+ # = D-Bus system bus class
656
+ #
657
+ # The system bus is a system-wide bus mostly used for global or
658
+ # system usages. This is a singleton class.
659
+ class SystemBus < Connection
660
+ include Singleton
661
+
662
+ # Get the default system bus.
663
+ def initialize socket_name=SystemSocketName
664
+ super(socket_name)
665
+ connect
666
+ send_hello
667
+ end
668
+ end
669
+
670
+ # FIXME: we should get rid of these singeltons
671
+
672
+ def DBus.system_bus
673
+ SystemBus.instance
674
+ end
675
+
676
+ def DBus.session_bus
677
+ SessionBus.instance
678
+ end
679
+
204
680
  # = Main event loop class.
205
681
  #
206
682
  # Class that takes care of handling message and signal events
@@ -1,3 +1,10 @@
1
+ require 'dbus/bus'
2
+ require 'dbus/auth'
3
+
4
+ # = D-Bus main module
5
+ #
6
+ # Module containing all the D-Bus modules and classes.
7
+ module DBus
1
8
  # D-Bus main connection class
2
9
  #
3
10
  # Main class that maintains a connection to a bus and can handle incoming
@@ -26,14 +33,18 @@
26
33
  @method_call_msgs = Hash.new
27
34
  @signal_matchrules = Array.new
28
35
  @proxy = nil
29
- # FIXME: can be TCP or any stream
30
- @socket = Socket.new(Socket::Constants::PF_UNIX,
31
- Socket::Constants::SOCK_STREAM, 0)
36
+ # FIXME: can be TCP or any stream, let's do it.
37
+ @socket = Socket.new(Socket::Constants::PF_UNIX,Socket::Constants::SOCK_STREAM, 0)
32
38
  @object_root = Node.new("/")
33
39
  end
34
40
 
35
41
  # Connect to the bus and initialize the connection.
36
42
  def connect
43
+ connect_to_unix_abstract
44
+ end
45
+
46
+ # Connect to the bus and initialize the connection.
47
+ def connect_to_unix_abstract
37
48
  parse_session_string
38
49
  if @transport == "unix" and @type == "abstract"
39
50
  if HOST_END == LIL_END
@@ -454,4 +465,4 @@
454
465
  #writel("BEGIN")
455
466
  end
456
467
  end # class Connection
457
-
468
+ end # module DBus
data/lib/dbus.rb CHANGED
@@ -16,7 +16,6 @@ require 'dbus/marshall'
16
16
  require 'dbus/message'
17
17
  require 'dbus/matchrule'
18
18
  require 'dbus/auth'
19
-
20
19
  require 'socket'
21
20
  require 'thread'
22
21
 
@@ -27,6 +26,9 @@ module DBus
27
26
  # Default socket name for the system bus.
28
27
  SystemSocketName = "unix:path=/var/run/dbus/system_bus_socket"
29
28
 
29
+ # Socket name for the session bus.
30
+ SessionSocketName = ENV["DBUS_SESSION_BUS_ADDRESS"]
31
+
30
32
  # Byte signifying big endianness.
31
33
  BIG_END = ?B
32
34
  # Byte signifying little endianness.
@@ -80,3 +82,5 @@ module DBus
80
82
  class InvalidIntrospectionData < Exception
81
83
  end
82
84
  end # module DBus
85
+ #just for my info
86
+ puts "pangdudus ruby-dbus fork."
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pangdudu-ruby-dbus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
- - Ruby DBUS Team
7
+ - Ruby DBUS Team, pangdudu
8
8
  autorequire: dbus
9
9
  bindir: bin
10
10
  cert_chain: []