tags:

views:

536

answers:

3

I got a problem connecting to a SUSE linux machine by Perl's Net::Telnet module. The code looks like below:

my $t = new Net::Telnet (Timeout => 20);
$t->open($server);
$t->input_log("telnet.log");
$t->login($user, $pass);
my @lines=$t->cmd($command);
print @lines;

The log file looks like below: Welcome to SUSE Linux Enterprise Server 10 SP1 (x86_64) - Kernel 2.6.16.46-0.12-default (5).

vm-sles10u5 login: <myuser>
Password: 
Last login: Thu Feb 25 10:41:07 EST 2010 from <mymachine> on pts/5
tset: unknown terminal type network
Terminal type? 

Any suggestions?

+1  A: 

See this discussion for the same problem. The solution (untested) that they propose is to set the TERM enviromental variable to a known value, such as TERM=vt100

Leon Timmermans
I see the same discussion, but how? Do I need to "export TERM=vt100" on my local machine or export that in the .profile of the remote machine for the telnet user? Thanks!
root1982
@root1982 or say `$ENV{TERM}='vt100'` in your Perl script
mobrule
Thanks everybody. I still have the same problem.
root1982
A: 

In /etc/profile, you should find the following line:

test -x /usr/bin/tset && /usr/bin/tset -I -Q

This is the line that causing the problem. You can confirm with running the following command:

$>TERM=network
$>/usr/bin/tset -I -Q
tset: unknown terminal type network
Terminal type? 

In /usr/share/terminfo/n/, network is a link to ../n/net. I don't know why system does not work for "network".

The temp fix is to change the line in /etc/profile to the following:

test -x /usr/bin/tset && /usr/bin/tset -I -Q -m network:vt100

The above command will map network to vt100.

root1982
+1  A: 

If you use the option_log function to log the telnet options received and returned. You will see that Perl does not send the terminal type to the server by default. Server will default the terminal type to "network" for some reasons.

The right way to do this is to set the terminal type on the perl side.

my $termtype = 'vt100'; my $telopt_ttype_ok = '';
my $t = new Net::Telnet (Timeout => 5);

$t->option_callback(\&opt_callback);
$t->option_accept(Do=>Net::Telnet->TELOPT_TTYPE);
$t->suboption_callback(\&subopt_callback);

$t->open($server);
$t->input_log("runRemoteCommand_telnet.log");
$t->login($user, $pass);
$t->cmd($command);

exit 0;

sub opt_callback { 
  my ($obj, $option, $is_remote, $is_enabled, $was_enabled, $buf_position) = @_;
  if ($option == Net::Telnet->TELOPT_TTYPE and $is_enabled and !$is_remote) {
    $telopt_ttype_ok = 1; 
   }
   1;
}

sub subopt_callback {
 my ($obj, $option, $parameters) = @_; 
 my ($ors_old, $otm_old);
 if ($option == Net::Telnet->TELOPT_TTYPE) 
 {
  $ors_old = $obj->output_record_separator('');
  $otm_old = $obj->telnetmode (0);
  $obj->print("\xff\xfa", pack("CC", $option, 0), $termtype, "\xff\xf0");
  $obj->output_record_separator($ors_old);
  $obj->telnetmode ($otm_old);
 }
 1;
}

Refer to this

root1982