summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorytti <saku@ytti.fi>2018-06-14 17:19:38 +0300
committerGitHub <noreply@github.com>2018-06-14 17:19:38 +0300
commit136c7fc10e0265fba614fff6aa6ba00bb9485bda (patch)
treea05762db9490b6c556ff4b962731d8556030ebd5
parentca938529738a411bd5a96b20f1509dfa5aa6f1ca (diff)
Fix 1385 - telnet broken
Refactor to common login method to ssh/telnet was broken, as common login method made assumptions of expect and cmd API which weren't true for telnet. telnet.rb updated to resemble ssh.rb API.
-rw-r--r--lib/oxidized/input/telnet.rb102
-rw-r--r--lib/oxidized/version.rb2
2 files changed, 30 insertions, 74 deletions
diff --git a/lib/oxidized/input/telnet.rb b/lib/oxidized/input/telnet.rb
index 102bc8c..63d811f 100644
--- a/lib/oxidized/input/telnet.rb
+++ b/lib/oxidized/input/telnet.rb
@@ -25,16 +25,19 @@ module Oxidized
rescue Timeout::Error
raise PromptUndetect, ['unable to detect prompt:', @node.prompt].join(' ')
end
+ connected?
end
def connected?
@telnet and not @telnet.sock.closed?
end
- def cmd cmd, expect = @node.prompt
- Oxidized.logger.debug "Telnet: #{cmd} @#{@node.name}"
- args = { 'String' => cmd }
- args.merge!({ 'Match' => expect, 'Timeout' => @timeout }) if expect
+ def cmd cmd_str, expect = @node.prompt
+ return send(cmd_str + "\n") unless expect
+ Oxidized.logger.debug "Telnet: #{cmd_str} @#{@node.name}"
+ args = { 'String' => cmd_str,
+ 'Match' => expect,
+ 'Timeout' => @timeout }
@telnet.cmd args
end
@@ -49,7 +52,7 @@ module Oxidized
private
def expect re
- @telnet.waitfor 'Match' => re, 'Timeout' => @timeout
+ @telnet.oxidized_expect expect: re, timeout: @timeout
end
def disconnect
@@ -66,75 +69,36 @@ module Oxidized
end
class Net::Telnet
- ## FIXME: we just need 'line = model.expects line' to handle pager
## how to do this, without redefining the whole damn thing
## FIXME: we also need output (not sure I'm going to support this)
attr_reader :output
- def waitfor(options) # :yield: recvdata
- time_out = @options["Timeout"]
- waittime = @options["Waittime"]
- fail_eof = @options["FailEOF"]
+ def oxidized_expect(options) # :yield: recvdata
model = @options["Model"]
@log = @options["Log"]
- if options.kind_of?(Hash)
- prompt = if options.has_key?("Match")
- options["Match"]
- elsif options.has_key?("Prompt")
- options["Prompt"]
- elsif options.has_key?("String")
- Regexp.new(Regexp.quote(options["String"]))
- end
- time_out = options["Timeout"] if options.has_key?("Timeout")
- waittime = options["Waittime"] if options.has_key?("Waittime")
- fail_eof = options["FailEOF"] if options.has_key?("FailEOF")
- else
- prompt = options
- end
-
- if time_out == false
- time_out = nil
- end
+ expects = [options[:expect]].flatten
+ time_out = options[:timeout] || @options["Timeout"] || Oxidized.config.timeout?
- line = ''
- buf = ''
- rest = ''
- until prompt === line and not IO::select([@sock], nil, nil, waittime)
- unless IO::select([@sock], nil, nil, time_out)
- raise Timeout::Error, "timed out while waiting for more data"
- end
- begin
+ Timeout::timeout(time_out) do
+ line = ""
+ rest = ""
+ buf = ""
+ loop do
c = @sock.readpartial(1024 * 1024)
@output = c
- @dumplog.log_dump('<', c) if @options.has_key?("Dump_log")
- if @options["Telnetmode"]
- c = rest + c
- if Integer(c.rindex(/#{IAC}#{SE}/no) || 0) <
- Integer(c.rindex(/#{IAC}#{SB}/no) || 0)
- buf = preprocess(c[0...c.rindex(/#{IAC}#{SB}/no)])
- rest = c[c.rindex(/#{IAC}#{SB}/no)..-1]
- elsif pt = c.rindex(/#{IAC}[^#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]?\z/no) ||
- c.rindex(/\r\z/no)
- buf = preprocess(c[0...pt])
- rest = c[pt..-1]
- else
- buf = preprocess(c)
- rest = ''
- end
+ c = rest + c
+
+ if Integer(c.rindex(/#{IAC}#{SE}/no) || 0) <
+ Integer(c.rindex(/#{IAC}#{SB}/no) || 0)
+ buf = preprocess(c[0...c.rindex(/#{IAC}#{SB}/no)])
+ rest = c[c.rindex(/#{IAC}#{SB}/no)..-1]
+ elsif pt = c.rindex(/#{IAC}[^#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]?\z/no) ||
+ c.rindex(/\r\z/no)
+ buf = preprocess(c[0...pt])
+ rest = c[pt..-1]
else
- # Not Telnetmode.
- #
- # We cannot use preprocess() on this data, because that
- # method makes some Telnetmode-specific assumptions.
- buf = rest + c
+ buf = preprocess(c)
rest = ''
- unless @options["Binmode"]
- if pt = buf.rindex(/\r\z/no)
- buf = buf[0...pt]
- rest = buf[pt..-1]
- end
- buf.gsub!(/#{EOL}/no, "\n")
- end
end
if Oxidized.config.input.debug?
@log.print buf
@@ -142,17 +106,9 @@ class Net::Telnet
end
line += buf
line = model.expects line
- line = yield line if block_given?
- yield buf if block_given?
- rescue EOFError # End of file reached
- raise if fail_eof
- if line == ''
- line = nil
- yield nil if block_given?
- end
- break
+ match = expects.find { |re| line.match re }
+ return match if match
end
end
- line
end
end
diff --git a/lib/oxidized/version.rb b/lib/oxidized/version.rb
index 4b710ef..c44884a 100644
--- a/lib/oxidized/version.rb
+++ b/lib/oxidized/version.rb
@@ -1,6 +1,6 @@
module Oxidized
VERSION = '0.23.0'
- VERSION_FULL = '0.23.0'
+ VERSION_FULL = '0.23.0-19-g4690521'
def self.version_set
version_full = %x(git describe --tags).chop rescue ""
version = %x(git describe --tags --abbrev=0).chop rescue ""