dizby 1.3.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.
- checksums.yaml +7 -0
- data/.rubocop.yml +10 -0
- data/LICENSE +24 -0
- data/dizby.gemspec +27 -0
- data/lib/dizby.rb +12 -0
- data/lib/dizby/access/control_list.rb +78 -0
- data/lib/dizby/access/entry.rb +61 -0
- data/lib/dizby/access/insecure.rb +30 -0
- data/lib/dizby/access/list.rb +10 -0
- data/lib/dizby/converter/simple.rb +12 -0
- data/lib/dizby/converter/timed.rb +23 -0
- data/lib/dizby/distributed/array.rb +30 -0
- data/lib/dizby/distributed/object.rb +44 -0
- data/lib/dizby/distributed/proxy.rb +41 -0
- data/lib/dizby/distributed/semi_proxy.rb +26 -0
- data/lib/dizby/distributed/undumpable.rb +8 -0
- data/lib/dizby/distributed/unknown.rb +57 -0
- data/lib/dizby/error.rb +29 -0
- data/lib/dizby/protocol/basic.rb +31 -0
- data/lib/dizby/protocol/manager.rb +62 -0
- data/lib/dizby/protocol/refined.rb +23 -0
- data/lib/dizby/protocols/dead.rb +24 -0
- data/lib/dizby/protocols/secure.rb +87 -0
- data/lib/dizby/protocols/tcp.rb +98 -0
- data/lib/dizby/protocols/unix.rb +95 -0
- data/lib/dizby/server/abstract.rb +42 -0
- data/lib/dizby/server/basic.rb +101 -0
- data/lib/dizby/server/registration.rb +23 -0
- data/lib/dizby/service.rb +64 -0
- data/lib/dizby/stream/client.rb +26 -0
- data/lib/dizby/stream/connection.rb +63 -0
- data/lib/dizby/stream/messenger.rb +28 -0
- data/lib/dizby/stream/query_ref.rb +13 -0
- data/lib/dizby/stream/readable.rb +65 -0
- data/lib/dizby/stream/writable.rb +37 -0
- data/lib/dizby/tunnel/abstract.rb +52 -0
- data/lib/dizby/tunnel/basic.rb +21 -0
- data/lib/dizby/tunnel/basic_spawn.rb +50 -0
- data/lib/dizby/tunnel/bidirectional_strategy.rb +29 -0
- data/lib/dizby/tunnel/factory.rb +29 -0
- data/lib/dizby/tunnel/local_strategy.rb +24 -0
- data/lib/dizby/tunnel/spawn_command.rb +49 -0
- data/lib/dizby/tunnel/spawned.rb +43 -0
- data/lib/dizby/tunnel/tunnelable_local.rb +8 -0
- data/lib/dizby/tunnel/tunnelable_remote.rb +21 -0
- data/lib/dizby/utility/classic_access.rb +25 -0
- data/lib/dizby/utility/configurable.rb +25 -0
- data/lib/dizby/utility/delegator.rb +28 -0
- data/lib/dizby/utility/io_barrier.rb +18 -0
- data/lib/dizby/utility/log.rb +23 -0
- data/lib/dizby/utility/monitor.rb +9 -0
- data/lib/dizby/utility/polymorphic_delegated.rb +58 -0
- data/lib/dizby/utility/self_pipe.rb +12 -0
- data/lib/dizby/utility/semi_built.rb +17 -0
- data/lib/dizby/utility/string.rb +8 -0
- data/lib/dizby/utility/timed_collection.rb +39 -0
- data/lib/dizby/utility/timed_state.rb +41 -0
- data/lib/dizby/version.rb +4 -0
- data/lib/dizby/worker/connection.rb +44 -0
- data/lib/dizby/worker/invoke_method.rb +55 -0
- data/lib/dizby/worker/server.rb +39 -0
- metadata +146 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
|
|
2
|
+
require 'dizby/error'
|
|
3
|
+
|
|
4
|
+
module Dizby
|
|
5
|
+
class UnknownObject
|
|
6
|
+
def initialize(err, buf)
|
|
7
|
+
case err.to_s
|
|
8
|
+
when /uninitialized constant (\S+)/
|
|
9
|
+
@name = $~[1]
|
|
10
|
+
when %r{undefined class/module (\S+)}
|
|
11
|
+
@name = $~[1]
|
|
12
|
+
else
|
|
13
|
+
@name = nil
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
@buf = buf
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
attr_reader :name, :buf
|
|
20
|
+
|
|
21
|
+
def self._load(str)
|
|
22
|
+
Marshal.load(str)
|
|
23
|
+
rescue NameError, ArgumentError
|
|
24
|
+
UnknownObject.new($!, str)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def _dump(_)
|
|
28
|
+
Marshal.dump(@buf)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def reload
|
|
32
|
+
self.class._load @buf
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def exception
|
|
36
|
+
UnknownObjectError.new self
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
class UnknownObjectError < DistributedError
|
|
41
|
+
def initialize(unknown)
|
|
42
|
+
@unknown = unknown
|
|
43
|
+
super unknown.name
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# give access to the UnknownObject class
|
|
47
|
+
attr_reader :unknown
|
|
48
|
+
|
|
49
|
+
def self._load(str)
|
|
50
|
+
Marshal.load(str)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def _dump(_)
|
|
54
|
+
Marshal.dump(@unknown)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
data/lib/dizby/error.rb
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
|
|
2
|
+
module Dizby
|
|
3
|
+
class DistributedError < RuntimeError; end
|
|
4
|
+
class ConnectionError < DistributedError; end
|
|
5
|
+
class ServerNotFound < DistributedError; end
|
|
6
|
+
class BadURI < DistributedError; end
|
|
7
|
+
class BadScheme < DistributedError; end
|
|
8
|
+
class LocalServerShutdown < DistributedError; end
|
|
9
|
+
class RemoteServerShutdown < ConnectionError; end
|
|
10
|
+
class SpawnError < DistributedError; end
|
|
11
|
+
|
|
12
|
+
class NonAcceptingServer < DistributedError
|
|
13
|
+
def initialize(server)
|
|
14
|
+
@server = server
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
attr_reader :server
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class RemoteDistributedError < DistributedError
|
|
21
|
+
def initialize(error)
|
|
22
|
+
@reason = error.class.to_s
|
|
23
|
+
super("#{error.message} (#{@reason})")
|
|
24
|
+
set_backtrace(error.backtrace)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
attr_reader :reason
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
|
|
2
|
+
require 'dizby/protocol/manager'
|
|
3
|
+
require 'dizby/protocol/refined'
|
|
4
|
+
|
|
5
|
+
module Dizby
|
|
6
|
+
module BasicProtocol
|
|
7
|
+
module ClassMethods
|
|
8
|
+
attr_reader :scheme
|
|
9
|
+
|
|
10
|
+
def get_refinement(type)
|
|
11
|
+
instance_variable_get(:"@#{type}_refined")
|
|
12
|
+
rescue NameError
|
|
13
|
+
nil
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
protected
|
|
17
|
+
|
|
18
|
+
attr_writer :scheme
|
|
19
|
+
|
|
20
|
+
def refine(type, regex, &block)
|
|
21
|
+
refined = RefinedProtocol.new(regex, &block)
|
|
22
|
+
instance_variable_set(:"@#{type}_refined", refined)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.included(base)
|
|
27
|
+
base.extend ClassMethods
|
|
28
|
+
ProtocolManager.add_protocol(base)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
|
|
2
|
+
require 'dizby/error'
|
|
3
|
+
|
|
4
|
+
module Dizby
|
|
5
|
+
class ProtocolManager
|
|
6
|
+
# TODO: all required portions of a Protocol class need to be documented
|
|
7
|
+
class << self
|
|
8
|
+
def add_protocol(klass)
|
|
9
|
+
@protocols << klass
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def open_client(server, uri)
|
|
13
|
+
call_refined(uri, :client, server)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def open_server(uri, front, config)
|
|
17
|
+
call_refined(uri, :server, front, config)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def spawn_server(server, command, uri)
|
|
21
|
+
call_refined(uri, :spawn, server, command)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def call_refined(uri, refiner, *base_args)
|
|
27
|
+
klass = get_protocol(uri)
|
|
28
|
+
refined = refine_protocol(klass, refiner)
|
|
29
|
+
args = get_arguments(refined, uri)
|
|
30
|
+
refined.call(*base_args, args)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def get_protocol(uri)
|
|
34
|
+
scheme = '' if uri.empty?
|
|
35
|
+
scheme ||= uri.split(':').first
|
|
36
|
+
fail BadScheme, "can't retrieve scheme: #{uri}" unless scheme
|
|
37
|
+
|
|
38
|
+
protocol = @protocols.find { |klass| klass.scheme == scheme }
|
|
39
|
+
protocol || fail(BadScheme, "scheme not found: #{scheme}")
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def refine_protocol(protocol, refinement)
|
|
43
|
+
refined = protocol.get_refinement(refinement)
|
|
44
|
+
|
|
45
|
+
unless refined
|
|
46
|
+
fail NotImplementedError,
|
|
47
|
+
"#{refinement} refinement not supported for #{protocol}"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
refined
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def get_arguments(refined, uri)
|
|
54
|
+
fail BadURI, "can't parse uri: #{uri}" unless refined.regex =~ uri
|
|
55
|
+
|
|
56
|
+
$~[1..-1]
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
@protocols = []
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
|
|
2
|
+
module Dizby
|
|
3
|
+
PROTOCOL_REGEX = {
|
|
4
|
+
user: '(?:(.+?)@)',
|
|
5
|
+
host: '(.*?)',
|
|
6
|
+
port: '(?::(\d+))',
|
|
7
|
+
file: '(.+?)',
|
|
8
|
+
query: '(?:\?(.*?))'
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
class RefinedProtocol
|
|
12
|
+
def initialize(regex, &block)
|
|
13
|
+
@regex = /^#{format(regex, Dizby::PROTOCOL_REGEX)}$/
|
|
14
|
+
@block = block
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
attr_reader :regex
|
|
18
|
+
|
|
19
|
+
def call(*args)
|
|
20
|
+
@block.call(*args)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
require 'dizby/protocol/basic'
|
|
3
|
+
require 'dizby/server/abstract'
|
|
4
|
+
|
|
5
|
+
module Dizby
|
|
6
|
+
class DeadProtocol
|
|
7
|
+
include BasicProtocol
|
|
8
|
+
|
|
9
|
+
self.scheme = ''
|
|
10
|
+
|
|
11
|
+
refine(:server, '') do |_, config|
|
|
12
|
+
fail NonAcceptingServer, Server.new(config)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class Server < AbstractServer
|
|
16
|
+
# A DeadProtocol server doesn't allow backwards connections
|
|
17
|
+
# therefore, making a distributed object goes against that.
|
|
18
|
+
def make_distributed(*_)
|
|
19
|
+
fail DistributedError,
|
|
20
|
+
'distributed objects not supported from DeadProtocol'
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
|
|
2
|
+
require 'dizby/protocol/basic'
|
|
3
|
+
require 'dizby/stream/client'
|
|
4
|
+
require 'dizby/stream/connection'
|
|
5
|
+
require 'dizby/server/basic'
|
|
6
|
+
require 'dizby/tunnel/basic'
|
|
7
|
+
require 'dizby/tunnel/factory'
|
|
8
|
+
|
|
9
|
+
require 'socket'
|
|
10
|
+
|
|
11
|
+
module Dizby
|
|
12
|
+
class SecureProtocol
|
|
13
|
+
include BasicProtocol
|
|
14
|
+
|
|
15
|
+
self.scheme = 'drbsec'
|
|
16
|
+
|
|
17
|
+
refine(:spawn,
|
|
18
|
+
"#{scheme}://%{user}?%{host}%{port}?%{query}?"
|
|
19
|
+
) do |server, command, (user, host, port, query)|
|
|
20
|
+
factory = TunnelFactory.new(server, port)
|
|
21
|
+
tunnel = factory.create(BasicSpawnTunnel).with(command, user, host)
|
|
22
|
+
|
|
23
|
+
socket = TCPSocket.open('localhost', tunnel.local_port)
|
|
24
|
+
TCProtocol.apply_sockopt(socket)
|
|
25
|
+
|
|
26
|
+
delegate = delegatable_tunnel(factory, server, tunnel)
|
|
27
|
+
client = BasicClient.new(delegate, socket,
|
|
28
|
+
"#{scheme}://#{host}:#{tunnel.remote_port}")
|
|
29
|
+
query &&= QueryRef.new(query)
|
|
30
|
+
|
|
31
|
+
[client, query]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
refine(:client,
|
|
35
|
+
"#{scheme}://%{user}?%{host}%{port}%{query}?"
|
|
36
|
+
) do |server, (user, host, port, query)|
|
|
37
|
+
port &&= port.to_i
|
|
38
|
+
|
|
39
|
+
factory = TunnelFactory.new(server, port)
|
|
40
|
+
tunnel = factory.create(BasicTunnel).with(user, host)
|
|
41
|
+
|
|
42
|
+
socket = TCPSocket.open('localhost', tunnel.local_port)
|
|
43
|
+
TCProtocol.apply_sockopt(socket)
|
|
44
|
+
|
|
45
|
+
delegate = delegatable_tunnel(factory, server, tunnel)
|
|
46
|
+
client = BasicClient.new(delegate, socket, "#{scheme}://#{host}:#{port}")
|
|
47
|
+
query &&= QueryRef.new(query)
|
|
48
|
+
|
|
49
|
+
[client, query]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def self.delegatable_tunnel(factory, server, tunnel)
|
|
53
|
+
if factory.bidirectional?
|
|
54
|
+
ResponseTunnel.new(server, tunnel)
|
|
55
|
+
else
|
|
56
|
+
DirectTunnel.new(server, tunnel)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
class DirectTunnel < Delegator
|
|
61
|
+
def initialize(server, tunnel)
|
|
62
|
+
super(server)
|
|
63
|
+
|
|
64
|
+
@tunnel = tunnel
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def close
|
|
68
|
+
@tunnel.close
|
|
69
|
+
super
|
|
70
|
+
@tunnel.thread.join
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
class ResponseTunnel < DirectTunnel
|
|
75
|
+
def initialize(server, tunnel)
|
|
76
|
+
super(server, tunnel)
|
|
77
|
+
|
|
78
|
+
@remote_port = tunnel.remote_port
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def uri # overload the uri of the server
|
|
82
|
+
# we use the drb protocol for the rebound connection
|
|
83
|
+
"drb://localhost:#{@remote_port}"
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
|
|
2
|
+
require 'dizby/protocol/basic'
|
|
3
|
+
require 'dizby/stream/client'
|
|
4
|
+
require 'dizby/stream/connection'
|
|
5
|
+
require 'dizby/server/basic'
|
|
6
|
+
|
|
7
|
+
require 'socket'
|
|
8
|
+
|
|
9
|
+
module Dizby
|
|
10
|
+
class TCProtocol
|
|
11
|
+
include BasicProtocol
|
|
12
|
+
|
|
13
|
+
self.scheme = 'drb'
|
|
14
|
+
|
|
15
|
+
refine(:server,
|
|
16
|
+
"#{scheme}://%{host}?%{port}?"
|
|
17
|
+
) do |front, config, (host, port)|
|
|
18
|
+
port &&= port.to_i
|
|
19
|
+
|
|
20
|
+
Server.new front, config, host, port
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
refine(:client,
|
|
24
|
+
"#{scheme}://%{host}?%{port}?%{query}?"
|
|
25
|
+
) do |server, (host, port, query)|
|
|
26
|
+
port &&= port.to_i
|
|
27
|
+
|
|
28
|
+
socket = TCPSocket.open(host, port)
|
|
29
|
+
apply_sockopt(socket)
|
|
30
|
+
|
|
31
|
+
client = BasicClient.new(server, socket, "#{scheme}://#{host}:#{port}")
|
|
32
|
+
query &&= QueryRef.new(query)
|
|
33
|
+
|
|
34
|
+
[client, query]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class << self
|
|
38
|
+
def getservername
|
|
39
|
+
Socket.gethostbyname(Socket.gethostname)[0]
|
|
40
|
+
rescue
|
|
41
|
+
'localhost'
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def apply_sockopt(soc)
|
|
45
|
+
soc.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
class Server < BasicServer
|
|
50
|
+
include PolymorphicDelegated
|
|
51
|
+
|
|
52
|
+
def initialize(front, config, host, port)
|
|
53
|
+
port ||= 0
|
|
54
|
+
|
|
55
|
+
if host.empty?
|
|
56
|
+
host = TCProtocol.getservername
|
|
57
|
+
socket = self.class.open_socket_inaddr_any(host, port)
|
|
58
|
+
else
|
|
59
|
+
socket = TCPServer.open(host, port)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
port = socket.addr[1] if port == 0
|
|
63
|
+
|
|
64
|
+
super("drb://#{host}:#{port}", front, socket, config)
|
|
65
|
+
|
|
66
|
+
TCProtocol.apply_sockopt(socket)
|
|
67
|
+
|
|
68
|
+
@port = port
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
attr_reader :port
|
|
72
|
+
|
|
73
|
+
def accept
|
|
74
|
+
socket = nil
|
|
75
|
+
loop do
|
|
76
|
+
socket = super
|
|
77
|
+
break if !tcp_acl || tcp_acl.allow_socket?(socket) # TODO: not tested
|
|
78
|
+
socket.close
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
TCProtocol.apply_sockopt(socket)
|
|
82
|
+
BasicConnection.new(self, socket)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
config_reader :tcp_acl
|
|
86
|
+
private :tcp_acl
|
|
87
|
+
|
|
88
|
+
def self.open_socket_inaddr_any(host, port)
|
|
89
|
+
infos = Socket.getaddrinfo(host, nil, Socket::AF_UNSPEC,
|
|
90
|
+
Socket::SOCK_STREAM, 0, Socket::AI_PASSIVE)
|
|
91
|
+
families = Hash[*infos.collect { |af, *_| af }.uniq.zip([]).flatten]
|
|
92
|
+
return TCPServer.open('0.0.0.0', port) if families.key?('AF_INET')
|
|
93
|
+
return TCPServer.open('::', port) if families.key?('AF_INET6')
|
|
94
|
+
TCPServer.open(port)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
|
|
2
|
+
require 'dizby/protocol/basic'
|
|
3
|
+
require 'dizby/stream/client'
|
|
4
|
+
require 'dizby/stream/connection'
|
|
5
|
+
require 'dizby/server/basic'
|
|
6
|
+
|
|
7
|
+
require 'socket'
|
|
8
|
+
require 'tempfile'
|
|
9
|
+
|
|
10
|
+
fail LoadError, 'UNIXServer is required' unless defined?(UNIXServer)
|
|
11
|
+
|
|
12
|
+
module Dizby
|
|
13
|
+
class UnixProtocol
|
|
14
|
+
include BasicProtocol
|
|
15
|
+
|
|
16
|
+
self.scheme = 'drbunix'
|
|
17
|
+
|
|
18
|
+
refine(:server,
|
|
19
|
+
"#{scheme}:%{file}?"
|
|
20
|
+
) do |front, config, (filename)|
|
|
21
|
+
Server.new front, config, filename
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
refine(:client,
|
|
25
|
+
"#{scheme}:%{file}%{query}?"
|
|
26
|
+
) do |server, (filename, query)|
|
|
27
|
+
socket = UNIXSocket.open(filename)
|
|
28
|
+
UnixProtocol.apply_sockopt(socket)
|
|
29
|
+
|
|
30
|
+
client = BasicClient.new server, socket, "#{scheme}:#{filename}"
|
|
31
|
+
query &&= QueryRef.new(query)
|
|
32
|
+
|
|
33
|
+
[client, query]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.apply_sockopt(_soc)
|
|
37
|
+
# no-op for now
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
class Server < BasicServer
|
|
41
|
+
include PolymorphicDelegated
|
|
42
|
+
|
|
43
|
+
def initialize(front, config, filename)
|
|
44
|
+
unless filename
|
|
45
|
+
temp = Tempfile.new(%w( dizby-unix .socket ))
|
|
46
|
+
filename = temp.path
|
|
47
|
+
temp.close!
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
socket = UNIXServer.open(filename)
|
|
51
|
+
UnixProtocol.apply_sockopt(socket)
|
|
52
|
+
|
|
53
|
+
super("drbunix:#{filename}", front, socket, config)
|
|
54
|
+
|
|
55
|
+
self.class.set_permissions(filename, config)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def close
|
|
59
|
+
if stream
|
|
60
|
+
path = stream.path
|
|
61
|
+
stream.close
|
|
62
|
+
self.stream = nil
|
|
63
|
+
|
|
64
|
+
log.debug("unlinking #{path}")
|
|
65
|
+
File.unlink(path)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
close_shutdown_pipe
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def accept
|
|
72
|
+
socket = super
|
|
73
|
+
|
|
74
|
+
UnixProtocol.apply_sockopt(socket)
|
|
75
|
+
BasicConnection.new(self, socket)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def self.set_permissions(filename, config)
|
|
79
|
+
owner = config[:unix_owner]
|
|
80
|
+
group = config[:unix_group]
|
|
81
|
+
mode = config[:unix_mode]
|
|
82
|
+
|
|
83
|
+
if owner || group
|
|
84
|
+
require 'etc'
|
|
85
|
+
owner = Etc.getpwnam(owner).uid if owner
|
|
86
|
+
group = Etc.getgrnam(group).gid if group
|
|
87
|
+
File.chown(owner, group, filename)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
File.chmod(mode, filename) if mode
|
|
91
|
+
end
|
|
92
|
+
private_class_method :set_permissions
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|