Telnet Ruby

Hi!

I am currently working on project which demands to dump raw data from
the target.
I am using a BDI2000 setup with telnet server.

The attached zip contains the design of the ruby script I am intending
to program and also the attempt I have made.

Will be glad if some one can help me out.

AG.

Amogh G. wrote:

I am currently working on project which demands to dump raw data from
the target.
I am using a BDI2000 setup with telnet server.

The attached zip contains the design of the ruby script I am intending
to program and also the attempt I have made.

Will be glad if some one can help me out.

http://www.catb.org/~esr/faqs/smart-questions.html#intro

That is: describe your problem. Provide minimal code which reproduces
it, and any error you see, or what you actually get compared to what you
expected to get.

I am able to use the script with a single prompt.
I am unable to make use of multiple prompts…

Amogh.

Amogh G. wrote:

I am able to use the script with a single prompt.
I am unable to make use of multiple prompts…

That’s not a description of your problem.

  • Post a minimal code example which replicates the problem
  • Show where it goes wrong

For example (this is just a guess): you’ve written some code which
connects to a device, sends one command, receives the reply, sends
another command. However it hangs after receiving the first reply. So
you want to know why it’s hanging. So show the code, with the extra
STDERR.puts debugging statements you’ve put in, so we can see exactly at
what point it hangs.

On 7/22/09, Amogh G. [email protected] wrote:

HI!

the current code which I am using is (also attached):
[snip]

I don’t know anything about this telnet library, but there seem to be
a couple of obvious problems with this code you’ve posted. First your
RBDI class doesn’t have a method named send_1. Presumably, you meant
send instead? Second, your @prompt variable is set to /BDI>/ initially
and never changed. So how could you expect it to be /-- Target
stopped/?(Unless @connection.waitfor changes it somehow, which seems
unlikely.)

I am looking at bdi.send_1 to send instructions when the @promt is /–
Target stopped/. I need to add a procedure in rbdi.rb for send_1 which
sends commands @prompt /-- Target stopped/, and I am unable to do this.

This made no sense. Please try to explain again.

HI!

the current code which I am using is (also attached):

-------Dump_Collect.rb--------
require ‘rbdi’
require ‘net/telnet’

HERE = File.dirname(File.expand_path(FILE))

bdi = RBDI.new({‘Host’ => ‘bdiemul’})
bdi.quiet = false

bdi.send_1 <<-LOAD_SCRIPT
re
ci
bi 0x00002e04
go
LOAD_SCRIPT

for k in 1…250

bdi.send_1 <<-LOAD_SCRIPT
dump 0x003f72e0 128
C:/EBAC_VnV/CCA/PBLSP/Results/Dump/Discrete_Services/atl_#{k}.dat
go
LOAD_SCRIPT

end

sleep 1


--------rbdi.rb-------
require ‘net/telnet’

class RBDI

attr_accessor :quiet

def initialize(options)
@prompt = /BDI>/
@quiet = options[‘Quiet’]
@quiet = true if @quiet.nil?

@connection = Net::Telnet.new({'Host'   => options['Host'],
                               'Prompt' => @prompt}) {|str| print 

str unless @quiet}

# consume the initial display of help
@connection.waitfor(@prompt) {|str| print str unless @quiet}

end

Send a script of commands to the BDI

If script is a filename, the commands will be read from the file.

The Quiet option specified at creating may be overruled for this

script.
def send(script, options={‘Quiet’ => @quiet})
script = File.new(script) if FileTest.file? script

begin
  script.each_line do |command|
    @connection.cmd({'String' => command.strip}.merge(options)) do 

|str|
print str unless str.nil? or options[‘Quiet’]
end
end
rescue Errno::ECONNRESET, Errno::ECONNABORTED
puts “Connection closed” unless options[‘Quiet’]
return
end
end

end

I am looking at bdi.send_1 to send instructions when the @promt is /–
Target stopped/. I need to add a procedure in rbdi.rb for send_1 which
sends commands @prompt /-- Target stopped/, and I am unable to do this.

Amogh.

Amogh G. wrote:

I am looking at bdi.send_1 to send instructions when the @promt is /–
Target stopped/. I need to add a procedure in rbdi.rb for send_1 which
sends commands @prompt /-- Target stopped/, and I am unable to do this.

Sorry, you’ve lost me there.

You can set the expected prompt on each call to Net::Telnet#cmd as an
option, which you should be able to pass through to your RBDI#send
method:

bdi.send(“Prompt” => /-- Target stopped/)

Or is the problem that you might have two possible prompts in response
to one command? Then you can do

res = @connection.cmd(“Prompt” => /-- Target stopped|BDI>/)

and check the value of res to see which of the two patterns was matched,
and take action accordingly.

Or is the problem that you want to send N different commands with N
different prompts? Then you can pass an array of arrays, or an array of
hashes:

bdi.send([
{“String”=>“cmd1”, “Prompt”=>/Prompt1/},
{“String”=>“cmd2”, “Prompt”=>/Prompt2/},
])

