summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTar Committer <tar@ocjtech.us>2001-10-16 03:14:40 +0000
committerTar Committer <tar@ocjtech.us>2001-10-16 03:14:40 +0000
commitb0d71377c1854271b4511488422427f73d9473d1 (patch)
tree4f4efba2179225c53238aa53e933ba81100cad81
parent10cc9157892d7902dddde70a5b9b2046d0c376ea (diff)
downloadrancid-b0d71377c1854271b4511488422427f73d9473d1.tar.gz
rancid-b0d71377c1854271b4511488422427f73d9473d1.tar.xz
rancid-b0d71377c1854271b4511488422427f73d9473d1.zip
Imported from rancid-2.2b8.tar.gz.rancid-2.2b8
-rw-r--r--CHANGES20
-rw-r--r--FAQ13
-rw-r--r--README20
-rw-r--r--Todo17
-rwxr-xr-xbin/blogin.in5
-rwxr-xr-xbin/brancid.in12
-rwxr-xr-xbin/clogin.in9
-rwxr-xr-xbin/control_rancid.in2
-rw-r--r--bin/env.in6
-rwxr-xr-xbin/hlogin.in672
-rwxr-xr-xbin/hrancid.in716
-rwxr-xr-xbin/jlogin.in5
-rwxr-xr-xbin/jrancid.in3
-rwxr-xr-xbin/par.in2
-rwxr-xr-xbin/rancid-fe.in2
-rwxr-xr-xbin/rancid.in2
-rwxr-xr-xbin/xrancid.in185
-rwxr-xr-xconfigure4
-rw-r--r--configure.in4
-rw-r--r--man/create_cvs.13
-rw-r--r--man/env.5.in17
-rw-r--r--man/router.db.53
-rwxr-xr-xutil/lg/lg.cgi.in2
23 files changed, 1628 insertions, 96 deletions
diff --git a/CHANGES b/CHANGES
index 4833413..cc8ec27 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,23 @@
+2.2b8
+ add PAR_COUNT variable to bin/env for adjusting the number of
+ simultaneous collections. see bin/env (or bin/env.new for those with
+ previous installation) and the env(5) manpage.
+
+ more work on extreme switch bits + fixes from Alex Bochannek.
+
+ jlogin: add 1s sleeps to avoid passwords being echo'd before tty noecho
+ is set. richard doty
+
+ few looking glass fixes
+
+ brancid: filter uptime and add -all option to config for bayrs version
+ 14. from mordechai abzug
+
+ jrancid: m160 measured chassis clock MHz fluctuates, trim the
+ decimal places. from Mark A Gebert.
+
+ par: -x fix for log file monitoring killing xterms. from rdrake.
+
2.2b7
brancid: patch to filter community strings from Mark Cooper
diff --git a/FAQ b/FAQ
index ed0178a..45b88d0 100644
--- a/FAQ
+++ b/FAQ
@@ -1,4 +1,4 @@
-Frequently Asked Questions about rancid - last updated 20010730
+Frequently Asked Questions about rancid - last updated 20010926
1) Platform specific
@@ -20,6 +20,17 @@ A. The manual page for cvs is quite complete, but can be be overwhelming even
for someone familiar with rcs. There are some excellent resources on the
pages http://www.loria.fr/~molli/cvs-index.html
+Q. Errors are showing up in the logs like:
+ cvs [diff aborted]: there is no version here; run 'cvs checkout' first
+A. The directory was not imported into CVS properly or was not properly checked
+ out afterward, so CVS control files or directories do not exist. create_cvs
+ should always be used to create the directories and perform the CVS work.
+ If it is just the directories have been created manually, save a copy of
+ the router.db file, then remove the group's directory, use create_cvs, and
+ replace the router.db file. If the CVS import was also performed manually,
+ cd to <BASEDIR> and use 'cvs co <rancid group>' to create all the CVS
+ control bits.
+
Q. I keep receiving the same diff for a (or set of) devices, but I know the
data is not changing repeatedly. Why?
A. This is most likely either a cvs or filesystem permissions problem. Check
diff --git a/README b/README
index b05a335..589cdc6 100644
--- a/README
+++ b/README
@@ -14,12 +14,17 @@ control_rancid.in
handles cvs routines.
rancid-fe.in chooses between rancid/[efjr]rancid/cat5rancid.
rancid.in Runs commands on cisco routers and processes the output.
+brancid.in Runs commands on baynet/nortel routers and processes the output.
erancid.in Runs commands on ADC EZ-T3 muxes and processes the output.
francid.in Runs commands on foundry switches and processes the output.
+hrancid.in Runs commands on hp procurve switches and processes the output.
jrancid.in Runs commands on juniper routers and processes the output.
rrancid.in Runs commands on redback routers and processes the output.
xancid.in Runs commands on extreme switches and processes the output.
cat5rancid.in Runs commands on cisco cat5 switches and processes the output.
+blogin.in Expect script that logs into baynet/nortel routers either
+ interactively, runs a set of commands, or runs another expect
+ script.
clogin.in Expect script that logs into routers either interactively,
runs a set of commands, or runs another expect script.
elogin.in Expect script that logs into ADC EZ-T3 muxes either
@@ -27,6 +32,9 @@ elogin.in Expect script that logs into ADC EZ-T3 muxes either
script.
flogin.in Expect script that logs into foundry switches. Once foundry
cleans up their bloody UI, clogin should do the job.
+blogin.in Expect script that logs into hp procurve switches either
+ interactively, runs a set of commands, or runs another expect
+ script.
jlogin.in Expect script that logs into juniper routers similarly to
clogin. It is not terribly robust, but mainly used for it's
-c and -s options.
@@ -43,8 +51,8 @@ The following are included as part of the installation tools:
Makefile.in processed by configure to produce Makefiles
configure GNU autoconf script
-install-sh shell script to simulate BSD style install
-mkinstalldirs shell script to make installation directories
+install-sh GNU autoconf shell script to simulate BSD style install
+mkinstalldirs GNU autoconf shell script to make installation directories
rancid will also need to have the following packages:
cvs code revision system available from prep.ai.mit.edu:/pub/gnu
@@ -118,7 +126,8 @@ Quick Installation Guide (an example):
7) Run create_cvs.
This creates all of the necessary directories and config files for
each of the groups in LIST_OF_GROUPS and imports them into CVS. This
- will also be run each time a new group is added. Also see
+ will also be run each time a new group is added. Do not create the
+ directories or CVS repository manually, allow create_cvs do it. Also see
'man -M <basedir>/man create_cvs'.
8) For each "group", modify the router.db file in the group directory.
@@ -185,7 +194,8 @@ Synopsis: SunOS 5.6: /kernel/drv/ip patch
another possibile contributor is expect/tcl. we've noticed that expect
5.24.1 (possibly 5.28.*) and whatever tcl happens to compile with it,
-eems to not exhibit this problem, while 5.32.* appears to on linux and
-solaris but not on netbsd 1.5.
+seems to not exhibit this problem, while 5.32.* appears to on linux and
+solaris but not on netbsd 1.5. see www.shrubbery.net/rancid for additional
+notes on this.
-Hank
diff --git a/Todo b/Todo
index e10c311..0a9c5fe 100644
--- a/Todo
+++ b/Todo
@@ -1,17 +1,18 @@
-- extreme (xrancid)
- - collect show switch
- - filter ssh host private key
- - ??? separate module p/n and s/n or collect from sh ver instead of
- show slot?
-- rancid should filter pap pwds, as in:
- ppp pap sent-username AS3727 password 7 10581C17581043
+- extreme collections loses when the config on the switch is in an unsaved
+ state, probably due to the prompt changing or rather the regex clogin
+ formulates for the prompt.
+- cat4 support?
+- would be nice if it were possible to add additional commands to be run
+ per-platform as a user desires. how could the user also provide a
+ filtering routine?
+- need par.1 manpage
- need to make sure the following patch was applied to the lookingglass
All routers not listed as 'up' in router.db are considered down.
This allows values other than down to mean 'not up'. for use
by util/downreport.
- a format such as {<user>} as the pwd in .cloginrc to indicate *login should
prompt the user for the password
-- handle reback in the looking glass
+- handle redback in the looking glass
- implement the bits marked unimplemented in lg.conf
- detect 'same' vty configs
- ignoring length/width/passwd is a start, but need more
diff --git a/bin/blogin.in b/bin/blogin.in
index 0c353d0..ceb58e6 100755
--- a/bin/blogin.in
+++ b/bin/blogin.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
@@ -19,7 +19,8 @@
# blogin - Bay Networks(Nortel) login
#
# Unlike the Cisco's, there is no enable function on the Bay's.
-# Instead there are seperate User and Manager accounts.
+# Instead there are seperate User and Manager accounts. A 'system' command
+# exists, which i am told does nothing.
#
# Usage line
diff --git a/bin/brancid.in b/bin/brancid.in
index 6beb78f..fd8e5aa 100755
--- a/bin/brancid.in
+++ b/bin/brancid.in
@@ -2,7 +2,7 @@
##
## hacked version of Hank's rancid - this one tries to deal with Bay's.
##
-## 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
@@ -140,6 +140,8 @@ sub ShowConfig {
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
next if (/^Reading configuration information/);
+ next if (/^Can\'t find object or class named \"\-all\"\s*$/);
+ next if (/^\# *uptime +\d+\s*$/);
if (/community label /) {
if (defined($ENV{'NOCOMMSTR'})) {
$_ =~ s/community label .*$/community label <removed>/;
@@ -178,15 +180,17 @@ sub DoNothing {print STDOUT;}
# Main
%commands=(
- 'bcc' => "RunCommand",
- 'show config' => "ShowConfig",
- 'exit' => "RunCommand"
+ 'bcc' => "RunCommand",
+ 'show config' => "ShowConfig",
+ 'show config -all' => "ShowConfig",
+ 'exit' => "RunCommand"
);
# 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=(
"bcc",
"show config",
+ "show config -all",
"exit"
);
$cisco_cmds=join(";",@commands);
diff --git a/bin/clogin.in b/bin/clogin.in
index 1929efd..4ebe2ac 100755
--- a/bin/clogin.in
+++ b/bin/clogin.in
@@ -432,7 +432,7 @@ proc run_commands { prompt command } {
# If the prompt is (enable), then we are on a switch and the
# command is "set length 0"; otherwise its "term length 0".
# skip if its and extreme.
- if { [ string compare "extreme" "$prompt" ] } {
+ if { [ string compare "extreme" "$platform" ] } {
if [ regexp -- ".*> .*enable" "$prompt" ] {
send "set length 0\r"
} else {
@@ -501,7 +501,12 @@ proc run_commands { prompt command } {
}
}
log_user 1
- send "exit\r"
+
+ if { [ string compare "extreme" "$platform" ] } {
+ send "exit\r"
+ } else {
+ send "quit\r"
+ }
expect {
"Do you wish to save your configuration changes" {
send "n\r"
diff --git a/bin/control_rancid.in b/bin/control_rancid.in
index ed8af8b..3d4935e 100755
--- a/bin/control_rancid.in
+++ b/bin/control_rancid.in
@@ -20,7 +20,7 @@
#
# Number of things par should run in parallel.
-PAR_COUNT=5
+PAR_COUNT=${PAR_COUNT:-5}
# Must specify a group to run rancid
if [ $# -lt 1 ]; then
diff --git a/bin/env.in b/bin/env.in
index ccfa9be..1f58c7d 100644
--- a/bin/env.in
+++ b/bin/env.in
@@ -25,9 +25,13 @@ CVSROOT=$BASEDIR/CVS; export CVSROOT
#NOCOMMSTR=YES; export NOCOMMSTR
#
# How many hours to go by before complaining about routers that
-# can not be reached.
+# can not be reached. The value should be greater than the number
+# of hours between your do-diffs cron job.
OLDTIME=4; export OLDTIME
#
+# The number of devices to collect simultaneously.
+#PAR_COUNT=5; export PAR_COUNT
+#
# list of rancid groups
LIST_OF_GROUPS="sl joebobisp"
#
diff --git a/bin/hlogin.in b/bin/hlogin.in
new file mode 100755
index 0000000..66f8859
--- /dev/null
+++ b/bin/hlogin.in
@@ -0,0 +1,672 @@
+#!@EXPECT_PATH@ --
+##
+##
+## 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.
+##
+##
+#
+# hlogin - hp login
+#
+# Most options are intuitive for logging into a Cisco router.
+# The default is to enable (thus -noenable). Some folks have
+# setup tacacs to have a user login at priv-lvl = 15 (enabled)
+# so the -autoenable flag was added for this case (don't go through
+# the process of enabling and the prompt will be the "#" prompt.
+# The default username password is the same as the vty password.
+#
+
+# Usage line
+set usage "Usage: $argv0 \[-autoenable\] \[-noenable\] \[-c command\] \
+\[-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"
+
+# env(CLOGIN) may contain:
+# x == do not set xterm banner or name
+
+# Password file
+set password_file $env(HOME)/.cloginrc
+# Default is to login to the router
+set do_command 0
+set do_script 0
+# The default is to automatically enable
+set enable 1
+# The default is that you login non-enabled (tacacs can have you login already enabled)
+set autoenable 0
+# The default is to look in the password file to find the passwords. This
+# 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) ] } {
+ set default_user $env(CISCO_USER)
+} elseif {[ info exists env(USER) ]} {
+ set default_user $env(USER)
+} else {
+ # This uses "id" which I think is portable. At least it has existed
+ # (without options) on all machines/OSes I've been on recently -
+ # unlike whoami or id -nu.
+ if [ catch {exec id} reason ] {
+ send_error "\nError: could not exec id: $reason\n"
+ exit 1
+ }
+ regexp {\(([^)]*)} "$reason" junk default_user
+}
+
+# Sometimes routers take awhile to answer (the default is 10 sec)
+set timeout 45
+
+# Process the command line
+for {set i 0} {$i < $argc} {incr i} {
+ set arg [lindex $argv $i]
+
+ switch -glob -- $arg {
+ # Username
+ -u* -
+ -U* {
+ if {! [ regexp .\[uU\](.+) $arg ignore user]} {
+ incr i
+ set username [ lindex $argv $i ]
+ }
+ # VTY Password
+ } -p* -
+ -P* {
+ if {! [ regexp .\[pP\](.+) $arg ignore userpasswd]} {
+ incr i
+ set userpasswd [ lindex $argv $i ]
+ }
+ set do_passwd 0
+ # VTY Password
+ } -v* -
+ -v* {
+ if {! [ regexp .\[vV\](.+) $arg ignore passwd]} {
+ incr i
+ set passwd [ lindex $argv $i ]
+ }
+ set do_passwd 0
+ # Enable Username
+ } -w* -
+ -W* {
+ if {! [ regexp .\[wW\](.+) $arg ignore enauser]} {
+ 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*
+ {
+ if {! [ regexp .\[e\](.+) $arg ignore enapasswd]} {
+ incr i
+ set enapasswd [ lindex $argv $i ]
+ }
+ set do_enapasswd 0
+ # Command to run.
+ } -c* -
+ -C* {
+ if {! [ regexp .\[cC\](.+) $arg ignore command]} {
+ incr i
+ set command [ lindex $argv $i ]
+ }
+ set do_command 1
+ # Expect script to run.
+ } -s* -
+ -S* {
+ if {! [ regexp .\[sS\](.+) $arg ignore sfile]} {
+ incr i
+ set sfile [ lindex $argv $i ]
+ }
+ if { ! [ file readable $sfile ] } {
+ send_user "\nError: Can't read $sfile\n"
+ exit 1
+ }
+ set do_script 1
+ # 'ssh -c' cypher type
+ } -y* -
+ -Y* {
+ if {! [ regexp .\[eE\](.+) $arg ignore cypher]} {
+ incr i
+ set cypher [ lindex $argv $i ]
+ }
+ # alternate cloginrc file
+ } -f* -
+ -F* {
+ if {! [ regexp .\[fF\](.+) $arg ignore password_file]} {
+ incr i
+ set password_file [ lindex $argv $i ]
+ }
+ # Timeout
+ } -t* -
+ -T* {
+ if {! [ regexp .\[tT\](.+) $arg ignore timeout]} {
+ incr i
+ set timeout [ lindex $argv $i ]
+ }
+ # Command file
+ } -x* -
+ -X {
+ if {! [ regexp .\[xX\](.+) $arg ignore cmd_file]} {
+ incr i
+ set cmd_file [ lindex $argv $i ]
+ }
+ 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] \;]
+ set do_command 1
+ # Do we enable?
+ } -noenable {
+ set enable 0
+ # Does tacacs automatically enable us?
+ } -autoenable {
+ # hp does not autoenable
+ #set autoenable 1
+ #set enable 0
+ } -* {
+ send_user "\nError: Unknown argument! $arg\n"
+ send_user $usage
+ exit 1
+ } default {
+ break
+ }
+ }
+}
+# Process routers...no routers listed is an error.
+if { $i == $argc } {
+ send_user "\nError: $usage"
+}
+
+# Only be quiet if we are running a script (it can log its output
+# on its own)
+if { $do_script } {
+ log_user 0
+} else {
+ log_user 1
+}
+
+#
+# Done configuration/variable setting. Now run with it...
+#
+
+# Sets Xterm title if interactive...if its an xterm and the user cares
+proc label { host } {
+ global env
+ # if CLOGIN has an 'x' in it, don't set the xterm name/banner
+ if [info exists env(CLOGIN)] {
+ if {[string first "x" $env(CLOGIN)] != -1} { return }
+ }
+ # take host from ENV(TERM)
+ if [info exists env(TERM)] {
+ if [regexp \^(xterm|vs) $env(TERM) ignore ] {
+ send_user "\033]1;[lindex [split $host "."] 0]\a"
+ send_user "\033]2;$host\a"
+ }
+ }
+}
+
+# This is a helper function to make the password file easier to
+# maintain. Using this the password file has the form:
+# add password sl* pete cow
+# add password at* steve
+# add password * hanky-pie
+proc add {var args} { global int_$var ; lappend int_$var $args}
+proc include {args} {
+ global env
+ regsub -all "(^{|}$)" $args {} args
+ if { [ regexp "^/" $args ignore ] == 0 } {
+ set args $env(HOME)/$args
+ }
+ source_password_file $args
+}
+
+proc find {var router} {
+ upvar int_$var list
+ if { [info exists list] } {
+ foreach line $list {
+ if { [string match [lindex $line 0] $router ] } {
+ return [lrange $line 1 end]
+ }
+ }
+ }
+ return {}
+}
+
+# Loads the password file. Note that as this file is tcl, and that
+# it is sourced, the user better know what to put in there, as it
+# could install more than just password info... I will assume however,
+# that a "bad guy" could just as easy put such code in the clogin
+# script, so I will leave .cloginrc as just an extention of that script
+proc source_password_file { password_file } {
+ global env
+ if { ! [file exists $password_file] } {
+ send_user "\nError: password file ($password_file) does not exist\n"
+ exit 1
+ }
+ file stat $password_file fileinfo
+ if { [expr ($fileinfo(mode) & 007)] != 0000 } {
+ send_user "\nError: $password_file must not be world readable/writable\n"
+ exit 1
+ }
+ if [ catch {source $password_file} reason ] {
+ send_user "\nError: $reason\n"
+ exit 1
+ }
+}
+
+# Log into the router.
+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
+ set progs [llength $cmethod]
+ foreach prog [lrange $cmethod 0 end] {
+ if ![string compare $prog "telnet"] {
+ if [ catch {spawn telnet $router} reason ] {
+ send_user "\nError: telnet failed: $reason\n"
+ exit 1
+ }
+ } elseif ![string compare $prog "ssh"] {
+ if [ catch {spawn ssh -c $cyphertype -x -l $user $router} reason ] {
+ send_user "\nError: ssh failed: $reason\n"
+ exit 1
+ }
+ } elseif ![string compare $prog "rsh"] {
+ if [ catch {spawn rsh -l $user $router} reason ] {
+ send_user "\nError: rsh failed: $reason\n"
+ exit 1
+ }
+ } else {
+ puts "\nError: unknown connection method: $prog"
+ return 1
+ }
+ incr progs -1
+ sleep 0.3
+
+ # This helps cleanup each expect clause.
+ expect_after {
+ timeout {
+ send_user "\nError: TIMEOUT reached\n"
+ catch {close}; wait
+ if { $in_proc} {
+ return 1
+ } else {
+ continue
+ }
+ } eof {
+ send_user "\nError: EOF received\n"
+ catch {close}; wait
+ if { $in_proc} {
+ return 1
+ } else {
+ continue
+ }
+ }
+ }
+
+ # Here we get a little tricky. There are several possibilities:
+ # the router can ask for a username and passwd and then
+ # talk to the TACACS server to authenticate you, or if the
+ # TACACS server is not working, then it will use the enable
+ # passwd. Or, the router might not have TACACS turned on,
+ # then it will just send the passwd.
+ # if telnet fails with connection refused, try ssh
+ expect {
+ "Press any key to continue" {
+ send " "
+ exp_continue
+ }
+ -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
+ }
+ } eof { send_user "\nError: Couldn't login\n"; wait; return 1
+ } -nocase "unknown host\r" {
+ catch {close};
+ send_user "\nError: Unknown host\n"; wait; return 1
+ } "Host is unreachable" {
+ catch {close};
+ send_user "\nError: Host Unreachable!\n"; wait; return 1
+ } "No address associated with name" {
+ catch {close};
+ send_user "\nError: Unknown host\n"; wait; return 1
+ }
+ -re "(Host key not found |The authenticity of host .* be established).*\(yes\/no\)\?" {
+ send "yes\r"
+ send_user "\nHost $router added to the list of known hosts.\n"
+ exp_continue }
+ -re "HOST IDENTIFICATION HAS CHANGED.* \(yes\/no\)\?" {
+ send "no\r"
+ send_user "\nError: The host key for $router has changed. update the known_hosts file accordingly.\n"
+ return 1 }
+ -re "$u_prompt" { send "$user\r"
+ expect {
+ eof { send_user "\nError: Couldn't login\n"; wait; return 1 }
+ "Login invalid" { send_user "\nError: Invalid login\n"; vatch {close}; wait; return 1 }
+ -re "$p_prompt" { send "$userpswd\r" }
+ "$prompt" { set in_proc 0; return 0 }
+ }
+ exp_continue
+ }
+ -re "$p_prompt" {
+ if ![string compare $prog "ssh"] {
+ send "$userpswd\r"
+ } else {
+ send "$passwd\r"
+ }
+ expect {
+ eof { send_user "\nError: Couldn't login\n"; wait; return 1 }
+ -re "$e_prompt" { send "$enapasswd\r" }
+ "$prompt" { set in_proc 0; return 0 }
+ }
+ exp_continue
+ }
+ "$prompt" { break; }
+ denied { send_user "\nError: Check your passwd for $router\n"
+ if { $do_command || $do_script } {
+ send "exit\r"
+ expect {
+ "Do you want to log out" {
+ send "y\r"
+ exp_continue
+ }
+ }
+ wait
+ return 1
+ } else {
+ return 1
+ }
+ }
+ "% Bad passwords" {send_user "\nError: Check your passwd for $router\n"; return 1 }
+ }
+ }
+
+ set in_proc 0
+ return 0
+}
+
+# Enable
+proc do_enable { enauser enapasswd } {
+ global prompt in_proc
+ global u_prompt e_prompt
+ set in_proc 1
+
+ send "enable\r"
+ expect {
+ -re "$u_prompt" { send "$enauser\r"; exp_continue}
+ -re "$e_prompt" { send "$enapasswd\r"; exp_continue}
+ "#" { set prompt "#" }
+ "(enable)" { set prompt "> (enable) " }
+ denied { send_user "\nError: Check your Enable passwd\n"; return 1}
+ "% Bad passwords" { send_user "\nError: Check your Enable passwd\n"
+ return 1
+ }
+ }
+ # We set the prompt variable (above) so script files don't need
+ # to know what it is.
+ set in_proc 0
+ return 0
+}
+
+# Run commands given on the command line.
+proc run_commands { prompt command } {
+ 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".
+ # skip if its and extreme.
+ send "no page\r"
+ regsub -all "\[)(]" $prompt {\\&} reprompt
+ expect {
+ -re $reprompt {}
+ -re "\[\n\r]+" { exp_continue }
+ }
+ # 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. 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" { 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 "\[^\r\n]*Press <SPACE> to cont\[^\r\n]*" { send " "
+ expect {
+ # gag, 2 more prompts
+ -re "\[\r\n]*\r" {}
+ -re "\[^\r\n]*Press <SPACE> 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. the extreme is equally obnoxious, with a
+ # global switch in the config.
+ send "[subst -nocommands $command]\r"
+ expect {
+ -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 "\[^\r\n]*Press <SPACE> 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 {
+ "Do you want to log out" {
+ send "y\r"
+ exp_continue
+ }
+ "Do you wish to save " {
+ send "n\r"
+ exp_continue
+ }
+ "\n" { exp_continue }
+ timeout { return 0 }
+ eof { return 0 }
+ }
+ set in_proc 0
+}
+
+#
+# For each router... (this is main loop)
+#
+source_password_file $password_file
+set in_proc 0
+foreach router [lrange $argv $i end] {
+ set router [string tolower $router]
+ send_user "$router\n"
+
+ # Figure out prompt.
+ # Since autoenable is off by default, if we have it defined, it
+ # was done on the command line. If it is not specifically set on the
+ # command line, check the password file.
+ if $autoenable {
+ set prompt "#"
+ } else {
+ set ae [find autoenable $router]
+ if { "$ae" == "1" } {
+ set autoenable 1
+ set enable 0
+ set prompt "#"
+ } else {
+ set autoenable 0
+ set prompt ">"
+ }
+ }
+
+ # look for noenable option in .cloginrc
+ if { [find noenable $router] != "" } {
+ set enable 0
+ }
+
+ # Figure out passwords
+ 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"
+ continue
+ }
+ 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]
+ set enapasswd [lindex $pswd 1]
+ }
+
+ # Figure out username
+ if {[info exists username]} {
+ # command line username
+ set ruser $username
+ } else {
+ set ruser [find user $router]
+ if { "$ruser" == "" } { set ruser $default_user }
+ }
+
+ # Figure out username's password (if different from the vty password)
+ if {[info exists userpasswd]} {
+ # command line username
+ set userpswd $userpasswd
+ } else {
+ set userpswd [find userpassword $router]
+ if { "$userpswd" == "" } { set userpswd $passwd }
+ }
+
+ # Figure out enable username
+ if {[info exists enausername]} {
+ # command line enausername
+ set enauser $enausername
+ } else {
+ set enauser [find enauser $router]
+ if { "$enauser" == "" } { set enauser $ruser }
+ }
+
+ # Figure out prompts
+ set u_prompt [find userprompt $router]
+ if { "$u_prompt" == "" } { set u_prompt "(Username|login|user name):" }
+ set p_prompt [find passprompt $router]
+ if { "$p_prompt" == "" } { set p_prompt "(\[Pp]assword|passwd):" }
+ set e_prompt [find enableprompt $router]
+ if { "$e_prompt" == "" } { set e_prompt "\[Pp]assword:" }
+
+ # Figure out cypher type
+ if {[info exists cypher]} {
+ # command line cypher type
+ set cyphertype $cypher
+ } else {
+ set cyphertype [find cyphertype $router]
+ if { "$cyphertype" == "" } { set cyphertype "3des" }
+ }
+
+ # Figure out connection method
+ set cmethod [find method $router]
+ if { "$cmethod" == "" } { set cmethod {{telnet} {ssh}} }
+
+ # Login to the router
+ if {[login $router $ruser $userpswd $passwd $enapasswd $cmethod $cyphertype]} {
+ continue
+ }
+ if { $enable } {
+ if {[do_enable $enauser $enapasswd]} {
+ if { $do_command || $do_script } {
+ close; wait
+ continue
+ }
+ }
+ }
+ # 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]} {
+ continue
+ }
+ } 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 [ regexp -- ".*> .*enable" "$prompt" ] {
+ send "set length 0\r"
+ send "set logging session disable\r"
+ } else {
+ send "term length 0\r"
+ }
+ expect -re $prompt {}
+ source $sfile
+ close
+ } else {
+ label $router
+ log_user 1
+ interact
+ }
+
+ # End of for each router
+ wait
+ sleep 0.3
+}
+exit 0
diff --git a/bin/hrancid.in b/bin/hrancid.in
new file mode 100755
index 0000000..a02ab81
--- /dev/null
+++ b/bin/hrancid.in
@@ -0,0 +1,716 @@
+#!@PERLV_PATH@
+##
+## Amazingly hacked version of Hank's rancid - this one tries to
+## deal with HPs.
+##
+## 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 (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+ next if(/^(\s*|\s*$cmd\s*)$/);
+ return(-1) if (/command authorization failed/i);
+ if (/^Slave in slot (\d+) is running/) {
+ $slave = " Slave:";
+ next;
+ }
+ /^Cisco Secure PIX /i &&
+ ProcessHistory("COMMENTS","keysort","F1", "!Image: $_") && next;
+ /^IOS .* Software \(([A-Za-z-0-9]*)\), .*Version\s+(.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","F1",
+ "!Image:$slave Software: $1, $2\n") && next;
+ /^([A-Za-z-0-9_]*) Synced to mainline version: (.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","F2",
+ "!Image:$slave $1 Synced to mainline version: $2\n") && next;
+ /^Compiled (.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","F3",
+ "!Image:$slave Compiled: $1\n") && next;
+ /^ROM: (System )?Bootstrap.*(Version.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","G1",
+ "!ROM Bootstrap: $2\n") && next;
+ if (/^Hardware:\s+(.*), (.* RAM), CPU (.*)$/) {
+ ProcessHistory("COMMENTS","keysort","A1",
+ "!Chassis type: $1 - a PIX\n");
+ ProcessHistory("COMMENTS","keysort","A2",
+ "!CPU: $3\n");
+ ProcessHistory("COMMENTS","keysort","B1", "!Memory: $2\n");
+ }
+ /^Serial Number:\s+(.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","C1", "!$_") && next;
+ /^Activation Key:\s+(.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","C2", "!$_") && next;
+ /^ROM: \d+ Bootstrap .*(Version.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","G2",
+ "!ROM Image: Bootstrap $1\n!\n") && next;
+ /^ROM: .*(Version.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","G3","!ROM Image: $1\n") && next;
+ /^BOOTFLASH: .*(Version.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","G4","!BOOTFLASH: $1\n") && next;
+ /^System image file is "([^\"]*)", booted via (\S*)/ &&
+# removed the booted source due to
+# CSCdk28131: cycling info in 'sh ver'
+# ProcessHistory("COMMENTS","keysort","F4","!Image: booted via $2, $1\n") &&
+ ProcessHistory("COMMENTS","keysort","F4","!Image: booted $1\n") &&
+ next;
+ /^System image file is "([^\"]*)"$/ &&
+ ProcessHistory("COMMENTS","keysort","F5","!Image: $1\n") && next;
+ if (/(\S+)\s+\((\S+)\)\s+processor.*with (\S+K) bytes/) {
+ my($proc) = $1;
+ my($cpu) = $2;
+ my($mem) = $3;
+ my($device) = "router";
+ if ( $1 eq "CSC") {
+ $type = "AGS";
+ } elsif ( $1 eq "CSC4") {
+ $type = "AGS+";
+ } elsif ( $1 eq "2511" || $1 eq "2524" || $1 eq "AS2511-RJ") {
+ $type = "2500";
+ } elsif ( $1 =~ /261[01]/ || $1 =~ /262[01]/ ) {
+ $type = "2600";
+ } elsif ( $1 eq "3620" || $1 eq "3640") {
+ $type = "3600";
+ } elsif ( $1 eq "RSP7000") {
+ $type = "7500";
+ } elsif ( $1 =~ /RSP\d/) {
+ $type = "7500";
+ } elsif ( $1 eq "RP1") {
+ $type = "7000";
+ } elsif ( $1 eq "RP") {
+ $type = "7000";
+ } elsif ( $1 =~ /720[246]/) {
+ $type = "7200";
+ } elsif ( $1 =~ /1200[48]\/GRP/ || $1 =~ /1201[26]\/GRP/) {
+ $type = "12000";
+ } elsif ( $1 =~ /1201[26]-8R\/GRP/) {
+ $type = "12000";
+ } elsif ( $1 =~ /WS-C29/) {
+ $type = "2900XL";
+ $device = "switch";
+ } elsif ( $1 =~ /WS-C35/) {
+ $type = "3500XL";
+ $device = "switch";
+ } elsif ( $1 =~ /6000/) {
+ $type = "6000";
+ $device = "switch";
+ } else {
+ $type = $1;
+ }
+ print STDERR "TYPE = $type\n" if ($debug);
+ ProcessHistory("COMMENTS","keysort","A1",
+ "!Chassis type:$slave $proc - a $type $device\n");
+ ProcessHistory("COMMENTS","keysort","B1",
+ "!Memory:$slave main $mem\n");
+ ProcessHistory("COMMENTS","keysort","A3","!CPU:$slave $cpu\n");
+ next;
+ }
+ if (/(\S+) Silicon\s*Switch Processor/) {
+ if (!defined($C0)) {
+ $C0=1; ProcessHistory("COMMENTS","keysort","C0","!\n");
+ }
+ ProcessHistory("COMMENTS","keysort","C2","!SSP: $1\n");
+ $ssp = 1;
+ $sspmem = $1;
+ next;
+ }
+ /^(\d+K) bytes of multibus/ &&
+ ProcessHistory("COMMENTS","keysort","B2",
+ "!Memory: multibus $1\n") && next;
+ /^(\d+K) bytes of non-volatile/ &&
+ ProcessHistory("COMMENTS","keysort","B3",
+ "!Memory: nvram $1\n") && next;
+ /^(\d+K) bytes of flash memory/ &&
+ ProcessHistory("COMMENTS","keysort","B5","!Memory: flash $1\n") &&
+ next;
+ /^(\d+K) bytes of .*flash partition/ &&
+ ProcessHistory("COMMENTS","keysort","B6",
+ "!Memory: flash partition $1\n") && next;
+ /^(\d+K) bytes of Flash internal/ &&
+ ProcessHistory("COMMENTS","keysort","B4",
+ "!Memory: bootflash $1\n") && next;
+ if(/^(\d+K) bytes of (Flash|ATA)?.*PCMCIA .*slot ?(\d)/i) {
+ ProcessHistory("COMMENTS","keysort","B7",
+ "!Memory: pcmcia $2 slot$3 $1\n");
+ next;
+ }
+ if(/^WARNING/) {
+ if (!defined($I0)) {
+ $I0=1;
+ ProcessHistory("COMMENTS","keysort","I0","!\n");
+ }
+ ProcessHistory("COMMENTS","keysort","I1","! $_");
+ # The line after the WARNING is what to do about it.
+ $_ = <INPUT>; tr/\015//d;
+ ProcessHistory("COMMENTS","keysort","I1","! $_");
+ }
+ if (/^Configuration register is (.*)$/) {
+ $config_register=$1;
+ next;
+ }
+ }
+ return(0);
+}
+
+# This routine parses "show flash"
+sub ShowFlash {
+ # 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 (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ 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 )/;
+ ProcessHistory("FLASH","","","!Flash: $_");
+ }
+ ProcessHistory("","","","!\n");
+ return;
+}
+
+# This routine parses "show system-information"
+sub ShowSystem {
+ print STDERR " In ShowSystem: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ # return(1) if ($type =~ /^(12[40]|7[05])/);
+ return(-1) if (/command authorization failed/i);
+ if (/^Interface ([^ \n(]*)/) { $INT = "$1, "; next; }
+ /^(BRI unit \d)/ &&
+ ProcessHistory("INT","","","!Interface: $1\n") && next;
+ /^LANCE unit \d, NIM/ &&
+ ProcessHistory("INT","","","!Interface: $_") && next;
+ /^(LANCE unit \d)/ &&
+ ProcessHistory("INT","","","!Interface: $1\n") && next;
+ /(Media Type is \S+),/ &&
+ ProcessHistory("INT","","","!\t$1\n");
+ if (/(M\dT[^ :]*:) show controller:$/) {
+ my($ctlr) = $1;
+ $_ = <INPUT>; tr/\015//d; s/ subunit \d,//;
+ ProcessHistory("INT","","","!Interface: $ctlr $_");
+ }
+ if (/^(\S+) : show controller:$/) {
+ my($ctlr) = $1;
+ $_ = <INPUT>; tr/\015//d; s/ subunit \d,//;
+ ProcessHistory("INT","","","!Interface: $ctlr: $_");
+ }
+ /^(HD unit \d), idb/ &&
+ ProcessHistory("INT","","","!Interface: $1\n") && next;
+ /^HD unit \d, NIM/ &&
+ ProcessHistory("INT","","","!Interface: $_") && next;
+ /^buffer size \d+ HD unit \d, (.*)/ &&
+ ProcessHistory("INT","","","!\t$1\n") && next;
+ /^AM79970 / && ProcessHistory("INT","","","!Interface: $_") && next;
+ /^buffer size \d+ (Universal Serial: .*)/ &&
+ ProcessHistory("INT","","","!\t$1\n") && next;
+ /^Hardware is (.*)/ &&
+ ProcessHistory("INT","","","!Interface: $INT$1\n") && next;
+ /^(QUICC Serial unit \d),/ &&
+ ProcessHistory("INT","","","!$1\n") && next;
+ /^QUICC Ethernet .*/ &&
+ ProcessHistory("INT","","","!$_") && next;
+ /^DTE .*\.$/ &&
+ ProcessHistory("INT","","","!\t$_") && next;
+ /^(cable type :.*),/ &&
+ ProcessHistory("INT","","","!\t$1\n") && next;
+ /^(.* cable.*), received clockrate \d+$/ &&
+ ProcessHistory("INT","","","!\t$1\n") && next;
+ /^.* cable.*$/ &&
+ ProcessHistory("INT","","","!\t$_") && next;
+ }
+ return(0);
+}
+
+# This routine parses "show module".
+sub ShowModule {
+ print STDERR " In ShowModule: $_" if ($debug);
+
+ my(@lines);
+ my($slot);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ return if (/^\s*\^$/);
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(-1) if (/command authorization failed/i);
+
+ # 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;
+ }
+ # 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;
+ }
+ }
+ foreach $slot (@lines) {
+ next if ($slot =~ /^\s*$/);
+ ProcessHistory("Module","","","$slot!\n");
+ }
+
+ return(0);
+}
+
+# This routine parses "show stack"
+sub ShowStack {
+ print STDERR " In ShowStack: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(-1) if (/command authorization failed/i);
+ /^$/ && next;
+ if (/C7200 Midplane EEPROM:/) {
+ $_ = <INPUT>;
+ /revision\s+(\S+).*revision\s+(\S+)/;
+ ProcessHistory("SLOT","","","!Slot Midplane: hvers $1 rev $2\n");
+ $_ = <INPUT>;
+ /number\s+(\S+)\s+Part number\s+(\S+)/;
+ ProcessHistory("SLOT","","","!Slot Midplane: part $2, serial $1\n!\n");
+ next;
+ }
+ if (/C720\d(VXR)? CPU EEPROM:/) {
+ $_ = <INPUT>;
+ /revision\s+(\S+).*revision\s+(\S+)/ &&
+ ProcessHistory("SLOT","","","!Slot CPU: hvers $1 rev $2\n");
+ $_ = <INPUT>;
+ /number\s+(\S+)\s+Part number\s+(\S+)/ &&
+ ProcessHistory("SLOT","","","!Slot CPU: part $2, serial $1\n!\n");
+ next;
+ }
+ }
+ return(0);
+}
+
+# This routine processes a "write term"
+sub WriteTerm {
+ print STDERR " In WriteTerm: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+ return(-1) if (/command authorization failed/i);
+ # the pager can not be disabled per-session on the PIX
+ s/^<-+ More -+>\s*//;
+ /Non-Volatile memory is in use/ && return(-1); # NvRAM is locked
+ # skip the crap
+ if (/^(##+$|Building configuration...)/i) {
+ while (<INPUT>) {
+ next if (/^Current configuration\s*:/i);
+ next if (/^:/);
+ next if (/^([%!].*|\s*)$/);
+ next if (/^ip add.*ipv4:/); # band-aid for 3620 12.0S
+ last;
+ }
+ if (defined($config_register)) {
+ ProcessHistory("","","","!\nconfig-register $config_register\n");
+ }
+ tr/\015//d;
+ }
+ # some versions have other crap mixed in with the bits in the
+ # block above
+ /^! (Last configuration|NVRAM config last)/ && next;
+
+ # Dog gone Cool matches to process the rest of the config
+ /^tftp-server flash / && next; # kill any tftp remains
+ /^ntp clock-period / && next; # kill ntp clock-period
+ /^ length / && next; # kill length on serial lines
+ /^ width / && next; # kill width on serial lines
+ /^ clockrate / && next; # kill clockrate on serial interfaces
+ /^(enable )?(password|passwd) / &&
+ ProcessHistory("ENABLE","","","!$1$2 <removed>\n") &&
+ next;
+ /^username (\S+)(\s.*)? password /&&
+ ProcessHistory("USER","keysort","$1","!username $1$2 password <removed>\n") && next;
+ /^\s*password / &&
+ ProcessHistory("LINE-PASS","","","! password <removed>\n") && next;
+ /^\s*neighbor (\S*) password / &&
+ ProcessHistory("","","","! neighbor $1 password <removed>\n") &&
+ next;
+ /^(ip ftp password) / &&
+ ProcessHistory("","","","!$1 <removed>\n") && next;
+ /^( ip ospf authentication-key) / &&
+ ProcessHistory("","","","!$1 <removed>\n") && next;
+ /^( ip ospf message-digest-key \d+ md5) / &&
+ ProcessHistory("","","","!$1 <removed>\n") && next;
+ /fair-queue individual-limit/ && next;
+ # sort ip explicit-paths.
+ if (/^ip explicit-path name (\S+)/) {
+ my($key) = $1;
+ my($expath) = $_;
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ last if (/^$prompt/ || ! /^(ip explicit-path name |[ !])/);
+ if (/^ip explicit-path name (\S+)/) {
+ ProcessHistory("EXPATH","keysort","$key","$expath");
+ $key = $1;
+ $expath = $_;
+ } else {
+ $expath .= $_;
+ }
+ }
+ ProcessHistory("EXPATH","keysort","$key","$expath");
+ }
+ # sort route-maps
+ if (/^route-map (\S+)/) {
+ my($key) = $1;
+ my($routemap) = $_;
+ while (<INPUT>) {
+ 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
+ /^logging (\d+\.\d+\.\d+\.\d+)/ &&
+ ProcessHistory("LOGGING","ipsort","$1","$_") && next;
+ # order/prune snmp-server host statements
+ # we only prune lines of the form
+ # snmp-server host a.b.c.d <community>
+ if (/^snmp-server host (\d+\.\d+\.\d+\.\d+) /) {
+ if (defined($ENV{'NOCOMMSTR'})) {
+ my($ip) = $1;
+ my($line) = "snmp-server host $ip";
+ my(@tokens) = split(' ', $');
+ my($token);
+ while ($token = shift(@tokens)) {
+ if ($token eq 'version') {
+ $line .= " " . join(' ', ($token, shift(@tokens)));
+ } elsif ($token =~ /^(informs?|traps?|(no)?auth)$/) {
+ $line .= " " . $token;
+ } else {
+ $line = "!$line " . join(' ', ("<removed>", join(' ',@tokens)));
+ last;
+ }
+ }
+ ProcessHistory("SNMPSERVERHOST","ipsort","$ip","$line\n");
+ } else {
+ ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_");
+ }
+ next;
+ }
+ if (/^(snmp-server community) (\S+)/) {
+ if (defined($ENV{'NOCOMMSTR'})) {
+ ProcessHistory("SNMPSERVERCOMM","keysort","$_","!$1 <removed>$'") && next;
+ } else {
+ ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next;
+ }
+ }
+ # order/prune tacacs/radius server statements
+ /^(tacacs-server|radius-server) key / &&
+ ProcessHistory("","","","!$1 key <removed>\n") && next;
+ # order clns host statements
+ /^clns host \S+ (\S+)/ &&
+ ProcessHistory("CLNS","keysort","$1","$_") && next;
+ # order alias statements
+ /^alias / && ProcessHistory("ALIAS","keysort","$_","$_") && next;
+ # delete ntp auth password
+ /^(ntp authentication-key \d+ md5) / &&
+ ProcessHistory("","","","!$1 <removed>\n") && next;
+ # order ntp peers/servers
+ if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) {
+ $sortkey = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5);
+ ProcessHistory("NTP","keysort",$sortkey,"$_");
+ next;
+ }
+ # order ip host line statements
+ /^ip host line(\d+)/ &&
+ ProcessHistory("IPHOST","numsort","$1","$_") && next;
+ # order ip nat source static statements
+ /^ip nat (\S+) source static (\S+)/ &&
+ ProcessHistory("IP NAT $1","ipsort","$2","$_") && next;
+ # order atm map-list statements
+ /^\s+ip\s+(\d+\.\d+\.\d+\.\d+)\s+atm-vc/ &&
+ ProcessHistory("ATM map-list","ipsort","$1","$_") && next;
+ # order ip rcmd lines
+ /^ip rcmd/ && ProcessHistory("RCMD","keysort","$_","$_") && next;
+
+ # system controller
+ /^syscon address (\S*) (\S*)/ &&
+ ProcessHistory("","","","!syscon address $1 <removed>\n") &&
+ next;
+ /^syscon password (\S*)/ &&
+ ProcessHistory("","","","!syscon password <removed>\n") &&
+ next;
+
+ # catch anything that wasnt match above.
+ ProcessHistory("","","","$_");
+ # end of config
+ #if (/^end(\n\[OK])?$/) {
+ if (/^(: )?end$/) {
+ $found_end = 1;
+ return(1);
+ }
+ }
+ return(0);
+}
+
+# dummy function
+sub DoNothing {print STDOUT;}
+
+# Main
+%commands=(
+ 'show version' => "ShowVersion",
+ 'show flash' => "ShowFlash",
+ 'show system-information' => "ShowSystem",
+ 'show module' => "ShowModule",
+ 'show stack' => "ShowStack",
+ 'write term' => "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 flash",
+ "show system-information",
+ "show module",
+ "show stack",
+ "write term"
+);
+$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 hlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug);
+ print STDOUT "executing hlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log);
+ if (defined($ENV{NOPIPE})) {
+ system "hlogin -t $timeo -c \"$cisco_cmds\" $host </dev/null > $host.raw 2>&1" || die "hlogin failed for $host: $!\n";
+ open(INPUT, "< $host.raw") || die "hlogin failed for $host: $!\n";
+ } else {
+ open(INPUT,"hlogin -t $timeo -c \"$cisco_cmds\" $host </dev/null |") || die "hlogin failed for $host: $!\n";
+ }
+}
+
+ProcessHistory("","","","!RANCID-CONTENT-TYPE: hp\n!\n");
+ProcessHistory("COMMENTS","keysort","B0","!\n");
+ProcessHistory("COMMENTS","keysort","F0","!\n");
+ProcessHistory("COMMENTS","keysort","G0","!\n");
+TOP: while(<INPUT>) {
+ tr/\015//d;
+ if (/\#\s?exit$/) {
+ $clean_run=1;
+ last;
+ }
+ if (/^Error:/) {
+ print STDOUT ("$host clogin error: $_");
+ print STDERR ("$host clogin error: $_") if ($debug);
+ $clean_run=0;
+ last;
+ }
+ while (/#\s*($cmds_regexp)\s*$/) {
+ $cmd = $1;
+ if (!defined($prompt)) {$prompt = ($_ =~ /^([^#]+#)/)[0]; }
+ 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) {
+ $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);
+}
diff --git a/bin/jlogin.in b/bin/jlogin.in
index ee49d31..6081365 100755
--- a/bin/jlogin.in
+++ b/bin/jlogin.in
@@ -333,6 +333,7 @@ proc login { router user passwd cmethod cyphertype identfile} {
}
-re "Enter passphrase for RSA key '\[^'\]*': " {
send_user "\nKey has passphrase!\n"
+ sleep 1
send "$passphrase\r"
exp_continue }
-re "(Host key not found |The authenticity of host .* be established).*\(yes\/no\)\?" {
@@ -347,12 +348,12 @@ proc login { router user passwd cmethod cyphertype identfile} {
expect {
eof { send_user "\nError: Couldn't login\n";
wait; return 1 }
- -re "\[Pp]assword:" { send "$passwd\r" }
+ -re "\[Pp]assword:" { sleep 1; send "$passwd\r" }
-re "$prompt" { break; }
}
exp_continue
}
- "\[Pp]assword:" { send "$passwd\r"
+ "\[Pp]assword:" { sleep 1; send "$passwd\r"
expect {
eof { send_user "\nError: Couldn't login\n"; wait; return 1 }
-re "$prompt" { break; }
diff --git a/bin/jrancid.in b/bin/jrancid.in
index 56d98c7..b75c8e7 100755
--- a/bin/jrancid.in
+++ b/bin/jrancid.in
@@ -152,6 +152,9 @@ sub ShowChassisClocks {
/command is not valid/ && return;
/^\s+\^/ && return;
/syntax error/ && return;
+
+ # filter decimal places of m160 measured clock MHz
+ /Measured frequency/ && s/\..*MHz/ MHz/;
ProcessHistory("","","","# $_");
}
return;
diff --git a/bin/par.in b/bin/par.in
index 88c66af..494de53 100755
--- a/bin/par.in
+++ b/bin/par.in
@@ -101,7 +101,6 @@ for($i=0;<>;$i++) {
if(/^:(.*)$/){$command=$1;$i--;next;}
if ($i<$procs) {
$logfile="running.$i"; $logfile="$parlog.$i" if (!$opt_q);
- watchf($logfile) if($opt_x);
} else { $logfile=finish; }
last if $signalled;
if ($logfile) {
@@ -109,6 +108,7 @@ for($i=0;<>;$i++) {
$cmd =~ s/\{\}/$_/g;
$cmd = "xterm -e $cmd" if ($opt_i);
$id=start($cmd,$logfile);
+ watchf($logfile) if($opt_x);
$log{$id}=$logfile;
}
print STDERR "$i/$procs: $_: id=$id, log=$log{$id}\n" if ($debug);
diff --git a/bin/rancid-fe.in b/bin/rancid-fe.in
index a00915f..a09d937 100755
--- a/bin/rancid-fe.in
+++ b/bin/rancid-fe.in
@@ -33,6 +33,8 @@ if ($vendor =~ /^baynet$/i) {
exec('cat5rancid', $router);
} elsif ($vendor =~ /^ezt3$/i) {
exec('erancid', $router);
+} elsif ($vendor =~ /^hp$/i) {
+ exec('hrancid', $router);
} elsif ($vendor =~ /^juniper$/i) {
exec('jrancid', $router);
} elsif ($vendor =~ /^foundry$/i) {
diff --git a/bin/rancid.in b/bin/rancid.in
index 45a8563..811cf37 100755
--- a/bin/rancid.in
+++ b/bin/rancid.in
@@ -887,6 +887,8 @@ sub WriteTerm {
/^\s*neighbor (\S*) password / &&
ProcessHistory("","","","! neighbor $1 password <removed>\n") &&
next;
+ /^(ppp .* password) 7 .*/ &&
+ ProcessHistory("","","","!$1 <removed>\n") && next;
/^(ip ftp password) / &&
ProcessHistory("","","","!$1 <removed>\n") && next;
/^( ip ospf authentication-key) / &&
diff --git a/bin/xrancid.in b/bin/xrancid.in
index b60697c..ace12b7 100755
--- a/bin/xrancid.in
+++ b/bin/xrancid.in
@@ -140,13 +140,17 @@ sub ShowVersion {
next if(/^(\s*|\s*$cmd\s*)$/);
/^\S+ Serial Number:/i &&
- ProcessHistory("COMMENTS","keysort","A0","#$_") && next;
+ ProcessHistory("COMMENTS","keysort","B0","#$_") && next;
/^(\S+) Power Supply ([^:]+):\s+(.*)/i &&
- ProcessHistory("COMMENTS","keysort","B0","#Power: $1 $2 $3\n")
+ ProcessHistory("COMMENTS","keysort","C0","#Power: $1 $2 $3\n")
&& next;
- /^Image\s*:\s*(.*)/i &&
- ProcessHistory("COMMENTS","keysort","C0","#Image: $1\n")
+ /^image\s*:\s*(.*)\s+by\s+/i &&
+ ProcessHistory("COMMENTS","keysort","D0","#Image: $1\n")
&& next;
+ /^bootrom\s+:\s+(.*)/i &&
+ ProcessHistory("COMMENTS","keysort","D1","#\n#Bootrom: $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 <FF>
#SLOT 2 : 702005-06 0021S-00131 CPLD Rev 02
@@ -166,12 +170,37 @@ sub ShowMemory {
next if(/^(\s*|\s*$cmd\s*)$/);
/^Total DRAM Size: (.*)/ &&
- ProcessHistory("COMMENTS","keysort","A0","#\n#Memory: $1\n")
+ ProcessHistory("COMMENTS","keysort","B1","#\n#Memory: $1\n")
+ }
+ return(0);
+}
+
+# This routine parses "show diagnostics"
+sub ShowDiag {
+ print STDERR " In ShowDiag: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+
+ /platform\s+:\s+(.*)$/i &&
+ ProcessHistory("COMMENTS","keysort","A0","#Chassis type: $1\n") &&
+ next;
+ /(\S+) part no\s+:\s+(.*)$/i &&
+ ProcessHistory("COMMENTS","keysort","E0","#$1 PN: $2\n") &&
+ next;
+ /(\S+ \S+) no\s+:\s+(.*)$/i &&
+ ProcessHistory("COMMENTS","keysort","E0","#$1 PN: $2\n") &&
+ next;
+ /(mac address)\s+:\s+(.*)$/i &&
+ ProcessHistory("COMMENTS","keysort","B0","#$1: $2\n") &&
+ next;
}
return(0);
}
-# This routine parses "show install active"
+# This routine parses "show slot"
sub ShowSlot {
print STDERR " In ShowSlot: $_" if ($debug);
@@ -183,7 +212,7 @@ sub ShowSlot {
if (/^Slot\s+(\d+)\s+/i) {
my($slot) = $1;
my($hwtype, $conftype, $sn, $state);
- ProcessHistory("SLOT","keysort","$slot","#\n");
+ ProcessHistory("COMMENTS","keysort","F$slot","#\n");
while (<INPUT>) {
tr/\015//d;
last if (/^$prompt/ || /^\s*$/);
@@ -192,7 +221,8 @@ sub ShowSlot {
if (/hw module type:\s+(.*)$/i) { $hwtype = $1; }
if (/configured type:\s+(.*)$/i) { $conftype = $1; }
}
- ProcessHistory("SLOT","keysort","$slot","#Slot $slot: type $hwtype,"
+ ProcessHistory("COMMENTS","keysort","F$slot","#Slot $slot: type "
+ . "$hwtype,"
. " $conftype\n#Slot $slot: serial $sn\n#Slot $slot: state "
. " $state\n");
return if (/^$prompt/);
@@ -202,9 +232,38 @@ sub ShowSlot {
return(0);
}
+# This routine parses "show switch"
+sub ShowSwitch {
+ print STDERR " In ShowSwitch: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+ next if(/^(\s*|\s*$cmd\s*)$/);
+
+ /^\s*$/i && next;
+ /^(primary|secondary) configuration:/i && next;
+ /^(boot |next reboot)/i && next;
+ /^(auto |qos mode|sys\S*:|temperature|time)/i && next;
+
+ /^power supply: (.*)/i &&
+ ProcessHistory("COMMENTS","keysort","C0","#$1") && next;
+ /^license/i && ProcessHistory("COMMENTS","keysort","D0","#Image: $_")
+ && next;
+ s/^software image (\S+):/Image: $1:/i &&
+ ProcessHistory("COMMENTS","keysort","D0","#$_") && next;
+ /^\S+ software version:/i &&
+ ProcessHistory("COMMENTS","keysort","D0","#Image: $_") && next;
+ /^(\S+ )?software/i && ProcessHistory("COMMENTS","keysort","D0","# $_");
+
+ }
+ return(0);
+}
+
# This routine processes a "write term"
sub WriteTerm {
print STDERR " In WriteTerm: $_" if ($debug);
+ my($comment) = 1; # strip extra comments, esp to preserve chassis type
while (<INPUT>) {
tr/\015//d;
@@ -213,52 +272,45 @@ sub WriteTerm {
# the pager can not be disabled per-session on the PIX
s/^<-+ More -+>\s*//;
+ s/^\s*$/#/;
+ # filter extra comments and lead comments in config so we can preserve
+ # the chassis type at the top of muched o/p before the processhistory
+ # key changes.
+ if (/^#\s*$/) {
+ if ($comment) {
+ next;
+ } else {
+ $comment++;
+ }
+ } else {
+ $comment = 0;
+ }
+
# Dog gone Cool matches to process the rest of the config
- /^(# \S+ Configuration) generated/i &&
- ProcessHistory("","","","$1\n") && next;
+ # some chassis report their chassis type in show diag...oh, but
+ # other noooo. grab it here, if available. so, nothing else
+ # can change the keysort key until this is grabbed. sigh.
+ /# (\S+) configuration generated/i &&
+ ProcessHistory("COMMENTS","keysort","A0","#Chassis type: $1\n") &&
+ ($comment = 0) && next;
+ /configuration generated/i && next;
+ /# system name/i && next;
+ /# software version/i && next;
+
+ if (/configure ssh2 key/) {
+ ProcessHistory("","","","# $_# <key removed>\n");
+ while (<INPUT>) {
+ if (/^(#|enable|conf|disable|unconf)/) {
+ last;
+ }
+ }
+ }
+
+ # filter out any RCS/CVS tags to avoid confusing local CVS storage
+ s/\$(Revision|Id):/ $1:/;
/^(config bgp (neighbor|peer-group) \S+ password encrypted)/i &&
ProcessHistory("","","","# $1 <removed>\n") &&
next;
-# /^( ip ospf authentication-key) / &&
-# ProcessHistory("","","","!$1 <removed>\n") && next;
-# /^( ip ospf message-digest-key \d+ md5) / &&
-# ProcessHistory("","","","!$1 <removed>\n") && next;
-# # sort route-maps
-# if (/^route-map (\S+)/) {
-# my($key) = $1;
-# my($routemap) = $_;
-# while (<INPUT>) {
-# 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+)/ &&
@@ -267,15 +319,15 @@ sub WriteTerm {
# we only prune lines of the form
# configure snmp add trapreceiver a.b.c.d <community>
- if (/^(configure snmp add trapreceiver )(\d+\.\d+\.\d+\.\d+) (community) \S+ (.*)/) {
+ if (/^(configure snmp add trapreceiver )(\d+\.\d+\.\d+\.\d+) (community) \S+/) {
if (defined($ENV{'NOCOMMSTR'})) {
- ProcessHistory("SNMPSVRHOST","ipsort","$2","# $1$2 $3 <removed> $4\n");
+ ProcessHistory("SNMPSVRHOST","ipsort","$2","# $1$2 $3 <removed> $'\n");
} else {
ProcessHistory("SNMPSVRHOST","ipsort","$2","$_\n");
}
next;
}
- if (/^(configure snmp add community (readonly|readwrite) \S+) (\S+)/) {
+ if (/^(configure snmp community (readonly|readwrite)) (\S+)/) {
if (defined($ENV{'NOCOMMSTR'})) {
ProcessHistory("SNMPSVRCOMM","keysort","$_","#$1 <removed>$'");
next;
@@ -306,6 +358,8 @@ sub DoNothing {print STDOUT;}
%commands=(
'show version' => "ShowVersion",
'show memory' => "ShowMemory",
+ 'show diagnostics' => "ShowDiag",
+ 'show switch' => "ShowSwitch",
'show slot' => "ShowSlot",
'show configuration' => "WriteTerm"
);
@@ -314,6 +368,8 @@ sub DoNothing {print STDOUT;}
@commands=(
"show version",
"show memory",
+ "show diagnostics",
+ "show switch",
"show slot",
"show configuration"
);
@@ -330,23 +386,26 @@ if ($file) {
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);
+ print STDERR "executing clogin -t $timeo -autoenable -c\"$cisco_cmds\" $host\n" if ($debug);
+ print STDOUT "executing clogin -t $timeo -autoenable -c\"$cisco_cmds\" $host\n" if ($log);
if (defined($ENV{NOPIPE})) {
- system "clogin -t $timeo -c \"$cisco_cmds\" $host </dev/null > $host.raw 2>&1" || die "clogin failed for $host: $!\n";
+ system "clogin -t $timeo -autoenable -c \"$cisco_cmds\" $host </dev/null > $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 </dev/null |") || die "clogin failed for $host: $!\n";
+ open(INPUT,"clogin -t $timeo -autoenable -c \"$cisco_cmds\" $host </dev/null |") || die "clogin failed for $host: $!\n";
}
}
ProcessHistory("","","","#RANCID-CONTENT-TYPE: extreme\n#\n");
-ProcessHistory("COMMENTS","keysort","B0","#\n"); # power supply info
-ProcessHistory("COMMENTS","keysort","C0","#\n"); # image name
-#ProcessHistory("COMMENTS","keysort","G0","#\n");
+ProcessHistory("COMMENTS","keysort","B0","#\n"); # chassis info
+ProcessHistory("COMMENTS","keysort","C0","#\n"); # power supply info
+ProcessHistory("COMMENTS","keysort","D0","#\n"); # image name
+ProcessHistory("COMMENTS","keysort","E0","#\n"); # h/w info
+ProcessHistory("COMMENTS","keysort","F0","#\n"); # slot info
+ProcessHistory("COMMENTS","keysort","X0","#\n");
TOP: while(<INPUT>) {
tr/\015//d;
- # note: this match sucks rocks, but the currently the extreme bits are
+ # note: this match sucks rocks, but 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) {
@@ -396,7 +455,9 @@ if (defined($ENV{NOPIPE})) {
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 ($debug) {
+ printf(STDERR "missed cmd(s): %s\n", join(',', keys(%commands)))
+ }
}
if (!$clean_run || !$found_end) {
print STDOUT "End of run not found\n";
diff --git a/configure b/configure
index ee2d373..80ad8fa 100755
--- a/configure
+++ b/configure
@@ -792,7 +792,7 @@ PACKAGE=rancid
# VERSION needs to be updated such that 'make dist' uses the correct
# filename for the directory name and tarball.
-VERSION=2.2b7
+VERSION=2.2b8
echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
echo "configure:799: checking whether to enable maintainer-specific portions of Makefiles" >&5
@@ -1420,7 +1420,7 @@ rd_cv_rd_bin_datas=$RD_BIN_DATAS
# RD_BIN_PROGS are bin/ .in's that need to be installed with execute perms.
RD_BIN_PROGS="cat5rancid control_rancid \
alogin arancid clogin create_cvs blogin brancid do-diffs elogin erancid \
-flogin francid jlogin jrancid par rancid-fe \
+flogin francid jlogin jrancid hlogin hrancid par rancid-fe \
rancid rename rrancid xrancid"
rd_cv_rd_bin_progs=$RD_BIN_PROGS
diff --git a/configure.in b/configure.in
index 5bba3f2..698d307 100644
--- a/configure.in
+++ b/configure.in
@@ -14,7 +14,7 @@ PACKAGE=rancid
# VERSION needs to be updated such that 'make dist' uses the correct
# filename for the directory name and tarball.
AC_SUBST(VERSION)
-VERSION=2.2b7
+VERSION=2.2b8
AM_MAINTAINER_MODE()
@@ -146,7 +146,7 @@ rd_cv_rd_bin_datas=$RD_BIN_DATAS
# RD_BIN_PROGS are bin/ .in's that need to be installed with execute perms.
RD_BIN_PROGS="cat5rancid control_rancid \
alogin arancid clogin create_cvs blogin brancid do-diffs elogin erancid \
-flogin francid jlogin jrancid par rancid-fe \
+flogin francid jlogin jrancid hlogin hrancid par rancid-fe \
rancid rename rrancid xrancid"
AC_SUBST(RD_BIN_PROGS)
rd_cv_rd_bin_progs=$RD_BIN_PROGS
diff --git a/man/create_cvs.1 b/man/create_cvs.1
index 353e92b..1e57459 100644
--- a/man/create_cvs.1
+++ b/man/create_cvs.1
@@ -45,7 +45,8 @@ The best method for adding groups is add the group name to
in
.BR env (5),
then run
-.B create_cvs.
+.B create_cvs. Do not create the directories manually, allow create_cvs
+to do it.
.\"
.SH SEE ALSO
.BR cvs (1),
diff --git a/man/env.5.in b/man/env.5.in
index f12acdc..854edbb 100644
--- a/man/env.5.in
+++ b/man/env.5.in
@@ -99,11 +99,26 @@ improvement in speed. By default, this is not set.
Specified as a number of hours, OLDTIME defines how many hours should pass
since a successful collection of a device's configuration and when
.IR control_rancid (1)
-should start complaining about failures.
+should start complaining about failures. The value should be greater than
+the number of hours between do-diffs cron runs.
.sp
Default: 4
.\"
.TP
+.B PAR_COUNT
+Defines the number of rancid processes that
+.IR par (1)
+will start simultaneously as
+.IR control_rancid (1)
+attempts to perform collections. Raising this value will decrease the amount
+of time necessary for a complete collection of a (or all) rancid groups at the
+of system load. The default is relatively cautious. If collections are not
+completing quickly enough for users, use trial and error of speed versus
+system load to find a suitable value.
+.sp
+Default: 5
+.\"
+.TP
.B PATH
Is a colon separate list of directory pathnames in the the file system
where rancid's
diff --git a/man/router.db.5 b/man/router.db.5
index 2139d99..8bc879e 100644
--- a/man/router.db.5
+++ b/man/router.db.5
@@ -70,6 +70,9 @@ A Extreme switch.
.B foundry
A Foundry router, switch, or router-switch.
.TP
+.B hp
+A HP switch such as the 2524 or 4108 procurve switches.
+.TP
.B juniper
A Juniper router.
.TP
diff --git a/util/lg/lg.cgi.in b/util/lg/lg.cgi.in
index 1e37b20..cf4caa8 100755
--- a/util/lg/lg.cgi.in
+++ b/util/lg/lg.cgi.in
@@ -363,7 +363,7 @@ if ($mfg =~ /juniper/) {
$results[0] = "$cmdDisp{$type} not implemented for junipers. sorry.\n";
&print_results;
}
- $cmd = $foundryCmd{$type};
+ $cmd = $juniperCmd{$type};
} elsif ($mfg =~ /foundry/) {
if(! defined($foundryCmd{$type})) {
$results[0] = "$cmdDisp{$type} not implemented for foundrys. sorry.\n";