From af496d2efa0969f29a22a4236c620f513eb90287 Mon Sep 17 00:00:00 2001 From: Tar Committer Date: Fri, 3 Aug 2001 03:13:25 +0000 Subject: Imported from rancid-2.2b5.tar.gz. --- bin/Makefile.in | 13 ++ bin/alogin.in | 57 ++++--- bin/arancid.in | 15 +- bin/cat5rancid.in | 4 +- bin/clogin.in | 146 +++++++++++++----- bin/control_rancid.in | 48 ++++-- bin/create_cvs.in | 2 +- bin/do-diffs.in | 25 +++- bin/elogin.in | 24 ++- bin/env.in | 11 +- bin/erancid.in | 4 +- bin/flogin.in | 35 +++-- bin/francid.in | 2 +- bin/jlogin.in | 64 ++++++-- bin/jrancid.in | 17 ++- bin/par.in | 2 +- bin/rancid-fe.in | 4 +- bin/rancid.in | 50 ++++--- bin/rrancid.in | 2 +- bin/xrancid.in | 407 ++++++++++++++++++++++++++++++++++++++++++++++++++ 20 files changed, 773 insertions(+), 159 deletions(-) create mode 100755 bin/xrancid.in (limited to 'bin') diff --git a/bin/Makefile.in b/bin/Makefile.in index 04b2545..511ad6b 100644 --- a/bin/Makefile.in +++ b/bin/Makefile.in @@ -1,3 +1,16 @@ +## Copyright (C) 1997-2001 by Henry Kilmer, Erik Sherk and Pete Whiting. +## All rights reserved. +## +## This software may be freely copied, modified and redistributed without +## fee for non-commerical purposes provided that this copyright notice is +## preserved intact on all copies and modified copies. +## +## There is no warranty or other guarantee of fitness of this software. +## It is provided solely "as is". The author(s) disclaim(s) all +## responsibility and liability with respect to this software's usage +## or its effect upon hardware, computer systems, other software, or +## anything else. + PREFIX = @prefix@ INSTALL = @INSTALL@ diff --git a/bin/alogin.in b/bin/alogin.in index fe55787..8ccf37b 100755 --- a/bin/alogin.in +++ b/bin/alogin.in @@ -1,7 +1,7 @@ #!@EXPECT_PATH@ -- ## ## -## Copyright (C) 1997 by Henry Kilmer, Erik Sherk and Pete Whiting. +## Copyright (C) 1997-2001 by Henry Kilmer, Erik Sherk and Pete Whiting. ## All rights reserved. ## ## This software may be freely copied, modified and redistributed without @@ -23,10 +23,10 @@ # # Usage line -set usage "Usage: $argv0 \[-c command\]\ -\[-f cloginrc-file\]\ -\[-s script-file\] \[-t timeout\] \[-u username\]\ -\[-v vty-password\] \[-x command-file\]\ +set usage "Usage: $argv0 \[-c command\] \ +\[-Evar=x\] \[-f cloginrc-file\] \ +\[-s script-file\] \[-t timeout\] \[-u username\] \ +\[-v vty-password\] \[-x command-file\] \ \[-y ssh_cypher_type\] router \[router...\]\n" # env(CLOGIN) may contain: @@ -88,9 +88,19 @@ for {set i 0} {$i < $argc} {incr i} { } -w* - -W* { # ignore -w + # Environment variable to pass to -s scripts + } -E* + { + if {[ regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} { + incr i + set E$varname $varvalue + } else { + send_user "Error: invalid format for -E in $arg\n" + exit 1 + } # Enable Password - } -e* - - -E* { + } -e* + { # ignore -e # Command to run. } -c* - @@ -140,7 +150,10 @@ for {set i 0} {$i < $argc} {incr i} { incr i set cmd_file [ lindex $argv $i ] } - set cmd_fd [open $cmd_file r] + if [ catch {set cmd_fd [open $cmd_file r]} reason ] { + send_user "\nError: $reason\n" + exit 1 + } set cmd_text [read $cmd_fd] close $cmd_fd set command [join [split $cmd_text \n] \;] @@ -320,7 +333,7 @@ proc login { router user userpswd passwd prompt cmethod cyphertype } { catch {close}; wait; return 1 } eof { send_user "Error: Couldn't login\n"; wait; return 1 } -re "$p_prompt" { send "$userpswd\r" } - "$prompt" { set in_proc 0; return 0 } + -re "$prompt" { set in_proc 0; return 0 } } exp_continue } @@ -329,7 +342,7 @@ proc login { router user userpswd passwd prompt cmethod cyphertype } { "Password incorrect" { send_user "Error: Couldn't login\n"; catch {close}; wait; return 1 } eof { send_user "Error: Couldn't login\n"; wait; return 1 } - "$prompt" { set in_proc 0; return 0 } + -re "$prompt" { set in_proc 0; return 0 } "Confirm seeing above note" { send "y\r" } } exp_continue @@ -337,7 +350,7 @@ proc login { router user userpswd passwd prompt cmethod cyphertype } { -re "^Confirm seeing above note" { send "y\r" } "Password incorrect" { send_user "Error: Check your password for $router\n"; catch {close}; wait; return 1 } - "$prompt" { } + -re "$prompt" { } denied { send_user "Error: Check your passwd for $router\n" if { $do_command || $do_script } { send "exit\r" @@ -347,7 +360,7 @@ proc login { router user userpswd passwd prompt cmethod cyphertype } { return 1 } } - "\r\n" { exp_continue; } + "\r\n" { exp_continue; } } set in_proc 0 return 0 @@ -360,7 +373,7 @@ proc run_commands { prompt command } { set in_proc 1 send "lines 0\r" - expect $prompt {} + expect -re $prompt {} regsub -all "\[)(]" $prompt {\\&} reprompt @@ -368,21 +381,20 @@ proc run_commands { prompt command } { if [ string match "*\;*" "$command" ] { set commands [split $command \;] set num_commands [llength $commands] - for {set i 0} {$i < $num_commands} { incr i} { send "[subst -nocommands [lindex $commands $i]]\r" expect { - -re "^\[^\n\r]*$reprompt." {} + -re "^\[^\n\r]*$reprompt" {} -re "^\[^\n\r ]*>>.*$reprompt" { exp_continue } - -re "\[\n\r]" { exp_continue } + -re "\[\n\r]+" { exp_continue } } } } else { send "[subst -nocommands $command]\r" expect { - -re "^\[^\n\r]*$reprompt." {} + -re "^\[^\n\r]*$reprompt" {} -re "^\[^\n\r ]*>>.*$reprompt" { exp_continue } - -re "\[\n\r]" { exp_continue } + -re "\[\n\r]+" { exp_continue } } } send "exit\r" @@ -410,9 +422,10 @@ foreach router [lrange $argv $i end] { send_user "$router\n" # Figure out prompt. - set prompt "#" - set autoenable 1 - set enable 0 + set prompt ">> \[^\r\n]*\[#|>] " + # alteon only "enables" based on the password used at login time + set autoenable 1 + set enable 0 # Figure out passwords if { $do_passwd } { @@ -472,7 +485,7 @@ foreach router [lrange $argv $i end] { } } elseif { $do_script } { send "lines 0\r" - expect $prompt {} + expect -re $prompt {} source $sfile close } else { diff --git a/bin/arancid.in b/bin/arancid.in index 5003ddd..f27e2ec 100755 --- a/bin/arancid.in +++ b/bin/arancid.in @@ -5,7 +5,7 @@ ## afort@choqolat.org (andrew fort) ## ## -## Copyright (C) 1997 by Henry Kilmer. +## Copyright (C) 1997-2001 by Henry Kilmer. ## All rights reserved. ## ## This software may be freely copied, modified and redistributed without @@ -170,17 +170,14 @@ sub WriteTerm { tr/\015//d; last if(/^>>.*$prompt/); chop; - print $ENV{'NOCOMMSTR'}; - /(rcomm|wcomm|t1com|t2com)(\s+)(.*)/ && + if (/(rcomm|wcomm|t1com|t2com)(\s+)(.*)/ && + defined($ENV{'NOCOMMSTR'})) { ProcessHistory("","","","\/\*\t$1$2\"\"\n") && next; - #if (/^\s*snmp/ && defined($ENV{'NOCOMMSTR'})) { - # /snmp (getcomm|setcomm|trapcomm)(\s+)(\S*)/ && - # ProcessHistory("","","","- snmp $1$2\"\"\n") && next; - #} + } next if (/^\/\* Configuration dump taken/i); - next if (/^\/\* Version.*Base MAC.*/i); + next if (/^\/\* Version.*Base MAC.*/i); - if (/^\/script end/) { + if (/^\/?script end/) { $found_end = 1; ProcessHistory("","","","$_\n"); return(1); diff --git a/bin/cat5rancid.in b/bin/cat5rancid.in index c5406b0..055ea04 100755 --- a/bin/cat5rancid.in +++ b/bin/cat5rancid.in @@ -1,7 +1,7 @@ #!@PERLV_PATH@ ## ## -## Copyright (C) 1997 by Henry Kilmer. +## Copyright (C) 1997-2001 by Henry Kilmer. ## All rights reserved. ## ## This software may be freely copied, modified and redistributed without @@ -1043,7 +1043,7 @@ ProcessHistory("COMMENTS","keysort","F0","!\n"); ProcessHistory("COMMENTS","keysort","G0","!\n"); TOP: while() { tr/\015//d; - if (/> \(enable\) exit$/) { + if (/> \(enable\) ?exit$/) { $clean_run=1; last; } diff --git a/bin/clogin.in b/bin/clogin.in index d1894b6..1929efd 100755 --- a/bin/clogin.in +++ b/bin/clogin.in @@ -1,7 +1,7 @@ #!@EXPECT_PATH@ -- ## ## -## Copyright (C) 1997 by Henry Kilmer, Erik Sherk and Pete Whiting. +## Copyright (C) 1997-2001 by Henry Kilmer, Erik Sherk and Pete Whiting. ## All rights reserved. ## ## This software may be freely copied, modified and redistributed without @@ -28,7 +28,7 @@ # Usage line set usage "Usage: $argv0 \[-autoenable\] \[-noenable\] \[-c command\] \ -\[-e enable-password\] \[-f cloginrc-file\] \[-p user-password\] \ +\[-Evar=x\] \[-e enable-password\] \[-f cloginrc-file\] \[-p user-password\] \ \[-s script-file\] \[-t timeout\] \[-u username\] \ \[-v vty-password\] \[-w enable-username\] \[-x command-file\] \ \[-y ssh_cypher_type\] router \[router...\]\n" @@ -49,6 +49,8 @@ set autoenable 0 # tracks if we receive them on the command line. set do_passwd 1 set do_enapasswd 1 +# attempt at platform switching. +set platform "" # Find the user in the ENV, or use the unix userid. if {[ info exists env(CISCO_USER) ] } { @@ -104,10 +106,19 @@ for {set i 0} {$i < $argc} {incr i} { incr i set enausername [ lindex $argv $i ] } + # Environment variable to pass to -s scripts + } -E* + { + if {[ regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} { + set E$varname $varvalue + } else { + send_user "Error: invalid format for -E in $arg\n" + exit 1 + } # Enable Password - } -e* - - -E* { - if {! [ regexp .\[eE\](.+) $arg ignore enapasswd]} { + } -e* + { + if {! [ regexp .\[e\](.+) $arg ignore enapasswd]} { incr i set enapasswd [ lindex $argv $i ] } @@ -160,7 +171,10 @@ for {set i 0} {$i < $argc} {incr i} { incr i set cmd_file [ lindex $argv $i ] } - set cmd_fd [open $cmd_file r] + if [ catch {set cmd_fd [open $cmd_file r]} reason ] { + send_user "\nError: $reason\n" + exit 1 + } set cmd_text [read $cmd_fd] close $cmd_fd set command [join [split $cmd_text \n] \;] @@ -264,9 +278,9 @@ proc source_password_file { password_file } { } # Log into the router. -proc login { router user userpswd passwd enapasswd prompt cmethod cyphertype } { - global spawn_id in_proc do_command do_script - global u_prompt p_prompt e_prompt +proc login { router user userpswd passwd enapasswd cmethod cyphertype } { + global spawn_id in_proc do_command do_script platform + global prompt u_prompt p_prompt e_prompt set in_proc 1 # try each of the connection methods in $cmethod until one is successful @@ -380,8 +394,9 @@ proc login { router user userpswd passwd enapasswd prompt cmethod cyphertype } { } } "% Bad passwords" {send_user "\nError: Check your passwd for $router\n"; return 1 } + } } -} + set in_proc 0 return 0 } @@ -411,55 +426,90 @@ proc do_enable { enauser enapasswd } { # Run commands given on the command line. proc run_commands { prompt command } { - global in_proc + global in_proc platform set in_proc 1 # If the prompt is (enable), then we are on a switch and the # command is "set length 0"; otherwise its "term length 0". - if [ string compare "> (enable) " "$prompt" ] { - send "term length 0\r" + # skip if its and extreme. + if { [ string compare "extreme" "$prompt" ] } { + if [ regexp -- ".*> .*enable" "$prompt" ] { + send "set length 0\r" + } else { + send "term length 0\r" + } + regsub -all "\[)(]" $prompt {\\&} reprompt + expect { + -re $reprompt {} + -re "\[\n\r]+" { exp_continue } + } } else { - send "set length 0\r" + regsub -all "\[)(]" $prompt {\\&} reprompt } - - expect $prompt {} - - regsub -all "\[)(]" $prompt {\\&} reprompt - + # this is the only way i see to get rid for more prompts in o/p..grrrrr + log_user 0 # Is this a multi-command? if [ string match "*\;*" "$command" ] { set commands [split $command \;] set num_commands [llength $commands] - # the pager can not be turned off on the PIX, so we have to look - # for the "More" prompt + # for the "More" prompt. the extreme is equally obnoxious, with a + # global switch in the config. for {set i 0} {$i < $num_commands} { incr i} { send "[subst -nocommands [lindex $commands $i]]\r" expect { - -re "^\[^\n\r *]*$reprompt" {} - -re "^\[^\n\r]*$reprompt." { exp_continue } - -re "^<--- More --->" { send " " + -re "^\[^\n\r *]*$reprompt" { send_user -- "$expect_out(buffer)" + } + -re "^\[^\n\r]*$reprompt." { send_user -- "$expect_out(buffer)" exp_continue } - -re "\[\n\r]" { exp_continue } + -re "\[\n\r]+" { send_user -- "$expect_out(buffer)" + exp_continue } + -re "\[^\r\n]*Press to cont\[^\r\n]*" { send " " + expect { + # gag, 2 more prompts + -re "\[\r\n]*\r" {} + -re "\[^\r\n]*Press to cont\[^\r\n]*" { send " "; exp_continue } + } + exp_continue + } + -re "^<-+ More -+>\[^\n\r]*" { send " " + exp_continue } + -re "\b+" { exp_continue } } } } else { # the pager can not be turned off on the PIX, so we have to look - # for the "More" prompt + # for the "More" prompt. the extreme is equally obnoxious, with a + # global switch in the config. send "[subst -nocommands $command]\r" expect { - -re "^\[^\n\r *]*$reprompt" {} - -re "^\[^\n\r]*$reprompt." { exp_continue } - -re "^<--- More --->" { send " " + -re "^\[^\n\r *]*$reprompt" { send_user -- "$expect_out(buffer)" + } + -re "^\[^\n\r]*$reprompt." { send_user -- "$expect_out(buffer)" + exp_continue } + -re "\[\n\r]+" { send_user -- "$expect_out(buffer)" exp_continue } - -re "\[\n\r]" { exp_continue } + -re "\[^\r\n]*Press to cont\[^\r\n]*" { send " " + expect { + -re "\[\r\n]*\r\r" {} + } + exp_continue + } + -re "^<-+ More -+>\[^\n\r]*" { send " " + exp_continue } + -re "\b+" { exp_continue } } } + log_user 1 send "exit\r" expect { - "\n" { exp_continue } - timeout { return 0 } - eof { return 0 } + "Do you wish to save your configuration changes" { + send "n\r" + exp_continue + } + "\n" { exp_continue } + timeout { return 0 } + eof { return 0 } } set in_proc 0 } @@ -500,11 +550,11 @@ foreach router [lrange $argv $i end] { if { $do_passwd || $do_enapasswd } { set pswd [find password $router] if { [llength $pswd] == 0 } { - send_user "Error - no password for $router in $password_file.\n" + send_user "Error: no password for $router in $password_file.\n" continue } - if { $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2 } { - send_user "Error - no enable password for $router in $password_file.\n" + if { $enable && $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2 } { + send_user "Error: no enable password for $router in $password_file.\n" continue } set passwd [lindex $pswd 0] @@ -560,7 +610,7 @@ foreach router [lrange $argv $i end] { if { "$cmethod" == "" } { set cmethod {{telnet} {ssh}} } # Login to the router - if {[login $router $ruser $userpswd $passwd $enapasswd $prompt $cmethod $cyphertype]} { + if {[login $router $ruser $userpswd $passwd $enapasswd $cmethod $cyphertype]} { continue } if { $enable } { @@ -571,6 +621,20 @@ foreach router [lrange $argv $i end] { } } } + # we are logged in, now figure out the full prompt + send "\r" + expect { + -re "\[\r\n]+" { exp_continue; } + -re "^(.+:)1 $prompt" { # stoopid extreme cmd-line numbers and + # prompt based on state of config changes + set junk $expect_out(1,string) + regsub -all "^\\\* " $expect_out(1,string) {} junk + set prompt ".? ?$junk\[0-9]+ $prompt"; + set platform "extreme" + } + -re "^.+$prompt" { set prompt $expect_out(0,string); } + -re "^.+> \\\(enable\\\)" { set prompt $expect_out(0,string); } + } if { $do_command } { if {[run_commands $prompt $command]} { @@ -579,13 +643,13 @@ foreach router [lrange $argv $i end] { } elseif { $do_script } { # If the prompt is (enable), then we are on a switch and the # command is "set length 0"; otherwise its "term length 0". - if [ string compare "> (enable) " "$prompt" ] { - send "term length 0\r" - } else { + if [ regexp -- ".*> .*enable" "$prompt" ] { send "set length 0\r" send "set logging session disable\r" + } else { + send "term length 0\r" } - expect $prompt {} + expect -re $prompt {} source $sfile close } else { diff --git a/bin/control_rancid.in b/bin/control_rancid.in index c61a0a4..ed8af8b 100755 --- a/bin/control_rancid.in +++ b/bin/control_rancid.in @@ -1,7 +1,7 @@ #!/bin/sh ## ## -## Copyright (C) 1996 by Henry Kilmer. +## Copyright (C) 1996-2001 by Henry Kilmer. ## All rights reserved. ## ## This software may be freely copied, modified and redistributed without @@ -38,9 +38,13 @@ then echo "$DIR does not exist." echo "Run bin/create_cvs $GROUP to make all of the needed directories." ( + echo "To: @MAILPLUS@admin-$GROUP" + echo "Subject: no $GROUP directory" + echo "Precedence: bulk" + echo "" echo "$DIR does not exist." echo "Run bin/create_cvs $GROUP to make all of the needed directories." - ) | Mail -s "no $GROUP directory" @MAILPLUS@admin-$GROUP + ) | sendmail -t exit 1 fi @@ -60,8 +64,12 @@ rm -f $TMP if [ ! -f $DIR/router.db ] then ( + echo "To: @MAILPLUS@admin-$GROUP" + echo "Subject: no $GROUP/router.db file" + echo "Precedence: bulk" + echo "" echo "$DIR/router.db does not exist." - ) | Mail -s "no $GROUP/router.db file" @MAILPLUS@admin-$GROUP + ) | sendmail -t exit 1; elif [ ! -s $DIR/router.db ] then @@ -119,7 +127,13 @@ then ) > routers.mail if [ -s routers.mail ] ; then - Mail -s "changes in $GROUP routers" @MAILPLUS@admin-$GROUP < routers.mail + ( + echo "To: @MAILPLUS@admin-$GROUP" + echo "Subject: changes in $GROUP routers" + echo "Precedence: bulk" + echo "" + cat routers.mail + ) | sendmail -t fi rm -f routers.mail @@ -149,8 +163,18 @@ mv routers.up.new routers.up rm -f routers.db trap 'rm -fr $TMP;' 1 2 15 -# cvs delete configs for routers not listed in routers.up. cd $DIR/configs +# check for 'up' routers missing in cvs. no idea how this happens to some folks +for router in `cut -d: -f1 ../routers.up` ; do + cvs status $router | grep -i 'status: unknown' > /dev/null 2>&1 + if [ $? -eq 0 ]; then + touch $router + cvs add -ko $router + echo "CVS added missing router $router" + fi + echo +done +# cvs delete configs for routers not listed in routers.up. for router in `find . \( -name \*.new -prune -o -name CVS -prune \) -o -type f -print | sed -e 's/^.\///'` ; do grep -i "^$router:" ../router.db > /dev/null 2>&1 if [ $? -eq 1 ]; then @@ -261,13 +285,15 @@ fi if [ -s $DIR/routers.failed ] then ( - cat </bin/env ## @@ -43,22 +55,27 @@ do if [ -s $TMPDIR/.$GROUP.old ] then ( - cat <) { tr/\015//d; diff --git a/bin/flogin.in b/bin/flogin.in index ac60bf3..85f77d6 100755 --- a/bin/flogin.in +++ b/bin/flogin.in @@ -1,7 +1,7 @@ #!@EXPECT_PATH@ -- ## ## -## Copyright (C) 1997 by Henry Kilmer, Erik Sherk and Pete Whiting. +## Copyright (C) 1997-2001 by Henry Kilmer, Erik Sherk and Pete Whiting. ## All rights reserved. ## ## This software may be freely copied, modified and redistributed without @@ -30,10 +30,11 @@ # # Usage line -set usage "Usage: $argv0 \[-u user\] \[-p user-password\] \[-v vty-password\] \ -\[-w enable-username\] \[-e enable-password\] \[-noenable\] \ -\[-f cloginrc-file\] \[-y ssh_cypher_type\] \[-c command\] \[-s script-file\] \ -\[-autoenable\] \[-t timeout\] router \[router...\]\n" +set usage "Usage: $argv0 \[-autoenable\] \[-noenable\] \ +\[-c command\] \[-Evar=x\] \[-e enable-password\] \[-p user-password\] \ +\[-f cloginrc-file\] \[-s script-file\] \[-t timeout\] \[-u user\] \ +\[-v vty-password\] \[-w enable-username\]\[-y ssh_cypher_type\] \ +router \[router...\]\n" # env(CLOGIN) may contain: # x == do not set xterm banner or name @@ -106,9 +107,18 @@ for {set i 0} {$i < $argc} {incr i} { incr i set enausername [ lindex $argv $i ] } + # Environment variable to pass to -s scripts + } -E* + { + if {[ regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} { + set E$varname $varvalue + } else { + send_user "Error: invalid format for -E in $arg\n" + exit 1 + } # Enable Password - } -e* - - -E* { + } -e* + { if {! [ regexp .\[eE\](.+) $arg ignore enapasswd]} { incr i set enapasswd [ lindex $argv $i ] @@ -158,7 +168,10 @@ for {set i 0} {$i < $argc} {incr i} { incr i set cmd_file [ lindex $argv $i ] } - set cmd_fd [open $cmd_file r] + if [ catch {set cmd_fd [open $cmd_file r]} reason ] { + send_user "\nError: $reason\n" + exit 1 + } set cmd_text [read $cmd_fd] close $cmd_fd set command [join [split $cmd_text \n] \;] @@ -464,11 +477,11 @@ foreach router [lrange $argv $i end] { if { $do_passwd || $do_enapasswd } { set pswd [find password $router] if { [llength $pswd] == 0 } { - send_user "Error - no password for $router in $password_file.\n" + send_user "Error: no password for $router in $password_file.\n" continue } - if { $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2 } { - send_user "Error - no enable password for $router in $password_file.\n" + if { $enable && $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2 } { + send_user "Error: no enable password for $router in $password_file.\n" continue } set passwd [lindex $pswd 0] diff --git a/bin/francid.in b/bin/francid.in index 66c4b75..f494ea6 100755 --- a/bin/francid.in +++ b/bin/francid.in @@ -3,7 +3,7 @@ ## Amazingly hacked version of Hank's rancid - this one tries to ## deal with foundrys. ## -## Copyright (C) 1997 by Henry Kilmer. +## Copyright (C) 1997-2001 by Henry Kilmer. ## All rights reserved. ## ## This software may be freely copied, modified and redistributed without diff --git a/bin/jlogin.in b/bin/jlogin.in index a74cff4..9ff0626 100755 --- a/bin/jlogin.in +++ b/bin/jlogin.in @@ -1,7 +1,7 @@ #!@EXPECT_PATH@ -- ## ## -## Copyright (C) 1997 by Henry Kilmer, Erik Sherk and Pete Whiting. +## Copyright (C) 1997-2001 by Henry Kilmer, Erik Sherk and Pete Whiting. ## All rights reserved. ## ## This software may be freely copied, modified and redistributed without @@ -23,7 +23,7 @@ # # Usage line -set usage "Usage: $argv0 \[-c command\] \[-f cloginrc-file\] \ +set usage "Usage: $argv0 \[-c command\] \[-Evar=x\] \[-f cloginrc-file\] \ \[-p user-password\] \[-r passphrase\] \[-s script-file\] \ \[-u username\] \[-t timeout\] \[-x command-file\] \[-y ssh_cypher_type\] \ router \[router...\]\n" @@ -76,6 +76,15 @@ for {set i 0} {$i < $argc} {incr i} { set command [ lindex $argv $i ] } set do_command 1 + # Environment variable to pass to -s scripts + } -E* + { + if {[ regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} { + set E$varname $varvalue + } else { + send_user "Error: invalid format for -E in $arg\n" + exit 1 + } # alternate cloginrc file } -f* - -F* { @@ -131,7 +140,10 @@ for {set i 0} {$i < $argc} {incr i} { incr i set cmd_file [ lindex $argv $i ] } - set cmd_fd [open $cmd_file r] + if [ catch {set cmd_fd [open $cmd_file r]} reason ] { + send_user "\nError: $reason\n" + exit 1 + } set cmd_text [read $cmd_fd] close $cmd_fd set command [join [split $cmd_text \n] \;] @@ -235,8 +247,8 @@ proc source_password_file { password_file } { } # Log into the router. -proc login { router user passwd prompt cmethod cyphertype identfile} { - global spawn_id in_proc do_command do_script passphrase +proc login { router user passwd cmethod cyphertype identfile} { + global spawn_id in_proc do_command do_script passphrase prompt set in_proc 1 # try each of the connection methods in $cmethod until one is successful @@ -302,7 +314,7 @@ proc login { router user passwd prompt cmethod cyphertype identfile} { # passwd. Or, the router might not have TACACS turned on, # then it will just send the passwd. expect { - -re "(Connection refused|Secure connection \[^\n\r]+ refused|Connectionclosed by)" { + -re "(Connection refused|Secure connection \[^\n\r]+ refused|Connection closed by)" { catch {close}; wait if !$progs { send_user "\nError: Connection Refused ($prog)\n"; return 1 @@ -336,18 +348,18 @@ proc login { router user passwd prompt cmethod cyphertype identfile} { eof { send_user "\nError: Couldn't login\n"; wait; return 1 } -re "\[Pp]assword:" { send "$passwd\r" } - "$prompt" { set in_proc 0; return 0 } + -re "$prompt" { break; } } exp_continue } "\[Pp]assword:" { send "$passwd\r" expect { eof { send_user "\nError: Couldn't login\n"; wait; return 1 } - "$prompt" { set in_proc 0; return 0 } + -re "$prompt" { break; } } exp_continue } - "$prompt" { break; } + -re "$prompt" { break; } denied { send_user "\nError: Check your passwd for $router\n" if { $do_command || $do_script } { send "quit" @@ -360,6 +372,16 @@ proc login { router user passwd prompt cmethod cyphertype identfile} { "% Bad passwords" {send_user "\nError: Check your passwd for $router\n"; return 1 } } } + + # we are logged in, now figure out the full prompt + send "\r" + expect { + -re "(\r\n|\n)" { exp_continue; } + -re "^\[^ ]+$prompt" { set prompt $expect_out(0,string); + regsub ">" $prompt "\[#>]" prompt; + } + } + set in_proc 0 return 0 } @@ -370,9 +392,9 @@ proc run_commands { prompt command } { set in_proc 1 send "set cli complete-on-space off\r" - expect $prompt {} + expect -re $prompt {} send "set cli screen-length 0\r" - expect $prompt {} + expect -re $prompt {} # Is this a multi-command? if [ string match "*\;*" "$command" ] { @@ -429,8 +451,18 @@ foreach router [lrange $argv $i end] { # command line passwd set passwd $userpswd } else { - set passwd [lindex [find password $loginname@$router] 0] - if { "$passwd" == "" } { set passwd [lindex [find password $router] 0] } + set userpswd [lindex [find userpassword $loginname@$router] 0] + if { "$userpswd" == "" } { + set userpswd [lindex [find userpassword $router] 0] + } + if { "$userpswd" == "" } { + set passwd [lindex [find password $loginname@$router] 0] + if { "$passwd" == "" } { + set passwd [lindex [find password $router] 0] + } + } else { + set passwd $userpswd + } } # figure out identity file to use @@ -453,7 +485,7 @@ foreach router [lrange $argv $i end] { if { "$cmethod" == "" } { set cmethod {{telnet} {ssh}} } # Login to the router - if {[login $router $loginname $passwd $prompt $cmethod $cyphertype $identfile]} { + if {[login $router $loginname $passwd $cmethod $cyphertype $identfile]} { continue } @@ -463,9 +495,9 @@ foreach router [lrange $argv $i end] { } } elseif { $do_script } { send "set cli complete-on-space off\r" - expect $prompt {} + expect -re $prompt {} send "set cli screen-length 0\r" - expect $prompt {} + expect -re $prompt {} source $sfile close } else { diff --git a/bin/jrancid.in b/bin/jrancid.in index 91bbf54..56d98c7 100755 --- a/bin/jrancid.in +++ b/bin/jrancid.in @@ -3,7 +3,7 @@ ## Amazingly hacked version of Hank's rancid - this one tries to ## deal with Junipers. ## -## Original Rancid: Copyright (C) 1997 by Henry Kilmer. +## Original Rancid: Copyright (C) 1997-2001 by Henry Kilmer. ## All rights reserved. ## ## This software may be freely copied, modified and redistributed without @@ -350,6 +350,7 @@ sub ShowVersion { # This routine parses "show configuration" sub ShowConfiguration { + my($lines) = 0; print STDERR " In ShowConfiguration: $_" if ($debug); s/^[a-z]+@//; @@ -363,6 +364,7 @@ sub ShowConfiguration { $found_end++; last; } + $lines++; /^database header mismatch: / && return(-1); /^version .*;\d+$/ && return(-1); @@ -376,6 +378,13 @@ sub ShowConfiguration { s/ # SECRET-DATA$//; ProcessHistory("","","","$_"); } + + if ($lines < 3) { + printf(STDERR "ERROR: configuration appears truncated.\n"); + $found_end = 0; + return(-1); + } + return; } @@ -458,6 +467,12 @@ TOP: while() { $clean_run = 0; last; } + if (/error: cli version does not match Managment Daemon/i) { + print STDOUT ("$host mgd version mismatch: $_"); + print STDERR ("$host mgd version mismatch: $_") if ($debug); + $clean_run = 0; + last; + } while (/>\s*($cmds_regexp)\s*$/) { $cmd = $1; if (!defined($prompt)) { diff --git a/bin/par.in b/bin/par.in index d8b628b..88c66af 100755 --- a/bin/par.in +++ b/bin/par.in @@ -1,7 +1,7 @@ #!@PERLV_PATH@ ## ## -## Copyright (C) 1997 by Henry Kilmer and Peter Whiting. +## Copyright (C) 1997-2001 by Henry Kilmer and Peter Whiting. ## All rights reserved. ## ## This software may be freely copied, modified and redistributed without diff --git a/bin/rancid-fe.in b/bin/rancid-fe.in index 7a6c7ff..b452f0f 100755 --- a/bin/rancid-fe.in +++ b/bin/rancid-fe.in @@ -1,7 +1,7 @@ #!@PERLV_PATH@ ## ## -## Copyright (C) 1997 by Henry Kilmer. +## Copyright (C) 1997-2001 by Henry Kilmer. ## All rights reserved. ## ## This software may be freely copied, modified and redistributed without @@ -39,6 +39,8 @@ if ($vendor =~ /^cisco$/i) { exec('rrancid', $router); } elsif ($vendor =~ /^alteon$/i) { exec('arancid', $router); +} elsif ($vendor =~ /^extreme$/i) { + exec('xrancid', $router); } printf(STDERR "unknown router manufacturer for $router: $vendor\n"); diff --git a/bin/rancid.in b/bin/rancid.in index d8b3694..45a8563 100755 --- a/bin/rancid.in +++ b/bin/rancid.in @@ -1,7 +1,7 @@ #!@PERLV_PATH@ ## ## -## Copyright (C) 1997 by Henry Kilmer. +## Copyright (C) 1997-2001 by Henry Kilmer. ## All rights reserved. ## ## This software may be freely copied, modified and redistributed without @@ -304,7 +304,7 @@ sub ShowEnv { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); - return(1) if ($type !~ /^7/); + #return(1) if ($type !~ /^7/); return(-1) if (/command authorization failed/i); if (!defined($E0)) { $E0=1; @@ -330,7 +330,7 @@ sub ShowEnv { } # This routine parses "show gsr chassis-info" for the gsr -# This will create arrarys for hw info. +# This will create arrays for hw info. sub ShowGSR { # Skip if this is not a 1200n. print STDERR " In ShowGSR: $_" if ($debug); @@ -340,7 +340,7 @@ sub ShowGSR { last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(-1) if (/command authorization failed/i); - return(1) if ($type !~ /^120/); + # return(1) if ($type !~ /^12[40]/); /^$/ && next; /^\s+Chassis: type (\S+) Fab Ver: (\S+)/ && ProcessHistory("COMMENTS","keysort","D0","!\n") && @@ -383,7 +383,7 @@ sub ShowBoot { if (!defined($H0)) { $H0=1; ProcessHistory("COMMENTS","keysort","H0","!\n"); } - if ($type !~ /^(120|7)/) { + if ($type !~ /^(12[04]|7)/) { if ($type !~ /^(29|35)00/) { ProcessHistory("COMMENTS","keysort","H2","!BootFlash: $_"); } else { @@ -399,14 +399,15 @@ sub ShowBoot { # This routine parses "show flash" sub ShowFlash { - # skip if this is 7000, 7200, 7500, or 12000. + # skip if this is 7000, 7200, 7500, or 12000; else we end up with + # redundant data from dir /all slot0: print STDERR " In ShowFlash: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); - return(1) if ($type =~ /^(120|7)/); + return(1) if ($type =~ /^(12[40]|7)/); return(-1) if (/command authorization failed/i); return(1) if /^\s*\^\s*$/; return(1) if /(Invalid input detected|Type help or )/; @@ -427,9 +428,10 @@ sub DirSlotN { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); - return(1) if ($type !~ /^(120|7|36)/); + # return(1) if ($type !~ /^(12[40]|7|36)/); return(1) if /^\s*\^\s*$/; return(1) if /(Invalid input detected|Type help or )/; + return(1) if /No such device/i; return(1) if /\%Error: No such file or directory/; return(1) if /No space information available/; return(-1) if /\%Error calling/; @@ -451,7 +453,7 @@ sub ShowContAll { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); - return(1) if ($type =~ /^(120|7[05])/); + # return(1) if ($type =~ /^(12[40]|7[05])/); return(-1) if (/command authorization failed/i); if (/^Interface ([^ \n(]*)/) { $INT = "$1, "; next; } /^(BRI unit \d)/ && @@ -462,7 +464,7 @@ sub ShowContAll { ProcessHistory("INT","","","!Interface: $1\n") && next; /(Media Type is \S+),/ && ProcessHistory("INT","","","!\t$1\n"); - if (/(M\dT:) show controller:$/) { + if (/(M\dT[^ :]*:) show controller:$/) { my($ctlr) = $1; $_ = ; tr/\015//d; s/ subunit \d,//; ProcessHistory("INT","","","!Interface: $ctlr $_"); @@ -509,7 +511,7 @@ sub ShowContCbus { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); - return(1) if ($type !~ /^7[05]0/); + #return(1) if ($type !~ /^7[05]0/); return(-1) if (/command authorization failed/i); if (/^\s*slot(\d+): ([^,]+), hw (\S+), sw (\S+), ccb/) { $slot = $1; @@ -554,7 +556,7 @@ sub ShowDiagbus { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); - return(1) if ($type !~ /^7[05]/); + #return(1) if ($type !~ /^7[05]/); return(-1) if (/command authorization failed/i); if (/^\s*Slot (\d+):/i) { $slot = $1; @@ -615,11 +617,11 @@ sub ShowDiagbus { } next; } - /\s+(.*) PA, (\d) ports?, (\S+)/ && - ProcessHistory("SLOT","","","!Slot $slot/$board: type $3, $2 ports\n") && + /\s+(.*) (IP|PA), (\d) ports?, (\S+)/ && + ProcessHistory("SLOT","","","!Slot $slot/$board: type $4, $3 ports\n") && next; - /\s+(.*) PA( \(\S+\))?, (\d) ports?/ && - ProcessHistory("SLOT","","","!Slot $slot/$board: type $1$2, $3 ports\n") && + /\s+(.*) (IP|PA)( \(\S+\))?, (\d) ports?/ && + ProcessHistory("SLOT","","","!Slot $slot/$board: type $1$3, $4 ports\n") && next; /^\s*HW rev (\S+), Board revision (\S+)/ && ProcessHistory("SLOT","","","!Slot $slot/$board: hvers $1 rev $2\n") && @@ -640,7 +642,7 @@ sub ShowDiag { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); - return(1) if ($type !~ /^(120|720|36|26)/); + # return(1) if ($type !~ /^(12[40]|720|36|26)/); return(-1) if (/command authorization failed/i); /^$/ && next; if (!defined($showdiags)) {$showdiags=1; ProcessHistory("SLOT","","","!\n");} @@ -744,12 +746,14 @@ sub ShowModule { next if (/^(\s*|\s*$cmd\s*)$/); return(-1) if (/command authorization failed/i); - # match slot info line, slot info then the rev info (the two are split) - if (/^ ?(\d+)\s+(\d+)\s+(.*)\s+(\S+)\s+(\S+)\s*$/) { + # match slot/card info line + if (/^ *(\d+)\s+(\d+)\s+(.*)\s+(\S+)\s+(\S+)\s*$/) { $lines[$1] .= "!Slot $1: type $3, $2 ports\n!Slot $1: part $4, serial $5\n"; $lines[$1] =~ s/\s+,/,/g; } - if (/^ ?(\d+)\s+\S+\s+to\s+\S+\s+(\S+)\s+(.*)\s+(\S+)\s*$/) { + # now match the Revs in the second paragraph of o/p and stick it in + # the array with the previous bits...grumble. + if (/^ *(\d+)\s+\S+\s+to\s+\S+\s+(\S+)\s+(.*)\s+(\S+)\s*$/) { $lines[$1] .= "!Slot $1: hvers $2, firmware $3, sw $4\n"; $lines[$1] =~ s/\s+,/,/g; } @@ -772,7 +776,7 @@ sub ShowC7200 { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); - return(1) if ($type !~ /^72/); + #return(1) if ($type !~ /^72/); return(-1) if (/command authorization failed/i); /^$/ && next; if (/C7200 Midplane EEPROM:/) { @@ -807,7 +811,7 @@ sub ShowVTP { next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if /(Invalid input detected|Type help or )/; - return(1) if ($type !~ /^(2900XL|3500XL|6000)$/); + #return(1) if ($type !~ /^(2900XL|3500XL|6000)$/); return(-1) if (/command authorization failed/i); next if (/^Configuration last modified by/); if (/^VTP Operating Mode\s+:\s+(Transparent|Server)/) { @@ -830,7 +834,7 @@ sub ShowVLAN { last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /(Invalid input detected|Type help or )/; - return(1) if ($type !~ /^(2900XL|3500XL|6000)$/); + #return(1) if ($type !~ /^(2900XL|3500XL|6000)$/); return(-1) if (/command authorization failed/i); ProcessHistory("COMMENTS","keysort","IO","!VLAN: $_"); } diff --git a/bin/rrancid.in b/bin/rrancid.in index 9d2663b..ab196c2 100755 --- a/bin/rrancid.in +++ b/bin/rrancid.in @@ -2,7 +2,7 @@ ## ## hacked version of Hank's rancid - this one tries to deal with redbacks. ## -## Copyright (C) 1997 by Henry Kilmer. +## Copyright (C) 1997-2001 by Henry Kilmer. ## All rights reserved. ## ## This software may be freely copied, modified and redistributed without diff --git a/bin/xrancid.in b/bin/xrancid.in new file mode 100755 index 0000000..b60697c --- /dev/null +++ b/bin/xrancid.in @@ -0,0 +1,407 @@ +#!@PERLV_PATH@ +## +## +## Copyright (C) 1997-2001 by Henry Kilmer. +## All rights reserved. +## +## This software may be freely copied, modified and redistributed without +## fee for non-commerical purposes provided that this copyright notice is +## preserved intact on all copies and modified copies. +## +## There is no warranty or other guarantee of fitness of this software. +## It is provided solely "as is". The author(s) disclaim(s) all +## responsibility and liability with respect to this software's usage +## or its effect upon hardware, computer systems, other software, or +## anything else. +## +## +# +# RANCID - Really Awesome New Cisco confIg Differ +# +# usage: rancid [-d] [-l] [-f filename | $host] +# +use Getopt::Std; +getopts('dflm'); +$log = $opt_l; +$debug = $opt_d; +$file = $opt_f; +$host = $ARGV[0]; +$clean_run = 0; +$found_end = 0; +$timeo = 90; # clogin timeout in seconds + +# This routine is used to print out the router configuration +sub ProcessHistory { + my($new_hist_tag,$new_command,$command_string,@string)=(@_); + if((($new_hist_tag ne $hist_tag) || ($new_command ne $command)) + && defined %history) { + print eval "$command \%history"; + undef %history; + } + if (($new_hist_tag) && ($new_command) && ($command_string)) { + if ($history{$command_string}) { + $history{$command_string} = "$history{$command_string}@string"; + } else { + $history{$command_string} = "@string"; + } + } elsif (($new_hist_tag) && ($new_command)) { + $history{++$#history} = "@string"; + } else { + print "@string"; + } + $hist_tag = $new_hist_tag; + $command = $new_command; + 1; +} + +sub numerically { $a <=> $b; } + +# This is a sort routing that will sort numerically on the +# keys of a hash as if it were a normal array. +sub keynsort { + local(%lines)=@_; + local($i) = 0; + local(@sorted_lines); + foreach $key (sort numerically keys(%lines)) { + $sorted_lines[$i] = $lines{$key}; + $i++; + } + @sorted_lines; +} + +# This is a sort routing that will sort on the +# keys of a hash as if it were a normal array. +sub keysort { + local(%lines)=@_; + local($i) = 0; + local(@sorted_lines); + foreach $key (sort keys(%lines)) { + $sorted_lines[$i] = $lines{$key}; + $i++; + } + @sorted_lines; +} + +# This is a sort routing that will sort on the +# values of a hash as if it were a normal array. +sub valsort{ + local(%lines)=@_; + local($i) = 0; + local(@sorted_lines); + foreach $key (sort values %lines) { + $sorted_lines[$i] = $key; + $i++; + } + @sorted_lines; +} + +# This is a numerical sort routing (ascending). +sub numsort { + local(%lines)=@_; + local($i) = 0; + local(@sorted_lines); + foreach $num (sort {$a <=> $b} keys %lines) { + $sorted_lines[$i] = $lines{$num}; + $i++; + } + @sorted_lines; +} + +# This is a sort routine that will sort on the +# ip address when the ip address is anywhere in +# the strings. +sub ipsort { + local(%lines)=@_; + local($i) = 0; + local(@sorted_lines); + foreach $addr (sort sortbyipaddr keys %lines) { + $sorted_lines[$i] = $lines{$addr}; + $i++; + } + @sorted_lines; +} + +# These two routines will sort based upon IP addresses +sub ipaddrval { + my(@a) = ($_[0] =~ m#^(\d+)\.(\d+)\.(\d+)\.(\d+)$#); + $a[3]+256*($a[2]+256*($a[1]+256*$a[0])); +} +sub sortbyipaddr { + &ipaddrval($a) <=> &ipaddrval($b); +} + +# This routine parses "show version" +sub ShowVersion { + print STDERR " In ShowVersion: $_" if ($debug); + + while () { + tr/\015//d; + last if(/^$prompt/); + next if(/^(\s*|\s*$cmd\s*)$/); + + /^\S+ Serial Number:/i && + ProcessHistory("COMMENTS","keysort","A0","#$_") && next; + /^(\S+) Power Supply ([^:]+):\s+(.*)/i && + ProcessHistory("COMMENTS","keysort","B0","#Power: $1 $2 $3\n") + && next; + /^Image\s*:\s*(.*)/i && + ProcessHistory("COMMENTS","keysort","C0","#Image: $1\n") + && next; +#heas: need to collect this from show vers for ShowSlot where rev #s are excluded +#SLOT 1 : 702005-06 0025S-00877 CPLD Rev +#SLOT 2 : 702005-06 0021S-00131 CPLD Rev 02 +#SLOT 3 : 702009-06 0024S-00170 CPLD Rev +#SLOT 4 : 702009-06 0024S-00319 CPLD Rev + } + return(0); +} + +# This routine parses "show memory" +sub ShowMemory { + print STDERR " In ShowMemory: $_" if ($debug); + + while () { + tr/\015//d; + last if(/^$prompt/); + next if(/^(\s*|\s*$cmd\s*)$/); + + /^Total DRAM Size: (.*)/ && + ProcessHistory("COMMENTS","keysort","A0","#\n#Memory: $1\n") + } + return(0); +} + +# This routine parses "show install active" +sub ShowSlot { + print STDERR " In ShowSlot: $_" if ($debug); + + while () { + tr/\015//d; + last if (/^$prompt/); + next if (/^(\s*|\s*$cmd\s*)$/); + + if (/^Slot\s+(\d+)\s+/i) { + my($slot) = $1; + my($hwtype, $conftype, $sn, $state); + ProcessHistory("SLOT","keysort","$slot","#\n"); + while () { + tr/\015//d; + last if (/^$prompt/ || /^\s*$/); + if (/State:\s+(.*)$/i) { $state = $1; } + if (/serial number:\s+(.*)$/i) { $sn = $1; } + if (/hw module type:\s+(.*)$/i) { $hwtype = $1; } + if (/configured type:\s+(.*)$/i) { $conftype = $1; } + } + ProcessHistory("SLOT","keysort","$slot","#Slot $slot: type $hwtype," + . " $conftype\n#Slot $slot: serial $sn\n#Slot $slot: state " + . " $state\n"); + return if (/^$prompt/); + next; + } + } + return(0); +} + +# This routine processes a "write term" +sub WriteTerm { + print STDERR " In WriteTerm: $_" if ($debug); + + while () { + tr/\015//d; + last if(/^$prompt/); + next if(/^\s*$/); + # the pager can not be disabled per-session on the PIX + s/^<-+ More -+>\s*//; + + # Dog gone Cool matches to process the rest of the config + /^(# \S+ Configuration) generated/i && + ProcessHistory("","","","$1\n") && next; + /^(config bgp (neighbor|peer-group) \S+ password encrypted)/i && + ProcessHistory("","","","# $1 \n") && + next; +# /^( ip ospf authentication-key) / && +# ProcessHistory("","","","!$1 \n") && next; +# /^( ip ospf message-digest-key \d+ md5) / && +# ProcessHistory("","","","!$1 \n") && next; +# # sort route-maps +# if (/^route-map (\S+)/) { +# my($key) = $1; +# my($routemap) = $_; +# while () { +# tr/\015//d; +# last if (/^$prompt/ || ! /^(route-map |[ !])/); +# if (/^route-map (\S+)/) { +# ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); +# $key = $1; +# $routemap = $_; +# } else { +# $routemap .= $_; +# } +# } +# ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); +# } + # filter out any RCS/CVS tags to avoid confusing local CVS storage + s/\$(Revision|Id):/ $1:/; + +# # order access-lists +# /^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ && +# ProcessHistory("ACL $1 $2","ipsort","$3","$_") && next; +# # order extended access-lists +# /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+host\s+(\S+)/ && +# ProcessHistory("EACL $1 $2","ipsort","$3","$_") && next; +# /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+(\d\S+)/ && +# ProcessHistory("EACL $1 $2","ipsort","$3","$_") && next; +# /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+any/ && +# ProcessHistory("EACL $1 $2","ipsort","0.0.0.0","$_") && next; +# # order arp lists +# /^arp\s+(\d+\.\d+\.\d+\.\d+)\s+/ && +# ProcessHistory("ARP","ipsort","$1","$_") && next; +# /^ip prefix-list\s+(\S+)\s+seq\s+(\d+)\s+(permit|deny)\s+(\d\S+)(\/.*)$/ && +# ProcessHistory("PACL $1 $3","ipsort","$4","ip prefix-list $1 $3 $4$5\n") +# && next; + + # order logging statements + /^configure syslog add logging (\d+\.\d+\.\d+\.\d+)/ && + ProcessHistory("LOGGING","ipsort","$1","$_") && next; + # order/prune snmp-server host statements + # we only prune lines of the form + + # configure snmp add trapreceiver a.b.c.d + if (/^(configure snmp add trapreceiver )(\d+\.\d+\.\d+\.\d+) (community) \S+ (.*)/) { + if (defined($ENV{'NOCOMMSTR'})) { + ProcessHistory("SNMPSVRHOST","ipsort","$2","# $1$2 $3 $4\n"); + } else { + ProcessHistory("SNMPSVRHOST","ipsort","$2","$_\n"); + } + next; + } + if (/^(configure snmp add community (readonly|readwrite) \S+) (\S+)/) { + if (defined($ENV{'NOCOMMSTR'})) { + ProcessHistory("SNMPSVRCOMM","keysort","$_","#$1 $'"); + next; + } else { + ProcessHistory("SNMPSVRCOMM","keysort","$_","$_") && next; + } + } + # order/prune tacacs/radius server statements + /^(configure radius (primary|secondary) (tacacs-server|radius-server) shared-secret encrypted)/ && + ProcessHistory("","","","# $1 \n") && next; + + # catch anything that wasnt match above. + ProcessHistory("","","","$_"); + # end of config + if (/^# End of configuration file/i) { + printf STDERR " End WriteTerm: $_" if ($debug); + $found_end = 1; + return(1); + } + } + return(0); +} + +# dummy function +sub DoNothing {print STDOUT;} + +# Main +%commands=( + 'show version' => "ShowVersion", + 'show memory' => "ShowMemory", + 'show slot' => "ShowSlot", + 'show configuration' => "WriteTerm" +); +# keys() doesnt return things in the order entered and the order of the +# cmds is important (show version first and write term last). pita +@commands=( + "show version", + "show memory", + "show slot", + "show configuration" +); +$cisco_cmds=join(";",@commands); +$cmds_regexp=join("|",@commands); + +open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n"; +select(OUTPUT); +# make OUTPUT unbuffered if debugging +if ($debug) { $| = 1; } + +if ($file) { + print STDERR "opening file $host\n" if ($debug); + print STDOUT "opening file $host\n" if ($log); + open(INPUT,"<$host") || die "open failed for $host: $!\n"; +} else { + print STDERR "executing clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); + print STDOUT "executing clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); + if (defined($ENV{NOPIPE})) { + system "clogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "clogin failed for $host: $!\n"; + open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n"; + } else { + open(INPUT,"clogin -t $timeo -c \"$cisco_cmds\" $host ) { + tr/\015//d; + # note: this match sucks rocks, but the currently the extreme bits are + # unreliable about echoing the 'exit\n' command. this match might really + # be a bad idea, but instead rely upon WriteTerm's found_end? + if (/$prompt\s?(exit$|Connection closed)/ && $found_end) { + $clean_run=1; + last; + } + if (/^Error:/) { + print STDOUT ("$host clogin error: $_"); + print STDERR ("$host clogin error: $_") if ($debug); + $clean_run=0; + last; + } + while (/$prompt\s*($cmds_regexp)\s*$/) { + $cmd = $1; + if (!defined($prompt)) { + $prompt = ($_ =~ /^([^#]+#)/)[0]; + $prompt =~ s/:(\d+ ?)#/:\\d+ ?#/; + print STDERR ("PROMPT MATCH:$prompt\n") if ($debug); + } + print STDERR ("HIT COMMAND:$_") if ($debug); + if (! defined($commands{$cmd})) { + print STDERR "found unexpected command - \"$cmd\"\n"; + $clean_run = 0; + last TOP; + } + $rval = &{$commands{$cmd}}; + delete($commands{$cmd}); + if ($rval == -1) { + printf STDERR "rval = -1\n" if (debug); + $clean_run = 0; + last TOP; + } + } +} +print STDOUT "Done $logincmd: $_\n" if ($log); +# Flush History +ProcessHistory("","","",""); +# Cleanup +close(INPUT); +close(OUTPUT); + +if (defined($ENV{NOPIPE})) { + unlink("$host.raw") if (! $debug); +} + +# check for completeness +if (scalar(%commands) || !$clean_run || !$found_end) { + if (scalar(%commands)) { + printf(STDOUT "missed cmd(s): %s\n", join(',', keys(%commands))); + printf(STDERR "missed cmd(s): %s\n", join(',', keys(%commands))) if ($debug); + } + if (!$clean_run || !$found_end) { + print STDOUT "End of run not found\n"; + print STDERR "End of run not found\n" if ($debug); + system("/usr/bin/tail -1 $host.new"); + } + unlink "$host.new" if (! $debug); +} -- cgit