Again, I must stress this: try to boil your problem down to as small a
possible test case which shows the problem you are having. In this case
I think it should be 10 lines or less.

There are three important reasons for doing this:

  1. In the process of boiling it down, you may find and fix the problem

  2. In the process of boiling it down, you will in any case learn more
    about what you’re trying to do

  3. It makes it much, much easier for someone to help you, when you can
    point to exactly where the problem lies. In the above reply I had to
    guess what your problem is, which wastes my time, and probably didn’t
    solve the problem anyway.

Regards,

Brian.

Thanks Brian!

The problem is that “I might have two possible prompts in response to
one command”

When I execute the command “go” on Telnet, I can either get the:
prompt 1: BDI> (or)
prompt 2: - TARGET: stopped \n BDI>

When I get prompt 1, I want it to send in the instructions:
“re”
“ci”
“bi 0x000044bc”
“go 0”

However when i get prompt 2, i want to send in the instructions:
“dump 0x003f7670 128 C:/Dump/atl.dat”
“go”.

Based on ur suggestion I modified the code to (also attached):

class RBDI_test

attr_accessor :quiet

def initialize(options)
@prompt = /- TARGET: stopped \n BDI>|BDI>/
@quiet = options[‘Quiet’]
@quiet = true if @quiet.nil?

@connection = Net::Telnet.new({'Host'   => options['Host'],
                               'Prompt' => @prompt}) {|str| print 

str unless @quiet}

# consume the initial display of help
@connection.waitfor(@prompt) {|str| print str unless @quiet}

end

Send a script of commands to the BDI

If script is a filename, the commands will be read from the file.

The Quiet option specified at creating may be overruled for this

script.
def send(script, options={‘Quiet’ => @quiet})
script = File.new(script) if FileTest.file? script

begin
  script.each_line do |command|
    @connection.cmd(command.strip) do |str|
      print str unless str.nil? or options['Quiet']
    end
  end
rescue Errno::ECONNRESET, Errno::ECONNABORTED
  puts "Connection closed" unless options['Quiet']
  return
end

end

end

AND

require ‘rbdi_test’

bdi = RBDI_test.new({‘Host’ => ‘bdiemul’})
bdi.quiet = false

bdi.send(“Prompt”=>/BDI>/) <<-LOAD_SCRIPT
re
ci
bi 0x000044bc
go 0
LOAD_SCRIPT

j = true

while j

bdi.send(“Prompt”=>/- TARGET: stopped \n BDI>/) <<-LOAD_SCRIPT
dump 0x003f7670 128 C:Dump/atl.dat
go
LOAD_SCRIPT

end

sleep 1

I end up with the error:
C:/load565-released/test.rb:18: syntax error, unexpected tINTEGER,
expecting kEND
dump 0x003f7670 128 C:Dump/atl.dat

Amogh.
^

Amogh G. wrote:

When I execute the command “go” on Telnet, I can either get the:
prompt 1: BDI> (or)
prompt 2: - TARGET: stopped \n BDI>

When I get prompt 1, I want it to send in the instructions:
“re”
“ci”
“bi 0x000044bc”
“go 0”

However when i get prompt 2, i want to send in the instructions:
“dump 0x003f7670 128 C:/Dump/atl.dat”
“go”.

Then I’d say you should still just look for the BDI> prompt as before -
because that’s when you want to stop reading the response - but check
the result from the cmd to see if it contains the string “TARGET:
stopped” or not.

res = cmd “go 0x003f7670 128 C:/Dump/atl.dat”
if res =~ /TARGET: stopped/
cmd "dump "
cmd “go 0”
else
cmd “re”
cmd “ci”
cmd “bi 0x000044bc”
cmd “go 0”
end

Based on ur suggestion I modified the code to (also attached):

I end up with the error:
C:/load565-released/test.rb:18: syntax error, unexpected tINTEGER,
expecting kEND
dump 0x003f7670 128 C:Dump/atl.dat

I think that’s because of this construct:

bdi.send(“Prompt”=>/BDI>/) <<-LOAD_SCRIPT

LOAD_SCRIPT

Imagine you wrote it with a normal string, then you would have the
following:

bdi.send(“Prompt”=>"/BDI/) “re\nci\n”

I think it’s clear this is nonsense. What you really want is

bdi.send(<<-LOAD_SCRIPT, “Prompt”=>/BDI>/)

LOAD_SCRIPT

HTH,

Brian.

Rilindo F. wrote:

Not to ask you to think about a different solution, but since you are
sending input based on certain output values, would the Ruby Expect
method be more appropriate?

I’d say that Net::Telnet is the right tool for the job here - he’s
telnetting to a device. The Net::Telnet class deals with a lot of telnet
protocol issues for you.

Not to ask you to think about a different solution, but since you are
sending input based on certain output values, would the Ruby Expect
method be more appropriate?