cmd.pm 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. package Rstat::cmd;
  2. #
  3. # Copyright (C) Roman Dmitiriev, rnd@rajven.ru
  4. #
  5. use strict;
  6. use English;
  7. use FindBin '$Bin';
  8. use lib "$Bin";
  9. use base 'Exporter';
  10. use vars qw(@EXPORT @ISA);
  11. use Data::Dumper;
  12. use Rstat::config;
  13. use Rstat::main;
  14. use Net::Telnet;
  15. @ISA = qw(Exporter);
  16. @EXPORT = qw( log_cmd log_cmd2 log_cmd3 log_cmd4 flush_telnet run_command);
  17. BEGIN
  18. {
  19. #---------------------------------------------------------------------------------
  20. # Execute command and wait answer from device
  21. # Args: t - telnet session, $command - command string, $sleep - pause after execute command (enabled by default)
  22. #
  23. sub log_cmd {
  24. my $t = shift;
  25. my $command = shift;
  26. my $sleep = shift || 1;
  27. if (!$t) { die "Telnet session not exists!"; }
  28. $t->binmode(0);
  29. $t->errmode('return');
  30. log_session('Send:'.$command);
  31. my @ret=$t->cmd(String => $command);
  32. my @a=();
  33. foreach my $row (@ret) {
  34. next if (!$row);
  35. #zyxel patch
  36. $row=~ s/\x1b\x37//g;
  37. #mikrotik patch
  38. $row=~ s/\x0d\x0d\x0d\x1b\x5b\x39\x39\x39\x39\x42//g;
  39. #new line
  40. $row=~ s/\n//g;
  41. $row=trim($row);
  42. if ($row) {
  43. my @tmp=split("\n",$row);
  44. foreach my $line (@tmp) {
  45. next if (!$line);
  46. $line=trim($line);
  47. next if (!$line);
  48. push(@a,$line);
  49. log_session('Get:'.$line);
  50. }
  51. }
  52. }
  53. select(undef, undef, undef, 0.15) if ($sleep);
  54. if (scalar(@a)) { return @a; }
  55. $t->cmd(String => "\n");
  56. my @tmp=flush_telnet($t);
  57. foreach my $line (@tmp) {
  58. next if (!$line);
  59. push(@a,$line);
  60. }
  61. return @a;
  62. }
  63. #---------------------------------------------------------------------------------
  64. # Execute command list array without confirmation from device
  65. # Args: t - telnet session, $command - array of command string, $sleep - pause after execute command (enabled by default)
  66. #
  67. sub log_cmd2 {
  68. my $t = shift;
  69. my $command = shift;
  70. my $sleep = shift || 1;
  71. if (!$t) { die "Telnet session not exists!"; }
  72. $t->binmode(0);
  73. $t->errmode("return");
  74. $t->cmd(String => "\n");
  75. $t->buffer_empty;
  76. my @a;
  77. foreach my $out (split("\n",$command)){
  78. if ($out =~ /SLEEP/) {
  79. if ($out =~ /SLEEP\s+(\d+)/) { sleep($1); } else { sleep(5); };
  80. next;
  81. }
  82. chomp($out);
  83. log_session('Send:'.$out);
  84. $t->print($out);
  85. #sleep 250 ms
  86. select(undef, undef, undef, 0.25) if ($sleep);
  87. foreach my $str ($t->waitfor($t->prompt)) {
  88. $str=trim($str);
  89. if ($str) {
  90. my @tmp=split("\n",$str);
  91. foreach my $line (@tmp) {
  92. next if (!$line);
  93. $line=trim($line);
  94. next if (!$line);
  95. push(@a,$line);
  96. log_session('Get:'.$line);
  97. }
  98. }
  99. }
  100. }
  101. chomp(@a);
  102. return @a;
  103. }
  104. #---------------------------------------------------------------------------------
  105. # Execute command list array without confirmation from device and press any key by device prompt
  106. # Args: t - telnet session, $command - array of command string, $sleep - pause after execute command (enabled by default)
  107. #
  108. sub log_cmd3 {
  109. my $t = shift;
  110. my $lines = shift;
  111. my $sleep = shift || 1;
  112. if (!$t) { die "Telnet session not exists!"; }
  113. $t->errmode("return");
  114. $t->buffer_empty;
  115. $t->binmode(0);
  116. my @result=();
  117. foreach my $out (split("\n",$lines)) {
  118. if ($out =~ /SLEEP/i) {
  119. if ($out =~ /SLEEP\s+(\d+)/i) { log_session('WAIT:'." $1 sec."); sleep($1); } else { log_session('WAIT:'." 10 sec."); sleep(10); };
  120. next;
  121. }
  122. chomp($out);
  123. log_session('Send:'.$out);
  124. $t->print($out);
  125. #sleep 250 ms
  126. select(undef, undef, undef, 0.25) if ($sleep);
  127. my $end = 0;
  128. my $get;
  129. while ($end == 0) {
  130. foreach my $str ($t->waitfor('/[(#)(\>)(\:)(press)(sure)(Please input)(next page)(continue)(quit)(-- more --)(Confirm)(ESC)(^C$)]/')) {
  131. $t->print("\n") if $str =~ /ENTER/i;
  132. $t->print(" ") if $str =~ /ESC/i;
  133. $t->print(" ") if $str =~ /^C$/i;
  134. $t->print(" ") if $str =~ /(-- more --)/i;
  135. $t->print(" ") if $str =~ /SPACE/i;
  136. $t->print("y\n") if $str =~ /sure/i;
  137. $t->print("\n") if $str =~ /continue/i;
  138. $t->print("y\n") if $str =~ /Please input/i;
  139. $t->print("Y\n") if $str =~ /Confirm/i;
  140. $t->print("Y\n") if $str =~ /\:/;
  141. #last line!!!
  142. $end = 1 if $str =~ /\>/;
  143. $get .= $str;
  144. }
  145. }
  146. log_debug('Get:'.$get) if ($get);
  147. push(@result,split(/\n/,$get));
  148. }
  149. log_session('Get:'.Dumper(\@result));
  150. return @result;
  151. }
  152. #---------------------------------------------------------------------------------
  153. # Execute command list array without confirmation from device and press any key by device prompt
  154. # Args: t - telnet session, $command - array of command string, $sleep - pause after execute command (enabled by default)
  155. #
  156. sub log_cmd4 {
  157. my $t = shift;
  158. my $lines = shift;
  159. if (!$t) { die "Telnet session not exists!"; }
  160. $t->errmode("return");
  161. $t->buffer_empty;
  162. $t->binmode(0);
  163. my @result=();
  164. log_session('Send:'.$lines);
  165. $t->print($lines);
  166. #sleep 250 ms
  167. select(undef, undef, undef, 0.25);
  168. my ($prematch, $match)=$t->waitfor('/\[.*\] >/');
  169. log_debug("Get: $prematch, $match");
  170. push(@result,split(/\n/,$prematch));
  171. log_session('Get:'.Dumper(\@result));
  172. return @result;
  173. }
  174. #---------------------------------------------------------------------------------
  175. sub flush_telnet {
  176. my $t = shift;
  177. return if (!$t);
  178. my @a=();
  179. $t->buffer_empty;
  180. $t->print("\n");
  181. foreach my $str ($t->waitfor($t->prompt)) {
  182. next if (!$str);
  183. my @tmp=split("\n",$str);
  184. foreach my $row (@tmp) {
  185. $row=trim($row);
  186. next if (!$row);
  187. log_session('Flush:'.$row);
  188. push(@a,$row);
  189. }
  190. }
  191. $t->buffer_empty;
  192. return(@a);
  193. }
  194. #---------------------------------------------------------------------------------
  195. sub run_command {
  196. my $t=shift;
  197. my $cmd=shift;
  198. my $cmd_id = shift || 1;
  199. my @tmp=();
  200. if (ref($cmd) eq 'ARRAY') {
  201. @tmp = @{$cmd};
  202. } else {
  203. push(@tmp,$cmd);
  204. }
  205. eval {
  206. foreach my $run_cmd (@tmp) {
  207. next if (!$run_cmd);
  208. log_cmd($t,$run_cmd) if ($cmd_id == 1);
  209. log_cmd2($t,$run_cmd) if ($cmd_id == 2);
  210. log_cmd3($t,$run_cmd) if ($cmd_id == 3);
  211. }
  212. };
  213. if ($@) { log_error("Abort: $@"); return 0; };
  214. return 1;
  215. }
  216. 1;
  217. }