=================================================================== RCS file: /cvs/trango/Net-Telnet-Trango/lib/Net/Telnet/Trango.pm,v retrieving revision 1.2 retrieving revision 1.5 diff -u -r1.2 -r1.5 --- trango/Net-Telnet-Trango/lib/Net/Telnet/Trango.pm 2005/12/30 01:02:41 1.2 +++ trango/Net-Telnet-Trango/lib/Net/Telnet/Trango.pm 2006/01/03 00:22:19 1.5 @@ -1,5 +1,5 @@ package Net::Telnet::Trango; -# $RedRiver$ +# $RedRiver: Trango.pm,v 1.4 2005/12/30 20:26:41 andrew Exp $ use strict; use warnings; use base 'Net::Telnet'; @@ -13,12 +13,9 @@ =head1 SYNOPSIS use Net::Telnet::Trango; - my $t = new Net::Telnet::Trango ({ - Host => $fox, - Timeout => 5, - }); + my $t = new Net::Telnet::Trango ( Timeout => 5 ); - my ($type, $version) = $t->open; + my ($type, $version) = $t->open( Host => $fox ); unless (defined $type && defined $version) { die "Error connecting: $!"; @@ -52,6 +49,111 @@ =pod +=item new + +Same as new from L but has defaults for the trango 'Prompt' + +=cut + +sub new +{ + my $class = shift; + + my %args; + if (@_ == 1) { + $args{'Host'} = shift; + } else { + %args = @_; + } + + $args{'Prompt'} ||= '/#> *$/'; + + foreach my $key (keys %args) { + $PRIVATE{$key} = $args{$key}; + } + + my $self = $class->SUPER::new(%args); + bless $self if ref $self; + + return $self; +} + +# _password +# ? [command] +# apsearch [ ]... +# arp -bcast +# bcastscant [ ... +# bye +# cf2cf ap [default|] +# date +# date +# freq scantable +# freq channeltable +# freq writescan [ ] +# freq writechannel [ ] ... +# freq +# help [command] +# heater [ ] +# ipconfig [ ] +# log [<# of entries, 1..179>] +# log <# of entries, 1..179> +# logout +# opmode [ap [y]] +# password +# ping +# polar +# power > +# reboot +# restart +# remarks [] +# rfrxthreshold [ <-90|-85|-80|-75|-70|-65>] +# rfrxth [ <-90|-85|-80|-75|-70|-65>] +# sysinfo +# set suid +# set apid +# set baseid +# set defaultopmode [ ] +# set defaultopmode off +# set snmpcomm [ ] +# set mir [on|off] +# set mir threshold +# set rssitarget [ ] +# set serviceradius [ ] +# ssrssi +# su [|all] +# su changechannel +# su ipconfig +# su [live|poweroff|priority] +# su +# su powerleveling +# su reboot +# su restart +# su testrflink [r] +# su testrflink [64..1600] +# su testrflink [20..100] +# su sw +# sudb [dload | view] +# sudb add pr +# sudb add reg +# sudb delete > +# sudb modify +# sudb modify +# sudb view +# sulog [lastmins | sampleperiod <1..60>] +# sulog [<# of entry,1..18>] +# survey +# sw [ ] +# temp +# tftpd [on|off] +# time +# time +# save +# save +# updateflash +# updateflash + +=pod + =head1 METHODS =head2 ACCESSORS @@ -106,9 +208,9 @@ alias of exit() -=item reboot +=item restart -alias of restart() +alias of reboot() =back @@ -141,91 +243,26 @@ reboots the trango and closes the connection -=cut +=item sulog -# _password -# ? [command] -# apsearch [ ]... -# arp -bcast -# bcastscant [ ... -# bye -# cf2cf ap [default|] -# date -# date -# freq scantable -# freq channeltable -# freq writescan [ ] -# freq writechannel [ ] ... -# freq -# help [command] -# heater [ ] -# ipconfig [ ] -# log [<# of entries, 1..179>] -# log <# of entries, 1..179> -# logout -# opmode [ap [y]] -# password -# ping -# polar -# power > -# reboot -# restart -# remarks [] -# rfrxthreshold [ <-90|-85|-80|-75|-70|-65>] -# rfrxth [ <-90|-85|-80|-75|-70|-65>] -# sysinfo -# set suid -# set apid -# set baseid -# set defaultopmode [ ] -# set defaultopmode off -# set snmpcomm [ ] -# set mir [on|off] -# set mir threshold -# set rssitarget [ ] -# set serviceradius [ ] -# ssrssi -# su [|all] -# su changechannel -# su ipconfig -# su [live|poweroff|priority] -# su -# su powerleveling -# su reboot -# su restart -# su testrflink [r] -# su testrflink [64..1600] -# su testrflink [20..100] -# su sw -# sudb [dload | view] -# sudb add pr -# sudb add reg -# sudb delete > -# sudb modify -# sudb modify -# sudb view -# sulog [lastmins | sampleperiod <1..60>] -# sulog [<# of entry,1..18>] -# survey -# sw [ ] -# temp -# tftpd [on|off] -# time -# time -# save -# save -# updateflash -# updateflash +returns an array ref of hashes containing each log line. +=cut + my $success = 'Success.'; my %COMMANDS = ( - tftpd => { decode => 1, expect => $success }, - ver => { decode => 1 }, - sysinfo => { decode => 1, expect => $success }, - updateflash => { decode => 1, expect => $success }, - 'exit' => { Prompt => '//', cmd_disconnects => 1 }, - reboot => { Prompt => '//', cmd_disconnects => 1 }, + tftpd => { decode => 'all', expect => $success }, + ver => { decode => 'all' }, + sysinfo => { decode => 'all', expect => $success }, + updateflash => { decode => 'all', expect => $success }, + sulog => { decode => 'sulog', expect => $success }, + 'exit' => { no_prompt => 1, cmd_disconnects => 1 }, + reboot => { no_prompt => 1, cmd_disconnects => 1 }, + #su password??? + #_bootloader + #temp + #heater ); my %ALIASES = ( @@ -242,6 +279,7 @@ login_banner Timeout last_lines + last_vals ); sub AUTOLOAD @@ -257,6 +295,7 @@ } if (exists $COMMANDS{$method}) { + $method = shift if (@_ == 1); $COMMANDS{$method}{'String'} ||= $method; return $self->cmd(%{ $COMMANDS{$method} }, @_); } @@ -273,54 +312,28 @@ =pod -=item new - -=cut - -sub new -{ - my $class = shift; - my $args = shift || {}; - - $args->{'Timeout'} ||= 5; - $args->{'Prompt'} ||= '/#> *$/'; - - foreach my $key (keys %{ $args }) { - $PRIVATE{$key} = $args->{$key}; - } - - my $self = $class->SUPER::new(%{ $args }); - bless $self if ref $self; - - return $self; -} - -=pod - =item open +Calls Net::Telnet::open() then makes sure you get a password prompt so you are ready to login() and parses the login banner so you can get host_type() and firmware_version() + =cut sub open { my $self = shift; - unless ( $self->SUPER::open( - #Host => $self->Host, - #Errmode => 'return', - ) ) { + unless ( $self->SUPER::open(@_) ) { #$! = "Couldn't connect to " . $self->Host . ": $!"; return undef; } - #$self->dump_log('dump.log'); - ## Login to remote host. + ## Get to login prompt unless ($self->waitfor( - -match => '/password: ?$/i', - -errmode => "return", - ) ) { - #$! = "problem connecting to host (" . $self->Host . "): " . - # $self->lastline; + -match => '/password: ?$/i', + -errmode => "return", + ) ) { + #$! = "problem connecting to host (" . $self->Host . "): " . + # $self->lastline; return undef; } @@ -335,6 +348,8 @@ =item login +Calls open() if not already connected, then sends the password and sets logged_in() if successful + =cut sub login @@ -365,6 +380,8 @@ =item parse_login_banner +Takes a login banner (what you get when you first connect to the Trango) or reads what is already in login_banner() then parses it and sets host_type() and firmware_version() as well as login_banner() + =cut sub parse_login_banner @@ -389,8 +406,82 @@ =pod +=item su_password + +C + +=cut + +sub su_password +{ + my $self = shift; + my $su = shift || '!'; + my $new_pass = shift || ''; + + unless (defined $su) { + warn "No su passed!" + #return undef; + } + + unless (defined $new_pass) { + warn "No new password!" + #return undef; + } + + return $self->cmd(String => 'su password ' . + $su . ' ' . + $new_pass . ' ' . + $new_pass, + expect => $success, + ); +} + + +=pod + +=item sudb_view + +returns a reference to an array of hashes each containing: + + suid + type + cir + mir + mac + +=cut + +sub sudb_view +{ + my $self = shift; + + my @lines = $self->cmd( String => 'sudb view', expect => $success ); + + return undef unless @lines; + + my @sus; + foreach (@lines) { + if (/^\[(\d+)\]\s+(\d+)\s+(\d+)\s+(\d+)\s+([0-9a-fA-F]+)/) { + my %s = ( + suid => $1, + type => $2, + cir => $3, + mir => $4, + mac => $5, + ); + push @sus, \%s; + } + } + + return \@sus; +} + +=pod + =item enable_tftpd +runs C 'on')> and makes sure that Tftpd is now 'listen'ing + =cut sub enable_tftpd @@ -410,6 +501,8 @@ =item disable_tftpd +runs C 'off')> and makes sure that Tftpd is now 'disabled' + =cut sub disable_tftpd @@ -429,6 +522,24 @@ =item cmd +This does most of the work. At the heart, it calls Net::Telnet::cmd() but it also does some special stuff for Trango. + +Normally returns the last lines from from the command + +Also accepts these options: + +I +- if this is true, then it will send the output lines to _decode_lines() and then returns the decoded output + +I +- if this is true, it then sets logged_in() to false, then it will close() the connection and then sets is_connected() to false + +I +- if this is set (usually to 'Success.') it will check for that in the last line of output and if it does not, will return undef because the command probably failed + +I +- a string containing the command line options that are passed to the command + =cut sub cmd @@ -459,19 +570,19 @@ unless ($cfg{'String'}) { #$! = "No command passed"; - warn "No command passed\n"; + #warn "No command passed\n"; return undef; } unless ($self->is_connected) { #$! = "Not connected"; - warn "Not connected\n"; + #warn "Not connected\n"; return undef; } unless ($self->logged_in) { #$! = "Not logged in"; - warn "Not logged in\n"; + #warn "Not logged in\n"; return undef; } @@ -485,16 +596,30 @@ if ($cfg{'args'}) { $cmd{'String'} .= ' ' . $cfg{'args'}; } - my @lines = $self->SUPER::cmd(%cmd); + my @lines; + unless ($cfg{'no_prompt'}) { + @lines = $self->SUPER::cmd(%cmd); + } else { + $self->print($cmd{'String'}); + @lines = $self->lastline; + } $self->last_lines(\@lines); my $vals = 1; if ($cfg{'decode'}) { - $vals = _decode_lines(@lines); + if ($cfg{'decode'} eq 'each') { + $vals = _decode_each_line(@lines); + } elsif ($cfg{'decode'} eq 'sulog') { + $vals = _decode_sulog(@lines); + } else { + $vals = _decode_lines(@lines); + } } + $self->last_vals($vals); + my $last = $self->lastline; if ((not $cfg{'expect'}) || $last =~ /$cfg{'expect'}$/) { @@ -529,6 +654,8 @@ my $in_val = 0; foreach my $line (@lines) { + next if $line =~ /$success$/; + my @chars = split //, $line; my $last_key = ''; @@ -580,18 +707,54 @@ if (%conf) { return \%conf; } else { - return \@lines; + return undef; } } +#=item _decode_each_line + +sub _decode_each_line +{ + my @lines = @_; + my @decoded; + foreach my $line (@lines) { + my $decoded = _decode_lines($line); + push @decoded, $decoded if defined $decoded; + } + return \@decoded; +} + +#=item _decode_sulog + +sub _decode_sulog +{ + my @lines = @_; + my @decoded; + my $last_tm; + foreach my $line (@lines) { + my $decoded = _decode_lines($line); + + if (defined $decoded) { + if ($decoded->{'tm'}) { + $last_tm = $decoded->{'tm'}; + next; + } else { + $decoded->{'tm'} = $last_tm; + } + next unless $last_tm; + + push @decoded, $decoded if defined $decoded; + } + } + return \@decoded; +} + 1; __END__ =back =head1 SEE ALSO - -If you have a web site set up for your module, mention it here. Trango Documentation - http://www.trangobroadband.com/support/product_docs.htm