Read data from the host until a certain sequence is matched.
If a block is given, the received data will be yielded as it is read in
(not necessarily all in one go), or nil if EOF occurs before any data is
received. Whether a block is given or not, all data read will be returned
in a single string, or again nil if EOF occurs before any data is received.
Note that received data includes the matched sequence we were looking for.
options can be either a regular expression or a hash of options.
If a regular expression, this specifies the data to wait for. If a hash,
this can specify the following options:
Match
a regular expression, specifying the data to wait for.
Prompt
as for Match; used only if Match is not specified.
the number of seconds to wait for data from the host before raising a Timeout::Error. If set to false, no timeout
will occur. If not specified, the Timeout
option value specified when this instance was created will be used, or,
failing that, the default value of 10 seconds.
Waittime
the number of seconds to wait after matching against the input data to see
if more data arrives. If more data arrives within this time, we will judge
ourselves not to have matched successfully, and will continue trying to
match. If not specified, the Waittime option value specified when this
instance was created will be used, or, failing that, the default value of 0
seconds, which means not to wait for more input.
FailEOF
if true, when the remote end closes the connection then an EOFError will be raised. Otherwise, defaults to
the old behaviour that the function will return whatever data has been
received already, or nil if nothing was received.
# File lib/net/telnet.rb, line 528
def waitfor(options) # :yield: recvdata
time_out = @options["Timeout"]
waittime = @options["Waittime"]
fail_eof = @options["FailEOF"]
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
line = ''
buf = ''
rest = ''
until(prompt === line and not IO::select([@sock], nil, nil, waittime))
unless IO::select([@sock], nil, nil, time_out)
raise Net::ReadTimeout, "timed out while waiting for more data"
end
begin
c = @sock.readpartial(1024 * 1024)
@dumplog.log_dump('<', c) if @options.has_key?("Dump_log")
if @options["Telnetmode"]
c = rest + c
if Integer(c.rindex(/#{IAC}#{SE}/o) || 0) <
Integer(c.rindex(/#{IAC}#{SB}/o) || 0)
buf = preprocess(c[0 ... c.rindex(/#{IAC}#{SB}/o)])
rest = c[c.rindex(/#{IAC}#{SB}/o) .. -1]
elsif pt = c.rindex(/#{IAC}[^#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]?\z/o) ||
c.rindex(/\r\z/o)
buf = preprocess(c[0 ... pt])
rest = c[pt .. -1]
else
buf = preprocess(c)
rest = ''
end
else
# Not Telnetmode.
#
# We cannot use preprocess() on this data, because that
# method makes some Telnetmode-specific assumptions.
buf = rest + c
rest = ''
unless @options["Binmode"]
if pt = buf.rindex(/\r\z/o)
buf = buf[0 ... pt]
rest = buf[pt .. -1]
end
buf.gsub!(/#{EOL}/o, "\n")
end
end
@log.print(buf) if @options.has_key?("Output_log")
line += buf
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
end
end
line
end