Net::Telnet, Terminal Programs, Prompts

M

Mike

Hi, I have been trying to create a Tk::Text that reads and writes to a
Net::Telnet object. It works fairly well, but doesnt handle terminal
types of programs like vi.

Just looking for any ideas from the experts. I dont know to much about
termianl emulations, etc.

Also, i get two prompts. Anyone know why i might be getting that from
Net::Telnet; I have prompt set to anything and timeout at 0, so i dont
match on prompt or block. I just poll every 1/4 sec. But what i read
with get, comes with two prompts. Any ideas on a better method let me
know. I was trying to keep from using prompt, allowing it to work no
matter what you logged into.

This script is an example of its use followed by the module itself
Note the ip is hardcoded so change to fit your system.

Thanks
Mike

############################################################

use strict;
use Tk;
use lib 'lib';
use Tk::ECC::Telnet;

my $mw = new MainWindow();
my $tn = $mw->Telnet->pack(-side => 'top', -expand => '1', -fill =>
'both');
my $bt = $mw->Button(-text => 'Connect', -command => [\&connect,
$tn])->pack(-expand => '1', -fill => 'x');
MainLoop;

sub connect {
my $tn = shift;
print "Connecting to $tn\n";
$tn->conn('10.1.24.226');
}

##############################################################

Here is the Module Tk::ECC::Telnet

# -------------------------------------------------------------------
# Tk Widget based on Standard Tk::Text and Net::Telnet
# -------------------------------------------------------------------

package Tk::ECC::Telnet;

use Net::Telnet;
use base qw(Tk::Derived Tk::Text);
Construct Tk::Widget 'Telnet';

sub ClassInit {
my ($class, $mw) = @_;
$class->SUPER::ClassInit($mw);
$mw->bind($class,'<Return>', \&Return)
#$mw->bind($class, '<KeyPress>', \&keypress);
}

sub Populate {
my ($self, $args) = @_;
my $ip = '192.168.2.10';
$self->SUPER::populate($args);
$self->{END} = 0.0;
$self->{KEY} = 0;
$self->{TELNET} = new Net::Telnet( Timeout => 0, Prompt => '//',);
$self->{TELNET}->errmode("return");
}

sub conn {
my ($self, $ip) = @_;
$self->{TELNET}->open($ip);
$self->repeat('250', [\&read_telnet, $self])
}

sub disconn {
print "Disccc\n";
my ($self,) = shift;
$self->{TELNET}->print("exit");
#$self->cancel('250', [\&read_telnet, $self])
}

sub insert {
#print "insert [@_]\n";
my ($self) = shift;
$self->SUPER::insert(@_);
return if ($self->{KEY});
print "Setting End\n";
$self->{END} = $self->index('insert');
}

sub Return {
#print "Return [@_]\n";
my $self = shift;
return unless ($self->compare($self->index('insert'), '>=',
$self->{END}));
my $cmd = $self->get($self->{END}, 'end');
$self->SUPER::Insert("\n");
$self->{TELNET}->print($cmd);
$self->{TELNET}->timeout(1);
$self->{TELNET}->getline();
$self->{TELNET}->getline();
$self->{TELNET}->timeout(0);
}

sub Backspace {
#print "BackSpace [@_]\n";
my $self = shift;
print $self->index('insert') . ">" . $self->{END} . "\n";
return unless ($self->compare($self->index('insert'), '>',
$self->{END}));
$self->SUPER::Backspace;
}

sub InsertKeypress {
#print "InsertKeypress [@_]\n";
my ($self, $key) = @_;
return unless ($self->compare($self->index('insert'), '>=',
$self->{END}));
$self->{KEY} = 1;
$self->SUPER::InsertKeypress($key);
$self->{KEY} = 0;
#print "END is currently " . $self->{END} . "\n";
}

sub read_telnet {
my ($self) = shift;
while (my $data = $self->{TELNET}->get()) {
print "Data [$data]\n";
$self->insert('end', $data);
$self->see('end');
$self->markSet('insert', 'end');
}
}

1;
 
M

Mike

Thanks for taking a look.

If you change the ip address and place the module where you can load
it, you should get a text box display with a connect button. Once i
press the button, i get whatever the host telnet echos out. Mine shows
a login prompt. Which i then can enter into the text box username and
password. I then see the command prompt and can type commands in.

Do you get anything after pressing the connect? If so make sure you
select the Text box in order to enter commands. I have added a focus in
the module now, but it is missing in what i posted.

I am now trying to use Term::VT120 along with Net::Telnet
The Term allows somewhat of the terminal buffering i need which i poll
for the current screen and update the Text Box. It works fairly well
also. But i currently dont sedn anything to the Telnet obj until i hit
return. But with programs like more for example, i need space to
immediately be sent. Or if an editor like vi, i need esc to be sent
right away.

If you can think of anything or have any ideas, please post.

Thanks
Mike

Hi, I have been trying to create a Tk::Text that reads and writes to a
Net::Telnet object. It works fairly well, but doesnt handle terminal
types of programs like vi.

Just looking for any ideas from the experts. I dont know to much about
termianl emulations, etc.

Also, i get two prompts. Anyone know why i might be getting that from
Net::Telnet; I have prompt set to anything and timeout at 0, so i dont
match on prompt or block. I just poll every 1/4 sec. But what i read
with get, comes with two prompts. Any ideas on a better method let me
know. I was trying to keep from using prompt, allowing it to work no
matter what you logged into.

This script is an example of its use followed by the module itself
Note the ip is hardcoded so change to fit your system.

Thanks
Mike

############################################################

use strict;
use Tk;
use lib 'lib';
use Tk::ECC::Telnet;

