summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTar Committer <tar@ocjtech.us>2002-08-09 21:59:06 +0000
committerTar Committer <tar@ocjtech.us>2002-08-09 21:59:06 +0000
commitff168ecfe045c690c24d5bbc5a3062bf9d64120c (patch)
treea480f841453c9e22b6fd9ad4a54d1c9d5dbfabf6
parentafcac75e572bcdd3cf269b921b7e8324aa5ffd4c (diff)
downloadrancid-ff168ecfe045c690c24d5bbc5a3062bf9d64120c.tar.gz
rancid-ff168ecfe045c690c24d5bbc5a3062bf9d64120c.tar.xz
rancid-ff168ecfe045c690c24d5bbc5a3062bf9d64120c.zip
Imported from rancid-2.2.2.tar.gz.rancid-2.2.2
-rw-r--r--CHANGES39
-rw-r--r--FAQ23
-rw-r--r--Todo2
-rw-r--r--bin/Makefile.in1
-rw-r--r--bin/alogin.in12
-rw-r--r--bin/blogin.in18
-rwxr-xr-xbin/clogin.in18
-rwxr-xr-xbin/control_rancid.in75
-rwxr-xr-xbin/elogin.in12
-rwxr-xr-xbin/f10rancid.in10
-rwxr-xr-xbin/flogin.in204
-rwxr-xr-xbin/hlogin.in18
-rw-r--r--bin/hpfilter.c1
-rwxr-xr-xbin/jrancid.in4
-rwxr-xr-xbin/par.in35
-rwxr-xr-xbin/rancid.in18
-rwxr-xr-xconfigure2
-rw-r--r--configure.in2
-rw-r--r--include/config.h2
-rw-r--r--include/version.h2
-rw-r--r--include/version.h.in2
-rw-r--r--man/env.5.in15
-rw-r--r--man/lg.conf.5.in31
-rw-r--r--man/lg_intro.1.in13
-rw-r--r--man/par.110
-rw-r--r--util/README5
-rwxr-xr-xutil/getipacctg.in103
-rw-r--r--util/lg/README14
-rwxr-xr-xutil/lg/lg.cgi.in364
-rwxr-xr-xutil/lg/lgform.cgi.in53
30 files changed, 817 insertions, 291 deletions
diff --git a/CHANGES b/CHANGES
index c2f9c1d..2795e3f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,42 @@
+2.2.2
+ *login: fix handling of userprompt et al so that {}'s are used in
+ .cloginrc as they are with every other .cloginrc directive.
+
+ f10rancid: Fix to pick up new info in show version output.
+
+ jrancid: Ignore Timecounter "TSC" in show system boot-messages output.
+
+ rancid: filter tty line speed when configured for auto-configure
+
+ flogin: bring login() and do_enable() in-line with [cj]login. also
+ match "telnet server disabled" - from brad volz.
+
+ control_rancid: report devices added to router.db - from Fredrik Thulin
+ also eliminate empty up/down lists.
+
+ rancid/jrancid: filter isis passwords - partial from Janos Mohacsi
+
+ lg: make o/p from the lg stream (unbuffered), so one doesnt have
+ to wait for entire o/p from the router in a failing traceroute, for
+ example. suggestion and clues from alexander koch. while here, fix
+ cache handling so 1) it doesnt cache cmds that resulted in an error or
+ otherwise failed and 2) log and run the cmd as normal if there are
+ problems opening a cache file.
+
+ lg: make logging more consistent. log as defined by LG_LOG if
+ possible and stderr as last resort. it was logging largely to stderr.
+ and make exit-code small (instead of 255); some wait()s only look at
+ the first 3 bits
+
+ lg: add check in lg.cgi that router name appears in the router.db
+ and is thus accessible. from richard doty. also fix-up a few
+ comments and such.
+
+ rancid: GSR LC PCA h/w revision now called "design release" on
+ some platforms. CSCdw13295
+
+ add util/getipacctg example script - contrib from steve neighorn
+
2.2.1
rancid: npe400 cpu eeprom info o/p format changed in 12.0.21S1 -
spotted by tom campbell
diff --git a/FAQ b/FAQ
index 242770d..7cda952 100644
--- a/FAQ
+++ b/FAQ
@@ -67,7 +67,26 @@ A. This is most likely either a CVS or filesystem permissions problem. Check
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
+ on the cvs repository is chown -R <rancid user> /usr/local/rancid/CVS
+
+Q. I am renaming a device but would like the retain the history in CVS. How
+ is this done?
+A. CVS does not provide a way (AFAIK) to rename files or to rename or delete
+ directories. The best way is to copy the CVS repository file manually
+ like this (disclaimer: BE VERY CAREFUL mucking around with the repository):
+ % su - rancid_user
+ % cd /usr/local/rancid
+ % echo "new_device_name:device_type:up" >> GROUP/router.db
+ % cp -p CVS/GROUP/configs/old_device_name,v \
+ CVS/GROUP/configs/new_device_name,v
+ where GROUP is the name of the rancid group the device is a member of.
+ Rancid will pick-up the new file with a CVS update the next time it runs.
+ Once the renaming is complete, remove the old name from the router.db file
+ and leave the CVS clean-up of the old filename to rancid.
+
+ If one wanted to move a device to a different group and maintain the
+ history, the same procedure would work. Substituting the new group name
+ appropriately.
3) General
@@ -94,7 +113,7 @@ A. Our usual diagnostic procedure for this is:
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
+ - Then see if the correct rancid commands work against the router. For
example:
rancid cisco_router
diff --git a/Todo b/Todo
index fd04b48..87b2520 100644
--- a/Todo
+++ b/Todo
@@ -1,3 +1,5 @@
+- fix varargs for knf in util.c
+- isis filtering for foundry?
- extreme v6.2.x need 'show configuration detail' to get full config but
does not work on older vers
- hlogin (hp procurve) needs to adjust it's PATH to find hpfilter
diff --git a/bin/Makefile.in b/bin/Makefile.in
index 74652a3..ad98aa8 100644
--- a/bin/Makefile.in
+++ b/bin/Makefile.in
@@ -299,7 +299,6 @@ distdir: $(DISTFILES)
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
-hpfilter.o: hpfilter.c ../include/config.h ../include/version.h
info-am:
info: info-am
diff --git a/bin/alogin.in b/bin/alogin.in
index dc5afaa..03f12ca 100644
--- a/bin/alogin.in
+++ b/bin/alogin.in
@@ -465,9 +465,17 @@ foreach router [lrange $argv $i end] {
# Figure out prompts
set u_prompt [find userprompt $router]
- if { "$u_prompt" == "" } { set u_prompt "(Username|login| Login):" }
+ if { "$u_prompt" == "" } {
+ set u_prompt "(Username|login| Login):"
+ } else {
+ set u_prompt [lindex $u_prompt 0]
+ }
set p_prompt [find passprompt $router]
- if { "$p_prompt" == "" } { set p_prompt "\[Pp]assword:" }
+ if { "$p_prompt" == "" } {
+ set p_prompt "\[Pp]assword:"
+ } else {
+ set p_prompt [lindex $p_prompt 0]
+ }
# Figure out cypher type
if {[info exists cypher]} {
diff --git a/bin/blogin.in b/bin/blogin.in
index 811a0d0..23bf97c 100644
--- a/bin/blogin.in
+++ b/bin/blogin.in
@@ -536,11 +536,23 @@ foreach router [lrange $argv $i end] {
# Figure out prompts
set u_prompt [find userprompt $router]
- if { "$u_prompt" == "" } { set u_prompt "(Username|login|user name):" }
+ if { "$u_prompt" == "" } {
+ set u_prompt "(Username|login|user name):"
+ } else {
+ set u_prompt [lindex $u_prompt 0]
+ }
set p_prompt [find passprompt $router]
- if { "$p_prompt" == "" } { set p_prompt "(\[Pp]assword|passwd):" }
+ if { "$p_prompt" == "" } {
+ set p_prompt "(\[Pp]assword|passwd):"
+ } else {
+ set p_prompt [lindex $p_prompt 0]
+ }
set e_prompt [find enableprompt $router]
- if { "$e_prompt" == "" } { set e_prompt "\[Pp]assword:" }
+ if { "$e_prompt" == "" } {
+ set e_prompt "\[Pp]assword:"
+ } else {
+ set e_prompt [lindex $e_prompt 0]
+ }
# Figure out cypher type
if {[info exists cypher]} {
diff --git a/bin/clogin.in b/bin/clogin.in
index 9fff218..c026699 100755
--- a/bin/clogin.in
+++ b/bin/clogin.in
@@ -627,11 +627,23 @@ foreach router [lrange $argv $i end] {
# Figure out prompts
set u_prompt [find userprompt $router]
- if { "$u_prompt" == "" } { set u_prompt "(Username|Login|login|user name):" }
+ if { "$u_prompt" == "" } {
+ set u_prompt "(Username|Login|login|user name):"
+ } else {
+ set u_prompt [lindex $u_prompt 0]
+ }
set p_prompt [find passprompt $router]
- if { "$p_prompt" == "" } { set p_prompt "(\[Pp]assword|passwd):" }
+ if { "$p_prompt" == "" } {
+ set p_prompt "(\[Pp]assword|passwd):"
+ } else {
+ set p_prompt [lindex $p_prompt 0]
+ }
set e_prompt [find enableprompt $router]
- if { "$e_prompt" == "" } { set e_prompt "\[Pp]assword:" }
+ if { "$e_prompt" == "" } {
+ set e_prompt "\[Pp]assword:"
+ } else {
+ set e_prompt [lindex $e_prompt 0]
+ }
# Figure out cypher type
if {[info exists cypher]} {
diff --git a/bin/control_rancid.in b/bin/control_rancid.in
index dc453a0..42f14ae 100755
--- a/bin/control_rancid.in
+++ b/bin/control_rancid.in
@@ -131,12 +131,12 @@ fi
# generate the list of all, up, & down routers
cd $DIR
trap 'rm -fr routers.db routers.all.new routers.down.new routers.up.new \
- $TMP;' 1 2 15
+ routers.mail routers.added routers.deleted $TMP;' 1 2 15
grep -v '^#' router.db > routers.db
cut -d: -f1,2 routers.db | sort -u > routers.all.new
if [ ! -f routers.all ] ; then touch routers.all; fi
diff routers.all routers.all.new > /dev/null 2>&1; RALL=$?
-@PERLV@ -F: -ane '{($F[0] =~ tr@A-Z@a-z@,print join(":", @F)."\n")
+@PERLV@ -F: -ane '{($F[0] =~ tr@A-Z@a-z@,print $_)
if ($F[2] !~ /^up$/i);}' routers.db | sort -u > routers.down.new
if [ ! -f routers.down ] ; then touch routers.down; fi
diff routers.down routers.down.new > /dev/null 2>&1; RDOWN=$?
@@ -149,32 +149,59 @@ if [ $RALL -ne 0 -o $RDOWN -ne 0 -o $RUP -ne 0 ]
then
(
if [ $RUP -ne 0 ] ; then
- if [ $RUP -eq 1 ] ; then
- echo Routers changed to up:
- comm -13 routers.up routers.up.new | sed -e 's/^/ /'
- echo
- elif [ -s routers.up.new ] ; then
- echo Routers changed to up:
- sed -e 's/^/ /' routers.up.new
- echo
+ if [ ! -s routers.up ] ; then
+ echo Routers changed to up:
+ sed -e 's/^/ /' routers.up.new
+ echo
+ else
+ WCUP=`comm -13 routers.up routers.up.new | wc -l | \
+ sed -e 's/^ *\([^ ]*\)/\1/'`
+ if [ $WCUP -gt 0 ] ; then
+ echo Routers changed to up:
+ comm -13 routers.up routers.up.new | sed -e 's/^/ /'
+ echo
+ fi
fi
fi
if [ $RDOWN -ne 0 ] ; then
- if [ $RDOWN -eq 1 ] ; then
- echo Routers changed to down:
- comm -13 routers.down routers.down.new | sed -e 's/^/ /'
- echo
- elif [ -s routers.down.new ] ; then
- echo Routers changed to down:
- sed -e 's/^/ /' routers.down.new
- echo
+ if [ ! -s routers.down ] ; then
+ echo Routers changed to down:
+ sed -e 's/^/ /' routers.down.new
+ echo
+ else
+ WCDOWN=`comm -13 routers.down routers.down.new | wc -l | \
+ sed -e 's/^ *\([^ ]*\)/\1/'`
+ if [ $WCDOWN -eq 1 ] ; then
+ echo Routers changed to down:
+ comm -13 routers.down routers.down.new | \
+ sed -e 's/^/ /'
+ echo
+ fi
fi
fi
- WC=`wc -l routers.all | sed -e 's/^ *\([^ ]*\) .*$/\1/'`
- WCNEW=`wc -l routers.all.new | sed -e 's/^ *\([^ ]*\) .*$/\1/'`
- if [ $RALL -eq 1 -a $WC -gt $WCNEW ] ; then
- echo Deleted routers:
- comm -23 routers.all routers.all.new | sed -e 's/^/ /'
+ if [ $RALL -eq 1 ] ; then
+ comm -13 routers.all routers.all.new | sed -e 's/^/ /' \
+ > routers.added
+ comm -23 routers.all routers.all.new | sed -e 's/^/ /' \
+ > routers.deleted
+
+ WCADDED=`wc -l routers.added | sed -e 's/^ *\([^ ]*\) .*$/\1/'`
+ WCDELETED=`wc -l routers.deleted | sed -e 's/^ *\([^ ]*\) .*$/\1/'`
+
+ if [ $WCADDED -gt 0 ]
+ then
+ echo Added routers:
+ cat routers.added
+ echo
+ fi
+ if [ $WCDELETED -gt 0 ]
+ then
+ echo Deleted routers:
+ cat routers.deleted
+ echo
+ fi
+
+ rm -f routers.added routers.deleted
fi
) > routers.mail
@@ -224,8 +251,8 @@ for router in `cut -d: -f1 ../routers.up` ; do
cvs add -ko $router
echo "CVS added missing router $router"
fi
- echo
done
+echo
# 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
diff --git a/bin/elogin.in b/bin/elogin.in
index a76155d..1b647fa 100755
--- a/bin/elogin.in
+++ b/bin/elogin.in
@@ -439,9 +439,17 @@ foreach router [lrange $argv $i end] {
# Figure out prompts
set u_prompt [find userprompt $router]
- if { "$u_prompt" == "" } { set u_prompt "(Username|login| Login):" }
+ if { "$u_prompt" == "" } {
+ set u_prompt "(Username|login| Login):"
+ } else {
+ set u_prompt [lindex $u_prompt 0]
+ }
set p_prompt [find passprompt $router]
- if { "$p_prompt" == "" } { set p_prompt "\[Pp]assword:" }
+ if { "$p_prompt" == "" } {
+ set p_prompt "\[Pp]assword:"
+ } else {
+ set p_prompt [lindex $p_prompt 0]
+ }
# Figure out cypher type
if {[info exists cypher]} {
diff --git a/bin/f10rancid.in b/bin/f10rancid.in
index 54ccd74..06528c5 100755
--- a/bin/f10rancid.in
+++ b/bin/f10rancid.in
@@ -242,10 +242,12 @@ sub ShowVersion {
ProcessHistory("COMMENTS","keysort","A3","!CPU:$slave $cpu\n");
next;
}
- if (/^(.*)\s+processor .*with (\d+[kK]?) bytes/) {
- my($cpu) = $1;
- my($mem) = $2;
- my($type) = "Buffy";
+ if (/^Chassis Type: (.*)$/) {
+ $type = $1;
+ }
+ if (/^(.*\s+Processor)( \d)?:(.*) with (\d+[kK]?) bytes/) {
+ my($cpu) = "$1$2:$3";
+ my($mem) = $4;
my($device) = "Force10";
ProcessHistory("COMMENTS","keysort","A1",
"!Chassis type:$slave - a $device $type\n");
diff --git a/bin/flogin.in b/bin/flogin.in
index 1e34077..1a34068 100755
--- a/bin/flogin.in
+++ b/bin/flogin.in
@@ -275,12 +275,13 @@ 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
+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
set uprompt_seen 0
- # Telnet to the router & try to login.
+ # try each of the connection methods in $cmethod until one is successful
set progs [llength $cmethod]
foreach prog [lrange $cmethod 0 end] {
if [string match "telnet*" $prog] {
@@ -297,8 +298,8 @@ proc login { router user userpswd passwd enapasswd prompt cmethod cyphertype } {
} elseif ![string compare $prog "ssh"] {
if [ catch {spawn ssh -c $cyphertype -x -l $user $router} reason ] {
send_user "\nError: ssh failed: $reason\n"
- exit 1
- }
+ exit 1
+ }
} elseif ![string compare $prog "rsh"] {
if [ catch {spawn rsh -l $user $router} reason ] {
send_user "\nError: rsh failed: $reason\n"
@@ -309,29 +310,28 @@ proc login { router user userpswd passwd enapasswd prompt cmethod cyphertype } {
return 1
}
incr progs -1
-
- sleep 0.3
-
- # This helps cleanup each expect clause.
- expect_after {
- timeout {
- send_user "\nError: TIMEOUT reached\n"
- catch {close}; wait
- if { $in_proc} {
- return 1
- } else {
- continue
- }
- } eof {
- send_user "\nError: EOF received\n"
- catch {close}; wait
- if { $in_proc} {
- return 1
- } else {
- continue
+ sleep 0.3
+
+ # This helps cleanup each expect clause.
+ expect_after {
+ timeout {
+ send_user "\nError: TIMEOUT reached\n"
+ catch {close}; wait
+ if { $in_proc} {
+ return 1
+ } else {
+ continue
+ }
+ } eof {
+ send_user "\nError: EOF received\n"
+ catch {close}; wait
+ if { $in_proc} {
+ return 1
+ } else {
+ continue
+ }
}
- }
- }
+ }
# Here we get a little tricky. There are several possibilities:
# the router can ask for a username and passwd and then
@@ -341,71 +341,77 @@ proc login { router user userpswd passwd enapasswd prompt cmethod cyphertype } {
# then it will just send the passwd.
# if telnet fails with connection refused, try ssh
expect {
- "Connection refused" {
- close; wait
- if { $tryssh } {
- if [ catch {spawn ssh -c $cyphertype -x -l $user $router} reason ] {
- send_user "\nError: failed to ssh: $reason\n"
- exit 1
- }
- set tryssh 0
- sleep 0.3
- exp_continue
- } else {
- expect eof
- send_user "\nError: Connection Refused\n"; wait; return 1
+ -re "(Connection refused|Secure connection \[^\n\r]+ refused|Connection closed by|Telnet server disabled)" {
+ catch {close}; wait
+ if !$progs {
+ send_user "\nError: Connection Refused ($prog)\n"; return 1
}
- } eof { send_user "\nError: Couldn't login\n"; wait; return 1
- } "Unknown host\r\n" {
- expect eof
+ }
+ eof { send_user "\nError: Couldn't login\n"; wait; return 1 }
+ -nocase "unknown host\r" {
+ catch {close};
send_user "\nError: Unknown host\n"; wait; return 1
- } "Host is unreachable" {
- expect eof
+ }
+ "Host is unreachable" {
+ catch {close};
send_user "\nError: Host Unreachable!\n"; wait; return 1
- } "No address associated with name" {
- expect eof
+ }
+ "No address associated with name" {
+ catch {close};
send_user "\nError: Unknown host\n"; wait; return 1
}
- -re "Host key not found .* \(yes\/no\)\?" {
- send "yes\r"
- send_user "Host $router added to the list of known hosts.\n"
- exp_continue }
- -re "HOST IDENTIFICATION HAS CHANGED.* \(yes\/no\)\?" {
- send "no\r"
- send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n"
- return 1 }
+ -re "(Host key not found |The authenticity of host .* be established).*\(yes\/no\)\?" {
+ send "yes\r"
+ send_user "\nHost $router added to the list of known hosts.\n"
+ exp_continue }
+ -re "HOST IDENTIFICATION HAS CHANGED.* \(yes\/no\)\?" {
+ send "no\r"
+ send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n"
+ return 1 }
-re "Offending key for .* \(yes\/no\)\?" {
send "no\r"
send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n"
return 1 }
- denied { send_user "\nError: Check your passwd for $router\n"
- catch {close}; wait; return 1
- }
- "% Bad passwords" {send_user "\nError: Check your passwd for $router\n"; return 1 }
- -re "(Username:|login:|Name :)" {
- sleep 1;
- send "$user\r"
- set uprompt_seen 1
- exp_continue
- }
- "@\[^\r\n]+\[Pp]assword:" {
+ -re "(denied|Sorry)" {
+ send_user "\nError: Check your passwd for $router\n"
+ catch {close}; wait; return 1
+ }
+ "Login failed" {
+ send_user "\nError: Check your passwd for $router\n"
+ return 1
+ }
+ -re "% (Bad passwords|Authentication failed)" {
+ send_user "\nError: Check your passwd for $router\n"
+ return 1
+ }
+ -re "@\[^\r\n]+ $p_prompt" {
# ssh pwd prompt
sleep 1
send "$userpswd\r"
exp_continue
}
- "\[Pp]assword:" {
- sleep 1;
- if {$uprompt_seen == 1} {
- send "$userpswd\r"
- } else {
- send "$passwd\r"
- }
- exp_continue
- }
- "$prompt" { break; }
+ -re "$u_prompt" {
+ send "$user\r"
+ set uprompt_seen 1
+ exp_continue
+ }
+ -re "$p_prompt" {
+ sleep 1
+ if {$uprompt_seen == 1} {
+ send "$userpswd\r"
+ } else {
+ send "$passwd\r"
+ }
+ exp_continue
+ }
+ "$prompt" { break; }
+ "Login invalid" {
+ send_user "\nError: Invalid login\n";
+ catch {close}; wait; return 1
+ }
}
}
+
set in_proc 0
return 0
}
@@ -413,21 +419,25 @@ proc login { router user userpswd passwd enapasswd prompt cmethod cyphertype } {
# Enable
proc do_enable { enauser enapasswd } {
global prompt in_proc
+ global u_prompt e_prompt
set in_proc 1
- sleep 1; # dont go too fast for it now...
+ sleep 1; # dont go too fast for it now...
send "enable\r"
expect {
- -re "(Username|User Name):" { send "$enauser\r"; exp_continue}
- "Password:" { send "$enapasswd\r"; exp_continue}
- "#" { }
- denied { send_user "\nError: Check your Enable passwd\n"; return 1}
- "% Bad passwords" { send_user "\nError: Check your Enable passwd\n"
- return 1
- }
+ -re "$u_prompt" { send "$enauser\r"; exp_continue}
+ -re "$e_prompt" { send "$enapasswd\r"; exp_continue}
+ "#" { set prompt "#" }
+ "(enable)" { set prompt "> (enable) " }
+ denied { send_user "\nError: Check your Enable passwd\n";
+ return 1
+ }
+ "% Bad passwords" { send_user "\nError: Check your Enable passwd\n";
+ return 1
+ }
}
- # Set the prompt variable so script files don't need to know what it is.
- set prompt "#"
+ # We set the prompt variable (above) so script files don't need
+ # to know what it is.
set in_proc 0
return 0
}
@@ -542,6 +552,26 @@ foreach router [lrange $argv $i end] {
if { "$enauser" == "" } { set enauser $ruser }
}
+ # Figure out prompts
+ set u_prompt [find userprompt $router]
+ if { "$u_prompt" == "" } {
+ set u_prompt "(Username|login|Name|User Name):"
+ } else {
+ set u_prompt [lindex $u_prompt 0]
+ }
+ set p_prompt [find passprompt $router]
+ if { "$p_prompt" == "" } {
+ set p_prompt "(\[Pp]assword):"
+ } else {
+ set p_prompt [lindex $p_prompt 0]
+ }
+ set e_prompt [find enableprompt $router]
+ if { "$e_prompt" == "" } {
+ set e_prompt "\[Pp]assword:"
+ } else {
+ set e_prompt [lindex $e_prompt 0]
+ }
+
# Figure out cypher tpye
if {[info exists cypher]} {
# command line cypher type
@@ -556,7 +586,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 } {
diff --git a/bin/hlogin.in b/bin/hlogin.in
index a3c00ac..917ea83 100755
--- a/bin/hlogin.in
+++ b/bin/hlogin.in
@@ -605,11 +605,23 @@ foreach router [lrange $argv $i end] {
# Figure out prompts
set u_prompt [find userprompt $router]
- if { "$u_prompt" == "" } { set u_prompt "(Username|login|user name):" }
+ if { "$u_prompt" == "" } {
+ set u_prompt "(Username|login|user name):"
+ } else {
+ set u_prompt [lindex $u_prompt 0]
+ }
set p_prompt [find passprompt $router]
- if { "$p_prompt" == "" } { set p_prompt "(\[Pp]assword|passwd):" }
+ if { "$p_prompt" == "" } {
+ set p_prompt "(\[Pp]assword|passwd):"
+ } else {
+ set p_prompt [lindex $p_prompt 0]
+ }
set e_prompt [find enableprompt $router]
- if { "$e_prompt" == "" } { set e_prompt "\[Pp]assword:" }
+ if { "$e_prompt" == "" } {
+ set e_prompt "\[Pp]assword:"
+ } else {
+ set e_prompt [lindex $e_prompt 0]
+ }
# Figure out cypher type
if {[info exists cypher]} {
diff --git a/bin/hpfilter.c b/bin/hpfilter.c
index f665b6f..83d799e 100644
--- a/bin/hpfilter.c
+++ b/bin/hpfilter.c
@@ -92,7 +92,6 @@ main(int argc, char **argv)
signal(SIGCHLD, (void *) reapchild);
signal(SIGHUP, (void *) reapchild);
signal(SIGINT, (void *) reapchild);
- signal(SIGKILL, (void *) reapchild);
signal(SIGTERM, (void *) reapchild);
/* create 2 pipes for send/recv and then fork and exec telnet */
diff --git a/bin/jrancid.in b/bin/jrancid.in
index 4eb6ee3..238e704 100755
--- a/bin/jrancid.in
+++ b/bin/jrancid.in
@@ -329,6 +329,7 @@ sub ShowSystemBootMessages {
/^\s+\^/ && return;
/syntax error/ && return;
/^JUNOS / && <INPUT> && next;
+ /^Timecounter "TSC" / && next;
/^real memory / && next;
/^avail memory / && next;
/^\/dev\// && next;
@@ -386,6 +387,9 @@ sub ShowConfiguration {
if (/(\s*authentication-key ).*$/ && $filter_pwds >= 1) {
s/(\s*authentication-key ).*$/#$1<removed>;/;
}
+ if (/(\s*hello-authentication-key ).*$/ && $filter_pwds >= 1) {
+ s/(\s*hello-authentication-key ).*$/#$1<removed>;/;
+ }
if (/^(.*\ssecret \")\$9\$.*(\".*)$/ && $filter_pwds >= 1) {
s/^(.*\ssecret \")\$9\$.*(\".*)$/#$1<removed>$2/;
}
diff --git a/bin/par.in b/bin/par.in
index 494de53..02a5383 100755
--- a/bin/par.in
+++ b/bin/par.in
@@ -27,6 +27,10 @@
# -x = view par logs as they run through xterms
# -i = run commands through interactive xterms
# -d = print debugging to stderr
+# -p # = pause # seconds between forks, default 0.
+# -f = no file or STDIN, just run a quantity of $command.
+# This precludes passing different args to each process.
+# -e = exec args split by spaces rather than use sh -c
#
# par takes a list of items to run a command on. If the list entry begins
# with a ":" the remainder of the line is the command to run ("{}" will be
@@ -37,15 +41,17 @@
# line is assumed to be a command to be run.
#
use Getopt::Std;
-getopts('n:l:c:xidq');
+getopts('p:n:l:c:fixedq');
$procs=$opt_n; $procs=3 if(!$procs);
-$command=$opt_c;$command="{}" if(!$command);
-$parlog=$opt_l; $parlog="par.log.".time if(!$parlog);
+$command=$opt_c; #$command="{}" if(!$command);
+$parlog=$opt_l; $parlog="par.log.".time() if(!$parlog);
$debug=$opt_d;
+$no_file=$opt_f ? 1 : 0;
+$pause_time = $opt_p ? $opt_p : 0;
if ($opt_q && ($opt_x || $opt_l)) {
print STDERR "-q nullifies -x and -l\n";
- exit 1;
+ exit(1);
}
$signalled=0;
@@ -54,7 +60,7 @@ sub handler {
$signalled++;
print STDERR "Received signal - ending run ($signalled).\n";
if($signalled>1) {
- printf STDERR "Ok - killing $id!\n";
+ printf(STDERR "Ok - killing $id!\n");
kill 9, 0;
exit(1);
}
@@ -74,6 +80,10 @@ sub start {
close(LOG);
exec "($cmd) >>$logfile";
} else {
+ if($opt_e) {
+ # Don't use sh -c.
+ exec split(/\s+/, $cmd);
+ }
exec "($cmd)";
}
exit 0;
@@ -95,13 +105,19 @@ sub watchf {
unless(fork) { exec "xterm -e tail -f $log" ; exit 1; }
}
-for($i=0;<>;$i++) {
+# this does not work, $_ doesnt end up with <>
+#for($i=0; ($no_file && $i<$procs) || (! $no_file && <> ) ;$i++) {
+for($i=0; ($no_file || ($_=<>)) ;$i++) {
chop;
if (/^\#/){$i--;next;}
- if(/^:(.*)$/){$command=$1;$i--;next;}
+ if ($opt_c == "" && /^:(.*)$/) {
+ $command=$1;$i--;next;
+ }
if ($i<$procs) {
$logfile="running.$i"; $logfile="$parlog.$i" if (!$opt_q);
- } else { $logfile=finish; }
+ } else {
+ $logfile=finish;
+ }
last if $signalled;
if ($logfile) {
$cmd = $command;
@@ -109,9 +125,10 @@ for($i=0;<>;$i++) {
$cmd = "xterm -e $cmd" if ($opt_i);
$id=start($cmd,$logfile);
watchf($logfile) if($opt_x);
- $log{$id}=$logfile;
+ $log{$id} = $logfile;
}
print STDERR "$i/$procs: $_: id=$id, log=$log{$id}\n" if ($debug);
+ sleep($pause_time) if ($pause_time);
}
if($signalled && !eof) {
diff --git a/bin/rancid.in b/bin/rancid.in
index 4bd7ee3..4566b58 100755
--- a/bin/rancid.in
+++ b/bin/rancid.in
@@ -671,9 +671,9 @@ sub ShowDiag {
if (/^\s+PCA:\s+(.*)/) {
local($part) = $1;
$_ = <INPUT>;
- /^\s+HW version (\S+)\s+S\/N (\S+)/ &&
- ProcessHistory("SLOT","keysort","C1","!Slot $slot/PCA: part $part, serial $2\n") &&
- ProcessHistory("SLOT","keysort","C2","!Slot $slot/PCA: hvers $1\n");
+ /^\s+(HW version|design release) (\S+)\s+S\/N (\S+)/i &&
+ ProcessHistory("SLOT","keysort","C1","!Slot $slot/PCA: part $part, serial $3\n") &&
+ ProcessHistory("SLOT","keysort","C2","!Slot $slot/PCA: hvers $2\n");
next;
}
if (/^\s+MBUS: .*\)\s+(.*)/) {
@@ -869,6 +869,7 @@ sub ShowVLAN {
# This routine processes a "write term"
sub WriteTerm {
print STDERR " In WriteTerm: $_" if ($debug);
+ my($lineauto) = 0;
while (<INPUT>) {
tr/\015//d;
@@ -878,6 +879,7 @@ sub WriteTerm {
# the pager can not be disabled per-session on the PIX
s/^<-+ More -+>\s*//;
/Non-Volatile memory is in use/ && return(-1); # NvRAM is locked
+ $lineauto = 0 if (/^[^ ]/);
# skip the crap
if (/^(##+$|(Building|Current) configuration)/i) {
while (<INPUT>) {
@@ -901,6 +903,8 @@ sub WriteTerm {
/^ntp clock-period / && next; # kill ntp clock-period
/^ length / && next; # kill length on serial lines
/^ width / && next; # kill width on serial lines
+ $lineauto = 1 if /^ modem auto/;
+ /^ speed / && $lineauto && next; # kill speed on serial lines
/^ clockrate / && next; # kill clockrate on serial interfaces
if (/^(enable )?(password|passwd) / && $filter_pwds >= 1) {
ProcessHistory("ENABLE","","","!$1$2 <removed>\n");
@@ -945,6 +949,14 @@ sub WriteTerm {
if (/^( ip ospf authentication-key) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
+ # isis passwords appear to be completely plain-text
+ if (/^\s+isis password (\S+)( .*)?/ && $filter_pwds >= 1) {
+ ProcessHistory("","","","!isis password <removed>$2\n"); next;
+ }
+ if (/^\s+(domain-password|area-password) (\S+)( .*)?/
+ && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>$2\n"); next;
+ }
# this is reversable, despite 'md5' in the cmd
if (/^( ip ospf message-digest-key \d+ md5) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
diff --git a/configure b/configure
index c0fb7d1..3861408 100755
--- a/configure
+++ b/configure
@@ -2566,7 +2566,7 @@ rancid rename rrancid xrancid"
rd_cv_rd_bin_progs=$RD_BIN_PROGS
# RD_UTIL_PROGS are util/ .in's that need to be installed with execute perms.
-RD_UTIL_PROGS="rtrfilter downreport"
+RD_UTIL_PROGS="rtrfilter downreport getipacctg"
rd_cv_rd_util_progs=$RD_UTIL_PROGS
diff --git a/configure.in b/configure.in
index 9d34f4a..b18d474 100644
--- a/configure.in
+++ b/configure.in
@@ -183,7 +183,7 @@ AC_SUBST(RD_BIN_PROGS)
rd_cv_rd_bin_progs=$RD_BIN_PROGS
# RD_UTIL_PROGS are util/ .in's that need to be installed with execute perms.
-RD_UTIL_PROGS="rtrfilter downreport"
+RD_UTIL_PROGS="rtrfilter downreport getipacctg"
AC_SUBST(RD_UTIL_PROGS)
rd_cv_rd_util_progs=$RD_UTIL_PROGS
diff --git a/include/config.h b/include/config.h
index 5ab2ffb..0e9e4d3 100644
--- a/include/config.h
+++ b/include/config.h
@@ -98,7 +98,7 @@
#define PACKAGE "rancid"
/* Version number of package */
-#define VERSION "2.2.1"
+#define VERSION "2.2.2"
/* Define if compiler has function prototypes */
#define PROTOTYPES 1
diff --git a/include/version.h b/include/version.h
index 685d3c8..c1348ad 100644
--- a/include/version.h
+++ b/include/version.h
@@ -4,6 +4,6 @@
/* pkg version */
char package[] = "rancid";
-char version[] = "2.2.1";
+char version[] = "2.2.2";
#endif
diff --git a/include/version.h.in b/include/version.h.in
index 685d3c8..c1348ad 100644
--- a/include/version.h.in
+++ b/include/version.h.in
@@ -4,6 +4,6 @@
/* pkg version */
char package[] = "rancid";
-char version[] = "2.2.1";
+char version[] = "2.2.2";
#endif
diff --git a/man/env.5.in b/man/env.5.in
index 1050ac7..99366c4 100644
--- a/man/env.5.in
+++ b/man/env.5.in
@@ -49,11 +49,20 @@ Default: $BASEDIR/CVS
Determines which passwords will be filtered from configs. The value may be
"NO", "YES", or "ALL" to filter none of the passwords, only those which are
reversable or plain-text, or all (plus ssh keys, etc), respectively.
-Note that passwords whose value cycles and would produce erroneous diffs
-are always filtered (eg: Alteon passwords). Note that a value of "NO" could
-be a security issue.
.sp
Default: YES
+.sp
+Note: a value of "NO" could be a security issue since diffs are sent via
+e-mail. A value of "ALL" is encouraged.
+.sp
+Note:
+.B FILTER_PWDS
+does not affect the handling of SNMP community strings. see
+.B NOCOMMSTR
+below.
+.sp
+Note: passwords whose value cycles and would produce erroneous diffs
+are always filtered (eg: Alteon passwords).
.\"
.TP
.B LIST_OF_GROUPS
diff --git a/man/lg.conf.5.in b/man/lg.conf.5.in
index cb052f7..b5d5423 100644
--- a/man/lg.conf.5.in
+++ b/man/lg.conf.5.in
@@ -9,7 +9,8 @@ contains configuration for the looking glass scripts.
.PP
The syntax is that of
.IR perl (1).
-It is used to set variables to affect run-time behavior or to locate resources.
+It is used to set variables to affect run-time behavior and/or to locate
+resources.
.\"
.SH VARIABLES
The following variables are used (alphabetically):
@@ -67,7 +68,7 @@ Defines a html image tag (<img>) which, if defined, will be included at
the top of the looking glass pages. It may contain any html as it is
simply handed off to print().
.sp
-Example: $LG_IMAGE="<img src=/icons/rancid.gif hspace=0>\n <font size=+2>FOO</font>";
+Example: $LG_IMAGE="<img src=/icons/rancid.gif hspace=0>\\n <font size=+2>FOO</font>";
.\"
.TP
.B LG_INFO
@@ -79,7 +80,8 @@ Example: $LG_INFO="For Support contact <a href=mailto:webmaster\@localhost>webma
.\"
.TP
.B LG_LOG
-Defines the fully qualified path name for the log file or the
+Defines the fully qualified path name (ie: begins with '/') for the log file
+or the
.BR syslog (3)
facility to use for logging. For syslog, the argument is the lowercase name
of a syslog facility (see syslog.h) without the 'LOG_' prefix.
@@ -98,12 +100,12 @@ format. It lists the devices that should be available to the looking glass
users. Only those devices of supported types and with state 'up' are made
available. If not defined and the default file does not exist, the looking
glass will compile a list from the router.db files of all the groups present
-in rancid, that is a concatenation of $BASEDIR/*/router.db.
+in rancid, that is, the list will be a concatenation of $BASEDIR/*/router.db.
.sp
Default: @prefix@/util/lg/router.db
.sp
Note that if the concatenation method is used, it may be necessary to alter
-the mode of the router.db files in the rancid group directories, since the
+the mode of the router.db files in the rancid group directories, since rancid's
default umask is 027 (see
.BR env (5)).
.\"
@@ -128,22 +130,35 @@ note that it must include $BASEDIR/bin (see above).
.\"
.El
.\"
+.SH ENVIRONMENT
+.Bl -tag -width LG_CONF -compact
+.TP
+.B LG_CONF
+Location of
+.B lg.conf
+file. See the
+.IR FILES
+section for more information.
+.El
+.\"
.SH ERRORS
.B lg.conf
is interpreted directly by
.IR perl (1),
-so its syntax follows that of perl. Errors may produce quite unexpected
+so its syntax follows that of perl. Syntax errors may produce quite unexpected
results.
.SH FILES
.Bl -tag -width .BASEDIR/bin/ENV -compact
.TP
.B $BASEDIR/util/lg/lg.conf
Configuration file described here, where $BASEDIR is set at the time that
-the rancid package was configured. In this case, $BASEDIR is
+the rancid package was configured. In this installation, $BASEDIR is
.IR @prefix@ .
+.sp
.B lg.conf
is located by the value of the environment variable LG_CONF, in the CWD
-(current working directory), or rancid install directory ($BASEDIR/util/lg).
+(current working directory), or rancid install directory ($BASEDIR/util/lg),
+in that order.
.El
.SH SEE ALSO
.BR cloginrc (5),
diff --git a/man/lg_intro.1.in b/man/lg_intro.1.in
index 1af8942..b6ced11 100644
--- a/man/lg_intro.1.in
+++ b/man/lg_intro.1.in
@@ -18,7 +18,7 @@ The looking glass consists of two CGI
scripts,
.IR lg.cgi
and
-.IR lg.form.cgi ,
+.IR lgform.cgi ,
and the
.BR lg.conf (5)
configuration file.
@@ -28,12 +28,12 @@ there is an error in the file's syntax or if the file can not be found, error
messages will be displayed on standard-error. The Apache http server
redirects standard-error to its error log file by default.
.PP
-lg.form.cgi displays a html form consisting of a list of possible
+lgform.cgi displays a html form consisting of a list of possible
router commands that can be run and a scrolling list of routers that
these commands may be run on. When the form is submitted, lg.cgi is
run.
.PP
-When lg.cgi is run, it begins by performing some basic checks on the
+lg.cgi begins by performing some basic checks on the
arguments passed to it. If these checks pass, lg.cgi either displays
cached data from a previous invocation if that data exists and is
within the cache interval or uses
@@ -59,6 +59,7 @@ these. See the README file.
.BR lg.conf (5)
.SH HISTORY
Rancid's looking glass is based on Ed Kern's (included by permission,
-thanks Ed!), which can be found on http://nitrous.digex.net/. Support
-for Junipers, rancid's device login scripts, and additional commands have
-been added to the original.
+thanks Ed!), which could once be found on http://nitrous.digex.net/ but
+has apparently been removed. Support for Juniper and Foundry devices,
+use of rancid's device login scripts, and additional commands and checks
+have been added to the original.
diff --git a/man/par.1 b/man/par.1
index b0f0cee..535246a 100644
--- a/man/par.1
+++ b/man/par.1
@@ -22,7 +22,7 @@ file
takes a list of files to run a command on. The first line of each file begins
with a colon (:) or a pound-sign (#). If a colon, the remainder of the
line is a command to run for each of the subsequent lines. If a pound-sign,
-then each subsequent line is command, unless the
+then each subsequent line is a command, unless the
.B \-c
option was specified, in which case it operates as if the argument to
.B \-c
@@ -60,7 +60,7 @@ The command-line options are as follows:
.PP
.TP
.B \-c
-Command to be run on each each of the arguments following the command-line
+Command to be run on each of the arguments following the command-line
options, when the first line of the input file(s) begin with a pound-sign
(#).
.\"
@@ -91,6 +91,12 @@ Default: 3
.TP
.B \-q
Quiet mode. Do not log anything.
+.B \-q
+is mutually exclusive with the
+.B \-x
+and
+.B \-l
+options and the option appearing last will take precedence.
.\"
.TP
.B \-x
diff --git a/util/README b/util/README
index 1a579d6..56d5673 100644
--- a/util/README
+++ b/util/README
@@ -1,8 +1,9 @@
rancid/util includes some utilities that either don't seem to belong
in rancid/bin (ie: not part of the core pkg), contributed sources, or
-sources included for convenience.
+sources included for convenience/example.
README This file.
+downreport Daily report of routers not listed as up in router.db
+getipacctg get and sort show ip accounting o/p from cisco router
lg looking glass pkg
rtrfilter mail filter for diffs
-downreport Daily report of routers not listed as up in router.db
diff --git a/util/getipacctg.in b/util/getipacctg.in
new file mode 100755
index 0000000..d77c919
--- /dev/null
+++ b/util/getipacctg.in
@@ -0,0 +1,103 @@
+#! /bin/sh
+#
+# getipacctg uses clogin to login to a cisco router, collect the o/p of
+# show ip accounting, and sort by the greatest number of bytes. if a
+# second argument is supplied, it is a number indicating the top N producers.
+# a third (3 to N) argument(s) specify a prefix(es) to match/select src/dst
+# IPs, while others will be filtered.
+#
+# usage: getipacctg <router name> [<number of lines off the top>] \
+# [<src/dest prefix filter> [...]]
+# example:
+# getipacctg router 25 192.168.0.0/24
+# will display the top 25 for src or dst ip's within prefix
+# 192.168.0.0/24
+#
+# contributed by steve neighorn.
+
+TMP="/tmp/ipacct.$$.prefixes"
+TMP2="/tmp/ipacct.$$.sorted"
+TMP3="/tmp/ipacct.$$.pl"
+
+if [ $# -eq 0 ] ; then
+ echo "usage: getipacctg router_name [<number of lines off the top>] [<src/dest prefix filter> [...]]" >&2
+ exit 1;
+fi
+
+trap 'rm -fr /tmp/ipacct.$$ $TMP $TMP2 $TMP3;' 1 2 15
+clogin -c 'show ip accounting' $1 > /tmp/ipacct.$$
+
+if [ $? -ne 0 ] ; then
+ echo "clogin failed." >&2
+ exit 1
+fi
+# rest of the command-line options
+exec 6>$TMP
+HEAD="cat"
+shift
+while [ $# -ne 0 ] ; do
+ echo $1 | grep '/' > /dev/null
+ if [ $? -eq 1 ] ; then
+ HEAD="head -$1"
+ else
+ echo $1 1>&6
+ fi
+ shift
+done
+6>&-
+
+egrep '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+ +[0-9]+\.[0-9]+\.' /tmp/ipacct.$$ | \
+ sed -e 's/^ *//' -e 's/ */ /g' -e 's/.$//' | \
+ awk '{print $4":"$0;}' | sort -nr | \
+ sed -e 's/^[^:]*://' > $TMP2
+
+if [ -s $TMP ] ; then
+cat > $TMP3 <<PERL
+ my(@prefs);
+ my(\$nprefs) = 0;
+ sub ip_to_int {
+ # Given xxx.xxx.xxx.xxx return corresponding integer.
+ my(\$int);
+ my(\$ip) = shift;
+ \$ip=~s/\s*//g;
+ \$ip =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\$/;
+ my (\$a,\$b,\$c,\$d) = (int(\$1),int(\$2),int(\$3),int(\$4));
+ return 0 + ((\$a << 24) + (\$b << 16) + (\$c << 8) + \$d) ;
+ }
+ open(PREFS, "< \$ARGV[0]") || die "could not open \$ARGV[0]\n";
+ while (<PREFS>) {
+ chomp;
+ s/\s*//g;
+ /(.*)\/(.*)\$/;
+ my(\$ip) = \$1; my(\$mask) = \$2;
+ \$ip = ip_to_int(\$ip);
+ \$mask = (~0) << (32 - \$mask);
+ \$ip = \$ip & (\$mask);
+ \$prefs[\$nprefs++] = \$ip;
+ \$prefs[\$nprefs++] = \$mask;
+ }
+ close(PREFS);
+ open(DATA, "< \$ARGV[1]") || die "could not open \$ARGV[1]\n";
+ while (<DATA>) {
+ chomp;
+ @A = split(/ /);
+ \$A[0] = ip_to_int(\$A[0]);
+ \$A[1] = ip_to_int(\$A[1]);
+ for (\$f = 0; \$f < \$nprefs; \$f += 2) {
+ if ((\$A[0] & \$prefs[\$f + 1]) == \$prefs[\$f] ||
+ (\$A[1] & \$prefs[\$f + 1]) == \$prefs[\$f]) {
+ print "\$_\n";
+ break;
+ }
+ }
+ }
+PERL
+ perl $TMP3 $TMP $TMP2 | $HEAD
+else
+ $HEAD $TMP2
+fi
+
+rm -fr /tmp/ipacct.$$ $TMP $TMP2 $TMP3
+trap ';' 1 2 15
+exit 0
+
diff --git a/util/lg/README b/util/lg/README
index 4546487..faa4120 100644
--- a/util/lg/README
+++ b/util/lg/README
@@ -1,4 +1,4 @@
-This is a looking glass based on Ed Kern's which can be found on
+This is a looking glass based on Ed Kern's which used to be available on
http://nitrous.digex.net/. This version supports cisco, juniper, and
foundry, using rancid's [cfj]login to login (so rcmd is not necessary,
it can use telnet, ssh, or rsh), and has some additional commands
@@ -18,7 +18,7 @@ the looking glass requires the CGI and LockFile-Simple perl modules.
these can be retrieved from CPAN, http://www.cpan.org/. CGI's home is
ftp://ftp-genome.wi.mit.edu/pub/software/WWW/. it also requires
the POSIX module (for strftime) and Sys::Syslog, which i believe come
-with perl5.
+with perl5 and/or are converted with h2ph(1).
basic installation instructions:
@@ -54,11 +54,13 @@ and install bits in /usr/local/rancid/util/lg (or <prefix>/util/lg).
DirectoryIndex lgform.cgi
2) the LG needs to be able to find and read lg.conf. by default this
- is installed as <PREFIX>/util/lg/lg.conf and the LG will look there.
- however, LG_CONF environment variable can be used to move it elsewhere.
+ is installed as <PREFIX>/util/lg/lg.conf and the LG will first look in
+ its CWD (current working directory) and then <PREFIX>/util/lg/lg.conf if
+ it does not exist in the CWD. However the LG_CONF environment variable can
+ be used to move it elsewhere.
- to get LG_CONF into the enviroment, you can SetEnvIf in apache's
- httpd.conf like this for example:
+ to get LG_CONF into the enviroment, you can use SetEnvIf in apache's
+ httpd.conf. for example:
SetEnvIf Request_URI "\/lg/.*.cgi" LG_CONF=/usr/local/util/lg/lg.conf
3) edit <PREFIX>/util/lg/lg.conf.
diff --git a/util/lg/lg.cgi.in b/util/lg/lg.cgi.in
index fe07c58..2921f72 100755
--- a/util/lg/lg.cgi.in
+++ b/util/lg/lg.cgi.in
@@ -1,6 +1,6 @@
#!@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/
+## is a single script and used to be available at http://nitrous.digex.net/
#
## Copyright (C) 1997-2001 by Henry Kilmer.
## All rights reserved.
@@ -39,6 +39,41 @@ my($LG_BGP_RT, $LG_CACHE_TIME, $LG_SINGLE, $LG_STRIP);
if (!defined($ENV{HOME})) { $ENV{HOME} = "."; }
+# note: the following functions are duplicated between lgform.cgi and lg.cgi
+# to avoid the need for module inclusion headaches from within a httpd context.
+# it is just easier to be self-contained.
+# SO, ANY CHANGES HERE SHOULD BE REFLECTED IN THE OTHER .cgi.
+
+# logging
+sub dolog
+{
+ my($level, $msg) = @_;
+
+ if (defined($LG_LOG) && $LG_LOG !~ /\//) {
+ openlog($me, "pid", $LG_LOG);
+ syslog($level, "%s", $msg);
+ closelog;
+ } else {
+ local(*LOG);
+ my($file);
+ if (defined($LG_LOG)) {
+ $file = $LG_LOG;
+ } else {
+ $file = "$cache_dir/lg.log";
+ }
+ # log date, hostname, query, addr
+ if (open(LOG, ">>$file") == 0) {
+ # stderr, if all else fails
+ printf(STDERR "[" . strftime("%a %b %e %H:%M:%S %Y", gmtime) .
+ "] could not open log file $file: $!\n");
+ printf(STDERR $msg);
+ } else {
+ printf(LOG $msg);
+ close(LOG);
+ }
+ }
+ return;
+}
# read LG configuration file
sub readconf
{
@@ -65,40 +100,101 @@ sub readconf
eval $cmds;
} else {
printf(STDERR "ERROR: couldn\'t open the configuration file: $conffile: $!\n");
- exit(255);
+ exit(1);
}
return;
}
-# logging
-sub dolog
+# read router.db file
+sub readrouters
{
- my($level, $msg) = @_;
+ my($rtrdb);
+ local(*RTR);
- if (defined($LG_LOG) && $LG_LOG !~ /\//) {
- openlog($me, "pid", $LG_LOG);
- syslog($level, "%s", $msg);
- closelog;
+ if (defined($LG_ROUTERDB)) {
+ $rtrdb = $LG_ROUTERDB;
} else {
- local(*LOG);
- my($file);
- if (defined($LG_LOG)) {
- $file = $LG_LOG;
+ $rtrdb = "$BASEDIR/util/lg/router.db";
+ }
+
+ if (! -f $rtrdb) {
+ my(@dirs, $dir);
+ # if the router.db file does not exist, try to compile the list from
+ # the rancid group router.db files.
+ local(*DIR);
+ if (! opendir(DIR, $BASEDIR)) {
+ dolog(LOG_ERR, "ERROR: couldn\'t read $BASEDIR: $!\n");
} else {
- $file = "$cache_dir/lg.log";
+ while ($dir = readdir(DIR)) {
+ next if ($dir =~ /^(\.|\.\.|CVS|bin|logs|util)$/);
+ push(@dirs, $dir) if (-d "$BASEDIR/$dir");
+ }
+ closedir(DIR);
+
+ foreach $dir (@dirs) {
+ if (! opendir(DIR, "$BASEDIR/$dir")) {
+ dolog(LOG_ERR, "ERROR: couldn\'t read $BASEDIR/$dir: $!\n");
+ next;
+ }
+ closedir(DIR);
+ next if (! -f "$BASEDIR/$dir/router.db");
+ if (open(RTR, "< $BASEDIR/$dir/router.db")) {
+ while (<RTR>) {
+ next if (/^\s*(#|$)/);
+ # fqdn:mfg:state
+ @record = split('\:', $_);
+ 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];
+ }
+ close(RTR);
+ } else {
+ dolog(LOG_ERR, "ERROR: couldn\'t open the router.db file: $BASEDIR/$dir/router.db: $!\n");
+ }
+ }
+ }
+ } else {
+ if (open(RTR, "< $rtrdb")) {
+ while (<RTR>) {
+ next if (/^\s*(#|$)/);
+ # fqdn:mfg:state
+ @record = split('\:', $_);
+ 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];
+ }
+ close(RTR);
+ } else {
+ dolog(LOG_ERR, "ERROR: couldn\'t open the router.db file: $rtrdb: $!\n");
+ exit(1);
}
- # log date, hostname, query, addr
- open(LOG,">>$file") ;
- printf(LOG "$msg");
- close(LOG);
}
+
return;
}
-# run commands on the router
+
+# the functions remaining are particular to lg.cgi.
+
+# return true if $router is a member of @rtrlist
+sub arraymember {
+ my($rtrlist) = shift;
+ my($router) = shift;
+ my($r);
+
+ foreach $r (@$rtrlist) {
+ $r = (split(':', $r))[0];
+ return(1) if ($r eq $router);
+ }
+
+ return(0);
+}
+# check reachability and lock file before attempting to connect to device
+# return non-zero on error.
sub DoRsh
{
my ($router, $mfg, $cmd, $arg) = @_;
my($ctime) = time();
+ my($val);
my($lckobj) = LockFile::Simple->make(-delay => $lock_int,
-max => $max_lock_wait, -hold => $max_lock_hold);
@@ -109,15 +205,20 @@ sub DoRsh
`$pingcmd $router 56 1`;
}
if ($?) {
- return ("$router is unreachable. Try again later.\n");
+ push(@results, "$router is unreachable. Try again later.\n");
+ print @results;
+ return(-1);
}
if (! $lckobj->lock("$cache_dir/$router")) {
- return ("$router is busy. Try again later.\n");
+ push(@results, "$router is busy. Try again later.\n");
+ print @results;
+ return(-1);
}
- @results = &DoCmd($router, $mfg, $cmd, $arg);
+ $val = &DoCmd($router, $mfg, $cmd, $arg);
$lckobj->unlock("$cache_dir/$router");
- return (@results);
+ return ($val);
}
+# run commands on the router. return non-zero on error.
sub DoCmd
{
my($rtr, $mfg, $cmd, $arg) = @_;
@@ -139,24 +240,60 @@ sub DoCmd
dolog(LOG_ERR, $_);
if ($LG_STRIP) { undef(@results); }
push(@results, $_);
- return (@results);
+ print @results;
+ return(-1);
}
push(@results, $_);
if (/$cmd/) {
($prompt) = /^(\S*)[\#>]/;
-# push(@results, "prompt = $prompt\n\n");
- if ($LG_STRIP) { undef(@results); }
+ if ($LG_STRIP) {
+ undef(@results);
+ } else {
+ print @results;
+ }
last;
}
}
+
while (<CMD>) {
last if /^$prompt[\#>]/;
tr/\015//d;
+ print $_;
push(@results, $_);
}
while (<CMD>) {}
close(CMD);
- return @results;
+
+ return(0);
+}
+# Subroutine: Error
+# Usage: &Error("msg"));
+# Description: displays an error and exits.
+##
+sub Error {
+ my($msg) = @_;
+
+ my($q) = new CGI();
+ print $q->header;
+ print $q->start_html("Looking Glass Error");
+
+ print "<BODY>";
+
+ # add the company image, LG_IMAGE
+ print $LG_IMAGE;
+
+
+ print <<EOF ;
+<br>
+<B><FONT SIZE=+2>Looking Glass Error:</FONT></B>
+<p>
+$msg
+<br>
+</body>
+EOF
+
+ print $q->end_html;
+ exit(0);
}
# convert a ipv4 address mask to prefix length
sub mask2len {
@@ -171,12 +308,24 @@ sub mask2len {
return($len);
}
-# create the page and log the transaction...
-sub print_results {
+# end the page and exit.
+sub end_page {
+
+ print <<END ;
+ </pre>
+ <!--- end page content --->
+ </body>
+END
+
+ print $query->end_html;
+ exit(0);
+}
+# start the page and log the transaction...
+sub start_page {
my($mfg) = @_;
my($cmd);
- my($timestr) = strftime("%a %b %e %H:%M:%S %Y %Z", gmtime);
+ my($timestr) = strftime("%a %b %e %H:%M:%S %Y", gmtime);
dolog(LOG_INFO, sprintf("%s %s %s %s\n",
$ENV{REMOTE_HOST}, $ENV{REMOTE_ADDR}, $ENV{REMOTE_USER},
"- - [$timestr] $type $router $arg"));
@@ -212,43 +361,35 @@ HEAD
if ($arg) { print "<b>Argument(s):</b> $arg\n"; }
print "</center>\n";
- print <<END ;
+ print <<END ;
<!--$cached-->
</center>
<p>
<pre>
END
- if ($seconds) { print "<b>From cache (number of seconds old (max $max_time_diff)):</b> $seconds\n\n" ; }
-
- print @results;
-
- print <<END ;
- </pre>
- <!--- end page content --->
- </body>
-END
-
- print $query->end_html;
- exit;
-
-} #end sub print_results
+ return;
+} #end sub start_page
+# Main()
# read the configuration file if it exists.
readconf();
## The script will now cache the results as simple files in the $cache_dir,
-## named after the type of query (queries must, of course, be one word no
+## named after the type of query (queries must, of course, be one word no
## spaces). Modify $max_time_diff to set the lifetime for each cache.
## Currently, cache lifetime is the same for all queries.
-# for most web servers, cache_dir must be writable by uid nobody
+# for most web servers, cache_dir must be writable by uid nobody
if (defined($LG_CACHE_DIR)) {
$cache_dir = $LG_CACHE_DIR;
} else {
$cache_dir = "./tmp";
}
+# read routers table to get @rtrlist
+readrouters();
+
# when to display cache? max time difference (in seconds)
if (defined($LG_CACHE_TIME)) {
$max_time_diff = $LG_CACHE_TIME;
@@ -279,15 +420,23 @@ $arg = ($query->param('args'))[0];
$arg =~ s/["'`]//g; # these are BS in any arg for any query
@arg = split(' ', $arg);
-# verify commands, arguments, etc.
+# verify router, commands, arguments, etc.
($router, $mfg) = split(':', $router_param);
if (!defined($type) || !defined($router)) {
$results[0] = "You must at least choose a Query and a router. Try buying a clue.\n";
- &print_results($mfg);
+ &Error("You must at least choose a Query and a router. Try buying a clue.\n");
+}
+
+if (! arraymember(\@rtrlist, $router)) {
+ my($timestr) = strftime("%a %b %e %H:%M:%S %Y", gmtime);
+ dolog(LOG_WARNING, sprintf("%s %s %s %s\n",
+ $ENV{REMOTE_HOST}, $ENV{REMOTE_ADDR}, $ENV{REMOTE_USER},
+ "- - [$timestr] lg.cgi: attempt to access $router\n"));
+ Error("access to $router not permitted");
}
# conversion of command "type" passed from lgform.cgi to the vendor's syntax.
-%ciscoCmd = (
+%ciscoCmd = (
#acl => "show access-list",
#aspath => "show ip as-path-access-list",
#communitylist => "show ip community-list",
@@ -309,7 +458,7 @@ if (!defined($type) || !defined($router)) {
summary => "show ip bgp summary",
trace => "traceroute"
);
-%foundryCmd = (
+%foundryCmd = (
#acl => "show access-list",
#aspath => "show ip as-path-access-list",
#communitylist => "show ip community-list",
@@ -330,7 +479,7 @@ if (!defined($type) || !defined($router)) {
summary => "show ip bgp summary",
trace => "traceroute"
);
-%juniperCmd = (
+%juniperCmd = (
#acl => "show access-list",
#aspath => "show ip as-path-access-list",
#communitylist => "show ip community-list",
@@ -351,7 +500,7 @@ if (!defined($type) || !defined($router)) {
summary => "show bgp summary",
trace => "traceroute"
);
-%cmdDisp = (
+%cmdDisp = (
#acl => "show access-list",
#aspath => "show ip as-path-access-list",
#communitylist => "show ip community-list",
@@ -376,37 +525,34 @@ if (!defined($type) || !defined($router)) {
# not all cmds/queries are implemented for junipers
if ($mfg =~ /juniper/) {
if (! defined($juniperCmd{$type})) {
- $results[0] = "$cmdDisp{$type} not implemented for junipers. sorry.\n";
- &print_results($mfg);
+ Error("$cmdDisp{$type} not implemented for junipers. sorry.\n");
}
$cmd = $juniperCmd{$type};
} elsif ($mfg =~ /foundry/) {
if(! defined($foundryCmd{$type})) {
- $results[0] = "$cmdDisp{$type} not implemented for foundrys. sorry.\n";
- &print_results($mfg);
+ Error("$cmdDisp{$type} not implemented for foundrys. sorry.\n");
}
$cmd = $foundryCmd{$type};
} else {
+ if(! defined($ciscoCmd{$type})) {
+ Error("$cmdDisp{$type} not implemented for cisco. sorry.\n");
+ }
$cmd = $ciscoCmd{$type};
}
-
if ($type eq "prefix" || $type eq "mbgp" || $type eq "route" ) {
if ($arg[0] !~ /^\d+\.\d+\.\d+\.\d+$/) {
- $results[0] = "The IP address \"$arg[0]\" is not valid and lacking an address would over-burden our router.\n";
- &print_results($mfg);
+ &Error("The IP address \"$arg[0]\" is not valid and lacking an address would over-burden our router.\n");
} elsif (defined($arg[1]) && $arg[1] !~ /^\d+\.\d+\.\d+\.\d+$/) {
- $results[0] = "The IP netmask \"$arg[1]\" is not valid.\n";
- &print_results($mfg);
+ &Error("The IP netmask \"$arg[1]\" is not valid.\n");
}
if ($mfg =~ /juniper/i && defined($arg[1])) {
$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($mfg);
+ &Error("Juniper does not have a show frame-relay pvc command. " .
+ "Use show interface.\n");
}
if ($arg[0] > 15 && $arg[0] < 1024) {
$arg = $arg[0];
@@ -459,30 +605,27 @@ if ($type eq "prefix" || $type eq "mbgp" || $type eq "route" ) {
} elsif ($type eq "ping" || $type eq "trace") {
if ($arg[0] !~ /^\d+\.\d+\.\d+\.\d+$/) {
if ($arg[0] !~ /^[A-Za-z0-9._-]+$/) {
- $results[0] = "That argument ($arg[0]) is not valid.\n";
- &print_results($mfg);
+ &Error("That argument ($arg[0]) is not valid.\n");
}
}
$arg = $arg[0];
} elsif ($type eq "aspath" || $type eq "communitylist") {
if ($arg[0] !~ /^\d+$/ || ($arg[0] < 1 && $arg[0] > 199)) {
- $results[0] = "That argument ($arg[0]) is not valid.\n";
- &print_results($mfg);
+ &Error("That argument ($arg[0]) is not valid.\n");
}
$arg = $arg[0];
} elsif ($type eq "acl") {
if ($arg[0] !~ /^\d+$/ || ($arg[0] < 100 && $arg[0] > 199) ||
($arg[0] < 1300 && $arg[0] > 2699)) {
- $results[0] = "That argument ($arg[0]) is not valid.\n";
- &print_results($mfg);
+ &Error("That argument ($arg[0]) is not valid.\n");
}
$arg = $arg[0];
# don't show the jewels
- &print_results($mfg) if ($arg == 98 || $arg == 99);
+ # XXX: this error msg is useless, but show acl is un-implemented.
+ &Error($mfg) if ($arg == 98 || $arg == 99);
} elsif ($type eq "prefixlist" || $type eq "routemap") {
if ($arg[0] !~ /^[0-9A-Za-z][^\s\"]*$/) {
- $results[0] = "That argument ($arg[0]) is not valid.\n";
- &print_results($mfg);
+ &Error("That argument ($arg[0]) is not valid.\n");
}
$arg = $arg[0];
} elsif ($type eq "regex") {
@@ -493,14 +636,13 @@ if ($type eq "prefix" || $type eq "mbgp" || $type eq "route" ) {
# 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($mfg);
+ &Error("That argument ($arg[0]) is not valid.\n");
}
# pathetic excuses for lookups
if ($arg =~ /^[_.* ^]*(\*|1|701|1239|1280|1740|3561|5462|10303)+[_\$]*$/ ||
$arg =~ /^[_.* ^]*(1|701|1239|1280|1740|3561|5462|10303)+[_ .]*[\[*.]/) {
- $results[0] = "Get real. Such a query has potential to over-burden our router.\nLook that up on your own router.\n";
- &print_results($mfg);
+ &Error("Get real. Such a query has potential to over-burden our " .
+ "router.\nLook that up on your own router.\n");
}
if ($mfg =~ /juniper/) {
$arg =~ s/_/ /g;
@@ -517,8 +659,7 @@ if ($type eq "prefix" || $type eq "mbgp" || $type eq "route" ) {
} 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($mfg);
+ &Error("That argument ($arg[0]) is not valid.\n");
}
}
$arg = $arg[0];
@@ -554,8 +695,7 @@ if ($type eq "prefix" || $type eq "mbgp" || $type eq "route" ) {
} 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($mfg);
+ &Error("That argument ($arg[0]) is not valid.\n");
}
}
$arg = $arg[0];
@@ -586,46 +726,58 @@ if ($type eq "prefix" || $type eq "mbgp" || $type eq "route" ) {
undef($arg);
}
+# make stdout unbuffered, so result page streams.
+$| = 1;
+start_page();
+
# cache the following
-if ($type eq "summary" || $type eq "mbgpsu" || $type eq "damp" || $type eq "log") {
+if ($type eq "summary" || $type eq "mbgpsu" || $type eq "damp"
+ || $type eq "log") {
if (!$arg) {
# cache requests with no addr/argument
local(*CACHE);
- my($file) = "$cache_dir/$type" ;
+ my($file) = "$cache_dir/$type" ;
$file =~ s/\s+/_/g;
$file .= "_$router";
if (-e $file) {
# see if cache exists
- @stat = stat($file);
- $ftime = $stat[9] ;
- $dtime = time - $stat[9] ;
+ @stat = stat($file);
+ $ftime = $stat[9];
+ $dtime = time() - $stat[9];
- # see if we are within cache time
+ # see if we are within cache time
if ($dtime <= $max_time_diff) {
- open(CACHE,"$file") ;
- while (<CACHE>) { push(@results, $_); }
- close CACHE ;
- $seconds = $dtime;
- &print_results($mfg);
+ if (open(CACHE, "<$file") == 0) {
+ dolog(LOG_ERR, "couldnt open cache file $file: $!\n");
+ } else {
+ print "<b>From cache (number of seconds old (max " .
+ "$max_time_diff)):</b> $dtime\n\n";
+ while (<CACHE>) { print $_; }
+ close(CACHE);
+ &end_page();
+ }
}
}
# else, execute command and save to a new cache file
- open(CACHE,">$file") || die "couldnt create cache file $file" ;
-
- @results = &DoRsh($router, $mfg, $cmd, $arg);
-
- print CACHE "@results";
- close CACHE ;
+ if (! &DoRsh($router, $mfg, $cmd, $arg)) {
+ if (open(CACHE, ">$file") == 0) {
+ dolog(LOG_ERR, "couldnt create cache file $file: $!\n");
+ exit(1);
+ } else {
+ printf(CACHE "@results");
+ close(CACHE);
+ }
+ }
} else {
- @results = &DoRsh($router, $mfg, $cmd, $arg);
+ &DoRsh($router, $mfg, $cmd, $arg);
}
- &print_results($mfg);
-} # end dampened-paths/flap-statistics
-
-@results = &DoRsh($router, $mfg, $cmd, $arg);
-&print_results($mfg);
+ &end_page();
+} else {
+ &DoRsh($router, $mfg, $cmd, $arg);
+ &end_page();
+}
-exit;
+exit(0);
diff --git a/util/lg/lgform.cgi.in b/util/lg/lgform.cgi.in
index 3ea6856..97a0c71 100755
--- a/util/lg/lgform.cgi.in
+++ b/util/lg/lgform.cgi.in
@@ -20,7 +20,41 @@ use CGI qw/:standard/;
my(@rtrlist, %rtrlabels);
my($BASEDIR) = "@prefix@";
+# note: the following functions are duplicated between lgform.cgi and lg.cgi
+# to avoid the need for module inclusion headaches from within a httpd context.
+# it is just easier to be self-contained.
+# SO, ANY CHANGES HERE SHOULD BE REFLECTED IN THE OTHER .cgi.
+# logging
+sub dolog
+{
+ my($level, $msg) = @_;
+
+ if (defined($LG_LOG) && $LG_LOG !~ /\//) {
+ openlog($me, "pid", $LG_LOG);
+ syslog($level, "%s", $msg);
+ closelog;
+ } else {
+ local(*LOG);
+ my($file);
+ if (defined($LG_LOG)) {
+ $file = $LG_LOG;
+ } else {
+ $file = "$cache_dir/lg.log";
+ }
+ # log date, hostname, query, addr
+ if (open(LOG, ">>$file") == 0) {
+ # stderr, if all else fails
+ printf(STDERR "[" . strftime("%a %b %e %H:%M:%S %Y", gmtime) .
+ "] could not open log file $file: $!\n");
+ printf(STDERR $msg);
+ } else {
+ printf(LOG $msg);
+ close(LOG);
+ }
+ }
+ return;
+}
# read LG configuration file
sub readconf
{
@@ -47,7 +81,7 @@ sub readconf
eval $cmds;
} else {
printf(STDERR "ERROR: couldn\'t open the configuration file: $conffile: $!\n");
- exit(255);
+ exit(1);
}
return;
@@ -66,11 +100,11 @@ sub readrouters
if (! -f $rtrdb) {
my(@dirs, $dir);
- # if the router.db file does not exist, try to compile from
- # the rancid group's router.db files.
+ # if the router.db file does not exist, try to compile the list from
+ # the rancid group router.db files.
local(*DIR);
if (! opendir(DIR, $BASEDIR)) {
- printf(STDERR "ERROR: couldn\'t read $BASEDIR: $!\n");
+ dolog(LOG_ERR, "ERROR: couldn\'t read $BASEDIR: $!\n");
} else {
while ($dir = readdir(DIR)) {
next if ($dir =~ /^(\.|\.\.|CVS|bin|logs|util)$/);
@@ -80,7 +114,7 @@ sub readrouters
foreach $dir (@dirs) {
if (! opendir(DIR, "$BASEDIR/$dir")) {
- printf(STDERR "ERROR: couldn\'t read $BASEDIR/$dir: $!\n");
+ dolog(LOG_ERR, "ERROR: couldn\'t read $BASEDIR/$dir: $!\n");
next;
}
closedir(DIR);
@@ -96,7 +130,7 @@ sub readrouters
}
close(RTR);
} else {
- printf(STDERR "ERROR: couldn\'t open the router.db file: $BASEDIR/$dir/router.db: $!\n");
+ dolog(LOG_ERR, "ERROR: couldn\'t open the router.db file: $BASEDIR/$dir/router.db: $!\n");
}
}
}
@@ -112,14 +146,15 @@ sub readrouters
}
close(RTR);
} else {
- printf(STDERR "ERROR: couldn\'t open the router.db file: $rtrdb: $!\n");
- exit(255);
+ dolog(LOG_ERR, "ERROR: couldn\'t open the router.db file: $rtrdb: $!\n");
+ exit(1);
}
}
return;
}
+# Main()
# read the configuration file if it exists.
readconf();
@@ -207,4 +242,4 @@ TAIL
print $query->end_html;
-exit 0;
+exit(0);