summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTar Committer <tar@ocjtech.us>2001-08-03 03:13:25 +0000
committerTar Committer <tar@ocjtech.us>2001-08-03 03:13:25 +0000
commitaf496d2efa0969f29a22a4236c620f513eb90287 (patch)
treef3bc37d0d677b7ae1b58ae643fa25a91b80655aa
parent0e84b727786a16ade28bb081742e5c39c33ed7fa (diff)
downloadrancid-af496d2efa0969f29a22a4236c620f513eb90287.tar.gz
rancid-af496d2efa0969f29a22a4236c620f513eb90287.tar.xz
rancid-af496d2efa0969f29a22a4236c620f513eb90287.zip
Imported from rancid-2.2b5.tar.gz.rancid-2.2b5
-rw-r--r--CHANGES62
-rw-r--r--COPYING18
-rw-r--r--FAQ103
-rw-r--r--Makefile.am5
-rw-r--r--Makefile.in9
-rw-r--r--README36
-rw-r--r--Todo24
-rw-r--r--bin/Makefile.in13
-rwxr-xr-xbin/alogin.in57
-rwxr-xr-xbin/arancid.in15
-rwxr-xr-xbin/cat5rancid.in4
-rwxr-xr-xbin/clogin.in146
-rwxr-xr-xbin/control_rancid.in48
-rwxr-xr-xbin/create_cvs.in2
-rwxr-xr-xbin/do-diffs.in25
-rwxr-xr-xbin/elogin.in24
-rw-r--r--bin/env.in11
-rwxr-xr-xbin/erancid.in4
-rwxr-xr-xbin/flogin.in35
-rwxr-xr-xbin/francid.in2
-rwxr-xr-xbin/jlogin.in64
-rwxr-xr-xbin/jrancid.in17
-rwxr-xr-xbin/par.in2
-rwxr-xr-xbin/rancid-fe.in4
-rwxr-xr-xbin/rancid.in50
-rwxr-xr-xbin/rrancid.in2
-rwxr-xr-xbin/xrancid.in407
-rwxr-xr-xconfigure164
-rw-r--r--configure.in18
-rw-r--r--man/Makefile.am2
-rw-r--r--man/Makefile.in3
-rw-r--r--man/clogin.116
-rw-r--r--man/lg.conf.5.in18
-rw-r--r--man/rancid.13
-rw-r--r--man/rancid_intro.18
-rw-r--r--man/router.db.55
-rw-r--r--man/xrancid.11
-rw-r--r--util/Makefile.in4
-rw-r--r--util/cisco-load.exp331
-rw-r--r--util/cisco-reload.exp141
-rwxr-xr-xutil/downreport.in9
-rw-r--r--util/lg/README8
-rwxr-xr-xutil/lg/lg.cgi.in248
-rw-r--r--util/lg/lg.conf.in75
-rwxr-xr-xutil/lg/lgform.cgi.in29
-rw-r--r--util/lg/lgnotes.html15
-rw-r--r--util/rtrfilter.README2
-rwxr-xr-xutil/rtrfilter.in15
48 files changed, 1860 insertions, 444 deletions
diff --git a/CHANGES b/CHANGES
index 6711320..0c577ae 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,59 @@
-2.2b
- bin/alogin and changes of beta quality for Alteon WebOS switch
+2.2b5
+ fix regex error in clogin affecting catalysts
+
+ clogin attempts to grope entire prompt after login
+
+ *login need to catch{} -x cmd file open so expect doesnt puke if
+ there is an error opening the file
+
+2.2b4
+ add extreme switch bits
+
+ cisco changed the o/p fmt of h/w info on the 65xx in 12.1.8e
+
+ PIX520 supplies different more(1) prompt than others. from William R
+ Thomas.
+
+ fix typo in jlogin. from richard doty.
+
+ add 2 example expect script for clogin -s
+
+ handle foundrys and more juniper bits in the lookingglass
+
+ add LG_STRIP knob to strip login o/p in the lookingglass
+
+ add LG_BGP_RT knob to {dis}allow heavy o/p sh ip bgp neighbor LG cmds
+
+ bin/clogin shouldnt insist upon an enable password with -noenable option
+
+2.2b3
+ bin/rancid changes for cisco 124xx
+
+ some serial controllers (PAs) have predefined cable-type in show
+ controllers. M8T-V.35 was being missed.
+
+ modify jlogin to grope the full prompt after login such that -x
+ can be used within configuration mode. note: this turns $prompt into
+ a regexp, WRT -s scripts and -re option for expect's.
+
+ add -Evar=x option to pass variables to scripts. eg:
+ clogin -Evariable=something router...
+ clogin -Evariable=a,b,c [ie: an array/list which user splits]
+
+2.2b2
+ fix jlogin's password/userpassword functionality which broke when
+ cmd-line options were made consistent.
+
+ add check for config/* files missing from the cvs repository.
+
+ add 2 juniper config checks to avoid truncation. 1) config should
+ have at least 1 "section" amounting to at least 3 lines and 2) if
+ a mgd version mismatch exists, there may be inaccuracies.
+
+ convert usage of Mail to sendmail for portability. local .mailrc
+ aliases can no longer be used.
+
+ bin/alogin and changes (of beta quality) for Alteon WebOS switch
from andrew fort.
Check for more types of cisco 12000s. Also check for 2600s.
@@ -12,6 +66,8 @@
make *login automatically add host keys with openssh's prompting
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.
2.1
Change default umask to 027 (it was 007) mainly as an
@@ -202,7 +258,7 @@
- adds a "-x" switch that takes lines from a file and does the same
thing as if you'd specified ;-separated commands with -c (newline
- separates commands)
+ separates commands). thanks to stephen stuart.
- does a subst on commands in run_commands so that expansion of
escapes is performed; e.g. you can say "copy rcp://blah slot0:\r" to
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..639e792
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,18 @@
+##
+## 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.
+##
+
+# bin/rename - is from CPAN by lwall.
+# util/lg - the original looking glass is by Ed Kern, provided by
+# permission and modified beyond recognition of the original
diff --git a/FAQ b/FAQ
new file mode 100644
index 0000000..ed0178a
--- /dev/null
+++ b/FAQ
@@ -0,0 +1,103 @@
+Frequently Asked Questions about rancid - last updated 20010730
+
+1) Platform specific
+
+Q. I have a Cisco Catalyst 6500 series switch running the IOS (NOT catOS)
+ software, is the router.db device type cisco or cat5?
+A. A catalyst running IOS is type "cisco". see the router.db(5) manual page.
+
+Q. I have a Cisco ??? on which collection stopped working, but clogin works
+ as expected.
+A. Check if 'write term' produces output. Some IOS combinated with large
+ configs and low free memory produce zero 'write term' output. The device
+ will have to be rebooted.
+
+
+2) CVS and filesystem permissions
+
+Q. I am new to cvs, where can i find additional information?
+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. 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
+ the log file from the last run for that group first; it may provide the
+ exact cause.
+
+ note: it is very important the following be done as the user who normally
+ runs the rancid collection from cron.
+
+ Check the cvs status of the device's file. eg:
+ guelah [2704] cvs status rtr.shrubbery.net
+ ===================================================================
+ File: yogi.shrubbery.net Status: Up-to-date
+
+ Working revision: 1.197 Tue Jul 10 15:41:16 2001
+ Repository revision: 1.197 /user/local/rancid/CVS/shrubbery/configs/rtr.shrubbery.net,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+ The Status: should be Up-to-date. If the status is "Unknown", then somehow
+ the file has been created without being cvs add'ed. This should be
+ corrected by removing that device's entry from the group's router.db file,
+ run do-diffs, replace the entry in router.db, and run do-diffs again.
+
+ If the Status is anything else, someone has most likely been touching the
+ files manually. Sane state can be achieved by removing the file and running
+ cvs update <file> to get a fresh copy from the repository.
+
+ Check the ownership and permissions of the file and directory and the
+ directory and file in the cvs repository (/usr/local/rancid/CVS/). They
+ should be owned by the user who runs do-diffs from cron. At the very least,
+ the directory and files should be writable by the rancid user. Group and
+ world permissions will determined by the umask (default 027), which is set
+ in /usr/local/rancid/bin/env. Likely the easiest way to fix the ownership
+ on the cvs repository is chmod -R <rancid user> /usr/local/rancid/CVS
+
+
+3) General
+
+Q. I have a (set of) device(s) on which collection fails. How can i debug
+ this?
+A. Our usual diagnostic procedure for this is:
+ - Make sure that the appropriate *login (eg: clogin for cisco) works.
+ This tests to make sure you don't have routing or firewall issues, DNS
+ or hostname errors, that your .cloginrc is correct, and that the *login
+ script doesnt have a bug of some sort. For example:
+
+ clogin cisco_router
+
+ Should login to cisco_router and produce a router prompt that you can
+ use normally, as if clogin were not used (ie: telnet cisco_router).
+
+ - See if commands can be executed on the router via clogin. This will
+ exercise the *login functionality needed for rancid. For example:
+
+ clogin -c 'show version; show diag' cisco_router
+
+ Should login to cisco_router, run show version and show diag, then
+ disconnect and exit. The output will be displayed on your terminal.
+
+ - The see if the correct rancid commands work against the router. For
+ example:
+
+ rancid cisco_router
+
+ Should produce a cisco_router.new file (cooked to a golden rancid-style
+ colour) in the current directory. If it does not, try again with the
+ -d option, so that the cisco_router.new file will not be removed if
+ an error is detected. Note: if you have NOPIPE set in your environment,
+ a cisco_router.raw file will be produced that is the raw output of the
+ dialogue with the device.
+
+ If all of these work, make sure that the device's entry in the group's
+ router.db file is correct and check the group's last log file for errors.
+
+Q. I'm still stuck on this problem. Where can i get more help?
+A. A discussion list is available, rancid-discuss@shrubbery.net. You must
+ be a subscriber to post. subscribe like this:
+
+ shell% echo "subscribe" | mail rancid-discuss-request@shrubbery.net
+
diff --git a/Makefile.am b/Makefile.am
index 4fa1628..ed81cf3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,12 +4,13 @@ AUTOMAKE_OPTIONS=foreign no-dependencies
@SET_MAKE@
-EXTRA_DIST = CHANGES README Todo cloginrc.sample configure install-sh \
+EXTRA_DIST = CHANGES COPYING FAQ README Todo cloginrc.sample configure \
+ install-sh \
mkinstalldirs Makefile.in Todo
#DIST_COMMON =
# '.' is here (and at the beginnging of the macro) so that distclean-recursive
-# will run make distclean in . after the other dirs (preserving Makefile.inc)
+# will run make distclean in . after the other dirs (preserving Makefile)
SUBDIRS = . bin man util
all:
diff --git a/Makefile.in b/Makefile.in
index 0030e35..33e8807 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -90,23 +90,22 @@ SSH = @SSH@
TAR = @TAR@
TELNET = @TELNET@
TOUCH = @TOUCH@
-UCBMAIL = @UCBMAIL@
VERSION = @VERSION@
AUTOMAKE_OPTIONS = foreign no-dependencies
-EXTRA_DIST = CHANGES README Todo cloginrc.sample configure install-sh mkinstalldirs Makefile.in Todo
+EXTRA_DIST = CHANGES COPYING FAQ README Todo cloginrc.sample configure install-sh mkinstalldirs Makefile.in Todo
#DIST_COMMON =
# '.' is here (and at the beginnging of the macro) so that distclean-recursive
-# will run make distclean in . after the other dirs (preserving Makefile.inc)
+# will run make distclean in . after the other dirs (preserving Makefile)
SUBDIRS = . bin man util
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_CLEAN_FILES =
-DIST_COMMON = README Makefile.am Makefile.in acinclude.m4 aclocal.m4 \
-configure configure.in install-sh missing mkinstalldirs
+DIST_COMMON = README COPYING Makefile.am Makefile.in acinclude.m4 \
+aclocal.m4 configure configure.in install-sh missing mkinstalldirs
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
diff --git a/README b/README
index 5d29c9a..e95d60a 100644
--- a/README
+++ b/README
@@ -93,6 +93,10 @@ Quick Installation Guide (an example):
Note: the juniper user you use *must* log into a cli shell (which
is the default on a juniper).
+ See the file cloginrc.sample, located in <basedir>, for examples and
+ good starting point. Also take a look at the cloginrc manual page,
+ 'man -M <basedir>/man cloginrc'.
+
6) Modify /etc/aliases
Rancid sends the diffs and other administrative emails to rancid-<GROUP>
and problems to rancid-admin-<GROUP>, where <GROUP> is the "GROUP" of
@@ -100,12 +104,8 @@ Quick Installation Guide (an example):
access routers or separate based upon network etc... Different router
uses forced different people being interested in router "groups" -
thus this setup. Make sure email to rancid-<GROUP> works. /etc/aliases
- can be maintainable by Majordomo stuff.
- - OR -
- Modify your home directory's .mailrc. Control_rancid uses sendmail
- to send diffs. To use a private .mailrc, control_rancid will have to
- be modified to use ucbmail or, better yet, something else which allow
- the Precedence header to be set. Pick your poison.
+ can be maintainable by Majordomo stuff, but make sure the user that
+ runs rancid can post to the list.
The Precedence header set to bulk or junk *hopefully* avoids replies from
auto-responders and vacation type mail filters.
@@ -116,7 +116,9 @@ 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.
+ 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
+ 'man -M <basedir>/man create_cvs'.
8) For each "group", modify the router.db file in the group directory.
The file is of the form "router:mfg:state" where "router" is
@@ -164,4 +166,24 @@ Quick Installation Guide (an example):
rancid-<announce or discuss>" to majordomo@shrubbery.net.
+Problem with clogin/telnet hanging within rancid or scripts?
+
+If you have experienced rancid (or more precisely, telnet) hanging on a
+solaris 2.6 box; check to be sure you have the following two patches
+installed (see showrev -p). There may be more recent versions of these
+patches and they are likely included with 2.7 and 2.8:
+
+Patch-ID# 105529-08
+Keywords: security tcp rlogin TCP ACK FIN packet listen
+Synopsis: SunOS 5.6: /kernel/drv/tcp patch
+
+Patch-ID# 105786-11
+Keywords: security ip tcp_priv_stream routing ip_enable_group_ifs ndd
+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.
+
-Hank
diff --git a/Todo b/Todo
index c608d37..0e09c91 100644
--- a/Todo
+++ b/Todo
@@ -1,16 +1,22 @@
+- rancid should filter pap pwds, as in:
+ ppp pap sent-username AS3727 password 7 10581C17581043
+- 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
-- better error loggin in the looking glass
-- handle foundry and reback in the looking glass
+- handle reback 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
-- merge clogin and jlogin into one. possible?
-- rancid needs to treat the 3600s like the 7Ks and 12Ks...
- Also, need to allow 12012s, and force 700s to not be treated like 7Ks.
+- merge clogin and jlogin (or *login !!) into one. possible?
- flogin (for foundry) needs more testing and should be integrated with
clogin when foundry fixes their UI.
-- include a few -s and -x type example *login scripts.
-- add -E to *login to pass through variables to scripts
- clogin -Evariable=something router...
- clogin -Evariable=a,b,c [ie: an array/list which user splits]
+- flogin needs to be fixed for the userpasswd bug seen in jlogin 1.17, but
+ this is clouded by the UI mess.
+- rancid needs to treat the 3600s like the 7Ks and 12Ks...
+ Also, need to allow 12012s, and force 700s to not be treated like 7Ks.
+- clogin/jlogin rsh is munged
+- LG additions
+ - show controllers T3 (data)
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\"<removed>\"\n") && next;
- #if (/^\s*snmp/ && defined($ENV{'NOCOMMSTR'})) {
- # /snmp (getcomm|setcomm|trapcomm)(\s+)(\S*)/ &&
- # ProcessHistory("","","","- snmp $1$2\"<removed>\"\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(<INPUT>) {
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 <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
+ # 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 <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 {
- "\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 <<END
-The following routers have not been successfully contacted for more
-than $OLDTIME hours.
+ echo "To: @MAILPLUS@admin-$GROUP"
+ echo "Subject: config fetcher problems - $GROUP"
+ echo "Precedence: bulk"
+ echo ""
+ echo "The following routers have not been successfully contacted for"
+ echo "more than $OLDTIME hours."
-END
- cat $DIR/routers.failed
- ) | Mail -s "config fetcher problems - $GROUP" @MAILPLUS@admin-$GROUP
+ cat $DIR/routers.failed
+ ) | sendmail -t
fi
# Cleanup
diff --git a/bin/create_cvs.in b/bin/create_cvs.in
index df7e56e..06d414b 100755
--- a/bin/create_cvs.in
+++ b/bin/create_cvs.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
diff --git a/bin/do-diffs.in b/bin/do-diffs.in
index 1304a7e..e5d1f62 100755
--- a/bin/do-diffs.in
+++ b/bin/do-diffs.in
@@ -1,4 +1,16 @@
#!/bin/sh
+## 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.
##
# do diffs for each of the diff groups ($LIST_OF_GROUPS) from <BASEDIR>/bin/env
##
@@ -43,22 +55,27 @@ do
if [ -s $TMPDIR/.$GROUP.old ]
then
(
- cat <<END
+ echo "To: @MAILPLUS@admin-$GROUP"
+ echo "Subject: rancid hung - $GROUP"
+ echo "Precedence: bulk"
+ echo ""
+
+ cat <<END
rancid $GROUP hung on `hostname`? Old lockfile still exists:
`ls -l $LOCKFILE`
END
- ) | Mail -s "rancid hung - $GROUP" @MAILPLUS@admin-$GROUP
+ ) | sendmail -t
fi
rm -f $TMPDIR/.$GROUP.old
else
- trap 'rm -fr $LOCKFILE;' 1 2 15
+ trap 'rm -fr $LOCKFILE;exit 1' 1 2 3 6 10 11 15
touch $LOCKFILE
if [ $? -eq 0 ] ; then
control_rancid $GROUP
rm -f $LOCKFILE
fi
- trap '' 1 2 15
+ trap '' 1 2 3 6 10 11 15
fi
echo
diff --git a/bin/elogin.in b/bin/elogin.in
index 46f459d..1affce7 100755
--- a/bin/elogin.in
+++ b/bin/elogin.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 \[-noenable\] \[-c command\] \
-\[-f cloginrc-file\] \[-p user-password\] \
+\[-Evar=x\] \[-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"
@@ -95,9 +95,18 @@ 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]} {
+ 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* -
@@ -147,7 +156,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] \;]
@@ -398,7 +410,7 @@ foreach router [lrange $argv $i end] {
if { $do_passwd } {
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
}
set passwd [lindex $pswd 0]
diff --git a/bin/env.in b/bin/env.in
index 08c2213..ccfa9be 100644
--- a/bin/env.in
+++ b/bin/env.in
@@ -1,5 +1,5 @@
#
-# This file setups up the environment used for rancid
+# This file setups up the environment used for rancid. see env(5)
#
# This will be site specific
#
@@ -7,8 +7,8 @@ TERM=network;export TERM
#
# Under $BASEDIR, there will be a bin directory for the rancid programs,
# a log directory for the logs from rancid and a directory for each group
-# of routers. In addition to these directories, there will be the CVS
-# repositories as well.
+# of routers (LIST_OF_GROUPS). In addition to these directories, there
+# will be the CVS repositories as well.
# use a full path (no sym-links) for BASEDIR. some versions of CVS seemingly
# don't take kindly to sym-links.
#
@@ -28,12 +28,11 @@ CVSROOT=$BASEDIR/CVS; export CVSROOT
# can not be reached.
OLDTIME=4; export OLDTIME
#
+# list of rancid groups
LIST_OF_GROUPS="sl joebobisp"
#
# For each group, define a list of people to receive the diffs.
-# in a .mailrc file in the following format:
-# alias rancid-$GROUP hank@rem.com pwhiting@sprint.net
-# or sendmail's /etc/aliases.
+# in sendmail's /etc/aliases.
# rancid-group: joe,moe@foo
# rancid-group-admin: hostmaster
# be sure to read ../README regarding aliases.
diff --git a/bin/erancid.in b/bin/erancid.in
index 0377612..aac7ea0 100755
--- a/bin/erancid.in
+++ b/bin/erancid.in
@@ -4,7 +4,7 @@
## with switch software 1.50 so far - terry@tmk.com
##
##
-## 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
@@ -138,7 +138,7 @@ sub ShowVersion {
print STDERR " In ShowVersion: $_" if ($debug);
ProcessHistory("COMMENTS","keysort","A1",
- "- Chassis type:EZT3 - an ADC EZT3 M13 multiplexor\n");
+ "- Chassis type: EZT3 - an ADC EZT3 M13 multiplexor\n");
while (<INPUT>) {
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(<INPUT>) {
$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 (<INPUT>) {
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;
$_ = <INPUT>; 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 (<INPUT>) {
+ 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 <FF>
+#SLOT 2 : 702005-06 0021S-00131 CPLD Rev 02
+#SLOT 3 : 702009-06 0024S-00170 CPLD Rev <FF>
+#SLOT 4 : 702009-06 0024S-00319 CPLD Rev <FF>
+ }
+ return(0);
+}
+
+# This routine parses "show memory"
+sub ShowMemory {
+ print STDERR " In ShowMemory: $_" if ($debug);
+
+ while (<INPUT>) {
+ 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 (<INPUT>) {
+ 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 (<INPUT>) {
+ 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 (<INPUT>) {
+ 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 <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+)/ &&
+ 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 <community>
+ 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");
+ } else {
+ ProcessHistory("SNMPSVRHOST","ipsort","$2","$_\n");
+ }
+ next;
+ }
+ if (/^(configure snmp add community (readonly|readwrite) \S+) (\S+)/) {
+ if (defined($ENV{'NOCOMMSTR'})) {
+ ProcessHistory("SNMPSVRCOMM","keysort","$_","#$1 <removed>$'");
+ 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 <removed>\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 </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";
+ }
+}
+
+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");
+TOP: while(<INPUT>) {
+ 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);
+}
diff --git a/configure b/configure
index 789b238..90666b9 100755
--- a/configure
+++ b/configure
@@ -17,8 +17,6 @@ ac_help="$ac_help
(and sometimes confusing) to the casual installer"
ac_help="$ac_help
--enable-mail-plus enable mail to rancid+ addresses, instead of rancid-"
-ac_help="$ac_help
- --with-ucbmail=[FQPN] path to UCB mail"
# Initialize some variables set by options.
# The variables have the same names as the options, with
@@ -561,7 +559,7 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:565: checking for a BSD compatible install" >&5
+echo "configure:563: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -614,7 +612,7 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
-echo "configure:618: checking whether build environment is sane" >&5
+echo "configure:616: checking whether build environment is sane" >&5
# Just in case
sleep 1
echo timestamp > conftestfile
@@ -671,7 +669,7 @@ test "$program_suffix" != NONE &&
test "$program_transform_name" = "" && program_transform_name="s,x,x,"
echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:675: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:673: checking whether ${MAKE-make} sets \${MAKE}" >&5
set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -717,7 +715,7 @@ EOF
missing_dir=`cd $ac_aux_dir && pwd`
echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
-echo "configure:721: checking for working aclocal" >&5
+echo "configure:719: checking for working aclocal" >&5
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
@@ -730,7 +728,7 @@ else
fi
echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
-echo "configure:734: checking for working autoconf" >&5
+echo "configure:732: checking for working autoconf" >&5
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
@@ -743,7 +741,7 @@ else
fi
echo $ac_n "checking for working automake""... $ac_c" 1>&6
-echo "configure:747: checking for working automake" >&5
+echo "configure:745: checking for working automake" >&5
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
@@ -756,7 +754,7 @@ else
fi
echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
-echo "configure:760: checking for working autoheader" >&5
+echo "configure:758: checking for working autoheader" >&5
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
@@ -769,7 +767,7 @@ else
fi
echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
-echo "configure:773: checking for working makeinfo" >&5
+echo "configure:771: checking for working makeinfo" >&5
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
@@ -794,10 +792,10 @@ PACKAGE=rancid
# VERSION needs to be updated such that 'make dist' uses the correct
# filename for the directory name and tarball.
-VERSION=2.2b
+VERSION=2.2b5
echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
-echo "configure:801: checking whether to enable maintainer-specific portions of Makefiles" >&5
+echo "configure:799: checking whether to enable maintainer-specific portions of Makefiles" >&5
# Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
if test "${enable_maintainer_mode+set}" = set; then
enableval="$enable_maintainer_mode"
@@ -823,7 +821,7 @@ fi
# Check for a preference for using mail addresses like rancid+admin-group
# instead of the standard rancid-admin-group
echo $ac_n "checking whether mail addresses should be in the rancid+ form""... $ac_c" 1>&6
-echo "configure:827: checking whether mail addresses should be in the rancid+ form" >&5
+echo "configure:825: checking whether mail addresses should be in the rancid+ form" >&5
# Check whether --enable-mail-plus or --disable-mail-plus was given.
if test "${enable_mail_plus+set}" = set; then
enableval="$enable_mail_plus"
@@ -848,7 +846,7 @@ rd_cv_MAILPLUS=$MAILPLUS
# Extract the first word of "dirname", so it can be a program name with args.
set dummy dirname; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:852: checking for $ac_word" >&5
+echo "configure:850: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_DIRNAME'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -885,7 +883,7 @@ fi
# Extract the first word of "diff", so it can be a program name with args.
set dummy diff; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:889: checking for $ac_word" >&5
+echo "configure:887: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_DIFF'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -946,7 +944,7 @@ rd_cv_DIFF_CMD=$DIFF_CMD
# Extract the first word of "sendmail", so it can be a program name with args.
set dummy sendmail; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:950: checking for $ac_word" >&5
+echo "configure:948: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_SENDMAIL'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -979,98 +977,11 @@ else
echo "$ac_t""no" 1>&6
fi
-# find UCB mail.
-# Check whether --with-ucbmail or --without-ucbmail was given.
-if test "${with_ucbmail+set}" = set; then
- withval="$with_ucbmail"
- UCBMAIL=$withval; unset ac_cv_path_UCBMAIL
-fi
-
-# Extract the first word of "Mail", so it can be a program name with args.
-set dummy Mail; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:993: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_path_UCBMAIL'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- case "$UCBMAIL" in
- /*)
- ac_cv_path_UCBMAIL="$UCBMAIL" # Let the user override the test with a path.
- ;;
- ?:/*)
- ac_cv_path_UCBMAIL="$UCBMAIL" # Let the user override the test with a dos path.
- ;;
- *)
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_path_UCBMAIL="$ac_dir/$ac_word"
- break
- fi
- done
- IFS="$ac_save_ifs"
- test -z "$ac_cv_path_UCBMAIL" && ac_cv_path_UCBMAIL="no"
- ;;
-esac
-fi
-UCBMAIL="$ac_cv_path_UCBMAIL"
-if test -n "$UCBMAIL"; then
- echo "$ac_t""$UCBMAIL" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-if test $UCBMAIL = no; then
- unset ac_cv_path_UCBMAIL
- # Extract the first word of "mailx", so it can be a program name with args.
-set dummy mailx; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1031: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_path_UCBMAIL'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- case "$UCBMAIL" in
- /*)
- ac_cv_path_UCBMAIL="$UCBMAIL" # Let the user override the test with a path.
- ;;
- ?:/*)
- ac_cv_path_UCBMAIL="$UCBMAIL" # Let the user override the test with a dos path.
- ;;
- *)
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_path_UCBMAIL="$ac_dir/$ac_word"
- break
- fi
- done
- IFS="$ac_save_ifs"
- test -z "$ac_cv_path_UCBMAIL" && ac_cv_path_UCBMAIL="no"
- ;;
-esac
-fi
-UCBMAIL="$ac_cv_path_UCBMAIL"
-if test -n "$UCBMAIL"; then
- echo "$ac_t""$UCBMAIL" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
- if test $UCBMAIL = no; then
- { echo "configure: error: can't locate a UCB Mail (one which accepts the -s option for subject)." 1>&2; exit 1; }
- { echo "configure: error: UCB mail is normally Mail or mailx. use --with-ucbmail to specify the path." 1>&2; exit 1; }
- exit 1
- fi
-fi
# Extract the first word of "gmake", so it can be a program name with args.
set dummy gmake; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1074: checking for $ac_word" >&5
+echo "configure:985: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_MAKE'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1108,7 +1019,7 @@ if test $MAKE = no; then
# Extract the first word of "make", so it can be a program name with args.
set dummy make; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1112: checking for $ac_word" >&5
+echo "configure:1023: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_MAKE'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1147,7 +1058,7 @@ fi
fi
fi
echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:1151: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:1062: checking whether ${MAKE-make} sets \${MAKE}" >&5
set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -1181,7 +1092,7 @@ do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1185: checking for $ac_word" >&5
+echo "configure:1096: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_TAR'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1216,7 +1127,7 @@ do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1220: checking for $ac_word" >&5
+echo "configure:1131: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AUTOMAKE'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1258,7 +1169,7 @@ done
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:1262: checking for a BSD compatible install" >&5
+echo "configure:1173: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -1313,7 +1224,7 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
# Extract the first word of "perl5", so it can be a program name with args.
set dummy perl5; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1317: checking for $ac_word" >&5
+echo "configure:1228: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_PERLV_PATH'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1351,7 +1262,7 @@ if test $PERLV_PATH = no; then
# Extract the first word of "perl", so it can be a program name with args.
set dummy perl; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1355: checking for $ac_word" >&5
+echo "configure:1266: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_PERLV_PATH'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1402,7 +1313,7 @@ ac_cv_PERLV=`basename $PERLV_PATH`
# Extract the first word of "expect", so it can be a program name with args.
set dummy expect; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1406: checking for $ac_word" >&5
+echo "configure:1317: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_EXPECT_PATH'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1444,7 +1355,7 @@ fi
# Extract the first word of "ping", so it can be a program name with args.
set dummy ping; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1448: checking for $ac_word" >&5
+echo "configure:1359: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_PING_PATH'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1510,7 +1421,7 @@ rd_cv_rd_bin_datas=$RD_BIN_DATAS
RD_BIN_PROGS="cat5rancid control_rancid \
alogin arancid clogin create_cvs do-diffs elogin erancid \
flogin francid jlogin jrancid par rancid-fe \
-rancid rename rrancid"
+rancid rename rrancid xrancid"
rd_cv_rd_bin_progs=$RD_BIN_PROGS
@@ -1531,12 +1442,12 @@ INST_PROGS=$progs
# locate tools to build $PATH for env. order is significant. want to be
# sure that we pick up the the proper diff and ucbmail in bin/env.
ENV_PATH="`dirname $PERLV_PATH`:`dirname $EXPECT_PATH`:`dirname $SENDMAIL`"
-ENV_PATH="$ENV_PATH:`dirname $DIRNAME`:`dirname $DIFF`:`dirname $UCBMAIL`"
+ENV_PATH="$ENV_PATH:`dirname $DIRNAME`:`dirname $DIFF`"
# Extract the first word of "cvs", so it can be a program name with args.
set dummy cvs; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1540: checking for $ac_word" >&5
+echo "configure:1451: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_CVS'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1573,7 +1484,7 @@ ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_CVS`"
# Extract the first word of "comm", so it can be a program name with args.
set dummy comm; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1577: checking for $ac_word" >&5
+echo "configure:1488: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_COMM'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1610,7 +1521,7 @@ ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_COMM`"
# Extract the first word of "find", so it can be a program name with args.
set dummy find; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1614: checking for $ac_word" >&5
+echo "configure:1525: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_FIND'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1647,7 +1558,7 @@ ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_FIND`"
# Extract the first word of "grep", so it can be a program name with args.
set dummy grep; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1651: checking for $ac_word" >&5
+echo "configure:1562: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_GREP'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1684,7 +1595,7 @@ ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_GREP`"
# Extract the first word of "id", so it can be a program name with args.
set dummy id; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1688: checking for $ac_word" >&5
+echo "configure:1599: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_ID'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1721,7 +1632,7 @@ ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_ID`"
# Extract the first word of "mkdir", so it can be a program name with args.
set dummy mkdir; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1725: checking for $ac_word" >&5
+echo "configure:1636: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_MKDIR'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1758,7 +1669,7 @@ ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_MKDIR`"
# Extract the first word of "rsh", so it can be a program name with args.
set dummy rsh; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1762: checking for $ac_word" >&5
+echo "configure:1673: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_RSH'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1795,7 +1706,7 @@ ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_RSH`"
# Extract the first word of "sort", so it can be a program name with args.
set dummy sort; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1799: checking for $ac_word" >&5
+echo "configure:1710: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_SORT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1832,7 +1743,7 @@ ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_SORT`"
# Extract the first word of "ssh", so it can be a program name with args.
set dummy ssh; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1836: checking for $ac_word" >&5
+echo "configure:1747: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_SSH'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1872,7 +1783,7 @@ unset ac_cv_path_SSH
# Extract the first word of "telnet", so it can be a program name with args.
set dummy telnet; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1876: checking for $ac_word" >&5
+echo "configure:1787: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_TELNET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1909,7 +1820,7 @@ ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_TELNET`"
# Extract the first word of "touch", so it can be a program name with args.
set dummy touch; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1913: checking for $ac_word" >&5
+echo "configure:1824: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_TOUCH'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2116,7 +2027,6 @@ s%@DIRNAME@%$DIRNAME%g
s%@DIFF@%$DIFF%g
s%@DIFF_CMD@%$DIFF_CMD%g
s%@SENDMAIL@%$SENDMAIL%g
-s%@UCBMAIL@%$UCBMAIL%g
s%@MAKE@%$MAKE%g
s%@TAR@%$TAR%g
s%@PERLV_PATH@%$PERLV_PATH%g
diff --git a/configure.in b/configure.in
index cf3bd4f..c15d907 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.2b
+VERSION=2.2b5
AM_MAINTAINER_MODE()
@@ -67,18 +67,6 @@ rd_cv_DIFF_CMD=$DIFF_CMD
AC_SUBST(DIFF_CMD)
AC_PATH_PROG(SENDMAIL,sendmail,no, /usr/sbin:/usr/bin:/usr/lib)
-# find UCB mail.
-AC_ARG_WITH(ucbmail, [ --with-ucbmail=[FQPN] path to UCB mail], UCBMAIL=$withval; unset ac_cv_path_UCBMAIL)
-AC_PATH_PROG(UCBMAIL,Mail,no)
-if test $UCBMAIL = no; then
- unset ac_cv_path_UCBMAIL
- AC_PATH_PROG(UCBMAIL,mailx,no)
- if test $UCBMAIL = no; then
- AC_MSG_ERROR([can't locate a UCB Mail (one which accepts the -s option for subject).])
- AC_MSG_ERROR([UCB mail is normally Mail or mailx. use --with-ucbmail to specify the path.])
- exit 1
- fi
-fi
AC_PATH_PROG(MAKE,gmake,no)
if test $MAKE = no; then
@@ -159,7 +147,7 @@ rd_cv_rd_bin_datas=$RD_BIN_DATAS
RD_BIN_PROGS="cat5rancid control_rancid \
alogin arancid clogin create_cvs do-diffs elogin erancid \
flogin francid jlogin jrancid par rancid-fe \
-rancid rename rrancid"
+rancid rename rrancid xrancid"
AC_SUBST(RD_BIN_PROGS)
rd_cv_rd_bin_progs=$RD_BIN_PROGS
@@ -180,7 +168,7 @@ INST_PROGS=$progs
# locate tools to build $PATH for env. order is significant. want to be
# sure that we pick up the the proper diff and ucbmail in bin/env.
ENV_PATH="`dirname $PERLV_PATH`:`dirname $EXPECT_PATH`:`dirname $SENDMAIL`"
-ENV_PATH="$ENV_PATH:`dirname $DIRNAME`:`dirname $DIFF`:`dirname $UCBMAIL`"
+ENV_PATH="$ENV_PATH:`dirname $DIRNAME`:`dirname $DIFF`"
AC_PATH_PROG(CVS,cvs,no)
ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_CVS`"
diff --git a/man/Makefile.am b/man/Makefile.am
index c0af44c..354b290 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -10,7 +10,7 @@ man_nogen_MANS = do-diffs.1 alogin.1 clogin.1 control_rancid.1 create_cvs.1 \
rancid.1 \
rancid_intro.1 cloginrc.5 router.db.5 \
elogin.1 flogin.1 jlogin.1 \
- jrancid.1 francid.1 cat5rancid.1 erancid.1
+ jrancid.1 francid.1 cat5rancid.1 erancid.1 xrancid.1
man_MANS = $(man_gen_MANS) $(man_nogen_MANS)
diff --git a/man/Makefile.in b/man/Makefile.in
index c74034e..a18c361 100644
--- a/man/Makefile.in
+++ b/man/Makefile.in
@@ -90,13 +90,12 @@ SSH = @SSH@
TAR = @TAR@
TELNET = @TELNET@
TOUCH = @TOUCH@
-UCBMAIL = @UCBMAIL@
VERSION = @VERSION@
AUTOMAKE_OPTIONS = foreign no-dependencies
man_gen_MANS = env.5 lg.conf.5 lg_intro.1
-man_nogen_MANS = do-diffs.1 alogin.1 clogin.1 control_rancid.1 create_cvs.1 rancid.1 rancid_intro.1 cloginrc.5 router.db.5 elogin.1 flogin.1 jlogin.1 jrancid.1 francid.1 cat5rancid.1 erancid.1
+man_nogen_MANS = do-diffs.1 alogin.1 clogin.1 control_rancid.1 create_cvs.1 rancid.1 rancid_intro.1 cloginrc.5 router.db.5 elogin.1 flogin.1 jlogin.1 jrancid.1 francid.1 cat5rancid.1 erancid.1 xrancid.1
man_MANS = $(man_gen_MANS) $(man_nogen_MANS)
diff --git a/man/clogin.1 b/man/clogin.1
index 909adc6..cbc6a65 100644
--- a/man/clogin.1
+++ b/man/clogin.1
@@ -11,6 +11,9 @@ clogin \- Cisco/Foundry login script
.BI \-c\
command]
[\c
+.BI \-E\
+var=x]
+[\c
.BI \-e\
enable-password]
[\c
@@ -47,8 +50,8 @@ router
is an
.BR expect (1)
script to automate the process of logging into a Cisco router, catalyst
-switch, or Redback router. There are complementary scripts for Alteon,
-Juniper, Foundry, and ADC-kentrox EZ-T3 mux named
+switch, Extreme switch, or Redback router. There are complementary scripts
+for Alteon, Juniper, Foundry, and ADC-kentrox EZ-T3 mux named
.B alogin,
.B jlogin,
.B flogin,
@@ -74,6 +77,12 @@ commands maybe listed by separating them with semi-colons (;). The argument
should be quoted to avoid shell expansion.
.\"
.TP
+.B \-E
+Specifies a variable to pass through to scripts (\-s). For example, the
+command-line option \-Efoo=bar will produce a global variable by the name
+Efoo with the initial value "foo".
+.\"
+.TP
.B \-e
Specify a password to be supplied when gaining enable privileges on the
router(s). Also see the password directive of the
@@ -100,7 +109,8 @@ The filename of an
script which will be sourced after the login is successful and is expected
to return control to
.B clogin,
-with the connection to the router intact, when it is done.
+with the connection to the router intact, when it is done. Example script(s)
+can be found in util/*.exp.
.\"
.TP
.B \-t
diff --git a/man/lg.conf.5.in b/man/lg.conf.5.in
index fe7bdc7..3b07f75 100644
--- a/man/lg.conf.5.in
+++ b/man/lg.conf.5.in
@@ -20,6 +20,13 @@ The following variables are used (alphabetically):
*** not implemented.
.\"
.TP
+.B LG_BGP_RT
+Allows show ip bgp neighbor commands that can produce heavy output, such as
+sh ip bgp neighbor <ip> advertised-routes for a transit customer when the
+neighbor address is followed by 'advertised-routes' for the sh ip bgp neighbor
+query.
+.\"
+.TP
.B LG_CACHE_DIR
Sets the location of the cache directory. The looking glass uses this
to hold lock files, log files, and output from cached commands.
@@ -40,7 +47,7 @@ Default: 600
.\"
.TP
.B LG_CLOGINRC
-Defines the
+Defines the location of the
.BR cloginrc (5)
that the looking glass should use. The path may be relative to the directory
where the CGI scripts run in the server's document root.
@@ -93,12 +100,15 @@ default umask is 027 (see
.BR env (5)).
.\"
.TP
-.B LG_SINGLE
-*** not implemented.
+.B LG_STRIP
+Causes the LG to strip login information from the looking glass results.
+Since Expect often munges disabling echo when passwords are entered,
+this is a SECURITY CONCERN! However, this output can be very useful for
+debugging clogin problems.
.\"
.TP
.B PATH
-Is a colon separate list of directory pathnames in the the file system
+Is a colon separated list of directory pathnames in the the file system
where rancid's login scripts,
.IR clogin (1)
etc. )
diff --git a/man/rancid.1 b/man/rancid.1
index fcb88bd..b74e412 100644
--- a/man/rancid.1
+++ b/man/rancid.1
@@ -24,11 +24,12 @@ product is a file with the name of it's last argument plus the suffix .new.
For example, hostname.new.
.PP
There are complementary scripts for Alteon WebOS switches, Cisco catalyst
-switch, Juniper, Foundry, and ADC-kentrox EZ-T3 mux named
+switch, Juniper, Foundry, Extreme, and ADC-kentrox EZ-T3 mux named
.B arancid,
.B cat5rancid,
.B jrancid,
.B francid,
+.B xrancid,
and
.B erancid,
respectively.
diff --git a/man/rancid_intro.1 b/man/rancid_intro.1
index 0bdf1ba..82837e9 100644
--- a/man/rancid_intro.1
+++ b/man/rancid_intro.1
@@ -6,15 +6,15 @@ rancid_intro \- introduction to the Really Awesome New Cisco confIg Differ
.SH INTRODUCTION
.B rancid
is really more than just a Cisco configuration differ. It handles several
-different device's configurations; currently including Alteon, Cisco, Foundry,
-Juniper, Redback, and the ADC-Kentrox EZ-T3 mux.
+different device's configurations; currently including Alteon, Cisco, Extreme,
+Foundry, Juniper, Redback, and the ADC-Kentrox EZ-T3 mux.
.PP
.B rancid
uses an expect script to login to a list of devices and run a set of
commands for that device-type and collects the output. The output
is run through some filtering to summarize, reformat, and/or snip
-unwanted or security related data such as temperature and easily reverse-able
-passwords.
+unwanted or security related data such as chassis temperature and easily
+reverse-able passwords.
.PP
Named after the device's name in the group's configuration file, the
resulting files are saved in the directory <group>/configs. Except for the
diff --git a/man/router.db.5 b/man/router.db.5
index 873497b..4b25b70 100644
--- a/man/router.db.5
+++ b/man/router.db.5
@@ -49,7 +49,7 @@ The type of device from the set:
.RS 8n
.TP
.B alteon
-A Alteon WebOS switches.
+An Alteon WebOS switches.
.TP
.B cat5
A cisco catalyst switch (ie: running the catalyst OS, not IOS).
@@ -61,6 +61,9 @@ OS.
.B ezt3
An ADC-Kentrox EZ-T3 mux.
.TP
+.B extreme
+A Extreme switch.
+.TP
.B foundry
A Foundry router, switch, or router-switch.
.TP
diff --git a/man/xrancid.1 b/man/xrancid.1
new file mode 100644
index 0000000..b4633ee
--- /dev/null
+++ b/man/xrancid.1
@@ -0,0 +1 @@
+.so man1/rancid.1
diff --git a/util/Makefile.in b/util/Makefile.in
index 511cb7f..445c86b 100644
--- a/util/Makefile.in
+++ b/util/Makefile.in
@@ -11,7 +11,7 @@ install: all
for file in $(UTIL_PROGS) ; do \
$(INSTALL) $$file $(PREFIX)/util; \
done; \
- for file in *README*; do \
+ for file in *README* *.exp; do \
$(INSTALL_DATA) $$file $(PREFIX)/util; \
done; \
cd lg; $(MAKE) -e install
@@ -27,7 +27,7 @@ distclean: clean
rm -f config.log config.status
distdir:
- for file in Makefile.in configure.in *README* ; do \
+ for file in Makefile.in configure.in *README* *.exp; do \
$(INSTALL_DATA) $$file $(distdir); \
done; \
for file in configure $(UTIL_PROGS:=.in) ; do \
diff --git a/util/cisco-load.exp b/util/cisco-load.exp
new file mode 100644
index 0000000..58277e2
--- /dev/null
+++ b/util/cisco-load.exp
@@ -0,0 +1,331 @@
+##
+## 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.
+#
+# this expect snipit is sourced by clogin (-s option) to load a configuration
+# file (named <routername>-confg into nvram from an rcp/tftp host. this is an
+# _example_ as it not guaranteed to work for all applications. PLEASE test
+# for your environment.
+#
+# it expects the following variables via the -E option:
+# rcphost ='host to rcp from' such as 'foo.org' or '192.168.0.1'
+# confgpath ='path under /tftpboot where configs are held'
+#
+# the config file is expected to be routername-confg, where routername is the
+# name as grok'd from the router's cmd-line prompt
+#
+# example usage:
+# % clogin -s ./cisco-load.exp -Ercphost=foo.shrubbery.net router
+# router
+# loading router config from foo.shrubbery.net
+#
+# keep in mind that it is important to NOT polute the global variable space.
+# particularly, do not use variables used within clogin. this may result in
+# indeterministic results. an easy way to avoid this is to use a variable
+# name prefix (like 'E' or '_').
+#
+# useful variables from clogin global space:
+# router router name as provided on the cmd-line
+# prompt cmd-line prompt as determined by clogin
+#
+# note: the tcl/expect parser is extremely stoopid. comment lines are NOT
+# completely ignored!! so, a '{' or '}' in a comment might produce
+# unexpected results.
+##
+# log_user 1
+# exp_internal 1
+
+# sometimes this is a bit slow. note: this overrides clogin -t
+set timeout 90
+
+# take rcp host from -Ercphost='foo'
+if ([info exists Ercphost]) {
+ #puts "CONFGHOST == $Ercphost"
+ set confghost [string tolower $Ercphost]
+} else {
+ send_error "ERROR: -Ercphost= was not set on the command-line.\n"
+ exit
+}
+
+#
+# logout of the router
+#
+proc logout { ecode } {
+ global prompt
+
+ send "quit\r"
+ expect {
+ "$prompt" { logout $ecode }
+ timeout { send_error "Error: timeout waiting for EOF after quit\n"}
+ eof {
+ send_user "\n"
+ exit $ecode }
+ }
+}
+
+#
+# erase the nvram
+#
+proc erase { } {
+ global prompt
+
+ send "\r"
+ expect $prompt {}
+ send "write erase\r"
+ expect {
+ -re " Continue\[^\n\]\*confirm\]" {
+ send "\r"
+ exp_continue }
+ "$prompt" { }
+ timeout {
+ send_error "Error: timeout waiting for write erase.\n"
+ logout 1 }
+ eof { logout 1 }
+ }
+}
+
+#
+# load a config via rcp into nvram
+#
+proc doload { confghost routername config retry } {
+ global prompt
+
+ # send a return just to be sure we have a prompt.
+ send "\r"
+ expect "$prompt"
+ # start the copy and send the host to load from
+ # use tftp if retry == 1
+ if { $retry == 0 } {
+ send "copy tftp startup-config\r"
+ } else {
+ send "copy rcp startup-config\r"
+ }
+ expect {
+ timeout {
+ send_error "\nError: timeout exceeded waiting for rcp/tftp host prompt\r"
+ logout 1 }
+ "mbiguous command" {
+ if { $retry == 0 } {
+ send "copy tftp: startup-config\r"
+ } else {
+ send "copy rcp: startup-config\r"
+ }
+ exp_continue }
+ -re "Host or network .*\]\?" {
+ send "host\r"
+ exp_continue }
+ "\]\?" {
+ send "$confghost\r" }
+ }
+
+ #
+ # fill in the rest of the blanks. username (12.0), filename, dest, etc.
+ #
+ expect {
+ -re "Source username .\*\]\?" {
+ send "$routername\r";
+ exp_continue }
+ -re "Source filename .\*\]\?" {
+ send "$config\r";
+ exp_continue }
+ -re "Name of configur.\*\]\?" {
+ send "$config\r";
+ exp_continue }
+ -re "Destination filename .\*\]\?" {
+ send "startup-config\r";
+ exp_continue }
+ -re "Configure using .\*confirm\]" { send "\r" }
+ "proceed\? \\\[" { send "yes\r" }
+ -re "Do you want to over write.\*confirm\]" { send "\r" }
+ -re "Accessing (rcp|tftp):" { }
+ timeout {
+ send_error "\n\tError: timeout exceeded while matching load prompts\n";
+ send "" }
+ }
+
+ expect {
+ timeout {
+ send_error "Error: timeout exceeded while loading config\n"
+ logout 1 }
+ -re "\[^\n\]*Connection refused" {
+ send_error "Error: $expect_out(0,string)\n"
+ logout 1 }
+ -re "\[^\n\]*Destination unreachable" {
+ send_error "Error: $expect_out(0,string)\n"
+ logout 1 }
+ -re "\[^\n\]*Permission denied" {
+ send_error "Error: $expect_out(0,string)\n"
+ logout 1 }
+ -re "\[^\n]*No such file or directory" {
+ send_error "Error: $expect_out(0,string)\n"
+ logout 1 }
+ -re "\[^\n]*Error copying\[^\n]*Not enough space on device\[^\n]*\r" {
+ send_error "Error: $expect_out(0,string)\n"
+ if { $retry == 2 } {
+# erase stomps ssh rsa key
+# send_user "erasing nvram\n"
+# erase
+ send_user "retrying load\n"
+ doload $confghost $routername $config 1
+ } elseif { $retry == 1 } {
+# erase stomps ssh rsa key
+# send_user "erasing nvram\n"
+# erase
+ send_user "retrying load with tftp.\n"
+ doload $confghost $routername $config 0
+ } else {
+ send_error "Error: $expect_out(0,string)\n"
+ logout 1
+ } }
+ -re "\[^\n]*.*configuration is too large.*\n" {
+ send_error "Error: $expect_out(0,string)\n"
+ expect {
+ -re "\[^\n]*Truncate config.*:" { send "no\r" }
+ }
+ logout 1 }
+ -re "\[^\n]*Error (opening|copying).*\r" {
+ send_error "Error: $expect_out(0,string)\n"
+ logout 1 }
+ -nocase -re "\[^\n]* error\[^a-z\n]+\[^\n]*" {
+ send_error "$expect_out(0,string)\n"
+ logout 1 }
+ "\n" { exp_continue }
+ -re "^\[^ ]*\#" {
+ send_user "load successful.\n"
+ }
+ }
+
+ return 0;
+}
+
+send_user "loading $router config from $confghost\n";
+
+# look for router hostname in prompt (ie: deal with fqdn)
+send "\r"
+expect {
+ timeout {
+ send_error "Error: did not receive prompt\n"
+ exit }
+ "\n" { exp_continue }
+ -re "^(\[^ ]*)\#" {
+ set routername $expect_out(1,string) }
+}
+
+# deal with config subdir? from Econfgpath
+if ([info exists confgpath]) {
+ set config "$confgpath/$routername-confg"
+} else {
+ set config "$routername-confg"
+}
+
+# load the config
+if { [doload $confghost $routername $config 1] != 0 } {
+ logout 1
+}
+
+logout 0
+
+# these were my original transcripts of performing loads. it is a useful
+# example of info you may collect to get an idea of what needs to be handled
+# in the expect{}s
+#
+# pdx-oob#
+# pdx-oob#copy rcp start
+# Address of remote host [255.255.255.255]? 205.238.52.35
+# Name of configuration file [a]? pdx-oob-confg
+# Configure using pdx-oob-confg from 205.238.52.35? [confirm]
+#
+# Connected to 205.238.52.35
+# Loading 8131 byte file pdx-oob-confg: !!!! [OK]
+# Compressing configuration from 8131 bytes to 3886 bytes
+# [OK]
+# pdx-oob#
+#
+
+# 12.0S-isms
+# pao2#cop rcp sta
+# Address or name of remote host []? eng0
+# Translating "eng0"...domain server (205.238.52.46) [OK]
+#
+# Source username [pao2]?
+# Source filename []? pao2-confg
+# Destination filename [startup-config]?
+# Warning: Copying this config directly into the nvram from a network server may
+# cause damage the the startup config. It is advisable to copy the file
+# into the running config first, and then save it using copy run start.
+# Do you wish to proceed? [no]: yes
+# Accessing rcp://pao2@eng0/pao2-confg...
+# Connected to 205.238.52.35
+# Loading 30138 byte file pao2-confg: !!!!!! [OK]
+#
+# 30138 bytes copied in 2.576 secs (15069 bytes/sec)
+# pao2#
+# OR IS IT
+# sea0#cop rcp sta
+# Address or name of remote host []? eng0
+# Source username [sea0]?
+# Source filename []? sea0-confg
+# Destination filename [startup-config]?
+# Accessing rcp://sea0@eng0/sea0-confg...!!!!!!!!!!!!!!!!!!
+# 89794 bytes copied in 0.704 secs
+# sea0#q
+# Connection closed by foreign host.
+
+# pdx-oob#copy rcp start
+# Address of remote host [255.255.255.255]? 205.238.52.35
+# Name of configuration file [a]? pdx-oob-confg
+# Configure using pdx-oob-confg from 205.238.52.35? [confirm]
+#
+# Connected to 205.238.52.35
+# Loading 8131 byte file pdx-oob-confg: !!!! [OK]
+# Compressing configuration from 8131 bytes to 3886 bytes
+# [OK]
+# pdx-oob#copy rcp start
+# Address of remote host [205.238.52.35]? 205.238.52.35
+# Name of configuration file [pdx-oob-confg]? pdx-oob-confg
+# Configure using pdx-oob-confg from 205.238.52.35? [confirm]
+#
+# Connected to 205.238.52.35
+# %rcp: /tftpboot/pdx-oob-confg: No such file or directory
+# pdx-oob#
+#
+
+# pdx-oob#copy rcp start
+# Address of remote host [205.238.52.35]? 205.238.52.35
+# Name of configuration file [pdx-oob-confg]? pdx-oob-confg
+# Configure using pdx-oob-confg from 205.238.52.35? [confirm]
+#
+# Connected to 205.238.52.35
+# %rcp: /tftpboot/pdx-oob-confg: Permission denied
+# pdx-oob#
+#
+
+# *** response from filtered pkt
+# pdx-oob#copy rcp sta
+# Address of remote host [205.238.52.35]? 205.238.1.94
+# Name of configuration file [pdx-oob-confg]?
+# Configure using pdx-oob-confg from 205.238.1.94? [confirm]
+# % Destination unreachable; gateway or host down
+#
+# pdx-oob#
+#
+
+# *** response from host w/o rcp daemon
+# pdx-oob#cop rcp sta
+# Address of remote host [205.238.52.35]? 205.238.1.66
+# Name of configuration file [pdx-oob-confg]?
+# Configure using pdx-oob-confg from 205.238.1.66? [confirm]
+# % Connection refused by remote host
+#
+# pdx-oob#
+#
diff --git a/util/cisco-reload.exp b/util/cisco-reload.exp
new file mode 100644
index 0000000..095a3b2
--- /dev/null
+++ b/util/cisco-reload.exp
@@ -0,0 +1,141 @@
+##
+## 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.
+#
+# this expect snipit is sourced by clogin (-s option) to issue a reload
+# command on a cisco router. it DOES NOT save the config if it has been
+# modified. this is an _example_ as it not guaranteed to work for all
+# applications. PLEASE test for your environment.
+#
+# it expects the following variables via the -E option:
+# reload_arg ='command argument' such as 'at 05:00' or 'cancel
+#
+# eg usage:
+# % clogin -s cisco-reload.exp -Ereload_arg='at 01:00' router
+# router
+# Reload scheduled for 01:00:00 UTC Sat Jun 23 2001 (in 7 hours and 16 minutes)
+# % clogin -s cisco-reload.exp -Ereload_arg='at cancel' router
+# router
+# % Ambiguous command: "reload at cancel"
+#
+# % clogin -s cisco-reload.exp -Ereload_arg='cancel' router
+# router
+# SHUTDOWN ABORTED
+#
+#
+# keep in mind that it is important to NOT polute the global variable space.
+# particularly, do not use variables used within clogin. this may result in
+# indeterministic results. an easy way to avoid this is to use a variable
+# name prefix (like 'E' or '_').
+#
+# useful variables from clogin global space:
+# router router name as provided on the cmd-line
+# prompt cmd-line prompt as determined by clogin
+#
+# note: the tcl/expect parser is extremely stoopid. comment lines are NOT
+# completely ignored!! so, a '{' or '}' in a comment might produce
+# unexpected results.
+##
+# exp_internal 1
+# log_user 1
+
+# take reload command from -Ereload_arg='at 05:00'
+if ([info exists Ereload_arg]) {
+ #puts "reload_arg == $Ereload_arg"
+ set reloadcmd "reload $Ereload_arg"
+} else {
+ send_error "ERROR: -Ereload_arg= was not set on the command-line.\n"
+ exit
+}
+
+#send_user "$router\n"
+
+send "\r"
+expect {
+ timeout { send_error "Error: did not receive prompt\n"
+ exit }
+ -re "^.*$prompt" { send "$reloadcmd\r"
+ expect * {} }
+}
+# look for response
+expect {
+ -re "configuration has been modified.*no.:" { send "no\r";
+ exp_continue }
+ -re "Reload scheduled .*\r" { set sched $expect_out(0,string)
+ exp_continue }
+ -re "SHUTDOWN ABORTED" { set sched $expect_out(0,string) }
+ -re "Proceed with .*confirm\]" { send "\r" }
+ -re "\n.*No reload " { set sched "no reload scheduled"
+ send "\r" }
+ -re "% Ambig\[^\n\r]*" { set sched $expect_out(0,string) }
+}
+send "\r"
+expect "$prompt"
+if ([info exists sched]) {
+ send_user "\t$sched\n"
+}
+send "quit\r"
+expect {
+ timeout { send_error "Error: timeout waiting for EOF after quit\n"}
+ eof { exit 0 }
+}
+
+## dennis#reload in ?
+## Delay before reload (mmm or hhh:mm)
+##
+## dennis#reload in 100:10
+##
+## System configuration has been modified. Save? [yes/no]: no
+## Reload scheduled in 100 hours and 9 minutes
+## Proceed with reload? [confirm]
+## dennis#reload ca
+## dennis#reload cancel
+## dennis#
+##
+##
+## ***
+## *** --- SHUTDOWN ABORTED ---
+## ***
+##
+## dennis#wr
+## Building configuration...
+## [OK]
+## dennis#reload in 100:10
+## Reload scheduled in 100 hours and 10 minutes
+## Proceed with reload? [confirm]
+## dennis#rel
+## dennis#reload can
+## dennis#reload cancel
+## dennis#
+##
+##
+## ***
+## *** --- SHUTDOWN ABORTED ---
+## ***
+## System configuration has been modified. Save? [yes/no]: no
+## Reload scheduled for 11:51:48 PST Thu Dec 10 1998 (in 299 hours and 59 minutes)
+## Proceed with reload? [confirm]
+## ultra#reload can
+## ultra#
+##
+##
+## ***
+## *** --- SHUTDOWN ABORTED ---
+## ***
+## ultra# reload at 8:10 10 dec
+##
+## System configuration has been modified. Save? [yes/no]: no
+## Reload scheduled for 08:10:00 PST Thu Dec 10 1998 (in 296 hours and 17 minutes)
+## Proceed with reload? [confirm]
+## ultra#
+##
diff --git a/util/downreport.in b/util/downreport.in
index 2926c5c..edb3ae0 100755
--- a/util/downreport.in
+++ b/util/downreport.in
@@ -3,7 +3,7 @@
# Reports the list of routers not listed as 'up'.
# Put this in your crontab to run once a day:
-# 0 0 * * * /where/rancid/lives/util/downreport
+# 0 0 * * * @prefix@/util/downreport
# It can optionally
# take a space list of groups on the command line
@@ -24,6 +24,10 @@ fi
for GROUP in $LIST_OF_GROUPS; do
(
+ echo "To: @MAILPLUS@admin-$GROUP"
+ echo "Subject: Down router report - $GROUP"
+ echo "Precedence: bulk"
+ echo ""
DIR=$BASEDIR/$GROUP
if [ -s $DIR/routers.down ]; then
(
@@ -53,7 +57,6 @@ EOM
)
fi
- ) |\
- Mail -s "Down router report - $GROUP" @MAILPLUS@admin-$GROUP
+ ) | sendmail -t
done
diff --git a/util/lg/README b/util/lg/README
index b4186b9..183dd15 100644
--- a/util/lg/README
+++ b/util/lg/README
@@ -1,9 +1,9 @@
This is a looking glass based on Ed Kern's which can be found on
-http://nitrous.digex.net/. This version supports cisco and
-juniper, uses rancid's [cj]login to login (so rcmd is not necessary,
+http://nitrous.digex.net/. This version supports cisco, juniper, and
+foundry, useing rancid's [cfj]login to login (so rcmd is not necessary,
it can use telnet, ssh, or rsh), and has some additional commands
-implemented. There are a few cisco commands where either no juniper
-exists or we have not had time to implement yet.
+implemented. There are a few cisco commands where either no juniper or
+foundry equivalent exists or we have not had time to implement yet.
packing list:
README This file.
diff --git a/util/lg/lg.cgi.in b/util/lg/lg.cgi.in
index 0900060..1e37b20 100755
--- a/util/lg/lg.cgi.in
+++ b/util/lg/lg.cgi.in
@@ -1,4 +1,20 @@
#!@PERLV_PATH@
+## The original original lookingglass s/w was written by Ed Kern. it
+## is a single script and can be found at http://nitrous.digex.net/
+#
+## 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.
+#
# Looking glass
# vars: query, router, args
@@ -76,7 +92,7 @@ sub dolog
# run commands on the router
sub DoRsh
{
- my ($router, $mfg, $type, $arg) = @_;
+ my ($router, $mfg, $cmd, $arg) = @_;
my($ctime) = time();
my($lckobj) = LockFile::Simple->make(-delay => $lock_int,
@@ -93,32 +109,38 @@ sub DoRsh
if (! $lckobj->lock("$cache_dir/$router")) {
return ("$router is busy. Try again later.\n");
}
- @results = &DoCmd($router, $mfg, $type, $arg);
+ @results = &DoCmd($router, $mfg, $cmd, $arg);
$lckobj->unlock("$cache_dir/$router");
return (@results);
}
sub DoCmd
{
- my($rtr, $mfg, $type, $arg) = @_;
+ my($rtr, $mfg, $cmd, $arg) = @_;
local(*CMD);
- if ($mfg =~ /juniper/i) {
- open(CMD, "jlogin -f $cloginrc -c \'$juniperCmd{$type} $arg\' $rtr |");
+ if ($mfg =~ /foundry/i) {
+ open(CMD, "sh -c \"flogin -f $cloginrc -c \'$cmd $arg\' $rtr\" 2>&1 |");
+ $cmd = $foundryCmd{$type};
+ } elsif ($mfg =~ /juniper/i) {
+ open(CMD, "sh -c \"jlogin -f $cloginrc -c \'$cmd $arg\' $rtr\" 2>&1 |");
$cmd = $juniperCmd{$type};
} else {
- open(CMD, "clogin -noenable -f $cloginrc -c \'$ciscoCmd{$type} $arg\' $rtr |");
+ open(CMD, "sh -c \"clogin -noenable -f $cloginrc -c \'$cmd $arg\' $rtr\" 2>&1 |");
$cmd = $ciscoCmd{$type};
}
while (<CMD>) {
tr/\015//d;
if (/^error:/i) {
dolog(LOG_ERR, $_);
- return ($_);
+ if ($LG_STRIP) { undef(@results); }
+ push(@results, $_);
+ return (@results);
}
-# push(@results, $_);
+ push(@results, $_);
if (/$cmd/) {
($prompt) = /^(\S*)[\#>]/;
# push(@results, "prompt = $prompt\n\n");
+ if ($LG_STRIP) { undef(@results); }
last;
}
}
@@ -250,41 +272,67 @@ if (!defined($type) || !defined($router)) {
# conversion of command "type" passed from lgform.cgi to the vendor's syntax.
%ciscoCmd = (
- #acl => "sh access-list",
- #aspath => "sh ip as-path-access-list",
- #communitylist => "sh ip community-list",
- damp => "sh ip bgp dampened-paths",
- framerelay => "sh frame-relay pvc",
- interface => "sh interface",
- intbrief => "sh ip interface",
- log => "sh logging",
- mbgp => "sh ip mbgp",
- mbgpsum => "sh ip mbgp summary",
- regex => "sh ip bgp regex",
- route => "sh ip route",
- #routemap => "sh route-map",
+ #acl => "show access-list",
+ #aspath => "show ip as-path-access-list",
+ #communitylist => "show ip community-list",
+ damp => "show ip bgp dampened-paths",
+ framerelay => "show frame-relay pvc",
+ interface => "show interface",
+ intbrief => "show ip interface",
+ log => "show logging",
+ mbgp => "show ip mbgp",
+ mbgpsum => "show ip mbgp summary",
+ mneighbor => "show ip bgp neighbor",
+ neighbor => "show ip bgp neighbor",
+ regex => "show ip bgp regex",
+ route => "show ip route",
+ routemap => "show route-map",
+ ping => "ping",
+ prefix => "show ip bgp",
+ prefixlist => "show ip prefix-list",
+ summary => "show ip bgp summary",
+ trace => "traceroute"
+ );
+%foundryCmd = (
+ #acl => "show access-list",
+ #aspath => "show ip as-path-access-list",
+ #communitylist => "show ip community-list",
+ damp => "show ip bgp dampened-paths",
+ #framerelay => "show frame-relay pvc", # no frame relay
+ interface => "show interface",
+ log => "show log",
+ #mbgp => "show ip mbgp",
+ #mbgpsum => "show bgp summary",
+ #mneighbor => "show ip bgp neighbor",
+ neighbor => "show ip bgp neighbor",
+ #regex => "show ip bgp aspath-regex",
+ route => "show ip route",
+ routemap => "show route-map",
ping => "ping",
- prefix => "sh ip bgp",
- prefixlist => "sh ip prefix-list",
- summary => "sh ip bgp summary",
+ prefix => "show ip bgp",
+ prefixlist => "show ip prefix-list",
+ summary => "show ip bgp summary",
trace => "traceroute"
);
%juniperCmd = (
- #acl => "sh access-list",
- #aspath => "sh ip as-path-access-list",
- #communitylist => "sh ip community-list",
+ #acl => "show access-list",
+ #aspath => "show ip as-path-access-list",
+ #communitylist => "show ip community-list",
damp => "show route damping suppressed terse table inet.0",
- interface => "sh interface",
+ framerelay => "show frame-relay pvc",
+ interface => "show interface",
log => "show log messages",
- mbgp => "sh route table inet.2 terse",
- mbgpsum => "sh bgp summary",
- #regex => "sh route table inet.0 aspath-regex",
- route => "sh route table inet.0",
- #routemap => "sh route-map",
+ mbgp => "show route table inet.2 terse",
+ mbgpsum => "show bgp summary",
+ mneighbor => "show bgp neighbor",
+ neighbor => "show bgp neighbor",
+ regex => "show route table inet.0 aspath-regex",
+ route => "show route forwarding-table destination",
+ routemap => "show policy",
ping => "ping rapid count 5",
- prefix => "sh route table inet.0",
- #prefixlist => "sh ip prefix-list",
- summary => "sh bgp summary",
+ prefix => "show route table inet.0",
+ prefixlist => "show policy",
+ summary => "show bgp summary",
trace => "traceroute"
);
%cmdDisp = (
@@ -292,12 +340,16 @@ if (!defined($type) || !defined($router)) {
#aspath => "show ip as-path-access-list",
#communitylist => "show ip community-list",
damp => "show ip bgp dampened-paths",
+ framerelay => "show frame-relay pvc",
+ interface => "show interface",
log => "show logging",
mbgp => "show ip mbgp",
mbgpsum => "show ip mbgp summary",
+ mneighbor => "show ip mbgp neighbor",
+ neighbor => "show ip bgp neighbor",
regex => "show ip bgp regex",
route => "show ip route",
- #routemap => "show route-map",
+ routemap => "show route-map",
ping => "ping",
prefix => "show ip bgp",
prefixlist => "show ip prefix-list",
@@ -306,9 +358,20 @@ if (!defined($type) || !defined($router)) {
);
# not all cmds/queries are implemented for junipers
-if ($mfg =~ /juniper/ && ! defined($juniperCmd{$type})) {
- $results[0] = "$cmdDisp{$type} not implemented for junipers. sorry.\n";
- &print_results;
+if ($mfg =~ /juniper/) {
+ if (! defined($juniperCmd{$type})) {
+ $results[0] = "$cmdDisp{$type} not implemented for junipers. sorry.\n";
+ &print_results;
+ }
+ $cmd = $foundryCmd{$type};
+} elsif ($mfg =~ /foundry/) {
+ if(! defined($foundryCmd{$type})) {
+ $results[0] = "$cmdDisp{$type} not implemented for foundrys. sorry.\n";
+ &print_results;
+ }
+ $cmd = $foundryCmd{$type};
+} else {
+ $cmd = $ciscoCmd{$type};
}
@@ -324,6 +387,11 @@ if ($type eq "prefix" || $type eq "mbgp" || $type eq "route" ) {
$arg = $arg[0] . "/" . mask2len($arg[1]);
}
} elsif ($type eq "framerelay") {
+ if ($mfg =~ /juniper/) {
+ $results[0] = "Juniper does not have a show frame-relay pvc command. ".
+ "Use show interface.\n";
+ &print_results;
+ }
if ($arg[0] > 15 && $arg[0] < 1024) {
$arg = $arg[0];
} else {
@@ -333,7 +401,7 @@ if ($type eq "prefix" || $type eq "mbgp" || $type eq "route" ) {
if ($arg[1] =~ /[-\/0-9:.]+/) {
$arg = $arg[0] . " " . $arg[1];
} else {
- if ($arg[0] =~ /^b/i && $mfg =~ /cisco/i) {
+ if ($arg[0] !~ /^b[^ ]+[0-9]/i && $arg[0] =~ /^b/i && $mfg =~ /(cisco|foundry)/i) {
$type = "intbrief";
$arg = "brief";
} else {
@@ -341,15 +409,17 @@ if ($type eq "prefix" || $type eq "mbgp" || $type eq "route" ) {
}
}
} elsif ($type eq "log") {
- $arg[0] =~ s/^\s*|//;
- if ($arg[0] =~ /^\s*$/) {
+ if ($arg[0] =~ /^\s*\|?$/) {
shift(@arg);
}
+ $arg[0] =~ s/^\s*\|?//;
if ($arg[0] !~ /^\s*$/) {
if ($mfg =~ /cisco/i) {
$arg = " | include " . join(' ', @arg);
} elsif ($mfg =~ /juniper/i) {
$arg = " | match \"" . join(' ', @arg) . "\"";
+ } else {
+ undef($arg);
}
} else {
undef($arg);
@@ -385,9 +455,11 @@ if ($type eq "prefix" || $type eq "mbgp" || $type eq "route" ) {
$arg = $arg[0];
} elsif ($type eq "regex") {
$arg = $arg[0];
- if ($#arg > 1) {
- for ($n = 1; $n <= $#arg - 1; $n++) { $arg .= " " . $arg[$n]; }
+ if ($#arg >= 1) {
+ for ($n = 1; $n <= $#arg; $n++) { $arg .= " " . $arg[$n]; }
}
+ # remove leading/trailing whitespace
+ $arg =~ s/^\s*//; $arg =~ s/\s*$//;
if ($arg !~ /^[0-9_ ^.*+?[\])\(-]*\$?$/ || $arg =~ /^\s*$/) {
$results[0] = "That argument ($arg[0]) is not valid.\n";
&print_results;
@@ -398,8 +470,86 @@ if ($type eq "prefix" || $type eq "mbgp" || $type eq "route" ) {
$results[0] = "Get real. Such a query has potential to over-burden our router.\nLook that up on your own router.\n";
&print_results;
}
- # escape any ()
+ if ($mfg =~ /juniper/) {
+ $arg =~ s/_/ /g;
+ # pre-junos 4.4 do not allow anchors
+ if ($arg =~ /\^\$/) {
+ $arg =~ "()";
+ } else {
+ $arg =~ s/[\$^]/ /g;
+ }
+ $arg = "\"$arg\"";
+ }
+ # escape any ()s
$arg =~ s/([\(\)])/\\$1/g;
+} elsif ($type eq "neighbor") {
+ if ($arg[0] !~ /^\d+\.\d+\.\d+\.\d+$/) {
+ if ($arg[0] !~ /([A-Za-z0-9-]*.)*[A-Za-z0-9-]*.(com|edu|net|org)/) {
+ $results[0] = "That argument ($arg[0]) is not valid.\n";
+ &print_results;
+ }
+ }
+ $arg = $arg[0];
+ if (defined($arg[1]) && $arg[1] =~ /^(a|ro|f|re)/) {
+ if ($mfg =~ /juniper/) {
+ if ($arg[1] =~ /^a/) {
+ if (defined($LG_BGP_RT)) {
+ $cmd = "show route table inet.0 all advertising-protocol ".
+ "bgp";
+ }
+ } elsif ($arg[1] =~ /^f/) {
+ if (defined($LG_BGP_RT)) {
+ $cmd = "show route damping table inet.0 all ".
+ "receive-protocol bgp";
+ }
+ } elsif ($arg[1] =~ /^r/) {
+ if (defined($LG_BGP_RT)) {
+ $cmd = "show route table inet.0 all receive-protocol bgp";
+ }
+ }
+ } else {
+ if ($arg[1] =~ /^a/) {
+ if (defined($LG_BGP_RT)) { $arg .= " advertised-routes"; }
+ } elsif ($arg[1] =~ /^f/) {
+ $arg .= " flap-statistics";
+ } elsif ($arg[1] =~ /^ro/) {
+ if (defined($LG_BGP_RT)) { $arg .= " routes"; }
+ } elsif ($arg[1] =~ /^re/) {
+ if (defined($LG_BGP_RT)) { $arg .= " received-routes"; }
+ }
+ }
+ }
+} elsif ($type eq "mneighbor") {
+ if ($arg[0] !~ /^\d+\.\d+\.\d+\.\d+$/) {
+ if ($arg[0] !~ /([A-Za-z0-9-]*.)*[A-Za-z0-9-]*.(com|edu|net|org)/) {
+ $results[0] = "That argument ($arg[0]) is not valid.\n";
+ &print_results;
+ }
+ }
+ $arg = $arg[0];
+ if (defined($arg[1]) && $arg[1] =~ /^(a|ro|f|re)/) {
+ if ($mfg =~ /juniper/) {
+ if ($arg[1] =~ /^a/) {
+ $cmd .= " advertised-routes";
+ } elsif ($arg[1] =~ /^f/) {
+ $cmd .= " flap-statistics";
+ } elsif ($arg[1] =~ /^ro/) {
+ $cmd .= " routes";
+ } elsif ($arg[1] =~ /^re/) {
+ $cmd .= " received-routes";
+ }
+ } else {
+ if ($arg[1] =~ /^a/) {
+ $arg .= " advertised-routes";
+ } elsif ($arg[1] =~ /^f/) {
+ $arg .= " flap-statistics";
+ } elsif ($arg[1] =~ /^ro/) {
+ $arg .= " routes";
+ } elsif ($arg[1] =~ /^re/) {
+ $arg .= " received-routes";
+ }
+ }
+ }
} elsif ($type eq "damp" || $type eq "summary" || $type eq "mbgpsum") {
undef($arg);
}
@@ -433,17 +583,17 @@ if ($type eq "summary" || $type eq "mbgpsu" || $type eq "damp" || $type eq "log"
# else, execute command and save to a new cache file
open(CACHE,">$file") || die "couldnt create cache file $file" ;
- @results = &DoRsh($router, $mfg, $type, $arg);
+ @results = &DoRsh($router, $mfg, $cmd, $arg);
print CACHE "@results";
close CACHE ;
} else {
- @results = &DoRsh($router, $mfg, $type, $arg);
+ @results = &DoRsh($router, $mfg, $cmd, $arg);
}
&print_results ;
} # end dampened-paths/flap-statistics
-@results = &DoRsh($router, $mfg, $type, $arg);
+@results = &DoRsh($router, $mfg, $cmd, $arg);
&print_results ;
exit ;
diff --git a/util/lg/lg.conf.in b/util/lg/lg.conf.in
index 7e8a96f..7b78c3f 100644
--- a/util/lg/lg.conf.in
+++ b/util/lg/lg.conf.in
@@ -2,11 +2,30 @@
#
# note: these are perl statements! mind the syntax
#
-# adjust the path to find [cj]login, telnet, ssh, rsh, etc.
+# adjust the path to find [cfj]login, telnet, ssh, rsh, etc.
#
$ENV{PATH}="@prefix@/bin:@ENV_PATH@";
#
#
+# LG_CACHE_DIR is the location of the cache directory. the LG uses this
+# to hold lock files, the default log file (lg.log), and o/p from
+# commands that can be very verbose. it defaults to "tmp",
+# ie: relative to the directory where lg.cgi runs in your
+# server's (httpd) DocumentRoot (eg: /usr/local/www/data/lg/tmp).
+#
+#$LG_CACHE_DIR="./tmp";
+#
+#
+# LG_CLOGINRC is the .cloginrc that the LG should use. it defaults to
+# <prefix>/.cloginrc. note that the .cloginrc must be readable
+# by the user or group (UID / GID) that will be running the CGI
+# and the clogin (and friends) will not allow a world readable
+# .cloginrc. this is normally the user the server (httpd) runs
+# under.
+#
+#$LG_CLOGINRC="@prefix@/.cloginrc";
+#
+#
# LG_IMAGE is the filename of an image you wish to appear at the top
# of the LG pages. it can also be other html goo, like
# the first example. this is just handed to print, so \n and
@@ -16,6 +35,17 @@ $ENV{PATH}="@prefix@/bin:@ENV_PATH@";
#$LG_IMAGE="<img src=rancid.gif hspace=0>\n";
#
#
+# LG_LOG is either a FQPN (fully qualified path name) the syslog
+# facility to use for logging. if not defined, the LG
+# will log to LG_CACHE_DIR/lg.log. possible syslog facility
+# values are from the facility codes in /usr/include/syslog.h
+# minus the 'LOG_' and lower case.
+#
+#$LG_LOG="$LG_CACHE_DIR/lg.log";
+#$LG_LOG="/tmp/lg.log";
+#$LG_LOG="local0";
+#
+#
# LG_ROUTERDB is the router.db in rancid's router.db format, listing
# the routers and their platform that should be available to
# the looking glass. if defined, the LG will use this variable
@@ -31,27 +61,19 @@ $ENV{PATH}="@prefix@/bin:@ENV_PATH@";
#$LG_ROUTERDB="@prefix@/util/lg/router.db";
#
#
-# LG_CLOGINRC is the .cloginrc that the LG should use. it defaults to
-# <prefix>/.cloginrc. note that the .cloginrc must readable
-# by the user or group (UID / GID) that will be running the CGI
-# and the clogin (and friends) will not allow a world readable
-# .cloginrc. this is normally the user the server (httpd) runs
-# under.
-#
-#$LG_CLOGINRC="@prefix@/.cloginrc";
+# Options:
#
+# LG_AS_REG *** not implemented.
#
-# LG_SINGLE *** not implemented.
-#$LG_SINGLE=0;
+#@LG_AS_REG=();
#
#
-# LG_CACHE_DIR is the location of the cache directory. the LG uses this
-# to hold lock files, lg.log log file, and o/p from commands
-# that can be very verbose. it defaults to "tmp", ie: relative
-# to the directory where lg.cgi runs in your server's (httpd's)
-# DocumentRoot (eg: /usr/local/www/data/lg/tmp).
+# LG_BGP_RT allows a few bgp commands which can produce long output (heavy
+# router load), such as sh ip bgp neighbor <ip> advertised-routes
+# for a transit customer, sh ip b neigh <ip> received-routes for
+# a transit provider.
#
-#$LG_CACHE_DIR="./tmp";
+#$LG_BGP_RT=1
#
#
# LG_CACHE_TIME is the number of seconds the LG should cache o/p from certain
@@ -62,18 +84,15 @@ $ENV{PATH}="@prefix@/bin:@ENV_PATH@";
#$LG_CACHE_TIME=600;
#
#
-# LG_LOG is either a FQPN (fully qualified path name) the syslog
-# facility to use for logging. if not defined, the LG
-# will log to LG_CACHE_DIR/lg.log. possible syslog facility
-# values are from the facility codes in /usr/include/syslog.h
-# minus the 'LOG_' and lower case.
-#
-#$LG_LOG="$LG_CACHE_DIR/lg.log";
-#$LG_LOG="/tmp/lg.log";
-#$LG_LOG="local0";
+# LG_SINGLE serializes and limits queries per-router to one at a time via
+# per-router lock files.
#
+#$LG_SINGLE=0;
#
-# LG_AS_REG *** not implemented.
+# $LG_STRIP strips login o/p from the looking glass results. Expect
+# occassionally screws up disabling echo when passwords are
+# entered (NOTE SECURITY CONCERN). However, this o/p can be
+# very useful for debugging clogin problems.
#
-#@LG_AS_REG=();
+$LG_STRIP=1;
#
diff --git a/util/lg/lgform.cgi.in b/util/lg/lgform.cgi.in
index 762c9d8..7fa7d0f 100755
--- a/util/lg/lgform.cgi.in
+++ b/util/lg/lgform.cgi.in
@@ -1,4 +1,17 @@
#!@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.
+#
# lgform.cgi - Looking glass front-end
# produces html form for calling lg.cgi
@@ -75,7 +88,7 @@ sub readrouters
next if (/^\s*(#|$)/);
# fqdn:mfg:state
@record = split('\:', $_);
- next if ($record[2] !~ /up/i || $record[1] !~ /(cisco|juniper)/);
+ next if ($record[2] !~ /up/i || $record[1] !~ /(cisco|foundry|juniper)/);
push(@rtrlist, join(':', ($record[0], $record[1])));
$rtrlabels{join(':', ($record[0], $record[1]))} = $record[0];
}
@@ -91,7 +104,7 @@ sub readrouters
next if (/^\s*(#|$)/);
# fqdn:mfg:state
@record = split('\:', $_);
- next if ($record[2] !~ /up/i || $record[1] !~ /(cisco|juniper)/);
+ next if ($record[2] !~ /up/i || $record[1] !~ /(cisco|foundry|juniper)/);
push(@rtrlist, join(':', ($record[0], $record[1])));
$rtrlabels{join(':', ($record[0], $record[1]))} = $record[0];
}
@@ -140,14 +153,16 @@ print <<QTYPES ;
<dd><input type=radio name="query" value="framerelay">show frame-relay pvc [DLCI]</DD>
<dd><input type=radio name="query" value="interface">show interface &lt;interface&gt;</DD>
<dd><input type=radio name="query" value="prefix">show ip bgp &lt;prefix&gt; [netmask]</DD>
+<dd><input type=radio name="query" value="neighbor">show ip bgp neighbor &lt;IP_addr&gt;</DD>
<dd><input type=radio name="query" value="regex">show ip bgp regex &lt;reg_exp&gt;</DD>
<dd><input type=radio name="query" value="summary">show ip bgp summary</DD>
<dd><input type=radio name="query" value="damp">show ip bgp dampened-paths</DD>
<dd><input type=radio name="query" value="prefixlist">show ip prefix-list &lt;list_name&gt;</DD>
<dd><input type=radio name="query" value="route">show ip route &lt;prefix&gt; [netmask]</DD>
+<dd><input type=radio name="query" value="routemap">show route-map &lt;map_name&gt;</DD>
<dd><input type=radio name="query" value="mbgp">show ip mbgp &lt;prefix&gt; [netmask]</dd>
<dd><input type=radio name="query" value="mbgpsum">show ip mbgp summary</dd>
-<dd><input type=radio name="query" value="log">show logging [| &lt;match_string&gt;]</DD>
+<dd><input type=radio name="query" value="log">show logging [ | &lt;match_string&gt;]</DD>
<dd><input type=radio name="query" value="ping">ping &lt;IP_addr | FQDN&gt;</dd>
<dd><input type=radio name="query" value="trace">traceroute &lt;IP_addr | FQDN&gt;</DD>
@@ -159,14 +174,6 @@ print <<QTYPES ;
<dd>
QTYPES
-# unimplemented/disabled/removed query types.
-#
-# <dd>show ip bgp neighbor &lt;IP_addr&gt;</dd>
-# <dd>show ip bgp neighbor &lt;IP_addr&gt; advertised routes</dd>
-# <dd>show ip bgp neighbor &lt;IP_addr&gt; flap statistics</dd>
-# <dd>show ip bgp neighbor &lt;IP_addr&gt; received</dd>
-# <dd>show ip bgp neighbor &lt;IP_addr&gt; routes</dd>
-#
# <dd><input type=radio name="query" value="aspath">sh ip as-path-access-list &lt;list_number&gt;</DD>
# <dd><input type="radio" name="query" value="acl">sh access-list &lt;list_number&gt;</dd>
# <dd><input type=radio name="query" value="communitylist">sh ip community-list &lt;list_number&gt;<DD>
diff --git a/util/lg/lgnotes.html b/util/lg/lgnotes.html
index 44fb4e0..9f28ec3 100644
--- a/util/lg/lgnotes.html
+++ b/util/lg/lgnotes.html
@@ -14,13 +14,13 @@ size=+3><strong>&nbsp;&nbsp;&nbsp;Looking Glass Notes
<p>
<ul>
Just a few straight forward notes on our implementation of
-Ed Kern's looking glass. See the "real thing" at
+Ed Kern's looking glass. See the original at
<a href=http://nitrous.digex.net>http://nitrous.digex.net</a>.
</ul>
</p>
<p>
<UL>
-<li>Some items are not implemented for the junipers yet (so, as i get
+<li>Some items are not implemented for the junipers/foundrys yet (so, as i get
to it) or no equivalent command exists.
<li>If there is something which you feel is missing, feel free to ask
and/or send comments to <a href=mailto:rancid@shrubbery.net>
@@ -46,5 +46,16 @@ Ed Kern's looking glass. See the "real thing" at
and produce lots of output, such as 'sh ip bgp' or 'sh ip bgp reg '^3561'.
The looking glass attempts to deny such commands.</li>
</ul>
+<p>
+Some useful hints:
+<UL>
+<li>Show interfaces can take arguments other than an interface name, assuming
+ the router is running an O/S version with the capability. For example; a
+ cisco can take 'descriptions' or 'brief' and 'terse' for the juniper. </li>
+<li>Show ip bgp neighbor can take additional arguments (if configured to allow
+ it), such as 'advertised routes', 'flap-statistics', 'received-routes',
+ and 'routes'. The argument will be converted for the platform.</li>
+</ul>
+
</body>
</html>
diff --git a/util/rtrfilter.README b/util/rtrfilter.README
index bc98c4e..19b64c3 100644
--- a/util/rtrfilter.README
+++ b/util/rtrfilter.README
@@ -1,6 +1,6 @@
rtrfilter can be used to filter rancid diffs to avoid sending unwanted
diffs to certain recipient(s) or diffs which those recipient(s) should
-not see without the need to create a separate group(s).
+not see without the need to create separate or duplicate group(s).
/etc/aliases eg:
diff --git a/util/rtrfilter.in b/util/rtrfilter.in
index 8826047..28bd21a 100755
--- a/util/rtrfilter.in
+++ b/util/rtrfilter.in
@@ -1,5 +1,18 @@
#!@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.
+#
# rtrtfilter - "| rtrfilter -x <perl regex> -i <perl regex> -f <regex file> \
# -u <From address> -s <subject> <rcpts>"
# expects to read an email message on stdin containing a diff from
@@ -25,7 +38,7 @@
# exclusion takes precedence and defaults to nothing. inclusion defaults to
# everything.
#
-# this program require the Mail::Mailer module which can be found on CPAN.
+# this program requires the Mail::Mailer module which can be found on CPAN.
##
BEGIN {
$me = $0;