demo/echo_server.rb
require 'logger'
require 'socket'
def start_service io, logger=nil
begin
require 'hrr_rb_ssh'
rescue LoadError
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
require 'hrr_rb_ssh'
end
auth_password = HrrRbSsh::Authentication::Authenticator.new { |context|
true # accept any user and password
}
conn_echo = HrrRbSsh::Connection::RequestHandler.new { |context|
context.chain_proc { |chain|
begin
loop do
buf = context.io[0].readpartial(10240)
break if buf.include?(0x04.chr) # break if ^D
context.io[1].write buf
end
exitstatus = 0
rescue => e
logger.error([e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join)
exitstatus = 1
end
exitstatus
}
}
options = {}
options['authentication_password_authenticator'] = auth_password
options['connection_channel_request_shell'] = conn_echo
server = HrrRbSsh::Server.new options, logger: logger
server.start io
end
class MyLoggerFormatter < ::Logger::Formatter
def call severity, time, progname, msg
"%s, [%s#%d.%x] %5s -- %s: %s\n" % [severity[0..0], format_datetime(time), Process.pid, Thread.current.object_id, severity, progname, msg2str(msg)]
end
end
logger = Logger.new STDOUT
logger.level = Logger::INFO
logger.formatter = MyLoggerFormatter.new
server = TCPServer.new 10022
loop do
Thread.new(server.accept) do |io|
begin
pid = fork do
begin
start_service io, logger
rescue => e
logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
exit false
end
end
logger.info { "process #{pid} started" }
io.close rescue nil
pid, status = Process.waitpid2 pid
rescue => e
logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
ensure
status ||= nil
logger.info { "process #{pid} finished with status #{status.inspect}" }
end
end
end