153 lines
2.1 KiB
Ruby
153 lines
2.1 KiB
Ruby
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.to_s} #{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
|