metasploit-framework/lib/rex/io/bidirectional_pipe.rb

152 lines
2.1 KiB
Ruby
Raw Normal View History

module Rex
module IO
require 'rex/ui/text/output'
require 'rex/ui/text/output/buffer'
require 'rex/ui/text/input/buffer'
class BidirectionalPipe < Rex::Ui::Text::Input
def initialize
@subscribers_out = {}
@subscribers_ref = {}
@subscribers_idx = 0
@pipe_input = Rex::Ui::Text::Input::Buffer.new
# We are the shell, the input, and the output
self.output = self
self.input = self
end
def pipe_input
@pipe_input
end
def close
@pipe_input.close
end
def has_subscriber?(id)
@subscribers_out.has_key?(id)
end
def create_subscriber(id=nil)
id ||= (@subscribers_idx += 1).to_s
@subscribers_out[id] = Rex::Ui::Text::Output::Buffer.new
return id
end
def create_subscriber_proc(id=nil, &block)
id = create_subscriber(id)
@subscribers_ref[id] = block
end
def remove_subscriber(id)
@subscribers_out.delete(id)
@subscribers_ref.delete(id)
end
def write_input(buf)
@pipe_input.put(buf)
end
def read_subscriber(id)
output = @subscribers_out[id]
return '' if output.nil?
buf = output.buf
output.reset
buf
end
def print(msg='')
@subscribers_out.each_pair { |id, buf|
begin
@subscribers_ref[id] ? @subscribers_ref[id].call(msg) : buf.print(msg)
rescue ::Exception => e
# $stderr.puts "Error handling subscriber #{id}: #{e} #{e.backtrace.inspect}"
raise e
end
}
msg
end
def print_error(msg='')
print_line('[-] ' + msg)
end
def print_line(msg='')
print(msg + "\n")
end
def print_good(msg='')
print_line('[+] ' + msg)
end
def flush
end
def print_status(msg='')
print_line('[*] ' + msg)
end
#
# Wrappers for the pipe_input methods
#
def close
@pipe_input.close
end
def sysread(len = 1)
@pipe_input.sysread(len)
end
def put(msg)
@pipe_input.put(msg)
end
def gets
@pipe_input.gets
end
def eof?
@pipe_input.eof?
end
def fd
@pipe_input.fd
end
#
# Wrappers for shell methods
#
attr_accessor :output, :prompt, :input
def intrinsic_shell?
true
end
def supports_readline
false
end
def supports_color?
false
end
def pgets
gets
end
protected
end
end
end