| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- package Rstat::cmd;
- #
- # Copyright (C) Roman Dmitiriev, rnd@rajven.ru
- #
- use strict;
- use English;
- use FindBin '$Bin';
- use lib "$Bin";
- use base 'Exporter';
- use vars qw(@EXPORT @ISA);
- use Data::Dumper;
- use Rstat::config;
- use Rstat::main;
- use Net::Telnet;
- @ISA = qw(Exporter);
- @EXPORT = qw( log_cmd log_cmd2 log_cmd3 log_cmd4 flush_telnet run_command);
- BEGIN
- {
- #---------------------------------------------------------------------------------
- # Execute command and wait answer from device
- # Args: t - telnet session, $command - command string, $sleep - pause after execute command (enabled by default)
- #
- sub log_cmd {
- my $t = shift;
- my $command = shift;
- my $sleep = shift || 1;
- if (!$t) { die "Telnet session not exists!"; }
- $t->binmode(0);
- $t->errmode('return');
- log_session('Send:'.$command);
- my @ret=$t->cmd(String => $command);
- my @a=();
- foreach my $row (@ret) {
- next if (!$row);
- #zyxel patch
- $row=~ s/\x1b\x37//g;
- #mikrotik patch
- $row=~ s/\x0d\x0d\x0d\x1b\x5b\x39\x39\x39\x39\x42//g;
- #new line
- $row=~ s/\n//g;
- $row=trim($row);
- if ($row) {
- my @tmp=split("\n",$row);
- foreach my $line (@tmp) {
- next if (!$line);
- $line=trim($line);
- next if (!$line);
- push(@a,$line);
- log_session('Get:'.$line);
- }
- }
- }
- select(undef, undef, undef, 0.15) if ($sleep);
- if (scalar(@a)) { return @a; }
- $t->cmd(String => "\n");
- my @tmp=flush_telnet($t);
- foreach my $line (@tmp) {
- next if (!$line);
- push(@a,$line);
- }
- return @a;
- }
- #---------------------------------------------------------------------------------
- # Execute command list array without confirmation from device
- # Args: t - telnet session, $command - array of command string, $sleep - pause after execute command (enabled by default)
- #
- sub log_cmd2 {
- my $t = shift;
- my $command = shift;
- my $sleep = shift || 1;
- if (!$t) { die "Telnet session not exists!"; }
- $t->binmode(0);
- $t->errmode("return");
- $t->cmd(String => "\n");
- $t->buffer_empty;
- my @a;
- foreach my $out (split("\n",$command)){
- if ($out =~ /SLEEP/) {
- if ($out =~ /SLEEP\s+(\d+)/) { sleep($1); } else { sleep(5); };
- next;
- }
- chomp($out);
- log_session('Send:'.$out);
- $t->print($out);
- #sleep 250 ms
- select(undef, undef, undef, 0.25) if ($sleep);
- foreach my $str ($t->waitfor($t->prompt)) {
- $str=trim($str);
- if ($str) {
- my @tmp=split("\n",$str);
- foreach my $line (@tmp) {
- next if (!$line);
- $line=trim($line);
- next if (!$line);
- push(@a,$line);
- log_session('Get:'.$line);
- }
- }
- }
- }
- chomp(@a);
- return @a;
- }
- #---------------------------------------------------------------------------------
- # Execute command list array without confirmation from device and press any key by device prompt
- # Args: t - telnet session, $command - array of command string, $sleep - pause after execute command (enabled by default)
- #
- sub log_cmd3 {
- my $t = shift;
- my $lines = shift;
- my $sleep = shift || 1;
- if (!$t) { die "Telnet session not exists!"; }
- $t->errmode("return");
- $t->buffer_empty;
- $t->binmode(0);
- my @result=();
- foreach my $out (split("\n",$lines)) {
- if ($out =~ /SLEEP/i) {
- if ($out =~ /SLEEP\s+(\d+)/i) { log_session('WAIT:'." $1 sec."); sleep($1); } else { log_session('WAIT:'." 10 sec."); sleep(10); };
- next;
- }
- chomp($out);
- log_session('Send:'.$out);
- $t->print($out);
- #sleep 250 ms
- select(undef, undef, undef, 0.25) if ($sleep);
- my $end = 0;
- my $get;
- while ($end == 0) {
- foreach my $str ($t->waitfor('/[(#)(\>)(\:)(press)(sure)(Please input)(next page)(continue)(quit)(-- more --)(Confirm)(ESC)(^C$)]/')) {
- $t->print("\n") if $str =~ /ENTER/i;
- $t->print(" ") if $str =~ /ESC/i;
- $t->print(" ") if $str =~ /^C$/i;
- $t->print(" ") if $str =~ /(-- more --)/i;
- $t->print(" ") if $str =~ /SPACE/i;
- $t->print("y\n") if $str =~ /sure/i;
- $t->print("\n") if $str =~ /continue/i;
- $t->print("y\n") if $str =~ /Please input/i;
- $t->print("Y\n") if $str =~ /Confirm/i;
- $t->print("Y\n") if $str =~ /\:/;
- #last line!!!
- $end = 1 if $str =~ /\>/;
- $get .= $str;
- }
- }
- log_debug('Get:'.$get) if ($get);
- push(@result,split(/\n/,$get));
- }
- log_session('Get:'.Dumper(\@result));
- return @result;
- }
- #---------------------------------------------------------------------------------
- # Execute command list array without confirmation from device and press any key by device prompt
- # Args: t - telnet session, $command - array of command string, $sleep - pause after execute command (enabled by default)
- #
- sub log_cmd4 {
- my $t = shift;
- my $lines = shift;
- if (!$t) { die "Telnet session not exists!"; }
- $t->errmode("return");
- $t->buffer_empty;
- $t->binmode(0);
- my @result=();
- log_session('Send:'.$lines);
- $t->print($lines);
- #sleep 250 ms
- select(undef, undef, undef, 0.25);
- my ($prematch, $match)=$t->waitfor('/\[.*\] >/');
- log_debug("Get: $prematch, $match");
- push(@result,split(/\n/,$prematch));
- log_session('Get:'.Dumper(\@result));
- return @result;
- }
- #---------------------------------------------------------------------------------
- sub flush_telnet {
- my $t = shift;
- return if (!$t);
- my @a=();
- $t->buffer_empty;
- $t->print("\n");
- foreach my $str ($t->waitfor($t->prompt)) {
- next if (!$str);
- my @tmp=split("\n",$str);
- foreach my $row (@tmp) {
- $row=trim($row);
- next if (!$row);
- log_session('Flush:'.$row);
- push(@a,$row);
- }
- }
- $t->buffer_empty;
- return(@a);
- }
- #---------------------------------------------------------------------------------
- sub run_command {
- my $t=shift;
- my $cmd=shift;
- my $cmd_id = shift || 1;
- my @tmp=();
- if (ref($cmd) eq 'ARRAY') {
- @tmp = @{$cmd};
- } else {
- push(@tmp,$cmd);
- }
- eval {
- foreach my $run_cmd (@tmp) {
- next if (!$run_cmd);
- log_cmd($t,$run_cmd) if ($cmd_id == 1);
- log_cmd2($t,$run_cmd) if ($cmd_id == 2);
- log_cmd3($t,$run_cmd) if ($cmd_id == 3);
- }
- };
- if ($@) { log_error("Abort: $@"); return 0; };
- return 1;
- }
- 1;
- }
|