my $mw = new MainWindow();
my $tn = $mw->Telnet->pack(-side => 'top', -expand => '1', -fill =>
'both');
my $bt = $mw->Button(-text => 'Connect', -command => [\&connect,
$tn])->pack(-expand => '1', -fill => 'x');
MainLoop;

sub connect {
my $tn = shift;
print "Connecting to $tn\n";
$tn->conn('10.1.24.226');
}

##############################################################

Here is the Module Tk::ECC::Telnet

# -------------------------------------------------------------------
# Tk Widget based on Standard Tk::Text and Net::Telnet
# -------------------------------------------------------------------

package Tk::ECC::Telnet;

use Net::Telnet;
use base qw(Tk::Derived Tk::Text);
Construct Tk::Widget 'Telnet';

sub ClassInit {
my ($class, $mw) = @_;
$class->SUPER::ClassInit($mw);
$mw->bind($class,'<Return>', \&Return)
#$mw->bind($class, '<KeyPress>', \&keypress);
}

sub Populate {
my ($self, $args) = @_;
my $ip = '192.168.2.10';
$self->SUPER::populate($args);
$self->{END} = 0.0;
$self->{KEY} = 0;
$self->{TELNET} = new Net::Telnet( Timeout => 0, Prompt => '//',);
$self->{TELNET}->errmode("return");
}

sub conn {
my ($self, $ip) = @_;
$self->{TELNET}->open($ip);
$self->repeat('250', [\&read_telnet, $self])
}

sub disconn {
print "Disccc\n";
my ($self,) = shift;
$self->{TELNET}->print("exit");
#$self->cancel('250', [\&read_telnet, $self])
}

sub insert {
#print "insert [@_]\n";
my ($self) = shift;
$self->SUPER::insert(@_);
return if ($self->{KEY});
print "Setting End\n";
$self->{END} = $self->index('insert');
}

sub Return {
#print "Return [@_]\n";
my $self = shift;
return unless ($self->compare($self->index('insert'), '>=',
$self->{END}));
my $cmd = $self->get($self->{END}, 'end');
$self->SUPER::Insert("\n");
$self->{TELNET}->print($cmd);
$self->{TELNET}->timeout(1);
$self->{TELNET}->getline();
$self->{TELNET}->getline();
$self->{TELNET}->timeout(0);
}

sub Backspace {
#print "BackSpace [@_]\n";
my $self = shift;
print $self->index('insert') . ">" . $self->{END} . "\n";
return unless ($self->compare($self->index('insert'), '>',
$self->{END}));
$self->SUPER::Backspace;
}

sub InsertKeypress {
#print "InsertKeypress [@_]\n";
my ($self, $key) = @_;
return unless ($self->compare($self->index('insert'), '>=',
$self->{END}));
$self->{KEY} = 1;
$self->SUPER::InsertKeypress($key);
$self->{KEY} = 0;
#print "END is currently " . $self->{END} . "\n";
}

sub read_telnet {
my ($self) = shift;
while (my $data = $self->{TELNET}->get()) {
print "Data [$data]\n";
$self->insert('end', $data);
$self->see('end');
$self->markSet('insert', 'end');
}
}

1;
 
M

Mike

I am in this to learn also, i have gathered so much from the postings
on this newsgroup. If you are interested, i have a version using
Term::VT102
that is working fairly well. If you would like send me an email and i
will email you a zip of it. Email to [jmw_misc at hotmail dot com]

Confused on your login, must be something to do with what telnet daemon
you are connecting to. I have only tried to telnet to a Sun box Solaris
2.5.1

I will try to telnet to a windows daemon this weekend at home.

Yes this is a work in progress, so i have not tidied evrything up like
the repeat call back. The new module has that fixed, but still a bunch
of testing things for troubleshooting.

Like the Web page 'JAPH' although it scares people at work when i have
the volume on, LOL. Cant wait til i can figure out how to write a cool
perl hack name.

Mike

Thanks for taking a look.

Purely selfish motives...I want to learn how to do it :)
If you change the ip address and place the module where you can load
it, you should get a text box display with a connect button. Once i
press the button, i get whatever the host telnet echos out. Mine shows
a login prompt. Which i then can enter into the text box username and
password. I then see the command prompt and can type commands in.

Do you get anything after pressing the connect? If so make sure you
select the Text box in order to enter commands. I have added a focus in
the module now, but it is missing in what i posted.

What happens with me, is I connect, then I get a login prompt.
I enter my name and press enter.
Then it returns A Password prompt, followed by "Login incorrect"
even before I get a chance to type in the password. Then another login
prompt appears.

( I have a test user 'z')
#################################################
darkstar login: z
Password: Login incorrect

darkstar login:
##################################################

Thats why I suggested you may need expect or IPC::Open3 to handle
the transaction.
But you probably could do it through your Telnet object methods, maybe
have a separate logon sub, for handling the login?

Maybe you could pass the username and password as args to your
new Telnet, and when you connect, do a

$self->{TELNET}->open($ip);
$self->{TELNET}->login($username, $password);

I tried this with no luck
#----------------------------------------------------------
sub conn {
my ( $self, $ip ) = @_;
$self->{TELNET}->open($ip);
$self->after( '250', [ \&read_telnet, $self ] );
$self->{TELNET}->login('z','foopass');
$self->repeat( '250', [ \&read_telnet, $self ] );
}
#-----------------------------------------------------------


By the way:

I see where you need to cancel your repeater, but have it
cancelled out. You could do something like:

self->{repeater} = $self->repeat( '250', [ \&read_telnet, $self ] );
and later
self->{repeater}->cancel;

#############################################

After toying with how it works, and seeing how it works from
a commandline version, it seems you are close to getting it to work.
Goodluck.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top