summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTar Committer <tar@ocjtech.us>2004-01-12 03:17:26 +0000
committerTar Committer <tar@ocjtech.us>2004-01-12 03:17:26 +0000
commit989312339ea2e16579803a48700628c5469e327a (patch)
tree967ee77195819d70f2dc675444e92340bb98e0d6
parentff168ecfe045c690c24d5bbc5a3062bf9d64120c (diff)
downloadrancid-989312339ea2e16579803a48700628c5469e327a.zip
rancid-989312339ea2e16579803a48700628c5469e327a.tar.gz
rancid-989312339ea2e16579803a48700628c5469e327a.tar.xz
Imported from rancid-2.3.rc1.tar.gz.rancid-2.3.rc1
-rw-r--r--CHANGES161
-rw-r--r--COPYING22
-rw-r--r--FAQ143
-rw-r--r--Makefile.am51
-rw-r--r--Makefile.in637
-rw-r--r--README132
-rw-r--r--README.lg79
-rw-r--r--Todo74
-rw-r--r--UPGRADING85
-rw-r--r--acconfig.h78
-rw-r--r--aclocal.m41080
-rw-r--r--bin/Makefile.am103
-rw-r--r--bin/Makefile.in746
-rw-r--r--bin/alogin.in84
-rw-r--r--bin/arancid.in25
-rw-r--r--bin/blogin.in85
-rw-r--r--bin/brancid.in20
-rw-r--r--[-rwxr-xr-x]bin/cat5rancid.in31
-rw-r--r--[-rwxr-xr-x]bin/clogin.in156
-rw-r--r--[-rwxr-xr-x]bin/control_rancid.in79
-rw-r--r--bin/cssrancid.in660
-rw-r--r--[-rwxr-xr-x]bin/elogin.in44
-rw-r--r--bin/env.in48
-rw-r--r--[-rwxr-xr-x]bin/erancid.in23
-rw-r--r--[-rwxr-xr-x]bin/f10rancid.in31
-rw-r--r--[-rwxr-xr-x]bin/flogin.in95
-rw-r--r--bin/fnrancid.in275
-rw-r--r--[-rwxr-xr-x]bin/francid.in25
-rw-r--r--[-rwxr-xr-x]bin/hlogin.in92
-rw-r--r--bin/hpuifilter.c (renamed from bin/hpfilter.c)29
-rw-r--r--[-rwxr-xr-x]bin/hrancid.in32
-rw-r--r--bin/htlogin.in492
-rw-r--r--bin/htrancid.in266
-rw-r--r--bin/jerancid.in645
-rw-r--r--[-rwxr-xr-x]bin/jlogin.in50
-rw-r--r--[-rwxr-xr-x]bin/jrancid.in102
-rw-r--r--[-rwxr-xr-x]bin/lg.cgi.in (renamed from util/lg/lg.cgi.in)334
-rw-r--r--[-rwxr-xr-x]bin/lgform.cgi.in (renamed from util/lg/lgform.cgi.in)116
-rw-r--r--[-rwxr-xr-x]bin/mrancid.in30
-rw-r--r--bin/nlogin.in524
-rw-r--r--bin/nrancid.in302
-rw-r--r--bin/nslogin.in642
-rw-r--r--bin/nsrancid.in313
-rw-r--r--[-rwxr-xr-x]bin/par.in17
-rwxr-xr-xbin/prancid.in569
-rw-r--r--[-rwxr-xr-x]bin/rancid-cvs.in (renamed from bin/create_cvs.in)27
-rw-r--r--[-rwxr-xr-x]bin/rancid-fe.in51
-rw-r--r--[-rwxr-xr-x]bin/rancid-run.in (renamed from bin/do-diffs.in)36
-rw-r--r--[-rwxr-xr-x]bin/rancid.in445
-rwxr-xr-xbin/rename.in113
-rw-r--r--bin/rivlogin.in1005
-rw-r--r--bin/rivrancid.in344
-rw-r--r--[-rwxr-xr-x]bin/rrancid.in23
-rw-r--r--bin/tntlogin.in528
-rw-r--r--bin/tntrancid.in292
-rw-r--r--[-rwxr-xr-x]bin/xrancid.in64
-rwxr-xr-xbin/zrancid.in411
-rw-r--r--cloginrc.sample16
-rwxr-xr-xconfigure8383
-rw-r--r--configure.in122
-rwxr-xr-xdepcomp520
-rw-r--r--etc/Makefile.am77
-rw-r--r--etc/Makefile.in375
-rw-r--r--etc/lg.conf.sample.in188
-rw-r--r--etc/rancid.conf.sample.in59
-rw-r--r--include/Makefile.am24
-rw-r--r--include/Makefile.in411
-rw-r--r--include/config.h165
-rw-r--r--include/config.h.in143
-rw-r--r--include/stamp-h.in1
-rw-r--r--include/version.h2
-rw-r--r--include/version.h.in2
-rwxr-xr-xinstall-sh443
-rw-r--r--man/Makefile.am71
-rw-r--r--man/Makefile.in444
-rw-r--r--man/clogin.159
-rw-r--r--man/cloginrc.557
-rw-r--r--man/control_rancid.112
-rw-r--r--man/cssrancid.11
-rw-r--r--man/fnrancid.11
-rw-r--r--man/htlogin.11
-rw-r--r--man/htrancid.11
-rw-r--r--man/jerancid.11
-rw-r--r--man/lg.conf.5.in45
-rw-r--r--man/lg_intro.1.in2
-rw-r--r--man/nlogin.11
-rw-r--r--man/nrancid.11
-rw-r--r--man/nslogin.11
-rw-r--r--man/nsrancid.11
-rw-r--r--man/par.110
-rw-r--r--man/prancid.11
-rw-r--r--man/rancid-cvs.1 (renamed from man/create_cvs.1)24
-rw-r--r--man/rancid-run.1 (renamed from man/do-diffs.1)36
-rw-r--r--man/rancid.148
-rw-r--r--man/rancid.conf.5.in (renamed from man/env.5.in)93
-rw-r--r--man/rancid_intro.152
-rw-r--r--man/rivlogin.11
-rw-r--r--man/rivrancid.11
-rw-r--r--man/router.db.551
-rw-r--r--man/tntlogin.11
-rw-r--r--man/tntrancid.11
-rw-r--r--man/zrancid.11
-rwxr-xr-xmissing212
-rwxr-xr-xmkinstalldirs149
-rw-r--r--share/Makefile.am53
-rw-r--r--share/Makefile.in401
-rw-r--r--share/README.misc24
-rw-r--r--share/cisco-load.exp (renamed from util/cisco-load.exp)19
-rw-r--r--share/cisco-reload.exp (renamed from util/cisco-reload.exp)18
-rw-r--r--share/downreport.in81
-rw-r--r--[-rwxr-xr-x]share/getipacctg (renamed from util/getipacctg.in)34
-rw-r--r--share/index.html (renamed from util/lg/index.html)3
-rw-r--r--share/lgnotes.html (renamed from util/lg/lgnotes.html)0
-rw-r--r--[-rwxr-xr-x]share/rtrfilter.in (renamed from util/rtrfilter.in)22
-rw-r--r--util/Makefile.in37
-rw-r--r--util/README9
-rwxr-xr-xutil/configure990
-rw-r--r--util/configure.in26
-rwxr-xr-xutil/downreport.in62
-rw-r--r--util/lg/Makefile.in43
-rw-r--r--util/lg/README76
-rwxr-xr-xutil/lg/configure991
-rw-r--r--util/lg/configure.in27
-rw-r--r--util/lg/lg.conf.in105
-rw-r--r--util/rtrfilter.README14
125 files changed, 21151 insertions, 7161 deletions
diff --git a/CHANGES b/CHANGES
index 2795e3f..fb139cf 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,156 @@
+2.3.rc1
+ The following files have been moved to make rancid more
+ install/pkg/port/rpm friendly.
+ *** bin/env has been moved to etc/rancid.conf ***
+ *** bin/hpfilter has been renamed hpuifilter ***
+ *** util/lg/lg.conf has been moved to etc/lg.conf ***
+ *** util/lg/lg*.cgi have been moved to bin/lg*cgi ***
+ Note: existing configuration files are *NOT* copied/moved for you
+
+ bin/rename is no longer shipped with rancid
+
+ rancid.conf: add LOGDIR variable - see rancid.conf(5)
+
+ rancid: add show spe version and parse FRU show diag output
+ - from Yuval Ben-Ari.
+
+ add option --enable-adminmail-plus to configure
+
+ jrancid: collect show chassis alarms
+
+ rancid: skip show vlan for (3550|4500|7600) - from Andrew Fort
+
+ rancid: collect 6500 slave sup bootflash - from Andrew Fort
+
+ rancid: show diag updates for 1700, 3700, etc - help from Michael Haba
+
+ The Extreme does not have an 'enable' level, so make sure
+ you have 'set autoenable' for it in your .cloginrc so clogin
+ will work.
+
+ add Cisco CSS support - from Wedge Martin
+
+ *login: add cloginrc sshcmd directive - idea from steve neighorn
+
+ rancid: IOS show version changes w/ 12.3 - from Yuval Ben-Ari
+
+ support for hitachi routers - from Mohacsi Janos
+
+ strip WS around router.db fields - from Alastair Galloway
+
+ add goveling of 2600 mainboard port adapter info
+
+ *login: also check LOGNAME for default username - from Fredrik Thulin
+
+ jerancid: add matches for "Please wait" to all functions -
+ reported by Dave Mack
+
+ fnrancid: Fortigate support - from D. Pfleger
+
+ nlogin: Fix prompt groveling when running a cluster - from D. Pfleger
+
+ nrancid: filter "set admin user" - from D. Pfleger
+
+ rancid: do both 'write term' and 'show running-config' and
+ keep the output from the first one that works. As cisco
+ phases out 'write term', this will keep things working.
+
+ jerancid: filter host ... ftp, encrypted passwords oscillate - reported
+ by Dave Mack.
+
+ rivlogin: add "User:" as a possible username prompt (u_prompt) for
+ some platforms - from Adam Rothschild
+
+ cat 3500 s/n and pix failover license - from Rob Evans
+
+ recognize cisco ContentEngine - from Rob Evans
+
+ Juniper ERX (jerancid) support, based on 5.0 - thanks to Dan Pfleger,
+ Richard Russman, Zaid, Mike Baker, and Mark Nguyen
+
+ rancid: drop the "suggested action" portion of GSR LC/RP ROM upgrade
+ warnings. Cisco keeps changing the format; it just is not worth the
+ aggrevation.
+
+ study causes missed command somehow in redhat9 - from David King
+
+ filter port security mac entries, from Arnold Nipper
+
+ add Procket Networks support, "prancid"
+
+ filter ipsec keys in rancid & jrancid.
+
+ rancid: collect show idprom backplane (6500 cmd); this could collect
+ more - request from jared mauch
+
+ rancid: order all 'ip host' commands.
+
+ rancid: collect show rsp chassis-info
+
+ rancid: filter HSRP auth and SSA key-string reversable passwords
+
+ lg: set query/command list in lg.conf, thus allowing individual cmds
+ to {dis,en}abled, and add some multicast and ipv6 queries all of which
+ are disabled by default (for lack of testing) - from Janos Mohacsi
+
+ cat5rancid: collect 'write term all' for cats that support it - tested
+ by terry kennedy and joe rizzo
+
+ cat5rancid: regularize escaping of regex operators in switch prompt
+
+ nsrancid: include "get log setting", as suggested by gael canal.
+
+ add manpage note about log_user with -s, from mail list discussion
+
+ xrancid: Handle end of ssh connection a bit better.
+
+ jrancid: skip master/backup re msgs
+
+ *rancid: escape regex chars found in prompt
+
+ xrancid: also collect 'show configuration detail'
+
+ hlogin: allow the port to be specified for method ssh and
+ add path to hlogin to env(PATH) for locating hpfilter
+
+ hpfilter: allow >2 arguments so that telnet port number can be passed.
+
+ rancid: gsr RP slot warning is only 1 line - Russell Heilling
+
+ add zrancid to handle zebra routing s/w
+
+ add riverstone support - from Jim Meehan. thanks to Hong Luo for
+ access to a riverstone to test. Kevin Chan reports that this works
+ for Cabletron routers with more recent s/w (~v9.0.3).
+
+ jrancid: fix handling of reversible keys such that trailing text is
+ not removed
+
+ rancid: slave/redundancy stuff - from stephen griffin
+
+ rancid: show version bootstrap format changed in 12.0(23)S
+
+ rancid: make sure we filter PIX pager prompts
+
+ xrancid: make xrancid work when the extreme has pending changes.
+
+ netscaler support - from Anshuman Kanwar.
+
+ netscreen firewall support - from Stephen Gill
+
+ rancid: include additional cpu info from show version in !CPU: line.
+
+ lucent tnt support - from Richard Vander Reyden
+
+ rancid: skip consecutive comment lines. on some access servers the
+ number of comment lines oscillate.
+
+ lg.conf: add LG_STYLE variable for style sheet - from Janos Mohacsi
+
+ also install the FAQ - good idea from Janos Mohacsi's freshport
+
+ rancid: filter 'cable shared-secret'
+
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.
@@ -77,7 +230,7 @@
alogin: misplaced brace caused improper return from proc login
relax the check ping and traceroute check of hostname arguments such
- that non-fqdn hosts are allowed. ie: just check that arg chars are
+ that non-fqdn hosts are allowed. i.e.: just check that arg chars are
valid dns chars and leave the resolve errors to the router.
Add initial support for Force10.
@@ -217,9 +370,9 @@
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:
+ add -Evar=x option to pass variables to scripts. e.g.:
clogin -Evariable=something router...
- clogin -Evariable=a,b,c [ie: an array/list which user splits]
+ clogin -Evariable=a,b,c [i.e.: an array/list which user splits]
2.2b2
fix jlogin's password/userpassword functionality which broke when
@@ -277,7 +430,7 @@
add man pages
- collect 'sh vlan' on cat 6000 - afort@staff.webcentral.com.au
+ collect 'sh vlan' on cat 6000 - afort@choqolat.org
Add 'show vtp status' for the 3500XLs as well.
diff --git a/COPYING b/COPYING
index 639e792..888b207 100644
--- a/COPYING
+++ b/COPYING
@@ -1,18 +1,22 @@
##
-## Copyright (C) 1997-2001 by Henry Kilmer, Erik Sherk and Pete Whiting.
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
+##
+#
+# The login expect scripts were based on Erik Sherk's gwtn, by permission.
+#
+# bin/lg - the original looking glass software was written by Ed Kern,
+# provided by permission and modified beyond recognition.
diff --git a/FAQ b/FAQ
index 7cda952..210700e 100644
--- a/FAQ
+++ b/FAQ
@@ -1,20 +1,65 @@
-Frequently Asked Questions about rancid - last updated 20011121.
+Frequently Asked Questions about rancid - last updated 20040107.
+
+This FAQ contains information that may not apply directly to versions of
+rancid prior to 2.3. It also contains paths containing tags such as
+<PREFIX>, which refer to paths that are site-specific and are determined
+by how rancid is or was configured at installation time. These are explained
+briefly in the configure --help output. Below are the defaults used in
+rancid.
+
+ PREFIX configure --prefix= option. default: /usr/local/rancid
+ EPREFIX configure --exec-prefix= option. default: <PREFIX>
+ BINDIR configure --bindir= option. default: <EPREFIX>/bin
+ The location of clogin, etc.
+ SYSCONFDIR configure --sysconfdir option. default: <PREFIX>/etc
+ The location of rancid.conf, etc.
+ LOCALSTATEDIR configure --localstatedir option. default: <PREFIX>/var
+ The location of the CVS repository, log files, etc.
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.
+A. A catalyst running IOS is type "cisco". The 'show version' output will
+ have banner including a phrase similar to "Cisco Internetwork Operating
+ System Software". See the router.db(5) manual page.
+
+Q. I have Hybrid Cisco switch, like a cat5k with an RSM. How do I collect
+ both the routing engine and switch configurations?
+A. Recommended way is to use two entries in the router.db, one for each.
+ For example:
+ cat5k_rsm.domain.com:cisco:up
+ cat5k_sw.domain.com:cat5:up
Q. I have a Cisco ??? on which collection stopped working, but clogin works
as expected.
A. Check if 'write term' produces output. Some IOS combined with large
configs and low free memory produce zero 'write term' output, esp. combined
- with a memory leak. The device will have to be rebooted or upgraded.
+ with a memory leak. The device will have to be rebooted and/or upgraded.
+
+Q. I have a Cisco Catalyst switch. clogin connects, but after receiving the
+ prompt, it stalls until it times out. Why?
+A. This may be due to your prompt. CatOS does not include an implicit '>' in
+ it's prompt, like IOS does. clogin looks for '>' during login, so specify
+ your prompt with a trailing '>'. Also see cat5rancid(1). For example:
+ cat5k>
+ cat5k> enable
+ Password:
+ cat5k> (enable)
+
+Q. Polling a ZebOS box fails from cron, but is successful from the command-
+ line.
+A. This is the tty/pty handling of either your O/S or ZebOS. Supposedly,
+ changing the TERM in <SYSCONFDIR>/rancid.conf to the following seems to
+ fix it.
+ TERM=vt100;export TERM
+ COLUMNS=160; LINES=48; export COLUMNS LINES
2) CVS and filesystem permissions
+ WARNING: Be careful when mucking around with the repository!
+
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
@@ -23,31 +68,31 @@ A. The manual page for CVS is quite complete, but can be be overwhelming even
Q. Errors are showing up in the logs like:
cvs [diff aborted]: there is no version here; run 'cvs checkout' first
A. The directory was not imported into CVS properly or was not properly checked
- out afterward, so CVS control files or directories do not exist. create_cvs
+ out afterward, so CVS control files or directories do not exist. rancid-cvs
should always be used to create the directories and perform the CVS work.
If it is just the directories that have been created manually, save a copy of
- the router.db file, then remove the group's directory, use create_cvs, and
+ the router.db file, then remove the group's directory, use rancid-cvs, and
replace the router.db file. If the CVS import was also performed manually,
- cd to <BASEDIR> and use 'cvs co <rancid group>' to create all the CVS
+ cd to <LOCALSTATEDIR> and use 'cvs co <rancid group>' to create all the CVS
control bits.
Q. I keep receiving the same diff for a (or set of) devices, but I know the
data is not changing repeatedly. Why?
-A. This is most likely either a CVS or filesystem permissions problem. Check
- the log file from the last run for that group first; it may provide the
+A. This is probably a CVS or filesystem permissions problem. Check the log
+ file from the last run for that group for clues 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:
+ Check the cvs status of the device's file. example:
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
+ Repository revision: 1.197 /usr/local/rancid/var/CVS/shrubbery/configs/rtr.shrubbery.net,v
Sticky Tag: (none)
Sticky Date: (none)
Sticky Options: (none)
@@ -55,19 +100,20 @@ A. This is most likely either a CVS or filesystem permissions problem. Check
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.
+ run rancid-run, replace the entry in router.db, and run rancid-run 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 chown -R <rancid user> /usr/local/rancid/CVS
+ directory and file in the cvs repository (<LOCALSTATEDIR>/CVS/). They
+ should be owned by the user who runs rancid-run 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 <SYSCONFDIR>/rancid.conf. Likely the easiest way to fix the
+ ownership on the cvs repository is
+ chown -R <rancid user> <LOCALSTATEDIR>/CVS <LOCALSTATEDIR>/<GROUPS>
Q. I am renaming a device but would like the retain the history in CVS. How
is this done?
@@ -75,11 +121,11 @@ 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
+ % cd <LOCALSTATEDIR>
% 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.
+ where GROUP is the name of the rancid group that 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.
@@ -88,13 +134,23 @@ A. CVS does not provide a way (AFAIK) to rename files or to rename or delete
history, the same procedure would work. Substituting the new group name
appropriately.
+Q. I am removing a group and would like to remove all traces of it from the
+ rancid directory and the CVS repository. How is this done?
+A. As far as I know, CVS does not provide a way to remove directories. First,
+ remove the group from <SYSCONFDIR>/rancid.conf. If rancid is running,
+ wait for it to complete. Then just recursively remove the
+ directory. For example, a group named "fubar":
+ % su - rancid_user
+ % cd <LOCALSTATEDIR>
+ % rm -rf fubar CVS/fubar
+
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.
+ - Make sure that the appropriate *login (example: 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, your banner does
not have some character that *login does not like, and that the *login
@@ -103,7 +159,7 @@ A. Our usual diagnostic procedure for this is:
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).
+ use normally, as if clogin were not used (i.e.: 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:
@@ -129,8 +185,8 @@ A. Our usual diagnostic procedure for this is:
router.db file is correct and check the group's last log file for errors.
Q. Are there any characters in the banner that rancid has problems with OR
- I changed the device's command prompt?
-A. The trickest part about clogin (et al) is recognizing the prompt
+ I changed the device's command prompt and now collection is failing?
+A. The trickiest part about clogin (et al) is recognizing the prompt
correctly. clogin looks for '>' and '#' to figure out if it is logged
in or in enable mode. So if you have a '>' or '#' in your login banner
(other other motd), then clogin gets all confused and will not be
@@ -138,8 +194,49 @@ A. The trickest part about clogin (et al) is recognizing the prompt
Don't use '>' or '#' in your prompt or in your banner or other motd.
+Q. I use <BINDIR>/*login -c to run commands on multiple boxes. Sometimes
+ these are commands that take secondary input, like a filename. How can
+ enter the data for that secondary prompt?
+A. Two methods will work. Write an expect script to be used with clogin's
+ -s option, for which a few examples come with rancid like cisco-load.exp.
+ OR provide all the input in one command with the -c option like so:
+ Router#clear counters
+ Clear "show interface" counters on all interfaces [confirm]
+ Router#
+
+ clogin -c 'clear counters\n'
+ The specific return (\n) will be entered after 'clear counters' followed
+ by the normal return after the command.
+
+Q. I would like to collect device configurations every hour, but only receive
+ diffs every Nth collection or every N hours. Is this possible?
+A. Certainly, but rancid does not provide such a mechanism natively. Two
+ approaches are recommended:
+
+ 1) Using your preferred mail-list software, add a list with a digest
+ and configure your MTA (example: sendmail) to send diffs to the
+ list. Configure the mail-list software to force the digest at the
+ interval desired. This allows folks to choose which type they
+ prefer, after each collection or every N hours.
+
+ This method also provides easy methods to archive the diff mail and
+ retrieve previous diffs.
+
+ 2) Write a script to send diffs, which saves the time it last ran
+ and passes this to the -D option of CVS.
+
+ Obviously, the first option is the cleanest and most featureful, which is
+ why the script mention in the second option is not provided.
+
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
+
+Q. What else can I do with rancid?
+A. The possibilities are endless...rancid is non-toxic when applied properly.
+ see Joe Abley and Stephen Stuart's NANOG presentation:
+ http://www.nanog.org/mtg-0210/abley.html
+ or our NANOG presentation:
+ http://www.shrubbery.net/rancid/NANOG29/
diff --git a/Makefile.am b/Makefile.am
index 6ad5316..df32f4f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,28 +1,41 @@
## Process this file with automake to produce Makefile.in
+## A Makefile.in is supplied, in case you do not have automake.
+
+## $Id: Makefile.am,v 1.19 2004/01/10 22:47:29 heas Exp $
+##
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## All rights reserved.
+##
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
+##
+## 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.
+##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, and Pete Whiting.
+##
AUTOMAKE_OPTIONS=foreign no-dependencies
@SET_MAKE@
-EXTRA_DIST = BUGS CHANGES COPYING FAQ README Todo cloginrc.sample configure \
- install-sh \
- mkinstalldirs Makefile.in Todo
+pkgdata_DATA = COPYING CHANGES FAQ README README.lg UPGRADING cloginrc.sample
+EXTRA_DIST = BUGS Todo configure install-sh \
+ mkinstalldirs Makefile.in Todo $(pkgdata_DATA)
#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)
-SUBDIRS = . include bin man util
-
-all:
-
-# install-exec-local:
-# $(mkinstalldirs) $(prefix) $(prefix)/bin $(prefix)/man $(prefix)/util $(prefix)/util/lg
-
-install-exec-local:
- $(mkinstalldirs) $(prefix)/util $(prefix)/util/lg
-
-install:
- for file in CHANGES README cloginrc.sample ; do \
- $(INSTALL_DATA) $$file $(prefix); \
- done
-
+# will run make distclean in . after the other dirs (preserving Makefile) and
+# mkinstalldirs will create the install destination before descending into
+# the subdirs.
+SUBDIRS = . include etc bin man share
+
+# sysconfdir is here because etc/Makefile uses a script to be careful about
+# installing rancid.conf, not over-writing an existing one.
+install-data-hook:
+ $(mkinstalldirs) $(prefix) $(localstatedir) $(sysconfdir);
diff --git a/Makefile.in b/Makefile.in
index 52e2caa..2c7c59e 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,6 +1,8 @@
-# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
+# Makefile.in generated by automake 1.8 from Makefile.am.
+# @configure_input@
-# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -10,127 +12,231 @@
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
-
-SHELL = @SHELL@
+@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-
-bindir = @bindir@
-sbindir = @sbindir@
-libexecdir = @libexecdir@
-datadir = @datadir@
-sysconfdir = @sysconfdir@
-sharedstatedir = @sharedstatedir@
-localstatedir = @localstatedir@
-libdir = @libdir@
-infodir = @infodir@
-mandir = @mandir@
-includedir = @includedir@
-oldincludedir = /usr/include
-
-DESTDIR =
-
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
-
top_builddir = .
-
-ACLOCAL = @ACLOCAL@
-AUTOCONF = @AUTOCONF@
-AUTOMAKE = @AUTOMAKE@
-AUTOHEADER = @AUTOHEADER@
-
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-transform = @program_transform_name@
-
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
+subdir = .
+DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(top_srcdir)/configure COPYING \
+ acconfig.h configure configure.in depcomp install-sh missing \
+ mkinstalldirs
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/include/config.h
+CONFIG_CLEAN_FILES =
+depcomp =
+am__depfiles_maybe =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-exec-recursive install-info-recursive \
+ install-recursive installcheck-recursive installdirs-recursive \
+ pdf-recursive ps-recursive uninstall-info-recursive \
+ uninstall-recursive
+am__installdirs = $(DESTDIR)$(pkgdatadir)
+pkgdataDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(pkgdata_DATA)
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ { test ! -d $(distdir) \
+ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -fr $(distdir); }; }
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+ADMINMAILPLUS = @ADMINMAILPLUS@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
COMM = @COMM@
CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
CVS = @CVS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
DIFF = @DIFF@
DIFF_CMD = @DIFF_CMD@
DIRNAME = @DIRNAME@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
ENV_PATH = @ENV_PATH@
+EXEEXT = @EXEEXT@
EXPECT_PATH = @EXPECT_PATH@
FIND = @FIND@
GREP = @GREP@
ID = @ID@
-INST_PROGS = @INST_PROGS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
LG_PING_CMD = @LG_PING_CMD@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
MAILPLUS = @MAILPLUS@
-MAINT = @MAINT@
MAKE = @MAKE@
MAKEINFO = @MAKEINFO@
MKDIR = @MKDIR@
+OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
PERLV = @PERLV@
PERLV_PATH = @PERLV_PATH@
PING_PATH = @PING_PATH@
-RD_BIN_DATAS = @RD_BIN_DATAS@
-RD_BIN_PROGS = @RD_BIN_PROGS@
-RD_UTIL_LG_PROGS = @RD_UTIL_LG_PROGS@
-RD_UTIL_PROGS = @RD_UTIL_PROGS@
RSH = @RSH@
SENDMAIL = @SENDMAIL@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
SORT = @SORT@
SSH = @SSH@
+STRIP = @STRIP@
TAR = @TAR@
TELNET = @TELNET@
TOUCH = @TOUCH@
U = @U@
VERSION = @VERSION@
-
+ac_ct_CC = @ac_ct_CC@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build_alias = @build_alias@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
AUTOMAKE_OPTIONS = foreign no-dependencies
-
-EXTRA_DIST = BUGS CHANGES COPYING FAQ README Todo cloginrc.sample configure install-sh mkinstalldirs Makefile.in Todo
+pkgdata_DATA = COPYING CHANGES FAQ README README.lg UPGRADING cloginrc.sample
+EXTRA_DIST = BUGS Todo configure install-sh \
+ mkinstalldirs Makefile.in Todo $(pkgdata_DATA)
#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)
-SUBDIRS = . include bin man util
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
-CONFIG_HEADER = ./include/config.h
-CONFIG_CLEAN_FILES =
-DIST_COMMON = README COPYING Makefile.am Makefile.in acinclude.m4 \
-aclocal.m4 configure configure.in install-sh missing mkinstalldirs
-
+# will run make distclean in . after the other dirs (preserving Makefile) and
+# mkinstalldirs will create the install destination before descending into
+# the subdirs.
+SUBDIRS = . include etc bin man share
+all: all-recursive
-DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
-
-GZIP_ENV = --best
-all: all-redirect
.SUFFIXES:
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
- cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile
-
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- cd $(top_builddir) \
- && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
-
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in acinclude.m4
- cd $(srcdir) && $(ACLOCAL)
-
-config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+am--refresh:
+ @:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \
+ cd $(srcdir) && $(AUTOMAKE) --foreign \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
-$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+
+$(top_srcdir)/configure: $(am__configure_deps)
cd $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+uninstall-info-am:
+install-pkgdataDATA: $(pkgdata_DATA)
+ @$(NORMAL_INSTALL)
+ $(mkdir_p) $(DESTDIR)$(pkgdatadir)
+ @list='$(pkgdata_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f="`echo $$p | sed -e 's|^.*/||'`"; \
+ echo " $(pkgdataDATA_INSTALL) $$d$$p $(DESTDIR)$(pkgdatadir)/$$f"; \
+ $(pkgdataDATA_INSTALL) $$d$$p $(DESTDIR)$(pkgdatadir)/$$f; \
+ done
+
+uninstall-pkgdataDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgdata_DATA)'; for p in $$list; do \
+ f="`echo $$p | sed -e 's|^.*/||'`"; \
+ echo " rm -f $(DESTDIR)$(pkgdatadir)/$$f"; \
+ rm -f $(DESTDIR)$(pkgdatadir)/$$f; \
+ done
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
@@ -138,13 +244,8 @@ $(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4)
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
-
-@SET_MAKE@
-
-all-recursive install-data-recursive install-exec-recursive \
-installdirs-recursive install-recursive uninstall-recursive \
-check-recursive installcheck-recursive info-recursive dvi-recursive:
- @set fnord $(MAKEFLAGS); amf=$$2; \
+$(RECURSIVE_TARGETS):
+ @set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
@@ -164,13 +265,18 @@ check-recursive installcheck-recursive info-recursive dvi-recursive:
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
- @set fnord $(MAKEFLAGS); amf=$$2; \
+ @set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
- rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
- rev="$$subdir $$rev"; \
- test "$$subdir" != "." || dot_seen=yes; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
done; \
- test "$$dot_seen" = "no" && rev=". $$rev"; \
+ rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
@@ -186,178 +292,313 @@ tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
tags: TAGS
-TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
+ if (etags --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ else \
+ include_option=--include; \
+ fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
- if test "$$subdir" = .; then :; else \
- test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
- fi; \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && \
+ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
done; \
- list='$(SOURCES) $(HEADERS)'; \
- unique=`for i in $$list; do echo $$i; done | \
- awk ' { files[$$0] = 1; } \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
- test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
- || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
-
-mostlyclean-tags:
+ test -z "$(ETAGS_ARGS)$$tags$$unique" \
+ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
-clean-tags:
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
- -rm -f TAGS ID
-
-maintainer-clean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-distdir = $(PACKAGE)-$(VERSION)
-top_distdir = $(distdir)
-
-# This target untars the dist file and tries a VPATH configuration. Then
-# it guarantees that the distribution is self-contained by making another
-# tarfile.
-distcheck: dist
- -rm -rf $(distdir)
- GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
- mkdir $(distdir)/=build
- mkdir $(distdir)/=inst
- dc_install_base=`cd $(distdir)/=inst && pwd`; \
- cd $(distdir)/=build \
- && ../configure --srcdir=.. --prefix=$$dc_install_base \
- && $(MAKE) $(AM_MAKEFLAGS) \
- && $(MAKE) $(AM_MAKEFLAGS) dvi \
- && $(MAKE) $(AM_MAKEFLAGS) check \
- && $(MAKE) $(AM_MAKEFLAGS) install \
- && $(MAKE) $(AM_MAKEFLAGS) installcheck \
- && $(MAKE) $(AM_MAKEFLAGS) dist
- -rm -rf $(distdir)
- @banner="$(distdir).tar.gz is ready for distribution"; \
- dashes=`echo "$$banner" | sed s/./=/g`; \
- echo "$$dashes"; \
- echo "$$banner"; \
- echo "$$dashes"
-dist: distdir
- -chmod -R a+r $(distdir)
- GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
- -rm -rf $(distdir)
-dist-all: distdir
- -chmod -R a+r $(distdir)
- GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
- -rm -rf $(distdir)
distdir: $(DISTFILES)
- -rm -rf $(distdir)
+ $(am__remove_distdir)
mkdir $(distdir)
- -chmod 777 $(distdir)
- @for file in $(DISTFILES); do \
- d=$(srcdir); \
+ $(mkdir_p) $(distdir)/bin $(distdir)/include $(distdir)/share
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
if test -d $$d/$$file; then \
- cp -pr $$d/$$file $(distdir)/$$file; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
- || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
- || cp -p $$d/$$file $(distdir)/$$file || :; \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
fi; \
done
- for subdir in $(SUBDIRS); do \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
- test -d $(distdir)/$$subdir \
- || mkdir $(distdir)/$$subdir \
+ test -d "$(distdir)/$$subdir" \
+ || mkdir "$(distdir)/$$subdir" \
|| exit 1; \
- chmod 777 $(distdir)/$$subdir; \
- (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
+ (cd $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="../$(top_distdir)" \
+ distdir="../$(distdir)/$$subdir" \
+ distdir) \
|| exit 1; \
fi; \
done
-info-am:
-info: info-recursive
-dvi-am:
-dvi: dvi-recursive
+ -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r $(distdir)
+dist-gzip: distdir
+ $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+dist-bzip2: distdir
+ $(AMTAR) chof - $(distdir) | bzip2 -9 -c >$(distdir).tar.bz2
+ $(am__remove_distdir)
+
+dist-tarZ: distdir
+ $(AMTAR) chof - $(distdir) | compress -c >$(distdir).tar.Z
+ $(am__remove_distdir)
+
+dist-shar: distdir
+ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ $(am__remove_distdir)
+
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__remove_distdir)
+
+dist dist-all: distdir
+ $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf - ;;\
+ *.tar.bz2*) \
+ bunzip2 -c $(distdir).tar.bz2 | $(AMTAR) xf - ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(AMTAR) xf - ;;\
+ *.shar.gz*) \
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+ chmod -R a-w $(distdir); chmod a+w $(distdir)
+ mkdir $(distdir)/_build
+ mkdir $(distdir)/_inst
+ chmod a-w $(distdir)
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && cd $(distdir)/_build \
+ && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && $(mkdir_p) "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && rm -rf $(DIST_ARCHIVES) \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck
+ $(am__remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}'
+distuninstallcheck:
+ @cd $(distuninstallcheck_dir) \
+ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
check-am: all-am
check: check-recursive
-installcheck-am:
-installcheck: installcheck-recursive
-install-exec-am: install-exec-local
+all-am: Makefile $(DATA)
+installdirs: installdirs-recursive
+installdirs-am:
+ $(mkdir_p) $(DESTDIR)$(pkgdatadir)
+install: install-recursive
install-exec: install-exec-recursive
-
-install-data-am:
install-data: install-data-recursive
+uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-install: install-recursive
-uninstall-am:
-uninstall: uninstall-recursive
-all-am: Makefile
-all-redirect: all-recursive
-install-strip:
- $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
-installdirs: installdirs-recursive
-installdirs-am:
-
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
- -rm -f Makefile $(CONFIG_CLEAN_FILES)
- -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+ -rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
-mostlyclean-am: mostlyclean-tags mostlyclean-generic
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
-mostlyclean: mostlyclean-recursive
+clean-am: clean-generic mostlyclean-am
-clean-am: clean-tags clean-generic mostlyclean-am
+distclean: distclean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
-clean: clean-recursive
+dvi: dvi-recursive
-distclean-am: distclean-tags distclean-generic clean-am
+dvi-am:
-distclean: distclean-recursive
- -rm -f config.status
+html: html-recursive
-maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \
- distclean-am
- @echo "This command is intended for maintainers to use;"
- @echo "it deletes files that may require special tools to rebuild."
+info: info-recursive
+
+info-am:
+
+install-data-am: install-pkgdataDATA
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
+
+install-exec-am:
+
+install-info: install-info-recursive
+
+install-man:
+
+installcheck-am:
maintainer-clean: maintainer-clean-recursive
- -rm -f config.status
-
-.PHONY: install-data-recursive uninstall-data-recursive \
-install-exec-recursive uninstall-exec-recursive installdirs-recursive \
-uninstalldirs-recursive all-recursive check-recursive \
-installcheck-recursive info-recursive dvi-recursive \
-mostlyclean-recursive distclean-recursive clean-recursive \
-maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
-distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
-dvi-am dvi check check-am installcheck-am installcheck \
-install-exec-local install-exec-am install-exec install-data-am \
-install-data install-am install uninstall-am uninstall all-redirect \
-all-am all installdirs-am installdirs mostlyclean-generic \
-distclean-generic clean-generic maintainer-clean-generic clean \
-mostlyclean distclean maintainer-clean
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+mostlyclean: mostlyclean-recursive
-@SET_MAKE@
+mostlyclean-am: mostlyclean-generic
-all:
+pdf: pdf-recursive
-# install-exec-local:
-# $(mkinstalldirs) $(prefix) $(prefix)/bin $(prefix)/man $(prefix)/util $(prefix)/util/lg
+pdf-am:
-install-exec-local:
- $(mkinstalldirs) $(prefix)/util $(prefix)/util/lg
+ps: ps-recursive
-install:
- for file in CHANGES README cloginrc.sample ; do \
- $(INSTALL_DATA) $$file $(prefix); \
- done
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-pkgdataDATA
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \
+ check-am clean clean-generic clean-recursive ctags \
+ ctags-recursive dist dist-all dist-bzip2 dist-gzip dist-shar \
+ dist-tarZ dist-zip distcheck distclean distclean-generic \
+ distclean-recursive distclean-tags distcleancheck distdir \
+ distuninstallcheck dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-exec \
+ install-exec-am install-info install-info-am install-man \
+ install-pkgdataDATA install-strip installcheck installcheck-am \
+ installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic maintainer-clean-recursive \
+ mostlyclean mostlyclean-generic mostlyclean-recursive pdf \
+ pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
+ uninstall-info-am uninstall-pkgdataDATA
+
+
+@SET_MAKE@
+# sysconfdir is here because etc/Makefile uses a script to be careful about
+# installing rancid.conf, not over-writing an existing one.
+install-data-hook:
+ $(mkinstalldirs) $(prefix) $(localstatedir) $(sysconfdir);
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/README b/README
index cce631c..3fd7fe7 100644
--- a/README
+++ b/README
@@ -1,14 +1,26 @@
Rancid is a "Really Awesome New Cisco confIg Differ" developed to
maintain CVS controlled copies of router configs.
+*** The Following Information is Very Important ****
+Rancid 2.3 introduces a new directory layout. It has been changed to more
+closely follow the standard path hierarchy, which is defined by the FHS
+standard and autoconf, and/or make these locations more easily configurable
+within rancid.
+
+The obvious advantage of this is making rancid more easily packagable; i.e.:
+NetBSD pkgsrc, FreeBSD port, Linux RPM, etc.
+
+Please please please please read the UPGRADING file for more information.
+**********
+
The following is the packing list for Rancid. .in is stripped from
the files below by configure with substitutions completed:
README This file.
CHANGES List of changes to Rancid.
-Todo partial list of what needs to be done.
-env.in Environment settings needed.
-do-diffs.in Script designed to be run from cron calling control_rancid.
+Todo Partial list of what needs to be done.
+rancid.conf.in Environment settings needed.
+rancid-run.in Script designed to be run from cron calling control_rancid.
control_rancid.in
Builds router list, calls rancid on each router and
handles cvs routines.
@@ -21,6 +33,7 @@ francid.in Runs commands on foundry switches and processes the output.
hrancid.in Runs commands on hp procurve switches and processes the output.
jrancid.in Runs commands on juniper routers and processes the output.
mrancid.in Runs commands on MRT daemons and processes the output.
+nrancid.in Runs commands on netscreen routers and processes the output.
rrancid.in Runs commands on redback routers and processes the output.
xrancid.in Runs commands on extreme switches and processes the output.
cat5rancid.in Runs commands on cisco Cat switches and processes the output.
@@ -43,12 +56,13 @@ jlogin.in Expect script that logs into juniper routers similarly to
.cloginrc TCL commands to set passwords, usernames etc. used by clogin
and jlogin.
par.in Parallel processing of commands - any commands.
-rename.in Perl script to rename files.
-create_cvs.in Creates all of the CVS and config directories.
-hpfilter.c HP procurve login filter - see end of hlogin(1).
+rancid-cvs.in Creates all of the CVS and config directories.
+hpuifilter.c HP procurve login filter - see end of hlogin(1).
+etc/ Configuration file samples
+etc/lg.conf.sample
+etc/rancid.conf.sample
man/ man pages
-util/ utilities / contribs
-util/lg looking glass
+share/ Readmes, samples, utilities, contribs, etc
The following are included as part of the installation tools:
@@ -58,41 +72,53 @@ install-sh GNU autoconf shell script to simulate BSD style install
mkinstalldirs GNU autoconf shell script to make installation directories
rancid will also need to have the following packages:
-cvs code revision system available from prep.ai.mit.edu:/pub/gnu
-gnudiff gnudiff provides the uni-diff (-u) option. if you do not have
- gnudiff, configure will set-up rancid to use 'diff -c' or
- 'diff -C'.
+cvs Code revision system available from prep.ai.mit.edu:/pub/gnu
+gnudiff gnudiff provides the uni-diff (-u) option. If you do not have
+ a diff that supports -u, configure will set-up rancid to use
+ 'diff -c' or 'diff -C'.
perl5 perl version 5 or greater available from www.cpan.org
-expect http://expect.nist.gov/ we highly suggest that you stick to
- expect 5.24.1 (or so). this seems to work best. note that
- you have to have the accompanying tcl &/ tk.
-tcl required by expect.
+expect http://expect.nist.gov/ We highly suggest that you stick to
+ expect 5.24.1 (or so). This seems to work best. Note that
+ you need to have the accompanying tcl &/ tk.
+tcl Required by expect.
-Bill Fenner has a cgi script for interacting with CVS repositories via
-a web interface. This provides a great way to view rancid diffs and
-full configs, especially for those unfamiliar with cvs. The package is
-not included, but can be found here:
+Bill Fenner (now maintained by others) has a cgi script for interacting
+with CVS repositories via a web interface. This provides a great way to
+view rancid diffs and full configs, especially for those unfamiliar with
+cvs. The package is not included, but can be found here:
- http://www.freebsd.org/~fenner/cvsweb/cvsweb-1.0.tar.gz
+ http://www.freebsd.org/projects/cvsweb.html
Quick Installation Guide (an example):
1) ./configure [--prefix=<basedir>]
- By default, All rancid crud will be installed under /usr/local/rancid.
- This can be overridden with the --prefix option. E.g.:
+ By default, rancid will be installed under /usr/local/rancid (the default
+ "prefix"). This can be overridden with the --prefix option. E.g.:
./configure --prefix=/home/rancid
- see ./configure --help for other configure options.
+ Rancid uses autoconf's "localstatedir" as the location of it's logs,
+ CVS respository, and directories where it's groups are placed. The user
+ who will run rancid (from cron, etc) will need write access to these
+ directories. By default, this is <prefix>/var, or /home/rancid/var
+ following the example above.
+
+ We realize that this is not optimal, but it follows the standards. We
+ suggest that this be altered to include the package name, like so:
- The user who will run rancid must have write permission in this
- directory.
+ ./configure --prefix=/home/rancid \
+ --localstatedir=/home/rancid/var/rancid
+
+ The user who will run rancid must have write permission in "localstatedir".
+
+ See ./configure --help for other configure options.
2) make install
-3) Modify <basedir>/bin/env. The variable LIST_OF_GROUPS is a
- space delimited list of router "groups". E.g.:
+3) Modify <sysconfdir>/rancid.conf (e.g.: <basedir>/etc/rancid.conf). The
+ variable LIST_OF_GROUPS is a space delimited list of router "groups".
+ E.g.:
LIST_OF_GROUPS="backbone aggregation switches"
4) Put .cloginrc in the home directory of the user who will run rancid.
@@ -106,9 +132,9 @@ 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'.
+ See the file cloginrc.sample, located in <datadir> (<basedir>/share/rancid),
+ 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>
@@ -127,24 +153,28 @@ Quick Installation Guide (an example):
addresses mentioned above to "rancid+". See sendmail's operation manual
for more information on handling of '+'.
-7) Run create_cvs.
+ The --enable-adminmail-plus configure option will set each of the
+ "rancid-admin-" addresses mentioned above to "rancid-admin+". If this
+ option is not used, the value of --enable-mail-plus is assumed. That is,
+ the addresses will be "rancid+", if it is specified.
+
+7) Run rancid-cvs.
This creates all of the necessary directories and config files for
each of the groups in LIST_OF_GROUPS and imports them into CVS. This
will also be run each time a new group is added. Do not create the
- directories or CVS repository manually, allow create_cvs do it. Also see
- 'man -M <basedir>/man create_cvs'.
+ directories or CVS repository manually, allow rancid-cvs do it. Also see
+ 'man -M <basedir>/man rancid-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
the name (we use FQDN) of the router, mfg is the manufacturer
- from the set of
- (alteon|baynet|cat5|cisco|extreme|ezt3|force10|foundry|hp|juniper|redback),
- and "state" is either up or down. Each router listed as "up"
- will have the configuration grabbed. Note: manufacturer cat5
- is intended only for cisco catalyst switches running catalyst (not
+ from the set of (cat5|cisco|juniper) (see router.db.5 for a complete
+ list and description), and "state" is either up or down. Each router
+ listed as "up" will have the configuration grabbed. Note: manufacturer
+ cat5 is intended only for cisco catalyst switches running catalyst (not
IOS) code.
- eg <basedir>/<group>/router.db:
+ e.g.: <localstatedir>/<group>/router.db:
cisco-router.domain.com:cisco:up
adc-mux.domain.com:ezt3:up
foundry-switch-router.domain.com:foundry:up
@@ -152,28 +182,28 @@ Quick Installation Guide (an example):
redback-dsl-router.domain.com:redback:down
extreme-switch.domain.com:extreme:down
-9) For first-time users or new installations, run bin/do-diffs (with no
+9) For first-time users or new installations, run bin/rancid-run (with no
arguments) and check the resulting log file(s) (in logs/*) for errors.
Repeat until there are no errors.
-10) Put do-diffs in cron to be called however often you want it to
- run for each group (do-diffs [<GROUP>]). If you run it less
- often than once/hour, check the setting of OLDTIME in bin/env.
+10) Put rancid-run in cron to be called however often you want it to
+ run for each group (rancid-run [<GROUP>]). If you run it less
+ often than once/hour, check the setting of OLDTIME in etc/rancid.conf.
E.g.:
# run config differ hourly
- 1 * * * * <BASEDIR>/bin/do-diffs
+ 1 * * * * <BASEDIR>/bin/rancid-run
# clean out config differ logs
- 50 23 * * * /usr/bin/find <BASEDIR>/logs -type f -mtime +2 -exec rm {} \;
+ 50 23 * * * /usr/bin/find <localstatedir>/logs -type f -mtime +2 -exec rm {} \;
11) Note: If you are using any of these programs (other than
- do-diffs) out of cron, make sure that you set your $PATH
+ rancid-run) out of cron, make sure that you set your $PATH
correctly so that they work. E.g.: if you are using clogin,
it can call id, telnet, ssh, and/or rsh.
configure already makes sure that $PATH is set correctly in
- bin/env for do-diffs, so you could use the $PATH from there. eg:
+ etc/rancid.conf for rancid-run, so you could use the $PATH from there. e.g.:
- 50 23 * * * . /usr/local/rancid/bin/env; clogin -c 'sh vers' router
+ 50 23 * * * . <sysconfdir>/rancid.conf; clogin -c 'sh vers' router
12) Send any bugs, suggestions or updates to rancid@shrubbery.net.
See the web page at http://www.shrubbery.net/rancid. We have
@@ -198,10 +228,10 @@ 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
+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,
seems to not exhibit this problem, while 5.32.* appears to on linux and
-solaris but not on netbsd 1.5. see www.shrubbery.net/rancid for additional
+solaris but not on netbsd 1.5. See www.shrubbery.net/rancid for additional
notes on this.
-Hank
diff --git a/README.lg b/README.lg
new file mode 100644
index 0000000..d66d1f1
--- /dev/null
+++ b/README.lg
@@ -0,0 +1,79 @@
+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
+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.
+index.html often the default document the server will load, contains
+ an html redirect to load lgform.cgi
+lg.conf looking glass configuration file
+lg.cgi work horse of the looking glass
+lgform.cgi front-end form for the looking glass engine
+lgnotes.html user info for the looking glass
+
+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 comes
+with perl5 and/or are converted with h2ph(1).
+
+basic installation instructions:
+
+The configure and make install process will make variable substitutions
+and install the looking glass bits. Assuming configure was run without
+directory options, such as --prefix, the default install prefix is
+/usr/local/rancid. So, the bits will be installed in
+/usr/local/rancid/etc/lg.conf, /usr/local/rancid/bin, and
+/usr/local/rancid/share/rancid (i.e.: <prefix>/etc/lg.conf, etc.).
+
+1) Make the scripts and html files available to your server (httpd) by
+ creating a directory in your server's document root directory
+ (apache's httpd.conf "DocumentRoot" variable). For example:
+
+ mkdir /usr/local/htdocs/lg
+
+ Then either:
+ - copy the files <PREFIX>/share/rancid/{index.html,lgnotes.html} and
+ <PREFIX>/bin/{lg.cgi,lgform.cgi} to /usr/local/htdocs/lg
+ OR
+ - create symlinks from /usr/local/htdocs/lg to each of these files.
+
+ Note on links: if you use symlinks, you have to configure apache to
+ allow following symlinks. e.g.:
+ % cat /usr/local/htdocs/lg/.htaccess
+ Options FollowSymLinks ExecCGI
+
+ Note on index.html: index.html is typically the default file loaded
+ when a url ends with a '/'. index.html can be used to redirect this
+ to lgform.cgi using a netscape meta refresh. Though this is supported
+ by many browsers, it is supposedly netscape specific and non-standard.
+ In apache, the same thing can be acheived by altering the default
+ directory index like this:
+
+ % cat /usr/local/htdocs/lg/.htaccess
+ DirectoryIndex lgform.cgi
+
+2) The looking glass scripts need to be able to find and read lg.conf. By
+ default it is installed as <SYSCONFDIR>/lg.conf (<PREFIX>/etc/lg.conf)
+ and the scripts will first look in their CWD (Current Working Directory)
+ and then <SYSCONFDIR>/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 CGI enviroment, you can use SetEnvIf in apache's
+ httpd.conf. For example:
+ SetEnvIf Request_URI "\/lg/.*.cgi" LG_CONF=/usr/local/htdocs/lg/lg.conf
+
+3) Edit <SYSCONFIGDIR>/lg.conf (usually <PREFIX>/etc/lg.conf). See lg.conf(5)
+ for additional information.
+
+4) Set-up cron jobs to rotate the log file and clean out old cache files.
+ See LG_CACHE_DIR & LG_LOG in lg.conf. Something like (YMMV):
+
+ # rotate lookingglass log
+ #0 0 * * * cd /usr/local/htdocs/lg/tmp; /usr/local/etc/savelog -m 666 -c14 lg.log
+ 0 0 * * * cd /usr/local/htdocs/lg/tmp; /bin/mv lg.log lg.log.0
+ # clean out the lookingglass cache
+ 0 0 * * * cd /usr/local/htdocs/lg/tmp; /usr/local/bin/find . -type f -maxdepth 1 \( \! -name lg.log\* \) -mtime +1 -exec rm -f {} \;
diff --git a/Todo b/Todo
index 87b2520..97ded87 100644
--- a/Todo
+++ b/Todo
@@ -1,19 +1,34 @@
+- could the cloginrc match function do a longest-match search instead of
+ first match?
+- look at Andreas Dahl's Brocade switch collection scripts
+- noenable should handle a value properly. i.e.: 1 == noenable, 0 == enable or
+ perhaps don't clear the -noenable cmd-line option. the manpage needs to be
+ fixed as well. see msg from fred jordan.
+- recent hp procurve s/w does not seem have show flash or show module
+- would like to have a "pre-login-sequence" cloginrc directive, see
+ rancid-disuss message from mike ethridge 16/may
+- would like to have a "timeout" cloginrc directive
+- would like to have a ssh "passphrase" cloginrc directive
+- would like to have a "login_option" cloginrc directive to specify arbitrary
+ command-line options
+- possibly a "debug" (exp_internal 1 ?) cloginrc directive? *login -d flag
+ for same? warning about filling logs?
+- on 6500, show boot and show bootvar produce the same output and both appear
+ in the crunched config. should one be filtered?
- 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
-- hlogin hangs when the procurve is does not ask for passwords
-- util/ tool to prune cvs versions, excluding those with tags, by (all but
+- hlogin hangs when the procurve does not ask for passwords
+- hlogin does not work with ssh, needs to alloc a pty?
+- share/ tool to prune cvs versions, excluding those with tags, by (all but
latest | keep N versions | keep N days/months/years)
-- extreme collections lose when the config on the switch is in an unsaved
- state, probably due to the prompt changing or rather how clogin formulates
- the prompt used by expect{ -re }'s.
- extreme collection fails for tacacs-enabled boxen due to diffs in UI - blech!
+- xrancid should collect both of these:
+ show configuration
+ show configuration detail
- FILTER_PWDS knob is not implemented in alteon, bay, ezt3 or redback due to
lack of h/w to test against. need help from the community.
- should par's -c override an input files' : cmd?
-- *login should emmit "clogin error:" or "*login error:" to make matches for
+- should *login emmit "clogin error:" or "*login error:" to make matches for
login failures definitive?
- would like hpfilter to be more friendly to interactive logins
- rancid with zebra? via vtysh?
@@ -34,6 +49,45 @@
- 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 {requested} additions
+- LG should sort routers
+- LG {requested} command additions
- show controllers T3 (data)
- handle redback in the looking glass
+ - show ip as-path-access-list
+ - show access-list
+ - show ip community-list
+ - show ip route-map
+- prancid - lots of GC'ing to be done
+- prancid - sort logging file by filename. e.g.:
+ logging file messages facility kernel level debugging
+ logging file log facility any level debugging
+ logging file log archive files 10 size 10m
+ logging file messages archive files 10 size 10m
+ then, sort by facility, e.g.:
+ logging file messages facility kernel level debugging
+ logging file messages facility authorization level debugging
+- should we add CVS ID header to saved configs? configurable option? - idea
+ from andrew fort
+- cat 2900 extra info
+ <hostname> uptime is 3 weeks, 3 days, 14 hours, 17 minutes
+ System returned to ROM by power-on
+ System restarted at 15:21:54 UTC Mon Sep 30 2002
+ System image file is "flash:c2950-i6q4l2-mz.121-9.EA1d.bin"
+
+ cisco WS-C2950-24 (RC32300) processor (revision B0) with 20821K bytes of memory.
+ Processor board ID FHK0619X2RN
+ Last reset from system-reset
+ Running Standard Image
+ 24 FastEthernet/IEEE 802.3 interface(s)
+
+ 32K bytes of flash-simulated non-volatile configuration memory.
+ Base ethernet MAC Address: 00:09:B7:50:DE:C0
+ Motherboard assembly number: 73-5781-10
+ Power supply part number: 34-0965-01
+ Motherboard serial number: FOC061903JF
+ Power supply serial number: DAB061735H4
+ Model revision number: B0
+ Motherboard revision number: A0
+ Model number: WS-C2950-24
+ System serial number: FHK0619X2RN
+ Configuration register is 0xF
diff --git a/UPGRADING b/UPGRADING
new file mode 100644
index 0000000..3724331
--- /dev/null
+++ b/UPGRADING
@@ -0,0 +1,85 @@
+Rancid 2.3 introduces a new directory layout. It has been changed to more
+closely follow the standard path hierarchy, which is defined by the FHS
+standard and autoconf, and/or make these locations more easily configurable
+within rancid.
+
+The obvious advantage of this is making rancid more easily packagable; i.e.:
+NetBSD pkgsrc, FreeBSD port, Linux RPM, etc.
+
+Make sure your rancid repository is quiet before upgrading; disable rancid
+cron jobs, wait for running jobs to complete, etc.
+
+Autoconf defines the following (see configure --help):
+ Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [/usr/local/rancid]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+ Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --mandir=DIR man documentation [PREFIX/man]
+
+ Also defined, though not mentioned above, is:
+ pkgdatadir same as datadir, but datadir/rancid
+
+File and directory movement:
+ bin/env the rancid configuration file has moved to
+ sysconfdir/rancid.conf
+ util/lg/lg.conf the looking glass configuration has moved to
+ sysconfdir/lg.conf
+ util/lg/lg.cgi
+ util/lg/lgform.cgi the looking glass CGI scripts have moved to bindir
+ util/lg/* the remainder of looking glass html, README, etc
+ files have moved to pkgdatadir
+ util/* misc examples, scripts, etc have moved to pkgdatadir
+ cloginrc.sample moved to pkgdatadir
+
+For those upgrading, there is one basic choice to make; to move your CVS
+repository and logs or not. Prior to rancid 2.3, these were placed in
+<PREFIX>. They are now in "localstatedir". The user who runs rancid will
+need write access to this directory.
+
+To maintain the same location as was used prior to rancid 2.3, provide
+the --localstatedir option to configure. e.g.:
+
+ ./configure --localstatedir=/usr/local/rancid
+
+/usr/local/rancid is, and has been, the default <PREFIX>.
+
+To move them elsewhere, accept the default (e.g.: /usr/local/rancid/var) or
+specify your own and move the existing directories. e.g.:
+
+ ./configure --localstatedir=/var/rancid
+ make install
+ edit <SYSCONFDIR>/rancid.conf # merge with your old bin/env
+ # configuration file
+ mv /usr/local/rancid/logs /var/rancid
+ mv /usr/local/rancid/CVS /var/rancid
+ cd /var/rancid
+ su - rancid_user
+ /bin/sh
+ . <SYSCONFDIR>/rancid.conf
+ for grp in $LIST_OF_GROUPS; do
+ cvs -d /var/rancid/CVS co $grp
+ done
+
+Note that the first rancid-run will send messages about routers being added,
+marked up or down, etc., because the routers.{all,down,up} will have been
+lost. Afterward, it will be back to normal.
+
+Note also that any non-rancid files that may have been placed in these CVS
+trees will be lost. You have been warned.
+
+*** We strongly suggest that if a DIR used as the install prefix, as in
+ --prefix=DIR, is not dedicated to rancid that "/rancid" should be
+ appended to the --localstatedir, as in the example above.
+
+Note that not all operating systems have a mv command that will move
+directories across file systems. It may be necessary to use 'cp -r' or
+'tar cf - <GROUPS> | (cd <SYSCONFDIR>; tar xpf -)'.
diff --git a/acconfig.h b/acconfig.h
new file mode 100644
index 0000000..87d5f53
--- /dev/null
+++ b/acconfig.h
@@ -0,0 +1,78 @@
+#ifndef CONFIG_H
+#define CONFIG_H 1
+
+@TOP@
+
+@BOTTOM@
+
+#ifndef __P
+# if STDC_HEADERS
+# define __P(a) a
+# else
+# define __P(a) ()
+# endif
+#endif
+
+#define BUF_SZ LINE_MAX /* (increments of) size of bufs */
+
+#if HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+# include <sys/types.h>
+#elif HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#if HAVE_ERRNO_H
+# include <errno.h>
+#endif
+extern int errno;
+
+#if HAVE_STRING_H
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#if ! HAVE_STRERROR
+# define strerror(n) sys_errlist[n];
+#endif
+
+#if HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#endif
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+
+#if HAVE_MEMSET
+# define bzero(p,s) memset(p, 0, s)
+# define bcopy(s,d,l) memcpy(d, s, l)
+#endif
+
+#if HAVE_INDEX && ! HAVE_STRCHR
+# define index(s,c) strchr(s,c)
+#endif
+
+#if HAVE_SYSEXITS_H
+# include <sysexits.h>
+#else
+ /* missing sysexits.h */
+# define EX_OK 0
+# define EX_USAGE 64 /* command line usage error */
+# define EX_NOINPUT 66 /* cannot open input */
+# define EX_TEMPFAIL 75 /* temp failure */
+# define EX_OSERR 71 /* system error */
+# define EX_CANTCREAT 73 /* can't create (user) output file */
+# define EX_IOERR 74 /* input/output error */
+# define EX_CONFIG 78 /* configuration error */
+#endif
+
+#endif /* CONFIG_H */
diff --git a/aclocal.m4 b/aclocal.m4
index c6f5608..42590ae 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,72 +1,857 @@
-dnl aclocal.m4 generated automatically by aclocal 1.4-p5
+# generated automatically by aclocal 1.8 -*- Autoconf -*-
-dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
-dnl This program is distributed in the hope that it will be useful,
-dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-dnl PARTICULAR PURPOSE.
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
-AUTOMAKE_OPTIONS=no-dependencies foreign
+# -*- Autoconf -*-
+# Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+# Generated from amversion.in; do not edit by hand.
-# Do all the work for Automake. This macro actually does too much --
-# some checks are only needed if your package does certain things.
-# But this isn't really a big deal.
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
-# serial 1
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.8"])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION so it can be traced.
+# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+ [AM_AUTOMAKE_VERSION([1.8])])
+
+# AM_AUX_DIR_EXPAND
+
+# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 6
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])
+AC_SUBST([$1_FALSE])
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.])
+fi])])
+
+# serial 5 -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
+ [$1], CXX, [depcc="$CXX" am_compiler_list=],
+ [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ : > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored.
+ if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[ --disable-dependency-tracking Speeds up one-time builds
+ --enable-dependency-tracking Do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+#serial 2
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[for mf in $CONFIG_FILES; do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # So let's grep whole file.
+ if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue
+ # Extract the definition of DEP_FILES from the Makefile without
+ # running `make'.
+ DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n -e '/^U = / s///p' < "$mf"`
+ test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
+ # We invoke sed twice because it is the simplest approach to
+ # changing $(DEPDIR) to its actual value in the expansion.
+ for file in `sed -n -e '
+ /^DEP_FILES = .*\\\\$/ {
+ s/^DEP_FILES = //
+ :loop
+ s/\\\\$//
+ p
+ n
+ /\\\\$/ b loop
+ p
+ }
+ /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+done
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# This macro actually does too much some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
-dnl Usage:
-dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+# serial 11
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
AC_DEFUN([AM_INIT_AUTOMAKE],
-[AC_REQUIRE([AC_PROG_INSTALL])
-PACKAGE=[$1]
-AC_SUBST(PACKAGE)
-VERSION=[$2]
-AC_SUBST(VERSION)
-dnl test to see if srcdir already configured
-if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+[AC_PREREQ([2.58])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+# test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+ test -f $srcdir/config.status; then
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
fi
-ifelse([$3],,
-AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
-AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
-AC_REQUIRE([AM_SANITY_CHECK])
-AC_REQUIRE([AC_ARG_PROGRAM])
-dnl FIXME This is truly gross.
-missing_dir=`cd $ac_aux_dir && pwd`
-AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
-AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
-AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
-AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
-AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
-AC_REQUIRE([AC_PROG_MAKE_SET])])
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AM_MISSING_PROG(AMTAR, tar)
+AM_PROG_INSTALL_SH
+AM_PROG_INSTALL_STRIP
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES(CC)],
+ [define([AC_PROG_CC],
+ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES(CXX)],
+ [define([AC_PROG_CXX],
+ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+])
+])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $1 | $1:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+
+# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+AC_SUBST(install_sh)])
+
+# -*- Autoconf -*-
+# Copyright (C) 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 1
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 2
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+ am__include=include
+ am__quote=
+ _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ fi
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# -*- Autoconf -*-
+
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 3
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
+
+# Copyright (C) 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+AC_DEFUN([AM_PROG_MKDIR_P],
+[if mkdir -m 0755 -p -- . 2>/dev/null; then
+ mkdir_p='mkdir -m 0755 -p --'
+else
+ # On NextStep and OpenStep, the `mkdir' command does not
+ # recognize any option. It will interpret all options as
+ # directories to create, and then abort because `.' already
+ # exists.
+ for d in ./-m ./0755 ./-p ./--;
+ do
+ test -d $d && rmdir $d
+ done
+ # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
+ if test -f "$ac_aux_dir/mkinstalldirs"; then
+ mkdir_p='$(mkinstalldirs) -m 0755'
+ else
+ mkdir_p='$(install_sh) -m 0755 -d'
+ fi
+fi
+AC_SUBST([mkdir_p])])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 2
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+
+# Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 3
+
+AC_DEFUN([AM_C_PROTOTYPES],
+[AC_REQUIRE([AC_C_PROTOTYPES])
+if test "$ac_cv_prog_cc_stdc" != no; then
+ U= ANSI2KNR=
+else
+ U=_ ANSI2KNR=./ansi2knr
+fi
+# Ensure some checks needed by ansi2knr itself.
+AC_REQUIRE([AC_HEADER_STDC])
+AC_CHECK_HEADERS(string.h)
+AC_SUBST(U)dnl
+AC_SUBST(ANSI2KNR)dnl
+])
+
+AU_DEFUN([fp_C_PROTOTYPES], [AM_C_PROTOTYPES])
#
# Check to make sure that the build environment is sane.
#
+# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 3
+
+# AM_SANITY_CHECK
+# ---------------
AC_DEFUN([AM_SANITY_CHECK],
[AC_MSG_CHECKING([whether build environment is sane])
# Just in case
sleep 1
-echo timestamp > conftestfile
+echo timestamp > conftest.file
# Do `set' in a subshell so we don't clobber the current shell's
# arguments. Must try -L first in case configure is actually a
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
if (
- set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
- if test "[$]*" = "X"; then
+ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
# -L didn't work.
- set X `ls -t $srcdir/configure conftestfile`
+ set X `ls -t $srcdir/configure conftest.file`
fi
- if test "[$]*" != "X $srcdir/configure conftestfile" \
- && test "[$]*" != "X conftestfile $srcdir/configure"; then
+ rm -f conftest.file
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
# If neither matched, then we have a broken ls. This can happen
# if, for instance, CONFIG_SHELL is bash and it inherits a
@@ -76,7 +861,7 @@ if (
alias in your environment])
fi
- test "[$]2" = conftestfile
+ test "$[2]" = conftest.file
)
then
# Ok.
@@ -85,188 +870,45 @@ else
AC_MSG_ERROR([newly created file is older than distributed files!
Check your system clock])
fi
-rm -f conftest*
AC_MSG_RESULT(yes)])
-dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
-dnl The program must properly implement --version.
-AC_DEFUN([AM_MISSING_PROG],
-[AC_MSG_CHECKING(for working $2)
-# 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.
-if ($2 --version) < /dev/null > /dev/null 2>&1; then
- $1=$2
- AC_MSG_RESULT(found)
-else
- $1="$3/missing $2"
- AC_MSG_RESULT(missing)
-fi
-AC_SUBST($1)])
+# AM_PROG_INSTALL_STRIP
-# Like AC_CONFIG_HEADER, but automatically create stamp file.
-
-AC_DEFUN([AM_CONFIG_HEADER],
-[AC_PREREQ([2.12])
-AC_CONFIG_HEADER([$1])
-dnl When config.status generates a header, we must update the stamp-h file.
-dnl This file resides in the same directory as the config header
-dnl that is generated. We must strip everything past the first ":",
-dnl and everything past the last "/".
-AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
-ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
-<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
-<<am_indx=1
-for am_file in <<$1>>; do
- case " <<$>>CONFIG_HEADERS " in
- *" <<$>>am_file "*<<)>>
- echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
- ;;
- esac
- am_indx=`expr "<<$>>am_indx" + 1`
-done<<>>dnl>>)
-changequote([,]))])
+# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
-# Add --enable-maintainer-mode option to configure.
-# From Jim Meyering
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
-# serial 1
-
-AC_DEFUN([AM_MAINTAINER_MODE],
-[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
- dnl maintainer-mode is disabled by default
- AC_ARG_ENABLE(maintainer-mode,
-[ --enable-maintainer-mode enable make rules and dependencies not useful
- (and sometimes confusing) to the casual installer],
- USE_MAINTAINER_MODE=$enableval,
- USE_MAINTAINER_MODE=no)
- AC_MSG_RESULT($USE_MAINTAINER_MODE)
- AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes)
- MAINT=$MAINTAINER_MODE_TRUE
- AC_SUBST(MAINT)dnl
-]
-)
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
-# Define a conditional.
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
-AC_DEFUN([AM_CONDITIONAL],
-[AC_SUBST($1_TRUE)
-AC_SUBST($1_FALSE)
-if $2; then
- $1_TRUE=
- $1_FALSE='#'
-else
- $1_TRUE='#'
- $1_FALSE=
-fi])
-
-
-# serial 1
-
-AC_DEFUN([AM_C_PROTOTYPES],
-[AC_REQUIRE([AM_PROG_CC_STDC])
-AC_REQUIRE([AC_PROG_CPP])
-AC_MSG_CHECKING([for function prototypes])
-if test "$am_cv_prog_cc_stdc" != no; then
- AC_MSG_RESULT(yes)
- AC_DEFINE(PROTOTYPES,1,[Define if compiler has function prototypes])
- U= ANSI2KNR=
-else
- AC_MSG_RESULT(no)
- U=_ ANSI2KNR=./ansi2knr
- # Ensure some checks needed by ansi2knr itself.
- AC_HEADER_STDC
- AC_CHECK_HEADERS(string.h)
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
fi
-AC_SUBST(U)dnl
-AC_SUBST(ANSI2KNR)dnl
-])
-
-
-# serial 1
-
-# @defmac AC_PROG_CC_STDC
-# @maindex PROG_CC_STDC
-# @ovindex CC
-# If the C compiler in not in ANSI C mode by default, try to add an option
-# to output variable @code{CC} to make it so. This macro tries various
-# options that select ANSI C on some system or another. It considers the
-# compiler to be in ANSI C mode if it handles function prototypes correctly.
-#
-# If you use this macro, you should check after calling it whether the C
-# compiler has been set to accept ANSI C; if not, the shell variable
-# @code{am_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source
-# code in ANSI C, you can make an un-ANSIfied copy of it by using the
-# program @code{ansi2knr}, which comes with Ghostscript.
-# @end defmac
-
-AC_DEFUN([AM_PROG_CC_STDC],
-[AC_REQUIRE([AC_PROG_CC])
-AC_BEFORE([$0], [AC_C_INLINE])
-AC_BEFORE([$0], [AC_C_CONST])
-dnl Force this before AC_PROG_CPP. Some cpp's, eg on HPUX, require
-dnl a magic option to avoid problems with ANSI preprocessor commands
-dnl like #elif.
-dnl FIXME: can't do this because then AC_AIX won't work due to a
-dnl circular dependency.
-dnl AC_BEFORE([$0], [AC_PROG_CPP])
-AC_MSG_CHECKING(for ${CC-cc} option to accept ANSI C)
-AC_CACHE_VAL(am_cv_prog_cc_stdc,
-[am_cv_prog_cc_stdc=no
-ac_save_CC="$CC"
-# Don't try gcc -ansi; that turns off useful extensions and
-# breaks some systems' header files.
-# AIX -qlanglvl=ansi
-# Ultrix and OSF/1 -std1
-# HP-UX -Aa -D_HPUX_SOURCE
-# SVR4 -Xc -D__EXTENSIONS__
-for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
- CC="$ac_save_CC $ac_arg"
- AC_TRY_COMPILE(
-[#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
- char **p;
- int i;
-{
- return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
- char *s;
- va_list v;
- va_start (v,p);
- s = g (p, va_arg (v,int));
- va_end (v);
- return s;
-}
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-], [
-return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
-],
-[am_cv_prog_cc_stdc="$ac_arg"; break])
-done
-CC="$ac_save_CC"
-])
-if test -z "$am_cv_prog_cc_stdc"; then
- AC_MSG_RESULT([none needed])
-else
- AC_MSG_RESULT($am_cv_prog_cc_stdc)
-fi
-case "x$am_cv_prog_cc_stdc" in
- x|xno) ;;
- *) CC="$CC $am_cv_prog_cc_stdc" ;;
-esac
-])
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+m4_include([acinclude.m4])
diff --git a/bin/Makefile.am b/bin/Makefile.am
index 67c8966..21fac52 100644
--- a/bin/Makefile.am
+++ b/bin/Makefile.am
@@ -1,26 +1,46 @@
## Process this file with automake to produce Makefile.in
## A Makefile.in is supplied, in case you do not have automake.
-## Copyright (C) 1997-2001 by Henry Kilmer, Erik Sherk and Pete Whiting.
+## $Id: Makefile.am,v 1.28 2004/01/11 07:15:23 hank Exp $
+##
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
+##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
+##
#AUTOMAKE_OPTIONS=foreign no-dependencies
AUTOMAKE_OPTIONS=foreign
-PREFIX = @prefix@
+bin_PROGRAMS = hpuifilter
+bin_SCRIPTS = cat5rancid control_rancid \
+ alogin arancid clogin blogin brancid cssrancid \
+ elogin erancid f10rancid flogin francid fnrancid \
+ jlogin jrancid jerancid \
+ hlogin hrancid htlogin htrancid \
+ mrancid nlogin nrancid nslogin nsrancid par prancid \
+ rancid rancid-fe rivlogin rivrancid rrancid \
+ tntlogin tntrancid xrancid zrancid
+
+bin_SCRIPTS += lg.cgi lgform.cgi rancid-cvs rancid-run
+EXTRA_DIST= lg.cgi.in lgform.cgi.in rancid-cvs.in rancid-run.in
+#dist_bin_SCRIPTS= $(bin_SCRIPTS:%=%.in)
+
+CLEANFILES= lg.cgi lgform.cgi rancid-cvs rancid-run
+#CLEANFILES= $(bin_SCRIPTS)
-bin_PROGRAMS = hpfilter
-hpfilter_SOURCES = hpfilter.c
+hpuifilter_SOURCES = hpuifilter.c
#CPPFLAGS += @PG_CPPFLAGS@
#INCLUDES += -I$(top_srcdir)/include @PG_CPPFLAGS@
@@ -35,35 +55,46 @@ YFLAGS = -d
# no idea why automake doesnt clean these targets
#CLEANFILES= y.tab.c y.tab.h lex.yy.c conf.h conf.c conflex.c
-BIN_PROGS=@RD_BIN_PROGS@
-BIN_DATAS=@RD_BIN_DATAS@
-
-install: all
- for prog in $(BIN_PROGS) ; do \
- $(INSTALL) $$prog $(bindir); \
- done; \
- if test -f $(bindir)/env ; then \
- echo "WARNING: *** $(bindir)/env exists: installing as env.new."; \
- echo " *** review env.new for new/deprecated switches"; \
- $(INSTALL_DATA) env $(bindir)/env.new; \
- else \
- $(INSTALL_DATA) env $(bindir); \
- fi
-# BIN_DATAS are empty at the moment.
-# for prog in $(BIN_DATAS) ; do \
-# $(INSTALL_DATA) $$prog $(PREFIX)/bin; \
-# done; \
-
#clean:
# rm -f Makefile env $(BIN_DATAS) $(BIN_PROGS)
-#distclean: clean
-# rm -f config.log config.status
+# auto_edit does the autoconf variable substitution. This allows the
+# substitution to have the full expansion of the variables, e.g.: $sysconfdir
+# will be /prefix/etc instead of ${prefix}/etc.
+#
+# This is a bit of a PITA, but is the method recommended by the autoconf
+# documentation.
+auto_edit = sed \
+ -e 's,@prefix\@,$(prefix),g' \
+ -e 's,@localstatedir\@,$(localstatedir),g' \
+ -e 's,@sysconfdir\@,$(sysconfdir),g' \
+ -e 's,@EXPECT_PATH\@,$(EXPECT_PATH),g' \
+ -e 's,@PERLV\@,$(PERLV),g' \
+ -e 's,@PERLV_PATH\@,$(PERLV_PATH),g' \
+ -e 's,@LG_PING_CMD\@,$(LG_PING_CMD),g' \
+ -e 's,@ADMINMAILPLUS\@,$(ADMINMAILPLUS),g' \
+ -e 's,@MAILPLUS\@,$(MAILPLUS),g'
+
+lg.cgi: Makefile $(srcdir)/lg.cgi.in
+ rm -f lg.cgi lg.cgi.tmp; \
+ $(auto_edit) $(srcdir)/lg.cgi.in >lg.cgi.tmp; \
+ chmod +x lg.cgi.tmp; \
+ mv lg.cgi.tmp lg.cgi
+
+lgform.cgi: Makefile $(srcdir)/lgform.cgi.in
+ rm -f lgform.cgi lgform.cgi.tmp; \
+ $(auto_edit) $(srcdir)/lgform.cgi.in >lgform.cgi.tmp; \
+ chmod +x lgform.cgi.tmp; \
+ mv lgform.cgi.tmp lgform.cgi
+
+rancid-cvs: Makefile $(srcdir)/rancid-cvs.in
+ rm -f rancid-cvs rancid-cvs.tmp; \
+ $(auto_edit) $(srcdir)/rancid-cvs.in >rancid-cvs.tmp; \
+ chmod +x rancid-cvs.tmp; \
+ mv rancid-cvs.tmp rancid-cvs
-#distdir:
-# for file in Makefile.in configure.in env.in $(BIN_DATAS:=.in) ; do \
-# $(INSTALL_DATA) $$file $(distdir); \
-# done
-# for file in configure $(BIN_PROGS:=.in) ; do \
-# $(INSTALL) $$file $(distdir); \
-# done
+rancid-run: Makefile $(srcdir)/rancid-run.in
+ rm -f rancid-run rancid-run.tmp; \
+ $(auto_edit) $(srcdir)/rancid-run.in >rancid-run.tmp; \
+ chmod +x rancid-run.tmp; \
+ mv rancid-run.tmp rancid-run
diff --git a/bin/Makefile.in b/bin/Makefile.in
index ad98aa8..eedc795 100644
--- a/bin/Makefile.in
+++ b/bin/Makefile.in
@@ -1,6 +1,8 @@
-# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
+# Makefile.in generated by automake 1.8 from Makefile.am.
+# @configure_input@
-# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -10,397 +12,595 @@
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
-#AUTOMAKE_OPTIONS=foreign no-dependencies
+@SET_MAKE@
-SHELL = @SHELL@
+SOURCES = $(hpuifilter_SOURCES)
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-
-bindir = @bindir@
-sbindir = @sbindir@
-libexecdir = @libexecdir@
-datadir = @datadir@
-sysconfdir = @sysconfdir@
-sharedstatedir = @sharedstatedir@
-localstatedir = @localstatedir@
-libdir = @libdir@
-infodir = @infodir@
-mandir = @mandir@
-includedir = @includedir@
-oldincludedir = /usr/include
-
-DESTDIR =
-
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
-
top_builddir = ..
-
-ACLOCAL = @ACLOCAL@
-AUTOCONF = @AUTOCONF@
-AUTOMAKE = @AUTOMAKE@
-AUTOHEADER = @AUTOHEADER@
-
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-transform = @program_transform_name@
-
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
+bin_PROGRAMS = hpuifilter$(EXEEXT)
+subdir = bin
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(srcdir)/alogin.in $(srcdir)/arancid.in $(srcdir)/blogin.in \
+ $(srcdir)/brancid.in $(srcdir)/cat5rancid.in \
+ $(srcdir)/clogin.in $(srcdir)/control_rancid.in \
+ $(srcdir)/cssrancid.in $(srcdir)/elogin.in \
+ $(srcdir)/erancid.in $(srcdir)/f10rancid.in \
+ $(srcdir)/flogin.in $(srcdir)/fnrancid.in $(srcdir)/francid.in \
+ $(srcdir)/hlogin.in $(srcdir)/hrancid.in $(srcdir)/htlogin.in \
+ $(srcdir)/htrancid.in $(srcdir)/jerancid.in \
+ $(srcdir)/jlogin.in $(srcdir)/jrancid.in $(srcdir)/mrancid.in \
+ $(srcdir)/nlogin.in $(srcdir)/nrancid.in $(srcdir)/nslogin.in \
+ $(srcdir)/nsrancid.in $(srcdir)/par.in $(srcdir)/prancid.in \
+ $(srcdir)/rancid-fe.in $(srcdir)/rancid.in \
+ $(srcdir)/rivlogin.in $(srcdir)/rivrancid.in \
+ $(srcdir)/rrancid.in $(srcdir)/tntlogin.in \
+ $(srcdir)/tntrancid.in $(srcdir)/xrancid.in \
+ $(srcdir)/zrancid.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/include/config.h
+CONFIG_CLEAN_FILES = control_rancid par rancid-fe alogin arancid \
+ blogin brancid cat5rancid clogin rancid cssrancid elogin \
+ erancid f10rancid flogin francid fnrancid jlogin jrancid \
+ jerancid hlogin hrancid htlogin htrancid mrancid nlogin \
+ nrancid nslogin nsrancid prancid rivlogin rivrancid rrancid \
+ tntlogin tntrancid xrancid zrancid
+am__installdirs = $(DESTDIR)$(bindir) $(DESTDIR)$(bindir)
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am_hpuifilter_OBJECTS = hpuifilter.$(OBJEXT)
+hpuifilter_OBJECTS = $(am_hpuifilter_OBJECTS)
+hpuifilter_LDADD = $(LDADD)
+binSCRIPT_INSTALL = $(INSTALL_SCRIPT)
+SCRIPTS = $(bin_SCRIPTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/hpuifilter.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(hpuifilter_SOURCES)
+DIST_SOURCES = $(hpuifilter_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ADMINMAILPLUS = @ADMINMAILPLUS@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+
+#CPPFLAGS += @PG_CPPFLAGS@
+#INCLUDES += -I$(top_srcdir)/include @PG_CPPFLAGS@
+#INCLUDES += -I$(top_srcdir)/include
+
+#CFLAGS += -g
+CFLAGS = -g -O0
COMM = @COMM@
CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
CVS = @CVS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
DIFF = @DIFF@
DIFF_CMD = @DIFF_CMD@
DIRNAME = @DIRNAME@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
ENV_PATH = @ENV_PATH@
+EXEEXT = @EXEEXT@
EXPECT_PATH = @EXPECT_PATH@
FIND = @FIND@
GREP = @GREP@
ID = @ID@
-INST_PROGS = @INST_PROGS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
LG_PING_CMD = @LG_PING_CMD@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
MAILPLUS = @MAILPLUS@
-MAINT = @MAINT@
MAKE = @MAKE@
MAKEINFO = @MAKEINFO@
MKDIR = @MKDIR@
+OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
PERLV = @PERLV@
PERLV_PATH = @PERLV_PATH@
PING_PATH = @PING_PATH@
-RD_BIN_DATAS = @RD_BIN_DATAS@
-RD_BIN_PROGS = @RD_BIN_PROGS@
-RD_UTIL_LG_PROGS = @RD_UTIL_LG_PROGS@
-RD_UTIL_PROGS = @RD_UTIL_PROGS@
RSH = @RSH@
SENDMAIL = @SENDMAIL@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
SORT = @SORT@
SSH = @SSH@
+STRIP = @STRIP@
TAR = @TAR@
TELNET = @TELNET@
TOUCH = @TOUCH@
U = @U@
VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build_alias = @build_alias@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+#AUTOMAKE_OPTIONS=foreign no-dependencies
AUTOMAKE_OPTIONS = foreign
-
-PREFIX = @prefix@
-
-bin_PROGRAMS = hpfilter
-hpfilter_SOURCES = hpfilter.c
-
-#CPPFLAGS += @PG_CPPFLAGS@
-#INCLUDES += -I$(top_srcdir)/include @PG_CPPFLAGS@
-#INCLUDES += -I$(top_srcdir)/include
-
-#CFLAGS += -g
-CFLAGS = -g -O0
-
+bin_SCRIPTS = cat5rancid control_rancid \
+ alogin arancid clogin blogin brancid cssrancid \
+ elogin erancid f10rancid flogin francid fnrancid \
+ jlogin jrancid jerancid \
+ hlogin hrancid htlogin htrancid \
+ mrancid nlogin nrancid nslogin nsrancid par prancid \
+ rancid rancid-fe rivlogin rivrancid rrancid \
+ tntlogin tntrancid xrancid zrancid\
+lg.cgi lgform.cgi rancid-cvs rancid-run
+EXTRA_DIST = lg.cgi.in lgform.cgi.in rancid-cvs.in rancid-run.in
+#dist_bin_SCRIPTS= $(bin_SCRIPTS:%=%.in)
+CLEANFILES = lg.cgi lgform.cgi rancid-cvs rancid-run
+#CLEANFILES= $(bin_SCRIPTS)
+hpuifilter_SOURCES = hpuifilter.c
YFLAGS = -d
#LFLAGS = -i
# no idea why automake doesnt clean these targets
#CLEANFILES= y.tab.c y.tab.h lex.yy.c conf.h conf.c conflex.c
-BIN_PROGS = @RD_BIN_PROGS@
-BIN_DATAS = @RD_BIN_DATAS@
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
-CONFIG_HEADER = ../include/config.h
-CONFIG_CLEAN_FILES = alogin arancid blogin brancid cat5rancid clogin \
-control_rancid create_cvs do-diffs elogin env erancid f10rancid flogin \
-francid jlogin jrancid hlogin hrancid mrancid par rancid-fe rancid \
-rename rrancid xrancid
-PROGRAMS = $(bin_PROGRAMS)
-
-
-DEFS = @DEFS@ -I. -I$(srcdir) -I../include
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@
-hpfilter_OBJECTS = hpfilter.o
-hpfilter_LDADD = $(LDADD)
-hpfilter_DEPENDENCIES =
-hpfilter_LDFLAGS =
-COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
-DIST_COMMON = Makefile.am Makefile.in alogin.in arancid.in blogin.in \
-brancid.in cat5rancid.in clogin.in control_rancid.in create_cvs.in \
-do-diffs.in elogin.in env.in erancid.in f10rancid.in flogin.in \
-francid.in hlogin.in hrancid.in jlogin.in jrancid.in mrancid.in par.in \
-rancid-fe.in rancid.in rename.in rrancid.in xrancid.in
-
-
-DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+#clean:
+# rm -f Makefile env $(BIN_DATAS) $(BIN_PROGS)
-GZIP_ENV = --best
-SOURCES = $(hpfilter_SOURCES)
-OBJECTS = $(hpfilter_OBJECTS)
+# auto_edit does the autoconf variable substitution. This allows the
+# substitution to have the full expansion of the variables, e.g.: $sysconfdir
+# will be /prefix/etc instead of ${prefix}/etc.
+#
+# This is a bit of a PITA, but is the method recommended by the autoconf
+# documentation.
+auto_edit = sed \
+ -e 's,@prefix\@,$(prefix),g' \
+ -e 's,@localstatedir\@,$(localstatedir),g' \
+ -e 's,@sysconfdir\@,$(sysconfdir),g' \
+ -e 's,@EXPECT_PATH\@,$(EXPECT_PATH),g' \
+ -e 's,@PERLV\@,$(PERLV),g' \
+ -e 's,@PERLV_PATH\@,$(PERLV_PATH),g' \
+ -e 's,@LG_PING_CMD\@,$(LG_PING_CMD),g' \
+ -e 's,@ADMINMAILPLUS\@,$(ADMINMAILPLUS),g' \
+ -e 's,@MAILPLUS\@,$(MAILPLUS),g'
+
+all: all-am
-all: all-redirect
.SUFFIXES:
-.SUFFIXES: .S .c .o .s
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
- cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps bin/Makefile
-
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- cd $(top_builddir) \
- && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-
-alogin: $(top_builddir)/config.status alogin.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-arancid: $(top_builddir)/config.status arancid.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-blogin: $(top_builddir)/config.status blogin.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-brancid: $(top_builddir)/config.status brancid.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-cat5rancid: $(top_builddir)/config.status cat5rancid.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-clogin: $(top_builddir)/config.status clogin.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-control_rancid: $(top_builddir)/config.status control_rancid.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-create_cvs: $(top_builddir)/config.status create_cvs.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-do-diffs: $(top_builddir)/config.status do-diffs.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-elogin: $(top_builddir)/config.status elogin.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-env: $(top_builddir)/config.status env.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-erancid: $(top_builddir)/config.status erancid.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-f10rancid: $(top_builddir)/config.status f10rancid.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-flogin: $(top_builddir)/config.status flogin.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-francid: $(top_builddir)/config.status francid.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-jlogin: $(top_builddir)/config.status jlogin.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-jrancid: $(top_builddir)/config.status jrancid.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-hlogin: $(top_builddir)/config.status hlogin.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-hrancid: $(top_builddir)/config.status hrancid.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-mrancid: $(top_builddir)/config.status mrancid.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-par: $(top_builddir)/config.status par.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-rancid-fe: $(top_builddir)/config.status rancid-fe.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-rancid: $(top_builddir)/config.status rancid.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-rename: $(top_builddir)/config.status rename.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-rrancid: $(top_builddir)/config.status rrancid.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-xrancid: $(top_builddir)/config.status xrancid.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-
-mostlyclean-binPROGRAMS:
-
-clean-binPROGRAMS:
- -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
-
-distclean-binPROGRAMS:
-
-maintainer-clean-binPROGRAMS:
-
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign bin/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign bin/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+control_rancid: $(top_builddir)/config.status $(srcdir)/control_rancid.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+par: $(top_builddir)/config.status $(srcdir)/par.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+rancid-fe: $(top_builddir)/config.status $(srcdir)/rancid-fe.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+alogin: $(top_builddir)/config.status $(srcdir)/alogin.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+arancid: $(top_builddir)/config.status $(srcdir)/arancid.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+blogin: $(top_builddir)/config.status $(srcdir)/blogin.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+brancid: $(top_builddir)/config.status $(srcdir)/brancid.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+cat5rancid: $(top_builddir)/config.status $(srcdir)/cat5rancid.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+clogin: $(top_builddir)/config.status $(srcdir)/clogin.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+rancid: $(top_builddir)/config.status $(srcdir)/rancid.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+cssrancid: $(top_builddir)/config.status $(srcdir)/cssrancid.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+elogin: $(top_builddir)/config.status $(srcdir)/elogin.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+erancid: $(top_builddir)/config.status $(srcdir)/erancid.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+f10rancid: $(top_builddir)/config.status $(srcdir)/f10rancid.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+flogin: $(top_builddir)/config.status $(srcdir)/flogin.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+francid: $(top_builddir)/config.status $(srcdir)/francid.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+fnrancid: $(top_builddir)/config.status $(srcdir)/fnrancid.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+jlogin: $(top_builddir)/config.status $(srcdir)/jlogin.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+jrancid: $(top_builddir)/config.status $(srcdir)/jrancid.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+jerancid: $(top_builddir)/config.status $(srcdir)/jerancid.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+hlogin: $(top_builddir)/config.status $(srcdir)/hlogin.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+hrancid: $(top_builddir)/config.status $(srcdir)/hrancid.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+htlogin: $(top_builddir)/config.status $(srcdir)/htlogin.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+htrancid: $(top_builddir)/config.status $(srcdir)/htrancid.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+mrancid: $(top_builddir)/config.status $(srcdir)/mrancid.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+nlogin: $(top_builddir)/config.status $(srcdir)/nlogin.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+nrancid: $(top_builddir)/config.status $(srcdir)/nrancid.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+nslogin: $(top_builddir)/config.status $(srcdir)/nslogin.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+nsrancid: $(top_builddir)/config.status $(srcdir)/nsrancid.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+prancid: $(top_builddir)/config.status $(srcdir)/prancid.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+rivlogin: $(top_builddir)/config.status $(srcdir)/rivlogin.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+rivrancid: $(top_builddir)/config.status $(srcdir)/rivrancid.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+rrancid: $(top_builddir)/config.status $(srcdir)/rrancid.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+tntlogin: $(top_builddir)/config.status $(srcdir)/tntlogin.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+tntrancid: $(top_builddir)/config.status $(srcdir)/tntrancid.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+xrancid: $(top_builddir)/config.status $(srcdir)/xrancid.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+zrancid: $(top_builddir)/config.status $(srcdir)/zrancid.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
- $(mkinstalldirs) $(DESTDIR)$(bindir)
+ $(mkdir_p) $(DESTDIR)$(bindir)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
- if test -f $$p; then \
- echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
- $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \
+ $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f || exit 1; \
else :; fi; \
done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
- list='$(bin_PROGRAMS)'; for p in $$list; do \
- rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f $(DESTDIR)$(bindir)/$$f"; \
+ rm -f $(DESTDIR)$(bindir)/$$f; \
done
-.c.o:
- $(COMPILE) -c $<
-
-.s.o:
- $(COMPILE) -c $<
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+hpuifilter$(EXEEXT): $(hpuifilter_OBJECTS) $(hpuifilter_DEPENDENCIES)
+ @rm -f hpuifilter$(EXEEXT)
+ $(LINK) $(hpuifilter_LDFLAGS) $(hpuifilter_OBJECTS) $(hpuifilter_LDADD) $(LIBS)
+install-binSCRIPTS: $(bin_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ $(mkdir_p) $(DESTDIR)$(bindir)
+ @list='$(bin_SCRIPTS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f $$d$$p; then \
+ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+ echo " $(binSCRIPT_INSTALL) $$d$$p $(DESTDIR)$(bindir)/$$f"; \
+ $(binSCRIPT_INSTALL) $$d$$p $(DESTDIR)$(bindir)/$$f; \
+ else :; fi; \
+ done
-.S.o:
- $(COMPILE) -c $<
+uninstall-binSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_SCRIPTS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+ echo " rm -f $(DESTDIR)$(bindir)/$$f"; \
+ rm -f $(DESTDIR)$(bindir)/$$f; \
+ done
mostlyclean-compile:
- -rm -f *.o core *.core
-
-clean-compile:
+ -rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
-maintainer-clean-compile:
-
-hpfilter: $(hpfilter_OBJECTS) $(hpfilter_DEPENDENCIES)
- @rm -f hpfilter
- $(LINK) $(hpfilter_LDFLAGS) $(hpfilter_OBJECTS) $(hpfilter_LDADD) $(LIBS)
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hpuifilter.Po@am__quote@
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
tags: TAGS
-TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
- list='$(SOURCES) $(HEADERS)'; \
- unique=`for i in $$list; do echo $$i; done | \
- awk ' { files[$$0] = 1; } \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
- test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
- || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
-
-mostlyclean-tags:
+ test -z "$(ETAGS_ARGS)$$tags$$unique" \
+ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
-clean-tags:
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
- -rm -f TAGS ID
-
-maintainer-clean-tags:
-
-distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
-
-subdir = bin
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
- @for file in $(DISTFILES); do \
- d=$(srcdir); \
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
if test -d $$d/$$file; then \
- cp -pr $$d/$$file $(distdir)/$$file; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
- || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
- || cp -p $$d/$$file $(distdir)/$$file || :; \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
fi; \
done
-
-info-am:
-info: info-am
-dvi-am:
-dvi: dvi-am
check-am: all-am
check: check-am
-installcheck-am:
-installcheck: installcheck-am
-install-exec-am: install-binPROGRAMS
+all-am: Makefile $(PROGRAMS) $(SCRIPTS)
+installdirs:
+ $(mkdir_p) $(DESTDIR)$(bindir) $(DESTDIR)$(bindir)
+install: install-am
install-exec: install-exec-am
-
-install-data-am:
install-data: install-data-am
+uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-install: install-am
-uninstall-am: uninstall-binPROGRAMS
-uninstall: uninstall-am
-all-am: Makefile $(PROGRAMS)
-all-redirect: all-am
-install-strip:
- $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
-installdirs:
- $(mkinstalldirs) $(DESTDIR)$(bindir)
-
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
- -rm -f Makefile $(CONFIG_CLEAN_FILES)
- -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+ -rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
-mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-compile \
- mostlyclean-tags mostlyclean-generic
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
-mostlyclean: mostlyclean-am
+clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
-clean-am: clean-binPROGRAMS clean-compile clean-tags clean-generic \
- mostlyclean-am
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
-clean: clean-am
+dvi: dvi-am
-distclean-am: distclean-binPROGRAMS distclean-compile distclean-tags \
- distclean-generic clean-am
+dvi-am:
-distclean: distclean-am
+html: html-am
-maintainer-clean-am: maintainer-clean-binPROGRAMS \
- maintainer-clean-compile maintainer-clean-tags \
- maintainer-clean-generic distclean-am
- @echo "This command is intended for maintainers to use;"
- @echo "it deletes files that may require special tools to rebuild."
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-binPROGRAMS install-binSCRIPTS
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
-.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
-maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
-mostlyclean-compile distclean-compile clean-compile \
-maintainer-clean-compile tags mostlyclean-tags distclean-tags \
-clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \
-check-am installcheck-am installcheck install-exec-am install-exec \
-install-data-am install-data install-am install uninstall-am uninstall \
-all-redirect all-am all installdirs mostlyclean-generic \
-distclean-generic clean-generic maintainer-clean-generic clean \
-mostlyclean distclean maintainer-clean
-
-
-install: all
- for prog in $(BIN_PROGS) ; do \
- $(INSTALL) $$prog $(bindir); \
- done; \
- if test -f $(bindir)/env ; then \
- echo "WARNING: *** $(bindir)/env exists: installing as env.new."; \
- echo " *** review env.new for new/deprecated switches"; \
- $(INSTALL_DATA) env $(bindir)/env.new; \
- else \
- $(INSTALL_DATA) env $(bindir); \
- fi
-# BIN_DATAS are empty at the moment.
-# for prog in $(BIN_DATAS) ; do \
-# $(INSTALL_DATA) $$prog $(PREFIX)/bin; \
-# done; \
+mostlyclean: mostlyclean-am
-#clean:
-# rm -f Makefile env $(BIN_DATAS) $(BIN_PROGS)
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
+ uninstall-info-am
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+ clean-generic ctags distclean distclean-compile \
+ distclean-generic distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-binPROGRAMS \
+ install-binSCRIPTS install-data install-data-am install-exec \
+ install-exec-am install-info install-info-am install-man \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-binPROGRAMS \
+ uninstall-binSCRIPTS uninstall-info-am
+
+
+lg.cgi: Makefile $(srcdir)/lg.cgi.in
+ rm -f lg.cgi lg.cgi.tmp; \
+ $(auto_edit) $(srcdir)/lg.cgi.in >lg.cgi.tmp; \
+ chmod +x lg.cgi.tmp; \
+ mv lg.cgi.tmp lg.cgi
-#distclean: clean
-# rm -f config.log config.status
+lgform.cgi: Makefile $(srcdir)/lgform.cgi.in
+ rm -f lgform.cgi lgform.cgi.tmp; \
+ $(auto_edit) $(srcdir)/lgform.cgi.in >lgform.cgi.tmp; \
+ chmod +x lgform.cgi.tmp; \
+ mv lgform.cgi.tmp lgform.cgi
-#distdir:
-# for file in Makefile.in configure.in env.in $(BIN_DATAS:=.in) ; do \
-# $(INSTALL_DATA) $$file $(distdir); \
-# done
-# for file in configure $(BIN_PROGS:=.in) ; do \
-# $(INSTALL) $$file $(distdir); \
-# done
+rancid-cvs: Makefile $(srcdir)/rancid-cvs.in
+ rm -f rancid-cvs rancid-cvs.tmp; \
+ $(auto_edit) $(srcdir)/rancid-cvs.in >rancid-cvs.tmp; \
+ chmod +x rancid-cvs.tmp; \
+ mv rancid-cvs.tmp rancid-cvs
+rancid-run: Makefile $(srcdir)/rancid-run.in
+ rm -f rancid-run rancid-run.tmp; \
+ $(auto_edit) $(srcdir)/rancid-run.in >rancid-run.tmp; \
+ chmod +x rancid-run.tmp; \
+ mv rancid-run.tmp rancid-run
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/bin/alogin.in b/bin/alogin.in
index 03f12ca..91623fb 100644
--- a/bin/alogin.in
+++ b/bin/alogin.in
@@ -1,21 +1,26 @@
-#!@EXPECT_PATH@ --
+#! @EXPECT_PATH@ --
##
+## $Id: alogin.in,v 1.22 2004/01/11 05:39:15 heas Exp $
##
-## Copyright (C) 1997-2001 by Henry Kilmer, Erik Sherk and Pete Whiting.
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
+# The login expect scripts were based on Erik Sherk's gwtn, by permission.
+#
# alogin - Alteon WebOS switch login
#
# afort@choqolat.org is responsible for this particular mess
@@ -39,8 +44,9 @@ set do_command 0
set do_script 0
# The default is to automatically enable
set enable 1
-# The default is that you login non-enabled (tacacs can have you login already enabled)
-set autoenable 0
+# The default is that you login non-enabled (tacacs can have you login already
+# enabled)
+set avautoenable 0
# The default is to look in the password file to find the passwords. This
# tracks if we receive them on the command line.
set do_passwd 1
@@ -50,12 +56,14 @@ if {[ info exists env(CISCO_USER) ] } {
set default_user $env(CISCO_USER)
} elseif {[ info exists env(USER) ]} {
set default_user $env(USER)
+} elseif {[ info exists env(LOGNAME) ]} {
+ set default_user $env(LOGNAME)
} else {
# This uses "id" which I think is portable. At least it has existed
# (without options) on all machines/OSes I've been on recently -
# unlike whoami or id -nu.
if [ catch {exec id} reason ] {
- send_error "Error: could not exec id: $reason\n"
+ send_error "\nError: could not exec id: $reason\n"
exit 1
}
regexp {\(([^)]*)} "$reason" junk default_user
@@ -95,7 +103,7 @@ for {set i 0} {$i < $argc} {incr i} {
incr i
set E$varname $varvalue
} else {
- send_user "Error: invalid format for -E in $arg\n"
+ send_user "\nError: invalid format for -E in $arg\n"
exit 1
}
# Enable Password
@@ -118,7 +126,7 @@ for {set i 0} {$i < $argc} {incr i} {
set sfile [ lindex $argv $i ]
}
if { ! [ file readable $sfile ] } {
- send_user "Error: Can't read $sfile\n"
+ send_user "\nError: Can't read $sfile\n"
exit 1
}
set do_script 1
@@ -160,12 +168,12 @@ for {set i 0} {$i < $argc} {incr i} {
set do_command 1
# Do we enable?
} -noenable {
- # ignore -noenable
+ # ignore -noenable
# Does tacacs automatically enable us?
} -autoenable {
- # ignore -autoenable
+ # ignore -autoenable
} -* {
- send_user "Error: Unknown argument! $arg\n"
+ send_user "\nError: Unknown argument! $arg\n"
send_user $usage
exit 1
} default {
@@ -175,7 +183,7 @@ for {set i 0} {$i < $argc} {incr i} {
}
# Process routers...no routers listed is an error.
if { $i == $argc } {
- send_user "Error: $usage"
+ send_user "\nError: $usage"
}
# Only be quiet if we are running a script (it can log its output
@@ -241,16 +249,16 @@ proc find {var router} {
proc source_password_file { password_file } {
global env
if { ! [file exists $password_file] } {
- send_user "Error: password file ($password_file) does not exist\n"
+ send_user "\nError: password file ($password_file) does not exist\n"
exit 1
}
file stat $password_file fileinfo
if { [expr ($fileinfo(mode) & 007)] != 0000 } {
- send_user "Error: $password_file must not be world readable/writable\n"
+ send_user "\nError: $password_file must not be world readable/writable\n"
exit 1
}
if [ catch {source $password_file} reason ] {
- send_user "Error: $reason\n"
+ send_user "\nError: $reason\n"
exit 1
}
}
@@ -258,7 +266,7 @@ proc source_password_file { password_file } {
# Log into the router.
proc login { router user userpswd passwd prompt cmethod cyphertype } {
global spawn_id in_proc do_command do_script
- global u_prompt p_prompt
+ global u_prompt p_prompt sshcmd
set in_proc 1
set uprompt_seen 0
@@ -277,17 +285,17 @@ proc login { router user userpswd passwd prompt cmethod cyphertype } {
exit 1
}
} elseif ![string compare $prog "ssh"] {
- if [ catch {spawn ssh -c $cyphertype -x -l $user $router} reason ] {
- send_user "Error: ssh failed: $reason\n"
+ if [ catch {spawn $sshcmd -c $cyphertype -x -l $user $router} reason ] {
+ send_user "\nError: $sshcmd failed: $reason\n"
exit 1
}
} elseif ![string compare $prog "rsh"] {
if [ catch {spawn rsh -l $user $router} reason ] {
- send_user "Error: rsh failed: $reason\n"
+ send_user "\nError: rsh failed: $reason\n"
exit 1
}
} else {
- puts "ERROR: unknown connection method: $prog"
+ puts "\nError: unknown connection method: $prog"
return 1
}
incr progs -1
@@ -319,17 +327,17 @@ proc login { router user userpswd passwd prompt cmethod cyphertype } {
close; wait
sleep 0.3
expect eof
- send_user "Error: Connection Refused\n"; wait; return 1
- } eof { send_user "Error: Couldn't login\n"; wait; return 1
+ send_user "\nError: Connection Refused\n"; wait; return 1
+ } eof { send_user "\nError: Couldn't login\n"; wait; return 1
} "Unknown host\r\n" {
expect eof
- send_user "Error: Unknown host\n"; wait; return 1
+ send_user "\nError: Unknown host\n"; wait; return 1
} "Host is unreachable" {
expect eof
- send_user "Error: Host Unreachable!\n"; wait; return 1
+ send_user "\nError: Host Unreachable!\n"; wait; return 1
} "No address associated with name" {
expect eof
- send_user "Error: Unknown host\n"; wait; return 1
+ send_user "\nError: Unknown host\n"; wait; return 1
}
-re "(Host key not found |The authenticity of host .* be established).*\(yes\/no\)\?" {
send "yes\r"
@@ -362,10 +370,10 @@ proc login { router user userpswd passwd prompt cmethod cyphertype } {
send "y\r"
exp_continue
}
- "Password incorrect" { send_user "Error: Check your password for $router\n";
+ "Password incorrect" { send_user "\nError: Check your password for $router\n";
catch {close}; wait; return 1 }
-re "$prompt" { break; }
- denied { send_user "Error: Check your passwd for $router\n"
+ denied { send_user "\nError: Check your passwd for $router\n"
catch {close}; wait; return 1
}
"\r\n" { exp_continue; }
@@ -439,10 +447,10 @@ 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 "\nError - no password for $router in $password_file.\n"
continue
}
- set passwd [lindex $pswd 0]
+ set passwd [join [lindex $pswd 0] ""]
}
# Figure out username
@@ -450,7 +458,7 @@ foreach router [lrange $argv $i end] {
# command line username
set ruser $username
} else {
- set ruser [find user $router]
+ set ruser [join [find user $router] ""]
if { "$ruser" == "" } { set ruser $default_user }
}
@@ -459,7 +467,7 @@ foreach router [lrange $argv $i end] {
# command line username
set userpswd $userpasswd
} else {
- set userpswd [find userpassword $router]
+ set userpswd [join [find userpassword $router] ""]
if { "$userpswd" == "" } { set userpswd $passwd }
}
@@ -468,13 +476,13 @@ foreach router [lrange $argv $i end] {
if { "$u_prompt" == "" } {
set u_prompt "(Username|login| Login):"
} else {
- set u_prompt [lindex $u_prompt 0]
+ set u_prompt [join [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 p_prompt [join [lindex $p_prompt 0] ""]
}
# Figure out cypher type
@@ -490,6 +498,10 @@ foreach router [lrange $argv $i end] {
set cmethod [find method $router]
if { "$cmethod" == "" } { set cmethod {{telnet} {ssh}} }
+ # Figure out the SSH executable name
+ set sshcmd [find sshcmd $router]
+ if { "$sshcmd" == "" } { set sshcmd {ssh} }
+
# Login to the router
if {[login $router $ruser $userpswd $passwd $prompt $cmethod $cyphertype]} {
continue
diff --git a/bin/arancid.in b/bin/arancid.in
index f51a6c3..a2bf1ef 100644
--- a/bin/arancid.in
+++ b/bin/arancid.in
@@ -1,23 +1,26 @@
-#!@PERLV_PATH@
+#! @PERLV_PATH@
+##
+## $Id: arancid.in,v 1.14 2004/01/11 03:49:13 heas Exp $
##
## Hacked version of rancid for Alteon WebOS switches
## tested with: ad3 v8.1.18
## afort@choqolat.org (andrew fort)
##
-##
-## Copyright (C) 1997-2001 by Henry Kilmer.
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
# RANCID - Really Awesome New Cisco confIg Differ
@@ -27,7 +30,7 @@
# usage: arancid [-d] [-l] [-f filename | $host]
#
use Getopt::Std;
-getopts('dflm');
+getopts('dfl');
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
@@ -240,7 +243,11 @@ TOP: while(<INPUT>) {
while (/>>.*$prompt\s*($cmds_regexp)\s*$/) {
$cmd = $1;
- if (!defined($prompt)) {$prompt = ($_ =~ /^([^#]+#)/)[0]; }
+ if (!defined($prompt)) {
+ $prompt = ($_ =~ /^([^#]+#)/)[0];
+ $prompt =~ s/([][}{)(\\])/\\$1/g;
+ print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
+ }
print STDERR ("HIT COMMAND:$_") if ($debug);
if (!defined($commands{$cmd})) {
print STDERR "$host: found unexpected command - \"$cmd\"\n";
diff --git a/bin/blogin.in b/bin/blogin.in
index 23bf97c..92d2e8c 100644
--- a/bin/blogin.in
+++ b/bin/blogin.in
@@ -1,26 +1,33 @@
-#!@EXPECT_PATH@ --
+#! @EXPECT_PATH@ --
##
+## $Id: blogin.in,v 1.22 2004/01/11 05:39:15 heas Exp $
##
-## Copyright (C) 1997-2001 by Henry Kilmer, Erik Sherk and Pete Whiting.
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
+# The login expect scripts were based on Erik Sherk's gwtn, by permission.
+#
# blogin - Bay Networks(Nortel) login
#
-# Unlike the Cisco's, there is no enable function on the Bay's.
-# Instead there are seperate User and Manager accounts. A 'system' command
-# exists, which i am told does nothing.
+# Unlike the Cisco's, there is no enable function on the Bay's. Instead
+# there are seperate User and Manager accounts. A 'system' command exists,
+# which I am told does nothing.
+#
+# The "bcc>" prompt changes to "box#", not "bcc#" after the config command.
#
# Usage line
@@ -40,8 +47,9 @@ set do_command 0
set do_script 0
# The default is to automatically enable
set enable 0
-# The default is that you login non-enabled (tacacs can have you login already enabled)
-set autoenable 0
+# The default is that you login non-enabled (tacacs can have you login already
+# enabled)
+set avautoenable 0
# The default is to look in the password file to find the passwords. This
# tracks if we receive them on the command line.
set do_passwd 1
@@ -52,6 +60,8 @@ if {[ info exists env(CISCO_USER) ] } {
set default_user $env(CISCO_USER)
} elseif {[ info exists env(USER) ]} {
set default_user $env(USER)
+} elseif {[ info exists env(LOGNAME) ]} {
+ set default_user $env(LOGNAME)
} else {
# This uses "id" which I think is portable. At least it has existed
# (without options) on all machines/OSes I've been on recently -
@@ -107,7 +117,7 @@ for {set i 0} {$i < $argc} {incr i} {
if {[ regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} {
set E$varname $varvalue
} else {
- send_user "Error: invalid format for -E in $arg\n"
+ send_user "\nError: invalid format for -E in $arg\n"
exit 1
}
# Enable Password
@@ -176,7 +186,7 @@ for {set i 0} {$i < $argc} {incr i} {
set enable 0
# Does tacacs automatically enable us?
} -autoenable {
- set autoenable 1
+ set avautoenable 1
set enable 0
} -* {
send_user "\nError: Unknown argument! $arg\n"
@@ -272,7 +282,7 @@ 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
+ global u_prompt p_prompt e_prompt sshcmd
set in_proc 1
# try each of the connection methods in $cmethod until one is successful
@@ -290,8 +300,8 @@ proc login { router user userpswd passwd enapasswd prompt cmethod cyphertype } {
exit 1
}
} elseif ![string compare $prog "ssh"] {
- if [ catch {spawn ssh -c $cyphertype -x -l $user $router} reason ] {
- send_user "\nError: ssh failed: $reason\n"
+ if [ catch {spawn $sshcmd -c $cyphertype -x -l $user $router} reason ] {
+ send_user "\nError: $sshcmd failed: $reason\n"
exit 1
}
} elseif ![string compare $prog "rsh"] {
@@ -408,10 +418,13 @@ proc do_enable { enauser enapasswd } {
-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
- }
+ denied { send_user "\nError: Check your Enable passwd\n"
+ return 1
+ }
+ "% Bad passwords" {
+ send_user "\nError: Check your Enable passwd\n"
+ return 1
+ }
}
# We set the prompt variable (above) so script files don't need
# to know what it is.
@@ -440,7 +453,7 @@ proc run_commands { prompt command } {
expect {
-re "^\[^\n\r *]*$reprompt" {}
-re "^\[^\n\r]*$reprompt." { exp_continue }
- -re "\[\n\r]" { exp_continue }
+ -re "\[\n\r]+" { exp_continue }
}
}
} else {
@@ -448,7 +461,7 @@ proc run_commands { prompt command } {
expect {
-re "^\[^\n\r *]*$reprompt" {}
-re "^\[^\n\r]*$reprompt." { exp_continue }
- -re "\[\n\r]" { exp_continue }
+ -re "\[\n\r]+" { exp_continue }
}
}
send "logout\r"
@@ -473,7 +486,9 @@ foreach router [lrange $argv $i end] {
# Since autoenable is off by default, if we have it defined, it
# was done on the command line. If it is not specifically set on the
# command line, check the password file.
- if $autoenable {
+ if $avautoenable {
+ set autoenable 1
+ set enable 0
set prompt "#"
} else {
set ae [find autoenable $router]
@@ -496,15 +511,15 @@ 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 "\nError - 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"
+ send_user "\nError - no enable password for $router in $password_file.\n"
continue
}
- set passwd [lindex $pswd 0]
- set enapasswd [lindex $pswd 1]
+ set passwd [join [lindex $pswd 0] ""]
+ set enapasswd [join [lindex $pswd 1] ""]
}
# Figure out username
@@ -512,7 +527,7 @@ foreach router [lrange $argv $i end] {
# command line username
set ruser $username
} else {
- set ruser [find user $router]
+ set ruser [join [find user $router] ""]
if { "$ruser" == "" } { set ruser $default_user }
}
@@ -521,7 +536,7 @@ foreach router [lrange $argv $i end] {
# command line username
set userpswd $userpasswd
} else {
- set userpswd [find userpassword $router]
+ set userpswd [join [find userpassword $router] ""]
if { "$userpswd" == "" } { set userpswd $passwd }
}
@@ -530,7 +545,7 @@ foreach router [lrange $argv $i end] {
# command line enausername
set enauser $enausername
} else {
- set enauser [find enauser $router]
+ set enauser [join [find enauser $router] ""]
if { "$enauser" == "" } { set enauser $ruser }
}
@@ -539,19 +554,19 @@ foreach router [lrange $argv $i end] {
if { "$u_prompt" == "" } {
set u_prompt "(Username|login|user name):"
} else {
- set u_prompt [lindex $u_prompt 0]
+ set u_prompt [join [lindex $u_prompt 0] ""]
}
set p_prompt [find passprompt $router]
if { "$p_prompt" == "" } {
set p_prompt "(\[Pp]assword|passwd):"
} else {
- set p_prompt [lindex $p_prompt 0]
+ set p_prompt [join [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]
+ set e_prompt [join [lindex $e_prompt 0] ""]
}
# Figure out cypher type
@@ -567,6 +582,10 @@ foreach router [lrange $argv $i end] {
set cmethod [find method $router]
if { "$cmethod" == "" } { set cmethod {{telnet}} }
+ # Figure out the SSH executable name
+ set sshcmd [find sshcmd $router]
+ if { "$sshcmd" == "" } { set sshcmd {ssh} }
+
# Login to the router
if {[login $router $ruser $userpswd $passwd $enapasswd $prompt $cmethod $cyphertype]} {
continue
diff --git a/bin/brancid.in b/bin/brancid.in
index 2ea7e3b..c2e602e 100644
--- a/bin/brancid.in
+++ b/bin/brancid.in
@@ -1,20 +1,23 @@
-#!@PERLV_PATH@
+#! @PERLV_PATH@
##
+## $Id: brancid.in,v 1.16 2004/01/11 03:49:13 heas Exp $
## hacked version of Hank's rancid - this one tries to deal with Bay's.
##
-## Copyright (C) 1997-2001 by Henry Kilmer.
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
# RANCID - Really Awesome New Cisco confIg Differ
@@ -22,7 +25,7 @@
# usage: rancid [-d] [-l] [-f filename | $host]
#
use Getopt::Std;
-getopts('dflm');
+getopts('dfl');
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
@@ -246,7 +249,8 @@ TOP: while(<INPUT>) {
$cmd = $1;
if (!defined($prompt)) {
$prompt = ($_ =~ /^([^>]+>)/)[0];
- $prompt =~ s/([][])/\\$1/g;
+ $prompt =~ s/([][}{)(\\])/\\$1/g;
+ print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
}
print STDERR ("HIT COMMAND:$_") if ($debug);
if (! defined($commands{$cmd})) {
diff --git a/bin/cat5rancid.in b/bin/cat5rancid.in
index c8219d8..f1214a1 100755..100644
--- a/bin/cat5rancid.in
+++ b/bin/cat5rancid.in
@@ -1,19 +1,22 @@
-#!@PERLV_PATH@
+#! @PERLV_PATH@
##
+## $Id: cat5rancid.in,v 1.36 2004/01/11 03:49:13 heas Exp $
##
-## Copyright (C) 1997-2001 by Henry Kilmer.
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
# RANCID - Really Awesome New Cisco confIg Differ
@@ -21,7 +24,7 @@
# usage: rancid [-d] [-l] [-f filename | $host]
#
use Getopt::Std;
-getopts('dflm');
+getopts('dfl');
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
@@ -783,7 +786,7 @@ sub ShowPortIfindex {
}
}
-# This routine processes a "write term"
+# This routine processes a "write term {all}"
sub WriteTerm {
print STDERR " In WriteTerm: $_" if ($debug);
@@ -791,7 +794,10 @@ sub WriteTerm {
while (<INPUT>) {
tr/\015//d;
last if (/^$prompt/);
+ last if (/^Unknown host /); # error when write term all
+ # is not supported
next if (/^\.+$/ | /^$/);
+ return(0) if ($found_end);
/Non-Volatile memory is in use/ && return(-1); # NvRAM is locked
# skip the crap
next if (/^This command shows non-default configurations only./i);
@@ -862,6 +868,7 @@ sub WriteTerm {
next;
}
/fair-queue individual-limit/ && next;
+ /^set port security \d+\/\d+ \S+-\S+\-/ && next;
# sort ip explicit-paths.
if (/^ip explicit-path name (\S+)/) {
my($key) = $1;
@@ -995,6 +1002,7 @@ sub DoNothing {print STDOUT;}
'dir sup-microcode:' => "DirSlotN",
'show module' => "ShowModule",
'show port ifindex' => "ShowPortIfindex",
+ 'write term all' => "WriteTerm",
'write term' => "WriteTerm"
);
# keys() doesnt return things in the order entered and the order of the
@@ -1010,6 +1018,7 @@ sub DoNothing {print STDOUT;}
"dir sup-microcode:",
"show module",
"show port ifindex",
+ "write term all",
"write term"
);
$cisco_cmds=join(";",@commands);
@@ -1062,7 +1071,11 @@ TOP: while(<INPUT>) {
}
while (/> \(enable\)\s*($cmds_regexp)\s*$/) {
$cmd = $1;
- if (!defined($prompt)) {$prompt = ($_ =~ /^([^>]+>)/)[0]; }
+ if (!defined($prompt)) {
+ $prompt = ($_ =~ /^([^>]+>)/)[0];
+ $prompt =~ s/([][}{)(\\])/\\$1/g;
+ print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
+ }
print STDERR ("HIT COMMAND:$_") if ($debug);
if (! defined($commands{$cmd})) {
print STDERR "$host: found unexpected command - \"$cmd\"\n";
diff --git a/bin/clogin.in b/bin/clogin.in
index c026699..281d634 100755..100644
--- a/bin/clogin.in
+++ b/bin/clogin.in
@@ -1,21 +1,26 @@
-#!@EXPECT_PATH@ --
+#! @EXPECT_PATH@ --
##
+## $Id: clogin.in,v 1.72 2004/01/11 05:39:15 heas Exp $
##
-## Copyright (C) 1997-2001 by Henry Kilmer, Erik Sherk and Pete Whiting.
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
+# The login expect scripts were based on Erik Sherk's gwtn, by permission.
+#
# clogin - Cisco login
#
# Most options are intuitive for logging into a Cisco router.
@@ -43,8 +48,9 @@ set do_command 0
set do_script 0
# The default is to automatically enable
set enable 1
-# The default is that you login non-enabled (tacacs can have you login already enabled)
-set autoenable 0
+# The default is that you login non-enabled (tacacs can have you login already
+# enabled)
+set avautoenable 0
# The default is to look in the password file to find the passwords. This
# tracks if we receive them on the command line.
set do_passwd 1
@@ -57,6 +63,8 @@ if {[ info exists env(CISCO_USER) ] } {
set default_user $env(CISCO_USER)
} elseif {[ info exists env(USER) ]} {
set default_user $env(USER)
+} elseif {[ info exists env(LOGNAME) ]} {
+ set default_user $env(LOGNAME)
} else {
# This uses "id" which I think is portable. At least it has existed
# (without options) on all machines/OSes I've been on recently -
@@ -112,7 +120,7 @@ for {set i 0} {$i < $argc} {incr i} {
if {[ regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} {
set E$varname $varvalue
} else {
- send_user "Error: invalid format for -E in $arg\n"
+ send_user "\nError: invalid format for -E in $arg\n"
exit 1
}
# Enable Password
@@ -184,7 +192,7 @@ for {set i 0} {$i < $argc} {incr i} {
set enable 0
# Does tacacs automatically enable us?
} -autoenable {
- set autoenable 1
+ set avautoenable 1
set enable 0
} -* {
send_user "\nError: Unknown argument! $arg\n"
@@ -280,7 +288,7 @@ proc source_password_file { password_file } {
# Log into the router.
proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
global spawn_id in_proc do_command do_script platform
- global prompt u_prompt p_prompt e_prompt
+ global prompt u_prompt p_prompt e_prompt sshcmd
set in_proc 1
set uprompt_seen 0
@@ -299,8 +307,8 @@ proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
exit 1
}
} elseif ![string compare $prog "ssh"] {
- if [ catch {spawn ssh -c $cyphertype -x -l $user $router} reason ] {
- send_user "\nError: ssh failed: $reason\n"
+ if [ catch {spawn $sshcmd -c $cyphertype -x -l $user $router} reason ] {
+ send_user "\nError: $sshcmd failed: $reason\n"
exit 1
}
} elseif ![string compare $prog "rsh"] {
@@ -344,24 +352,32 @@ proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
# then it will just send the passwd.
# if telnet fails with connection refused, try ssh
expect {
- -re "(Connection refused|Secure connection \[^\n\r]+ refused|Connection closed by)" {
+ -re "(Connection refused|Secure connection \[^\n\r]+ refused)" {
+ catch {close}; wait
+ if !$progs {
+ send_user "\nError: Connection Refused ($prog): $router\n"
+ return 1
+ }
+ }
+ -re "(Connection closed by|Connection to \[^\n\r]+ closed)" {
catch {close}; wait
if !$progs {
- send_user "\nError: Connection Refused ($prog)\n"; return 1
+ send_user "\nError: Connection closed ($prog): $router\n"
+ return 1
}
}
- eof { send_user "\nError: Couldn't login\n"; wait; return 1 }
+ eof { send_user "\nError: Couldn't login: $router\n"; wait; return 1 }
-nocase "unknown host\r" {
catch {close};
- send_user "\nError: Unknown host\n"; wait; return 1
+ send_user "\nError: Unknown host $router\n"; wait; return 1
}
"Host is unreachable" {
catch {close};
- send_user "\nError: Host Unreachable!\n"; wait; return 1
+ send_user "\nError: Host Unreachable: $router\n"; wait; return 1
}
"No address associated with name" {
catch {close};
- send_user "\nError: Unknown host\n"; wait; return 1
+ send_user "\nError: Unknown host $router\n"; wait; return 1
}
-re "(Host key not found |The authenticity of host .* be established).*\(yes\/no\)\?" {
send "yes\r"
@@ -387,6 +403,12 @@ proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
send_user "\nError: Check your passwd for $router\n"
return 1
}
+ -re "^Enter Selection: " {
+ # Catalyst 1900s have some lame menu. Enter
+ # K to reach a command-line.
+ send "K\r"
+ exp_continue;
+ }
-re "@\[^\r\n]+ $p_prompt" {
# ssh pwd prompt
sleep 1
@@ -407,9 +429,9 @@ proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
}
exp_continue
}
- "$prompt" { break; }
+ -re "$prompt" { break; }
"Login invalid" {
- send_user "\nError: Invalid login\n";
+ send_user "\nError: Invalid login: $router\n";
catch {close}; wait; return 1
}
}
@@ -431,10 +453,19 @@ proc do_enable { enauser enapasswd } {
-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
- }
+ "denied" {
+ # % Access denied - from local auth
+ send_user "\nError: Check your Enable passwd\n";
+ return 1
+ }
+ "% Error in authentication" {
+ send_user "\nError: Check your Enable passwd\n"
+ return 1
+ }
+ "% Bad passwords" {
+ send_user "\nError: Check your Enable passwd\n"
+ return 1
+ }
}
# We set the prompt variable (above) so script files don't need
# to know what it is.
@@ -449,16 +480,19 @@ proc run_commands { prompt command } {
# If the prompt is (enable), then we are on a switch and the
# command is "set length 0"; otherwise its "term length 0".
- # skip if its an extreme.
+ # skip if its an extreme (since the pager can not be disabled on a
+ # per-vty basis).
if { [ string compare "extreme" "$platform" ] } {
if [ regexp -- ".*> .*enable" "$prompt" ] {
send "set length 0\r"
} else {
send "term length 0\r"
}
- regsub -all "\[)(]" $prompt {\\&} reprompt
- # match cisco config mode prompts too, but not for catalyst ie: (enable)
- regsub -all "\[#>]$" $reprompt {(\\([^\\r\\n]+\\))?&} reprompt
+ # escape any parens in the prompt, such as "(enable)"
+ regsub -all {[)(]} $prompt {\\&} reprompt
+ # match cisco config mode prompts too, such as router(config-if)#,
+ # but catalyst does not change in this fashion.
+ regsub -all {^(.{1,14}).*([#>])$} $reprompt {\1([^#>\r\n]+)?[#>](\\([^)\\r\\n]+\\))?} reprompt
expect {
-re $reprompt {}
-re "\[\n\r]+" { exp_continue }
@@ -466,6 +500,7 @@ proc run_commands { prompt command } {
} else {
regsub -all "\[)(]" $prompt {\\&} reprompt
}
+
# this is the only way i see to get rid of more prompts in o/p..grrrrr
log_user 0
# Is this a multi-command?
@@ -540,11 +575,18 @@ proc run_commands { prompt command } {
send "quit\r"
}
expect {
+ -re "^\[^\n\r *]*$reprompt" {
+ # the Cisco CE and Jnx ERX
+ # return to non-enabled mode
+ # on exit in enabled mode.
+ send "exit\r"
+ exp_continue;
+ }
"Do you wish to save your configuration changes" {
send "n\r"
exp_continue
}
- "\n" { exp_continue }
+ -re "\[\n\r]+" { exp_continue }
timeout { return 0 }
eof { return 0 }
}
@@ -564,14 +606,16 @@ foreach router [lrange $argv $i end] {
# Since autoenable is off by default, if we have it defined, it
# was done on the command line. If it is not specifically set on the
# command line, check the password file.
- if $autoenable {
- set prompt "#"
+ if $avautoenable {
+ set autoenable 1
+ set enable 0
+ set prompt "(#| \\(enable\\))"
} else {
set ae [find autoenable $router]
if { "$ae" == "1" } {
set autoenable 1
set enable 0
- set prompt "#"
+ set prompt "(#| \\(enable\\))"
} else {
set autoenable 0
set prompt ">"
@@ -587,15 +631,15 @@ 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 "\nError: no password for $router in $password_file.\n"
continue
}
if { $enable && $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2 } {
- send_user "Error: no enable password for $router in $password_file.\n"
+ send_user "\nError: no enable password for $router in $password_file.\n"
continue
}
- set passwd [lindex $pswd 0]
- set enapasswd [lindex $pswd 1]
+ set passwd [join [lindex $pswd 0] ""]
+ set enapasswd [join [lindex $pswd 1] ""]
}
# Figure out username
@@ -603,7 +647,7 @@ foreach router [lrange $argv $i end] {
# command line username
set ruser $username
} else {
- set ruser [find user $router]
+ set ruser [join [find user $router] ""]
if { "$ruser" == "" } { set ruser $default_user }
}
@@ -612,7 +656,7 @@ foreach router [lrange $argv $i end] {
# command line username
set userpswd $userpasswd
} else {
- set userpswd [find userpassword $router]
+ set userpswd [join [find userpassword $router] ""]
if { "$userpswd" == "" } { set userpswd $passwd }
}
@@ -621,7 +665,7 @@ foreach router [lrange $argv $i end] {
# command line enausername
set enauser $enausername
} else {
- set enauser [find enauser $router]
+ set enauser [join [find enauser $router] ""]
if { "$enauser" == "" } { set enauser $ruser }
}
@@ -630,34 +674,38 @@ foreach router [lrange $argv $i end] {
if { "$u_prompt" == "" } {
set u_prompt "(Username|Login|login|user name):"
} else {
- set u_prompt [lindex $u_prompt 0]
+ set u_prompt [join [lindex $u_prompt 0] ""]
}
set p_prompt [find passprompt $router]
if { "$p_prompt" == "" } {
set p_prompt "(\[Pp]assword|passwd):"
} else {
- set p_prompt [lindex $p_prompt 0]
+ set p_prompt [join [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]
+ set e_prompt [join [lindex $e_prompt 0] ""]
}
# Figure out cypher type
if {[info exists cypher]} {
- # command line cypher type
- set cyphertype $cypher
+ # command line cypher type
+ set cyphertype $cypher
} else {
- set cyphertype [find cyphertype $router]
- if { "$cyphertype" == "" } { set cyphertype "3des" }
+ set cyphertype [find cyphertype $router]
+ if { "$cyphertype" == "" } { set cyphertype "3des" }
}
# Figure out connection method
set cmethod [find method $router]
if { "$cmethod" == "" } { set cmethod {{telnet} {ssh}} }
+ # Figure out the SSH executable name
+ set sshcmd [find sshcmd $router]
+ if { "$sshcmd" == "" } { set sshcmd {ssh} }
+
# Login to the router
if {[login $router $ruser $userpswd $passwd $enapasswd $cmethod $cyphertype]} {
continue
@@ -675,16 +723,20 @@ foreach router [lrange $argv $i end] {
expect {
-re "\[\r\n]+" { exp_continue; }
-re "^(.+:)1 $prompt" { # stoopid extreme cmd-line numbers and
- # prompt based on state of config changes
+ # prompt based on state of config changes,
+ # which may have an * at the beginning.
set junk $expect_out(1,string)
regsub -all "^\\\* " $expect_out(1,string) {} junk
- set prompt ".? ?$junk\[0-9]+ $prompt";
+ set prompt ".? ?$junk\[0-9]+ $expect_out(2,string)";
set platform "extreme"
}
-re "^.+$prompt" { set junk $expect_out(0,string);
- regsub -all "\[\]\[]" $junk {\\&} prompt; }
- -re "^.+> \\\(enable\\\)" { set junk $expect_out(0,string);
- regsub -all "\[\]\[]" $junk {\\&} prompt; }
+ regsub -all "\[\]\[]" $junk {\\&} prompt;
+ }
+ -re "^.+> \\\(enable\\\)" {
+ set junk $expect_out(0,string);
+ regsub -all "\[\]\[]" $junk {\\&} prompt;
+ }
}
if { $do_command } {
diff --git a/bin/control_rancid.in b/bin/control_rancid.in
index 42f14ae..f51a21b 100755..100644
--- a/bin/control_rancid.in
+++ b/bin/control_rancid.in
@@ -1,19 +1,22 @@
-#!/bin/sh
+#! /bin/sh
##
+## $Id: control_rancid.in,v 1.61 2004/01/11 05:25:13 hank Exp $
##
-## Copyright (C) 1996-2001 by Henry Kilmer.
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
# control_rancid $GROUP
@@ -80,6 +83,7 @@ trap 'rm -fr $TMP;' 1 2 15
# the receipient(s) of diffs
mailrcpt=${mailrcpt:-"@MAILPLUS@$GROUP"}; export mailrcpt
+adminmailrcpt=${mailrcpt:-"@ADMINMAILPLUS@$GROUP"}; export adminmailrcpt
# Number of things par should run in parallel.
PAR_COUNT=${PAR_COUNT:-5}
@@ -88,14 +92,14 @@ PAR_COUNT=${PAR_COUNT:-5}
if [ ! -d $DIR ]
then
echo "$DIR does not exist."
- echo "Run bin/create_cvs $GROUP to make all of the needed directories."
+ echo "Run bin/rancid-cvs $GROUP to make all of the needed directories."
(
- echo "To: @MAILPLUS@admin-$GROUP"
+ echo "To: $adminmailrcpt"
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."
+ echo "Run bin/rancid-cvs $GROUP to make all of the needed directories."
) | sendmail -t
exit 1
fi
@@ -116,7 +120,7 @@ rm -f $TMP
if [ ! -f $DIR/router.db ]
then
(
- echo "To: @MAILPLUS@admin-$GROUP"
+ echo "To: $adminmailrcpt"
echo "Subject: no $GROUP/router.db file"
echo "Precedence: bulk"
echo ""
@@ -132,16 +136,17 @@ fi
cd $DIR
trap 'rm -fr routers.db routers.all.new routers.down.new routers.up.new \
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
+sed -e '/^#/d' -e 's/^ *//' -e 's/ *$//' -e 's/ *: */:/g' router.db |
+ sort -u > routers.db
+cut -d: -f1,2 routers.db > 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 $_)
- if ($F[2] !~ /^up$/i);}' routers.db | sort -u > routers.down.new
+ if ($F[2] !~ /^up$/i);}' routers.db > routers.down.new
if [ ! -f routers.down ] ; then touch routers.down; fi
diff routers.down routers.down.new > /dev/null 2>&1; RDOWN=$?
@PERLV@ -F: -ane '{($F[0] =~ tr@A-Z@a-z@,print "$F[0]:$F[1]\n")
- if ($F[2] =~ /^up$/i);}' routers.db | sort -u > routers.up.new
+ if ($F[2] =~ /^up$/i);}' routers.db > routers.up.new
if [ ! -f routers.up ] ; then touch routers.up; fi
diff routers.up routers.up.new > /dev/null 2>&1; RUP=$?
@@ -207,7 +212,7 @@ then
if [ -s routers.mail ] ; then
(
- echo "To: @MAILPLUS@admin-$GROUP"
+ echo "To: $adminmailrcpt"
echo "Subject: changes in $GROUP routers"
echo "Precedence: bulk"
echo ""
@@ -236,9 +241,18 @@ then
cd $DIR
fi
-mv routers.all.new routers.all
-mv routers.down.new routers.down
-mv routers.up.new routers.up
+mv -f routers.all.new routers.all
+if [ $? -ne 0 ]; then
+ echo "Error: could not rename routers.all.new"
+fi
+mv -f routers.down.new routers.down
+if [ $? -ne 0 ]; then
+ echo "Error: could not rename routers.down.new"
+fi
+mv -f routers.up.new routers.up
+if [ $? -ne 0 ]; then
+ echo "Error: could not rename routers.up.new"
+fi
rm -f routers.db
trap 'rm -fr $TMP;' 1 2 15
@@ -290,6 +304,7 @@ cd $DIR/configs
# The number of processes running at any given time can be
# tailored to the specific installation.
+echo ""
echo "Trying to get all of the configs."
par -q -n $PAR_COUNT -c "rancid-fe \{}" $devlistfile
@@ -331,19 +346,27 @@ do
done
echo
-# Make sure that all of the new configs are not empty.
-for config in *.new
-do
- if [ ! -s $config ]
+# Make sure that no empty configs are accepted. Those that are non-empty
+# are renamed from device_name.new -> device_name.
+for router in `cat $devlistfile`
+do
+ OFS=$IFS
+ IFS=':'
+ set $router
+ IFS=$OFS
+ router=$1;
+
+ if [ ! -s $router.new ]
then
- rm -f $config
+ rm -f $router.new
+ else
+ mv $router.new $router
+ if [ $? -ne 0 ]; then
+ echo "Error: could not rename $router.new to $router"
+ fi
fi
done
-# Now that we have the new configs, rename them to their proper
-# name.
-rename 's/.new$//' *.new
-
# This has been different for different machines...
# Diff the directory and then checkin.
trap 'rm -fr $TMP $TMP.diff $DIR/routers.single;' 1 2 15
@@ -387,7 +410,7 @@ fi
if [ -s $DIR/routers.failed ]
then
(
- echo "To: @MAILPLUS@admin-$GROUP"
+ echo "To: $adminmailrcpt"
echo "Subject: config fetcher problems - $GROUP"
echo "Precedence: bulk"
echo ""
diff --git a/bin/cssrancid.in b/bin/cssrancid.in
new file mode 100644
index 0000000..27049df
--- /dev/null
+++ b/bin/cssrancid.in
@@ -0,0 +1,660 @@
+#! @PERLV_PATH@
+##
+## $Id: cssrancid.in,v 1.4 2004/01/11 03:49:13 heas Exp $
+##
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## All rights reserved.
+##
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
+##
+## 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.
+##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
+##
+#
+# RANCID - Really Awesome New Cisco confIg Differ
+#
+# usage: rancid [-d] [-l] [-f filename | $host]
+#
+use Getopt::Std;
+getopts('dfl');
+$log = $opt_l;
+$debug = $opt_d;
+$file = $opt_f;
+$host = $ARGV[0];
+$clean_run = 0;
+$found_end = 0;
+$timeo = 90; # clogin timeout in seconds
+
+my(%filter_pwds); # password filtering mode
+
+# 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 routine 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 routine 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 routine 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 routine (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;
+ study;
+ last if(/^$prompt/);
+ next if(/^(\s*|\s*$cmd\s*)$/);
+ return(-1) if (/command authorization failed/i);
+ if (/^Slave in slot (\d+) is running/) {
+ $slave = " Slave:";
+ next;
+ }
+ /^Cisco Secure PIX /i &&
+ ProcessHistory("COMMENTS","keysort","F1", "!Image: $_") && next;
+ /^IOS .* Software \(([A-Za-z-0-9]*)\), .*Version\s+(.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","F1",
+ "!Image:$slave Software: $1, $2\n") && next;
+ /^([A-Za-z-0-9_]*) Synced to mainline version: (.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","F2",
+ "!Image:$slave $1 Synced to mainline version: $2\n") && next;
+ /^Compiled (.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","F3",
+ "!Image:$slave Compiled: $1\n") && next;
+ /^ROM: (System )?Bootstrap.*(Version.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","G1",
+ "!ROM Bootstrap: $2\n") && next;
+ if (/^Hardware:\s+(.*), (.* RAM), CPU (.*)$/) {
+ ProcessHistory("COMMENTS","keysort","A1",
+ "!Chassis type: $1 - a PIX\n");
+ ProcessHistory("COMMENTS","keysort","A2",
+ "!CPU: $3\n");
+ ProcessHistory("COMMENTS","keysort","B1", "!Memory: $2\n");
+ }
+ /^Serial Number:\s+(.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","C1", "!$_") && next;
+ /^Activation Key:\s+(.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","C2", "!$_") && next;
+ /^ROM: \d+ Bootstrap .*(Version.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","G2",
+ "!ROM Image: Bootstrap $1\n!\n") && next;
+ /^ROM: .*(Version.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","G3","!ROM Image: $1\n") && next;
+ /^BOOTFLASH: .*(Version.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","G4","!BOOTFLASH: $1\n") && next;
+ /^BOOTLDR: .*(Version.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","G4","!BOOTLDR: $1\n") && next;
+ /^System image file is "([^\"]*)", booted via (\S*)/ &&
+ ProcessHistory("COMMENTS","keysort","F4","!Image: booted $1\n") &&
+ next;
+ /^System image file is "([^\"]*)"$/ &&
+ ProcessHistory("COMMENTS","keysort","F5","!Image: $1\n") && next;
+ if (/(\S+)\s+\((\S+)\)\s+processor.*with (\S+[kK]) bytes/) {
+ my($proc) = $1;
+ my($cpu) = $2;
+ my($mem) = $3;
+ my($device) = "router";
+ $type = "CSS";
+ print STDERR "TYPE = $type\n" if ($debug);
+ ProcessHistory("COMMENTS","keysort","A1",
+ "!Chassis type:$slave $proc - a $type $device\n");
+ ProcessHistory("COMMENTS","keysort","B1",
+ "!Memory:$slave main $mem\n");
+ ProcessHistory("COMMENTS","keysort","A3","!CPU:$slave $cpu\n");
+ next;
+ }
+ if (/(\S+) Silicon\s*Switch Processor/) {
+ if (!defined($C0)) {
+ $C0=1; ProcessHistory("COMMENTS","keysort","C0","!\n");
+ }
+ ProcessHistory("COMMENTS","keysort","C2","!SSP: $1\n");
+ $ssp = 1;
+ $sspmem = $1;
+ next;
+ }
+ /^(\d+[kK]) bytes of multibus/ &&
+ ProcessHistory("COMMENTS","keysort","B2",
+ "!Memory: multibus $1\n") && next;
+ /^(\d+[kK]) bytes of non-volatile/ &&
+ ProcessHistory("COMMENTS","keysort","B3",
+ "!Memory: nvram $1\n") && next;
+ /^(\d+[kK]) bytes of flash memory/ &&
+ ProcessHistory("COMMENTS","keysort","B5","!Memory: flash $1\n") &&
+ next;
+ /^(\d+[kK]) bytes of .*flash partition/ &&
+ ProcessHistory("COMMENTS","keysort","B6",
+ "!Memory: flash partition $1\n") && next;
+ /^(\d+[kK]) bytes of Flash internal/ &&
+ ProcessHistory("COMMENTS","keysort","B4",
+ "!Memory: bootflash $1\n") && next;
+ if(/^(\d+[kK]) bytes of (Flash|ATA)?.*PCMCIA .*(slot|disk) ?(\d)/i) {
+ ProcessHistory("COMMENTS","keysort","B7",
+ "!Memory: pcmcia $2 $3$4 $1\n");
+ next;
+ }
+ if(/^WARNING/) {
+ if (!defined($I0)) {
+ $I0=1;
+ ProcessHistory("COMMENTS","keysort","I0","!\n");
+ }
+ ProcessHistory("COMMENTS","keysort","I1","! $_");
+ # The line after the WARNING is what to do about it.
+ $_ = <INPUT>; tr/\015//d;
+ ProcessHistory("COMMENTS","keysort","I1","! $_");
+ }
+ if (/^Configuration register is (.*)$/) {
+ $config_register=$1;
+ next;
+ }
+ }
+ return(0);
+}
+
+
+# Dummy routine to set term length....
+sub TermLength {
+ # Dummy subroutine.. need to set term length differently for CSS
+ # boxes as term length 0 doesnt work correctly. POS.
+ return(0);
+}
+
+# Dummy routine to copy profile...
+sub CopyProfile {
+ ## Because the term length gets changed twice, the stupid
+ ## box will ask you to save or discard changes. This prompt
+ ## of couse breaks the interaction... strangely enough tho
+ ## in a failover environment, only the secondary behaves this
+ ## way.. the primary lets you log out and does not complain.
+ return(0);
+}
+
+
+# This routine parses "show boot"
+sub ShowBoot {
+ # Pick up boot variables if 7000/7200/7500/12000/2900/3500;
+ # otherwise pick up bootflash.
+ print STDERR " In ShowBoot: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if /^\s*\^\s*$/;
+ return(-1) if (/command authorization failed/i);
+ return(1) if /Ambiguous command/i;
+ # return(1) if /(Invalid input detected|Type help or )/;
+ return(1) if /(Open device \S+ failed|Error opening \S+:)/;
+ next if /CONFGEN variable/;
+ if (!defined($H0)) {
+ $H0=1; ProcessHistory("COMMENTS","keysort","H0","!\n");
+ }
+ if ($type !~ /^(12[04]|7)/) {
+ if ($type !~ /^(29|35)00/) {
+ ProcessHistory("COMMENTS","keysort","H2","!BootFlash: $_");
+ } else {
+ ProcessHistory("COMMENTS","keysort","H1","!Variable: $_");
+ }
+ } elsif (/variable/) {
+ ProcessHistory("COMMENTS","keysort","H1","!Variable: $_");
+ }
+ }
+ ProcessHistory("COMMENTS","","","!\n");
+ return(0);
+}
+
+
+# This routine processes a "show run"
+sub ShowRun {
+ print STDERR " In ShowRun: $_" if ($debug);
+ my($lineauto) = 0;
+
+ while (<INPUT>) {
+ tr/\015//d;
+ study;
+ last if(/^$prompt/);
+ return(-1) if (/command authorization failed/i);
+ # the pager can not be disabled per-session on the PIX
+ s/^<-+ More -+>\s*//;
+ /Non-Volatile memory is in use/ && return(-1); # NvRAM is locked
+ $lineauto = 0 if (/^[^ ]/);
+ # skip the crap
+ if (/^(##+$|(Building|Current) configuration)/i) {
+ while (<INPUT>) {
+ next if (/^Current configuration\s*:/i);
+ next if (/^:/);
+ next if (/^([%!].*|\s*)$/);
+ next if (/^ip add.*ipv4:/); # band-aid for 3620 12.0S
+ last;
+ }
+ if (defined($config_register)) {
+ ProcessHistory("","","","!\nconfig-register $config_register\n");
+ }
+ tr/\015//d;
+ }
+ # some versions have other crap mixed in with the bits in the
+ # block above
+ /^! (Last configuration|NVRAM config last)/ && next;
+ ## CSS specific....
+ /Generated on/ && next;
+
+ # Dog gone Cool matches to process the rest of the config
+ /^tftp-server flash / && next; # kill any tftp remains
+ /^ntp clock-period / && next; # kill ntp clock-period
+ /^ length / && next; # kill length on serial lines
+ /^ width / && next; # kill width on serial lines
+ $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");
+ next;
+ }
+ if (/^(enable secret) / && $filter_pwds >= 2) {
+ ProcessHistory("ENABLE","","","!$1 <removed>\n");
+ next;
+ }
+ if (/^username (\S+)(\s.*)? secret /) {
+ if ($filter_pwds >= 2) {
+ ProcessHistory("USER","keysort","$1","!username $1$2 secret <removed>\n");
+ } else {
+ ProcessHistory("USER","keysort","$1","$_");
+ }
+ next;
+ }
+ if (/^username (\S+)(\s.*)? password ((\d) \S+|\S+)/) {
+ if ($filter_pwds == 2) {
+ ProcessHistory("USER","keysort","$1","!username $1$2 password <removed>\n");
+ } elsif ($filter_pwds == 1 && $4 ne "5"){
+ ProcessHistory("USER","keysort","$1","!username $1$2 password <removed>\n");
+ } else {
+ ProcessHistory("USER","keysort","$1","$_");
+ }
+ next;
+ }
+ if (/^(\s*)password / && $filter_pwds >= 1) {
+ ProcessHistory("LINE-PASS","","","!$1password <removed>\n");
+ next;
+ }
+ if (/^\s*neighbor (\S*) password / && $filter_pwds >= 1) {
+ ProcessHistory("","","","! neighbor $1 password <removed>\n");
+ next;
+ }
+ if (/^(ppp .* password) 7 .*/ && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
+ if (/^(ip ftp password) / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
+ 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;
+ }
+ if (/^((crypto )?isakmp key) \S+ / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed> $'"); next;
+ }
+ # i am told these are plain-text on the PIX
+ if (/^(vpdn username \S+ password)/ && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
+ /fair-queue individual-limit/ && next;
+ # sort ip explicit-paths.
+ if (/^ip explicit-path name (\S+)/) {
+ my($key) = $1;
+ my($expath) = $_;
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ last if (/^$prompt/ || ! /^(ip explicit-path name |[ !])/);
+ if (/^ip explicit-path name (\S+)/) {
+ ProcessHistory("EXPATH","keysort","$key","$expath");
+ $key = $1;
+ $expath = $_;
+ } else {
+ $expath .= $_;
+ }
+ }
+ ProcessHistory("EXPATH","keysort","$key","$expath");
+ }
+ # sort route-maps
+ if (/^route-map (\S+)/) {
+ my($key) = $1;
+ my($routemap) = $_;
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/ || ! /^(route-map |[ !])/);
+ if (/^route-map (\S+)/) {
+ ProcessHistory("ROUTEMAP","keysort","$key","$routemap");
+ $key = $1;
+ $routemap = $_;
+ } else {
+ $routemap .= $_;
+ }
+ }
+ ProcessHistory("ROUTEMAP","keysort","$key","$routemap");
+ }
+ # filter out any RCS/CVS tags to avoid confusing local CVS storage
+ s/\$(Revision|Id):/ $1:/;
+ # order access-lists
+ /^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ &&
+ ProcessHistory("ACL $1 $2","ipsort","$3","$_") && next;
+ # order extended access-lists
+ /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+host\s+(\S+)/ &&
+ ProcessHistory("EACL $1 $2","ipsort","$3","$_") && next;
+ /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+(\d\S+)/ &&
+ ProcessHistory("EACL $1 $2","ipsort","$3","$_") && next;
+ /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+any/ &&
+ ProcessHistory("EACL $1 $2","ipsort","0.0.0.0","$_") && next;
+ # order arp lists
+ /^arp\s+(\d+\.\d+\.\d+\.\d+)\s+/ &&
+ ProcessHistory("ARP","ipsort","$1","$_") && next;
+ /^ip prefix-list\s+(\S+)\s+seq\s+(\d+)\s+(permit|deny)\s+(\d\S+)(\/.*)$/ &&
+ ProcessHistory("PACL $1 $3","ipsort","$4","ip prefix-list $1 $3 $4$5\n")
+ && next;
+ # order logging statements
+ /^logging (\d+\.\d+\.\d+\.\d+)/ &&
+ ProcessHistory("LOGGING","ipsort","$1","$_") && next;
+ # order/prune snmp-server host statements
+ # we only prune lines of the form
+ # snmp-server host a.b.c.d <community>
+ if (/^snmp-server host (\d+\.\d+\.\d+\.\d+) /) {
+ if (defined($ENV{'NOCOMMSTR'})) {
+ my($ip) = $1;
+ my($line) = "snmp-server host $ip";
+ my(@tokens) = split(' ', $');
+ my($token);
+ while ($token = shift(@tokens)) {
+ if ($token eq 'version') {
+ $line .= " " . join(' ', ($token, shift(@tokens)));
+ } elsif ($token =~ /^(informs?|traps?|(no)?auth)$/) {
+ $line .= " " . $token;
+ } else {
+ $line = "!$line " . join(' ', ("<removed>", join(' ',@tokens)));
+ last;
+ }
+ }
+ ProcessHistory("SNMPSERVERHOST","ipsort","$ip","$line\n");
+ } else {
+ ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_");
+ }
+ next;
+ }
+ if (/^(snmp-server community) (\S+)/) {
+ if (defined($ENV{'NOCOMMSTR'})) {
+ ProcessHistory("SNMPSERVERCOMM","keysort","$_","!$1 <removed>$'") && next;
+ } else {
+ ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next;
+ }
+ }
+ # order/prune tacacs/radius server statements
+ if (/^(tacacs-server|radius-server) key / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 key <removed>\n"); next;
+ }
+ # order clns host statements
+ /^clns host \S+ (\S+)/ &&
+ ProcessHistory("CLNS","keysort","$1","$_") && next;
+ # order alias statements
+ /^alias / && ProcessHistory("ALIAS","keysort","$_","$_") && next;
+ # delete ntp auth password - this md5 is a reversable too
+ if (/^(ntp authentication-key \d+ md5) / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
+ # order ntp peers/servers
+ if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) {
+ $sortkey = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5);
+ ProcessHistory("NTP","keysort",$sortkey,"$_");
+ next;
+ }
+ # order ip host line statements
+ /^ip host line(\d+)/ &&
+ ProcessHistory("IPHOST","numsort","$1","$_") && next;
+ # order ip nat source static statements
+ /^ip nat (\S+) source static (\S+)/ &&
+ ProcessHistory("IP NAT $1","ipsort","$2","$_") && next;
+ # order atm map-list statements
+ /^\s+ip\s+(\d+\.\d+\.\d+\.\d+)\s+atm-vc/ &&
+ ProcessHistory("ATM map-list","ipsort","$1","$_") && next;
+ # order ip rcmd lines
+ /^ip rcmd/ && ProcessHistory("RCMD","keysort","$_","$_") && next;
+
+ # system controller
+ /^syscon address (\S*) (\S*)/ &&
+ ProcessHistory("","","","!syscon address $1 <removed>\n") &&
+ next;
+ if (/^syscon password (\S*)/ && $filter_pwds >= 1) {
+ ProcessHistory("","","","!syscon password <removed>\n");
+ next;
+ }
+
+ # catch anything that wasnt matched above.
+ ProcessHistory("","","","$_");
+ # end of config. the ": " game is for the PIX
+ if (/^(: +)?end$/ || /CSS.*#/ || /$prompt/ ) {
+ $found_end = 1;
+ return(1);
+ }
+ }
+ return(0);
+}
+
+# dummy function
+sub DoNothing {print STDOUT;}
+
+# Main
+%commands=(
+ 'term length 65535' => "TermLength",
+ 'copy profile user-profile' => "CopyProfile",
+ 'show version' => "ShowVersion",
+ 'show boot' => "ShowBoot",
+ 'show run' => "ShowRun"
+);
+# keys() doesnt return things in the order entered and the order of the
+# cmds is important (show version first and show run last). pita
+@commands=(
+ "term length 65535",
+ "copy profile user-profile",
+ "show version",
+ "show boot",
+ "show run"
+);
+$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";
+ }
+}
+
+# determine password filtering mode
+if ($ENV{"FILTER_PWDS"} =~ /no/i) {
+ $filter_pwds = 0;
+} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
+ $filter_pwds = 2;
+} else {
+ $filter_pwds = 1;
+}
+
+ProcessHistory("","","","!RANCID-CONTENT-TYPE: cisco-css\n!\n");
+ProcessHistory("COMMENTS","keysort","B0","!\n");
+ProcessHistory("COMMENTS","keysort","F0","!\n");
+ProcessHistory("COMMENTS","keysort","G0","!\n");
+
+TOP: while(<INPUT>) {
+ tr/\015//d;
+ if (/\#\s?exit/) {
+ $clean_run=1;
+ last;
+ }
+ if (/^Error:/) {
+ print STDOUT ("$host clogin error: $_");
+ print STDERR ("$host clogin error: $_") if ($debug);
+ $clean_run=0;
+ last;
+ }
+ while (/#\s*($cmds_regexp)\s*$/) {
+ $cmd = $1;
+ if (!defined($prompt)) {$prompt = ($_ =~ /^([^#]+#)/)[0]; }
+ print STDERR ("HIT COMMAND:$_") if ($debug);
+ if (! defined($commands{$cmd})) {
+ print STDERR "$host: found unexpected command - \"$cmd\"\n";
+ # $clean_run = 0;
+ # last TOP;
+ next TOP;
+ } else {
+ $rval = &{$commands{$cmd}};
+ delete($commands{$cmd});
+ if ($rval == -1) {
+ $clean_run = 0;
+ last TOP;
+ }
+ }
+ }
+}
+print STDOUT "Done $logincmd: $_\n" if ($log);
+# Flush History
+ProcessHistory("","","","");
+# Cleanup
+close(INPUT);
+close(OUTPUT);
+
+if (defined($ENV{NOPIPE})) {
+ unlink("$host.raw") if (! $debug);
+}
+
+# check for completeness
+if (scalar(%commands) || !$clean_run || !$found_end) {
+ if (scalar(%commands)) {
+ printf(STDOUT "$host: missed cmd(s): %s\n", join(',', keys(%commands)));
+ printf(STDERR "$host: missed cmd(s): %s\n", join(',', keys(%commands))) if ($debug);
+ }
+ if (!$clean_run || !$found_end) {
+ print STDOUT "$host: End of run not found\n";
+ print STDERR "$host: End of run not found\n" if ($debug);
+ system("/usr/bin/tail -1 $host.new");
+ }
+ unlink "$host.new" if (! $debug);
+}
diff --git a/bin/elogin.in b/bin/elogin.in
index 1b647fa..651d7fb 100755..100644
--- a/bin/elogin.in
+++ b/bin/elogin.in
@@ -1,19 +1,22 @@
-#!@EXPECT_PATH@ --
+#! @EXPECT_PATH@ --
##
+## $Id: elogin.in,v 1.27 2004/01/11 05:39:15 heas Exp $
##
-## Copyright (C) 1997-2001 by Henry Kilmer, Erik Sherk and Pete Whiting.
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
# elogin - ADC EZT3 login
@@ -38,8 +41,9 @@ set do_command 0
set do_script 0
# The default is to automatically enable
set enable 1
-# The default is that you login non-enabled (tacacs can have you login already enabled)
-set autoenable 0
+# The default is that you login non-enabled (tacacs can have you login already
+# enabled)
+set avautoenable 0
# The default is to look in the password file to find the passwords. This
# tracks if we receive them on the command line.
set do_passwd 1
@@ -49,6 +53,8 @@ if {[ info exists env(CISCO_USER) ] } {
set default_user $env(CISCO_USER)
} elseif {[ info exists env(USER) ]} {
set default_user $env(USER)
+} elseif {[ info exists env(LOGNAME) ]} {
+ set default_user $env(LOGNAME)
} else {
# This uses "id" which I think is portable. At least it has existed
# (without options) on all machines/OSes I've been on recently -
@@ -101,7 +107,7 @@ for {set i 0} {$i < $argc} {incr i} {
if {[ regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} {
set E$varname $varvalue
} else {
- send_user "Error: invalid format for -E in $arg\n"
+ send_user "\nError: invalid format for -E in $arg\n"
exit 1
}
# Enable Password
@@ -166,10 +172,10 @@ for {set i 0} {$i < $argc} {incr i} {
set do_command 1
# Do we enable?
} -noenable {
- # ignore -noenable
+ # ignore -noenable
# Does tacacs automatically enable us?
} -autoenable {
- # ignore -autoenable
+ # ignore -autoenable
} -* {
send_user "\nError: Unknown argument! $arg\n"
send_user $usage
@@ -406,17 +412,17 @@ foreach router [lrange $argv $i end] {
# Figure out prompt.
set prompt "Active) > "
- set autoenable 1
- set enable 0
+ set autoenable 1
+ set enable 0
# Figure out passwords
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 "\nError: no password for $router in $password_file.\n"
continue
}
- set passwd [lindex $pswd 0]
+ set passwd [join [lindex $pswd 0] ""]
}
# Figure out username
@@ -424,7 +430,7 @@ foreach router [lrange $argv $i end] {
# command line username
set ruser $username
} else {
- set ruser [find user $router]
+ set ruser [join [find user $router] ""]
if { "$ruser" == "" } { set ruser $default_user }
}
@@ -433,7 +439,7 @@ foreach router [lrange $argv $i end] {
# command line username
set userpswd $userpasswd
} else {
- set userpswd [find userpassword $router]
+ set userpswd [join [find userpassword $router] ""]
if { "$userpswd" == "" } { set userpswd $passwd }
}
@@ -442,13 +448,13 @@ foreach router [lrange $argv $i end] {
if { "$u_prompt" == "" } {
set u_prompt "(Username|login| Login):"
} else {
- set u_prompt [lindex $u_prompt 0]
+ set u_prompt [join [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 p_prompt [join [lindex $p_prompt 0] ""]
}
# Figure out cypher type
diff --git a/bin/env.in b/bin/env.in
deleted file mode 100644
index e3c2ba4..0000000
--- a/bin/env.in
+++ /dev/null
@@ -1,48 +0,0 @@
-#
-# This file setups up the environment used for rancid. see env(5)
-#
-# This will be site specific
-#
-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 (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.
-#
-TMPDIR=/tmp; export TMPDIR
-BASEDIR=@prefix@; export BASEDIR
-PATH=$BASEDIR/bin:@ENV_PATH@; export PATH
-CVSROOT=$BASEDIR/CVS; export CVSROOT
-#
-# if NOPIPE is set, temp files will be used instead of a cmd pipe during
-# collection from the router(s).
-#NOPIPE=YES; export NOPIPE
-#
-# FILTER_PWDS determines which passwords are filtered from configs by the
-# value set (NO | YES | ALL). see env(5).
-#FILTER_PWDS=YES; export FILTER_PWDS
-#
-# if NOCOMMSTR is set, snmp community strings will be stripped from the configs
-#NOCOMMSTR=YES; export NOCOMMSTR
-#
-# How many hours to go by before complaining about routers that
-# can not be reached. The value should be greater than the number
-# of hours between your do-diffs cron job.
-OLDTIME=4; export OLDTIME
-#
-# The number of devices to collect simultaneously.
-#PAR_COUNT=5; export PAR_COUNT
-#
-# list of rancid groups
-LIST_OF_GROUPS="sl joebobisp"
-#
-# For each group, define a list of people to receive the diffs.
-# in sendmail's /etc/aliases.
-# rancid-group: joe,moe@foo
-# rancid-group-admin: hostmaster
-# be sure to read ../README regarding aliases.
-#
-umask 027
diff --git a/bin/erancid.in b/bin/erancid.in
index 01a6268..20da43d 100755..100644
--- a/bin/erancid.in
+++ b/bin/erancid.in
@@ -1,22 +1,22 @@
-#!@PERLV_PATH@
+#! @PERLV_PATH@
##
-## Hacked version of rancid for ADC EZT3 series muxes. Only tested
-## with switch software 1.50 so far - terry@tmk.com
+## $Id: erancid.in,v 1.18 2004/01/11 03:49:13 heas Exp $
##
-##
-## Copyright (C) 1997-2001 by Henry Kilmer.
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
# RANCID - Really Awesome New Cisco confIg Differ
@@ -24,7 +24,7 @@
# usage: rancid [-d] [-l] [-f filename | $host]
#
use Getopt::Std;
-getopts('dflm');
+getopts('dfl');
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
@@ -268,7 +268,8 @@ while(<INPUT>) {
$cmd = $1;
if (!defined($prompt)) {
$prompt = ($_ =~ /^([^#]+#)/)[0];
- $prompt =~ s/([}{)(\\])/\\$1/g;
+ $prompt =~ s/([][}{)(\\])/\\$1/g;
+ print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
}
print STDERR ("HIT COMMAND:$_") if ($debug);
if (! defined($commands{$cmd})) {
diff --git a/bin/f10rancid.in b/bin/f10rancid.in
index 06528c5..2c4e485 100755..100644
--- a/bin/f10rancid.in
+++ b/bin/f10rancid.in
@@ -1,28 +1,32 @@
-#!@PERLV_PATH@
+#! @PERLV_PATH@
##
-## This version of rancid tries to deal with Force10s.
+## $Id: f10rancid.in,v 1.11 2004/01/11 03:49:13 heas Exp $
##
-## Copyright (C) 1997-2001 by Henry Kilmer.
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
+# This version of rancid tries to deal with Force10s.
+#
# RANCID - Really Awesome New Cisco confIg Differ
#
# usage: rancid [-d] [-l] [-f filename | $host]
#
use Getopt::Std;
-getopts('dflm');
+getopts('dfl');
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
@@ -139,7 +143,6 @@ sub ShowVersion {
while (<INPUT>) {
tr/\015//d;
- study;
last if(/^$prompt/);
next if(/^(\s*|\s*$cmd\s*)$/);
return(-1) if (/command authorization failed/i);
@@ -479,7 +482,6 @@ sub ShowContAll {
while (<INPUT>) {
tr/\015//d;
- study;
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
# return(1) if ($type =~ /^(12[40]|7[05])/);
@@ -583,7 +585,6 @@ sub ShowDiagbus {
while (<INPUT>) {
tr/\015//d;
- study;
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
#return(1) if ($type !~ /^7[05]/);
@@ -670,7 +671,6 @@ sub ShowDiag {
while (<INPUT>) {
tr/\015//d;
- study;
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
# return(1) if ($type !~ /^(12[40]|720|36|26)/);
@@ -882,7 +882,6 @@ sub WriteTerm {
while (<INPUT>) {
tr/\015//d;
- study;
last if(/^$prompt/);
return(-1) if (/command authorization failed/i);
# the pager can not be disabled per-session on the PIX
@@ -1216,7 +1215,11 @@ TOP: while(<INPUT>) {
}
while (/#\s*($cmds_regexp)\s*$/) {
$cmd = $1;
- if (!defined($prompt)) {$prompt = ($_ =~ /^([^#]+#)/)[0]; }
+ if (!defined($prompt)) {
+ $prompt = ($_ =~ /^([^#]+#)/)[0];
+ $prompt =~ s/([][}{)(\\])/\\$1/g;
+ print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
+ }
print STDERR ("HIT COMMAND:$_") if ($debug);
if (! defined($commands{$cmd})) {
print STDERR "$host: found unexpected command - \"$cmd\"\n";
diff --git a/bin/flogin.in b/bin/flogin.in
index 1a34068..169e522 100755..100644
--- a/bin/flogin.in
+++ b/bin/flogin.in
@@ -1,21 +1,26 @@
-#!@EXPECT_PATH@ --
+#! @EXPECT_PATH@ --
##
+## $Id: flogin.in,v 1.32 2004/01/11 05:39:15 heas Exp $
##
-## Copyright (C) 1997-2001 by Henry Kilmer, Erik Sherk and Pete Whiting.
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
-##
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
+##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
+# The login expect scripts were based on Erik Sherk's gwtn, by permission.
+#
# flogin - foundry login
#
# Most options are intuitive for logging into a foundry switch.
@@ -46,8 +51,9 @@ set do_command 0
set do_script 0
# The default is to automatically enable
set enable 1
-# The default is that you login non-enabled (tacacs can have you login already enabled)
-set autoenable 0
+# The default is that you login non-enabled (tacacs can have you login already
+# enabled)
+set avautoenable 0
# The default is to look in the password file to find the passwords. This
# tracks if we receive them on the command line.
set do_passwd 1
@@ -58,6 +64,8 @@ if {[ info exists env(CISCO_USER) ] } {
set default_user $env(CISCO_USER)
} elseif {[ info exists env(USER) ]} {
set default_user $env(USER)
+} elseif {[ info exists env(LOGNAME) ]} {
+ set default_user $env(LOGNAME)
} else {
# This uses "id" which I think is portable. At least it has existed
# (without options) on all machines/OSes I've been on recently -
@@ -113,7 +121,7 @@ for {set i 0} {$i < $argc} {incr i} {
if {[ regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} {
set E$varname $varvalue
} else {
- send_user "Error: invalid format for -E in $arg\n"
+ send_user "\nError: invalid format for -E in $arg\n"
exit 1
}
# Enable Password
@@ -181,7 +189,7 @@ for {set i 0} {$i < $argc} {incr i} {
set enable 0
# Does tacacs automatically enable us?
} -autoenable {
- set autoenable 1
+ set avautoenable 1
set enable 0
} -* {
send_user "\nError: Unknown argument! $arg\n"
@@ -277,7 +285,7 @@ proc source_password_file { password_file } {
# Log into the router.
proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
global spawn_id in_proc do_command do_script platform
- global prompt u_prompt p_prompt e_prompt
+ global prompt u_prompt p_prompt e_prompt sshcmd
set in_proc 1
set uprompt_seen 0
@@ -296,8 +304,8 @@ proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
exit 1
}
} elseif ![string compare $prog "ssh"] {
- if [ catch {spawn ssh -c $cyphertype -x -l $user $router} reason ] {
- send_user "\nError: ssh failed: $reason\n"
+ if [ catch {spawn $sshcmd -c $cyphertype -x -l $user $router} reason ] {
+ send_user "\nError: $sshcmd failed: $reason\n"
exit 1
}
} elseif ![string compare $prog "rsh"] {
@@ -341,24 +349,39 @@ proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
# then it will just send the passwd.
# if telnet fails with connection refused, try ssh
expect {
- -re "(Connection refused|Secure connection \[^\n\r]+ refused|Connection closed by|Telnet server disabled)" {
+ -re "(Connection refused|Secure connection \[^\n\r]+ refused)" {
+ catch {close}; wait
+ if !$progs {
+ send_user "\nError: Connection Refused ($prog): $router\n"
+ return 1
+ }
+ }
+ -re "(Connection closed by|Connection to \[^\n\r]+ closed)" {
catch {close}; wait
if !$progs {
- send_user "\nError: Connection Refused ($prog)\n"; return 1
+ send_user "\nError: Connection closed ($prog): $router\n"
+ return 1
+ }
+ }
+ -re "Telnet server disabled" {
+ catch {close}; wait
+ if !$progs {
+ send_user "\nError: Connection Refused ($prog): $router\n"
+ return 1
}
}
eof { send_user "\nError: Couldn't login\n"; wait; return 1 }
-nocase "unknown host\r" {
catch {close};
- send_user "\nError: Unknown host\n"; wait; return 1
+ send_user "\nError: Unknown host $router\n"; wait; return 1
}
"Host is unreachable" {
catch {close};
- send_user "\nError: Host Unreachable!\n"; wait; return 1
+ send_user "\nError: Host Unreachable: $router\n"; wait; return 1
}
"No address associated with name" {
catch {close};
- send_user "\nError: Unknown host\n"; wait; return 1
+ send_user "\nError: Unknown host $router\n"; wait; return 1
}
-re "(Host key not found |The authenticity of host .* be established).*\(yes\/no\)\?" {
send "yes\r"
@@ -406,7 +429,7 @@ proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
}
"$prompt" { break; }
"Login invalid" {
- send_user "\nError: Invalid login\n";
+ send_user "\nError: Invalid login: $router\n";
catch {close}; wait; return 1
}
}
@@ -432,6 +455,10 @@ proc do_enable { enauser enapasswd } {
denied { send_user "\nError: Check your Enable passwd\n";
return 1
}
+ "Incorrect username or password" {
+ send_user "\nError: Check your Enable passwd\n";
+ return 1
+ }
"% Bad passwords" { send_user "\nError: Check your Enable passwd\n";
return 1
}
@@ -496,7 +523,9 @@ foreach router [lrange $argv $i end] {
# Since autoenable is off by default, if we have it defined, it
# was done on the command line. If it is not specifically set on the
# command line, check the password file.
- if $autoenable {
+ if $avautoenable {
+ set autoenable 1
+ set enable 0
set prompt "#"
} else {
set ae [find autoenable $router]
@@ -514,15 +543,15 @@ 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 "\nError: no password for $router in $password_file.\n"
continue
}
if { $enable && $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2 } {
- send_user "Error: no enable password for $router in $password_file.\n"
+ send_user "\nError: no enable password for $router in $password_file.\n"
continue
}
- set passwd [lindex $pswd 0]
- set enapasswd [lindex $pswd 1]
+ set passwd [join [lindex $pswd 0] ""]
+ set enapasswd [join [lindex $pswd 1] ""]
}
# Figure out username
@@ -530,7 +559,7 @@ foreach router [lrange $argv $i end] {
# command line username
set ruser $username
} else {
- set ruser [find user $router]
+ set ruser [join [find user $router] ""]
if { "$ruser" == "" } { set ruser $default_user }
}
@@ -539,7 +568,7 @@ foreach router [lrange $argv $i end] {
# command line username
set userpswd $userpasswd
} else {
- set userpswd [find userpassword $router]
+ set userpswd [join [find userpassword $router] ""]
if { "$userpswd" == "" } { set userpswd $passwd }
}
@@ -548,7 +577,7 @@ foreach router [lrange $argv $i end] {
# command line enausername
set enauser $enausername
} else {
- set enauser [find enauser $router]
+ set enauser [join [find enauser $router] ""]
if { "$enauser" == "" } { set enauser $ruser }
}
@@ -557,19 +586,19 @@ foreach router [lrange $argv $i end] {
if { "$u_prompt" == "" } {
set u_prompt "(Username|login|Name|User Name):"
} else {
- set u_prompt [lindex $u_prompt 0]
+ set u_prompt [join [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 p_prompt [join [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]
+ set e_prompt [join [lindex $e_prompt 0] ""]
}
# Figure out cypher tpye
@@ -585,6 +614,10 @@ foreach router [lrange $argv $i end] {
set cmethod [find method $router]
if { "$cmethod" == "" } { set cmethod {{telnet} {ssh}} }
+ # Figure out the SSH executable name
+ set sshcmd [find sshcmd $router]
+ if { "$sshcmd" == "" } { set sshcmd {ssh} }
+
# Login to the router
if {[login $router $ruser $userpswd $passwd $enapasswd $cmethod $cyphertype]} {
continue
diff --git a/bin/fnrancid.in b/bin/fnrancid.in
new file mode 100644
index 0000000..815227b
--- /dev/null
+++ b/bin/fnrancid.in
@@ -0,0 +1,275 @@
+#! @PERLV_PATH@
+##
+## $Id: fnrancid.in,v 1.3 2004/01/11 03:49:13 heas Exp $
+##
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## All rights reserved.
+##
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
+##
+## 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.
+##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
+##
+#
+# A library built on Stephen Gill's Netscreen stuff to accomodate
+# the Fortinet product line. [d_pfleger@juniper.net]
+#
+# RANCID - Really Awesome New Cisco confIg Differ
+#
+# usage: rancid [-d] [-l] [-f filename | $host]
+#
+use Getopt::Std;
+getopts('dfl');
+$log = $opt_l;
+$debug = $opt_d;
+#$debug = 1;
+$file = $opt_f;
+$host = $ARGV[0];
+$found_end = 0;
+$timeo = 90; # nlogin timeout in seconds
+
+my(%filter_pwds); # password filtering mode
+
+# 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 "get system"
+sub GetSystem {
+ print STDERR " In GetSystem: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ next if /^\s*$/;
+ last if(/$prompt/);
+ ProcessHistory("","","","$_");
+ #print STDOUT "$_";
+ }
+ print STDOUT "Vendor: $vendor";
+ ProcessHistory("SYSTEM","","","\n");
+ return(0);
+}
+
+sub GetFile {
+ print STDERR " In GetFile: $_" if ($debug);
+ while (<INPUT>) {
+ last if(/$prompt/);
+ }
+ ProcessHistory("FILE","","","\n");
+ return(0);
+}
+
+sub GetConf {
+ print STDERR " In GetConf: $_" if ($debug);
+ while (<INPUT>) {
+ tr/\015//d;
+ next if /^\s*$/;
+ last if(/$prompt/);
+ if (/(^set.*)('Enc .*')(.*)/) {
+ ProcessHistory("ENC","","","!$1 'Enc **encoding removed**' $3\n");
+ next;
+ }
+ ProcessHistory("","","","$_");
+ #print STDOUT "$_";
+ }
+ $found_end=1;
+ return(1);
+}
+
+# dummy function
+sub DoNothing {print STDOUT;}
+
+# Main
+%commands=(
+ 'get system status' => "GetSystem",
+ 'get conf' => "GetConf"
+);
+# keys() doesnt return things in the order entered and the order of the
+# cmds is important. pita
+@commands=(
+ "get system status",
+ "get conf"
+);
+$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 nlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug);
+ print STDOUT "executing nlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log);
+ if (defined($ENV{NOPIPE})) {
+ system "nlogin -t $timeo -c \"$cisco_cmds\" $host </dev/null > $host.raw 2>&1" || die "nlogin failed for $host: $!\n";
+ open(INPUT, "< $host.raw") || die "nlogin failed for $host: $!\n";
+ } else {
+ open(INPUT,"nlogin -t $timeo -c \"$cisco_cmds\" $host </dev/null |") || die "nlogin failed for $host: $!\n";
+ }
+}
+
+# determine password filtering mode
+if ($ENV{"FILTER_PWDS"} =~ /no/i) {
+ $filter_pwds = 0;
+} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
+ $filter_pwds = 2;
+} else {
+ $filter_pwds = 1;
+}
+
+ProcessHistory("","","","!RANCID-CONTENT-TYPE: Fortigate\n\n");
+TOP: while(<INPUT>) {
+ tr/\015//d;
+ if (/^Error:/) {
+ print STDOUT ("$host nlogin error: $_");
+ print STDERR ("$host nlogin error: $_") if ($debug);
+ last;
+ }
+ while (/>\s*($cmds_regexp)\s*$/) {
+ $cmd = $1;
+ if (!defined($prompt)) { $prompt = " >\s*"; }
+ print STDERR ("HIT COMMAND:$_") if ($debug);
+ if (!defined($commands{$cmd})) {
+ print STDERR "$host: found unexpected command - \"$cmd\"\n";
+ last TOP;
+ }
+ $rval = &{$commands{$cmd}};
+ delete($commands{$cmd});
+ if ($rval == -1) {
+ 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) || !$found_end) {
+ if (scalar(%commands)) {
+ printf(STDOUT "$host: missed cmd(s): %s\n", join(',', keys(%commands)));
+ printf(STDERR "$host: missed cmd(s): %s\n", join(',', keys(%commands))) if ($debug);
+ }
+ if (!$found_end) {
+ print STDOUT "$found_end: found end\n";
+ print STDOUT "$host: End of run not found\n";
+ print STDERR "$host: End of run not found\n" if ($debug);
+ system("/usr/bin/tail -1 $host.new");
+ }
+ unlink "$host.new" if (! $debug);
+}
diff --git a/bin/francid.in b/bin/francid.in
index b03052e..e1fd284 100755..100644
--- a/bin/francid.in
+++ b/bin/francid.in
@@ -1,29 +1,33 @@
-#!@PERLV_PATH@
+#! @PERLV_PATH@
##
-## Amazingly hacked version of Hank's rancid - this one tries to
-## deal with foundrys and foundrys OEM'd by HP as Procurves.
+## $Id: francid.in,v 1.26 2004/01/11 03:49:13 heas Exp $
##
-## Copyright (C) 1997-2001 by Henry Kilmer.
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
+# Amazingly hacked version of Hank's rancid - this one tries to
+# deal with foundrys and foundrys OEM'd by HP as Procurves.
+#
# RANCID - Really Awesome New Cisco confIg Differ
#
# usage: rancid [-d] [-l] [-f filename | $host]
#
use Getopt::Std;
-getopts('dflm');
+getopts('dfl');
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
@@ -376,7 +380,8 @@ TOP: while(<INPUT>) {
$cmd = $1;
if (!defined($prompt)) {
$prompt = ($_ =~ /^([^#]+#)/)[0];
- $prompt =~ s/([}{)(\\])/\\$1/g;
+ $prompt =~ s/([][}{)(\\])/\\$1/g;
+ print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
}
print STDERR ("HIT COMMAND:$_") if ($debug);
if (! defined($commands{$cmd})) {
diff --git a/bin/hlogin.in b/bin/hlogin.in
index 917ea83..6af11b4 100755..100644
--- a/bin/hlogin.in
+++ b/bin/hlogin.in
@@ -1,21 +1,26 @@
-#!@EXPECT_PATH@ --
+#! @EXPECT_PATH@ --
##
+## $Id: hlogin.in,v 1.21 2004/01/11 05:39:15 heas Exp $
##
-## Copyright (C) 1997-2001 by Henry Kilmer, Erik Sherk and Pete Whiting.
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
+# The login expect scripts were based on Erik Sherk's gwtn, by permission.
+#
# hlogin - hp login
#
# Most options are intuitive for logging into a Cisco router.
@@ -43,8 +48,9 @@ set do_command 0
set do_script 0
# The default is to automatically enable
set enable 1
-# The default is that you login non-enabled (tacacs can have you login already enabled)
-set autoenable 0
+# The default is that you login non-enabled (tacacs can have you login already
+# enabled)
+set avautoenable 0
# The default is to look in the password file to find the passwords. This
# tracks if we receive them on the command line.
set do_passwd 1
@@ -57,6 +63,8 @@ if {[ info exists env(CISCO_USER) ] } {
set default_user $env(CISCO_USER)
} elseif {[ info exists env(USER) ]} {
set default_user $env(USER)
+} elseif {[ info exists env(LOGNAME) ]} {
+ set default_user $env(LOGNAME)
} else {
# This uses "id" which I think is portable. At least it has existed
# (without options) on all machines/OSes I've been on recently -
@@ -112,7 +120,7 @@ for {set i 0} {$i < $argc} {incr i} {
if {[ regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} {
set E$varname $varvalue
} else {
- send_user "Error: invalid format for -E in $arg\n"
+ send_user "\nError: invalid format for -E in $arg\n"
exit 1
}
# Enable Password
@@ -281,30 +289,35 @@ proc source_password_file { password_file } {
# Log into the router.
proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
global spawn_id in_proc do_command do_script platform
- global prompt u_prompt p_prompt e_prompt
+ global prompt u_prompt p_prompt e_prompt sshcmd
set in_proc 1
# try each of the connection methods in $cmethod until one is successful
set progs [llength $cmethod]
foreach prog [lrange $cmethod 0 end] {
+ regexp {(telnet|ssh)(:([^[:space:]]+))*} $prog command suffix junk port
if [string match "telnet*" $prog] {
- regexp {telnet(:([^[:space:]]+))*} $prog command suffix port
if {"$port" == ""} {
- set retval [ catch {spawn hpfilter telnet $router} reason ]
+ set retval [ catch {spawn hpuifilter telnet $router} reason ]
} else {
- set retval [ catch {spawn hpfilter telnet $router $port} reason ]
+ set retval [ catch {spawn hpuifilter telnet $router $port} reason ]
}
if { $retval } {
send_user "\nError: telnet failed: $reason\n"
exit 1
}
- } elseif ![string compare $prog "ssh"] {
- if [ catch {spawn hpfilter ssh -c $cyphertype -x -l $user $router} reason ] {
- send_user "\nError: ssh failed: $reason\n"
+ } elseif [string match "ssh*" $prog] {
+ if {"$port" == ""} {
+ set retval [ catch {spawn hpuifilter $sshcmd -c $cyphertype -x -l $user $router} reason ]
+ } else {
+ set retval [ catch {spawn hpuifilter $sshcmd -c $cyphertype -p $port -x -l $user $router} reason ]
+ }
+ if { $retval } {
+ send_user "\nError: $sshcmd failed: $reason\n"
exit 1
}
} elseif ![string compare $prog "rsh"] {
- if [ catch {spawn hpfilter rsh -l $user $router} reason ] {
+ if [ catch {spawn hpuifilter rsh -l $user $router} reason ] {
send_user "\nError: rsh failed: $reason\n"
exit 1
}
@@ -353,14 +366,17 @@ proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
if !$progs {
send_user "\nError: Connection Refused ($prog)\n"; return 1
}
- } eof { send_user "\nError: Couldn't login\n"; wait; return 1
- } -nocase "unknown host\r" {
+ }
+ 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" {
+ }
+ "Host is unreachable" {
catch {close};
send_user "\nError: Host Unreachable!\n"; wait; return 1
- } "No address associated with name" {
+ }
+ "No address associated with name" {
catch {close};
send_user "\nError: Unknown host\n"; wait; return 1
}
@@ -542,7 +558,9 @@ foreach router [lrange $argv $i end] {
# Since autoenable is off by default, if we have it defined, it
# was done on the command line. If it is not specifically set on the
# command line, check the password file.
- if $autoenable {
+ if $avautoenable {
+ set autoenable 1
+ set enable 0
set prompt "#"
} else {
set ae [find autoenable $router]
@@ -565,15 +583,15 @@ 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 "\nError: no password for $router in $password_file.\n"
continue
}
if { $enable && $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2 } {
- send_user "Error: no enable password for $router in $password_file.\n"
+ send_user "\nError: no enable password for $router in $password_file.\n"
continue
}
- set passwd [lindex $pswd 0]
- set enapasswd [lindex $pswd 1]
+ set passwd [join [lindex $pswd 0] ""]
+ set enapasswd [join [lindex $pswd 1] ""]
}
# Figure out username
@@ -581,7 +599,7 @@ foreach router [lrange $argv $i end] {
# command line username
set ruser $username
} else {
- set ruser [find user $router]
+ set ruser [join [find user $router] ""]
if { "$ruser" == "" } { set ruser $default_user }
}
@@ -590,7 +608,7 @@ foreach router [lrange $argv $i end] {
# command line username
set userpswd $userpasswd
} else {
- set userpswd [find userpassword $router]
+ set userpswd [join [find userpassword $router] ""]
if { "$userpswd" == "" } { set userpswd $passwd }
}
@@ -599,7 +617,7 @@ foreach router [lrange $argv $i end] {
# command line enausername
set enauser $enausername
} else {
- set enauser [find enauser $router]
+ set enauser [join [find enauser $router] ""]
if { "$enauser" == "" } { set enauser $ruser }
}
@@ -608,19 +626,19 @@ foreach router [lrange $argv $i end] {
if { "$u_prompt" == "" } {
set u_prompt "(Username|login|user name):"
} else {
- set u_prompt [lindex $u_prompt 0]
+ set u_prompt [join [lindex $u_prompt 0] ""]
}
set p_prompt [find passprompt $router]
if { "$p_prompt" == "" } {
set p_prompt "(\[Pp]assword|passwd):"
} else {
- set p_prompt [lindex $p_prompt 0]
+ set p_prompt [join [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]
+ set e_prompt [join [lindex $e_prompt 0] ""]
}
# Figure out cypher type
@@ -636,6 +654,16 @@ foreach router [lrange $argv $i end] {
set cmethod [find method $router]
if { "$cmethod" == "" } { set cmethod {{telnet} {ssh}} }
+ # Figure out the SSH executable name
+ set sshcmd [find sshcmd $router]
+ if { "$sshcmd" == "" } { set sshcmd {ssh} }
+
+ # Adjust our path to find hpuifilter
+ regexp {(.*)/[^/]+} $argv0 junk hpf_path
+ if { "$hpf_path" != "" && "$hpf_path" != "." } {
+ append env(PATH) ":$hpf_path"
+ }
+
# Login to the router
if {[login $router $ruser $userpswd $passwd $enapasswd $cmethod $cyphertype]} {
continue
diff --git a/bin/hpfilter.c b/bin/hpuifilter.c
index 83d799e..8f7005a 100644
--- a/bin/hpfilter.c
+++ b/bin/hpuifilter.c
@@ -1,21 +1,26 @@
/*
- * Copyright (C) 1997-2002 by Henry Kilmer, Erik Sherk and Pete Whiting.
+ * $Id: hpuifilter.c,v 1.17 2004/01/11 03:49:13 heas Exp $
+ *
+ * Copyright (C) 1997-2004 by Terrapin Communications, Inc.
* 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.
+ * This software may be freely copied, modified and redistributed
+ * without fee for non-commerical purposes provided that this license
+ * remains intact and unmodified with any RANCID distribution.
*
* There is no warranty or other guarantee of fitness of this software.
- * It is provided solely "as is". The author(s) disclaim(s) all
+ * 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.
*
+ * Except where noted otherwise, rancid was written by and is maintained by
+ * Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
*
- * run telnet or ssh to connect to device specified on the command line. the
+ * Run telnet or ssh to connect to device specified on the command line. The
* point of hpfilter is to filter all the bloody vt100 (curses) escape codes
- * that the HP procurve switches belch and make hlogin a real bitch.
+ * that the HP procurve switches belch out, which are a real bitch to handle
+ * in hlogin.
*/
#define DFLT_TO 60 /* default timeout */
@@ -83,7 +88,7 @@ main(int argc, char **argv)
return(EX_USAGE);
}
- if (argc - optind != 2) {
+ if (argc - optind < 2) {
usage();
return(EX_USAGE);
}
@@ -382,16 +387,14 @@ void
usage(void)
{
fprintf(stderr,
-"usage: %s [-hv] <telnet|ssh> <hostname>
-", progname);
+"usage: %s [-hv] <telnet|ssh> [<ssh options>] <hostname> [<telnet_port>]\n",
+ progname);
return;
}
void
vers(void)
{
- fprintf(stderr,
-"%s: %s version %s
-", progname, package, version);
+ fprintf(stderr, "%s: %s version %s\n", progname, package, version);
return;
}
diff --git a/bin/hrancid.in b/bin/hrancid.in
index d0bcc55..fa048ce 100755..100644
--- a/bin/hrancid.in
+++ b/bin/hrancid.in
@@ -1,29 +1,33 @@
-#!@PERLV_PATH@
+#! @PERLV_PATH@
##
-## Amazingly hacked version of Hank's rancid - this one tries to
-## deal with HP procurves.
+## $Id: hrancid.in,v 1.17 2004/01/11 03:49:13 heas Exp $
##
-## Copyright (C) 1997-2001 by Henry Kilmer.
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
+# Amazingly hacked version of Hank's rancid - this one tries to
+# deal with HP procurves.
+#
# RANCID - Really Awesome New Cisco confIg Differ
#
# usage: rancid [-d] [-l] [-f filename | $host]
#
use Getopt::Std;
-getopts('dflm');
+getopts('dfl');
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
@@ -334,7 +338,7 @@ sub WriteTerm {
ProcessHistory("","","",";$_") && next;
- # the rest are from rancid (ie: cisco), but suspect they will someday
+ # the rest are from rancid (i.e.: cisco), but suspect they will someday
# be applicable or close to it.
/^tftp-server flash / && next; # kill any tftp remains
@@ -493,8 +497,12 @@ TOP: while(<INPUT>) {
}
while (/#\s*($cmds_regexp)\s*$/) {
$cmd = $1;
- if (!defined($prompt)) {$prompt = ($_ =~ /^([^#]+)/)[0];
- $prompt .= "[#>]"; }
+ if (!defined($prompt)) {
+ $prompt = ($_ =~ /^([^#]+)/)[0];
+ $prompt =~ s/([][}{)(\\])/\\$1/g;
+ $prompt .= "[#>]";
+ print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
+ }
print STDERR ("HIT COMMAND:$_") if ($debug);
if (! defined($commands{$cmd})) {
print STDERR "$host: found unexpected command - \"$cmd\"\n";
diff --git a/bin/htlogin.in b/bin/htlogin.in
new file mode 100644
index 0000000..8e9c5f5
--- /dev/null
+++ b/bin/htlogin.in
@@ -0,0 +1,492 @@
+#! @EXPECT_PATH@ --
+##
+## $Id: htlogin.in,v 1.7 2004/01/11 05:39:15 heas Exp $
+##
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## All rights reserved.
+##
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
+##
+## 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.
+##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
+##
+#
+# The login expect scripts were based on Erik Sherk's gwtn, by permission.
+#
+# htlogin - Hitachi router login
+#
+# Most options are intuitive for logging into an Hitachi router login.
+#
+
+# Usage line
+set usage "Usage: $argv0 \[-noenable\] \[-c command\] \
+\[-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"
+
+# env(CLOGIN) may contain:
+# x == do not set xterm banner or name
+
+# Password file
+set password_file $env(HOME)/.cloginrc
+# Default is to login to the router
+set do_command 0
+set do_script 0
+# The default is to automatically enable
+set enable 1
+# The default is that you login non-enabled (tacacs can have you login already
+# enabled)
+set avautoenable 0
+# The default is to look in the password file to find the passwords. This
+# tracks if we receive them on the command line.
+set do_passwd 1
+
+# Find the user in the ENV, or use the unix userid.
+if {[ info exists env(CISCO_USER) ] } {
+ set default_user $env(CISCO_USER)
+} elseif {[ info exists env(USER) ]} {
+ set default_user $env(USER)
+} elseif {[ info exists env(LOGNAME) ]} {
+ set default_user $env(LOGNAME)
+} else {
+ # This uses "id" which I think is portable. At least it has existed
+ # (without options) on all machines/OSes I've been on recently -
+ # unlike whoami or id -nu.
+ if [ catch {exec id} reason ] {
+ send_error "\nError: could not exec id: $reason\n"
+ exit 1
+ }
+ regexp {\(([^)]*)} "$reason" junk default_user
+}
+
+# Sometimes routers take awhile to answer (the default is 10 sec)
+set timeout 45
+
+# Process the command line
+for {set i 0} {$i < $argc} {incr i} {
+ set arg [lindex $argv $i]
+
+ switch -glob -- $arg {
+ # Username
+ -u* -
+ -U* {
+ if {! [ regexp .\[uU\](.+) $arg ignore user]} {
+ incr i
+ set username [ lindex $argv $i ]
+ }
+ # VTY Password
+ } -p* -
+ -P* {
+ if {! [ regexp .\[pP\](.+) $arg ignore userpasswd]} {
+ incr i
+ set userpasswd [ lindex $argv $i ]
+ }
+ set do_passwd 0
+ # VTY Password
+ } -v* -
+ -v* {
+ if {! [ regexp .\[vV\](.+) $arg ignore passwd]} {
+ incr i
+ set passwd [ lindex $argv $i ]
+ }
+ set do_passwd 0
+ # Enable Username
+ } -w* -
+ -W* {
+ # 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*
+ {
+ # ignore -e
+ # Command to run.
+ } -c* -
+ -C* {
+ if {! [ regexp .\[cC\](.+) $arg ignore command]} {
+ incr i
+ set command [ lindex $argv $i ]
+ }
+ set do_command 1
+ # Expect script to run.
+ } -s* -
+ -S* {
+ if {! [ regexp .\[sS\](.+) $arg ignore sfile]} {
+ incr i
+ set sfile [ lindex $argv $i ]
+ }
+ if { ! [ file readable $sfile ] } {
+ send_user "\nError: Can't read $sfile\n"
+ exit 1
+ }
+ set do_script 1
+ # 'ssh -c' cypher type
+ } -y* -
+ -Y* {
+ if {! [ regexp .\[eE\](.+) $arg ignore cypher]} {
+ incr i
+ set cypher [ lindex $argv $i ]
+ }
+ # alternate cloginrc file
+ } -f* -
+ -F* {
+ if {! [ regexp .\[fF\](.+) $arg ignore password_file]} {
+ incr i
+ set password_file [ lindex $argv $i ]
+ }
+ # Timeout
+ } -t* -
+ -T* {
+ if {! [ regexp .\[tT\](.+) $arg ignore timeout]} {
+ incr i
+ set timeout [ lindex $argv $i ]
+ }
+ # Command file
+ } -x* -
+ -X {
+ if {! [ regexp .\[xX\](.+) $arg ignore cmd_file]} {
+ incr i
+ set cmd_file [ lindex $argv $i ]
+ }
+ if [ catch {set cmd_fd [open $cmd_file r]} reason ] {
+ send_user "\nError: $reason\n"
+ exit 1
+ }
+ set cmd_text [read $cmd_fd]
+ close $cmd_fd
+ set command [join [split $cmd_text \n] \;]
+ set do_command 1
+ # Do we enable?
+ } -noenable {
+ # ignore -noenable
+ # Does tacacs automatically enable us?
+ } -autoenable {
+ # ignore -autoenable
+ } -* {
+ send_user "\nError: Unknown argument! $arg\n"
+ send_user $usage
+ exit 1
+ } default {
+ break
+ }
+ }
+}
+# Process routers...no routers listed is an error.
+if { $i == $argc } {
+ send_user "\nError: $usage"
+}
+
+# Only be quiet if we are running a script (it can log its output
+# on its own)
+if { $do_script } {
+ log_user 0
+} else {
+ log_user 1
+}
+
+#
+# Done configuration/variable setting. Now run with it...
+#
+
+# Sets Xterm title if interactive...if its an xterm and the user cares
+proc label { host } {
+ global env
+ # if CLOGIN has an 'x' in it, don't set the xterm name/banner
+ if [info exists env(CLOGIN)] {
+ if {[string first "x" $env(CLOGIN)] != -1} { return }
+ }
+ # take host from ENV(TERM)
+ if [info exists env(TERM)] {
+ if [regexp \^(xterm|vs) $env(TERM) ignore ] {
+ send_user "\033]1;[lindex [split $host "."] 0]\a"
+ send_user "\033]2;$host\a"
+ }
+ }
+}
+
+# This is a helper function to make the password file easier to
+# maintain. Using this the password file has the form:
+# add password sl* pete cow
+# add password at* steve
+# add password * hanky-pie
+proc add {var args} { global int_$var ; lappend int_$var $args}
+proc include {args} {
+ global env
+ regsub -all "(^{|}$)" $args {} args
+ if { [ regexp "^/" $args ignore ] == 0 } {
+ set args $env(HOME)/$args
+ }
+ source_password_file $args
+}
+
+proc find {var router} {
+ upvar int_$var list
+ if { [info exists list] } {
+ foreach line $list {
+ if { [string match [lindex $line 0] $router ] } {
+ return [lrange $line 1 end]
+ }
+ }
+ }
+ return {}
+}
+
+# Loads the password file. Note that as this file is tcl, and that
+# it is sourced, the user better know what to put in there, as it
+# could install more than just password info... I will assume however,
+# that a "bad guy" could just as easy put such code in the clogin
+# script, so I will leave .cloginrc as just an extention of that script
+proc source_password_file { password_file } {
+ global env
+ if { ! [file exists $password_file] } {
+ send_user "\nError: password file ($password_file) does not exist\n"
+ exit 1
+ }
+ file stat $password_file fileinfo
+ if { [expr ($fileinfo(mode) & 007)] != 0000 } {
+ send_user "\nError: $password_file must not be world readable/writable\n"
+ exit 1
+ }
+ if [ catch {source $password_file} reason ] {
+ send_user "\nError: $reason\n"
+ exit 1
+ }
+}
+
+# Log into the router.
+proc login { router user userpswd passwd prompt cmethod cyphertype } {
+ global spawn_id in_proc do_command do_script
+ global u_prompt p_prompt
+ set in_proc 1
+ set uprompt_seen 0
+
+ # 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] {
+ regexp {telnet(:([^[:space:]]+))*} $prog command suffix port
+ if {"$port" == ""} {
+ set retval [ catch {spawn telnet $router} reason ]
+ } else {
+ set retval [ catch {spawn telnet $router $port} reason ]
+ }
+ if { $retval } {
+ send_user "\nError: telnet failed: $reason\n"
+ exit 1
+ }
+ } else {
+ puts "\nError: unknown connection method: $prog"
+ return 1
+ }
+ incr progs -1
+ sleep 0.3
+
+ # This helps cleanup each expect clause.
+ expect_after {
+ timeout {
+ send_user "\nError: TIMEOUT reached\n"
+ catch {close}; wait
+ if { $in_proc} {
+ return 1
+ } else {
+ continue
+ }
+ } eof {
+ send_user "\nError: EOF received\n"
+ catch {close}; wait
+ if { $in_proc} {
+ return 1
+ } else {
+ continue
+ }
+ }
+ }
+
+ expect {
+ "Connection refused" {
+ close; wait
+ sleep 0.3
+ expect eof
+ send_user "\nError: Connection Refused\n"; wait; return 1
+ } eof { send_user "\nError: Couldn't login\n"; wait; return 1
+ } "Unknown host\r\n" {
+ expect eof
+ send_user "\nError: Unknown host\n"; wait; return 1
+ } "Host is unreachable" {
+ expect eof
+ send_user "\nError: Host Unreachable!\n"; wait; return 1
+ } "No address associated with name" {
+ expect eof
+ send_user "\nError: Unknown host\n"; wait; return 1
+ }
+ -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
+ }
+ "Password incorrect" { send_user "\nError: Check your password for $router\n";
+ catch {close}; wait; return 1
+ }
+ "$prompt" { break; }
+ denied { send_user "\nError: Check your passwd for $router\n"
+ catch {close}; wait; return 1
+ }
+ "\r\n" { exp_continue; }
+ }
+ }
+ set in_proc 0
+ return 0
+}
+
+# Run commands given on the command line.
+proc run_commands { prompt command } {
+ global in_proc
+ set in_proc 1
+
+ # Is this a multi-command?
+ if [ string match "*\;*" "$command" ] {
+ set commands [split $command \;]
+ set num_commands [llength $commands]
+
+ for {set i 0} {$i < $num_commands} { incr i} {
+ send "[lindex $commands $i]\r"
+ expect {
+ -re "^\[^\n\r]*$prompt" {}
+ -re "^\[^\n\r *]*$prompt" {}
+ -re "\[\n\r]" { exp_continue }
+ }
+ }
+ } else {
+ send "$command\r"
+ expect {
+ -re "^\[^\n\r]*$prompt" {}
+ -re "^\[^\n\r *]*$prompt" {}
+ -re "\[\n\r]" { exp_continue }
+ }
+ }
+ send "exit\r"
+ expect {
+ "\n" { exp_continue }
+ timeout { return 0 }
+ eof { return 0 }
+ }
+ set in_proc 0
+}
+
+#
+# For each router... (this is main loop)
+#
+source_password_file $password_file
+set in_proc 0
+foreach router [lrange $argv $i end] {
+ set router [string tolower $router]
+ send_user "$router\n"
+
+ # Figure out prompt.
+ set prompt "command: "
+ set autoenable 1
+ set enable 0
+
+ # Figure out passwords
+ if { $do_passwd } {
+ set pswd [find password $router]
+ if { [llength $pswd] == 0 } {
+ send_user "Error: no password for $router in $password_file.\n"
+ continue
+ }
+ set passwd [join [lindex $pswd 0] ""]
+ }
+
+ # Figure out username
+ if {[info exists username]} {
+ # command line username
+ set ruser $username
+ } else {
+ set ruser [join [find user $router] ""]
+ if { "$ruser" == "" } { set ruser $default_user }
+ }
+
+ # Figure out username's password (if different from the vty password)
+ if {[info exists userpasswd]} {
+ # command line username
+ set userpswd $userpasswd
+ } else {
+ set userpswd [join [find userpassword $router] ""]
+ if { "$userpswd" == "" } { set userpswd $passwd }
+ }
+
+ # Figure out prompts
+ set u_prompt [find userprompt $router]
+ if { "$u_prompt" == "" } {
+ set u_prompt "(Username|login| Login):"
+ } else {
+ set u_prompt [join [lindex $u_prompt 0] ""]
+ }
+ set p_prompt [find passprompt $router]
+ if { "$p_prompt" == "" } {
+ set p_prompt "\[Pp]assword:"
+ } else {
+ set p_prompt [join [lindex $p_prompt 0] ""]
+ }
+
+ # Figure out cypher type
+ if {[info exists cypher]} {
+ # command line cypher type
+ set cyphertype $cypher
+ } else {
+ set cyphertype [find cyphertype $router]
+ if { "$cyphertype" == "" } { set cyphertype "3des" }
+ }
+
+ # Figure out connection method
+ set cmethod [find method $router]
+ if { "$cmethod" == "" } { set cmethod {{telnet}} }
+
+ # Login to the router
+ if {[login $router $ruser $userpswd $passwd $prompt $cmethod $cyphertype]} {
+ continue
+ }
+
+ if { $do_command } {
+ if {[run_commands $prompt $command]} {
+ continue
+ }
+ } elseif { $do_script } {
+ source $sfile
+ close
+ } else {
+ label $router
+ log_user 1
+ interact
+ }
+
+ # End of for each router
+ wait
+ sleep 0.3
+}
+exit 0
diff --git a/bin/htrancid.in b/bin/htrancid.in
new file mode 100644
index 0000000..2b2eaaa
--- /dev/null
+++ b/bin/htrancid.in
@@ -0,0 +1,266 @@
+#! @PERLV_PATH@
+##
+## $Id: htrancid.in,v 1.5 2004/01/11 03:49:13 heas Exp $
+##
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## All rights reserved.
+##
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
+##
+## 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.
+##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
+##
+#
+# hacked version of Hank's rancid - this one tries to deal with Hitachi's.
+#
+# RANCID - Really Awesome New Cisco confIg Differ
+#
+# usage: htrancid [-d] [-l] [-f filename | $host]
+#
+use Getopt::Std;
+getopts('dfl');
+$log = $opt_l;
+$debug = $opt_d;
+$file = $opt_f;
+$host = $ARGV[0];
+$clean_run = 0;
+$found_end = 0;
+$timeo = 90; # blogin timeout in seconds
+
+my(%filter_pwds); # password filtering mode
+
+# 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 config"
+sub ShowConfig {
+ print STDERR " In ShowConfig: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ ProcessHistory("","","","$_");
+ }
+ return(0);
+}
+
+# This routine parses single command's that return no required info
+sub ShowVersion {
+ print STDERR " In ShowVersion: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ }
+ return(0)
+}
+
+# dummy function
+sub DoNothing {print STDOUT;}
+
+# Main
+%commands=(
+ 'version -a' => "ShowVersion",
+ 'cat /config/router.cnf' => "ShowConfig"
+);
+# 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=(
+ "version -a",
+ "cat /config/router.cnf"
+);
+$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 htlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug);
+ print STDOUT "executing htlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log);
+ if (defined($ENV{NOPIPE})) {
+ system "htlogin -t $timeo -c \"$cisco_cmds\" $host </dev/null > $host.raw 2>&1" || die "htlogin failed for $host: $!\n";
+ open(INPUT, "< $host.raw") || die "htlogin failed for $host: $!\n";
+ } else {
+ open(INPUT,"htlogin -t $timeo -c \"$cisco_cmds\" $host </dev/null |") || die "htlogin failed for $host: $!\n";
+ }
+}
+
+# determine password filtering mode
+if ($ENV{"FILTER_PWDS"} =~ /no/i) {
+ $filter_pwds = 0;
+} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
+ $filter_pwds = 2;
+} else {
+ $filter_pwds = 1;
+}
+
+ProcessHistory("","","","!RANCID-CONTENT-TYPE: hitachi\n!\n");
+TOP: while(<INPUT>) {
+ tr/\015//d;
+ if (/^.*logout$/) {
+ $clean_run=1;
+ last;
+ }
+ if (/^Error:/) {
+ print STDOUT ("$host htlogin error: $_");
+ print STDERR ("$host htlogin error: $_") if ($debug);
+ $clean_run=0;
+ last;
+ }
+ while (/command:\s*($cmds_regexp)\s*$/) {
+ $cmd = $1;
+ if (!defined($prompt)) {
+ $prompt = ($_ =~ /^([^:]+:)/)[0];
+ }
+ print STDERR ("HIT COMMAND:$_") if ($debug);
+ if (! defined($commands{$cmd})) {
+ print STDERR "$host: found unexpected command - \"$cmd\"\n";
+ $clean_run = 0;
+ last TOP;
+ }
+ $rval = &{$commands{$cmd}};
+ delete($commands{$cmd});
+ if ($rval == -1) {
+ $clean_run = 0;
+ last TOP;
+ }
+ }
+}
+print STDOUT "Done $logincmd: $_\n" if ($log);
+# Flush History
+ProcessHistory("","","","");
+# Cleanup
+close(INPUT);
+close(OUTPUT);
+
+if (defined($ENV{NOPIPE})) {
+ unlink("$host.raw") if (! $debug);
+}
+
+# check for completeness
+if (scalar(%commands) || !$clean_run ) {
+ if (scalar(%commands)) {
+ printf(STDOUT "$host: missed cmd(s): %s\n", join(',', keys(%commands)));
+ printf(STDERR "$host: missed cmd(s): %s\n", join(',', keys(%commands))) if ($debug);
+ }
+ if (!$clean_run ) {
+ print STDOUT "$host: End of run not found\n";
+ print STDERR "$host: End of run not found\n" if ($debug);
+ system("/usr/bin/tail -1 $host.new");
+ }
+ unlink "$host.new" if (! $debug);
+}
diff --git a/bin/jerancid.in b/bin/jerancid.in
new file mode 100644
index 0000000..1b72737
--- /dev/null
+++ b/bin/jerancid.in
@@ -0,0 +1,645 @@
+#! @PERLV_PATH@
+##
+## $Id: jerancid.in,v 1.25 2004/01/11 03:49:13 heas Exp $
+##
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## All rights reserved.
+##
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
+##
+## 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.
+##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
+##
+#
+# jerancid - tries to deal with Juniper ERXs.
+#
+# RANCID - Really Awesome New Cisco confIg Differ
+#
+# usage: rancid [-d] [-l] [-f filename | $host]
+#
+use Getopt::Std;
+getopts('dfl');
+$log = $opt_l;
+$debug = $opt_d;
+$file = $opt_f;
+$host = $ARGV[0];
+$clean_run = 0;
+$found_end = 0;
+$timeo = 90; # clogin timeout in seconds
+
+my(%filter_pwds); # password filtering mode
+
+# 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);
+ my($slots);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+ next if(/^(\s*|\s*$cmd\s*)$/);
+ next if (/^Please wait/i);
+ return(-1) if (/command authorization failed/i);
+
+ /^Juniper Edge .* (\S+)$/ &&
+ ProcessHistory("COMMENTS","keysort","A1",
+ "!Chassis type: $1 - a $_") && next;
+ /^System Release: / &&
+ ProcessHistory("COMMENTS","keysort","B1", "!$_") && next;
+ /^\s+(Version: .*)$/ &&
+ ProcessHistory("COMMENTS","keysort","B1", "!System $1\n") &&
+ next;
+
+ if (/^(slot .*)\s+slot uptime/i) {
+ ($slots++);
+ ProcessHistory("COMMENTS","keysort","B2", "!\n! $1\n");
+ next;
+ }
+ /^(--.*) --+$/ && $slots &&
+ ProcessHistory("COMMENTS","keysort","B2", "! $1\n") && next;
+ if (/^(\d+ +\S+ +(\S+).*) \S+$/ && $slots) {
+ my($line) = $1;
+ if ($2 != /--+/) {
+ ProcessHistory("COMMENTS","keysort","B3", "! $line\n");
+ }
+ next;
+ }
+ }
+ ProcessHistory("COMMENTS","keysort","B4","!\n");
+ return(0);
+}
+
+# This routine parses "show redundancy"
+sub ShowRedundancy {
+ print STDERR " In ShowRedundancy: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+ next if(/^(\s*|\s*$cmd\s*)$/);
+ next if (/^Please wait/i);
+
+ ProcessHistory("","","","! $_");
+ }
+ ProcessHistory("","","","!\n");
+ return(0);
+}
+
+# This routine parses "show environment all"
+sub ShowEnv {
+ print STDERR " In ShowEnv: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ next if (/^Please wait/i);
+ return(-1) if (/command authorization failed/i);
+
+ # skip the temperature goop
+ if (/processor\s+processor/) {
+ <INPUT>; <INPUT>; <INPUT>;
+ next;
+ }
+ /^\d+\s+\d+\s+\S+/ && next;
+
+ # strip nvs usage
+ s/, \d+% \S+\)/\)/;
+
+ s/^ //;
+ ProcessHistory("COMMENTS","keysort","D1","! $_");
+ }
+ ProcessHistory("COMMENTS","keysort","D1","!\n");
+ return(0);
+}
+
+# This routine parses "show boot"
+sub ShowBoot {
+ print STDERR " In ShowBoot: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ next if (/^Please wait/i);
+ next if (/^\s*$/);
+ return(1) if /^\s*\^\s*$/;
+ return(-1) if (/command authorization failed/i);
+ return(1) if /Ambiguous command/i;
+
+ /System Release:\s+(.*)/ &&
+ ProcessHistory("COMMENTS","keysort","C1","!Boot Release: $1\n")
+ && next;
+ /System Configuration:\s+(.*)/ &&
+ ProcessHistory("COMMENTS","keysort","C1",
+ "!Boot Configuration: $1\n") && next;
+
+ ProcessHistory("COMMENTS","keysort","C1","!$_");
+ }
+ ProcessHistory("COMMENTS","keysort","C1","!\n");
+ return(0);
+}
+
+# This routine parses "dir"
+sub DirSlotN {
+ print STDERR " In DirSlotN: $_" if ($debug);
+
+ my($dev) = (/\s([^\s]+):/);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ next if (/^Please wait/i);
+ next if (/^system\.log/);
+
+ ProcessHistory("FLASH","","","!Flash: $_");
+ }
+ ProcessHistory("","","","!\n");
+ return(0);
+}
+
+# This routine parses "show hardware"
+sub ShowHardware {
+ print STDERR " In ShowHardware: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ next if (/^Please wait/i);
+ # return(1) if ($type =~ /^(12[40]|7[05])/);
+ return(-1) if (/command authorization failed/i);
+ next if (/^Please wait/i);
+
+ # wow...a clean table
+ ProcessHistory("","","","!$_");
+ }
+ ProcessHistory("","","","!\n");
+ return(0);
+}
+
+# This routine processes a "show configuration"
+sub WriteTerm {
+ print STDERR " In WriteTerm: $_" if ($debug);
+ my($lineauto) = 0;
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+ next if (/^Please wait/i);
+ return(-1) if (/command authorization failed/i);
+ /Non-Volatile memory is in use/ && return(-1); # NvRAM is locked
+ $lineauto = 0 if (/^[^ ]/);
+
+ # skip the crap
+ /^! Configuration script /i && next;
+ /^! Copyright /i && next;
+
+ # Dog gone Cool matches to process the rest of the config
+ /^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");
+ next;
+ }
+ if (/^(enable secret) / && $filter_pwds >= 2) {
+ ProcessHistory("ENABLE","","","!$1 <removed>\n");
+ next;
+ }
+
+ # XXX: ERX appears to not have local usernames, but leaving these in
+ # case I am wrong.
+ if (/^username (\S+)(\s.*)? secret /) {
+ if ($filter_pwds >= 2) {
+ ProcessHistory("USER","keysort","$1",
+ "!username $1$2 secret <removed>\n");
+ } else {
+ ProcessHistory("USER","keysort","$1","$_");
+ }
+ next;
+ }
+ if (/^username (\S+)(\s.*)? password ((\d) \S+|\S+)/) {
+ if ($filter_pwds == 2) {
+ ProcessHistory("USER","keysort","$1",
+ "!username $1$2 password <removed>\n");
+ } elsif ($filter_pwds == 1 && $4 ne "5"){
+ ProcessHistory("USER","keysort","$1",
+ "!username $1$2 password <removed>\n");
+ } else {
+ ProcessHistory("USER","keysort","$1","$_");
+ }
+ next;
+ }
+
+ if (/^(\s*)password / && $filter_pwds >= 1) {
+ ProcessHistory("LINE-PASS","","","!$1password <removed>\n");
+ next;
+ }
+ if (/^\s*neighbor (\S*) password / && $filter_pwds >= 1) {
+ ProcessHistory("","","","! neighbor $1 password <removed>\n");
+ next;
+ }
+ if (/^(ppp .* password) 7 .*/ && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
+ if (/^( ip ospf authentication-key) / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
+ # isis interface passwords
+ if (/^(\s+isis authentication-key \S+)( \d)? \S+/ &&
+ $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>$'\n"); next;
+ }
+ if (/^(\s+isis message-digest-key \d+ hmac-md5)( \d)?( \S+)/ &&
+ $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>$'"); next;
+ }
+
+ # this is reversable, despite 'md5' in the cmd
+ if (/^(\s+ip ospf authentication-key \S+)( \d)? \S+/ &&
+ $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>$'\n"); next;
+ }
+ if (/^(\s+ip ospf message-digest-key \d+ hmac-md5)( \d)?( \S+)/ &&
+ $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>$'"); next;
+ }
+ if (/^( ip ospf message-digest-key \d+ md5) / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
+
+ # filter VRRP passwords
+ if (/^(\s+ip vrrp authentication-key \d+)( \d)? \s+ / &&
+ $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
+
+ # ftp host encrypted password oscillates
+ if (/^(host \S+ \S+ ftp) /) {
+ if ($filter_pwds >= 1 || /^host \S+ \S+ ftp \d /) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
+ }
+
+ # sort ip explicit-paths.
+ if (/^ip explicit-path name (\S+)/) {
+ my($key) = $1;
+ my($expath) = $_;
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ last if (/^$prompt/ || ! /^(ip explicit-path name |[ !])/);
+ if (/^ip explicit-path name (\S+)/) {
+ ProcessHistory("EXPATH","keysort","$key","$expath");
+ $key = $1;
+ $expath = $_;
+ } else {
+ $expath .= $_;
+ }
+ }
+ ProcessHistory("EXPATH","keysort","$key","$expath");
+ }
+ # sort route-maps
+ if (/^route-map (\S+)/) {
+ my($key) = $1;
+ my($routemap) = $_;
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/ || ! /^(route-map |[ !])/);
+ if (/^route-map (\S+)/) {
+ ProcessHistory("ROUTEMAP","keysort","$key","$routemap");
+ $key = $1;
+ $routemap = $_;
+ } else {
+ $routemap .= $_;
+ }
+ }
+ ProcessHistory("ROUTEMAP","keysort","$key","$routemap");
+ }
+ # filter out any RCS/CVS tags to avoid confusing local CVS storage
+ s/\$(Revision|Id):/ $1:/;
+
+ # order 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/prune snmp-server host statements
+ # we only prune lines of the form
+ # snmp-server host a.b.c.d <community>
+ if (/^snmp-server host (\d+\.\d+\.\d+\.\d+) /) {
+ if (defined($ENV{'NOCOMMSTR'})) {
+ my($ip) = $1;
+ my($line) = "snmp-server host $ip";
+ my(@tokens) = split(' ', $');
+ my($token);
+ while ($token = shift(@tokens)) {
+ if ($token eq 'version' || $tokens[0] == 1) {
+ $line .= " " . join(' ', ($token, shift(@tokens)));
+ } elsif ($token =~ /^(informs?|traps?|(no)?auth)$/) {
+ $line .= " " . $token;
+ } else {
+ $line = "!$line " .
+ join(' ', ("<removed>", join(' ',@tokens)));
+ last;
+ }
+ }
+ ProcessHistory("SNMPSERVERHOST","ipsort","$ip","$line\n");
+ } else {
+ ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_");
+ }
+ next;
+ }
+ if (/^(snmp-server community) (\S+)/) {
+ if (defined($ENV{'NOCOMMSTR'})) {
+ ProcessHistory("SNMPSERVERCOMM","keysort","$_","!$1 <removed>$'");
+ next;
+ } else {
+ ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next;
+ }
+ }
+
+ # prune tacacs/radius server keys
+ if (/^(tacacs-server|radius-server) key / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 key <removed>\n"); next;
+ }
+ if (/^((tacacs-server|radius-server) host \S+ key)( \d)? \S+/ &&
+ $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>$'"); next;
+ }
+ if (/^( key )(\d )?\S+/ && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>$'"); next;
+ }
+
+ # order clns host statements
+ /^clns host \S+ (\S+)/ &&
+ ProcessHistory("CLNS","keysort","$1","$_") && next;
+ # order alias statements
+ /^alias / && ProcessHistory("ALIAS","keysort","$_","$_") && next;
+ # filter isis keys
+ if (/^( (area|domain)-message-digest-key \d+ hmac-md5)( \d)? \S+/ &&
+ $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>$'\n"); next;
+ }
+ if (/^( (area|domain)-authentication-key)( \d)? \S+( \d)?/ &&
+ $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>$'\n"); next;
+ }
+
+ # delete ntp auth password - this md5 is a reversable too
+ if (/^(ntp authentication-key \d+ md5) / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
+
+ # order ntp peers/servers
+ if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) {
+ $sortkey = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5);
+ ProcessHistory("NTP","keysort",$sortkey,"$_");
+ next;
+ }
+
+ # catch anything that wasnt matched above.
+ ProcessHistory("","","","$_");
+ # end of config...is a comment.
+ if (/^! end of /i) {
+ $found_end = 1;
+ return(1);
+ }
+ }
+ return(0);
+}
+
+# dummy function
+sub DoNothing {print STDOUT;}
+
+# Main
+%commands=(
+ 'show version' => "ShowVersion",
+ 'show redundancy' => "ShowRedundancy",
+ 'show boot' => "ShowBoot",
+ 'show environment all' => "ShowEnv",
+ 'dir' => "DirSlotN",
+ 'show hardware' => "ShowHardware",
+ '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 redundancy",
+ "show boot",
+ "show environment all",
+ "dir",
+ "show hardware",
+ "show configuration"
+);
+$jnxe_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\"$jnxe_cmds\" $host\n" if ($debug);
+ print STDOUT "executing clogin -t $timeo -c\"$jnxe_cmds\" $host\n" if ($log);
+ if (defined($ENV{NOPIPE})) {
+ system "clogin -t $timeo -c \"$jnxe_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 \"$jnxe_cmds\" $host </dev/null |") || die "clogin failed for $host: $!\n";
+ }
+}
+
+# determine password filtering mode
+if ($ENV{"FILTER_PWDS"} =~ /no/i) {
+ $filter_pwds = 0;
+} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
+ $filter_pwds = 2;
+} else {
+ $filter_pwds = 1;
+}
+
+ProcessHistory("","","","!RANCID-CONTENT-TYPE: Juniper_ERX\n!\n");
+ProcessHistory("COMMENTS","keysort","B0","!\n");
+ProcessHistory("COMMENTS","keysort","F0","!\n");
+ProcessHistory("COMMENTS","keysort","G0","!\n");
+TOP: while(<INPUT>) {
+ tr/\015//d;
+ if (/\#\s?exit$/) {
+ $clean_run=1;
+ last;
+ }
+ if (/^Error:/) {
+ print STDOUT ("$host clogin error: $_");
+ print STDERR ("$host clogin error: $_") if ($debug);
+ $clean_run=0;
+ last;
+ }
+ while (/#\s*($cmds_regexp)\s*$/) {
+ $cmd = $1;
+ if (!defined($prompt)) {
+ $prompt = ($_ =~ /^([^#]+#)/)[0];
+ $prompt =~ s/([][}{)(\\])/\\$1/g;
+ print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
+ }
+ print STDERR ("HIT COMMAND:$_") if ($debug);
+ if (! defined($commands{$cmd})) {
+ print STDERR "$host: found unexpected command - \"$cmd\"\n";
+ $clean_run = 0;
+ last TOP;
+ }
+ $rval = &{$commands{$cmd}};
+ delete($commands{$cmd});
+ if ($rval == -1) {
+ $clean_run = 0;
+ last TOP;
+ }
+ }
+}
+print STDOUT "Done $logincmd: $_\n" if ($log);
+# Flush History
+ProcessHistory("","","","");
+# Cleanup
+close(INPUT);
+close(OUTPUT);
+
+if (defined($ENV{NOPIPE})) {
+ unlink("$host.raw") if (! $debug);
+}
+
+# check for completeness
+if (scalar(%commands) || !$clean_run || !$found_end) {
+ if (scalar(%commands)) {
+ printf(STDOUT "$host: missed cmd(s): %s\n", join(',', keys(%commands)));
+ printf(STDERR "$host: missed cmd(s): %s\n", join(',', keys(%commands))) if ($debug);
+ }
+ if (!$clean_run || !$found_end) {
+ print STDOUT "$host: End of run not found\n";
+ print STDERR "$host: End of run not found\n" if ($debug);
+ system("/usr/bin/tail -1 $host.new");
+ }
+ unlink "$host.new" if (! $debug);
+}
diff --git a/bin/jlogin.in b/bin/jlogin.in
index 0f005d7..31be4f6 100755..100644
--- a/bin/jlogin.in
+++ b/bin/jlogin.in
@@ -1,25 +1,30 @@
-#!@EXPECT_PATH@ --
+#! @EXPECT_PATH@ --
##
+## $Id: jlogin.in,v 1.41 2004/01/11 05:39:15 heas Exp $
##
-## Copyright (C) 1997-2001 by Henry Kilmer, Erik Sherk and Pete Whiting.
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
-# jlogin - juniper ssh login
+# The login expect scripts were based on Erik Sherk's gwtn, by permission.
#
-## Most options are intuitive for logging into a Cisco router.
-## The default username password is the same as the vty password.
+# jlogin - juniper login
+#
+# Most options are intuitive for logging into a Cisco router.
+# The default username password is the same as the vty password.
#
# Usage line
@@ -49,6 +54,8 @@ if {[ info exists env(CISCO_USER) ] } {
set default_user $env(CISCO_USER)
} elseif {[ info exists env(USER) ]} {
set default_user $env(USER)
+} elseif {[ info exists env(LOGNAME) ]} {
+ set default_user $env(LOGNAME)
} else {
# This uses "id" which I think is portable. At least it has existed
# (without options) on all machines/OSes I've been on recently -
@@ -82,7 +89,7 @@ for {set i 0} {$i < $argc} {incr i} {
if {[ regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} {
set E$varname $varvalue
} else {
- send_user "Error: invalid format for -E in $arg\n"
+ send_user "\nError: invalid format for -E in $arg\n"
exit 1
}
# alternate cloginrc file
@@ -249,6 +256,7 @@ proc source_password_file { password_file } {
# Log into the router.
proc login { router user passwd cmethod cyphertype identfile} {
global spawn_id in_proc do_command do_script passphrase prompt
+ global sshcmd
set in_proc 1
# try each of the connection methods in $cmethod until one is successful
@@ -270,13 +278,13 @@ proc login { router user passwd cmethod cyphertype identfile} {
# We use two calls to spawn since spawn does not seem to parse
# spaces correctly.
if {$identfile != ""} {
- if [ catch {spawn ssh -c $cyphertype -x -l $user -i $identfile $router} reason ] {
- send_user "\nError: failed to ssh: $reason\n"
+ if [ catch {spawn $sshcmd -c $cyphertype -x -l $user -i $identfile $router} reason ] {
+ send_user "\nError: failed to $sshcmd: $reason\n"
exit 1
}
} else {
- if [ catch {spawn ssh -c $cyphertype -x -l $user $router} reason ] {
- send_user "\nError: failed to ssh: $reason\n"
+ if [ catch {spawn $sshcmd -c $cyphertype -x -l $user $router} reason ] {
+ send_user "\nError: failed to $sshcmd: $reason\n"
exit 1
}
}
@@ -438,7 +446,7 @@ foreach router [lrange $argv $i end] {
# command line username
set loginname $username
} else {
- set loginname [find user $router]
+ set loginname [join [find user $router] ""]
if { "$loginname" == "" } { set loginname $default_user }
}
@@ -447,11 +455,11 @@ foreach router [lrange $argv $i end] {
# command line passwd
set passwd $userpasswd
} else {
- set passwd [lindex [find userpassword $router] 0]
+ set passwd [join [lindex [find userpassword $router] 0] ""]
if { "$passwd" == "" } {
- set passwd [lindex [find password $router] 0]
+ set passwd [join [lindex [find password $router] 0] ""]
if { "$passwd" == "" } {
- send_user "Error: no password for $router in $password_file.\n"
+ send_user "\nError: no password for $router in $password_file.\n"
continue
}
}
@@ -460,7 +468,7 @@ foreach router [lrange $argv $i end] {
# figure out identity file to use
set identfile ""
if {[info exists identity]} {
- set identfile [lindex [find identity $router] 0]
+ set identfile [join [lindex [find identity $router] 0] ""]
}
# Figure out ssh cypher type
@@ -476,6 +484,10 @@ foreach router [lrange $argv $i end] {
set cmethod [find method $router]
if { "$cmethod" == "" } { set cmethod {{telnet} {ssh}} }
+ # Figure out the SSH executable name
+ set sshcmd [find sshcmd $router]
+ if { "$sshcmd" == "" } { set sshcmd {ssh} }
+
# Login to the router
if {[login $router $loginname $passwd $cmethod $cyphertype $identfile]} {
continue
diff --git a/bin/jrancid.in b/bin/jrancid.in
index 238e704..2793446 100755..100644
--- a/bin/jrancid.in
+++ b/bin/jrancid.in
@@ -1,23 +1,27 @@
-#!@PERLV_PATH@
+#! @PERLV_PATH@
##
-## Amazingly hacked version of Hank's rancid - this one tries to
-## deal with Junipers.
+## $Id: jrancid.in,v 1.58 2004/01/11 03:49:13 heas Exp $
##
-## Original Rancid: Copyright (C) 1997-2001 by Henry Kilmer.
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
+# Amazingly hacked version of Hank's rancid - this one tries to
+# deal with Junipers.
+#
# RANCID - Really Awesome New Cisco confIg Differ
#
# usage: jrancid [-d] [-l] [-f filename | $host]
@@ -147,6 +151,8 @@ sub ShowChassisClocks {
while (<INPUT>) {
tr/\015//d;
last if(/^$prompt/);
+ next if(/^system (shutdown message from|going down )/i);
+ next if(/^\{(master|backup)}/);
/error: the chassis subsystem is not running/ && return;
/Couldn\'t initiate connection/ && return;
@@ -171,6 +177,8 @@ sub ShowChassisEnvironment {
while (<INPUT>) {
tr/\015//d;
last if(/^$prompt/);
+ next if(/^system (shutdown message from|going down )/i);
+ next if(/^\{(master|backup)}/);
/error: the chassis subsystem is not running/ && return;
/Couldn\'t initiate connection/ && return;
@@ -199,6 +207,8 @@ sub ShowChassisFirmware {
while (<INPUT>) {
tr/\015//d;
last if(/^$prompt/);
+ next if(/^system (shutdown message from|going down )/i);
+ next if(/^\{(master|backup)}/);
/error: the chassis subsystem is not running/ && return;
/Couldn\'t initiate connection/ && return;
@@ -220,6 +230,8 @@ sub ShowChassisFpcDetail {
while (<INPUT>) {
tr/\015//d;
last if(/^$prompt/);
+ next if(/^system (shutdown message from|going down )/i);
+ next if(/^\{(master|backup)}/);
/error: the chassis subsystem is not running/ && return;
/Couldn\'t initiate connection/ && return;
@@ -244,6 +256,8 @@ sub ShowChassisHardware {
while (<INPUT>) {
tr/\015//d;
last if(/^$prompt/);
+ next if(/^system (shutdown message from|going down )/i);
+ next if(/^\{(master|backup)}/);
/error: the chassis subsystem is not running/ && return;
/Couldn\'t initiate connection/ && return;
@@ -266,6 +280,8 @@ sub ShowChassisRoutingEngine {
while (<INPUT>) {
tr/\015//d;
last if(/^$prompt/);
+ next if(/^system (shutdown message from|going down )/i);
+ next if(/^\{(master|backup)}/);
/error: the chassis subsystem is not running/ && return;
/Couldn\'t initiate connection/ && return;
@@ -284,8 +300,8 @@ sub ShowChassisRoutingEngine {
return;
}
-# This routine parses "show chassis feb" "show chassis scb", "show
-# chassis sfm detail", and "show chassis ssb".
+# This routine parses "show chassis cfeb", "show chassis feb", "show
+# chassis scb", "show chassis sfm detail", and "show chassis ssb".
# Only do this routine once.
sub ShowChassisSCB {
print STDERR " In ShowChassisSCB: $_" if ($debug);
@@ -295,6 +311,8 @@ sub ShowChassisSCB {
while (<INPUT>) {
tr/\015//d;
last if(/^$prompt/);
+ next if(/^system (shutdown message from|going down )/i);
+ next if(/^\{(master|backup)}/);
return if ($ShowChassisSCB);
/error: the chassis subsystem is not running/ && return;
@@ -316,6 +334,25 @@ sub ShowChassisSCB {
}
# This routine parses "show system boot-messages"
+sub ShowChassisAlarms {
+ print STDERR " In ShowChassisAlarms: $_" if ($debug);
+
+ ProcessHistory("","","","# $_");
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+ next if(/^system (shutdown message from|going down )/i);
+ next if(/^\{(master|backup)}/);
+
+ /Unrecognized command/ && return;
+ /^\s+\^/ && return;
+ /syntax error/ && return;
+ ProcessHistory("","","","# $_");
+ }
+ return;
+}
+
+# This routine parses "show system boot-messages"
sub ShowSystemBootMessages {
print STDERR " In ShowSystemBootMessages: $_" if ($debug);
@@ -324,6 +361,8 @@ sub ShowSystemBootMessages {
while (<INPUT>) {
tr/\015//d;
last if(/^$prompt/);
+ next if(/^system (shutdown message from|going down )/i);
+ next if(/^\{(master|backup)}/);
/Unrecognized command/ && return;
/^\s+\^/ && return;
@@ -347,10 +386,15 @@ sub ShowVersion {
while (<INPUT>) {
tr/\015//d;
last if(/^$prompt/);
+ next if(/^\s*$/);
+ next if(/^system (shutdown message from|going down )/i);
+ next if(/^\{(master|backup)}/);
/^Juniper Networks is:/ && ProcessHistory("","","","# \n# $_") && next;
ProcessHistory("","","","# $_");
}
+ ProcessHistory("","","","#\n");
+
return;
}
@@ -371,11 +415,14 @@ sub ShowConfiguration {
$found_end++;
last;
}
+ next if(/^system (shutdown message from|going down )/i);
+ next if(/^\{(master|backup)}/);
$lines++;
/^database header mismatch: / && return(-1);
/^version .*;\d+$/ && return(-1);
+ s/ # SECRET-DATA$//;
# filter snmp community, when in snmp { stanza }
/^snmp/ && $snmp++;
/^}/ && ($snmp = 0);
@@ -384,24 +431,30 @@ sub ShowConfiguration {
$_ = "$1$2 \"<removed>\"$3\n";
}
}
- if (/(\s*authentication-key ).*$/ && $filter_pwds >= 1) {
- s/(\s*authentication-key ).*$/#$1<removed>;/;
+ if (/(\s*authentication-key )[^ ;]+/ && $filter_pwds >= 1) {
+ ProcessHistory("","","","#$1<removed>$'");
+ next;
}
- if (/(\s*hello-authentication-key ).*$/ && $filter_pwds >= 1) {
- s/(\s*hello-authentication-key ).*$/#$1<removed>;/;
+ if (/(\s*hello-authentication-key )[^ ;]+/ && $filter_pwds >= 1) {
+ ProcessHistory("","","","#$1<removed>$'");
+ next;
}
- if (/^(.*\ssecret \")\$9\$.*(\".*)$/ && $filter_pwds >= 1) {
- s/^(.*\ssecret \")\$9\$.*(\".*)$/#$1<removed>$2/;
+ if (/^(.*\ssecret )[^ ;]+/ && $filter_pwds >= 1) {
+ ProcessHistory("","","","#$1<removed>$'");
+ next;
}
- if (/(\s+encrypted-password ).*$/ && $filter_pwds >= 2) {
- ProcessHistory("","","","#$1<removed>;\n");
+ if (/(\s+encrypted-password )[^ ;]+/ && $filter_pwds >= 2) {
+ ProcessHistory("","","","#$1<removed>$'");
next;
}
if (/(\s+ssh-(rsa|dsa) )\"/ && $filter_pwds >= 2) {
ProcessHistory("","","","#$1<removed>;\n");
next;
}
- s/ # SECRET-DATA$//;
+ if (/^(\s+(pre-shared-|)key (ascii-text|hexadecimal) )[^ ;]+/ && $filter_pwds >= 1) {
+ ProcessHistory("","","","#$1<removed>$'");
+ next;
+ }
ProcessHistory("","","","$_");
}
@@ -433,8 +486,10 @@ sub DoNothing {print STDOUT;}
"show chassis sfm detail" => "ShowChassisSCB",
"show chassis ssb" => "ShowChassisSCB",
"show chassis feb" => "ShowChassisSCB",
+ "show chassis cfeb" => "ShowChassisSCB",
+ "show chassis alarms" => "ShowChassisAlarms",
"show system boot-messages" => "ShowSystemBootMessages",
- "show version" => "ShowVersion",
+ "show version detail" => "ShowVersion",
"show configuration" => "ShowConfiguration"
);
@commands=(
@@ -448,8 +503,10 @@ sub DoNothing {print STDOUT;}
"show chassis sfm detail",
"show chassis ssb",
"show chassis feb",
+ "show chassis cfeb",
+ "show chassis alarms",
"show system boot-messages",
- "show version",
+ "show version detail",
"show configuration"
);
@@ -512,7 +569,8 @@ TOP: while(<INPUT>) {
$cmd = $1;
if (!defined($prompt)) {
$prompt = ($_ =~ /^([^>]+>)/)[0];
- $prompt =~ s/([}{)(\\])/\\$1/g;
+ $prompt =~ s/([][}{)(\\])/\\$1/g;
+ print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
}
print STDERR ("HIT COMMAND:$_") if ($debug);
if (! defined($commands{$cmd})) {
diff --git a/util/lg/lg.cgi.in b/bin/lg.cgi.in
index 2921f72..ad08c68 100755..100644
--- a/util/lg/lg.cgi.in
+++ b/bin/lg.cgi.in
@@ -1,19 +1,27 @@
-#!@PERLV_PATH@
-## The original original lookingglass s/w was written by Ed Kern. it
-## is a single script and used to be available at http://nitrous.digex.net/
-#
-## Copyright (C) 1997-2001 by Henry Kilmer.
+#! @PERLV_PATH@
+##
+## $Id: lg.cgi.in,v 1.47 2004/01/11 03:49:13 heas Exp $
+##
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
+##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
+##
+#
+# The original original lookingglass s/w was written by Ed Kern. It was
+# a single script that used to be available at http://nitrous.digex.net/.
+# Provided by permission and modified beyond recognition.
#
# Looking glass
# vars: query, router, args
@@ -23,12 +31,13 @@ $me = $0;
$me =~ s/.*\/(\S+)$/$1/;
}
-use CGI qw/:standard/;
+use CGI qw/:standard escapeHTML/;
use POSIX qw(strftime);
use Sys::Syslog;
use LockFile::Simple qw(lock trylock unlock);
my($BASEDIR) = "@prefix@";
+my($SYSCONFDIR) = "@sysconfdir@";
my($pingcmd) = "@LG_PING_CMD@";
my($query, $max_time_diff, $cache_dir, $cloginrc, @results);
@@ -74,17 +83,18 @@ sub dolog
}
return;
}
+
# read LG configuration file
sub readconf
{
my($conffile, $cmds);
local(*CONF);
- if (defined($env{LG_CONF})) {
- $conffile = $env{LG_CONF};
+ if (defined($ENV{LG_CONF})) {
+ $conffile = $ENV{LG_CONF};
} elsif (-e "lg.conf") {
$conffile = "lg.conf";
} else {
- $conffile = "$BASEDIR/util/lg/lg.conf";
+ $conffile = "$SYSCONFDIR/lg.conf";
}
if (! -f $conffile) {
@@ -99,12 +109,14 @@ sub readconf
close(CONF);
eval $cmds;
} else {
- printf(STDERR "ERROR: couldn\'t open the configuration file: $conffile: $!\n");
+ printf(STDERR "ERROR: couldn\'t open the configuration file: " .
+ "$conffile: $!\n");
exit(1);
}
return;
}
+
# read router.db file
sub readrouters
{
@@ -114,7 +126,7 @@ sub readrouters
if (defined($LG_ROUTERDB)) {
$rtrdb = $LG_ROUTERDB;
} else {
- $rtrdb = "$BASEDIR/util/lg/router.db";
+ $rtrdb = "$SYSCONFDIR/router.db";
}
if (! -f $rtrdb) {
@@ -126,7 +138,7 @@ sub readrouters
dolog(LOG_ERR, "ERROR: couldn\'t read $BASEDIR: $!\n");
} else {
while ($dir = readdir(DIR)) {
- next if ($dir =~ /^(\.|\.\.|CVS|bin|logs|util)$/);
+ next if ($dir =~ /^(\.|\.\.|CVS|bin|etc|logs|util)$/);
push(@dirs, $dir) if (-d "$BASEDIR/$dir");
}
closedir(DIR);
@@ -149,7 +161,8 @@ sub readrouters
}
close(RTR);
} else {
- dolog(LOG_ERR, "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");
}
}
}
@@ -165,7 +178,8 @@ sub readrouters
}
close(RTR);
} else {
- dolog(LOG_ERR, "ERROR: couldn\'t open the router.db file: $rtrdb: $!\n");
+ dolog(LOG_ERR, "ERROR: couldn\'t open the router.db file: " .
+ "$rtrdb: $!\n");
exit(1);
}
}
@@ -173,7 +187,7 @@ sub readrouters
return;
}
-# the functions remaining are particular to lg.cgi.
+# the remaining functions are particular to lg.cgi.
# return true if $router is a member of @rtrlist
sub arraymember {
@@ -188,6 +202,7 @@ sub arraymember {
return(0);
}
+
# check reachability and lock file before attempting to connect to device
# return non-zero on error.
sub DoRsh
@@ -205,19 +220,18 @@ sub DoRsh
`$pingcmd $router 56 1`;
}
if ($?) {
- push(@results, "$router is unreachable. Try again later.\n");
- print @results;
+ print "$router is unreachable. Try again later.\n";
return(-1);
}
if (! $lckobj->lock("$cache_dir/$router")) {
- push(@results, "$router is busy. Try again later.\n");
- print @results;
+ print "$router is busy. Try again later.\n";
return(-1);
}
$val = &DoCmd($router, $mfg, $cmd, $arg);
$lckobj->unlock("$cache_dir/$router");
- return ($val);
+ return($val);
}
+
# run commands on the router. return non-zero on error.
sub DoCmd
{
@@ -225,13 +239,10 @@ sub DoCmd
local(*CMD);
if ($mfg =~ /foundry/i) {
- $cmd = $foundryCmd{$type};
open(CMD, "sh -c \"flogin -f $cloginrc -c \'$cmd $arg\' $rtr\" 2>&1 |");
} elsif ($mfg =~ /juniper/i) {
- $cmd = $juniperCmd{$type};
open(CMD, "sh -c \"jlogin -f $cloginrc -c \'$cmd $arg\' $rtr\" 2>&1 |");
} else {
- $cmd = $ciscoCmd{$type};
open(CMD, "sh -c \"clogin -noenable -f $cloginrc -c \'$cmd $arg\' $rtr\" 2>&1 |");
}
while (<CMD>) {
@@ -266,6 +277,8 @@ sub DoCmd
return(0);
}
+
+##
# Subroutine: Error
# Usage: &Error("msg"));
# Description: displays an error and exits.
@@ -275,27 +288,32 @@ sub Error {
my($q) = new CGI();
print $q->header;
- print $q->start_html("Looking Glass Error");
-
- print "<BODY>";
+ if ($LG_STYLE) {
+ print $query->start_html(-title => "LookingGlass Results - $router",
+ -style => {'src' => $LG_STYLE});
+ } else {
+ print $query->start_html(-title => "LookingGlass Results - $router");
+ }
# 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>
+ <br>
+ <B><FONT SIZE=+2>Looking Glass Error:</FONT></B>
+ <p>
+ $msg
+ <br>
+ <hr>
+ $LG_INFO
EOF
print $q->end_html;
exit(0);
}
-# convert a ipv4 address mask to prefix length
+
+# convert an ipv4 address mask to prefix length
sub mask2len {
my($mask) = shift;
my($a, $b, $c, $d) = split('\.', $mask);
@@ -308,6 +326,7 @@ sub mask2len {
return($len);
}
+
# end the page and exit.
sub end_page {
@@ -320,6 +339,7 @@ END
print $query->end_html;
exit(0);
}
+
# start the page and log the transaction...
sub start_page {
my($mfg) = @_;
@@ -330,7 +350,12 @@ sub start_page {
$ENV{REMOTE_HOST}, $ENV{REMOTE_ADDR}, $ENV{REMOTE_USER},
"- - [$timestr] $type $router $arg"));
print $query->header;
- print $query->start_html("Looking Glass Results - $router");
+ if ($LG_STYLE) {
+ print $query->start_html(-title =>"LookingGlass form",
+ -style => {'src' => $LG_STYLE});
+ } else {
+ print $query->start_html(-title =>"LookingGlass from");
+ }
$timestr = strftime("%a %b %e %H:%M:%S %Y %Z", gmtime);
@@ -369,17 +394,16 @@ HEAD
END
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
-## spaces). Modify $max_time_diff to set the lifetime for each cache.
-## Currently, cache lifetime is the same for all queries.
+# 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 with
+# no spaces). Modify $LG_CACHE_TIME to set the lifetime for cache entries.
# for most web servers, cache_dir must be writable by uid nobody
if (defined($LG_CACHE_DIR)) {
$cache_dir = $LG_CACHE_DIR;
@@ -406,7 +430,7 @@ $max_lock_hold = 300;
if (defined($LG_CLOGINRC)) {
$cloginrc = $LG_CLOGINRC;
} else {
- $cloginrc = "$BASEDIR/.cloginrc";
+ $cloginrc = "$ENV(HOME)/.cloginrc";
}
$query = new CGI;
@@ -422,9 +446,16 @@ $arg =~ s/["'`]//g; # these are BS in any arg for any query
# 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";
- &Error("You must at least choose a Query and a router. Try buying a clue.\n");
+if (!defined($type) || !defined($router) || $router eq "") {
+ &Error("You must at least choose a Query and a router. Try buying " .
+ "a clue.\n");
+}
+
+if ($arg !~ /^[-A-Za-z0-9|_\/ \.^\$]*$/) {
+ &Error("Funny characters in argument; ignoring.\n");
+}
+if (length($arg) >= 50) {
+ &Error("Argument string too long; ignoring. \n");
}
if (! arraymember(\@rtrlist, $router)) {
@@ -436,130 +467,182 @@ if (! arraymember(\@rtrlist, $router)) {
}
# conversion of command "type" passed from lgform.cgi to the vendor's syntax.
-%ciscoCmd = (
- #acl => "show access-list",
- #aspath => "show ip as-path-access-list",
- #communitylist => "show ip community-list",
- damp => "show ip bgp dampened-paths",
+if ($mfg =~ /cisco/i) {
+ %mfgCmd = (
+ # Debug Queries
+ log => "show logging",
+ # Interface Queries
framerelay => "show frame-relay pvc",
interface => "show interface",
intbrief => "show ip interface", # switch in {interface}
- log => "show logging",
+ # Routing Queries
+ damp => "show ip bgp dampened-paths",
+ neighbor => "show ip bgp neighbor",
+ # Multicast Queries
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",
+ msdp => "show ip msdp summary",
+ msdpsa => "show ip msdp sa-cache",
+ msess => "show ip sdr",
+ mroute => "show ip mroute",
+ pim_interface => "show ip pim interface",
+ pim_neighbor => "show ip pim neighbor",
+ pim_rp => "show ip pim rp mapping",
+ # IPv6 Queries
+ #
+ #acl => "show access-list",
+ #aspath => "show ip as-path-access-list",
+ #communitylist => "show ip community-list",
ping => "ping",
prefix => "show ip bgp",
prefixlist => "show ip prefix-list",
+ regex => "show ip bgp regex",
+ route => "show ip route",
+ routemap => "show route-map",
+ rpf => "show ip rpf",
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",
+ trace => "traceroute",
+ v6_bgp => "show bgp ipv6",
+ v6_interface => "show ipv6 interface",
+ v6_summary => "show bgp ipv6 summary"
+ );
+} elsif ($mfg =~ /foundry/i) {
+ %mfgCmd = (
+ # Debug Queries
log => "show log",
- #mbgp => "show ip mbgp",
- #mbgpsum => "show bgp summary",
- #mneighbor => "show ip bgp neighbor",
+ ping => "ping",
+ trace => "traceroute",
+ # Interface Queries
+ #framerelay => "show frame-relay pvc", # no compatible command
+ interface => "show interface",
+ # Routing Queries
+ damp => "show ip bgp dampened-paths",
neighbor => "show ip bgp neighbor",
#regex => "show ip bgp aspath-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"
- );
-%juniperCmd = (
+ # Multicast Queries
+ #mbgp => "show ip mbgp",
+ #mbgpsum => "show bgp summary",
+ #mneighbor => "show ip bgp neighbor",
+ mroute => "show ip mroute",
+ msdp => "show ip msdp summary",
+ msdpsa => "show ip msdp sa-cache",
+ msess => "show ip sdr",
+ pim_interface => "show ip pim interface",
+ pim_neighbor => "show ip pim neighbor",
+ pim_rp => "show ip pim rp mapping",
+ rpf => "show ip rpf",
+ # IPv6 Queries
+ # v6_bgp => "show bgp ipv6",
+ # v6_interface => "show ipv6 interface",
+ # v6_summary => "show bgp ipv6 summary"
+ #
#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",
+ routemap => "show route-map",
+ prefix => "show ip bgp",
+ prefixlist => "show ip prefix-list"
+ );
+} elsif ($mfg =~ /juniper/i) {
+ %mfgCmd = (
+ # Debug Queries
+ log => "show log messages",
+ ping => "ping rapid count 5",
+ trace => "traceroute",
+ # Interface Queries
framerelay => "show frame-relay pvc",
interface => "show interface",
- log => "show log messages",
- mbgp => "show route table inet.2 terse",
- mbgpsum => "show bgp summary",
- mneighbor => "show bgp neighbor",
+ #intbrief => "show ip interface", # switch in {interface}
+ # Routing Queries
+ damp => "show route damping suppressed terse table inet.0",
neighbor => "show bgp neighbor",
regex => "show route table inet.0 aspath-regex",
- route => "show route table inet.0 terse",
- routemap => "show policy",
- ping => "ping rapid count 5",
- prefix => "show route table inet.0",
- prefixlist => "show policy",
summary => "show bgp summary",
- trace => "traceroute"
- );
-%cmdDisp = (
+ # Multicast Queries
+ mbgp => "show route table inet.2 terse",
+ mbgpsum => "show bgp summary",
+ mneighbor => "show bgp neighbor",
+ mroute => "show multicast route extensive",
+ msdp => "show msdp",
+ msdpsa => "show msdp source-active",
+ msess => "show multicast sessions",
+ pim_interface => "show pim interface",
+ pim_neighbor => "show pim neighbors",
+ pim_rp => "show pim rps",
+ pim_join => "show pim join",
+ rpf => "show multicast rpf",
+ # IPv6 Queries
+ v6_bgp => "show route table inet6.0",
+ v6_interface => "show interface",
+ v6_summary => "show bgp summary",
+ #
#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",
- 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",
- ping => "ping",
- prefix => "show ip bgp",
- prefixlist => "show ip prefix-list",
- summary => "show ip bgp summary",
- trace => "traceroute"
+ prefix => "show route table inet.0",
+ prefixlist => "show policy",
+ route => "show route table inet.0 terse",
+ routemap => "show policy"
);
+}
-# not all cmds/queries are implemented for junipers
-if ($mfg =~ /juniper/) {
- if (! defined($juniperCmd{$type})) {
- Error("$cmdDisp{$type} not implemented for junipers. sorry.\n");
- }
- $cmd = $juniperCmd{$type};
-} elsif ($mfg =~ /foundry/) {
- if(! defined($foundryCmd{$type})) {
- 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");
+# construct Display command from configuration
+%cmdDisp=();
+foreach $qtype (sort keys(%$queries)) {
+ next if (! scalar(%{$queries->{$qtype}}));
+ foreach $sub_type (sort keys(%{$queries->{$qtype}})) {
+ $cmdDisp{$sub_type} = $queries->{$qtype}->{$sub_type};
}
- $cmd = $ciscoCmd{$type};
}
+# make sure the command is not disabled
+if (! defined($cmdDisp{$type})) {
+ &Error("Unknown command type: $type\n");
+}
+
+# not all cmds/queries are implemented for all platforms
+if (! defined($mfgCmd{$type})) {
+ Error("$cmdDisp{$type} not implemented for $mfg or no suitable " .
+ "equivalent exists. sorry.\n");
+}
+$cmd = $mfgCmd{$type};
+
+# handle each query/command type
if ($type eq "prefix" || $type eq "mbgp" || $type eq "route" ) {
if ($arg[0] !~ /^\d+\.\d+\.\d+\.\d+$/) {
- &Error("The IP address \"$arg[0]\" is not valid and lacking an address would over-burden our router.\n");
+ &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+$/) {
&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 "v6_route" ){
+ # XXX: is this check of the address arg correct and pedantic?
+ if ($arg[0] !~ /[0-9a-fA-F:]+$/) {
+ &Error("The IPv6 address \"$arg[0]\" is not valid.\n");
+ }
} elsif ($type eq "framerelay") {
if ($mfg =~ /juniper/) {
&Error("Juniper does not have a show frame-relay pvc command. " .
- "Use show interface.\n");
+ "Use show interface.\n");
}
if ($arg[0] > 15 && $arg[0] < 1024) {
$arg = $arg[0];
} else {
undef($arg);
}
-} elsif ($type eq "interface") {
+} elsif ($type eq "interface" || $type eq "v6_interface") {
+
+ # XXX: wtf is arg[1]?
+# if ($arg[1] =~ /[-\/0-9:.]+/) {
+# $arg = $arg[0] . " " . $arg[1];
+# } else {
+
if ($mfg =~ /(cisco|foundry)/) {
if ($arg[0] !~ /^b[^ ]+[0-9]/i && $arg[0] =~ /^b/i) {
$type = "intbrief";
@@ -629,6 +712,7 @@ if ($type eq "prefix" || $type eq "mbgp" || $type eq "route" ) {
}
$arg = $arg[0];
} elsif ($type eq "regex") {
+ # bgp as-path regex
$arg = $arg[0];
if ($#arg >= 1) {
for ($n = 1; $n <= $#arg; $n++) { $arg .= " " . $arg[$n]; }
@@ -646,7 +730,7 @@ if ($type eq "prefix" || $type eq "mbgp" || $type eq "route" ) {
}
if ($mfg =~ /juniper/) {
$arg =~ s/_/ /g;
- # pre-junos 4.4 do not allow anchors
+ # pre-junos 4.4 does not allow anchors
if ($arg =~ /\^\$/) {
$arg =~ "()";
} else {
@@ -732,7 +816,7 @@ start_page();
# cache the following
if ($type eq "summary" || $type eq "mbgpsu" || $type eq "damp"
- || $type eq "log") {
+ || $type eq "log") {
if (!$arg) {
# cache requests with no addr/argument
local(*CACHE);
diff --git a/util/lg/lgform.cgi.in b/bin/lgform.cgi.in
index 97a0c71..461ae68 100755..100644
--- a/util/lg/lgform.cgi.in
+++ b/bin/lgform.cgi.in
@@ -1,16 +1,27 @@
-#!@PERLV_PATH@
-## Copyright (C) 1997-2001 by Henry Kilmer.
+#! @PERLV_PATH@
+##
+## $Id: lgform.cgi.in,v 1.25 2004/01/11 03:49:13 heas Exp $
+##
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
+##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
+##
+#
+# The original original lookingglass s/w was written by Ed Kern. It was
+# a single script that used to be available at http://nitrous.digex.net/.
+# Provided by permission and modified beyond recognition.
#
# lgform.cgi - Looking glass front-end
# produces html form for calling lg.cgi
@@ -19,6 +30,7 @@ use CGI qw/:standard/;
my(@rtrlist, %rtrlabels);
my($BASEDIR) = "@prefix@";
+my($SYSCONFDIR) = "@sysconfdir@";
# 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.
@@ -50,22 +62,23 @@ sub dolog
printf(STDERR $msg);
} else {
printf(LOG $msg);
- close(LOG);
+ close(LOG);
}
}
return;
}
+
# read LG configuration file
sub readconf
{
my($conffile, $cmds);
local(*CONF);
- if (defined($env{LG_CONF})) {
- $conffile = $env{LG_CONF};
+ if (defined($ENV{LG_CONF})) {
+ $conffile = $ENV{LG_CONF};
} elsif (-e "lg.conf") {
$conffile = "lg.conf";
} else {
- $conffile = "$BASEDIR/util/lg/lg.conf";
+ $conffile = "$SYSCONFDIR/lg.conf";
}
if (! -f $conffile) {
@@ -80,12 +93,14 @@ sub readconf
close(CONF);
eval $cmds;
} else {
- printf(STDERR "ERROR: couldn\'t open the configuration file: $conffile: $!\n");
+ printf(STDERR "ERROR: couldn\'t open the configuration file: " .
+ "$conffile: $!\n");
exit(1);
}
return;
}
+
# read router.db file
sub readrouters
{
@@ -95,7 +110,7 @@ sub readrouters
if (defined($LG_ROUTERDB)) {
$rtrdb = $LG_ROUTERDB;
} else {
- $rtrdb = "$BASEDIR/util/lg/router.db";
+ $rtrdb = "$SYSCONFDIR/router.db";
}
if (! -f $rtrdb) {
@@ -107,7 +122,7 @@ sub readrouters
dolog(LOG_ERR, "ERROR: couldn\'t read $BASEDIR: $!\n");
} else {
while ($dir = readdir(DIR)) {
- next if ($dir =~ /^(\.|\.\.|CVS|bin|logs|util)$/);
+ next if ($dir =~ /^(\.|\.\.|CVS|bin|etc|logs|util)$/);
push(@dirs, $dir) if (-d "$BASEDIR/$dir");
}
closedir(DIR);
@@ -130,7 +145,8 @@ sub readrouters
}
close(RTR);
} else {
- dolog(LOG_ERR, "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");
}
}
}
@@ -146,7 +162,8 @@ sub readrouters
}
close(RTR);
} else {
- dolog(LOG_ERR, "ERROR: couldn\'t open the router.db file: $rtrdb: $!\n");
+ dolog(LOG_ERR, "ERROR: couldn\'t open the router.db file: " .
+ "$rtrdb: $!\n");
exit(1);
}
}
@@ -161,9 +178,12 @@ readconf();
$query = new CGI;
print $query->header;
-print $query->start_html("LookingGlass form");
-
-print "<BODY>";
+if ($LG_STYLE) {
+ print $query->start_html(-title =>"LookingGlass form",
+ -style => {'src' => $LG_STYLE});
+} else {
+ print $query->start_html(-title =>"LookingGlass form");
+}
# add the company image, LG_IMAGE
print $LG_IMAGE;
@@ -176,46 +196,37 @@ print <<HEAD ;
HEAD
# start table, etc here
+print $query->startform( -action => 'lg.cgi', -method => 'POST');
print <<DOTABLE ;
-<form action=lg.cgi method=GET>
<center>
<table border cellspacing=0 width=575 align=center>
DOTABLE
# available query types here
-print <<QTYPES ;
+print <<TABLEHEAD ;
<tr valign=top>
- <TD><B>Query:</B>
-<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="ping">ping &lt;IP_addr | FQDN&gt;</dd>
-<dd><input type=radio name="query" value="trace">traceroute &lt;IP_addr | FQDN&gt;</DD>
+ <th align=left><B>Query:</B></th>
+ <th align=left><B>Router:</B></th>
+</tr>
+<tr><td>
+TABLEHEAD
+
+foreach $sub_type (sort keys(%$queries)) {
+ next if (! scalar(%{$queries->{$sub_type}}));
+ print $query->radio_group (-name => 'query',
+ -values => $queries->{$sub_type},
+ -default => '-', -linebreak => 'true');
+ print "\n" . $query->hr . "\n";
+}
+
+print <<QTYPES ;
<P><B>Argument(s):</B> <INPUT name="args" size=30></P>
</TD>
- <td ALIGH=left VALIGN=top>
- <b>Router:</B>
-
-<dd>
+ <td aligh=left valign=top>
QTYPES
-# <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>
-# <dd><input type=radio name="query" value="routemap">sh ip route-map &lt;map_name&gt;</DD>
-
# read routers table and create the scrolling list
readrouters();
print $query->scrolling_list(-name => 'router',
@@ -224,20 +235,23 @@ print $query->scrolling_list(-name => 'router',
-labels => \%rtrlabels);
# end
-print <<TAIL ;
+print <<TABLEEND ;
</dd>
</td>
</TABLE>
-<p><input type=submit value=Submit> <INPUT type=reset value=Reset></FORM>
+<p>
+TABLEEND
+
+print $query->submit(-name => 'submit', -value =>'Submit');
+print $query->reset;
+print $query->endform;
+
+print <<TAIL ;
</center>
<br>
<a href=lgnotes.html>Looking Glass notes</a>
-TAIL
-
-print <<TAIL ;
<p>
$LG_INFO
-</body>
TAIL
print $query->end_html;
diff --git a/bin/mrancid.in b/bin/mrancid.in
index 8054917..8d52c27 100755..100644
--- a/bin/mrancid.in
+++ b/bin/mrancid.in
@@ -1,29 +1,33 @@
-#!@PERLV_PATH@
+#! @PERLV_PATH@
##
-## Amazingly hacked version of Hank's rancid - this one tries to
-## deal with MRTd.
+## $Id: mrancid.in,v 1.11 2004/01/11 03:49:13 heas Exp $
##
-## Copyright (C) 1997-2001 by Henry Kilmer.
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
+# Amazingly hacked version of Hank's rancid - this one tries to
+# deal with MRTd.
+#
# RANCID - Really Awesome New Cisco confIg Differ
#
# usage: rancid [-d] [-l] [-f filename | $host]
#
use Getopt::Std;
-getopts('dflm');
+getopts('dfl');
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
@@ -355,8 +359,12 @@ TOP: while(<INPUT>) {
}
while (/#\s*($cmds_regexp)\s*$/) {
$cmd = $1;
- if (!defined($prompt)) {$prompt = ($_ =~ /^([^#]+)/)[0];
- $prompt .= "[#>]"; }
+ if (!defined($prompt)) {
+ $prompt = ($_ =~ /^([^#]+)/)[0];
+ $prompt =~ s/([][}{)(\\])/\\$1/g;
+ $prompt .= "[#>]";
+ print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
+ }
print STDERR ("HIT COMMAND:$_") if ($debug);
if (! defined($commands{$cmd})) {
print STDERR "$host: found unexpected command - \"$cmd\"\n";
diff --git a/bin/nlogin.in b/bin/nlogin.in
new file mode 100644
index 0000000..685c759
--- /dev/null
+++ b/bin/nlogin.in
@@ -0,0 +1,524 @@
+#! @EXPECT_PATH@ --
+##
+## $Id: nlogin.in,v 1.14 2004/01/11 05:39:15 heas Exp $
+##
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## All rights reserved.
+##
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
+##
+## 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.
+##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
+##
+#
+# The login expect scripts were based on Erik Sherk's gwtn, by permission.
+#
+# nlogin - netscreen login
+#
+# Most options are intuitive for logging into a netscreen firewall.
+#
+
+# Usage line
+set usage "Usage: $argv0 \[-c command\] \[-Evar=x\] \[-f cloginrc-file\]
+\[-s script-file\] \[-t timeout\] \[-u user\] \
+\[-p user-password\] \[-y ssh_cypher_type\] firewall \[firewall...\]\n"
+
+# env(CLOGIN) may contain:
+# x == do not set xterm banner or name
+
+# Password file
+set password_file $env(HOME)/.cloginrc
+# Default is to login to the firewall
+set do_command 0
+set do_script 0
+# The default is to automatically enable
+set enable 0
+# The default is that you login non-enabled (tacacs can have you login already
+# enabled)
+set avautoenable 1
+# The default is to look in the password file to find the passwords. This
+# tracks if we receive them on the command line.
+set do_passwd 1
+set do_enapasswd 1
+
+# Find the user in the ENV, or use the unix userid.
+if {[ info exists env(CISCO_USER) ] } {
+ set default_user $env(CISCO_USER)
+} elseif {[ info exists env(USER) ]} {
+ set default_user $env(USER)
+} elseif {[ info exists env(LOGNAME) ]} {
+ set default_user $env(LOGNAME)
+} else {
+ # This uses "id" which I think is portable. At least it has existed
+ # (without options) on all machines/OSes I've been on recently -
+ # unlike whoami or id -nu.
+ if [ catch {exec id} reason ] {
+ send_error "\nError: could not exec id: $reason\n"
+ exit 1
+ }
+ regexp {\(([^)]*)} "$reason" junk default_user
+}
+
+# Sometimes firewall take awhile to answer (the default is 10 sec)
+set timeout 45
+
+# Process the command line
+for {set i 0} {$i < $argc} {incr i} {
+ set arg [lindex $argv $i]
+
+ switch -glob -- $arg {
+ # Username
+ -u* -
+ -U* {
+ if {! [ regexp .\[uU\](.+) $arg ignore user]} {
+ incr i
+ set username [ lindex $argv $i ]
+ }
+ # VTY Password
+ } -p* -
+ -P* {
+ if {! [ regexp .\[pP\](.+) $arg ignore userpasswd]} {
+ incr i
+ set userpasswd [ lindex $argv $i ]
+ }
+ set do_passwd 0
+ # Environment variable to pass to -s scripts
+ } -E*
+ {
+ if {[ regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} {
+ set E$varname $varvalue
+ } else {
+ send_user "\nError: invalid format for -E in $arg\n"
+ exit 1
+ }
+ # Command to run.
+ } -c* -
+ -C* {
+ if {! [ regexp .\[cC\](.+) $arg ignore command]} {
+ incr i
+ set command [ lindex $argv $i ]
+ }
+ set do_command 1
+ # Expect script to run.
+ } -s* -
+ -S* {
+ if {! [ regexp .\[sS\](.+) $arg ignore sfile]} {
+ incr i
+ set sfile [ lindex $argv $i ]
+ }
+ if { ! [ file readable $sfile ] } {
+ send_user "\nError: Can't read $sfile\n"
+ exit 1
+ }
+ set do_script 1
+ # cypher type
+ } -y* -
+ -Y* {
+ if {! [ regexp .\[eE\](.+) $arg ignore cypher]} {
+ incr i
+ set cypher [ lindex $argv $i ]
+ }
+ # alternate cloginrc file
+ } -f* -
+ -F* {
+ if {! [ regexp .\[fF\](.+) $arg ignore password_file]} {
+ incr i
+ set password_file [ lindex $argv $i ]
+ }
+ } -t* -
+ -T* {
+ incr i
+ set timeout [ lindex $argv $i ]
+ } -x* -
+ -X {
+ if {! [ regexp .\[xX\](.+) $arg ignore cmd_file]} {
+ incr i
+ set cmd_file [ lindex $argv $i ]
+ }
+ if [ catch {set cmd_fd [open $cmd_file r]} reason ] {
+ send_user "\nError: $reason\n"
+ exit 1
+ }
+ set cmd_text [read $cmd_fd]
+ close $cmd_fd
+ set command [join [split $cmd_text \n] \;]
+ set do_command 1
+ # Does tacacs automatically enable us?
+ } -autoenable {
+ # ignore autoenable
+ #set avautoenable 1
+ } -* {
+ send_user "\nError: Unknown argument! $arg\n"
+ send_user $usage
+ exit 1
+ } default {
+ break
+ }
+ }
+}
+# Process firewalls...no firewalls listed is an error.
+if { $i == $argc } {
+ send_user "\nError: $usage"
+}
+
+# Only be quiet if we are running a script (it can log its output
+# on its own)
+if { $do_script } {
+ log_user 0
+} else {
+ log_user 1
+}
+
+#
+# Done configuration/variable setting. Now run with it...
+#
+
+# Sets Xterm title if interactive...if its an xterm and the user cares
+proc label { host } {
+ global env
+ # if CLOGIN has an 'x' in it, don't set the xterm name/banner
+ if [info exists env(CLOGIN)] {
+ if {[string first "x" $env(CLOGIN)] != -1} { return }
+ }
+ # take host from ENV(TERM)
+ if [info exists env(TERM)] {
+ if [regexp \^(xterm|vs) $env(TERM) ignore ] {
+ send_user "\033]1;[lindex [split $host "."] 0]\a"
+ send_user "\033]2;$host\a"
+ }
+ }
+}
+
+# This is a helper function to make the password file easier to
+# maintain. Using this the password file has the form:
+# add password sl* pete cow
+# add password at* steve
+# add password * hanky-pie
+proc add {var args} { global int_$var ; lappend int_$var $args}
+proc include {args} {
+ global env
+ regsub -all "(^{|}$)" $args {} args
+ if { [ regexp "^/" $args ignore ] == 0 } {
+ set args $env(HOME)/$args
+ }
+ source_password_file $args
+}
+
+proc find {var firewall} {
+ upvar int_$var list
+ if { [info exists list] } {
+ foreach line $list {
+ if { [string match [lindex $line 0] $firewall ] } {
+ return [lrange $line 1 end]
+ }
+ }
+ }
+ return {}
+}
+
+# Loads the password file. Note that as this file is tcl, and that
+# it is sourced, the user better know what to put in there, as it
+# could install more than just password info... I will assume however,
+# that a "bad guy" could just as easy put such code in the clogin
+# script, so I will leave .cloginrc as just an extention of that script
+proc source_password_file { password_file } {
+ global env
+ if { ! [file exists $password_file] } {
+ send_user "\nError: password file ($password_file) does not exist\n"
+ exit 1
+ }
+ file stat $password_file fileinfo
+ if { [expr ($fileinfo(mode) & 007)] != 0000 } {
+ send_user "\nError: $password_file must not be world readable/writable\n"
+ exit 1
+ }
+ if [ catch {source $password_file} reason ] {
+ send_user "\nError: $reason\n"
+ exit 1
+ }
+}
+
+# Log into the firewall.
+proc login { firewall user userpswd passwd enapasswd prompt cmethod
+cyphertype } {
+ global spawn_id in_proc do_command do_script sshcmd
+ set in_proc 1
+ set uprompt_seen 0
+
+ # Telnet to the firewall & try to login.
+ set progs [llength $cmethod]
+ foreach prog [lrange $cmethod 0 end] {
+ if [string match "telnet*" $prog] {
+ regexp {telnet(:([^[:space:]]+))*} $prog command suffix port
+ if {"$port" == ""} {
+ set retval [ catch {spawn telnet $firewall} reason ]
+ } else {
+ set retval [ catch {spawn telnet $firewall $port} reason ]
+ }
+ if { $retval } {
+ send_user "\nError: telnet failed: $reason\n"
+ exit 1
+ }
+ } elseif ![string compare $prog "ssh"] {
+ if [ catch {spawn $sshcmd -c $cyphertype -x -l $user $firewall} reason ] {
+ send_user "\nError: $sshcmd failed: $reason\n"
+ exit 1
+ }
+ } elseif ![string compare $prog "rsh"] {
+ if [ catch {spawn rsh -l $user $firewall} reason ] {
+ send_user "\nError: rsh failed: $reason\n"
+ exit 1
+ }
+ } else {
+ puts "\nError: unknown connection method: $prog"
+ return 1
+ }
+ incr progs -1
+
+ sleep 0.3
+
+ # This helps cleanup each expect clause.
+ expect_after {
+ timeout {
+ send_user "\nError: TIMEOUT reached\n"
+ catch {close}; wait
+ if { $in_proc} {
+ return 1
+ } else {
+ continue
+ }
+ } eof {
+ send_user "\nError: EOF received\n"
+ catch {close}; wait
+ if { $in_proc} {
+ return 1
+ } else {
+ continue
+ }
+ }
+ }
+
+ # Here we get a little tricky. There are several possibilities:
+ # the firewall can ask for a username and passwd and then
+ # talk to the TACACS server to authenticate you, or if the
+ # TACACS server is not working, then it will use the enable
+ # passwd. Or, the firewall might not have TACACS turned on,
+ # then it will just send the passwd.
+ # if telnet fails with connection refused, try ssh
+ expect {
+ "Connection refused" {
+ send_user "\nError: Connection Refused\n"; wait; return 1
+ } eof { send_user "\nError: Couldn't login\n"; wait; return 1
+ } "Unknown host\r\n" {
+ expect eof
+ send_user "\nError: Unknown host\n"; wait; return 1
+ } "Host is unreachable" {
+ expect eof
+ send_user "\nError: Host Unreachable!\n"; wait; return 1
+ } "No address associated with name" {
+ expect eof
+ send_user "\nError: Unknown host\n"; wait; return 1
+ }
+ -re "Are you sure you want to continue connecting .*" {
+ send "yes\r"
+ send_user "Host $firewall added to the list of known hosts.\n"
+ exp_continue }
+ -re "Host key not found .* \(yes\/no\)\?" {
+ send "yes\r"
+ send_user "Host $firewall 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 $firewall 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 $firewall. Update the SSH known_hosts file accordingly.\n"
+ return 1 }
+ denied { send_user "\nError: Check your passwd for $firewall\n"
+ catch {close}; wait; return 1
+ }
+ " ### Login failed" {send_user "\nError: Check your passwd for $firewall\n"; return 1 }
+ -re "(login:)" {
+ sleep 1;
+ send "$user\r"
+ set uprompt_seen 1
+ exp_continue
+ }
+ "@\[^\r\n]+\[Pp]assword:" {
+ # 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; }
+ }
+ }
+ set in_proc 0
+ return 0
+}
+
+# Run commands given on the command line.
+proc run_commands { prompt command } {
+ global in_proc
+ set in_proc 1
+
+ send "set console page 0\r"
+ expect $prompt {}
+
+ # Is this a multi-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 [lindex $commands $i]]\r"
+ expect {
+ -re "$prompt" {}
+ }
+ }
+ } else {
+ send "[subst $command]\r"
+ expect {
+ -re "$prompt" {}
+ }
+ }
+ send "exit\r"
+ expect {
+ "\n" { exp_continue }
+ -re "$prompt" {
+ send "exit\r"
+ exp_continue }
+ -re "Configuration modified, save?" {
+ send "n\r"
+ exp_continue }
+ timeout { return 0 }
+ eof { return 0 }
+ }
+ set in_proc 0
+}
+
+#
+# For each firewall... (this is main loop)
+#
+source_password_file $password_file
+set in_proc 0
+foreach firewall [lrange $argv $i end] {
+ set firewall [string tolower $firewall]
+ send_user "$firewall\n"
+
+ set prompt ">"
+
+ # Figure out passwords
+ if { $do_passwd || $do_enapasswd } {
+ set pswd [find password $firewall]
+ if { [llength $pswd] == 0 } {
+ send_user "\nError: no password for $firewall in $password_file.\n"
+ continue
+ }
+ set passwd [join [lindex $pswd 0]""]
+ set enapasswd [join [lindex $pswd 1] ""]
+ }
+
+ # Figure out username
+ if {[info exists username]} {
+ # command line username
+ set ruser $username
+ } else {
+ set ruser [join [find user $firewall] ""]
+ if { "$ruser" == "" } { set ruser $default_user }
+ }
+
+ # Figure out username's password (if different from the vty password)
+ if {[info exists userpasswd]} {
+ # command line username
+ set userpswd $userpasswd
+ } else {
+ set userpswd [join [find userpassword $firewall] ""]
+ if { "$userpswd" == "" } { set userpswd $passwd }
+ }
+
+ # Figure out enable username
+ if {[info exists enausername]} {
+ # command line enausername
+ set enauser $enausername
+ } else {
+ set enauser [join [find enauser $firewall] ""]
+ if { "$enauser" == "" } { set enauser $ruser }
+ }
+
+ # Figure out cypher type
+ if {[info exists cypher]} {
+ # command line cypher type
+ set cyphertype $cypher
+ } else {
+ set cyphertype [find cyphertype $firewall]
+ if { "$cyphertype" == "" } { set cyphertype "3des" }
+ }
+
+ # Figure out connection method
+ set cmethod [find method $firewall]
+ if { "$cmethod" == "" } { set cmethod {{telnet} {ssh}} }
+
+ # Figure out the SSH executable name
+ set sshcmd [find sshcmd $router]
+ if { "$sshcmd" == "" } { set sshcmd {ssh} }
+
+ # Login to the firewall
+ if {[login $firewall $ruser $userpswd $passwd $enapasswd $prompt $cmethod $cyphertype]} {
+ continue
+ }
+ if { $enable } {
+ if {[do_enable $enauser $enapasswd]} {
+ if { $do_command || $do_script } {
+ close; wait
+ continue
+ }
+ }
+ }
+ # we are logged in, now figure out the full prompt
+ send "\r"
+ expect {
+ -re "\[\r\n]+" { exp_continue; }
+ -re "^.+$prompt" { set junk $expect_out(0,string);
+ regsub -all "\[\]\(\)\[]" $junk {\\&} prompt;
+ }
+ }
+
+ if { $do_command } {
+ if {[run_commands $prompt $command]} {
+ continue
+ }
+ } elseif { $do_script } {
+ send "set console page 0\r"
+ expect $prompt {}
+ source $sfile
+ close
+ } else {
+ label $firewall
+ log_user 1
+ interact
+ }
+
+ # End of for each firewall
+ wait
+ sleep 0.3
+}
+exit 0
diff --git a/bin/nrancid.in b/bin/nrancid.in
new file mode 100644
index 0000000..9b965a2
--- /dev/null
+++ b/bin/nrancid.in
@@ -0,0 +1,302 @@
+#! @PERLV_PATH@
+##
+## $Id: nrancid.in,v 1.13 2004/01/11 03:49:13 heas Exp $
+##
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## All rights reserved.
+##
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
+##
+## 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.
+##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
+##
+#
+# Amazingly hacked version of Hank's rancid - this one tries to
+# deal with Netscreen firewalls
+#
+# Original Netscreen hacks implemented by Stephen Gill [gillsr@yahoo.com]
+#
+# RANCID - Really Awesome New Cisco confIg Differ
+#
+# usage: rancid [-d] [-l] [-f filename | $host]
+#
+use Getopt::Std;
+getopts('dfl');
+$log = $opt_l;
+$debug = $opt_d;
+$file = $opt_f;
+$host = $ARGV[0];
+$found_end = 0;
+$timeo = 90; # nlogin timeout in seconds
+
+my(%filter_pwds); # password filtering mode
+
+# This routine is used to print out the firewall 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 "get system"
+sub GetSystem {
+ print STDERR " In GetSystem: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ next if /^\s*$/;
+ last if(/$prompt/);
+
+ /^Serial Number: (\d+), Control Number: \d+$/ &&
+ ProcessHistory("SYSTEM","","", "!SN: $1\n") && next;
+ /^Product Name: (\S+)$/ &&
+ ProcessHistory("SYSTEM","","", "!Product: $1\n") && next;
+ /^Hardware Version: (\S+), / &&
+ ProcessHistory("SYSTEM","","", "!HW: $1\n") && next;
+ /^Software Version: (\S+), Type: (\S+)$/ &&
+ ProcessHistory("SYSTEM","","", "!Netscreen Type: $2\n!Software Version: $1\n") && next;
+ /^Image: (\S+), / &&
+ ProcessHistory("SYSTEM","","", "!Image: $1\n") && next;
+ /^Feature: (\S+)$/ &&
+ ProcessHistory("SYSTEM","","", "!Feature: $1\n") && next;
+ /^File Name: (\S+), Checksum: (\S+)$/ &&
+ ProcessHistory("SYSTEM","","", "!File Name: $1, Checksum: $2\n") && next;
+
+ }
+ ProcessHistory("SYSTEM","","","!\n");
+ return(0);
+}
+
+sub GetFile {
+ print STDERR " In GetFile: $_" if ($debug);
+ while (<INPUT>) {
+ last if(/$prompt/);
+ }
+ ProcessHistory("FILE","","","!\n");
+ return(0);
+}
+
+sub GetConf {
+ print STDERR " In GetConf: $_" if ($debug);
+ while (<INPUT>) {
+ tr/\015//d;
+ next if /^\s*$/;
+ last if(/$prompt/);
+
+ if (/^set admin name "(\S+)"$/ && $filter_pwds >= 1) {
+ ProcessHistory("ADMIN","","","!set admin name <removed>\n");
+ next;
+ }
+ if (/^set admin password (\S+)$/ && $filter_pwds >= 1) {
+ ProcessHistory("ADMIN","","","!set admin password <removed>\n");
+ next;
+ }
+ if (/^set admin user (\S+) password (\S+) privilege (\S+)$/ &&
+ $filter_pwds >= 1) {
+ ProcessHistory("ADMIN","","",
+ "!set admin user $1 password <removed> privilege $3\n");
+ next;
+ ProcessHistory("","","","$_");
+ }
+ $found_end=1;
+ return(1);
+}
+
+# dummy function
+sub DoNothing {print STDOUT;}
+
+# Main
+%commands=(
+ 'get system' => "GetSystem",
+ 'get conf' => "GetConf"
+);
+# keys() doesnt return things in the order entered and the order of the
+# cmds is important. pita
+@commands=(
+ "get system",
+ "get conf"
+);
+$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 nlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug);
+ print STDOUT "executing nlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log);
+ if (defined($ENV{NOPIPE})) {
+ system "nlogin -t $timeo -c \"$cisco_cmds\" $host </dev/null > $host.raw 2>&1" || die "nlogin failed for $host: $!\n";
+ open(INPUT, "< $host.raw") || die "nlogin failed for $host: $!\n";
+ } else {
+ open(INPUT,"nlogin -t $timeo -c \"$cisco_cmds\" $host </dev/null |") || die "nlogin failed for $host: $!\n";
+ }
+}
+
+# determine password filtering mode
+if ($ENV{"FILTER_PWDS"} =~ /no/i) {
+ $filter_pwds = 0;
+} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
+ $filter_pwds = 2;
+} else {
+ $filter_pwds = 1;
+}
+
+ProcessHistory("","","","!RANCID-CONTENT-TYPE: netscreen\n!\n");
+TOP: while(<INPUT>) {
+ tr/\015//d;
+ if (/^Error:/) {
+ print STDOUT ("$host nlogin error: $_");
+ print STDERR ("$host nlogin error: $_") if ($debug);
+ last;
+ }
+ while (/>\s*($cmds_regexp)\s*$/) {
+ $cmd = $1;
+ if (!defined($prompt)) {
+ $prompt = "\-\>\s*";
+ print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
+ }
+ print STDERR ("HIT COMMAND:$_") if ($debug);
+ if (!defined($commands{$cmd})) {
+ print STDERR "$host: found unexpected command - \"$cmd\"\n";
+ last TOP;
+ }
+ $rval = &{$commands{$cmd}};
+ delete($commands{$cmd});
+ if ($rval == -1) {
+ 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) || !$found_end) {
+ if (scalar(%commands)) {
+ printf(STDOUT "$host: missed cmd(s): %s\n", join(',', keys(%commands)));
+ printf(STDERR "$host: missed cmd(s): %s\n", join(',', keys(%commands))) if ($debug);
+ }
+ if (!$found_end) {
+ print STDOUT "$found_end: found end\n";
+ print STDOUT "$host: End of run not found\n";
+ print STDERR "$host: End of run not found\n" if ($debug);
+ system("/usr/bin/tail -1 $host.new");
+ }
+ unlink "$host.new" if (! $debug);
+}
diff --git a/bin/nslogin.in b/bin/nslogin.in
new file mode 100644
index 0000000..385f530
--- /dev/null
+++ b/bin/nslogin.in
@@ -0,0 +1,642 @@
+#! @EXPECT_PATH@ --
+##
+## $Id: nslogin.in,v 1.10 2004/01/11 05:39:15 heas Exp $
+##
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## All rights reserved.
+##
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
+##
+## 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.
+##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
+##
+#
+# The login expect scripts were based on Erik Sherk's gwtn, by permission.
+#
+# nslogin - Netscaler login
+#
+# Hacks from Anshuman Kanwar.
+#
+# Most options are intuitive for logging into a Cisco router.
+# The default is to enable (thus -noenable). Some folks have
+# setup tacacs to have a user login at priv-lvl = 15 (enabled)
+# so the -autoenable flag was added for this case (don't go through
+# the process of enabling and the prompt will be the "#" prompt.
+# The default username password is the same as the vty password.
+#
+
+# Usage line
+set usage "Usage: $argv0 \[-autoenable\] \[-noenable\] \[-c command\] \
+\[-Evar=x\] \[-e enable-password\] \[-f cloginrc-file\] \[-p user-password\] \
+\[-s script-file\] \[-t timeout\] \[-u username\] \
+\[-v vty-password\] \[-w enable-username\] \[-x command-file\] \
+\[-y ssh_cypher_type\] router \[router...\]\n"
+
+# env(CLOGIN) may contain:
+# x == do not set xterm banner or name
+
+# Password file
+set password_file $env(HOME)/.cloginrc
+# Default is to login to the router
+set do_command 1
+set do_script 0
+# The default is to automatically enable
+set enable 0
+# The default is that you login non-enabled (tacacs can have you login already
+# enabled)
+set avautoenable 0
+# The default is to look in the password file to find the passwords. This
+# tracks if we receive them on the command line.
+set do_passwd 1
+set do_enapasswd 1
+# attempt at platform switching.
+set platform ""
+
+# Find the user in the ENV, or use the unix userid.
+if {[ info exists env(CISCO_USER) ] } {
+ set default_user $env(CISCO_USER)
+} elseif {[ info exists env(USER) ]} {
+ set default_user $env(USER)
+} elseif {[ info exists env(LOGNAME) ]} {
+ set default_user $env(LOGNAME)
+} else {
+ # This uses "id" which I think is portable. At least it has existed
+ # (without options) on all machines/OSes I've been on recently -
+ # unlike whoami or id -nu.
+ if [ catch {exec id} reason ] {
+ send_error "\nError: could not exec id: $reason\n"
+ exit 1
+ }
+ regexp {\(([^)]*)} "$reason" junk default_user
+}
+
+# Sometimes routers take awhile to answer (the default is 10 sec)
+set timeout 45
+
+# Process the command line
+for {set i 0} {$i < $argc} {incr i} {
+ set arg [lindex $argv $i]
+
+ switch -glob -- $arg {
+ # Username
+ -u* -
+ -U* {
+ if {! [ regexp .\[uU\](.+) $arg ignore user]} {
+ incr i
+ set username [ lindex $argv $i ]
+ }
+ # VTY Password
+ } -p* -
+ -P* {
+ if {! [ regexp .\[pP\](.+) $arg ignore userpasswd]} {
+ incr i
+ set userpasswd [ lindex $argv $i ]
+ }
+ set do_passwd 0
+ # VTY Password
+ } -v* -
+ -v* {
+ if {! [ regexp .\[vV\](.+) $arg ignore passwd]} {
+ incr i
+ set passwd [ lindex $argv $i ]
+ }
+ set do_passwd 0
+ # Enable Username
+ } -w* -
+ -W* {
+ if {! [ regexp .\[wW\](.+) $arg ignore enauser]} {
+ incr i
+ set enausername [ lindex $argv $i ]
+ }
+ # Environment variable to pass to -s scripts
+ } -E*
+ {
+ if {[ regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} {
+ set E$varname $varvalue
+ } else {
+ send_user "\nError: invalid format for -E in $arg\n"
+ exit 1
+ }
+ # Enable Password
+ } -e*
+ {
+ if {! [ regexp .\[e\](.+) $arg ignore enapasswd]} {
+ incr i
+ set enapasswd [ lindex $argv $i ]
+ }
+ set do_enapasswd 0
+ # Command to run.
+ } -c* -
+ -C* {
+ if {! [ regexp .\[cC\](.+) $arg ignore command]} {
+ incr i
+ set command [ lindex $argv $i ]
+ }
+ set do_command 1
+ # Expect script to run.
+ } -s* -
+ -S* {
+ if {! [ regexp .\[sS\](.+) $arg ignore sfile]} {
+ incr i
+ set sfile [ lindex $argv $i ]
+ }
+ if { ! [ file readable $sfile ] } {
+ send_user "\nError: Can't read $sfile\n"
+ exit 1
+ }
+ set do_script 1
+ # 'ssh -c' cypher type
+ } -y* -
+ -Y* {
+ if {! [ regexp .\[eE\](.+) $arg ignore cypher]} {
+ incr i
+ set cypher [ lindex $argv $i ]
+ }
+ # alternate cloginrc file
+ } -f* -
+ -F* {
+ if {! [ regexp .\[fF\](.+) $arg ignore password_file]} {
+ incr i
+ set password_file [ lindex $argv $i ]
+ }
+ # Timeout
+ } -t* -
+ -T* {
+ if {! [ regexp .\[tT\](.+) $arg ignore timeout]} {
+ incr i
+ set timeout [ lindex $argv $i ]
+ }
+ # Command file
+ } -x* -
+ -X {
+ if {! [ regexp .\[xX\](.+) $arg ignore cmd_file]} {
+ incr i
+ set cmd_file [ lindex $argv $i ]
+ }
+ if [ catch {set cmd_fd [open $cmd_file r]} reason ] {
+ send_user "\nError: $reason\n"
+ exit 1
+ }
+ set cmd_text [read $cmd_fd]
+ close $cmd_fd
+ set command [join [split $cmd_text \n] \;]
+ set do_command 1
+ # Do we enable?
+ } -noenable {
+ set enable 0
+ # Does tacacs automatically enable us?
+ } -autoenable {
+ set avautoenable 1
+ set enable 0
+ } -* {
+ send_user "\nError: Unknown argument! $arg\n"
+ send_user $usage
+ exit 1
+ } default {
+ break
+ }
+ }
+}
+# Process routers...no routers listed is an error.
+if { $i == $argc } {
+ send_user "\nError: $usage"
+}
+
+# Only be quiet if we are running a script (it can log its output
+# on its own)
+if { $do_script } {
+ log_user 0
+} else {
+ log_user 1
+}
+
+#
+# Done configuration/variable setting. Now run with it...
+#
+
+# Sets Xterm title if interactive...if its an xterm and the user cares
+proc label { host } {
+ global env
+ # if CLOGIN has an 'x' in it, don't set the xterm name/banner
+ if [info exists env(CLOGIN)] {
+ if {[string first "x" $env(CLOGIN)] != -1} { return }
+ }
+ # take host from ENV(TERM)
+ if [info exists env(TERM)] {
+ if [regexp \^(xterm|vs) $env(TERM) ignore ] {
+ send_user "\033]1;[lindex [split $host "."] 0]\a"
+ send_user "\033]2;$host\a"
+ }
+ }
+}
+
+# This is a helper function to make the password file easier to
+# maintain. Using this the password file has the form:
+# add password sl* pete cow
+# add password at* steve
+# add password * hanky-pie
+proc add {var args} { global int_$var ; lappend int_$var $args}
+proc include {args} {
+ global env
+ regsub -all "(^{|}$)" $args {} args
+ if { [ regexp "^/" $args ignore ] == 0 } {
+ set args $env(HOME)/$args
+ }
+ source_password_file $args
+}
+
+proc find {var router} {
+ upvar int_$var list
+ if { [info exists list] } {
+ foreach line $list {
+ if { [string match [lindex $line 0] $router ] } {
+ return [lrange $line 1 end]
+ }
+ }
+ }
+ return {}
+}
+
+# Loads the password file. Note that as this file is tcl, and that
+# it is sourced, the user better know what to put in there, as it
+# could install more than just password info... I will assume however,
+# that a "bad guy" could just as easy put such code in the clogin
+# script, so I will leave .cloginrc as just an extention of that script
+proc source_password_file { password_file } {
+ global env
+ if { ! [file exists $password_file] } {
+ send_user "\nError: password file ($password_file) does not exist\n"
+ exit 1
+ }
+ file stat $password_file fileinfo
+ if { [expr ($fileinfo(mode) & 007)] != 0000 } {
+ send_user "\nError: $password_file must not be world readable/writable\n"
+ exit 1
+ }
+ if [ catch {source $password_file} reason ] {
+ send_user "\nError: $reason\n"
+ exit 1
+ }
+}
+
+# Log into the router.
+proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
+ global spawn_id in_proc do_command do_script platform
+ global prompt u_prompt p_prompt e_prompt sshcmd
+ set in_proc 1
+ set uprompt_seen 0
+
+ # try each of the connection methods in $cmethod until one is successful
+ set progs [llength $cmethod]
+ foreach prog [lrange $cmethod 0 end] {
+ if ![string compare $prog "ssh"] {
+ if [ catch {spawn $sshcmd -c $cyphertype -x -l $user $router} reason ] {
+ send_user "\nError: $sshcmd failed: $reason\n"
+ exit 1
+ }
+ } else {
+ puts "\nError: unknown connection method: $prog"
+ return 1
+ }
+ incr progs -1
+ sleep 0.3
+
+ # This helps cleanup each expect clause.
+ expect_after {
+ timeout {
+ send_user "\nError: TIMEOUT reached\n"
+ catch {close}; wait
+ if { $in_proc} {
+ return 1
+ } else {
+ continue
+ }
+ } eof {
+ send_user "\nError: EOF received\n"
+ catch {close}; wait
+ if { $in_proc} {
+ return 1
+ } else {
+ continue
+ }
+ }
+ }
+
+ # Here we get a little tricky. There are several possibilities:
+ # the router can ask for a username and passwd and then
+ # talk to the TACACS server to authenticate you, or if the
+ # TACACS server is not working, then it will use the enable
+ # passwd. Or, the router might not have TACACS turned on,
+ # then it will just send the passwd.
+ # if telnet fails with connection refused, try ssh
+ expect {
+ -re "(Connection refused|Secure connection \[^\n\r]+ refused|Connection closed by)" {
+ catch {close}; wait
+ if !$progs {
+ send_user "\nError: Connection Refused ($prog)\n"; return 1
+ }
+ }
+ eof { send_user "\nError: Couldn't login\n"; wait; return 1 }
+ -nocase "unknown host\r" {
+ catch {close};
+ send_user "\nError: Unknown host\n"; wait; return 1
+ }
+ "Host is unreachable" {
+ catch {close};
+ send_user "\nError: Host Unreachable!\n"; wait; return 1
+ }
+ "No address associated with name" {
+ catch {close};
+ send_user "\nError: Unknown host\n"; wait; return 1
+ }
+ -re "(Host key not found |The authenticity of host .* be established).*\(yes\/no\)\?" {
+ send "yes\r"
+ send_user "\nHost $router added to the list of known hosts.\n"
+ exp_continue }
+ -re "HOST IDENTIFICATION HAS CHANGED.* \(yes\/no\)\?" {
+ send "no\r"
+ send_user "\nError: The host key for $router has changed. Update the 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 }
+ -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
+ }
+
+ "$prompt" { break; }
+ "Login invalid" {
+ send_user "\nError: Invalid login\n";
+ catch {close}; wait; return 1
+ }
+ }
+ }
+
+ set in_proc 0
+ return 0
+}
+
+
+# Run commands given on the command line.
+
+proc run_commands { prompt command } {
+ global in_proc platform
+ set in_proc 1
+
+ regsub -all "\[)(]" $prompt {\\&} reprompt
+ # this is the only way i see to get rid of more prompts in o/p..grrrrr
+ log_user 0
+ # Is this a multi-command?
+ if [ string match "*\;*" "$command" ] {
+ set commands [split $command \;]
+ set num_commands [llength $commands]
+ # the pager can not be turned off on the PIX, so we have to look
+ # for the "More" prompt. the extreme is equally obnoxious, with a
+ # global switch in the config.
+ for {set i 0} {$i < $num_commands} { incr i} {
+ send "[subst -nocommands [lindex $commands $i]]\r"
+ expect {
+ -re "\b+" { exp_continue }
+ -re "^\[^\n\r *]*$reprompt" { send_user -- "$expect_out(buffer)"
+ }
+ -re "^\[^\n\r]*$reprompt." { send_user -- "$expect_out(buffer)"
+ exp_continue }
+ -re "\[\n\r]+" { send_user -- "$expect_out(buffer)"
+ exp_continue }
+ -re "\[^\r\n]*Press <SPACE> to cont\[^\r\n]*" {
+ send " "
+ # bloody ^[[2K after " "
+ expect {
+ -re "^\[^\r\n]*\r" {}
+ }
+ exp_continue
+ }
+ -re "^ --More--\[^\n\r]*" {
+ send " "
+ exp_continue }
+ -re "^<-+ More -+>\[^\n\r]*" {
+ send_user -- "$expect_out(buffer)"
+ send " "
+ exp_continue }
+ }
+ }
+ } else {
+ # the pager can not be turned off on the PIX, so we have to look
+ # for the "More" prompt. the extreme is equally obnoxious, with a
+ # global switch in the config.
+ send "[subst -nocommands $command]\r"
+ expect {
+ -re "\b+" { exp_continue }
+ -re "^\[^\n\r *]*$reprompt" { send_user -- "$expect_out(buffer)"
+ }
+ -re "^\[^\n\r]*$reprompt." { send_user -- "$expect_out(buffer)"
+ exp_continue }
+ -re "\[\n\r]+" { send_user -- "$expect_out(buffer)"
+ exp_continue }
+ -re "\[^\r\n]*Press <SPACE> to cont\[^\r\n]*" {
+ send " "
+ # bloody ^[[2K after " "
+ expect {
+ -re "^\[^\r\n]*\r" {}
+ }
+ exp_continue
+ }
+ -re "^ --More--\[^\n\r]*" {
+ send " "
+ exp_continue }
+ -re "^<-+ More -+>\[^\n\r]*" {
+ send_user -- "$expect_out(buffer)"
+ send " "
+ exp_continue }
+ }
+ }
+ log_user 1
+
+ if { [ string compare "extreme" "$platform" ] } {
+ send "exit\r"
+ } else {
+ send "quit\r"
+ }
+ expect {
+ "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
+}
+
+
+
+#
+# For each router... (this is main loop)
+#
+source_password_file $password_file
+set in_proc 0
+foreach router [lrange $argv $i end] {
+ set router [string tolower $router]
+ send_user "$router\n"
+
+ # Figure out prompt.
+ set prompt "#"
+
+ # look for noenable option in .cloginrc
+ if { [find noenable $router] != "" } {
+ set enable 0
+ }
+
+ # Figure out passwords
+ if { $do_passwd } {
+ set pswd [find password $router]
+ if { [llength $pswd] == 0 } {
+ send_user "\nError: no password for $router in $password_file.\n"
+ continue
+ }
+ if { $enable && $autoenable == 0 && [llength $pswd] < 2 } {
+ send_user "\nError: no enable password for $router in $password_file.\n"
+ continue
+ }
+ set passwd [join [lindex $pswd 0] ""]
+ set enapasswd [join [lindex $pswd 1] ""]
+ }
+
+ # Figure out username
+ if {[info exists username]} {
+ # command line username
+ set ruser $username
+ } else {
+ set ruser [join [find user $router] ""]
+ if { "$ruser" == "" } { set ruser $default_user }
+ }
+
+ # Figure out username's password (if different from the vty password)
+ if {[info exists userpasswd]} {
+ # command line username
+ set userpswd $userpasswd
+ } else {
+ set userpswd [join [find userpassword $router] ""]
+ if { "$userpswd" == "" } { set userpswd $passwd }
+ }
+
+ # Figure out enable username
+ if {[info exists enausername]} {
+ # command line enausername
+ set enauser $enausername
+ } else {
+ set enauser [join [find enauser $router] ""]
+ if { "$enauser" == "" } { set enauser $ruser }
+ }
+
+ # Figure out prompts
+ set u_prompt [find userprompt $router]
+ if { "$u_prompt" == "" } {
+ set u_prompt "(Username|Login|login|user name):"
+ } else {
+ set u_prompt [join [lindex $u_prompt 0] ""]
+ }
+ set p_prompt [find passprompt $router]
+ if { "$p_prompt" == "" } {
+ set p_prompt "(\[Pp]assword|passwd):"
+ } else {
+ set p_prompt [join [lindex $p_prompt 0] ""]
+ }
+ set e_prompt [find enableprompt $router]
+ if { "$e_prompt" == "" } {
+ set e_prompt "\[Pp]assword:"
+ } else {
+ set e_prompt [join [lindex $e_prompt 0] ""]
+ }
+
+ # Figure out cypher type
+ if {[info exists cypher]} {
+ # command line cypher type
+ set cyphertype $cypher
+ } else {
+ set cyphertype [find cyphertype $router]
+ if { "$cyphertype" == "" } { set cyphertype "3des" }
+ }
+
+ # Figure out connection method
+ set cmethod [find method $router]
+ if { "$cmethod" == "" } { set cmethod {{telnet} {ssh}} }
+
+ # Figure out the SSH executable name
+ set sshcmd [find sshcmd $router]
+ if { "$sshcmd" == "" } { set sshcmd {ssh} }
+
+ # Login to the router
+ if {[login $router $ruser $userpswd $passwd $enapasswd $cmethod $cyphertype]} {
+ continue
+ }
+
+ # we are logged in, now figure out the full prompt
+ send "\r"
+ expect {
+ -re "\[\r\n]+" { exp_continue; }
+ -re "^(.+:)1 $prompt" { # stoopid extreme cmd-line numbers and
+ # prompt based on state of config changes
+ set junk $expect_out(1,string)
+ regsub -all "^\\\* " $expect_out(1,string) {} junk
+ set prompt ".? ?$junk\[0-9]+ $prompt";
+ set platform "extreme"
+ }
+ -re "^.+$prompt" { set junk $expect_out(0,string);
+ regsub -all "\[\]\[]" $junk {\\&} prompt; }
+ -re "^.+> \\\(enable\\\)" { set junk $expect_out(0,string);
+ regsub -all "\[\]\[]" $junk {\\&} prompt; }
+ }
+
+ if { $do_command } {
+ if {[run_commands $prompt $command]} {
+ continue
+ }
+ } elseif { $do_script } {
+ # If the prompt is (enable), then we are on a switch and the
+ # command is "set length 0"; otherwise its "term length 0".
+ if [ regexp -- ".*> .*enable" "$prompt" ] {
+ send "set length 0\r"
+ send "set logging session disable\r"
+ } else {
+ send "term length 0\r"
+ }
+ expect -re $prompt {}
+ source $sfile
+ close
+ } else {
+ label $router
+ log_user 1
+ interact
+ }
+
+ # End of for each router
+ wait
+ sleep 0.3
+}
+exit 0
diff --git a/bin/nsrancid.in b/bin/nsrancid.in
new file mode 100644
index 0000000..40a286f
--- /dev/null
+++ b/bin/nsrancid.in
@@ -0,0 +1,313 @@
+#! @PERLV_PATH@
+##
+## $Id: nsrancid.in,v 1.7 2004/01/11 03:49:13 heas Exp $
+##
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## All rights reserved.
+##
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
+##
+## 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.
+##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
+##
+#
+# hacked version of Hank's rancid - this one tries to deal with Netscalers.
+# Hacks from Anshuman Kanwar.
+#
+# RANCID - Really Awesome New Cisco confIg Differ
+#
+# usage: rancid [-d] [-l] [-f filename | $host]
+#
+use Getopt::Std;
+getopts('dfl');
+$log = $opt_l;
+$debug = $opt_d;
+$file = $opt_f;
+$host = $ARGV[0];
+$clean_run = 0;
+$found_end = 0;
+$timeo = 90; # nslogin timeout in seconds
+
+
+@temp1 = split (/\./,$host);
+$prompt = "$temp1[0]#";
+$prompt = "netscaler#";
+
+my(%filter_pwds); # password filtering mode
+
+# 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 config"
+sub ShowConfig {
+ print STDERR " In ShowConfig: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ next if (/^Reading configuration information/);
+ next if (/^Can\'t find object or class named \"\-all\"\s*$/);
+ next if (/lock-address .*$/);
+ next if (/^\# *uptime +\d+\s*$/);
+ if (/community label /) {
+ if (defined($ENV{'NOCOMMSTR'})) {
+ $_ =~ s/community label .*$/community label <removed>/;
+ }
+ }
+ return(1) if /(invalid command name)/;
+ ProcessHistory("","","","$_");
+ }
+
+ if (/exit$/) {
+ $found_end = 1;
+ $clean_run = 1;
+ return(1);
+ }
+ return(0);
+}
+
+# This routine parses "get log setting"
+sub GetLogSet {
+ print STDERR " In GetLogSet: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ next if (/^Reading configuration information/);
+ next if (/^Can\'t find object or class named \"\-all\"\s*$/);
+ return(1) if /(invalid command name)/;
+
+ ProcessHistory("","","","$_");
+ }
+ return(0);
+}
+
+# This routine parses single command's that return no required info
+sub RunCommand {
+ print STDERR " In RunCommand: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ }
+ return(0)
+}
+
+# dummy function
+sub DoNothing {print STDOUT;}
+
+# Main
+#--------------------------------------------------
+%commands=(
+ 'cat /etc/ns.conf' => "ShowConfig",
+ 'get log setting' => "GetLogSet"
+);
+# 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=(
+ "cat /etc/ns.conf",
+ "get log setting"
+);
+$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 nslogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug);
+ print STDOUT "executing nslogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log);
+ if (defined($ENV{NOPIPE})) {
+ system "nslogin -t $timeo -c \"$cisco_cmds\" $host </dev/null > $host.raw 2>&1" || die "nslogin failed for $host: $!\n";
+ open(INPUT, "< $host.raw") || die "nslogin failed for $host: $!\n";
+ } else {
+ open(INPUT,"nslogin -t $timeo -c \"$cisco_cmds\" $host </dev/null |") || die "nslogin failed for $host: $!\n";
+ }
+}
+
+# determine password filtering mode
+if ($ENV{"FILTER_PWDS"} =~ /no/i) {
+ $filter_pwds = 0;
+} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
+ $filter_pwds = 2;
+} else {
+ $filter_pwds = 1;
+}
+
+#print STDOUT "$prompt \n";
+ProcessHistory("","","","!RANCID-CONTENT-TYPE: netscaler\n!\n");
+TOP: while(<INPUT>) {
+ tr/\015//d;
+#print STDOUT " --IN--$_";
+ # if ( (/exit/) || $found_end ) {
+# $clean_run=1;
+#print STDOUT "\n\nhere11\n";
+#last;
+# }
+
+ # if ( (/netscaler#/) || $found_end ) {
+#print STDOUT "\n\nhere1\n";
+# $clean_run=1;
+# last;
+# }
+
+ if (/^Error:/) {
+ print STDOUT ("$host nslogin error: $_");
+ print STDERR ("$host nslogin error: $_") if ($debug);
+ $clean_run=0;
+ last;
+ }
+ while (/#\s*($cmds_regexp)\s*$/) {
+ $cmd = $1;
+ print STDERR ("HIT COMMAND:$_") if ($debug);
+ if (! defined($commands{$cmd})) {
+ print STDERR "$host: found unexpected command - \"$cmd\"\n";
+ $clean_run = 0;
+ last TOP;
+ }
+ $rval = &{$commands{$cmd}};
+ delete($commands{$cmd});
+ if ($rval == -1) {
+ $clean_run = 0;
+ last TOP;
+ }
+ }
+}
+print STDOUT "Done $logincmd: $_\n" if ($log);
+# Flush History
+ProcessHistory("","","","");
+# Cleanup
+close(INPUT);
+close(OUTPUT);
+
+if (defined($ENV{NOPIPE})) {
+ unlink("$host.raw") if (! $debug);
+}
+
+# check for completeness
+if (scalar(%commands) || !$clean_run || !$found_end) {
+ if (scalar(%commands)) {
+ printf(STDOUT "$host: missed cmd(s): %s\n", join(',', keys(%commands)));
+ printf(STDERR "$host: missed cmd(s): %s\n", join(',', keys(%commands))) if ($debug);
+ }
+ if (!$clean_run || !$found_end) {
+ print STDOUT "$host: End of run not found\n";
+ print STDERR "$host: End of run not found\n" if ($debug);
+ system("/usr/bin/tail -1 $host.new");
+ }
+ unlink "$host.new" if (! $debug);
+}
diff --git a/bin/par.in b/bin/par.in
index 02a5383..b50bd05 100755..100644
--- a/bin/par.in
+++ b/bin/par.in
@@ -1,19 +1,22 @@
-#!@PERLV_PATH@
+#! @PERLV_PATH@
##
+## $Id: par.in,v 1.10 2004/01/11 03:49:13 heas Exp $
##
-## Copyright (C) 1997-2001 by Henry Kilmer and Peter Whiting.
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
-##
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
+##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
# PAR - parallel processing of command
diff --git a/bin/prancid.in b/bin/prancid.in
new file mode 100755
index 0000000..7ded178
--- /dev/null
+++ b/bin/prancid.in
@@ -0,0 +1,569 @@
+#! @PERLV_PATH@
+##
+## $Id: prancid.in,v 1.29 2004/01/11 03:49:13 heas Exp $
+##
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## All rights reserved.
+##
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
+##
+## 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.
+##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
+##
+#
+# This version of rancid tries to deal with Prockets.
+#
+# RANCID - Really Awesome New Cisco confIg Differ
+#
+# usage: rancid [-d] [-l] [-f filename | $host]
+#
+use Getopt::Std;
+getopts('dfl');
+$log = $opt_l;
+$debug = $opt_d;
+$file = $opt_f;
+$host = $ARGV[0];
+$clean_run = 0;
+$found_end = 0;
+$timeo = 90; # clogin timeout in seconds
+
+my($platform); # platform/cpu type
+my(%filter_pwds); # password filtering mode
+
+# This routine is used to print out the router configuration
+sub ProcessHistory {
+ my($new_hist_tag,$new_command,$command_string,@string)=(@_);
+ if((($new_hist_tag ne $hist_tag) || ($new_command ne $command))
+ && defined %history) {
+ print eval "$command \%history";
+ undef %history;
+ }
+ if (($new_hist_tag) && ($new_command) && ($command_string)) {
+ if ($history{$command_string}) {
+ $history{$command_string} = "$history{$command_string}@string";
+ } else {
+ $history{$command_string} = "@string";
+ }
+ } elsif (($new_hist_tag) && ($new_command)) {
+ $history{++$#history} = "@string";
+ } else {
+ print "@string";
+ }
+ $hist_tag = $new_hist_tag;
+ $command = $new_command;
+ 1;
+}
+
+sub numerically { $a <=> $b; }
+
+# This is a sort routing that will sort numerically on the
+# keys of a hash as if it were a normal array.
+sub keynsort {
+ local(%lines)=@_;
+ local($i) = 0;
+ local(@sorted_lines);
+ foreach $key (sort numerically keys(%lines)) {
+ $sorted_lines[$i] = $lines{$key};
+ $i++;
+ }
+ @sorted_lines;
+}
+
+# This is a sort routing that will sort on the
+# keys of a hash as if it were a normal array.
+sub keysort {
+ local(%lines)=@_;
+ local($i) = 0;
+ local(@sorted_lines);
+ foreach $key (sort keys(%lines)) {
+ $sorted_lines[$i] = $lines{$key};
+ $i++;
+ }
+ @sorted_lines;
+}
+
+# This is a sort routing that will sort on the
+# values of a hash as if it were a normal array.
+sub valsort{
+ local(%lines)=@_;
+ local($i) = 0;
+ local(@sorted_lines);
+ foreach $key (sort values %lines) {
+ $sorted_lines[$i] = $key;
+ $i++;
+ }
+ @sorted_lines;
+}
+
+# This is a numerical sort routing (ascending).
+sub numsort {
+ local(%lines)=@_;
+ local($i) = 0;
+ local(@sorted_lines);
+ foreach $num (sort {$a <=> $b} keys %lines) {
+ $sorted_lines[$i] = $lines{$num};
+ $i++;
+ }
+ @sorted_lines;
+}
+
+# This is a sort routine that will sort on the
+# ip address when the ip address is anywhere in
+# the strings.
+sub ipsort {
+ local(%lines)=@_;
+ local($i) = 0;
+ local(@sorted_lines);
+ foreach $addr (sort sortbyipaddr keys %lines) {
+ $sorted_lines[$i] = $lines{$addr};
+ $i++;
+ }
+ @sorted_lines;
+}
+
+# These two routines will sort based upon IP addresses
+sub ipaddrval {
+ my(@a) = ($_[0] =~ m#^(\d+)\.(\d+)\.(\d+)\.(\d+)$#);
+ $a[3]+256*($a[2]+256*($a[1]+256*$a[0]));
+}
+sub sortbyipaddr {
+ &ipaddrval($a) <=> &ipaddrval($b);
+}
+
+# This routine parses "show version"
+sub ShowVersion {
+ print STDERR " In ShowVersion: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+ next if(/^(\s*|\s*$cmd\s*)$/);
+ return(-1) if (/command authorization failed/i);
+
+ if (/(lynxos|kernel) Version: .* (\S+)/i) {
+ $platform = $2;
+ }
+ /Procket/ && ProcessHistory("COMMENTS","keysort","B0", "! $_") && next;
+ /System Uptime:/ && next;
+ /Protocol Uptime:/ && next;
+ ProcessHistory("COMMENTS","keysort","B0", "!$_") && next;
+
+ }
+ return(0);
+}
+
+# This routine parses "show package"
+sub ShowPackage {
+ print STDERR " In ShowPackage: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+ next if(/^(\s*|\s*$cmd\s*)$/);
+ return(-1) if (/command authorization failed/i);
+
+ ProcessHistory("COMMENTS","keysort","C0", "! $_") && next;
+
+ }
+ return(0);
+}
+
+# This routine parses "show hardware"
+sub ShowHardware {
+ print STDERR " In ShowHardware: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+ next if(/^(\s*|\s*$cmd\s*)$/);
+ # skip show hardware on titanium
+ return(0) if ($platform =~ /i386/i);
+ return(-1) if (/command authorization failed/i);
+ return(-1) if (/cli: couldn.t communicate with/);
+
+ ProcessHistory("COMMENTS","keysort","D0", "! $_") && next;
+
+ }
+ return(0);
+}
+
+# This routine parses "show inventory"
+sub ShowInventory {
+ print STDERR " In ShowInventory: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+ next if(/^(\s*|\s*$cmd\s*)$/);
+ return(0) if (/^\s+\^/);
+ return(-1) if (/command authorization failed/i);
+
+ /Procket/ && ProcessHistory("COMMENTS","keysort","E0", "! $_") && next;
+ /System Uptime:/ && next;
+ /Protocol Uptime:/ && next;
+ ProcessHistory("COMMENTS","keysort","E0", "!$_") && next;
+
+ }
+ return(0);
+}
+
+# This routine processes a "write term"
+sub WriteTerm {
+ print STDERR " In WriteTerm: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+ return(-1) if (/command authorization failed/i);
+
+ /Non-Volatile memory is in use/ && return(-1); # NvRAM is locked
+ # skip the crap
+ if (/^(##+$|(Building|Current) configuration)/i) {
+ while (<INPUT>) {
+ next if (/^Current configuration\s*:/i);
+ next if (/^([%!].*|\s*)$/);
+ last;
+ }
+ tr/\015//d;
+ }
+ # some versions have other crap mixed in with the bits in the
+ # block above
+ /^! Last Changed:/ && next;
+
+ # Dog gone Cool matches to process the rest of the config
+# /^tftp-server flash / && next; # kill any tftp remains
+# /^ntp clock-period / && next; # kill ntp clock-period
+# /^ length / && next; # kill length on serial lines
+# /^ width / && next; # kill width on serial lines
+# /^ clockrate / && next; # kill clockrate on serial interfaces
+
+ if (/^(enable secret( level \d)?) / && $filter_pwds >= 2) {
+ ProcessHistory("ENABLE","","","!$1 <removed>\n");
+ next;
+ }
+ if (/^username (\S+)(\s.*)? password ((\d) \S+|\S+)/) {
+ if ($filter_pwds == 2) {
+ ProcessHistory("USER","keysort","$1","!username $1$2 password <removed>\n");
+ } elsif ($filter_pwds == 1 && $4 ne "5"){
+ ProcessHistory("USER","keysort","$1","!username $1$2 password <removed>\n");
+ } else {
+ ProcessHistory("USER","keysort","$1","$_");
+ }
+ next;
+ }
+
+ # prune passwords {bgp, ...}
+ if (/^(\s*)password / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1password <removed>\n");
+ next;
+ }
+ # prune authentication keys {vrrp vrid N, router isis...}
+ if (/^(\s*authentication \S+ key) / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n");
+ next;
+ }
+ if (/^(\s*authentication-key) \d \S+( .*)/ && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>$2\n");
+ next;
+ }
+
+# if (/^\s*neighbor (\S*) password / && $filter_pwds >= 1) {
+# ProcessHistory("","","","! neighbor $1 password <removed>\n");
+# next;
+# }
+# if (/^(ppp .* password) 7 .*/ && $filter_pwds >= 1) {
+# ProcessHistory("","","","!$1 <removed>\n"); next;
+# }
+# if (/^(ip ftp password) / && $filter_pwds >= 1) {
+# ProcessHistory("","","","!$1 <removed>\n"); next;
+# }
+
+ # prune ospf keys
+ if (/^( ip ospf authentication-key) / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\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;
+ }
+ # this is reversable, despite 'md5' in the cmd
+ if (/^(\s*message-digest-key \d+ md5) / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
+
+# if (/^((crypto )?isakmp key) \S+ / && $filter_pwds >= 1) {
+# ProcessHistory("","","","!$1 <removed> $'"); next;
+# }
+
+ # sort ip explicit-paths.
+ if (/^ip explicit-path name (\S+)/) {
+ my($key) = $1;
+ my($expath) = $_;
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ last if (/^$prompt/ || ! /^(ip explicit-path name |[ !])/);
+ if (/^ip explicit-path name (\S+)/) {
+ ProcessHistory("EXPATH","keysort","$key","$expath");
+ $key = $1;
+ $expath = $_;
+ } else {
+ $expath .= $_;
+ }
+ }
+ ProcessHistory("EXPATH","keysort","$key","$expath");
+ }
+
+ # sort route-maps
+ if (/^route-map (\S+)/) {
+ my($key) = $1;
+ my($routemap) = $_;
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/ || ! /^(route-map |[ !])/);
+ if (/^route-map (\S+)/) {
+ ProcessHistory("ROUTEMAP","keysort","$key","$routemap");
+ $key = $1;
+ $routemap = $_;
+ } else {
+ $routemap .= $_;
+ }
+ }
+ ProcessHistory("ROUTEMAP","keysort","$key","$routemap");
+ }
+
+ # filter out any RCS/CVS tags to avoid confusing local CVS storage
+ s/\$(Revision|Id):/ $1:/;
+
+# # order access-lists
+# /^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ &&
+# ProcessHistory("ACL $1 $2","ipsort","$3","$_") && next;
+# # order extended access-lists
+# /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+host\s+(\S+)/ &&
+# ProcessHistory("EACL $1 $2","ipsort","$3","$_") && next;
+# /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+(\d\S+)/ &&
+# ProcessHistory("EACL $1 $2","ipsort","$3","$_") && next;
+# /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+any/ &&
+# ProcessHistory("EACL $1 $2","ipsort","0.0.0.0","$_") && next;
+# # order arp lists
+# /^arp\s+(\d+\.\d+\.\d+\.\d+)\s+/ &&
+# ProcessHistory("ARP","ipsort","$1","$_") && next;
+# /^ip prefix-list\s+(\S+)\s+seq\s+(\d+)\s+(permit|deny)\s+(\d\S+)(\/.*)$/ &&
+# ProcessHistory("PACL $1 $3","ipsort","$4","ip prefix-list $1 $3 $4$5\n")
+# && next;
+
+ # order logging statements
+ /^logging (\d+\.\d+\.\d+\.\d+)/ &&
+ ProcessHistory("LOGGING","ipsort","$1","$_") && next;
+
+ # order/prune snmp-server host statements
+ # we only prune lines of the form
+ # snmp-server host a.b.c.d <community>
+ if (/^snmp-server host (\d+\.\d+\.\d+\.\d+) /) {
+ if (defined($ENV{'NOCOMMSTR'})) {
+ my($ip) = $1;
+ my($line) = "snmp-server host $ip";
+ my(@tokens) = split(' ', $');
+ my($token);
+ while ($token = shift(@tokens)) {
+ if ($token eq 'version') {
+ $line .= " " . join(' ', ($token, shift(@tokens)));
+ } elsif ($token =~ /^(informs?|traps?|(no)?auth)$/) {
+ $line .= " " . $token;
+ } else {
+ $line = "!$line " . join(' ', ("<removed>", join(' ',@tokens)));
+ last;
+ }
+ }
+ ProcessHistory("SNMPSERVERHOST","ipsort","$ip","$line\n");
+ } else {
+ ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_");
+ }
+ next;
+ }
+ if (/^(snmp-server community) (\S+)/) {
+ if (defined($ENV{'NOCOMMSTR'})) {
+ ProcessHistory("SNMPSERVERCOMM","keysort","$_","!$1 <removed>$'") && next;
+ } else {
+ ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next;
+ }
+ }
+
+ # prune tacacs/radius server keys
+ if (/^(tacacs-server|radius-server) key / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 key <removed>\n"); next;
+ }
+ if (/^(tacacs-server host \S+( .*)? key) (\d )?\S+/
+ && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
+
+ # order clns host statements
+# /^clns host \S+ (\S+)/ &&
+# ProcessHistory("CLNS","keysort","$1","$_") && next;
+
+ # prune vrrp password
+ if (/^( ip vrrp authentication .* key) / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
+ # prune isis password
+ if (/^( isis authentication-key) \d \S+/ && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>$'"); next;
+ }
+ # prune msdp password
+ if (/^(ip msdp password \S+) / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
+ # delete ntp auth password - this md5 is a reversable too
+ if (/^(ntp authentication-key \d+ md5) / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
+ # order ntp peers/servers
+ if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) {
+ $sortkey = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5);
+ ProcessHistory("NTP","keysort",$sortkey,"$_");
+ next;
+ }
+
+# # order ip host line statements
+# /^ip host line(\d+)/ &&
+# ProcessHistory("IPHOST","numsort","$1","$_") && next;
+# # order ip nat source static statements
+# /^ip nat (\S+) source static (\S+)/ &&
+# ProcessHistory("IP NAT $1","ipsort","$2","$_") && next;
+# # order atm map-list statements
+# /^\s+ip\s+(\d+\.\d+\.\d+\.\d+)\s+atm-vc/ &&
+# ProcessHistory("ATM map-list","ipsort","$1","$_") && next;
+# # order ip rcmd lines
+# /^ip rcmd/ && ProcessHistory("RCMD","keysort","$_","$_") && next;
+
+ # catch anything that wasnt matched above.
+ ProcessHistory("","","","$_");
+ # end of config.
+ if (/^end$/) {
+ $found_end = 1;
+ return(1);
+ }
+ }
+ return(0);
+}
+
+# dummy function
+sub DoNothing {print STDOUT;}
+
+# Main
+%commands=(
+ 'show version all' => "ShowVersion",
+ 'show package' => "ShowPackage",
+ 'show hardware' => "ShowHardware",
+ 'show inventory' => "ShowInventory",
+ 'write term' => "WriteTerm"
+);
+# keys() doesnt return things in the order entered and the order of the
+# cmds is important (show version first and write term last). pita
+@commands=(
+ "show version all",
+ "show package",
+ "show hardware",
+ "show inventory",
+ "write term"
+);
+$cisco_cmds=join(";",@commands);
+$cmds_regexp=join("|",@commands);
+
+open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
+select(OUTPUT);
+# make OUTPUT unbuffered if debugging
+if ($debug) { $| = 1; }
+
+if ($file) {
+ print STDERR "opening file $host\n" if ($debug);
+ print STDOUT "opening file $host\n" if ($log);
+ open(INPUT,"<$host") || die "open failed for $host: $!\n";
+} else {
+ print STDERR "executing 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";
+ }
+}
+
+# determine password filtering mode
+if ($ENV{"FILTER_PWDS"} =~ /no/i) {
+ $filter_pwds = 0;
+} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
+ $filter_pwds = 2;
+} else {
+ $filter_pwds = 1;
+}
+
+ProcessHistory("","","","!RANCID-CONTENT-TYPE: procket\n!\n");
+ProcessHistory("COMMENTS","keysort","B0","!\n"); # show version
+ProcessHistory("COMMENTS","keysort","C0","!\n"); # show package
+ProcessHistory("COMMENTS","keysort","D0","!\n"); # show hardware
+ProcessHistory("COMMENTS","keysort","E0","!\n"); # show inventory
+ProcessHistory("COMMENTS","keysort","Z0","!\n");
+TOP: while(<INPUT>) {
+ tr/\015//d;
+ if (/\#\s?exit$/) {
+ $clean_run=1;
+ last;
+ }
+ if (/^Error:/) {
+ print STDOUT ("$host clogin error: $_");
+ print STDERR ("$host clogin error: $_") if ($debug);
+ $clean_run=0;
+ last;
+ }
+ while (/#\s*($cmds_regexp)\s*$/) {
+ $cmd = $1;
+ if (!defined($prompt)) {$prompt = ($_ =~ /^([^#]+#)/)[0]; }
+ print STDERR ("HIT COMMAND:$_") if ($debug);
+ if (! defined($commands{$cmd})) {
+ print STDERR "$host: found unexpected command - \"$cmd\"\n";
+ $clean_run = 0;
+ last TOP;
+ }
+ $rval = &{$commands{$cmd}};
+ delete($commands{$cmd});
+ if ($rval == -1) {
+ $clean_run = 0;
+ last TOP;
+ }
+ }
+}
+print STDOUT "Done $logincmd: $_\n" if ($log);
+# Flush History
+ProcessHistory("","","","");
+# Cleanup
+close(INPUT);
+close(OUTPUT);
+
+if (defined($ENV{NOPIPE})) {
+ unlink("$host.raw") if (! $debug);
+}
+
+# check for completeness
+if (scalar(%commands) || !$clean_run || !$found_end) {
+ if (scalar(%commands)) {
+ printf(STDOUT "$host: missed cmd(s): %s\n", join(',', keys(%commands)));
+ printf(STDERR "$host: missed cmd(s): %s\n", join(',', keys(%commands))) if ($debug);
+ }
+ if (!$clean_run || !$found_end) {
+ print STDOUT "$host: End of run not found\n";
+ print STDERR "$host: End of run not found\n" if ($debug);
+ system("/usr/bin/tail -1 $host.new");
+ }
+ unlink "$host.new" if (! $debug);
+}
diff --git a/bin/create_cvs.in b/bin/rancid-cvs.in
index 06d414b..22d5fd2 100755..100644
--- a/bin/create_cvs.in
+++ b/bin/rancid-cvs.in
@@ -1,34 +1,39 @@
-#!/bin/sh
+#! /bin/sh
##
+## $Id: rancid-cvs.in,v 1.16 2004/01/11 03:49:13 heas Exp $
##
-## Copyright (C) 1996-2001 by Henry Kilmer.
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
-##
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
+##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
-# Create all of the misc files & dirs needed.
+# Create all of the misc files & dirs needed for each group and import them
+# into CVS.
#
-# create_cvs
+# rancid-cvs
#
# Read in the environment
-ENVFILE="`dirname $0`/env"
+ENVFILE="@sysconfdir@/rancid.conf"
. $ENVFILE
# Base dir
if [ ! -d $BASEDIR ]; then
- mkdir -p $BASEDIR
+ mkdir -p $BASEDIR ||
+ (echo "Could not create local state directory: $BASEDIR"; exit 1)
fi
cd $BASEDIR
diff --git a/bin/rancid-fe.in b/bin/rancid-fe.in
index b25dcb1..b80a194 100755..100644
--- a/bin/rancid-fe.in
+++ b/bin/rancid-fe.in
@@ -1,22 +1,25 @@
-#!@PERLV_PATH@
+#! @PERLV_PATH@
##
+## $Id: rancid-fe.in,v 1.36 2004/01/11 03:49:13 heas Exp $
##
-## Copyright (C) 1997-2001 by Henry Kilmer.
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
-# rancid-FE - front-end to rancid/jrancid for use with par.
+# rancid-FE - front-end to rancid/jrancid/etc. for use with par.
#
# usage: rancid-fe <router>:<vendor>
#
@@ -25,18 +28,28 @@ require 5;
($router, $vendor) = split('\:', $ARGV[0]);
- if ($vendor =~ /^alteon$/i) { exec('arancid', $router); }
-elsif ($vendor =~ /^baynet$/i) { exec('brancid', $router); }
-elsif ($vendor =~ /^cat5$/i) { exec('cat5rancid', $router); }
-elsif ($vendor =~ /^cisco$/i) { exec('rancid', $router); }
-elsif ($vendor =~ /^extreme$/i) { exec('xrancid', $router); }
-elsif ($vendor =~ /^ezt3$/i) { exec('erancid', $router); }
-elsif ($vendor =~ /^force10$/i) { exec('f10rancid', $router); }
-elsif ($vendor =~ /^foundry$/i) { exec('francid', $router); }
-elsif ($vendor =~ /^hp$/i) { exec('hrancid', $router); }
-elsif ($vendor =~ /^juniper$/i) { exec('jrancid', $router); }
-elsif ($vendor =~ /^mrtd$/i) { exec('mrancid', $router); }
-elsif ($vendor =~ /^redback$/i) { exec('rrancid', $router); }
+ if ($vendor =~ /^alteon$/i) { exec('arancid', $router); }
+elsif ($vendor =~ /^baynet$/i) { exec('brancid', $router); }
+elsif ($vendor =~ /^cat5$/i) { exec('cat5rancid', $router); }
+elsif ($vendor =~ /^cisco$/i) { exec('rancid', $router); }
+elsif ($vendor =~ /^css$/i) { exec('cssrancid', $router); }
+elsif ($vendor =~ /^enterasys$/i) { exec('rivrancid', $router); }
+elsif ($vendor =~ /^erx$/i) { exec('jerancid', $router); }
+elsif ($vendor =~ /^extreme$/i) { exec('xrancid', $router); }
+elsif ($vendor =~ /^ezt3$/i) { exec('erancid', $router); }
+elsif ($vendor =~ /^force10$/i) { exec('f10rancid', $router); }
+elsif ($vendor =~ /^foundry$/i) { exec('francid', $router); }
+elsif ($vendor =~ /^hitachi$/i) { exec('htrancid', $router); }
+elsif ($vendor =~ /^hp$/i) { exec('hrancid', $router); }
+elsif ($vendor =~ /^juniper$/i) { exec('jrancid', $router); }
+elsif ($vendor =~ /^mrtd$/i) { exec('mrancid', $router); }
+elsif ($vendor =~ /^netscaler$/i) { exec('nsrancid', $router); }
+elsif ($vendor =~ /^netscreen$/i) { exec('nrancid', $router); }
+elsif ($vendor =~ /^procket$/i) { exec('prancid', $router); }
+elsif ($vendor =~ /^redback$/i) { exec('rrancid', $router); }
+elsif ($vendor =~ /^riverstone$/i) { exec('rivrancid', $router); }
+elsif ($vendor =~ /^tnt$/i) { exec('tntrancid', $router); }
+elsif ($vendor =~ /^zebra$/i) { exec('zrancid', $router); }
else {
printf(STDERR "unknown router manufacturer for $router: $vendor\n");
exit(-1);
diff --git a/bin/do-diffs.in b/bin/rancid-run.in
index 874007c..b59b026 100755..100644
--- a/bin/do-diffs.in
+++ b/bin/rancid-run.in
@@ -1,21 +1,29 @@
-#!/bin/sh
-## Copyright (C) 1997-2001 by Henry Kilmer.
+#! /bin/sh
+##
+## $Id: rancid-run.in,v 1.28 2004/01/11 06:11:23 hank Exp $
+##
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
+#
+# Run rancid for each of the rancid groups defined by $LIST_OF_GROUPS in
+# @sysconfdir@/rancid.conf or those specified on the command-line.
+#
-ENVFILE="`dirname $0`/env"
+ENVFILE="@sysconfdir@/rancid.conf"
. $ENVFILE
@@ -69,12 +77,12 @@ fi
if [ $# -ge 1 ] ; then
LIST_OF_GROUPS="$*"; export LIST_OF_GROUPS
elif [ "$LIST_OF_GROUPS" = "" ] ; then
- echo "LIST_OF_GROUPS is empty in $ENVFILE"
- exit 1
+ echo "LIST_OF_GROUPS is empty in $ENVFILE"
+ exit 1
fi
-if [ ! -d $BASEDIR/logs ] ; then
- mkdir $BASEDIR/logs
+if [ ! -d $LOGDIR ] ; then
+ mkdir $LOGDIR || (echo "Could not create log directory: $LOGDIR"; exit 1)
fi
for GROUP in $LIST_OF_GROUPS
@@ -99,7 +107,7 @@ do
if [ -s $TMPDIR/.$GROUP.old ]
then
(
- echo "To: @MAILPLUS@admin-$GROUP"
+ echo "To: @ADMINMAILPLUS@$GROUP"
echo "Subject: rancid hung - $GROUP"
echo "Precedence: bulk"
echo ""
@@ -124,5 +132,5 @@ END
echo
echo ending: `date`
- ) >$BASEDIR/logs/$GROUP.`date +%Y%m%d.%H%M%S` 2>&1
+ ) >$LOGDIR/$GROUP.`date +%Y%m%d.%H%M%S` 2>&1
done
diff --git a/bin/rancid.in b/bin/rancid.in
index 4566b58..27a5a48 100755..100644
--- a/bin/rancid.in
+++ b/bin/rancid.in
@@ -1,19 +1,22 @@
-#!@PERLV_PATH@
+#! @PERLV_PATH@
##
+## $Id: rancid.in,v 1.168 2004/01/12 00:52:47 asp Exp $
##
-## Copyright (C) 1997-2001 by Henry Kilmer.
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
# RANCID - Really Awesome New Cisco confIg Differ
@@ -21,7 +24,7 @@
# usage: rancid [-d] [-l] [-f filename | $host]
#
use Getopt::Std;
-getopts('dflm');
+getopts('dfl');
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
@@ -135,31 +138,40 @@ sub sortbyipaddr {
# This routine parses "show version"
sub ShowVersion {
print STDERR " In ShowVersion: $_" if ($debug);
+ my($slaveslot);
while (<INPUT>) {
tr/\015//d;
- study;
last if(/^$prompt/);
next if(/^(\s*|\s*$cmd\s*)$/);
return(-1) if (/command authorization failed/i);
+ # the pager can not be disabled per-session on the PIX
+ s/^<-+ More -+>\s*//;
if (/^Slave in slot (\d+) is running/) {
$slave = " Slave:";
+ $slaveslot = ", slot $1";
next;
}
+ if (/^Application and Content Networking Software/) { $type="CE"; }
+ /^Application and Content Networking Software Release /i &&
+ ProcessHistory("COMMENTS","keysort","F1", "!Image: $_") && next;
/^Cisco Secure PIX /i &&
ProcessHistory("COMMENTS","keysort","F1", "!Image: $_") && next;
- /^IOS .* Software \(([A-Za-z-0-9]*)\), .*Version\s+(.*)$/ &&
+ # PIX fail-over license
+ /^This PIX has an?\s+(.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","C1", "!$_") && next;
+ /^(Cisco )?IOS .* Software,? \(([A-Za-z-0-9]*)\), .*Version\s+(.*)$/ &&
ProcessHistory("COMMENTS","keysort","F1",
- "!Image:$slave Software: $1, $2\n") && next;
+ "!Image:$slave Software: $2, $3\n") && next;
/^([A-Za-z-0-9_]*) Synced to mainline version: (.*)$/ &&
ProcessHistory("COMMENTS","keysort","F2",
"!Image:$slave $1 Synced to mainline version: $2\n") && next;
/^Compiled (.*)$/ &&
ProcessHistory("COMMENTS","keysort","F3",
"!Image:$slave Compiled: $1\n") && next;
- /^ROM: (System )?Bootstrap.*(Version.*)$/ &&
+ /^ROM: (IOS \S+ )?(System )?Bootstrap.*(Version.*)$/ &&
ProcessHistory("COMMENTS","keysort","G1",
- "!ROM Bootstrap: $2\n") && next;
+ "!ROM Bootstrap: $3\n") && next;
if (/^Hardware:\s+(.*), (.* RAM), CPU (.*)$/) {
ProcessHistory("COMMENTS","keysort","A1",
"!Chassis type: $1 - a PIX\n");
@@ -169,6 +181,17 @@ sub ShowVersion {
}
/^Serial Number:\s+(.*)$/ &&
ProcessHistory("COMMENTS","keysort","C1", "!$_") && next;
+ # CatOS 3500xl stuff
+ /^System serial number(:\s+.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","C1", "!Serial Number$1\n") &&
+ next;
+ /^Model / &&
+ ProcessHistory("COMMENTS","keysort","C2", "!$_") && next;
+ /^Motherboard / &&
+ ProcessHistory("COMMENTS","keysort","C3", "!$_") && next;
+ /^Power supply / &&
+ ProcessHistory("COMMENTS","keysort","C4", "!$_") && next;
+
/^Activation Key:\s+(.*)$/ &&
ProcessHistory("COMMENTS","keysort","C2", "!$_") && next;
/^ROM: \d+ Bootstrap .*(Version.*)$/ &&
@@ -193,48 +216,80 @@ sub ShowVersion {
my($cpu) = $2;
my($mem) = $3;
my($device) = "router";
- if ( $1 eq "CSC") {
+
+ # the next line ought to be the more specific cpu info, grab it.
+ # yet, some boards/IOS vers have a processor ID line between these
+ # two. grrr. make sure we dont grab the "software" junk that
+ # follows these lines by looking for "CPU at " or the 2600s
+ # "processor: " unique string. there are undoubtedly many other
+ # incantations. for a slave, we dont get this info and its just a
+ # blank line.
+ $_ = <INPUT>;
+ $_ = <INPUT> if (/processor board id/i);
+ $_ = "" if (! /(cpu at |processor: |$cpu processor,)/i);
+ tr/\015//d;
+ s/implementation/impl/i;
+ if ($_ !~ /^\s*$/) {
+ chomp;
+ s/^/, /;
+ }
+
+ if ( $proc eq "CSC") {
$type = "AGS";
- } elsif ( $1 eq "CSC4") {
+ } elsif ( $proc eq "CSC4") {
$type = "AGS+";
- } elsif ( $1 eq "2511" || $1 eq "2524" || $1 eq "AS2511-RJ") {
+ } elsif ( $proc =~ /^(AS)?25[12][12]/) {
$type = "2500";
- } elsif ( $1 =~ /261[01]/ || $1 =~ /262[01]/ ) {
+ } elsif ( $proc =~ /261[01]/ || $proc =~ /262[01]/ ) {
$type = "2600";
- } elsif ( $1 eq "3620" || $1 eq "3640") {
+ } elsif ( $proc =~ /^36[0246][0-9]/) {
$type = "3600";
- } elsif ( $1 eq "RSP7000") {
+ } elsif ( $proc =~ /^37/) {
+ $type = "3700";
+ } elsif ( $proc eq "RSP7000") {
$type = "7500";
- } elsif ( $1 =~ /RSP\d/) {
+ } elsif ( $proc =~ /RSP\d/) {
$type = "7500";
- } elsif ( $1 eq "RP1") {
+ } elsif ( $proc eq "RP1") {
$type = "7000";
- } elsif ( $1 eq "RP") {
+ } elsif ( $proc eq "RP") {
$type = "7000";
- } elsif ( $1 =~ /720[246]/) {
+ } elsif ( $proc =~ /720[246]/) {
$type = "7200";
- } elsif ( $1 =~ /1200[48]\/GRP/ || $1 =~ /1201[26]\/GRP/) {
+ } elsif ( $proc =~ /1200[48]\/GRP/ || $proc =~ /1201[26]\/GRP/) {
$type = "12000";
- } elsif ( $1 =~ /1201[26]-8R\/GRP/) {
+ } elsif ( $proc =~ /1201[26]-8R\/GRP/) {
$type = "12000";
- } elsif ( $1 =~ /WS-C29/) {
+ } elsif ( $proc =~ /WS-C29/) {
$type = "2900XL";
$device = "switch";
- } elsif ( $1 =~ /WS-C35/) {
+ } elsif ( $proc =~ /WS-C355/) {
+ $type = "3550";
+ $device = "switch";
+ } elsif ( $proc =~ /WS-C35/) {
$type = "3500XL";
$device = "switch";
- } elsif ( $1 =~ /6000/) {
+ } elsif ( $proc =~ /WS-C45/) {
+ $type = "4500";
+ $device = "switch";
+ } elsif ( $proc =~ /6000/) {
$type = "6000";
$device = "switch";
+ } elsif ( $proc =~ /CISCO76/) {
+ $type = "7600";
+ $device = "router";
+ } elsif ( $proc =~ /1900/) {
+ $type = "1900";
+ $device = "switch";
} else {
- $type = $1;
+ $type = $proc;
}
print STDERR "TYPE = $type\n" if ($debug);
ProcessHistory("COMMENTS","keysort","A1",
"!Chassis type:$slave $proc - a $type $device\n");
ProcessHistory("COMMENTS","keysort","B1",
"!Memory:$slave main $mem\n");
- ProcessHistory("COMMENTS","keysort","A3","!CPU:$slave $cpu\n");
+ ProcessHistory("COMMENTS","keysort","A3","!CPU:$slave $cpu$_$slaveslot\n");
next;
}
if (/(\S+) Silicon\s*Switch Processor/) {
@@ -249,7 +304,7 @@ sub ShowVersion {
/^(\d+[kK]) bytes of multibus/ &&
ProcessHistory("COMMENTS","keysort","B2",
"!Memory: multibus $1\n") && next;
- /^(\d+[kK]) bytes of non-volatile/ &&
+ /^(\d+[kK]) bytes of (non-volatile|NVRAM)/ &&
ProcessHistory("COMMENTS","keysort","B3",
"!Memory: nvram $1\n") && next;
/^(\d+[kK]) bytes of flash memory/ &&
@@ -272,9 +327,6 @@ sub ShowVersion {
ProcessHistory("COMMENTS","keysort","I0","!\n");
}
ProcessHistory("COMMENTS","keysort","I1","! $_");
- # The line after the WARNING is what to do about it.
- $_ = <INPUT>; tr/\015//d;
- ProcessHistory("COMMENTS","keysort","I1","! $_");
}
if (/^Configuration register is (.*)$/) {
$config_register=$1;
@@ -284,6 +336,57 @@ sub ShowVersion {
return(0);
}
+# This routine parses "show redundancy"
+sub ShowRedundancy {
+ print STDERR " In ShowRedundancy: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+ next if(/^(\s*|\s*$cmd\s*)$/);
+ # the pager can not be disabled per-session on the PIX
+ s/^<-+ More -+>\s*//;
+
+ /^IOS .* Software \(([A-Za-z-0-9]*)\), .*Version\s+(.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","F1",
+ "!Image:$slave Software: $1, $2\n") && next;
+ /^Compiled (.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","F3",
+ "!Image:$slave Compiled: $1\n") && next;
+ }
+ return(0);
+}
+
+# This routine parses "show IDprom"
+sub ShowIDprom {
+ my($tmp);
+
+ print STDERR " In ShowIDprom: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+ next if(/^(\s*|\s*$cmd\s*)$/);
+ # the pager can not be disabled per-session on the PIX
+ s/^<-+ More -+>\s*//;
+
+ /FRU is .(.*)\'/ && ($tmp = $1);
+ /Product Number = .(.*)\'/ &&
+ ProcessHistory("COMMENTS","keysort","D0","!\n") &&
+ ProcessHistory("COMMENTS","keysort","D0",
+ "!Catalyst Chassis type: $1, $tmp\n");
+ /Serial Number = .([0-9A-Za-z]+)/ &&
+ ProcessHistory("COMMENTS","keysort","D1",
+ "!Catalyst Chassis S/N: $1\n");
+ /Manufacturing Assembly Number = .([-0-9]+)/ && ($tmp = $1);
+ /Manufacturing Assembly Revision = .(.*)\'/ && ($tmp .= ", rev " . $1);
+ /Hardware Revision = ([0-9.]+)/ &&
+ ProcessHistory("COMMENTS","keysort","D2",
+ "!Catalyst Chassis assembly: $tmp, ver $1\n");
+ }
+ return(0);
+}
+
# This routine parses "show install active"
sub ShowInstallActive {
print STDERR " In ShowInstallActive: $_" if ($debug);
@@ -295,6 +398,8 @@ sub ShowInstallActive {
return(1) if /^\s*\^\s*$/;
return(1) if /(Invalid input detected|Type help or )/;
return(-1) if (/command authorization failed/i);
+ # the pager can not be disabled per-session on the PIX
+ s/^<-+ More -+>\s*//;
ProcessHistory("COMMENTS","keysort","F5","!Image: $_") && next;
}
return(0);
@@ -311,6 +416,8 @@ sub ShowEnv {
next if (/^(\s*|\s*$cmd\s*)$/);
#return(1) if ($type !~ /^7/);
return(-1) if (/command authorization failed/i);
+ # the pager can not be disabled per-session on the PIX
+ s/^<-+ More -+>\s*//;
if (!defined($E0)) {
$E0=1;
ProcessHistory("COMMENTS","keysort","E0","!\n");
@@ -331,11 +438,42 @@ sub ShowEnv {
ProcessHistory("COMMENTS","keysort","E2","!Power: $1\n") && next;
/^\s*(redundant .*)/i &&
ProcessHistory("COMMENTS","keysort","E2","!Power: $1\n") && next;
+ /^\s*(RPS is .*)/i &&
+ ProcessHistory("COMMENTS","keysort","E2","!Power: $1\n") && next;
}
ProcessHistory("COMMENTS","","","!\n");
return(0);
}
+# This routine parses "show rsp chassis-info" for the rsp
+# This will create arrays for hw info.
+sub ShowRSP {
+ print STDERR " In ShowRSP: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(-1) if (/command authorization failed/i);
+ # return(1) if ($type !~ /^12[40]/);
+ # the pager can not be disabled per-session on the PIX
+ s/^<-+ More -+>\s*//;
+ /^$/ && next;
+
+ /^\s+Chassis model: (\S+)/ &&
+ ProcessHistory("COMMENTS","keysort","D0","!\n") &&
+ ProcessHistory("COMMENTS","keysort","D1",
+ "!RSP Chassis model: $1\n") &&
+ next;
+ /^\s+Chassis S\/N: (.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","D2",
+ "!RSP Chassis S/N: $1\n") &&
+ next;
+ }
+
+ return(0);
+}
+
# This routine parses "show gsr chassis-info" for the gsr
# This will create arrays for hw info.
sub ShowGSR {
@@ -348,6 +486,8 @@ sub ShowGSR {
next if (/^(\s*|\s*$cmd\s*)$/);
return(-1) if (/command authorization failed/i);
# return(1) if ($type !~ /^12[40]/);
+ # the pager can not be disabled per-session on the PIX
+ s/^<-+ More -+>\s*//;
/^$/ && next;
/^\s+Chassis: type (\S+) Fab Ver: (\S+)/ &&
ProcessHistory("COMMENTS","keysort","D0","!\n") &&
@@ -386,15 +526,17 @@ sub ShowBoot {
return(1) if /Ambiguous command/i;
return(1) if /(Invalid input detected|Type help or )/;
return(1) if /(Open device \S+ failed|Error opening \S+:)/;
+ # the pager can not be disabled per-session on the PIX
+ s/^<-+ More -+>\s*//;
next if /CONFGEN variable/;
if (!defined($H0)) {
$H0=1; ProcessHistory("COMMENTS","keysort","H0","!\n");
}
if ($type !~ /^(12[04]|7)/) {
if ($type !~ /^(29|35)00/) {
- ProcessHistory("COMMENTS","keysort","H2","!BootFlash: $_");
+ ProcessHistory("COMMENTS","keysort","H2","!BootFlash: $_");
} else {
- ProcessHistory("COMMENTS","keysort","H1","!Variable: $_");
+ ProcessHistory("COMMENTS","keysort","H1","!Variable: $_");
}
} elsif (/variable/) {
ProcessHistory("COMMENTS","keysort","H1","!Variable: $_");
@@ -418,6 +560,8 @@ sub ShowFlash {
return(-1) if (/command authorization failed/i);
return(1) if /^\s*\^\s*$/;
return(1) if /(Invalid input detected|Type help or )/;
+ # the pager can not be disabled per-session on the PIX
+ s/^<-+ More -+>\s*//;
ProcessHistory("FLASH","","","!Flash: $_");
}
ProcessHistory("","","","!\n");
@@ -438,13 +582,15 @@ sub DirSlotN {
# 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 /(No such device|Error Sending Request)/i;
return(1) if /\%Error: No such file or directory/;
return(1) if /No space information available/;
return(-1) if /\%Error calling/;
return(-1) if /(: device being squeezed|ATA_Status time out)/i; # busy
return(-1) if (/command authorization failed/i);
return(1) if /(Open device \S+ failed|Error opening \S+:)/;
+ # the pager can not be disabled per-session on the PIX
+ s/^<-+ More -+>\s*//;
ProcessHistory("FLASH","","","!Flash: $dev: $_");
}
ProcessHistory("","","","!\n");
@@ -458,11 +604,12 @@ sub ShowContAll {
while (<INPUT>) {
tr/\015//d;
- study;
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
# return(1) if ($type =~ /^(12[40]|7[05])/);
return(-1) if (/command authorization failed/i);
+ # the pager can not be disabled per-session on the PIX
+ s/^<-+ More -+>\s*//;
if (/^Interface ([^ \n(]*)/) { $INT = "$1, "; next; }
/^(BRI unit \d)/ &&
ProcessHistory("INT","","","!Interface: $1\n") && next;
@@ -521,6 +668,8 @@ sub ShowContCbus {
next if (/^(\s*|\s*$cmd\s*)$/);
#return(1) if ($type !~ /^7[05]0/);
return(-1) if (/command authorization failed/i);
+ # the pager can not be disabled per-session on the PIX
+ s/^<-+ More -+>\s*//;
if (/^\s*slot(\d+): ([^,]+), hw (\S+), sw (\S+), ccb/) {
$slot = $1;
$board{$slot} = $2;
@@ -562,11 +711,12 @@ sub ShowDiagbus {
while (<INPUT>) {
tr/\015//d;
- study;
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
#return(1) if ($type !~ /^7[05]/);
return(-1) if (/command authorization failed/i);
+ # the pager can not be disabled per-session on the PIX
+ s/^<-+ More -+>\s*//;
if (/^\s*Slot (\d+):/i) {
$slot = $1;
next;
@@ -641,7 +791,7 @@ sub ShowDiagbus {
return(0);
}
-# This routine parses "show diag" for the gsr, 7200, 3600, 2600.
+# This routine parses "show diag" for the gsr, 7200, 3700, 3600, 2600.
# This will create arrarys for hw info.
sub ShowDiag {
# Skip if this is not a 12000.
@@ -649,12 +799,14 @@ sub ShowDiag {
while (<INPUT>) {
tr/\015//d;
- study;
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
# return(1) if ($type !~ /^(12[40]|720|36|26)/);
return(-1) if (/command authorization failed/i);
/^$/ && next;
+ # the pager can not be disabled per-session on the PIX
+ s/^<-+ More -+>\s*//;
+
s/Port Packet Over SONET/POS/;
if (/^\s*SLOT\s+(\d+)\s+\((.*)\): (.*)/) {
$slot = $1;
@@ -663,11 +815,22 @@ sub ShowDiag {
next;
}
if (/^\s+MAIN:\s* type \d+,\s+(.*)/) {
- ProcessHistory("SLOT","keysort","AM","!Slot $slot/MAIN: part $1\n") && next;
+ ProcessHistory("SLOT","keysort","AM","!Slot $slot/MAIN: part $1\n");
+ next;
+ }
+ if (/^c3700\s+(io-board|mid-plane)/i) {
+ $slot=$1;
+ ProcessHistory("SLOT","","","!\n");
+ ProcessHistory("SLOT","keysort","A","!Slot $slot: part $1\n");
+ next;
}
if (/ Engine:\s+(.*)/) {
ProcessHistory("SLOT","keysort","AE","!Slot $slot/Engine: $1\n");
}
+ if (/FRU:\s+Linecard\/Module:\s+(\S+)/) {
+ ProcessHistory("SLOT","keysort","AF","!Slot $slot/FRU: Linecard/Module: $1\n");
+ next;
+ }
if (/^\s+PCA:\s+(.*)/) {
local($part) = $1;
$_ = <INPUT>;
@@ -707,35 +870,78 @@ sub ShowDiag {
}
next;
}
- # 7200 and 3600 stuff
- if (/^(Slot)\s+(\d+(\/\d+)?):/ || /^\s+(WIC|VIC) Slot (\d):/) {
+ # 7200, 3600, 2600, and 1700 stuff
+ if (/^(Slot)\s+(\d+(\/\d+)?):/
+ || /^\s+(WIC|VIC|WIC\/VIC) Slot (\d):/
+ || /^(Encryption AIM) (\d):/) {
if ($1 eq "WIC") {
$WIC = "/$2";
} elsif ($1 eq "VIC") {
$WIC = "/$2";
+ } elsif ($1 eq "WIC/VIC") {
+ $WIC = "/$2";
+ } elsif ($1 eq "Encryption AIM") {
+ $slot = "$2";
+ undef($WIC);
+ ProcessHistory("SLOT","","","!\n");
+ ProcessHistory("SLOT","keysort","B","!Slot $slot: type $1\n");
+ next;
} else {
$slot = $2;
undef($WIC);
}
$_ = <INPUT>; tr/\015//d;
- # clean up hideous 7200 format to look more like 7500 output
+ # clean up hideous 7200/etc formats to look more like 7500 output
s/Fast-ethernet on C7200 I\/O card/FE-IO/;
s/ with MII or RJ45/-TX/;
s/Fast-ethernet /100Base/; s/[)(]//g;
+ s/intermediate reach/IR/i;
ProcessHistory("SLOT","","","!\n");
/\s+(.*) port adapter,?\s+(\d+)\s+/i &&
- ProcessHistory("SLOT","keysort","B","!Slot $slot: type $1, $2 ports\n");
+ ProcessHistory("SLOT","keysort","B","!Slot $slot: type $1, $2 ports\n") && next;
# I/O controller with no interfaces
/\s+(.*)\s+port adapter\s*$/i &&
- ProcessHistory("SLOT","keysort","B","!Slot $slot: type $1, 0 ports\n");
+ ProcessHistory("SLOT","keysort","B","!Slot $slot: type $1, 0 ports\n") && next;
/\s+(.*)\s+daughter card(.*)$/ &&
- ProcessHistory("SLOT","keysort","B","!Slot $slot$WIC: type $1$2\n");
+ ProcessHistory("SLOT","keysort","B","!Slot $slot$WIC: type $1$2\n") && next;
/\s+(FT1)$/ &&
- ProcessHistory("SLOT","keysort","B","!Slot $slot$WIC: type $1\n");
+ ProcessHistory("SLOT","keysort","B","!Slot $slot$WIC: type $1\n") && next;
+ # handle WICs lacking "daughter card" in the 2nd line of their
+ # show diag o/p
+ if (defined($WIC)) {
+ s/^\s+//;
+ ProcessHistory("SLOT","keysort","B","!Slot $slot$WIC: type $_");
+ }
next;
}
+ # yet another format. seen on 2600s w/ 12.1, but appears to be all
+ # 12.1, including 7200s & 3700s. Sometimes the PCB serial appears
+ # before the hardware revision.
+ if (/(pcb serial number|hardware revision)\s+:\s+(\S+)$/i) {
+ my($hw, $pn, $rev, $sn);
+ if ($1 =~ /^pcb/i) {
+ $sn = $2;
+ } else {
+ $hw = $2;
+ }
+ while (<INPUT>) {
+ tr/\015//d;
+
+ if (/0x..: /) {
+ # no effing idea why break does not work there
+ goto PerlSucks;
+ }
+ if (/hardware revision\s+:\s+(\S+)/i) { $hw = $1; }
+ if (/part number\s+:\s+(\S+)/i) { $pn = $1; }
+ if (/board revision\s+:\s+(\S+)/i) { $rev = $1; }
+ if (/pcb serial number\s+:\s+(\S+)/i) { $sn = $1; }
+ }
+PerlSucks:
+ ProcessHistory("SLOT","keysort","B","!Slot $slot$WIC: hvers $hw rev $rev\n");
+ ProcessHistory("SLOT","keysort","C","!Slot $slot$WIC: part $pn, serial $sn\n");
+ }
/revision\s+(\S+).*revision\s+(\S+)/ &&
ProcessHistory("SLOT","keysort","C","!Slot $slot$WIC: hvers $1 rev $2\n") &&
next;
@@ -760,6 +966,8 @@ sub ShowModule {
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
return(-1) if (/command authorization failed/i);
+ # the pager can not be disabled per-session on the PIX
+ s/^<-+ More -+>\s*//;
# match slot/card info line
if (/^ *(\d+)\s+(\d+)\s+(.*)\s+(\S+)\s+(\S+)\s*$/) {
@@ -781,6 +989,24 @@ sub ShowModule {
return(0);
}
+# This routine parses "show spe version".
+sub ShowSpeVersion {
+ print STDERR " In ShowSpeVersion: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if /^\s*\^\s*$/;
+ return(1) if /(Invalid input detected|Type help or )/;
+ return(-1) if (/command authorization failed/i);
+
+ ProcessHistory("MODEM","","","!Modem: $_") && next;
+ }
+ ProcessHistory("MODEM","","","!\n");
+ return(0);
+}
+
# This routine parses "show c7200" for the 7200
# This will create arrays for hw info.
sub ShowC7200 {
@@ -794,6 +1020,8 @@ sub ShowC7200 {
#return(1) if ($type !~ /^72/);
return(-1) if (/command authorization failed/i);
/^$/ && next;
+ # the pager can not be disabled per-session on the PIX
+ s/^<-+ More -+>\s*//;
if (/^(C7200 )?Midplane EEPROM:/) {
$_ = <INPUT>;
/revision\s+(\S+).*revision\s+(\S+)/;
@@ -838,6 +1066,8 @@ sub ShowVTP {
#return(1) if ($type !~ /^(2900XL|3500XL|6000)$/);
return(-1) if (/command authorization failed/i);
next if (/^Configuration last modified by/);
+ # the pager can not be disabled per-session on the PIX
+ s/^<-+ More -+>\s*//;
if (/^VTP Operating Mode\s+:\s+(Transparent|Server)/) {
$DO_SHOW_VLAN = 1;
}
@@ -858,8 +1088,13 @@ sub ShowVLAN {
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
return(1) if /(Invalid input detected|Type help or )/;
+ # newer releases (~12.1(9)) place the vlan config in the normal
+ # configuration (write term).
+ return(1) if ($type =~ /^(3550|4500|7600)$/);
#return(1) if ($type !~ /^(2900XL|3500XL|6000)$/);
return(-1) if (/command authorization failed/i);
+ # the pager can not be disabled per-session on the PIX
+ s/^<-+ More -+>\s*//;
ProcessHistory("COMMENTS","keysort","IO","!VLAN: $_");
}
ProcessHistory("COMMENTS","keysort","IO","!\n");
@@ -869,16 +1104,17 @@ sub ShowVLAN {
# This routine processes a "write term"
sub WriteTerm {
print STDERR " In WriteTerm: $_" if ($debug);
- my($lineauto) = 0;
+ my($lineauto,$comment,$linecnt) = (0,0,0);
while (<INPUT>) {
tr/\015//d;
- study;
last if(/^$prompt/);
return(-1) if (/command authorization failed/i);
# the pager can not be disabled per-session on the PIX
s/^<-+ More -+>\s*//;
/Non-Volatile memory is in use/ && return(-1); # NvRAM is locked
+ return(0) if ($found_end); # Only do this routine once
+ $linecnt++;
$lineauto = 0 if (/^[^ ]/);
# skip the crap
if (/^(##+$|(Building|Current) configuration)/i) {
@@ -898,6 +1134,16 @@ sub WriteTerm {
# block above
/^! (Last configuration|NVRAM config last)/ && next;
+ # skip consecutive comment lines to avoid oscillating extra comment
+ # line on some access servers. grrr.
+ if (/^!/) {
+ next if ($comment);
+ ProcessHistory("","","",$_);
+ $comment++;
+ next;
+ }
+ $comment = 0;
+
# Dog gone Cool matches to process the rest of the config
/^tftp-server flash / && next; # kill any tftp remains
/^ntp clock-period / && next; # kill ntp clock-period
@@ -932,6 +1178,14 @@ sub WriteTerm {
}
next;
}
+ if (/^( set session-key (in|out)bound ah \d+ )/ && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1<removed>\n");
+ next;
+ }
+ if (/^( set session-key (in|out)bound esp \d+ (authenticator|cypher) )/ && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1<removed>\n");
+ next;
+ }
if (/^(\s*)password / && $filter_pwds >= 1) {
ProcessHistory("LINE-PASS","","","!$1password <removed>\n");
next;
@@ -955,7 +1209,7 @@ sub WriteTerm {
}
if (/^\s+(domain-password|area-password) (\S+)( .*)?/
&& $filter_pwds >= 1) {
- ProcessHistory("","","","!$1 <removed>$2\n"); next;
+ ProcessHistory("","","","!$1 <removed>$3\n"); next;
}
# this is reversable, despite 'md5' in the cmd
if (/^( ip ospf message-digest-key \d+ md5) / && $filter_pwds >= 1) {
@@ -964,10 +1218,25 @@ sub WriteTerm {
if (/^((crypto )?isakmp key) \S+ / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed> $'"); next;
}
+ # filter HSRP passwords
+ if (/^(\s+standby \d authentication) / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
+ # this appears in "measurement/sla" images
+ if (/^(\s+key-string \d?)/ && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
+ if (/^( l2tp tunnel \S+ password)/ && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
# i am told these are plain-text on the PIX
if (/^(vpdn username \S+ password)/ && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
+ if (/^( cable shared-secret ) / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n");
+ next;
+ }
/fair-queue individual-limit/ && next;
# sort ip explicit-paths.
if (/^ip explicit-path name (\S+)/) {
@@ -1057,10 +1326,14 @@ sub WriteTerm {
ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next;
}
}
- # order/prune tacacs/radius server statements
+ # prune tacacs/radius server keys
if (/^(tacacs-server|radius-server) key / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 key <removed>\n"); next;
}
+ if (/^((tacacs-server|radius-server) host \S+ key) / &&
+ $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
# order clns host statements
/^clns host \S+ (\S+)/ &&
ProcessHistory("CLNS","keysort","$1","$_") && next;
@@ -1076,9 +1349,9 @@ sub WriteTerm {
ProcessHistory("NTP","keysort",$sortkey,"$_");
next;
}
- # order ip host line statements
- /^ip host line(\d+)/ &&
- ProcessHistory("IPHOST","numsort","$1","$_") && next;
+ # order ip host statements
+ /^ip host (\S+) / &&
+ ProcessHistory("IPHOST","keysort","$1","$_") && next;
# order ip nat source static statements
/^ip nat (\S+) source static (\S+)/ &&
ProcessHistory("IP NAT $1","ipsort","$2","$_") && next;
@@ -1105,6 +1378,14 @@ sub WriteTerm {
return(1);
}
}
+ # The ContentEngine lacks a definitive "end of config" marker. If we
+ # know that it is a CE and we have seen at least 5 lines of write term
+ # o/p, we can be reasonably sure that we got the config.
+ if ($type =~ /^CE$/ && $linecnt > 5) {
+ $found_end = 1;
+ return(1);
+ }
+
return(0);
}
@@ -1114,8 +1395,11 @@ sub DoNothing {print STDOUT;}
# Main
%commands=(
'show version' => "ShowVersion",
+ 'show redundancy secondary' => "ShowRedundancy",
+ 'show idprom backplane', => "ShowIDprom",
'show install active' => "ShowInstallActive",
'show env all' => "ShowEnv",
+ 'show rsp chassis-info',=> "ShowRSP",
'show gsr chassis' => "ShowGSR",
'show boot' => "ShowBoot",
'show bootvar' => "ShowBoot",
@@ -1131,22 +1415,44 @@ sub DoNothing {print STDOUT;}
'dir /all disk2:' => "DirSlotN",
"dir /all sup-bootflash:"=> "DirSlotN", # cat 6500-ios
"dir /all sup-microcode:"=> "DirSlotN", # cat 6500-ios
+ 'dir /all slavenvram:' => "DirSlotN",
+ 'dir /all slavebootflash:' => "DirSlotN",
+ 'dir /all slaveslot0:' => "DirSlotN",
+ 'dir /all slavedisk0:' => "DirSlotN",
+ 'dir /all slaveslot1:' => "DirSlotN",
+ 'dir /all slavedisk1:' => "DirSlotN",
+ 'dir /all slaveslot2:' => "DirSlotN",
+ 'dir /all slavedisk2:' => "DirSlotN",
+ "dir /all slavesup-bootflash:"=> "DirSlotN", # cat 7609
+ 'dir /all sec-nvram:' => "DirSlotN",
+ 'dir /all sec-bootflash:' => "DirSlotN",
+ 'dir /all sec-slot0:' => "DirSlotN",
+ 'dir /all sec-disk0:' => "DirSlotN",
+ 'dir /all sec-slot1:' => "DirSlotN",
+ 'dir /all sec-disk1:' => "DirSlotN",
+ 'dir /all sec-slot2:' => "DirSlotN",
+ 'dir /all sec-disk2:' => "DirSlotN",
'show controllers' => "ShowContAll",
'show controllers cbus' => "ShowContCbus",
'show diagbus' => "ShowDiagbus",
'show diag' => "ShowDiag",
'show module' => "ShowModule", # cat 6500-ios
+ 'show spe version' => "ShowSpeVersion",
'show c7200' => "ShowC7200",
'show vtp status' => "ShowVTP",
'show vlan' => "ShowVLAN",
+ 'show running-config' => "WriteTerm",
'write term' => "WriteTerm"
);
# keys() doesnt return things in the order entered and the order of the
# cmds is important (show version first and write term last). pita
@commands=(
"show version",
+ "show redundancy secondary",
+ "show idprom backplane",
"show install active",
"show env all",
+ "show rsp chassis-info",
"show gsr chassis",
"show boot",
"show bootvar",
@@ -1162,14 +1468,33 @@ sub DoNothing {print STDOUT;}
"dir /all disk2:",
"dir /all sup-bootflash:",
"dir /all sup-microcode:",
+ "dir /all slavenvram:",
+ "dir /all slavebootflash:",
+ "dir /all slaveslot0:",
+ "dir /all slavedisk0:",
+ "dir /all slaveslot1:",
+ "dir /all slavedisk1:",
+ "dir /all slaveslot2:",
+ "dir /all slavedisk2:",
+ "dir /all slavesup-bootflash:",
+ "dir /all sec-nvram:",
+ "dir /all sec-bootflash:",
+ "dir /all sec-slot0:",
+ "dir /all sec-disk0:",
+ "dir /all sec-slot1:",
+ "dir /all sec-disk1:",
+ "dir /all sec-slot2:",
+ "dir /all sec-disk2:",
"show controllers",
"show controllers cbus",
"show diagbus",
"show diag",
"show module",
+ "show spe version",
"show c7200",
"show vtp status",
"show vlan",
+ "show running-config",
"write term"
);
$cisco_cmds=join(";",@commands);
@@ -1196,7 +1521,7 @@ if ($file) {
}
# determine password filtering mode
-if ($ENV{"FILTER_PWDS"} =~ /no/i) {
+if ($ENV{"FILTER_PWDS"} =~ /no/i) {
$filter_pwds = 0;
} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
$filter_pwds = 2;
@@ -1210,7 +1535,7 @@ ProcessHistory("COMMENTS","keysort","F0","!\n");
ProcessHistory("COMMENTS","keysort","G0","!\n");
TOP: while(<INPUT>) {
tr/\015//d;
- if (/\#\s?exit$/) {
+ if (/[>#]\s?exit$/) {
$clean_run=1;
last;
}
@@ -1222,7 +1547,11 @@ TOP: while(<INPUT>) {
}
while (/#\s*($cmds_regexp)\s*$/) {
$cmd = $1;
- if (!defined($prompt)) {$prompt = ($_ =~ /^([^#]+#)/)[0]; }
+ if (!defined($prompt)) {
+ $prompt = ($_ =~ /^([^#]+#)/)[0];
+ $prompt =~ s/([][}{)(\\])/\\$1/g;
+ print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
+ }
print STDERR ("HIT COMMAND:$_") if ($debug);
if (! defined($commands{$cmd})) {
print STDERR "$host: found unexpected command - \"$cmd\"\n";
diff --git a/bin/rename.in b/bin/rename.in
deleted file mode 100755
index 8c3a111..0000000
--- a/bin/rename.in
+++ /dev/null
@@ -1,113 +0,0 @@
-#!@PERLV_PATH@
-'di';
-'ig00';
-#
-# Revision 3.0.1.2 90/08/09 03:17:57 lwall
-# patch19: added man page for relink and rename
-#
-
-if ($ARGV[0] eq '-i') {
- shift;
- if (open(TTYIN, "</dev/tty") && open(TTYOUT,">/dev/tty")) {
- $inspect++;
- select((select(TTYOUT),$|=1)[0]);
- }
-}
-($op = shift) || die "Usage: rename [-i] perlexpr [filenames]\n";
-if (!@ARGV) {
- @ARGV = <STDIN>;
- chop(@ARGV);
-}
-for (@ARGV) {
- unless (-e) {
- print STDERR "$0: $_: $!\n";
- $status = 1;
- next;
- }
- $was = $_;
- eval $op;
- die $@ if $@;
- if ($was ne $_) {
- if ($inspect && -e) {
- print TTYOUT "remove $_? ";
- next unless <TTYIN> =~ /^y/i;
- }
- unless (rename($was, $_)) {
- print STDERR "$0: can't rename $was to $_: $!\n";
- $status = 1;
- }
- }
-}
-exit $status;
-##############################################################################
-__END__
- # These next few lines are legal in both Perl and nroff.
-
-.00; # finish .ig
-
-'di \" finish diversion--previous line must be blank
-.nr nl 0-1 \" fake up transition to first page again
-.nr % 0 \" start at page 1
-';<<'.ex'; #__END__ ############# From here on it's a standard manual page ############
-.TH RENAME 1 "July 30, 1990"
-.AT 3
-.SH NAME
-rename \- renames multiple files
-.SH SYNOPSIS
-.B rename [-i] perlexpr [files]
-.SH DESCRIPTION
-.I Rename
-renames the filenames supplied according to the rule specified as the
-first argument.
-The argument is a Perl expression which is expected to modify the $_
-string in Perl for at least some of the filenames specified.
-If a given filename is not modified by the expression, it will not be
-renamed.
-If no filenames are given on the command line, filenames will be read
-via standard input.
-.PP
-The
-.B \-i
-flag will prompt to remove the old file first if it exists. This
-flag will be ignored if there is no tty.
-.PP
-For example, to rename all files matching *.bak to strip the extension,
-you might say
-.nf
-
- rename 's/\e.bak$//' *.bak
-
-.fi
-To translate uppercase names to lower, you'd use
-.nf
-
- rename 'y/A-Z/a-z/' *
-
-.fi
-To do the same thing but leave Makefiles unharmed:
-.nf
-
- rename 'y/A-Z/a-z/ unless /^Make/' *
-
-.fi
-To rename all the *.f files to *.BAD, you'd use
-.nf
-
- rename 's/\e.f$/.BAD/' *.f
-
-.SH ENVIRONMENT
-.fi
-No environment variables are used.
-.SH FILES
-.SH AUTHOR
-Larry Wall
-.SH "SEE ALSO"
-mv(1)
-.br
-perl(1)
-.SH DIAGNOSTICS
-If you give an invalid Perl expression you'll get a syntax error.
-.SH BUGS
-.I Rename
-does not check for the existence of target filenames, so use with care.
-.ex
diff --git a/bin/rivlogin.in b/bin/rivlogin.in
new file mode 100644
index 0000000..12554d5
--- /dev/null
+++ b/bin/rivlogin.in
@@ -0,0 +1,1005 @@
+#! @EXPECT_PATH@ --
+##
+## $Id: rivlogin.in,v 1.15 2004/01/11 05:39:15 heas Exp $
+##
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## All rights reserved.
+##
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
+##
+## 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.
+##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
+##
+#
+# The login expect scripts were based on Erik Sherk's gwtn, by permission.
+#
+# rivlogin - Riverstone (and Enterasys SSR) login
+#
+# Based upon rscmd (see nmops.org)
+# rscmd - Riverstone Networks Automated login
+# by Mike MacFaden, Kiran Addepalli
+# Riverstone Networks, 2000
+#
+# Returned to the RANCID crowd by andrew fort
+
+# Global vars section
+
+# program diagnostics
+set verbose 0
+set success 1
+set config 0
+
+# in seconds to wait for data back from device
+set timeout 10
+set tempfile "/tmp/rivlogin.[exec date]"
+
+# cli command prompt
+set my_prompt ">"
+set enable_prompt "\#"
+
+set default_user ""
+set output_file ""
+set conf_prompt "*\(config\)# "
+set logging 0
+set config_mode 0
+
+# Password file for routers to access
+set password_file $env(HOME)/.cloginrc
+
+# If no -c or -s specified, just automate router login ala rsh
+set do_command 0
+set do_script 0
+set log_user 0
+
+# The default CLI mode to login to is "enable" mode
+set enable 1
+
+# The default is to look in the password file to find the passwords. This
+# tracks if we receive them on the command line.
+set do_passwd 1
+set do_enapasswd 1
+
+# cmd usage
+set usage "Error: Usage: $argv0 \[-noenable\] \
+\[-f cloginrc-file\] \[-c command\] \[-Evar=x\] \[-s script-file\] \
+\[-x command-file\] \[-t timeout\] \[-o output-file\] \
+router \[router...\]\n"
+
+# Procedures Section
+
+
+#
+# Sets Xterm title if interactive...if its an xterm and the user cares
+#
+
+proc label { host } {
+
+ global env
+
+ # if CLOGIN has an 'x' in it, don't set the xterm name/banner
+ if [info exists env(CLOGIN)] {
+ if {[string first "x" $env(CLOGIN)] != -1} { return }
+ }
+
+ if [info exists env(TERM)] {
+ if [regexp \^(xterm|vs) $env(TERM) ignore ] {
+ send_user "\033]1;[lindex [split $host "."] 0]\a"
+ send_user "\033]2;$host\a"
+ }
+ }
+}
+
+
+# This is a helper function to make the password file easier to
+# maintain.
+# NOTES: Using this the password file has the form:
+# add password sl* pete cow
+# add password at* steve
+# add password * hanky-pie
+
+proc add { var args } {
+
+ global $var
+ lappend $var $args
+}
+
+# Loads the password file. Note that as this file is tcl, and that
+# it is sourced, the user better know what to put in there, as it
+# could install more than just password info... I will assume however,
+# that a "bad guy" could just as easy put such code in the clogin
+# script, so I will leave .cloginrc as just an extention of that script
+
+proc source_password_file { } {
+
+ global env password_file read_password_file
+
+ if { [info exists read_password_file] } {
+ return 1
+ }
+
+ if { [info exists password_file] == 0 } {
+ set password_file $env(HOME)/.cloginrc
+ }
+
+ set read_password_file 1
+ file stat $password_file fileinfo
+
+ if { [expr ($fileinfo(mode) & 007)] != 0000 } {
+ puts "ERROR: $password_file must not be group or world readable and writable\n"
+ return 1
+ }
+
+ source $password_file
+}
+
+# pre: var is x, router is y
+# post: return routerr entry from database else null string
+
+proc find { var router } {
+
+ if {[ source_password_file ] == 0 } {
+ return {}
+ }
+
+ upvar $var list
+ if { [info exists list] } {
+ foreach line $list {
+ if { [string match [lindex $line 0] $router ] } {
+ return [lrange $line 1 end]
+ }
+ }
+ }
+ return {}
+}
+
+
+# pre: login completed ok
+# post: terminate login session by closing tcp connection
+
+proc auto_exit { } {
+
+ global telnet_id
+
+ if { $verbose == 1 } {
+ puts "DEBUG: auto_exit closing connection to pid $telnet_id\n"
+ }
+ close -i telnet_id
+}
+
+# perform login basic to a router
+# pre: args are valid, router is reachable via network
+# post: return 0 on successful login, else 1
+#
+# NOTE: a number of globals are setup: my_prompt, telnet_id are key
+# and paging of cli output is disabled
+
+proc login { router user userpswd passwd enapasswd } {
+
+ global login_array
+ global telnet_id
+ global expect_out
+ global spawn_id
+ global verbose
+ global config verbose my_prompt
+
+ if { $verbose == 1 } {
+ puts "DEBUG: login router = $router"
+ puts "DEBUG: login username = $user"
+ puts "DEBUG: login userpasswd = $userpswd"
+ puts "DEBUG: login passwd = $passwd"
+ puts "DEBUG: login enapasswd = $enapasswd"
+ }
+
+ spawn -noecho telnet $router
+ set telnet_id $spawn_id
+
+ if { $telnet_id == 0 } {
+ puts "ERROR: login: spawn telnet session failed.\n"
+ return 1
+ }
+
+ # wait for initial 'Press RETURN to...' response
+ sleep 0.3
+
+ expect "*"
+ send "\r"
+
+ # If password fails 3 times then expect again
+ set pass_attempt 0
+
+ expect {
+
+ -re ".*> " { }
+
+ "Password:" {
+ incr pass_attempt
+ send "$passwd\r"
+ exp_continue
+ }
+
+ "Username: " {
+
+ set pattempt 0
+
+ send "$user\r"
+ expect {
+
+ "Password: " {
+
+ incr pattempt
+ if {$pattempt == 1} {
+ send "$userpswd\r";
+ } else {
+ send "$enapasswd\r";
+ }
+ exp_continue
+ }
+
+ -re ".*> " { exp_continue;}
+ }
+ }
+
+ "%TELNETD-W-BADPASSWD" {
+ puts "ERROR: bad userid or password to telnet."
+ return 1
+ }
+ "%CONS-W-AUTH_PASSWD" {
+ exp_continue
+ }
+
+ "% Authentication failed." {
+ puts "ERROR: bad userid or password to telnet."
+ return 1
+ }
+
+
+ "Authentication Failed:" {
+ puts "ERROR: bad userid or password to radius/tacacs+"
+ return 1
+ }
+
+ "Connection closed *" {
+ if {$pass_attempt == 3} {
+ puts "ERROR: Maximum attempts for password reached. Check password. Exiting.";
+ puts $expect_out(0,string);
+ return 1
+ }
+ }
+
+ timeout {
+ puts "ERROR: Timeout on login. Exiting.";
+ return 1
+ }
+
+ eof {
+ puts "ERROR: device closed telnet connection during login"
+ return 1
+ }
+ }
+
+ # save my_prompt for later use
+ send "\r"
+ expect -re ".*> "
+ set abc "$expect_out(buffer)"
+ set my_prompt "[lindex $abc 0]"
+ regexp {(.*[^>])} $my_prompt my
+
+ return 0;
+}
+
+
+# pre: login completed ok
+# post: turn off paging of commands
+
+proc disable_cli_paging { } {
+ global my_prompt
+
+ send "cli set terminal rows 0\r"
+
+ expect {
+ "$my_prompt" {return 0 }
+ }
+ return 1
+}
+
+# pre: login returned 0, prompt at top level
+# post: turn off command completion return 0
+# on error, return 1
+
+proc disable_cmd_autocomplete { } {
+ global my_prompt
+
+ send "cli set command completion off\r"
+ expect {
+
+ $my_prompt { }
+
+ timeout {
+ puts "ERROR:disable_cmd_autocomplete(TIMEOUT)";
+ return 0;
+ }
+
+ }
+
+ return 0
+}
+
+# pre: login returned 0, do_enable returned 0, cli is in enable or config mode
+# post: issues logout cli to device, returns 0
+
+proc logout { prompt } {
+ global config_mode enable_prompt
+
+ # in case of not being at root cmd...
+ # verify top level prompt state, move to it if necessary
+
+ if { $config_mode == 1 } {
+
+ send "exit\r"
+
+ expect {
+ "Do you want*" {
+ send "no\r"
+ }
+
+ "$enable_prompt" { }
+
+ timeout { puts "ERROR: logout: timeout from config mode\n" }
+ eof { puts "ERROR: device dropped connection\n" }
+ }
+ set config_mode 0
+ }
+
+ send "logout\r"
+ expect {
+
+ "Are you sure*" {
+ send "yes\r"
+ return 0
+ }
+ }
+}
+
+# pre: current mode allows transition to enable mode
+# post: enable mode entered, my_prompt updated, return 0 else 1
+
+proc do_enable { enauser enapasswd userpswd } {
+ global expect_out verbose
+ global my_prompt enable_prompt
+ set enable_prompt [ string trimright $my_prompt ">" ]
+ set enable_prompt $enable_prompt\#
+
+ if { $verbose == 1 } {
+ puts "DEBUG: do_enable: my_prompt = $my_prompt ena_prompt = $enable_prompt"
+ }
+
+ send "enable\r"
+
+ expect {
+ Username: { send "$enauser\r"; exp_continue }
+ Password: { send "$userpswd\r"; exp_continue }
+
+ "$my_prompt" {
+ puts "ERROR: do_enable failed to gain enable mode."
+ return 1
+ }
+
+ "CONS-W-AUTH_PASSWD" { send "$enapasswd\r"; }
+
+ "$enable_prompt " { }
+ "%SYS-W-NOPASSWD*" { }
+
+ "Authentication Failed: Access Denied" {
+ puts "ERROR: Bad user or password for enable mode."
+ return 1
+ }
+ }
+
+ set my_prompt $enable_prompt
+ return 0
+}
+
+# pre: current mode allows transition to enable mode
+# post: enable mode entered, my_prompt updated, return 0 else 1
+
+proc do_configure { } {
+ global expect_out verbose config_mode
+ global my_prompt
+ set config_prompt [ string trimright $my_prompt "\#" ]
+ set config_prompt $config_prompt\(config\)\#
+
+ if { $verbose == 1 } {
+ puts "DEBUG: do_config: my_prompt = $my_prompt cfg_prompt = $config_prompt"
+ }
+
+ send "configure\r"
+ expect {
+ "$config_prompt " { }
+ "$my_prompt" {
+ }
+
+ eof { return 1}
+ timeout { return 1}
+ }
+
+ set config_mode 1
+ set my_prompt $config_prompt
+ return 0
+}
+
+# track sent/received from device to output_file
+# pre: outut_file is valid filename w/write access
+# post: logfile open, global var logging == 1, return 0 , else 1
+
+proc start_logfile { output_file } {
+ global logging
+
+ if { [ string length $output_file ] != 0 } {
+ set rc [ catch {
+ log_file -noappend $output_file
+ } errMsg ]
+
+ if { $rc != 0 } {
+ puts "ERROR: open file $output_file for write access failed. $errMsg\n"
+ return 1
+ }
+ set logging 1
+ }
+
+ return 0
+}
+
+proc run_commands { prompt cmdstring } {
+ global sendstring
+
+ set commands [split $cmdstring \;]
+ set num_commands [llength $cmdstring]
+
+ for {set i 0} {$i < $num_commands} { incr i} {
+ regsub -- {[ ]*([^\.]*)} [subst -nocommands [lindex $commands $i]] {\1} sendstring
+
+ if {[ run_single_command $prompt $sendstring ] == 1} {
+ puts "ERROR: command '$sendstring' not processed by device. Check previous error messages."
+ return 1
+ }
+ }
+ return 0
+}
+
+
+# Run commands given on the command line
+# pre: prompt is current system cli prompt, cmdstring is command to execute
+# post: return 0 on success else 1
+# NOTE: output from router ends up in output_file if specified
+# expect internal input buffer is reset to "" after each command
+
+proc run_single_command { prompt cmdstring } {
+ global verbose
+ set rc 0
+ set seen_prompt 0
+ set seen_timeout 0
+ set need_ays 0
+ set delay 0
+
+ if {$verbose == 1} {
+ puts "DEBUG: run_commands: prompt=$prompt \"$cmdstring\" "
+ }
+
+ # ays == "are you sure" - must send back yes
+ if { [string compare $cmdstring "save startup" ] == 0 } {
+ set need_ays 1
+ set delay 1
+ if {$verbose == 1} {
+ puts "DEBUG: save startup cmd seen, set need_ays = 1"
+ }
+ }
+
+ # TODO: add case for copy command to startup, also prompts for ok
+
+ # TODO: if we see config command: system set name note it
+ # if we see a save active, then update system prompts as well
+
+ send "$cmdstring\r"
+
+ if { $delay == 1} {
+ sleep 1
+ }
+
+ expect {
+
+ "%CLI-E-IVCMD*" {
+ puts "ERROR: run_commands(command rejected by device)\n"
+ set rc 1
+ }
+
+ "%CLI-E-FACUNKNWN*" {
+ puts "ERROR: run_commands(command rejected by device)\n"
+ set rc 1
+ }
+
+ "%SYS-I-ADDFAILED*" {
+ puts "ERROR: run_commands(command rejected by device)\n"
+ set rc 1
+ }
+ "%TFTP-E-REMOTE,*" {
+ puts "ERROR: run_commands(command rejected by device)\n"
+ set rc 1
+ }
+
+ "%SYS-E-PRIMARY_NO_SUCH_IMAGE*" {
+ puts "ERROR: run_commands(command rejected by device)\n"
+ set rc 1
+ }
+
+ "want to overwrite " {
+ send "yes\r"
+ if {$verbose == 1} {
+ puts "DEBUG: got overwrite question, set need_ays to 0"
+ }
+ set need_ays 0
+ }
+
+
+ "%CONFIG-E-DUPLICATE,*" {
+ }
+
+ "$prompt" {
+ if { $seen_prompt == 0 } {
+ set seen_prompt 1
+ }
+
+ if {$verbose == 1} {
+ puts "DEBUG: saw double prompt, exiting expect loop\n"
+ }
+
+ if { $need_ays == 1 } {
+ exp_continue
+ }
+ }
+
+ -re ".* More: m,<space> --- Quit: q --- One line: <return> ---" {
+ send "q"
+ exp_continue
+ }
+
+
+ timeout {
+ if {$verbose == 1} {
+ puts "DEBUG: timeout occured for the $seen_time time\n"
+ }
+
+ if { $seen_timeout == 0 } {
+ set seen_timeout 1
+ send "\r\r"
+ exp_continue
+ }
+
+ puts "ERROR:run_commands(TIMEOUT)"
+ set rc 1
+ }
+
+ eof {
+ puts "ERROR:run_commands(connection closed by device)\n"
+ set rc 1
+ }
+
+ "\n" { exp_continue }
+ }
+
+ # clear input buffer of any remaining data
+ expect "*"
+ return $rc
+}
+
+
+# pre: RSTONE_USER env var is set
+# post: update global "default_user" to this string
+
+proc init_userid { } {
+ global default_user
+
+ if {[ info exists env(RSTONE_USER) ] } {
+ set default_user $env(RSTONE_USER)
+ } else {
+ # This uses "id" which I think is portable. At least it has existed
+ # (without options) on all machines/OSes I've been on recently -
+ # unlike whoami or id -nu.
+ regexp {\(([^)]*)} [exec id] junk default_user
+ }
+}
+
+proc source_script_file { filename } {
+ global my_prompt
+
+ expect -re "$my_prompt" {}
+
+ source $filename
+
+}
+
+
+# pre: login completed ok, filename contains set of cli commands one per line
+# post: each command is extracted from filename and sent to device
+# return 0 on success, return 1 on error
+# NOTE: for scripts that begin with "configure", change the mode to configure
+# before executing the following commands
+
+proc process_script_file { filename } {
+
+ global my_prompt verbose
+ set rc 0
+ set ifile ""
+
+ set rc [ catch {
+ set ifile [ open $filename r]
+ } errMsg ]
+
+ if { $rc != 0 } {
+ puts "ERROR: process_script_file: open script file $filename for read access failed. $errMsg\n"
+ return 1
+ }
+
+ set line_cnt 0
+
+ while { [eof $ifile] != 1 } {
+
+ set bytes [ gets $ifile cmd ]
+ incr line_cnt
+
+ if { $bytes < 0 } {
+ break
+ } elseif { $bytes == 0 } {
+ continue
+ }
+
+ if { $verbose == 1 } {
+ puts "DEBUG: line:$line_cnt cmd = $cmd\n"
+ }
+
+ # skip comments in script files
+ if { [regexp "^\#" $cmd] != 1 } {
+
+ # puts "$cmd rc = [string compare $cmd "configure" ]\n"
+
+ if { [string compare $cmd "configure" ] == 0 } {
+
+ do_configure
+
+ } else {
+ if {[ run_commands $my_prompt $cmd ] == 1} {
+ puts "ERROR: line $line_cnt in $filename not processed by device. Check previous error msgs."
+ set rc 1
+ break
+ }
+ }
+ }
+ }
+
+ close $ifile
+ return $rc
+}
+
+
+
+# pre: filename is valid file
+# post: remove extended ascii sequences and other cruft
+# and prepend a header: rscmd: ip-addr : date
+# TODO: should watch all file commands more closely
+
+proc strip_log { filename router } {
+
+ global tempfile
+
+ set rc [ catch {
+ set ifile [ open $filename r]
+ } errMsg ]
+
+ if { $rc != 0 } {
+ puts "ERROR: strip_log: open script file $filename for read access failed. $errMsg\n"
+ return 1
+ }
+ set rc [ catch {
+ set ofile [ open $tempfile w]
+ } errMsg ]
+
+ if { $rc != 0 } {
+ puts "ERROR: strip_log: open temp file $tempfile for write access failed. $errMsg\n"
+ return 1
+ }
+
+ set nl 0
+
+ puts $ofile "rscmd: $router : [exec date]"
+
+ while { [eof $ifile] != 1 } {
+
+ set bytes [ gets $ifile cmd ]
+ if { $bytes <= 0 } {
+ break
+ }
+ incr nl
+ if { $nl <= 2 } {
+ continue
+ }
+
+ regsub -all -- "\r" $cmd "" newcmd
+ puts $ofile $newcmd
+ }
+
+ close $ifile
+ close $ofile
+ set rc 0
+ file copy -force $tempfile $filename
+ file delete $tempfile
+ return $rc
+}
+
+#
+# main section
+#
+
+
+if { $verbose == 1 } {
+ puts "\n\nrscmd: Version 1.1 started on [exec date]"
+ puts "[exec uname -a]"
+ puts "Expect Version: [exp_version]\n"
+}
+
+# send input like in a fast and consistent human style
+set send_human {.1 .3 1 .05 2}
+
+# initialize default_user variable
+init_userid
+
+# Parse Command Line
+
+for {set idx 0} {$idx < $argc} {incr idx} {
+
+ set arg [lindex $argv $idx]
+
+ switch -glob -- $arg {
+
+ -c* -
+ -C* {
+ if {! [ regexp .\[cC\](.+) $arg ignore command]} {
+ incr idx
+ set command [ lindex $argv $idx ]
+ }
+ 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
+ }
+ # Expect script to run
+ } -s* -
+ -S* {
+ if {! [ regexp .\[sS\](.+) $arg ignore sfile]} {
+ incr idx
+ set sfile [ lindex $argv $idx ]
+ }
+
+ if { ! [ file exists $sfile ] } {
+ puts "ERROR: invalid argument script file \"$sfile\" does not exist.\n"
+ exit 1
+ }
+ if { ! [ file readable $sfile ] } {
+ puts "ERROR: invalid argument script file \"$sfile\" permissions disallow read access.\n"
+ exit 1
+ }
+
+ set do_script 1
+ # Command file
+ } -x* -
+ -X {
+ if {! [ regexp .\[xX\](.+) $arg ignore cmd_file]} {
+ incr idx
+ set cmd_file [ lindex $argv $idx ]
+ }
+ if [ catch {set cmd_fd [open $cmd_file r]} reason ] {
+ send_user "\nError: $reason\n"
+ exit 1
+ }
+ set cmd_text [read $cmd_fd]
+ close $cmd_fd
+ set command [join [split $cmd_text \n] \;]
+ set do_command 1
+ } -f* -
+ -F* {
+ if {! [ regexp .\[fF\](.+) $arg ignore password_file]} {
+ incr idx
+ set password_file [ lindex $argv $idx ]
+ }
+
+ } -o* -
+ -O* {
+ if {! [ regexp .\[fF\](.+) $arg ignore password_file]} {
+ incr idx
+ set output_file [ lindex $argv $idx ]
+ if { $verbose == 1 } {
+ puts "DEBUG: output file: $output_file"
+ }
+ }
+
+ } -t* -
+ -T* {
+ incr idx
+ set timeout [ lindex $argv $idx ]
+
+ } -noenable {
+ set enable 0
+ } -* {
+ puts "ERROR:unkown argument passed: $arg\n"
+ puts $usage
+ exit 1
+
+ } default {
+ break
+ }
+ }
+}
+
+# Verify at least one router is specified
+#
+if { $idx == $argc } {
+ puts "\n$usage"
+ exit 1
+}
+
+# main loop
+
+foreach router [lrange $argv $idx end] {
+set router [string tolower $router]
+
+# Figure out passwords
+if {$verbose == 1} {
+ puts "DEBUG: do_passwd = $do_passwd\n"
+ puts "DEBUG: do_enablepasswd = $do_enapasswd\n"
+}
+
+if { $do_passwd || $do_enapasswd } {
+ set pswd [find password $router]
+ if { [llength $pswd] == 0 } {
+ puts "ERROR: - no password for $router in $password_file.\n"
+ exit 1
+ }
+ if { $do_enapasswd && [llength $pswd] < 2 } {
+ puts "ERROR: no enable password found for $router in $password_file."
+ exit 1
+ }
+
+ set passwd [join [lindex $pswd 0] ""]
+ set enapasswd [join [lindex $pswd 1] ""]
+}
+
+
+# Figure out user to login with if necessary
+
+if {[info exists username]} {
+ # command line username
+ set user $username
+} else {
+ set user [join [find user $router] ""]
+ if { "$user" == "" } { set user $default_user }
+}
+
+# Figure out username's password
+
+if {[info exists userpasswd]} {
+ # command line username
+ set userpswd $userpasswd
+} else {
+ set userpswd [join [find userpassword $router] ""]
+ if { "$userpswd" == "" } { set userpswd $passwd }
+}
+
+# Figure out enable username
+
+if {[info exists enausername]} {
+ # command line enausername
+ set enauser $enausername
+} else {
+ set enauser [join [find enauser $router] ""]
+ if { "$enauser" == "" } { set enauser $user }
+}
+
+# Login to the router, set my_prompt to router's cmd prompt
+
+if {[login $router $user $userpswd $passwd $enapasswd ]} {
+ if { $verbose == 1 } {
+ puts "DEBUG: login to $router failed\n"
+ }
+ exit 1
+}
+
+if {$verbose == 1 } {
+ puts "DEBUG: login completed ok\n"
+}
+
+if { $enable == 1 } {
+
+ if { [do_enable $enauser $enapasswd $userpswd] == 1} {
+ if { $verbose == 1 } {
+ puts "DEBUG: switch to enable mode on $router failed\n"
+ }
+ exit 1
+ }
+}
+
+# run in one of three modes
+
+if { $do_command } {
+
+ disable_cmd_autocomplete
+ disable_cli_paging
+
+ if {[ start_logfile $output_file] != 0 } {
+ exit 1
+ }
+
+ if {[ run_commands $my_prompt $command ]} {
+
+ log_file
+ exit 1
+
+ } else {
+
+ logout $my_prompt
+
+ }
+
+} elseif { $do_script } {
+
+ disable_cmd_autocomplete
+ disable_cli_paging
+
+ if {[ start_logfile $output_file] != 0 } {
+ exit 1
+ }
+
+ #if { [process_script_file $sfile] == 1} {
+# puts "DEBUG: logfile $output_file closed on error\n"
+# logout $my_prompt
+# exit 1
+# }
+
+ source_script_file $sfile
+
+ logout $my_prompt
+
+} else {
+
+ label $router
+ log_user 1
+
+ if {[ start_logfile $output_file] != 0 } {
+ exit 1
+ }
+ interact
+ log_file
+}
+
+if { $verbose == 1 } {
+ puts "DEBUG: exiting normally.\n"
+}
+
+if { $logging == 1} {
+ log_file
+ strip_log $output_file $router
+}
+}
+
+# puts "\n"
+exit 0
diff --git a/bin/rivrancid.in b/bin/rivrancid.in
new file mode 100644
index 0000000..8b9ae03
--- /dev/null
+++ b/bin/rivrancid.in
@@ -0,0 +1,344 @@
+#! @PERLV_PATH@
+##
+## $Id: rivrancid.in,v 1.9 2004/01/11 03:49:13 heas Exp $
+##
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## All rights reserved.
+##
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
+##
+## 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.
+##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
+##
+#
+# Amazingly hacked version of Hank's rancid - this one tries to
+# deal with Cabletron, Riverstone and Enterasys routers/switches
+#
+# 10/23/2002 -- Initial changes for Riverstone/Cabletron support
+# Jim Meehan -- jmeehan@vpizza.org
+#
+# RANCID - Really Awesome New Cisco confIg Differ
+#
+# usage: rivrancid [-d] [-l] [-f filename | $host]
+#
+use Getopt::Std;
+getopts('dfl');
+$log = $opt_l;
+$debug = $opt_d;
+$file = $opt_f;
+$host = $ARGV[0];
+$clean_run = 0;
+$found_end = 0;
+$timeo = 90; # flogin timeout in seconds
+
+my(%filter_pwds); # password filtering mode
+
+# 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 "system show version"
+sub ShowVersion {
+ my($slot);
+
+ print STDERR " In ShowVersion: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ next if /^\s*$/;
+ last if(/^$prompt/);
+
+ ProcessHistory("VERSION","","","!SW: $_");
+ }
+ ProcessHistory("VERSION","","","!\n");
+ return(0);
+}
+
+# This routine parses "system show hardware"
+sub ShowHardware {
+ print STDERR " In ShowHardware: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ ProcessHistory("HARDWARE","","","!HW: $_");
+ }
+ ProcessHistory("","","","!\n");
+ return(0);
+}
+
+# This routine parses "system show uptime"
+sub ShowUptime {
+ print STDERR " In ShowUptime: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+ next if /^\s*$/;
+ next if /System up/;
+ ProcessHistory("UPTIME","","","!UPTIME: $_");
+ }
+ ProcessHistory("","","","!\n");
+ return;
+}
+
+# This routine processes a "system show active"
+sub ShowActive {
+ print STDERR " In ShowActive: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+
+ # Remove leading whitespace and/or line numbers
+ s/^\s*(\d+\D: )*//;
+
+ # Riverstone/Cabletron doesn't have an "end" line, so
+ # we need to set $clean_run here
+ if (/^$prompt/) {
+ $clean_run = 1;
+ last;
+ }
+
+ next if (/Running system configuration/);
+
+ # filter out any RCS/CVS tags to avoid confusing local CVS storage
+ s/\$(Revision|Id):/ $1:/;
+
+ if (/^(.*hashed-password \S+)/ && $filter_pwds == 2) {
+ ProcessHistory("","","","! $1 <removed>\n");
+ next;
+ }
+
+ if (/^(snmp set community )\S+/ && defined($ENV{'NOCOMMSTR'})) {
+ ProcessHistory("","","","! $1<removed>$'");
+ next;
+ }
+
+ ProcessHistory("","","","$_");
+ }
+ return;
+}
+
+# dummy function
+sub DoNothing {print STDOUT;}
+
+# Main
+%commands=(
+ 'system show uptime' => "ShowUptime",
+ 'system show version' => "ShowVersion",
+ 'system show hardware' => "ShowHardware",
+ 'system show active-config' => "ShowActive"
+);
+
+# keys() doesnt return things in the order entered and the order of the
+# cmds is important. pita
+
+@commands=(
+ "system show uptime",
+ "system show version",
+ "system show hardware",
+ "system show active-config"
+);
+
+$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 rivlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug);
+ print STDOUT "executing rivlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log);
+ if (defined($ENV{NOPIPE})) {
+ system "rivlogin -t $timeo -c \"$cisco_cmds\" $host </dev/null > $host.raw 2>&1" || die "rivlogin failed for $host: $!\n";
+ open(INPUT, "< $host.raw") || die "rivlogin failed for $host: $!\n";
+ } else {
+ open(INPUT,"rivlogin -t $timeo -c \"$cisco_cmds\" $host </dev/null |") || die "rivlogin failed for $host: $!\n";
+ }
+}
+
+# determine password filtering mode
+if ($ENV{"FILTER_PWDS"} =~ /no/i) {
+ $filter_pwds = 0;
+} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
+ $filter_pwds = 2;
+} else {
+ $filter_pwds = 1;
+}
+
+ProcessHistory("","","","!RANCID-CONTENT-TYPE: riverstone\n!\n");
+TOP: while(<INPUT>) {
+ tr/\015//d;
+ last if ($clean_run);
+ if (/^Error:/) {
+ print STDOUT ("$host rivlogin error: $_");
+ print STDERR ("$host rivlogin error: $_") if ($debug);
+ $clean_run=0;
+ last;
+ }
+
+ $kradcount++;
+
+ while (/\033(\[\?25l)/) {
+ s/\033\[\?25l//g;
+ #print STDERR "krad $1\n";
+ #print STDERR $_;
+ #print STDERR $kradcount;
+ next;
+ }
+
+
+ while (/#\s*($cmds_regexp)\s*$/) {
+ $cmd = $1;
+ if (!defined($prompt)) {
+ $prompt = ($_ =~ /^([^#]+#)/)[0];
+ $prompt =~ s/([}{)(\\])/\\$1/g;
+ }
+ print STDERR ("HIT COMMAND:$_") if ($debug);
+ if (! defined($commands{$cmd})) {
+ print STDERR "$host: found unexpected command - \"$cmd\"\n";
+ $clean_run = 0;
+ last TOP;
+ }
+ $rval = &{$commands{$cmd}};
+ delete($commands{$cmd});
+ if ($rval == -1) {
+ $clean_run = 0;
+ last TOP;
+ }
+ }
+}
+print STDOUT "Done $logincmd: $_\n" if ($log);
+# Flush History
+ProcessHistory("","","","");
+# Cleanup
+close(INPUT);
+close(OUTPUT);
+
+if (defined($ENV{NOPIPE})) {
+ unlink("$host.raw") if (! $debug);
+}
+
+# check for completeness
+if (scalar(%commands) || !$clean_run) {
+ if (scalar(%commands)) {
+ printf(STDOUT "$host: missed cmd(s): %s\n", join(',', keys(%commands)));
+ printf(STDERR "$host: missed cmd(s): %s\n", join(',', keys(%commands))) if ($debug);
+ }
+ if (!$clean_run) {
+ print STDOUT "$host: End of run not found\n";
+ print STDERR "$host: End of run not found\n" if ($debug);
+ system("/usr/bin/tail -1 $host.new");
+ }
+ unlink "$host.new" if (! $debug);
+}
diff --git a/bin/rrancid.in b/bin/rrancid.in
index f242ec4..7674452 100755..100644
--- a/bin/rrancid.in
+++ b/bin/rrancid.in
@@ -1,28 +1,32 @@
-#!@PERLV_PATH@
+#! @PERLV_PATH@
##
-## hacked version of Hank's rancid - this one tries to deal with redbacks.
+## $Id: rrancid.in,v 1.18 2004/01/11 03:49:13 heas Exp $
##
-## Copyright (C) 1997-2001 by Henry Kilmer.
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
+# hacked version of Hank's rancid - this one tries to deal with redbacks.
+#
# RANCID - Really Awesome New Cisco confIg Differ
#
# usage: rancid [-d] [-l] [-f filename | $host]
#
use Getopt::Std;
-getopts('dflm');
+getopts('dfl');
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
@@ -353,7 +357,8 @@ while(<INPUT>) {
$cmd = $1;
if (!defined($prompt)) {
$prompt = ($_ =~ /^([^#]*#)/)[0];
- $prompt =~ s/([][])/\\$1/g; # quote the damn []'s
+ $prompt =~ s/([][}{)(\\])/\\$1/g; # quote the damn []'s
+ print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
}
print STDERR ("HIT COMMAND:$_") if ($debug);
if (! defined($commands{$cmd})) {
diff --git a/bin/tntlogin.in b/bin/tntlogin.in
new file mode 100644
index 0000000..021f0d2
--- /dev/null
+++ b/bin/tntlogin.in
@@ -0,0 +1,528 @@
+#! @EXPECT_PATH@ --
+##
+## $Id: tntlogin.in,v 1.11 2004/01/11 05:39:15 heas Exp $
+##
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## All rights reserved.
+##
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
+##
+## 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.
+##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
+##
+#
+# The login expect scripts were based on Erik Sherk's gwtn, by permission.
+#
+# Modified by P B Matthews.
+
+# Usage line
+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:
+# x == do not set xterm banner or name
+
+# Password file
+set password_file $env(HOME)/.cloginrc
+# Default is to login to the router
+set do_command 0
+set do_script 0
+# The default is to automatically enable
+set enable 0
+# The default is that you login non-enabled (tacacs can have you login already
+# enabled)
+set avautoenable 1
+# The default is to look in the password file to find the passwords. This
+# tracks if we receive them on the command line.
+set do_passwd 1
+
+# Find the user in the ENV, or use the unix userid.
+if {[ info exists env(CISCO_USER) ] } {
+ set default_user $env(CISCO_USER)
+} elseif {[ info exists env(USER) ]} {
+ set default_user $env(USER)
+} elseif {[ info exists env(LOGNAME) ]} {
+ set default_user $env(LOGNAME)
+} else {
+ # This uses "id" which I think is portable. At least it has existed
+ # (without options) on all machines/OSes I've been on recently -
+ # unlike whoami or id -nu.
+ if [ catch {exec id} reason ] {
+ send_error "\nError: could not exec id: $reason\n"
+ exit 1
+ }
+ regexp {\(([^)]*)} "$reason" junk default_user
+}
+
+# Sometimes routers take awhile to answer (the default is 10 sec)
+set timeout 45
+
+# Process the command line
+for {set i 0} {$i < $argc} {incr i} {
+ set arg [lindex $argv $i]
+
+ switch -glob -- $arg {
+ # Username
+ -u* -
+ -U* {
+ if {! [ regexp .\[uU\](.+) $arg ignore user]} {
+ incr i
+ set username [ lindex $argv $i ]
+ }
+ # VTY Password
+ } -v* -
+ -v* {
+ if {! [ regexp .\[vV\](.+) $arg ignore passwd]} {
+ incr i
+ set passwd [ lindex $argv $i ]
+ }
+ set do_passwd 0
+ # Enable Username
+ } -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 "\nError: invalid format for -E in $arg\n"
+ exit 1
+ }
+ # Enable Password
+ } -e*
+ {
+ # ignore -e
+ # Command to run.
+ } -c* -
+ -C* {
+ if {! [ regexp .\[cC\](.+) $arg ignore command]} {
+ incr i
+ set command [ lindex $argv $i ]
+ }
+ set do_command 1
+ # Expect script to run.
+ } -s* -
+ -S* {
+ if {! [ regexp .\[sS\](.+) $arg ignore sfile]} {
+ incr i
+ set sfile [ lindex $argv $i ]
+ }
+ if { ! [ file readable $sfile ] } {
+ send_user "\nError: Can't read $sfile\n"
+ exit 1
+ }
+ set do_script 1
+ # 'ssh -c' cypher type
+ } -y* -
+ -Y* {
+ if {! [ regexp .\[eE\](.+) $arg ignore cypher]} {
+ incr i
+ set cypher [ lindex $argv $i ]
+ }
+ # alternate cloginrc file
+ } -f* -
+ -F* {
+ if {! [ regexp .\[fF\](.+) $arg ignore password_file]} {
+ incr i
+ set password_file [ lindex $argv $i ]
+ }
+ # Timeout
+ } -t* -
+ -T* {
+ if {! [ regexp .\[tT\](.+) $arg ignore timeout]} {
+ incr i
+ set timeout [ lindex $argv $i ]
+ }
+ # Command file
+ } -x* -
+ -X {
+ if {! [ regexp .\[xX\](.+) $arg ignore cmd_file]} {
+ incr i
+ set cmd_file [ lindex $argv $i ]
+ }
+ if [ catch {set cmd_fd [open $cmd_file r]} reason ] {
+ send_user "\nError: $reason\n"
+ exit 1
+ }
+ set cmd_text [read $cmd_fd]
+ close $cmd_fd
+ set command [join [split $cmd_text \n] \;]
+ set do_command 1
+ # Do we enable?
+ } -noenable {
+ # ignore -noenable
+ # Does tacacs automatically enable us?
+ } -autoenable {
+ # ignore -autoenable
+ } -* {
+ send_user "\nError: Unknown argument! $arg\n"
+ send_user $usage
+ exit 1
+ } default {
+ break
+ }
+ }
+}
+# Process routers...no routers listed is an error.
+if { $i == $argc } {
+ send_user "\nError: $usage"
+}
+
+# Only be quiet if we are running a script (it can log its output
+# on its own)
+if { $do_script } {
+ log_user 0
+} else {
+ log_user 1
+}
+
+#
+# Done configuration/variable setting. Now run with it...
+#
+
+# Sets Xterm title if interactive...if its an xterm and the user cares
+proc label { host } {
+ global env
+ # if CLOGIN has an 'x' in it, don't set the xterm name/banner
+ if [info exists env(CLOGIN)] {
+ if {[string first "x" $env(CLOGIN)] != -1} { return }
+ }
+ # take host from ENV(TERM)
+ if [info exists env(TERM)] {
+ if [regexp \^(xterm|vs) $env(TERM) ignore ] {
+ send_user "\033]1;[lindex [split $host "."] 0]\a"
+ send_user "\033]2;$host\a"
+ }
+ }
+}
+
+# This is a helper function to make the password file easier to
+# maintain. Using this the password file has the form:
+# add password sl* pete cow
+# add password at* steve
+# add password * hanky-pie
+proc add {var args} { global int_$var ; lappend int_$var $args}
+proc include {args} {
+ global env
+ regsub -all "(^{|}$)" $args {} args
+ if { [ regexp "^/" $args ignore ] == 0 } {
+ set args $env(HOME)/$args
+ }
+ source_password_file $args
+}
+
+proc find {var router} {
+ upvar int_$var list
+ if { [info exists list] } {
+ foreach line $list {
+ if { [string match [lindex $line 0] $router ] } {
+ return [lrange $line 1 end]
+ }
+ }
+ }
+ return {}
+}
+
+# Loads the password file. Note that as this file is tcl, and that
+# it is sourced, the user better know what to put in there, as it
+# could install more than just password info... I will assume however,
+# that a "bad guy" could just as easy put such code in the clogin
+# script, so I will leave .cloginrc as just an extention of that script
+proc source_password_file { password_file } {
+ global env
+ if { ! [file exists $password_file] } {
+ send_user "\nError: password file ($password_file) does not exist\n"
+ exit 1
+ }
+ file stat $password_file fileinfo
+ if { [expr ($fileinfo(mode) & 007)] != 0000 } {
+ send_user "\nError: $password_file must not be world readable/writable\n"
+ exit 1
+ }
+ if [ catch {source $password_file} reason ] {
+ send_user "\nError: $reason\n"
+ exit 1
+ }
+}
+
+# Log into the router.
+proc login { router user userpswd passwd prompt cmethod cyphertype } {
+ global spawn_id in_proc do_command do_script
+ global u_prompt p_prompt sshcmd
+ set in_proc 1
+ set uprompt_seen 0
+
+ # 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] {
+ regexp {telnet(:([^[:space:]]+))*} $prog command suffix port
+ if {"$port" == ""} {
+ set retval [ catch {spawn telnet $router} reason ]
+ } else {
+ set retval [ catch {spawn telnet $router $port} reason ]
+ }
+ if { $retval } {
+ send_user "\nError: telnet failed: $reason\n"
+ exit 1
+ }
+ } elseif ![string compare $prog "ssh"] {
+ if [ catch {spawn $sshcmd -c $cyphertype -x -l $user $router} reason ] {
+ send_user "\nError: $sshcmd failed: $reason\n"
+ exit 1
+ }
+ } elseif ![string compare $prog "rsh"] {
+ if [ catch {spawn rsh -l $user $router} reason ] {
+ send_user "\nError: rsh failed: $reason\n"
+ exit 1
+ }
+ } else {
+ puts "\nError: unknown connection method: $prog"
+ return 1
+ }
+ incr progs -1
+ sleep 0.3
+
+ # This helps cleanup each expect clause.
+ expect_after {
+ timeout {
+ send_user "\nError: TIMEOUT reached\n"
+ catch {close}; wait
+ if { $in_proc} {
+ return 1
+ } else {
+ continue
+ }
+ } eof {
+ send_user "\nError: EOF received\n"
+ catch {close}; wait
+ if { $in_proc} {
+ return 1
+ } else {
+ continue
+ }
+ }
+ }
+
+ expect {
+ "Connection refused" {
+ close; wait
+ sleep 0.3
+ expect eof
+ send_user "\nError: Connection Refused\n"; wait; return 1
+ } eof { send_user "\nError: Couldn't login\n"; wait; return 1
+ } "Unknown host\r\n" {
+ expect eof
+ send_user "\nError: Unknown host\n"; wait; return 1
+ } "Host is unreachable" {
+ expect eof
+ send_user "\nError: Host Unreachable!\n"; wait; return 1
+ } "No address associated with name" {
+ expect eof
+ send_user "\nError: Unknown host\n"; wait; return 1
+ }
+ -re "(Host key not found |The authenticity of host .* be established).*\(yes\/no\)\?" {
+ send "yes\r"
+ send_user "\nHost $router added to the list of known hosts.\n"
+ exp_continue }
+ -re "HOST IDENTIFICATION HAS CHANGED.* \(yes\/no\)\?" {
+ send "no\r"
+ send_user "\nError: The host key for $router has changed. Update the 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 }
+
+ -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
+ }
+ -re "^Confirm seeing above note" {
+ send "y\r"
+ exp_continue
+ }
+ "Password incorrect" { send_user "\nError: Check your password for $router\n";
+ catch {close}; wait; return 1 }
+ -re "$prompt" { break; }
+ denied { send_user "\nError: Check your passwd for $router\n"
+ catch {close}; wait; return 1
+ }
+ "\r\n" { exp_continue; }
+ }
+ }
+ set in_proc 0
+ return 0
+}
+
+# Run commands given on the command line.
+proc run_commands { prompt command } {
+ global in_proc
+ set in_proc 1
+
+ send "lines 0\r"
+ expect -re $prompt {}
+ regsub -all "\[)(]" $prompt {\\&} reprompt
+
+ # Is this a multi-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" { exp_continue }
+ -re "\[\n\r]+" { exp_continue }
+ }
+ }
+ } else {
+ send "[subst -nocommands $command]\r"
+ send "y\r"
+ expect {
+ -re "^\[^\n\r]*$reprompt" {}
+ -re "^\[^\n\r ]*>>.*$reprompt" { exp_continue }
+ -re "\[\n\r]+" { exp_continue }
+ }
+ }
+
+ send "quit\r"
+# expect {
+# -re "^WARNING: the current user has insufficient rights to view password fields. A configuration saved under this circumstance should not be used to restore profiles containing passwords. Save anyway? [y/n]"
+# {
+# send "y\r"
+ exp_continue
+ }
+ "\n" { exp_continue }
+ "\[^\n\r *]*Session terminated" { return 0 }
+ timeout { return 0 }
+ eof { return 0 }
+ }
+ set in_proc 0
+}
+
+#
+# For each router... (this is main loop)
+#
+source_password_file $password_file
+set in_proc 0
+foreach router [lrange $argv $i end] {
+ set router [string tolower $router]
+ send_user "$router\n"
+
+ # Figure out prompt.
+ set prompt "admin>"
+ # TNT only "enables" based on the password used at login time
+ set autoenable 1
+ set enable 0
+
+ # Figure out passwords
+ if { $do_passwd } {
+ set pswd [find password $router]
+ if { [llength $pswd] == 0 } {
+ send_user "\nError - no password for $router in $password_file.\n"
+ continue
+ }
+ set passwd [join [lindex $pswd 0] ""]
+ }
+
+ # Figure out username
+ if {[info exists username]} {
+ # command line username
+ set ruser $username
+ } else {
+ set ruser [join [find user $router] ""]
+ if { "$ruser" == "" } { set ruser $default_user }
+ }
+
+ # Figure out username's password (if different from the vty password)
+ if {[info exists userpasswd]} {
+ # command line username
+ set userpswd $userpasswd
+ } else {
+ set userpswd [join [find userpassword $router] ""]
+ if { "$userpswd" == "" } { set userpswd $passwd }
+ }
+
+ # Figure out prompts
+ set u_prompt [find userprompt $router]
+ if { "$u_prompt" == "" } {
+ set u_prompt "(User|Username|login| Login):"
+ } else {
+ set u_prompt [join [lindex $u_prompt 0] ""]
+ }
+
+ set p_prompt [find passprompt $router]
+ if { "$p_prompt" == "" } {
+ set p_prompt "\[Pp]assword:"
+ } else {
+ set p_prompt [join [lindex $p_prompt 0] ""]
+ }
+
+ # Figure out cypher type
+ if {[info exists cypher]} {
+ # command line cypher type
+ set cyphertype $cypher
+ } else {
+ set cyphertype [find cyphertype $router]
+ if { "$cyphertype" == "" } { set cyphertype "3des" }
+ }
+
+ # Figure out connection method
+ set cmethod [find method $router]
+ if { "$cmethod" == "" } { set cmethod {{telnet} {ssh}} }
+
+ # Figure out the SSH executable name
+ set sshcmd [find sshcmd $router]
+ if { "$sshcmd" == "" } { set sshcmd {ssh} }
+
+ # Login to the router
+ if {[login $router $ruser $userpswd $passwd $prompt $cmethod $cyphertype]} {
+ continue
+ }
+
+ if { $do_command } {
+ if {[run_commands $prompt $command]} {
+ continue
+ }
+ } elseif { $do_script } {
+# send "lines 0\r"
+ expect -re $prompt {}
+ source $sfile
+ send "y\r"
+ close
+ } else {
+ label $router
+ log_user 1
+ interact
+ }
+
+ # End of for each router
+ wait
+ sleep 0.3
+}
+exit 0
diff --git a/bin/tntrancid.in b/bin/tntrancid.in
new file mode 100644
index 0000000..88520fd
--- /dev/null
+++ b/bin/tntrancid.in
@@ -0,0 +1,292 @@
+#! @PERLV_PATH@
+##
+## $Id: tntrancid.in,v 1.8 2004/01/11 03:49:13 heas Exp $
+##
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## All rights reserved.
+##
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
+##
+## 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.
+##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
+##
+#
+# Modified by Paul B Matthews & Richard Vander Reyden.
+# I'm suprised it still works....
+#
+# RANCID - Really Awesome New Cisco confIg Differ
+#
+# usage: tntrancid [-d] [-l] [-f filename | $host]
+#
+use Getopt::Std;
+getopts('dfl');
+$log = $opt_l;
+$debug = $opt_d;
+$file = $opt_f;
+$host = $ARGV[0];
+$clean_run = 0;
+$found_end = 0;
+$timeo = 90; # tntlogin timeout in seconds
+$prompt = "admin> ";
+$always_y = "y"; # cause its a pain.
+
+my(%filter_pwds); # password filtering mode
+
+# 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";
+ print eval "$always_y \%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 processes a "save con"
+sub SaveConf {
+ print STDERR " In SaveConf: $_" if ($debug);
+ my($comment) = 1; # strip extra comments, esp to preserve chassis type
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+# next if(/^\s*$/);
+
+### s/^\s*$/;/;
+
+# Leave software revision, but strip out saved date,
+# which causes rancid to think it changes each poll
+
+ if (/^; saved from /) {
+ ProcessHistory("","","","$_");
+ next;
+ }
+ /^; saved / && next;
+
+ # catch anything that wasnt match above.
+ ProcessHistory("","","","$_");
+ # end of config
+# if (/^# End of configuration file/i) {
+ if (/; profiles saved$/) {
+ printf STDERR " End SaveConf: $_" if ($debug);
+ $found_end = 1;
+ print STDOUT "$found_end = found_end within test\n";
+ return(1);
+ }
+ $found_end = 1;
+#### print STDOUT "$found_end = found_end at test\n";
+ }
+ $found_end = 1;
+ return(0);
+}
+$found_end = 1;
+print STDOUT "$found_end = found_end at end test\n";
+
+
+
+
+# dummy function
+sub DoNothing {print STDOUT;}
+
+# Main
+%commands=(
+ 'save con' => "SaveConf"
+);
+# 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=(
+ "save con"
+);
+$tnt_cmds=join(";",@commands);
+$cmds_regexp=join("|",@commands);
+$tnt_cmds="save con";
+
+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 tntlogin -t $timeo -c\"$tnt_cmds\" $host\n" if ($debug);
+ print STDOUT "executing tntlogin -t $timeo -c\"$tnt_cmds\" $host\n" if ($log);
+ if (defined($ENV{NOPIPE})) {
+ system "tntlogin -t $timeo -c \"$tnt_cmds\" $host </dev/null > $host.raw 2>&1" || die "tntlogin failed for $host: $!\n";
+ open(INPUT, "< $host.raw") || die "tntlogin failed for $host: $!\n";
+ } else {
+ open(INPUT,"tntlogin -t $timeo -c \"$tnt_cmds\" $host </dev/null |") || die "tntlogin failed for $host: $!\n";
+ }
+}
+
+# determine password filtering mode
+if ($ENV{"FILTER_PWDS"} =~ /no/i) {
+ $filter_pwds = 0;
+} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
+ $filter_pwds = 2;
+} else {
+ $filter_pwds = 1;
+}
+
+ProcessHistory("","","","#RANCID-CONTENT-TYPE: tnt\n#\n");
+ProcessHistory("COMMENTS","keysort","X0",";\n");
+TOP: while(<INPUT>) {
+ tr/\015//d;
+
+ if (/^Error:/) {
+ print STDOUT ("$host tntlogin error: $_");
+ print STDERR ("$host tntlogin error: $_") if ($debug);
+ $clean_run=0;
+ last;
+ }
+ while (/$prompt\s*($cmds_regexp)\s*$/) {
+ $cmd = $1;
+ if (!defined($prompt)) {
+ $prompt = ($_ =~ /^([^#]+#)/)[0];
+ $prompt =~ s/([][}{)(\\])/\\$1/g;
+ $prompt =~ s/:(\d+ ?)#/:\\d+ ?#/;
+ print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
+ }
+ print STDERR ("HIT COMMAND:$_") if ($debug);
+ if (! defined($commands{$cmd})) {
+ print STDERR "$host: 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
+$clean_run = 1;
+print STDOUT "$clean_run - clean\n";
+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 "$host: missed cmd(s): %s\n", join(',', keys(%commands)));
+ printf(STDERR "$host: missed cmd(s): %s\n", join(',', keys(%commands))) if ($debug);
+ }
+ if (!$clean_run || !$found_end) {
+ print STDOUT "$host: End of run not found\n";
+ print STDERR "$host: End of run not found\n" if ($debug);
+ system("/usr/bin/tail -1 $host.new");
+ }
+ unlink "$host.new" if (! $debug);
+}
diff --git a/bin/xrancid.in b/bin/xrancid.in
index 06ff30b..4aeb1d3 100755..100644
--- a/bin/xrancid.in
+++ b/bin/xrancid.in
@@ -1,19 +1,22 @@
-#!@PERLV_PATH@
+#! @PERLV_PATH@
##
+## $Id: xrancid.in,v 1.32 2004/01/11 03:49:13 heas Exp $
##
-## Copyright (C) 1997-2001 by Henry Kilmer.
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## 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.
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
+## 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.
##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
# RANCID - Really Awesome New Cisco confIg Differ
@@ -21,7 +24,7 @@
# usage: rancid [-d] [-l] [-f filename | $host]
#
use Getopt::Std;
-getopts('dflm');
+getopts('dfl');
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
@@ -272,10 +275,14 @@ sub WriteTerm {
tr/\015//d;
last if(/^$prompt/);
next if(/^\s*$/);
+ return(0) if(/^syntax error at token /i);
# the pager can not be disabled per-session on the PIX
s/^<-+ More -+>\s*//;
+ return(0) if ($found_end);
s/^\s*$/#/;
+ next if (/full detail configuration/i);
+
# filter extra comments and lead comments in config so we can preserve
# the chassis type at the top of muched o/p before the process history
# key changes.
@@ -291,7 +298,7 @@ sub WriteTerm {
# Dog gone Cool matches to process the rest of the config
# some chassis report their chassis type in show diag...oh, but
- # other noooo. grab it here, if available. so, nothing else
+ # others do not. grab it here, if available. so, nothing else
# can change the keysort key until this is grabbed. sigh.
/# (\S+) configuration generated/i &&
ProcessHistory("COMMENTS","keysort","A0","#Chassis type: $1\n") &&
@@ -301,11 +308,11 @@ sub WriteTerm {
/# software version/i && next;
if (/((create|configure) account \S+ \S+) / && $filter_pwds >= 2) {
- ProcessHistory("","","","# $1 <key removed>\n");
+ ProcessHistory("COMMENTS","keysort","H0","# $1 <key removed>\n");
next;
}
if (/configure ssh2 key/ && $filter_pwds >= 1) {
- ProcessHistory("","","","# $_# <key removed>\n");
+ ProcessHistory("COMMENTS","keysort","H0","# $_# <key removed>\n");
while (<INPUT>) {
if (/^(#|enable|conf|disable|unconf)/) {
tr/\015//d;
@@ -317,7 +324,7 @@ sub WriteTerm {
# filter out any RCS/CVS tags to avoid confusing local CVS storage
s/\$(Revision|Id):/ $1:/;
if (/^((config|configure) bgp (neighbor|peer-group) \S+ password encrypted)/i && $filter_pwds >= 1) {
- ProcessHistory("","","","# $1 <removed>\n");
+ ProcessHistory("COMMENTS","keysort","H0","# $1 <removed>\n");
next;
}
@@ -346,17 +353,17 @@ sub WriteTerm {
}
# order/prune tacacs/radius server statements
if (/^(configure radius (primary|secondary) (tacacs-server|radius-server) shared-secret encrypted)/ && $filter_pwds >= 1) {
- ProcessHistory("","","","# $1 <removed>\n");
+ ProcessHistory("COMMENTS","keysort","H0","# $1 <removed>\n");
next;
}
# catch anything that wasnt match above.
- ProcessHistory("","","","$_");
+ ProcessHistory("COMMENTS","keysort","H0","$_");
# end of config
if (/^# End of configuration file/i) {
printf STDERR " End WriteTerm: $_" if ($debug);
$found_end = 1;
- return(1);
+ return(0);
}
}
return(0);
@@ -367,12 +374,13 @@ sub DoNothing {print STDOUT;}
# Main
%commands=(
- 'show version' => "ShowVersion",
- 'show memory' => "ShowMemory",
- 'show diagnostics' => "ShowDiag",
- 'show switch' => "ShowSwitch",
- 'show slot' => "ShowSlot",
- 'show configuration' => "WriteTerm"
+ 'show version' => "ShowVersion",
+ 'show memory' => "ShowMemory",
+ 'show diagnostics' => "ShowDiag",
+ 'show switch' => "ShowSwitch",
+ 'show slot' => "ShowSlot",
+ 'show configuration detail' => "WriteTerm",
+ '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
@@ -382,6 +390,7 @@ sub DoNothing {print STDOUT;}
"show diagnostics",
"show switch",
"show slot",
+ "show configuration detail",
"show configuration"
);
$cisco_cmds=join(";",@commands);
@@ -397,13 +406,13 @@ if ($file) {
print STDOUT "opening file $host\n" if ($log);
open(INPUT,"<$host") || die "open failed for $host: $!\n";
} else {
- print STDERR "executing clogin -t $timeo -autoenable -c\"$cisco_cmds\" $host\n" if ($debug);
- print STDOUT "executing clogin -t $timeo -autoenable -c\"$cisco_cmds\" $host\n" if ($log);
+ 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 -autoenable -c \"$cisco_cmds\" $host </dev/null > $host.raw 2>&1" || die "clogin failed for $host: $!\n";
+ 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 -autoenable -c \"$cisco_cmds\" $host </dev/null |") || die "clogin failed for $host: $!\n";
+ open(INPUT,"clogin -t $timeo -c \"$cisco_cmds\" $host </dev/null |") || die "clogin failed for $host: $!\n";
}
}
@@ -422,13 +431,14 @@ ProcessHistory("COMMENTS","keysort","C0","#\n"); # power supply info
ProcessHistory("COMMENTS","keysort","D0","#\n"); # image name
ProcessHistory("COMMENTS","keysort","E0","#\n"); # h/w info
ProcessHistory("COMMENTS","keysort","F0","#\n"); # slot info
+ProcessHistory("COMMENTS","keysort","H0","#\n"); # config
ProcessHistory("COMMENTS","keysort","X0","#\n");
TOP: while(<INPUT>) {
tr/\015//d;
# note: this match sucks rocks, but currently the extreme bits are
# unreliable about echoing the 'exit\n' command. this match might really
# be a bad idea, but instead rely upon WriteTerm's found_end?
- if (/$prompt\s?(quit|exit|Connection closed)/ && $found_end) {
+ if (/$prompt\s?(quit|exit|Connection( to \S+)? closed)/ && $found_end) {
$clean_run=1;
last;
}
@@ -442,8 +452,10 @@ TOP: while(<INPUT>) {
$cmd = $1;
if (!defined($prompt)) {
$prompt = ($_ =~ /^([^#]+#)/)[0];
+ $prompt =~ s/([][}{)(\\])/\\$1/g;
$prompt =~ s/:(\d+ ?)#/:\\d+ ?#/;
- print STDERR ("PROMPT MATCH:$prompt\n") if ($debug);
+ $prompt =~ s/\*/\\\*/;
+ print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
}
print STDERR ("HIT COMMAND:$_") if ($debug);
if (! defined($commands{$cmd})) {
diff --git a/bin/zrancid.in b/bin/zrancid.in
new file mode 100755
index 0000000..a969553
--- /dev/null
+++ b/bin/zrancid.in
@@ -0,0 +1,411 @@
+#! @PERLV_PATH@
+##
+## $Id: zrancid.in,v 1.8 2004/01/11 03:49:13 heas Exp $
+##
+## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## All rights reserved.
+##
+## This software may be freely copied, modified and redistributed
+## without fee for non-commerical purposes provided that this license
+## remains intact and unmodified with any RANCID distribution.
+##
+## 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.
+##
+## Except where noted otherwise, rancid was written by and is maintained by
+## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
+##
+#
+# This version of rancid tries to deal with zebra s/w.
+#
+# RANCID - Really Awesome New Cisco confIg Differ
+#
+# usage: rancid [-d] [-l] [-f filename | $host]
+#
+use Getopt::Std;
+getopts('dfl');
+$log = $opt_l;
+$debug = $opt_d;
+$file = $opt_f;
+$host = $ARGV[0];
+$clean_run = 0;
+$found_end = 0;
+$timeo = 90; # clogin timeout in seconds
+
+my(%filter_pwds); # password filtering mode
+
+# This routine is used to print out the router configuration
+sub ProcessHistory {
+ my($new_hist_tag,$new_command,$command_string,@string)=(@_);
+ if((($new_hist_tag ne $hist_tag) || ($new_command ne $command))
+ && defined %history) {
+ print eval "$command \%history";
+ undef %history;
+ }
+ if (($new_hist_tag) && ($new_command) && ($command_string)) {
+ if ($history{$command_string}) {
+ $history{$command_string} = "$history{$command_string}@string";
+ } else {
+ $history{$command_string} = "@string";
+ }
+ } elsif (($new_hist_tag) && ($new_command)) {
+ $history{++$#history} = "@string";
+ } else {
+ print "@string";
+ }
+ $hist_tag = $new_hist_tag;
+ $command = $new_command;
+ 1;
+}
+
+sub numerically { $a <=> $b; }
+
+# This is a sort routing that will sort numerically on the
+# keys of a hash as if it were a normal array.
+sub keynsort {
+ local(%lines)=@_;
+ local($i) = 0;
+ local(@sorted_lines);
+ foreach $key (sort numerically keys(%lines)) {
+ $sorted_lines[$i] = $lines{$key};
+ $i++;
+ }
+ @sorted_lines;
+}
+
+# This is a sort routing that will sort on the
+# keys of a hash as if it were a normal array.
+sub keysort {
+ local(%lines)=@_;
+ local($i) = 0;
+ local(@sorted_lines);
+ foreach $key (sort keys(%lines)) {
+ $sorted_lines[$i] = $lines{$key};
+ $i++;
+ }
+ @sorted_lines;
+}
+
+# This is a sort routing that will sort on the
+# values of a hash as if it were a normal array.
+sub valsort{
+ local(%lines)=@_;
+ local($i) = 0;
+ local(@sorted_lines);
+ foreach $key (sort values %lines) {
+ $sorted_lines[$i] = $key;
+ $i++;
+ }
+ @sorted_lines;
+}
+
+# This is a numerical sort routing (ascending).
+sub numsort {
+ local(%lines)=@_;
+ local($i) = 0;
+ local(@sorted_lines);
+ foreach $num (sort {$a <=> $b} keys %lines) {
+ $sorted_lines[$i] = $lines{$num};
+ $i++;
+ }
+ @sorted_lines;
+}
+
+# This is a sort routine that will sort on the
+# ip address when the ip address is anywhere in
+# the strings.
+sub ipsort {
+ local(%lines)=@_;
+ local($i) = 0;
+ local(@sorted_lines);
+ foreach $addr (sort sortbyipaddr keys %lines) {
+ $sorted_lines[$i] = $lines{$addr};
+ $i++;
+ }
+ @sorted_lines;
+}
+
+# These two routines will sort based upon IP addresses
+sub ipaddrval {
+ my(@a) = ($_[0] =~ m#^(\d+)\.(\d+)\.(\d+)\.(\d+)$#);
+ $a[3]+256*($a[2]+256*($a[1]+256*$a[0]));
+}
+sub sortbyipaddr {
+ &ipaddrval($a) <=> &ipaddrval($b);
+}
+
+# This routine parses "show version"
+sub ShowVersion {
+ print STDERR " In ShowVersion: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+ next if(/^(\s*|\s*$cmd\s*)$/);
+ return(-1) if (/command authorization failed/i);
+
+ ProcessHistory("COMMENTS","keysort","B0", "!$_") && next;
+
+ }
+ return(0);
+}
+
+# This routine processes a "write term"
+sub WriteTerm {
+ print STDERR " In WriteTerm: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+ return(-1) if (/command authorization failed/i);
+
+ /Non-Volatile memory is in use/ && return(-1); # NvRAM is locked
+ # skip the crap
+ if (/^(##+$|(Building|Current) configuration)/i) {
+ while (<INPUT>) {
+ next if (/^Current configuration\s*:/i);
+ next if (/^([%!].*|\s*)$/);
+ last;
+ }
+ tr/\015//d;
+ }
+ # some versions have other crap mixed in with the bits in the
+ # block above
+ /^! Last Changed:/ && next;
+
+ # Dog gone Cool matches to process the rest of the config
+# /^tftp-server flash / && next; # kill any tftp remains
+# /^ntp clock-period / && next; # kill ntp clock-period
+# /^ length / && next; # kill length on serial lines
+# /^ width / && next; # kill width on serial lines
+# /^ clockrate / && next; # kill clockrate on serial interfaces
+
+ if (/^(enable password( \d)?) / && $filter_pwds >= 1) {
+ ProcessHistory("ENABLE","","","!$1 <removed>\n");
+ next;
+ }
+ if (/^username (\S+)(\s.*)? password ((\d) \S+|\S+)/) {
+ if ($filter_pwds == 2) {
+ ProcessHistory("USER","keysort","$1","!username $1$2 password <removed>\n");
+ } elsif ($filter_pwds == 1 && $4 ne "5"){
+ ProcessHistory("USER","keysort","$1","!username $1$2 password <removed>\n");
+ } else {
+ ProcessHistory("USER","keysort","$1","$_");
+ }
+ next;
+ }
+
+ # prune passwords {bgp, ...}
+ if (/^\s*neighbor (\S*) password / && $filter_pwds >= 1) {
+ ProcessHistory("","","","! neighbor $1 password <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 logging statements
+ /^logging (\d+\.\d+\.\d+\.\d+)/ &&
+ ProcessHistory("LOGGING","ipsort","$1","$_") && next;
+
+ # order/prune snmp-server host statements
+ # we only prune lines of the form
+ # snmp-server host a.b.c.d <community>
+ if (/^snmp-server host (\d+\.\d+\.\d+\.\d+) /) {
+ if (defined($ENV{'NOCOMMSTR'})) {
+ my($ip) = $1;
+ my($line) = "snmp-server host $ip";
+ my(@tokens) = split(' ', $');
+ my($token);
+ while ($token = shift(@tokens)) {
+ if ($token eq 'version') {
+ $line .= " " . join(' ', ($token, shift(@tokens)));
+ } elsif ($token =~ /^(informs?|traps?|(no)?auth)$/) {
+ $line .= " " . $token;
+ } else {
+ $line = "!$line " . join(' ', ("<removed>", join(' ',@tokens)));
+ last;
+ }
+ }
+ ProcessHistory("SNMPSERVERHOST","ipsort","$ip","$line\n");
+ } else {
+ ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_");
+ }
+ next;
+ }
+ if (/^(snmp-server community) (\S+)/) {
+ if (defined($ENV{'NOCOMMSTR'})) {
+ ProcessHistory("SNMPSERVERCOMM","keysort","$_","!$1 <removed>$'") && next;
+ } else {
+ ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next;
+ }
+ }
+
+ # prune tacacs/radius server keys
+ if (/^(tacacs-server|radius-server) key / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 key <removed>\n"); next;
+ }
+ if (/^(tacacs-server host \S+( .*)? key) (\d )?\S+/
+ && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
+
+ # order clns host statements
+# /^clns host \S+ (\S+)/ &&
+# ProcessHistory("CLNS","keysort","$1","$_") && next;
+
+ # prune isis password
+ if (/^( isis authentication-key) \d \S+/ && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>$'"); next;
+ }
+ # prune msdp password
+ if (/^(ip msdp password \S+) / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
+
+# # order ip host line statements
+# /^ip host line(\d+)/ &&
+# ProcessHistory("IPHOST","numsort","$1","$_") && next;
+
+ # catch anything that wasnt matched above.
+ ProcessHistory("","","","$_");
+ # end of config.
+ if (/^end$/) {
+ $found_end = 1;
+ return(1);
+ }
+ }
+ return(0);
+}
+
+# dummy function
+sub DoNothing {print STDOUT;}
+
+# Main
+%commands=(
+ 'show version' => "ShowVersion",
+ 'write term' => "WriteTerm"
+);
+# keys() doesnt return things in the order entered and the order of the
+# cmds is important (show version first and write term last). pita
+@commands=(
+ "show version",
+ "write term"
+);
+$cisco_cmds=join(";",@commands);
+$cmds_regexp=join("|",@commands);
+
+open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
+select(OUTPUT);
+# make OUTPUT unbuffered if debugging
+if ($debug) { $| = 1; }
+
+if ($file) {
+ print STDERR "opening file $host\n" if ($debug);
+ print STDOUT "opening file $host\n" if ($log);
+ open(INPUT,"<$host") || die "open failed for $host: $!\n";
+} else {
+ print STDERR "executing 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";
+ }
+}
+
+# determine password filtering mode
+if ($ENV{"FILTER_PWDS"} =~ /no/i) {
+ $filter_pwds = 0;
+} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
+ $filter_pwds = 2;
+} else {
+ $filter_pwds = 1;
+}
+
+ProcessHistory("","","","!RANCID-CONTENT-TYPE: zebra\n!\n");
+ProcessHistory("COMMENTS","keysort","B0","!\n"); # show version
+ProcessHistory("COMMENTS","keysort","C0","!\n"); # show package
+ProcessHistory("COMMENTS","keysort","D0","!\n"); # show hardware
+ProcessHistory("COMMENTS","keysort","Z0","!\n");
+TOP: while(<INPUT>) {
+ tr/\015//d;
+ if (/\#\s?exit$/) {
+ $clean_run=1;
+ last;
+ }
+ if (/^Error:/) {
+ print STDOUT ("$host clogin error: $_");
+ print STDERR ("$host clogin error: $_") if ($debug);
+ $clean_run=0;
+ last;
+ }
+ while (/#\s*($cmds_regexp)\s*$/) {
+ $cmd = $1;
+ if (!defined($prompt)) {
+ $prompt = ($_ =~ /^([^#]+#)/)[0];
+ $prompt =~ s/([][}{)(\\])/\\$1/g;
+ }
+ print STDERR ("HIT COMMAND:$_") if ($debug);
+ if (! defined($commands{$cmd})) {
+ print STDERR "$host: found unexpected command - \"$cmd\"\n";
+ $clean_run = 0;
+ last TOP;
+ }
+ $rval = &{$commands{$cmd}};
+ delete($commands{$cmd});
+ if ($rval == -1) {
+ $clean_run = 0;
+ last TOP;
+ }
+ }
+}
+print STDOUT "Done $logincmd: $_\n" if ($log);
+# Flush History
+ProcessHistory("","","","");
+# Cleanup
+close(INPUT);
+close(OUTPUT);
+
+if (defined($ENV{NOPIPE})) {
+ unlink("$host.raw") if (! $debug);
+}
+
+# check for completeness
+if (scalar(%commands) || !$clean_run || !$found_end) {
+ if (scalar(%commands)) {
+ printf(STDOUT "$host: missed cmd(s): %s\n", join(',', keys(%commands)));
+ printf(STDERR "$host: missed cmd(s): %s\n", join(',', keys(%commands))) if ($debug);
+ }
+ if (!$clean_run || !$found_end) {
+ print STDOUT "$host: End of run not found\n";
+ print STDERR "$host: End of run not found\n" if ($debug);
+ system("/usr/bin/tail -1 $host.new");
+ }
+ unlink "$host.new" if (! $debug);
+}
diff --git a/cloginrc.sample b/cloginrc.sample
index da66459..2d430d0 100644
--- a/cloginrc.sample
+++ b/cloginrc.sample
@@ -34,9 +34,9 @@
#
# add method <router name glob> {ssh} [...]
# Defines, in order, which connection method(s) to use for a device
-# from the set {ssh,telnet,rsh}. eg: add method * {ssh} {telnet} {rsh}
+# from the set {ssh,telnet,rsh}. e.g.: add method * {ssh} {telnet} {rsh}
# will attempt ssh connection first. if ssh fails with connection
-# refused (ie: not due to authentication failure), then try telnet,
+# refused (i.e.: not due to authentication failure), then try telnet,
# then rsh.
# Default: {telnet} {ssh}
#
@@ -101,7 +101,7 @@ add method *.custz.net ssh
# equivalent.
add noenable route-server* 1
-# all our routers, ie: everything else
+# all our routers, i.e.: everything else
add password * {clearance} {clarence}
# set ssh encryption type, dflt: 3des
@@ -112,3 +112,13 @@ add cyphertype * {3des}
# ssh identity for a juniper; used with jlogin
add identity my.juniper $env(HOME)/.ssh/juniper
+
+# riverstone / enterasys / cabletron (rivlogin) example
+# these boxes are 'back-to-front' from cisco (i.e., ask
+# for vty password always, then tac+/radius if configured).
+#
+# vty password and last resort (enable) password for rivlogin
+add password rs3000 {vtypass} {lastresort}
+# if using tac+ or radius login, include these lines
+add user rs3000 {monster}
+add userpassword rs3000 {scary}
diff --git a/configure b/configure
index 3861408..ce3976d 100755
--- a/configure
+++ b/configure
@@ -1,32 +1,326 @@
#! /bin/sh
-
# Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.13
-# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+# Generated by GNU Autoconf 2.59.
#
+# Copyright (C) 2003 Free Software Foundation, Inc.
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
-# Defaults:
-ac_help=
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
ac_default_prefix=/usr/local
-# Any additions from configure.in:
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete. It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="CHANGES"
ac_default_prefix=/usr/local/rancid
-ac_help="$ac_help
- --enable-maintainer-mode enable make rules and dependencies not useful
- (and sometimes confusing) to the casual installer"
-ac_help="$ac_help
- --enable-mail-plus enable mail to rancid+ addresses, instead of rancid-"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS VERSION PACKAGE INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot MAKE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP EGREP U ANSI2KNR MAILPLUS ADMINMAILPLUS DIRNAME DIFF DIFF_CMD SENDMAIL TAR PERLV_PATH PERLV EXPECT_PATH PING_PATH LG_PING_CMD CVS COMM FIND GREP ID MKDIR RSH SORT SSH TELNET TOUCH ENV_PATH LIBOBJS LTLIBOBJS'
+ac_subst_files=''
# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
# The variables have the same names as the options, with
# dashes changed to underlines.
-build=NONE
-cache_file=./config.cache
+cache_file=/dev/null
exec_prefix=NONE
-host=NONE
no_create=
-nonopt=NONE
no_recursion=
prefix=NONE
program_prefix=NONE
@@ -35,10 +329,15 @@ program_transform_name=s,x,x,
silent=
site=
srcdir=
-target=NONE
verbose=
x_includes=NONE
x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
bindir='${exec_prefix}/bin'
sbindir='${exec_prefix}/sbin'
libexecdir='${exec_prefix}/libexec'
@@ -52,17 +351,9 @@ oldincludedir='/usr/include'
infodir='${prefix}/info'
mandir='${prefix}/man'
-# Initialize some other variables.
-subdirs=
-MFLAGS= MAKEFLAGS=
-SHELL=${CONFIG_SHELL-/bin/sh}
-# Maximum number of lines to put in a shell here document.
-ac_max_here_lines=12
-
ac_prev=
for ac_option
do
-
# If the previous option needs an argument, assign it.
if test -n "$ac_prev"; then
eval "$ac_prev=\$ac_option"
@@ -70,59 +361,59 @@ do
continue
fi
- case "$ac_option" in
- -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
- *) ac_optarg= ;;
- esac
+ ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
# Accept the important Cygnus configure options, so we can diagnose typos.
- case "$ac_option" in
+ case $ac_option in
-bindir | --bindir | --bindi | --bind | --bin | --bi)
ac_prev=bindir ;;
-bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
- bindir="$ac_optarg" ;;
+ bindir=$ac_optarg ;;
-build | --build | --buil | --bui | --bu)
- ac_prev=build ;;
+ ac_prev=build_alias ;;
-build=* | --build=* | --buil=* | --bui=* | --bu=*)
- build="$ac_optarg" ;;
+ build_alias=$ac_optarg ;;
-cache-file | --cache-file | --cache-fil | --cache-fi \
| --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
ac_prev=cache_file ;;
-cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
| --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
- cache_file="$ac_optarg" ;;
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
-datadir | --datadir | --datadi | --datad | --data | --dat | --da)
ac_prev=datadir ;;
-datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
| --da=*)
- datadir="$ac_optarg" ;;
+ datadir=$ac_optarg ;;
-disable-* | --disable-*)
- ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
# Reject names that are not valid shell variable names.
- if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
- { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
- fi
- ac_feature=`echo $ac_feature| sed 's/-/_/g'`
- eval "enable_${ac_feature}=no" ;;
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ eval "enable_$ac_feature=no" ;;
-enable-* | --enable-*)
- ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
# Reject names that are not valid shell variable names.
- if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
- { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
- fi
- ac_feature=`echo $ac_feature| sed 's/-/_/g'`
- case "$ac_option" in
- *=*) ;;
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
*) ac_optarg=yes ;;
esac
- eval "enable_${ac_feature}='$ac_optarg'" ;;
+ eval "enable_$ac_feature='$ac_optarg'" ;;
-exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
| --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
@@ -131,95 +422,47 @@ do
-exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
| --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
| --exec=* | --exe=* | --ex=*)
- exec_prefix="$ac_optarg" ;;
+ exec_prefix=$ac_optarg ;;
-gas | --gas | --ga | --g)
# Obsolete; use --with-gas.
with_gas=yes ;;
- -help | --help | --hel | --he)
- # Omit some internal or obsolete options to make the list less imposing.
- # This message is too long to be a string in the A/UX 3.1 sh.
- cat << EOF
-Usage: configure [options] [host]
-Options: [defaults in brackets after descriptions]
-Configuration:
- --cache-file=FILE cache test results in FILE
- --help print this message
- --no-create do not create output files
- --quiet, --silent do not print \`checking...' messages
- --version print the version of autoconf that created configure
-Directory and file names:
- --prefix=PREFIX install architecture-independent files in PREFIX
- [$ac_default_prefix]
- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [same as prefix]
- --bindir=DIR user executables in DIR [EPREFIX/bin]
- --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
- --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
- --datadir=DIR read-only architecture-independent data in DIR
- [PREFIX/share]
- --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
- --sharedstatedir=DIR modifiable architecture-independent data in DIR
- [PREFIX/com]
- --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
- --libdir=DIR object code libraries in DIR [EPREFIX/lib]
- --includedir=DIR C header files in DIR [PREFIX/include]
- --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
- --infodir=DIR info documentation in DIR [PREFIX/info]
- --mandir=DIR man documentation in DIR [PREFIX/man]
- --srcdir=DIR find the sources in DIR [configure dir or ..]
- --program-prefix=PREFIX prepend PREFIX to installed program names
- --program-suffix=SUFFIX append SUFFIX to installed program names
- --program-transform-name=PROGRAM
- run sed PROGRAM on installed program names
-EOF
- cat << EOF
-Host type:
- --build=BUILD configure for building on BUILD [BUILD=HOST]
- --host=HOST configure for HOST [guessed]
- --target=TARGET configure for TARGET [TARGET=HOST]
-Features and packages:
- --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
- --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
- --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
- --x-includes=DIR X include files are in DIR
- --x-libraries=DIR X library files are in DIR
-EOF
- if test -n "$ac_help"; then
- echo "--enable and --with options recognized:$ac_help"
- fi
- exit 0 ;;
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
-host | --host | --hos | --ho)
- ac_prev=host ;;
+ ac_prev=host_alias ;;
-host=* | --host=* | --hos=* | --ho=*)
- host="$ac_optarg" ;;
+ host_alias=$ac_optarg ;;
-includedir | --includedir | --includedi | --included | --include \
| --includ | --inclu | --incl | --inc)
ac_prev=includedir ;;
-includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
| --includ=* | --inclu=* | --incl=* | --inc=*)
- includedir="$ac_optarg" ;;
+ includedir=$ac_optarg ;;
-infodir | --infodir | --infodi | --infod | --info | --inf)
ac_prev=infodir ;;
-infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
- infodir="$ac_optarg" ;;
+ infodir=$ac_optarg ;;
-libdir | --libdir | --libdi | --libd)
ac_prev=libdir ;;
-libdir=* | --libdir=* | --libdi=* | --libd=*)
- libdir="$ac_optarg" ;;
+ libdir=$ac_optarg ;;
-libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
| --libexe | --libex | --libe)
ac_prev=libexecdir ;;
-libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
| --libexe=* | --libex=* | --libe=*)
- libexecdir="$ac_optarg" ;;
+ libexecdir=$ac_optarg ;;
-localstatedir | --localstatedir | --localstatedi | --localstated \
| --localstate | --localstat | --localsta | --localst \
@@ -228,19 +471,19 @@ EOF
-localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
| --localstate=* | --localstat=* | --localsta=* | --localst=* \
| --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
- localstatedir="$ac_optarg" ;;
+ localstatedir=$ac_optarg ;;
-mandir | --mandir | --mandi | --mand | --man | --ma | --m)
ac_prev=mandir ;;
-mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
- mandir="$ac_optarg" ;;
+ mandir=$ac_optarg ;;
-nfp | --nfp | --nf)
# Obsolete; use --without-fp.
with_fp=no ;;
-no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c)
+ | --no-cr | --no-c | -n)
no_create=yes ;;
-no-recursion | --no-recursion | --no-recursio | --no-recursi \
@@ -254,26 +497,26 @@ EOF
-oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
| --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
| --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
- oldincludedir="$ac_optarg" ;;
+ oldincludedir=$ac_optarg ;;
-prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
ac_prev=prefix ;;
-prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
- prefix="$ac_optarg" ;;
+ prefix=$ac_optarg ;;
-program-prefix | --program-prefix | --program-prefi | --program-pref \
| --program-pre | --program-pr | --program-p)
ac_prev=program_prefix ;;
-program-prefix=* | --program-prefix=* | --program-prefi=* \
| --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
- program_prefix="$ac_optarg" ;;
+ program_prefix=$ac_optarg ;;
-program-suffix | --program-suffix | --program-suffi | --program-suff \
| --program-suf | --program-su | --program-s)
ac_prev=program_suffix ;;
-program-suffix=* | --program-suffix=* | --program-suffi=* \
| --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
- program_suffix="$ac_optarg" ;;
+ program_suffix=$ac_optarg ;;
-program-transform-name | --program-transform-name \
| --program-transform-nam | --program-transform-na \
@@ -290,7 +533,7 @@ EOF
| --program-transfo=* | --program-transf=* \
| --program-trans=* | --program-tran=* \
| --progr-tra=* | --program-tr=* | --program-t=*)
- program_transform_name="$ac_optarg" ;;
+ program_transform_name=$ac_optarg ;;
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
| -silent | --silent | --silen | --sile | --sil)
@@ -300,7 +543,7 @@ EOF
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
| --sbi=* | --sb=*)
- sbindir="$ac_optarg" ;;
+ sbindir=$ac_optarg ;;
-sharedstatedir | --sharedstatedir | --sharedstatedi \
| --sharedstated | --sharedstate | --sharedstat | --sharedsta \
@@ -311,58 +554,57 @@ EOF
| --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
| --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
| --sha=* | --sh=*)
- sharedstatedir="$ac_optarg" ;;
+ sharedstatedir=$ac_optarg ;;
-site | --site | --sit)
ac_prev=site ;;
-site=* | --site=* | --sit=*)
- site="$ac_optarg" ;;
+ site=$ac_optarg ;;
-srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
ac_prev=srcdir ;;
-srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
- srcdir="$ac_optarg" ;;
+ srcdir=$ac_optarg ;;
-sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
| --syscon | --sysco | --sysc | --sys | --sy)
ac_prev=sysconfdir ;;
-sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
| --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
- sysconfdir="$ac_optarg" ;;
+ sysconfdir=$ac_optarg ;;
-target | --target | --targe | --targ | --tar | --ta | --t)
- ac_prev=target ;;
+ ac_prev=target_alias ;;
-target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
- target="$ac_optarg" ;;
+ target_alias=$ac_optarg ;;
-v | -verbose | --verbose | --verbos | --verbo | --verb)
verbose=yes ;;
- -version | --version | --versio | --versi | --vers)
- echo "configure generated by autoconf version 2.13"
- exit 0 ;;
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
-with-* | --with-*)
- ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
# Reject names that are not valid shell variable names.
- if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
- { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
- fi
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
ac_package=`echo $ac_package| sed 's/-/_/g'`
- case "$ac_option" in
- *=*) ;;
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
*) ac_optarg=yes ;;
esac
- eval "with_${ac_package}='$ac_optarg'" ;;
+ eval "with_$ac_package='$ac_optarg'" ;;
-without-* | --without-*)
- ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
# Reject names that are not valid shell variable names.
- if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
- { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
- fi
- ac_package=`echo $ac_package| sed 's/-/_/g'`
- eval "with_${ac_package}=no" ;;
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package | sed 's/-/_/g'`
+ eval "with_$ac_package=no" ;;
--x)
# Obsolete; use --with-x.
@@ -373,99 +615,110 @@ EOF
ac_prev=x_includes ;;
-x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
| --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
- x_includes="$ac_optarg" ;;
+ x_includes=$ac_optarg ;;
-x-libraries | --x-libraries | --x-librarie | --x-librari \
| --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
ac_prev=x_libraries ;;
-x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
| --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
- x_libraries="$ac_optarg" ;;
+ x_libraries=$ac_optarg ;;
- -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
;;
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+ eval "$ac_envvar='$ac_optarg'"
+ export $ac_envvar ;;
+
*)
- if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
- echo "configure: warning: $ac_option: invalid host type" 1>&2
- fi
- if test "x$nonopt" != xNONE; then
- { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
- fi
- nonopt="$ac_option"
+ # FIXME: should be removed in autoconf 3.0.
+ echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
;;
esac
done
if test -n "$ac_prev"; then
- { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
-fi
-
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
-# File descriptor usage:
-# 0 standard input
-# 1 file creation
-# 2 errors and warnings
-# 3 some systems may open it to /dev/tty
-# 4 used on the Kubota Titan
-# 6 checking for... messages and results
-# 5 compiler messages saved in config.log
-if test "$silent" = yes; then
- exec 6>/dev/null
-else
- exec 6>&1
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
fi
-exec 5>./config.log
-echo "\
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-" 1>&5
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Also quote any args containing shell metacharacters.
-ac_configure_args=
-for ac_arg
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+ localstatedir libdir includedir oldincludedir infodir mandir
do
- case "$ac_arg" in
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c) ;;
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
- *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
- ac_configure_args="$ac_configure_args '$ac_arg'" ;;
- *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
esac
done
-# NLS nuisances.
-# Only set these to C if already set. These must not be set unconditionally
-# because not all systems understand e.g. LANG=C (notably SCO).
-# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
-# Non-C LC_CTYPE values break the ctype check.
-if test "${LANG+set}" = set; then LANG=C; export LANG; fi
-if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
-if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
-if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -rf conftest* confdefs.h
-# AIX cpp loses on an empty file, so make sure it contains at least a newline.
-echo > confdefs.h
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
-# A filename unique to this package, relative to the directory that
-# configure is in, which we can look for to find out if srcdir is correct.
-ac_unique_file=CHANGES
# Find the source files, if location was not specified.
if test -z "$srcdir"; then
ac_srcdir_defaulted=yes
# Try the directory containing this script, then its parent.
- ac_prog=$0
- ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
- test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$0" : 'X\(//\)[^/]' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
srcdir=$ac_confdir
if test ! -r $srcdir/$ac_unique_file; then
srcdir=..
@@ -475,13 +728,468 @@ else
fi
if test ! -r $srcdir/$ac_unique_file; then
if test "$ac_srcdir_defaulted" = yes; then
- { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+ { (exit 1); exit 1; }; }
else
- { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
fi
fi
-srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+ { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+ { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+ cat <<_ACEOF
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --infodir=DIR info documentation [PREFIX/info]
+ --mandir=DIR man documentation [PREFIX/man]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --disable-dependency-tracking Speeds up one-time builds
+ --enable-dependency-tracking Do not reject slow dependency extractors
+ --enable-mail-plus enable mail to rancid+ addresses, instead of rancid-
+ --enable-adminmail-plus enable mail to rancid-admin+ addresses, instead of
+ rancid-admin-
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
+ headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ ac_popdir=`pwd`
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d $ac_dir || continue
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+ cd $ac_dir
+ # Check for guested configure; otherwise get Cygnus style configure.
+ if test -f $ac_srcdir/configure.gnu; then
+ echo
+ $SHELL $ac_srcdir/configure.gnu --help=recursive
+ elif test -f $ac_srcdir/configure; then
+ echo
+ $SHELL $ac_srcdir/configure --help=recursive
+ elif test -f $ac_srcdir/configure.ac ||
+ test -f $ac_srcdir/configure.in; then
+ echo
+ $ac_configure --help
+ else
+ echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi
+ cd $ac_popdir
+ done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+ cat <<\_ACEOF
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF<