summaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
authorJeffrey C. Ollie <jeff@ocjtech.us>2007-03-25 23:16:40 -0500
committerJeffrey C. Ollie <jeff@ocjtech.us>2007-03-25 23:16:40 -0500
commited56ea51bb811dcdabb00d036786b412fdbf4d36 (patch)
treee880bcf06d9e757c39ee0cae83713b3de885c6df /bin
parentad03c748e10fe5b8dbd95c3bcdbcc2c02e777e7b (diff)
parentac54243f382e817c08c1f895ccfdc05dcacdb044 (diff)
downloadrancid-ed56ea51bb811dcdabb00d036786b412fdbf4d36.tar.gz
rancid-ed56ea51bb811dcdabb00d036786b412fdbf4d36.tar.xz
rancid-ed56ea51bb811dcdabb00d036786b412fdbf4d36.zip
Update usercmd branch with latest vendor changes.rancid-2.3.2a7-usercmd.patch
Diffstat (limited to 'bin')
-rw-r--r--bin/Makefile.am14
-rw-r--r--bin/Makefile.in199
-rw-r--r--bin/agmrancid.in493
-rw-r--r--bin/alogin.in70
-rw-r--r--bin/arancid.in114
-rw-r--r--bin/blogin.in79
-rw-r--r--bin/brancid.in82
-rw-r--r--bin/cat5rancid.in163
-rw-r--r--bin/clogin.in208
-rw-r--r--bin/control_rancid.in176
-rw-r--r--bin/cssrancid.in144
-rw-r--r--bin/elogin.in56
-rw-r--r--bin/erancid.in83
-rw-r--r--bin/f10rancid.in215
-rw-r--r--bin/flogin.in105
-rw-r--r--bin/fnrancid.in86
-rw-r--r--bin/francid.in157
-rw-r--r--bin/hlogin.in148
-rw-r--r--bin/hpuifilter.c710
-rw-r--r--bin/hrancid.in100
-rw-r--r--bin/htlogin.in60
-rw-r--r--bin/htrancid.in76
-rw-r--r--bin/jerancid.in91
-rw-r--r--bin/jlogin.in75
-rw-r--r--bin/jrancid.in339
-rw-r--r--bin/lg.cgi.in37
-rw-r--r--bin/lgform.cgi.in32
-rw-r--r--bin/mrancid.in73
-rw-r--r--bin/nlogin.in156
-rw-r--r--bin/nrancid.in169
-rw-r--r--bin/nslogin.in50
-rw-r--r--bin/nsrancid.in80
-rw-r--r--bin/par.in15
-rwxr-xr-xbin/prancid.in81
-rw-r--r--bin/rancid-cvs.in66
-rw-r--r--bin/rancid-fe.in61
-rw-r--r--bin/rancid-run.in119
-rw-r--r--bin/rancid.in731
-rw-r--r--bin/rivlogin.in433
-rw-r--r--bin/rivrancid.in99
-rw-r--r--bin/rrancid.in95
-rwxr-xr-xbin/srancid.in404
-rw-r--r--bin/tntlogin.in73
-rw-r--r--bin/tntrancid.in98
-rw-r--r--bin/xrancid.in91
-rwxr-xr-xbin/zrancid.in70
46 files changed, 4736 insertions, 2340 deletions
diff --git a/bin/Makefile.am b/bin/Makefile.am
index 21fac52..b7fc75f 100644
--- a/bin/Makefile.am
+++ b/bin/Makefile.am
@@ -1,9 +1,9 @@
## 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.28 2004/01/11 07:15:23 hank Exp $
+## $Id: Makefile.am,v 1.36 2007/01/13 22:01:53 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -25,12 +25,12 @@ AUTOMAKE_OPTIONS=foreign
bin_PROGRAMS = hpuifilter
bin_SCRIPTS = cat5rancid control_rancid \
- alogin arancid clogin blogin brancid cssrancid \
+ agmrancid alogin arancid blogin brancid clogin cssrancid \
elogin erancid f10rancid flogin francid fnrancid \
- jlogin jrancid jerancid \
hlogin hrancid htlogin htrancid \
+ jerancid jlogin jrancid \
mrancid nlogin nrancid nslogin nsrancid par prancid \
- rancid rancid-fe rivlogin rivrancid rrancid \
+ rancid rancid-fe rivlogin rivrancid rrancid srancid \
tntlogin tntrancid xrancid zrancid
bin_SCRIPTS += lg.cgi lgform.cgi rancid-cvs rancid-run
@@ -73,7 +73,9 @@ auto_edit = sed \
-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'
+ -e 's,@MAILPLUS\@,$(MAILPLUS),g' \
+ -e 's,@PACKAGE\@,$(PACKAGE),g' \
+ -e 's,@VERSION\@,$(VERSION),g'
lg.cgi: Makefile $(srcdir)/lg.cgi.in
rm -f lg.cgi lg.cgi.tmp; \
diff --git a/bin/Makefile.in b/bin/Makefile.in
index eedc795..ca80b2a 100644
--- a/bin/Makefile.in
+++ b/bin/Makefile.in
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.8 from Makefile.am.
+# Makefile.in generated by automake 1.10 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
-# Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006 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.
@@ -15,17 +15,11 @@
@SET_MAKE@
-SOURCES = $(hpuifilter_SOURCES)
-
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
-top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
@@ -40,22 +34,23 @@ 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)/agmrancid.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
+ $(srcdir)/rrancid.in $(srcdir)/srancid.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
@@ -63,13 +58,13 @@ 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)
+CONFIG_CLEAN_FILES = control_rancid par rancid-fe agmrancid 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 srancid tntlogin tntrancid xrancid zrancid
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)"
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(bin_PROGRAMS)
am_hpuifilter_OBJECTS = hpuifilter.$(OBJEXT)
@@ -77,10 +72,9 @@ hpuifilter_OBJECTS = $(am_hpuifilter_OBJECTS)
hpuifilter_LDADD = $(LDADD)
binSCRIPT_INSTALL = $(INSTALL_SCRIPT)
SCRIPTS = $(bin_SCRIPTS)
-DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include
+DEFAULT_INCLUDES = -I. -I$(top_builddir)/include@am__isrc@
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)
@@ -92,8 +86,6 @@ 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@
@@ -128,6 +120,7 @@ EXPECT_PATH = @EXPECT_PATH@
FIND = @FIND@
GREP = @GREP@
ID = @ID@
+INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@@ -141,6 +134,7 @@ MAILPLUS = @MAILPLUS@
MAKE = @MAKE@
MAKEINFO = @MAKEINFO@
MKDIR = @MKDIR@
+MKDIR_P = @MKDIR_P@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -152,6 +146,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERLV = @PERLV@
PERLV_PATH = @PERLV_PATH@
PING_PATH = @PING_PATH@
+RCSSYS = @RCSSYS@
RSH = @RSH@
SENDMAIL = @SENDMAIL@
SET_MAKE = @SET_MAKE@
@@ -159,50 +154,63 @@ SHELL = @SHELL@
SORT = @SORT@
SSH = @SSH@
STRIP = @STRIP@
+SVN = @SVN@
TAR = @TAR@
TELNET = @TELNET@
TOUCH = @TOUCH@
U = @U@
VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
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@
+am__tar = @am__tar@
+am__untar = @am__untar@
bindir = @bindir@
build_alias = @build_alias@
+builddir = @builddir@
datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
exec_prefix = @exec_prefix@
host_alias = @host_alias@
+htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
+localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
+psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
#AUTOMAKE_OPTIONS=foreign no-dependencies
AUTOMAKE_OPTIONS = foreign
-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
+bin_SCRIPTS = cat5rancid control_rancid agmrancid alogin arancid \
+ blogin brancid clogin cssrancid elogin erancid f10rancid \
+ flogin francid fnrancid hlogin hrancid htlogin htrancid \
+ jerancid jlogin jrancid mrancid nlogin nrancid nslogin \
+ nsrancid par prancid rancid rancid-fe rivlogin rivrancid \
+ rrancid srancid 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
@@ -232,7 +240,9 @@ auto_edit = sed \
-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'
+ -e 's,@MAILPLUS\@,$(MAILPLUS),g' \
+ -e 's,@PACKAGE\@,$(PACKAGE),g' \
+ -e 's,@VERSION\@,$(VERSION),g'
all: all-am
@@ -273,6 +283,8 @@ 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)/$@
+agmrancid: $(top_builddir)/config.status $(srcdir)/agmrancid.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
@@ -333,6 +345,8 @@ 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)/$@
+srancid: $(top_builddir)/config.status $(srcdir)/srancid.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
@@ -343,14 +357,14 @@ zrancid: $(top_builddir)/config.status $(srcdir)/zrancid.in
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
- $(mkdir_p) $(DESTDIR)$(bindir)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
@list='$(bin_PROGRAMS)'; for p in $$list; do \
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; \
+ echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
else :; fi; \
done
@@ -358,24 +372,24 @@ uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
@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; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
done
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)
+ $(LINK) $(hpuifilter_OBJECTS) $(hpuifilter_LDADD) $(LIBS)
install-binSCRIPTS: $(bin_SCRIPTS)
@$(NORMAL_INSTALL)
- $(mkdir_p) $(DESTDIR)$(bindir)
+ test -z "$(bindir)" || $(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; \
+ echo " $(binSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(binSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(bindir)/$$f"; \
else :; fi; \
done
@@ -383,8 +397,8 @@ 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; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
done
mostlyclean-compile:
@@ -396,21 +410,18 @@ distclean-compile:
@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
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@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@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(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
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@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@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(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)'; \
@@ -432,9 +443,11 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
- test -z "$(ETAGS_ARGS)$$tags$$unique" \
- || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- $$tags $$unique
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
@@ -459,22 +472,21 @@ distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
- @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; \
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
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 \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
@@ -489,7 +501,9 @@ check-am: all-am
check: check-am
all-am: Makefile $(PROGRAMS) $(SCRIPTS)
installdirs:
- $(mkdir_p) $(DESTDIR)$(bindir) $(DESTDIR)$(bindir)
+ for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
@@ -510,7 +524,7 @@ clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
- -rm -f $(CONFIG_CLEAN_FILES)
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@@ -537,12 +551,20 @@ info-am:
install-data-am:
+install-dvi: install-dvi-am
+
install-exec-am: install-binPROGRAMS install-binSCRIPTS
+install-html: install-html-am
+
install-info: install-info-am
install-man:
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
installcheck-am:
maintainer-clean: maintainer-clean-am
@@ -562,20 +584,23 @@ ps: ps-am
ps-am:
-uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
- uninstall-info-am
+uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS
+
+.MAKE: install-am install-strip
.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-binSCRIPTS install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
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
+ uninstall-binSCRIPTS
lg.cgi: Makefile $(srcdir)/lg.cgi.in
diff --git a/bin/agmrancid.in b/bin/agmrancid.in
new file mode 100644
index 0000000..0542bd2
--- /dev/null
+++ b/bin/agmrancid.in
@@ -0,0 +1,493 @@
+#! @PERLV_PATH@
+##
+## $Id: agmrancid.in,v 1.2 2006/12/06 00:40:54 heas Exp $
+##
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 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 Cisco AGMs.
+#
+# RANCID - Really Awesome New Cisco confIg Differ
+#
+# usage: rancid [-dV] [-l] [-f filename | hostname]
+#
+use Getopt::Std;
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
+$log = $opt_l;
+$debug = $opt_d;
+$file = $opt_f;
+$host = $ARGV[0];
+$clean_run = 0;
+$found_end = 0;
+$found_version = 0;
+$found_env = 0;
+$found_diag = 0;
+$timeo = 90; # clogin timeout in seconds
+
+# the AGM kicks us off if it does not know our terminal type
+$ENV{'TERM'} = "dumb";
+
+my(@commandtable, %commands, @commands);# command lists
+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);
+ my($slaveslot);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ if (/^$prompt/) { $found_version=1; last};
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if /Line has invalid autocommand /;
+ return(1) if /(Invalid input detected|Type help or )/;
+ return(-1) if (/command authorization failed/i);
+ return(0) if ($found_version); # Only do this routine once
+ # the pager can not be disabled per-session on the PIX
+ if (/^(-+More-+)/i) {
+ my($len) = length($1);
+ s/^$1\s{$len}//;
+ }
+
+ /^Cisco Anomaly Guard Image /i &&
+ ProcessHistory("COMMENTS","keysort","B1", "! $_") && next;
+ /^MDM agent /i &&
+ ProcessHistory("COMMENTS","keysort","B1", "! $_") && next;
+ }
+ return(0);
+}
+
+# This routine parses "show diag"
+# This will create arrarys for hw info.
+sub ShowDiag {
+ print STDERR " In ShowDiag: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ if (/^$prompt/) { $found_diag=1; last};
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if /Line has invalid autocommand /;
+ return(1) if /(Invalid input detected|Type help or )/;
+ return(-1) if (/command authorization failed/i);
+ return(0) if ($found_diag); # Only do this routine once
+ /^$/ && next;
+ # the pager can not be disabled per-session on the PIX
+ if (/^(-+More-+)/i) {
+ my($len) = length($1);
+ s/^$1\s{$len}//;
+ }
+
+ /^Cisco Anomaly Guard Image /i && next;
+ /^... ... \d+ \d+:\d+:\d+ \w \d+$/ && next;
+ /^Copyright /i && next;
+ /^All rights /i && next;
+ /sample loss:/i && next;
+ /forward failures /i && next;
+
+ ProcessHistory("DIAG","keysort","C1","! $_");
+ }
+ ProcessHistory("DIAG","","","!\n");
+ return(0);
+}
+
+# This routine processes a "write term"
+sub WriteTerm {
+ print STDERR " In WriteTerm: $_" if ($debug);
+ my($lineauto,$comment,$linecnt) = (0,0,0);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ return(1) if /Line has invalid autocommand /;
+ return(1) if (/(Invalid input detected|Type help or )/i);
+ return(-1) if (/command authorization failed/i);
+ # the pager can not be disabled per-session on the PIX
+ if (/^(-+More-+)/i) {
+ my($len) = length($1);
+ s/^$1\s{$len}//;
+ }
+
+ /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 consecutive comment/blank 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
+ /^ 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)( level \w+)? encrypted ((.)\S+)/) {
+ if ($filter_pwds >= 2) {
+ ProcessHistory("USER","keysort","$1",
+ "!$1$2$3 encrypted <removed>\n");
+ } elsif ($filter_pwds >= 1 && $5 ne "\$") {
+ ProcessHistory("USER","keysort","$1",
+ "!$1$2$3 encrypted <removed>\n");
+ } else {
+ ProcessHistory("USER","keysort","$1","$_");
+ }
+ next;
+ }
+
+ if ((/^(enable )?(password|passwd)( level \w+)? encrypted [^\$]/ &&
+ $filter_pwds >= 1) ||
+ (/^(enable )?(password|passwd)( level \w+)? encrypted [^\$]/ &&
+ $filter_pwds >= 2)) {
+ ProcessHistory("ENABLE","","","!$1$2$3 <removed>\n");
+ next;
+ }
+ if (/^username (\S+)(\s.*)? encrypted ((.)\S+)/) {
+ if ($filter_pwds >= 2) {
+ ProcessHistory("USER","keysort","$1",
+ "!username $1$2 encrypted <removed>\n");
+ } elsif ($filter_pwds >= 1 && $4 ne "\$") {
+ ProcessHistory("USER","keysort","$1",
+ "!username $1$2 encrypted <removed>\n");
+ } else {
+ ProcessHistory("USER","keysort","$1","$_");
+ }
+ next;
+ }
+ if (/^(\s*)password / && $filter_pwds >= 1) {
+ ProcessHistory("LINE-PASS","","","!$1password <removed>\n");
+ next;
+ }
+ if (/^(\s*)secret / && $filter_pwds >= 2) {
+ ProcessHistory("LINE-PASS","","","!$1secret <removed>\n");
+ next;
+ }
+ # 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;
+
+ # order logging statements
+ /^logging host (\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 trap-dest (\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)));
+ if ($token eq '3') {
+ $line .= " " . join(' ', ($token, shift(@tokens)));
+ }
+ } elsif ($token eq 'vrf') {
+ $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 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)\s(\w*[-\s(\s\S+])*\s?key) \d \w+/
+ && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>$'"); 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. the ": " game is for the PIX
+ if (/^(: +)?end$/) {
+ $found_end = 1;
+ return(1);
+ }
+ }
+ # The AGM lacks a definitive "end of config" marker. If we have seen at
+ # least 5 lines of write term o/p, we can be reasonably sure that we got
+ # the config.
+ if ($linecnt > 5) {
+ $found_end = 1;
+ return(1);
+ }
+
+ return(0);
+}
+
+# dummy function
+sub DoNothing {print STDOUT;}
+
+# Main
+@commandtable = (
+ {'show version' => 'ShowVersion'},
+ {'show diagnostic-info' => 'ShowDiag'},
+ {'show running-config' => 'WriteTerm'},
+);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
+
+$cisco_cmds=join(";",@commands);
+$cmds_regexp=join("|",@commands);
+
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
+open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
+select(OUTPUT);
+# make OUTPUT unbuffered if debugging
+if ($debug) { $| = 1; }
+
+if ($file) {
+ print STDERR "opening file $host\n" if ($debug);
+ print STDOUT "opening file $host\n" if ($log);
+ open(INPUT,"<$host") || die "open failed for $host: $!\n";
+} else {
+ print STDERR "executing hlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug);
+ print STDOUT "executing hlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log);
+ if (defined($ENV{NOPIPE})) {
+ system "hlogin -t $timeo -c \"$cisco_cmds\" $host </dev/null > $host.raw 2>&1" || die "hlogin failed for $host: $!\n";
+ open(INPUT, "< $host.raw") || die "hlogin failed for $host: $!\n";
+ } else {
+ open(INPUT,"hlogin -t $timeo -c \"$cisco_cmds\" $host </dev/null |") || die "hlogin failed for $host: $!\n";
+ }
+}
+
+# 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: riverhead\n!\n");
+ProcessHistory("COMMENTS","keysort","B0","!\n");
+ProcessHistory("COMMENTS","keysort","C0","!\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;
+ }
+ if (/[>#]\s?exit$/) {
+ $clean_run=1;
+ last;
+ }
+ }
+}
+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 $clean_run . " " . $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/alogin.in b/bin/alogin.in
index 91623fb..27286d7 100644
--- a/bin/alogin.in
+++ b/bin/alogin.in
@@ -1,8 +1,9 @@
#! @EXPECT_PATH@ --
##
-## $Id: alogin.in,v 1.22 2004/01/11 05:39:15 heas Exp $
+## $Id: alogin.in,v 1.35 2006/12/05 16:50:52 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -24,7 +25,7 @@
# alogin - Alteon WebOS switch login
#
# afort@choqolat.org is responsible for this particular mess
-# (andrew fort)
+# (andrew fort)
#
# Usage line
@@ -43,7 +44,7 @@ set password_file $env(HOME)/.cloginrc
set do_command 0
set do_script 0
# The default is to automatically enable
-set enable 1
+set avenable 1
# The default is that you login non-enabled (tacacs can have you login already
# enabled)
set avautoenable 0
@@ -52,7 +53,7 @@ set avautoenable 0
set do_passwd 1
# Find the user in the ENV, or use the unix userid.
-if {[ info exists env(CISCO_USER) ] } {
+if {[ info exists env(CISCO_USER) ]} {
set default_user $env(CISCO_USER)
} elseif {[ info exists env(USER) ]} {
set default_user $env(USER)
@@ -65,9 +66,12 @@ if {[ info exists env(CISCO_USER) ] } {
if [ catch {exec id} reason ] {
send_error "\nError: could not exec id: $reason\n"
exit 1
- }
+ }
regexp {\(([^)]*)} "$reason" junk default_user
-}
+}
+if {[ info exists env(CLOGINRC) ]} {
+ set password_file $env(CLOGINRC)
+}
# Sometimes routers take awhile to answer (the default is 10 sec)
set timeout 45
@@ -85,13 +89,16 @@ for {set i 0} {$i < $argc} {incr i} {
set username [ lindex $argv $i ]
}
# VTY Password
- } -v* -
- -v* {
+ } -v* {
if {! [ regexp .\[vV\](.+) $arg ignore passwd]} {
incr i
set passwd [ lindex $argv $i ]
}
set do_passwd 0
+ # Version string
+ } -V* {
+ send_user "@PACKAGE@ @VERSION@\n"
+ exit 0
# Enable Username
} -w* -
-W* {
@@ -264,6 +271,7 @@ proc source_password_file { password_file } {
}
# Log into the router.
+# returns: 0 on success, 1 on failure
proc login { router user userpswd passwd prompt cmethod cyphertype } {
global spawn_id in_proc do_command do_script
global u_prompt p_prompt sshcmd
@@ -273,6 +281,7 @@ proc login { router user userpswd passwd prompt cmethod cyphertype } {
# try each of the connection methods in $cmethod until one is successful
set progs [llength $cmethod]
foreach prog [lrange $cmethod 0 end] {
+ incr progs -1
if [string match "telnet*" $prog] {
regexp {telnet(:([^[:space:]]+))*} $prog command suffix port
if {"$port" == ""} {
@@ -282,23 +291,23 @@ proc login { router user userpswd passwd prompt cmethod cyphertype } {
}
if { $retval } {
send_user "\nError: telnet failed: $reason\n"
- exit 1
+ return 1
}
- } elseif ![string compare $prog "ssh"] {
+ } 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
+ return 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"
+ } elseif ![string compare $prog "rsh"] {
+ send_error "\nError: unsupported method: rsh\n"
+ if { $progs == 0 } {
+ return 1
+ }
+ continue;
+ } else {
+ send_user "\nError: unknown connection method: $prog\n"
return 1
- }
- incr progs -1
+ }
sleep 0.3
# This helps cleanup each expect clause.
@@ -415,15 +424,16 @@ proc run_commands { prompt command } {
}
send "exit\r"
expect {
- -re "^WARNING: There are unsaved configuration changes."
- {
- send "y\r"
- exp_continue
- }
- "\n" { exp_continue }
- "\[^\n\r *]*Session terminated" { return 0 }
- timeout { return 0 }
- eof { return 0 }
+ -re "^WARNING: There are unsaved configuration changes." {
+ send "y\r"
+ exp_continue
+ }
+ "\n" { exp_continue }
+ "\[^\n\r *]*Session terminated" { return 0 }
+ timeout { catch {close}; wait
+ return 0
+ }
+ eof { return 0 }
}
set in_proc 0
}
diff --git a/bin/arancid.in b/bin/arancid.in
index a2bf1ef..165a187 100644
--- a/bin/arancid.in
+++ b/bin/arancid.in
@@ -1,12 +1,13 @@
#! @PERLV_PATH@
##
-## $Id: arancid.in,v 1.14 2004/01/11 03:49:13 heas Exp $
+## $Id: arancid.in,v 1.22 2006/10/05 04:27:42 heas Exp $
##
-## Hacked version of rancid for Alteon WebOS switches
+## @PACKAGE@ @VERSION@
+## Hacked version of rancid for Alteon WebOS switches
## tested with: ad3 v8.1.18
## afort@choqolat.org (andrew fort)
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -24,13 +25,17 @@
##
#
# RANCID - Really Awesome New Cisco confIg Differ
-#
+#
# arancid - Alteon WebOS plugin for rancid
#
-# usage: arancid [-d] [-l] [-f filename | $host]
+# usage: arancid [-dV] [-l] [-f filename | hostname]
#
use Getopt::Std;
-getopts('dfl');
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
@@ -38,13 +43,16 @@ $host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
$prompt = "#";
-$timeo = 90; # clogin timeout in seconds
+$timeo = 90; # alogin timeout in seconds
+
+my(@commandtable, %commands, @commands);# command lists
+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) {
+ 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;
}
@@ -66,10 +74,10 @@ sub ProcessHistory {
sub numerically { $a <=> $b; }
-# This is a sort routing that will sort numerically on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
@@ -79,10 +87,10 @@ sub keynsort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
@@ -92,10 +100,10 @@ sub keysort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
@@ -105,9 +113,9 @@ sub valsort{
@sorted_lines;
}
-# This is a numerical sort routing (ascending).
+# This is a numerical sort routine (ascending).
sub numsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a <=> $b} keys %lines) {
@@ -121,7 +129,7 @@ sub numsort {
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
@@ -134,7 +142,7 @@ sub ipsort {
# 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]));
+ $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
@@ -142,23 +150,23 @@ sub sortbyipaddr {
# This routine parses "/info/sys" (cf. show version)
sub ShowVersion {
- print STDERR " In ShowVersion: $_" if ($debug);
+ print STDERR " In ShowVersion: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^>>.*$prompt/);
+ next if(/^(\s*|\s*$cmd\s*)$/);
- while (<INPUT>) {
- tr/\015//d;
- last if (/^>>.*$prompt/);
- next if(/^(\s*|\s*$cmd\s*)$/);
-
- /^(ACEdirector.*|ACEswitch.*|Alteon.*)/i &&
+ /^(ACEdirector.*|ACEswitch.*|Alteon.*)/i &&
ProcessHistory("COMMENTS","keysort","A1", "\/\*Model: $1\n") && next;
/^Software Version\s+(.*?)\s\((.*)\)/i &&
ProcessHistory("COMMENTS","keysort","B1", "\/\*Image: Software: $1 ($2)\n") && next;
/^Hardware Part No:\s+(.*?)\s+/i &&
ProcessHistory("COMMENTS","keysort","A2", "\/\*Hardware part no: $1\n") && next;
/^MAC address:\s+([0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2})/i &&
- ProcessHistory("COMMENTS","keysort","C1", "\/\*Base MAC address: $1\n") && next;
- }
- return(0);
+ ProcessHistory("COMMENTS","keysort","C1", "\/\*Base MAC address: $1\n") && next;
+ }
+ return(0);
}
# This routine processes a "/cfg/dump"
@@ -170,10 +178,10 @@ sub WriteTerm {
# now just copy it verbatim to the history file
while (<INPUT>) {
- tr/\015//d;
- last if(/^>>.*$prompt/);
+ tr/\015//d;
+ last if(/^>>.*$prompt/);
chop;
- if (/(rcomm|wcomm|t1com|t2com)(\s+)(.*)/ &&
+ if (/(rcomm|wcomm|t1com|t2com)(\s+)(.*)/ &&
defined($ENV{'NOCOMMSTR'})) {
ProcessHistory("","","","\/\*\t$1$2\"<removed>\"\n") && next;
}
@@ -183,8 +191,8 @@ sub WriteTerm {
next if (/^\/\* Configuration dump taken/i);
next if (/^\/\* Version.*Base MAC.*/i);
- if (/^\/?script end/) {
- $found_end = 1;
+ if (/^\/?script end/) {
+ $found_end = 1;
ProcessHistory("","","","$_\n");
return(1);
}
@@ -198,19 +206,27 @@ sub WriteTerm {
sub DoNothing {print STDOUT;}
# Main
-%commands=(
- '/info/sys' => "ShowVersion",
- '/cfg/dump' => "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=(
- "/info/sys",
- "/cfg/dump",
+@commandtable = (
+ {'/info/sys' => 'ShowVersion'},
+ {'/cfg/dump' => 'WriteTerm'}
);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
+
$cisco_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
@@ -237,13 +253,13 @@ ProcessHistory("COMMENTS","keysort","F0","\/\*\n");
TOP: while(<INPUT>) {
tr/\015//d;
if (/^>>.*$prompt exit/) {
- $clean_run=1;
- last;
+ $clean_run=1;
+ last;
}
while (/>>.*$prompt\s*($cmds_regexp)\s*$/) {
- $cmd = $1;
- if (!defined($prompt)) {
+ $cmd = $1;
+ if (!defined($prompt)) {
$prompt = ($_ =~ /^([^#]+#)/)[0];
$prompt =~ s/([][}{)(\\])/\\$1/g;
print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
@@ -252,7 +268,7 @@ TOP: while(<INPUT>) {
if (!defined($commands{$cmd})) {
print STDERR "$host: found unexpected command - \"$cmd\"\n";
$clean_run = 0;
- last TOP;
+ last TOP;
}
$rval = &{$commands{$cmd}};
delete($commands{$cmd});
diff --git a/bin/blogin.in b/bin/blogin.in
index 92d2e8c..37c28e8 100644
--- a/bin/blogin.in
+++ b/bin/blogin.in
@@ -1,8 +1,9 @@
#! @EXPECT_PATH@ --
##
-## $Id: blogin.in,v 1.22 2004/01/11 05:39:15 heas Exp $
+## $Id: blogin.in,v 1.36 2006/12/08 21:28:25 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -46,7 +47,7 @@ set password_file $env(HOME)/.cloginrc
set do_command 0
set do_script 0
# The default is to automatically enable
-set enable 0
+set avenable 0
# The default is that you login non-enabled (tacacs can have you login already
# enabled)
set avautoenable 0
@@ -56,7 +57,7 @@ set do_passwd 1
set do_enapasswd 0
# Find the user in the ENV, or use the unix userid.
-if {[ info exists env(CISCO_USER) ] } {
+if {[ info exists env(CISCO_USER) ]} {
set default_user $env(CISCO_USER)
} elseif {[ info exists env(USER) ]} {
set default_user $env(USER)
@@ -72,6 +73,9 @@ if {[ info exists env(CISCO_USER) ] } {
}
regexp {\(([^)]*)} "$reason" junk default_user
}
+if {[ info exists env(CLOGINRC) ]} {
+ set password_file $env(CLOGINRC)
+}
# Sometimes routers take awhile to answer (the default is 10 sec)
set timeout 45
@@ -97,13 +101,16 @@ for {set i 0} {$i < $argc} {incr i} {
}
set do_passwd 0
# VTY Password
- } -v* -
- -v* {
+ } -v* {
if {! [ regexp .\[vV\](.+) $arg ignore passwd]} {
incr i
set passwd [ lindex $argv $i ]
}
set do_passwd 0
+ # Version string
+ } -V* {
+ send_user "@PACKAGE@ @VERSION@\n"
+ exit 0
# Enable Username
} -w* -
-W* {
@@ -112,14 +119,14 @@ for {set i 0} {$i < $argc} {incr i} {
set enausername [ lindex $argv $i ]
}
# Environment variable to pass to -s scripts
- } -E*
+ } -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*
{
@@ -183,11 +190,11 @@ for {set i 0} {$i < $argc} {incr i} {
set do_command 1
# Do we enable?
} -noenable {
- set enable 0
+ set avenable 0
# Does tacacs automatically enable us?
} -autoenable {
set avautoenable 1
- set enable 0
+ set avenable 0
} -* {
send_user "\nError: Unknown argument! $arg\n"
send_user $usage
@@ -237,25 +244,25 @@ proc label { host } {
# add password * hanky-pie
proc add {var args} { global int_$var ; lappend int_$var $args}
proc include {args} {
- global env
- regsub -all "(^{|}$)" $args {} 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
+ upvar int_$var list
if { [info exists list] } {
foreach line $list {
if { [string match [lindex $line 0] $router ] } {
return [lrange $line 1 end]
- }
- }
- }
- return {}
-}
+ }
+ }
+ }
+ 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
@@ -280,6 +287,7 @@ proc source_password_file { password_file } {
}
# Log into the router.
+# returns: 0 on success, 1 on failure
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 sshcmd
@@ -288,6 +296,7 @@ proc login { router user userpswd passwd enapasswd prompt cmethod cyphertype } {
# try each of the connection methods in $cmethod until one is successful
set progs [llength $cmethod]
foreach prog [lrange $cmethod 0 end] {
+ incr progs -1
if [string match "telnet*" $prog] {
regexp {telnet(:([^[:space:]]+))*} $prog command suffix port
if {"$port" == ""} {
@@ -297,23 +306,23 @@ proc login { router user userpswd passwd enapasswd prompt cmethod cyphertype } {
}
if { $retval } {
send_user "\nError: telnet failed: $reason\n"
- exit 1
+ return 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
+ return 1
}
} elseif ![string compare $prog "rsh"] {
- if [ catch {spawn rsh -l $user $router} reason ] {
- send_user "\nError: rsh failed: $reason\n"
- exit 1
+ send_error "\nError: unsupported method: rsh\n"
+ if { $progs == 0 } {
+ return 1
}
+ continue;
} else {
- puts "\nError: unknown connection method: $prog"
+ send_user "\nError: unknown connection method: $prog\n"
return 1
}
- incr progs -1
sleep 0.3
# This helps cleanup each expect clause.
@@ -466,9 +475,11 @@ proc run_commands { prompt command } {
}
send "logout\r"
expect {
- "\n" { exp_continue }
- timeout { return 0 }
- eof { return 0 }
+ "\n" { exp_continue }
+ timeout { catch {close}; wait
+ return 0
+ }
+ eof { return 0 }
}
set in_proc 0
}
@@ -498,6 +509,7 @@ foreach router [lrange $argv $i end] {
set prompt "#"
} else {
set autoenable 0
+ set enable $avenable
set prompt ">"
}
}
@@ -520,6 +532,9 @@ foreach router [lrange $argv $i end] {
}
set passwd [join [lindex $pswd 0] ""]
set enapasswd [join [lindex $pswd 1] ""]
+ } else {
+ set passwd $userpasswd
+ set enapasswd $enapasswd
}
# Figure out username
@@ -593,7 +608,7 @@ foreach router [lrange $argv $i end] {
if { $enable } {
if {[do_enable $enauser $enapasswd]} {
if { $do_command || $do_script } {
- close; wait
+ catch {close}; catch {wait}
continue
}
}
diff --git a/bin/brancid.in b/bin/brancid.in
index c2e602e..35f3f2f 100644
--- a/bin/brancid.in
+++ b/bin/brancid.in
@@ -1,9 +1,10 @@
#! @PERLV_PATH@
##
-## $Id: brancid.in,v 1.16 2004/01/11 03:49:13 heas Exp $
+## $Id: brancid.in,v 1.24 2006/10/05 04:27:42 heas Exp $
## hacked version of Hank's rancid - this one tries to deal with Bay's.
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -22,25 +23,30 @@
#
# RANCID - Really Awesome New Cisco confIg Differ
#
-# usage: rancid [-d] [-l] [-f filename | $host]
+# usage: rancid [-dV] [-l] [-f filename | hostname]
#
use Getopt::Std;
-getopts('dfl');
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
-$timeo = 90; # blogin timeout in seconds
+$timeo = 90; # blogin timeout in seconds
-my(%filter_pwds); # password filtering mode
+my(@commandtable, %commands, @commands);# command lists
+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) {
+ 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;
}
@@ -62,10 +68,10 @@ sub ProcessHistory {
sub numerically { $a <=> $b; }
-# This is a sort routing that will sort numerically on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
@@ -75,10 +81,10 @@ sub keynsort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
@@ -88,10 +94,10 @@ sub keysort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
@@ -101,9 +107,9 @@ sub valsort{
@sorted_lines;
}
-# This is a numerical sort routing (ascending).
+# This is a numerical sort routine (ascending).
sub numsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a <=> $b} keys %lines) {
@@ -117,7 +123,7 @@ sub numsort {
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
@@ -130,7 +136,7 @@ sub ipsort {
# 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]));
+ $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
@@ -158,8 +164,8 @@ sub ShowConfig {
}
# ProcessHistory("","","","!$_");
if (/exit$/) {
- $found_end = 1;
- return(1);
+ $found_end = 1;
+ return(1);
}
return(0);
}
@@ -186,23 +192,29 @@ sub RunCommand {
sub DoNothing {print STDOUT;}
# Main
-%commands=(
- 'bcc' => "RunCommand",
- 'show config' => "ShowConfig",
- 'show config -all' => "ShowConfig",
- 'exit' => "RunCommand"
-);
-# keys() doesnt return things in the order entered and the order of the
-# cmds is important (show version first and write term last). pita
-@commands=(
- "bcc",
- "show config",
- "show config -all",
- "exit"
+@commandtable = (
+ {'bcc' => 'RunCommand'},
+ {'show config' => 'ShowConfig'},
+ {'show config -all' => 'ShowConfig'},
+ {'exit' => 'RunCommand'}
);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
+
$cisco_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
@@ -225,7 +237,7 @@ if ($file) {
# determine password filtering mode
if ($ENV{"FILTER_PWDS"} =~ /no/i) {
- $filter_pwds = 0;
+ $filter_pwds = 0;
} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
$filter_pwds = 2;
} else {
diff --git a/bin/cat5rancid.in b/bin/cat5rancid.in
index f1214a1..bd13d65 100644
--- a/bin/cat5rancid.in
+++ b/bin/cat5rancid.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: cat5rancid.in,v 1.36 2004/01/11 03:49:13 heas Exp $
+## $Id: cat5rancid.in,v 1.47 2006/10/05 04:27:42 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -21,26 +22,31 @@
#
# RANCID - Really Awesome New Cisco confIg Differ
#
-# usage: rancid [-d] [-l] [-f filename | $host]
+# usage: rancid [-dV] [-l] [-f filename | hostname]
#
use Getopt::Std;
-getopts('dfl');
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
-$timeo = 90; # clogin timeout in seconds
+$timeo = 90; # clogin timeout in seconds
-my(%filter_pwds); # password filtering mode
+my(@commandtable, %commands, @commands);# command lists
+my(%filter_pwds); # password filtering mode
my(%modules); # module info (part from sh ver, part from sh module)
# 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) {
+ 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;
}
@@ -62,10 +68,10 @@ sub ProcessHistory {
sub numerically { $a <=> $b; }
-# This is a sort routing that will sort numerically on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
@@ -75,10 +81,10 @@ sub keynsort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
@@ -88,10 +94,10 @@ sub keysort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
@@ -101,9 +107,9 @@ sub valsort{
@sorted_lines;
}
-# This is a numerical sort routing (ascending).
+# This is a numerical sort routine (ascending).
sub numsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a <=> $b} keys %lines) {
@@ -117,7 +123,7 @@ sub numsort {
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
@@ -130,7 +136,7 @@ sub ipsort {
# 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]));
+ $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
@@ -665,14 +671,46 @@ sub ShowDiag {
return(0);
}
+# This routine parses "show inventory".
+sub ShowInventory {
+ print STDERR " In ShowInventory: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ return if (/^\s*\^$/);
+ 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*//;
+
+ chomp;
+
+ # split PID/VID line
+ if (/^(NAME: ".*,) (DESCR: .*)/) {
+ ProcessHistory("INVENTORY","","", sprintf("!%-30s%s\n", $1, $2));
+ next;
+ }
+ if (/^(PID: \w?) *, (VID: .*), (SN: .*)$/) {
+ ProcessHistory("INVENTORY","","", "!$1\n!$2\n!$3\n");
+ next;
+ }
+
+ ProcessHistory("INVENTORY","","","!$_");
+ }
+ ProcessHistory("INVENTORY","","","");
+
+ return(0);
+}
+
# This routine parses "show module"
sub ShowModule {
my($slot);
print STDERR " In ShowModule: $_" if ($debug);
OUTER:while (<INPUT>) {
- tr/\015//d;
- last if(/^$prompt/);
+ tr/\015//d;
+ last if(/^$prompt/);
# stuff module type into %module
if (/^Mod\s+Slot\s+Ports/) {
<INPUT>;
@@ -696,7 +734,7 @@ OUTER:while (<INPUT>) {
}
next;
}
- # one does it one way... pita
+ # one does it one way... pita
if (/^Mod\s+Module-Name\s+Ports/) {
<INPUT>;
#my($slot);
@@ -713,7 +751,7 @@ OUTER:while (<INPUT>) {
}
next;
}
- # daughter boards
+ # daughter boards
if (/^Mod\s+Sub-Type/) {
<INPUT>;
my($slot, $board);
@@ -767,7 +805,7 @@ OUTER:while (<INPUT>) {
ProcessHistory("MODS","","",$model);
if ($dboards) {ProcessHistory("MODS","","",$dboards);}
}
-}
+}
# This routine processes a "show port ifindex"
sub ShowPortIfindex {
@@ -790,7 +828,10 @@ sub ShowPortIfindex {
sub WriteTerm {
print STDERR " In WriteTerm: $_" if ($debug);
- ProcessHistory("","","","!\n");
+ if (! $found_end) {
+ ProcessHistory("","","","!\n");
+ }
+
while (<INPUT>) {
tr/\015//d;
last if (/^$prompt/);
@@ -822,9 +863,9 @@ sub WriteTerm {
/^#Time: / && next;
# Dog gone Cool matches to process the rest of the config
- /^#time: / && next; # kill time:
- /^tftp-server flash / && next; # kill any tftp remains
- /^ntp clock-period / && next; # kill ntp clock-period
+ /^#time: / && next; # kill time:
+ /^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
if (/^enable password / && $filter_pwds >= 1) {
@@ -925,15 +966,15 @@ sub WriteTerm {
# order logging statements
/^set logging server (\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>
+ # order/prune snmp-server host statements
+ # we only prune lines of the form
+ # snmp-server host a.b.c.d <community>
if (/^set snmp trap (\d+\.\d+\.\d+\.\d+) /) {
if (defined($ENV{'NOCOMMSTR'})) {
ProcessHistory("SNMPSERVERHOST","ipsort","$1","!set snmp trap $1 <removed>\n");
} else {
ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_");
- }
+ }
next;
}
if (/^(set snmp community) (\S+) (\S+)/) {
@@ -991,39 +1032,39 @@ sub WriteTerm {
sub DoNothing {print STDOUT;}
# Main
-%commands=(
- 'show version' => "ShowVersion",
- 'show boot' => "ShowBoot",
- 'show flash' => "ShowFlash",
- 'dir bootflash:' => "DirSlotN",
- 'dir slot0:' => "DirSlotN",
- 'dir slot1:' => "DirSlotN",
- 'dir sup-bootflash:' => "DirSlotN",
- '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
-# cmds is important (show version first and write term last). pita
-@commands=(
- "show version",
- "show boot",
- "show flash",
- "dir bootflash:",
- "dir slot0:",
- "dir slot1:",
- "dir sup-bootflash:",
- "dir sup-microcode:",
- "show module",
- "show port ifindex",
- "write term all",
- "write term"
+@commandtable = (
+ {'show version' => 'ShowVersion'},
+ {'show boot' => 'ShowBoot'},
+ {'show flash' => 'ShowFlash'},
+ {'dir bootflash:' => 'DirSlotN'},
+ {'dir slot0:' => 'DirSlotN'},
+ {'dir slot1:' => 'DirSlotN'},
+ {'dir sup-bootflash:' => 'DirSlotN'},
+ {'dir sup-microcode:' => 'DirSlotN'},
+ {'show module' => 'ShowModule'},
+ {'show inventory raw' => 'ShowInventory'},
+ {'show port ifindex' => 'ShowPortIfindex'},
+ {'write term all' => 'WriteTerm'},
+ {'write term' => 'WriteTerm'},
+ {'show running-config' => 'WriteTerm'}
);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
+
$cisco_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
diff --git a/bin/clogin.in b/bin/clogin.in
index b05b56e..b7ac1a2 100644
--- a/bin/clogin.in
+++ b/bin/clogin.in
@@ -1,8 +1,9 @@
#! @EXPECT_PATH@ --
##
-## $Id: clogin.in,v 1.72 2004/01/11 05:39:15 heas Exp $
+## $Id: clogin.in,v 1.107 2006/12/08 21:28:25 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -47,7 +48,7 @@ set password_file $env(HOME)/.cloginrc
set do_command 0
set do_script 0
# The default is to automatically enable
-set enable 1
+set avenable 1
# The default is that you login non-enabled (tacacs can have you login already
# enabled)
set avautoenable 0
@@ -55,11 +56,11 @@ set avautoenable 0
# tracks if we receive them on the command line.
set do_passwd 1
set do_enapasswd 1
-# attempt at platform switching.
-set platform ""
+#
+set send_human {.4 .4 .7 .3 5}
# Find the user in the ENV, or use the unix userid.
-if {[ info exists env(CISCO_USER) ] } {
+if {[ info exists env(CISCO_USER) ]} {
set default_user $env(CISCO_USER)
} elseif {[ info exists env(USER) ]} {
set default_user $env(USER)
@@ -75,6 +76,9 @@ if {[ info exists env(CISCO_USER) ] } {
}
regexp {\(([^)]*)} "$reason" junk default_user
}
+if {[ info exists env(CLOGINRC) ]} {
+ set password_file $env(CLOGINRC)
+}
# Sometimes routers take awhile to answer (the default is 10 sec)
set timeout 45
@@ -100,13 +104,16 @@ for {set i 0} {$i < $argc} {incr i} {
}
set do_passwd 0
# VTY Password
- } -v* -
- -v* {
+ } -v* {
if {! [ regexp .\[vV\](.+) $arg ignore passwd]} {
incr i
set passwd [ lindex $argv $i ]
}
set do_passwd 0
+ # Version string
+ } -V* {
+ send_user "@PACKAGE@ @VERSION@\n"
+ exit 0
# Enable Username
} -w* -
-W* {
@@ -189,11 +196,11 @@ for {set i 0} {$i < $argc} {incr i} {
set do_command 1
# Do we enable?
} -noenable {
- set enable 0
+ set avenable 0
# Does tacacs automatically enable us?
} -autoenable {
set avautoenable 1
- set enable 0
+ set avenable 0
} -* {
send_user "\nError: Unknown argument! $arg\n"
send_user $usage
@@ -286,6 +293,7 @@ proc source_password_file { password_file } {
}
# Log into the router.
+# returns: 0 on success, 1 on failure, -1 if rsh was used successfully
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 usercmd usercmd_chat
@@ -295,6 +303,7 @@ proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
# try each of the connection methods in $cmethod until one is successful
set progs [llength $cmethod]
foreach prog [lrange $cmethod 0 end] {
+ incr progs -1
if [string match "telnet*" $prog] {
regexp {telnet(:([^[:space:]]+))*} $prog command suffix port
if {"$port" == ""} {
@@ -304,12 +313,19 @@ proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
}
if { $retval } {
send_user "\nError: telnet failed: $reason\n"
- exit 1
+ return 1
}
- } elseif ![string compare $prog "ssh"] {
- if [ catch {spawn $sshcmd -c $cyphertype -x -l $user $router} reason ] {
+ } elseif [string match "ssh*" $prog] {
+ regexp {ssh(:([^[:space:]]+))*} $prog command suffix port
+ if {"$port" == ""} {
+ set retval [ catch {spawn $sshcmd -c $cyphertype -x -l $user $router} reason ]
+
+ } else {
+ set retval [ catch {spawn $sshcmd -c $cyphertype -x -l $user -p $port $router} reason ]
+ }
+ if { $retval } {
send_user "\nError: $sshcmd failed: $reason\n"
- exit 1
+ return 1
}
} elseif [string match "usercmd" $prog] { # user supplies connect cmd
set retval [ catch {eval spawn $usercmd} reason ]
@@ -328,15 +344,83 @@ proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
}
}
} elseif ![string compare $prog "rsh"] {
- if [ catch {spawn rsh -l $user $router} reason ] {
- send_user "\nError: rsh failed: $reason\n"
- exit 1
+ global command
+
+ if { ! $do_command } {
+ if { [llength $cmethod] == 1 } {
+ send_user "\nError: rsh is an invalid method for -x and "
+ send_user "interactive logins\n"
+ }
+ if { $progs == 0 } {
+ return 1
+ }
+ continue;
+ }
+
+ set commands [split $command \;]
+ set num_commands [llength $commands]
+ set rshfail 0
+ for {set i 0} {$i < $num_commands && !$rshfail} { incr i} {
+ log_user 0
+ set retval [ catch {spawn rsh $user@$router [lindex $commands $i] } reason ]
+ if { $retval } {
+ send_user "\nError: rsh failed: $reason\n"
+ log_user 1; return 1
+ }
+ send_user "$router# [lindex $commands $i]\n"
+
+ # rcmd does not get a pager and no prompts, so we just have to
+ # look for failures & lines.
+ expect {
+ "Connection refused" { catch {close}; wait;
+ send_user "\nError: Connection\
+ Refused ($prog): $router\n"
+ set rshfail 1
+ }
+ -re "(Connection closed by|Connection to \[^\n\r]+ closed)" {
+ catch {close}; wait;
+ send_user "\nError: Connection\
+ closed ($prog): $router\n"
+ set rshfail 1
+ }
+ "Host is unreachable" { catch {close}; wait;
+ send_user "\nError: Host Unreachable:\
+ $router\n"
+ set rshfail 1
+ }
+ "No address associated with" {
+ catch {close}; wait;
+ send_user "\nError: Unknown host\
+ $router\n"
+ set rshfail 1
+ }
+ -re "\b+" { exp_continue }
+ -re "\[\n\r]+" { send_user -- "$expect_out(buffer)"
+ exp_continue
+ }
+ timeout { catch {close}; wait
+ send_user "\nError: TIMEOUT reached\n"
+ set rshfail 1
+ }
+ eof { catch {close}; wait }
+ }
+ log_user 1
+ }
+ if { $rshfail } {
+ if { !$progs } {
+ return 1
+ } else {
+ continue
+ }
}
+ # fake the end of the session for rancid.
+ send_user "$router# exit\n"
+ # return rsh "success"
+ return -1
} else {
- puts "\nError: unknown connection method: $prog"
+ send_user "\nError: unknown connection method: $prog\n"
return 1
}
- incr progs -1
sleep 0.3
# This helps cleanup each expect clause.
@@ -419,18 +503,26 @@ proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
send_user "\nError: Check your passwd for $router\n"
return 1
}
- -re "^Enter Selection: " {
+ "Press any key to continue." {
+ # send_user "Pressing the ANY key\n"
+ send "\r"
+ exp_continue
+ }
+ -re "Enter Selection: " {
# Catalyst 1900s have some lame menu. Enter
# K to reach a command-line.
send "K\r"
- exp_continue;
+ exp_continue
+ }
+ -re "Last login:" {
+ exp_continue
}
-re "@\[^\r\n]+ $p_prompt" {
- # ssh pwd prompt
- sleep 1
- send "$userpswd\r"
- exp_continue
- }
+ # ssh pwd prompt
+ sleep 1
+ send "$userpswd\r"
+ exp_continue
+ }
-re "$u_prompt" {
send "$user\r"
set uprompt_seen 1
@@ -469,8 +561,8 @@ proc do_enable { enauser enapasswd } {
-re "$e_prompt" { send "$enapasswd\r"; exp_continue}
"#" { set prompt "#" }
"(enable)" { set prompt "> (enable) " }
- "denied" {
- # % Access denied - from local auth
+ -re "(denied|Sorry|Incorrect)" {
+ # % Access denied - from local auth and poss. others
send_user "\nError: Check your Enable passwd\n";
return 1
}
@@ -501,6 +593,9 @@ proc run_commands { prompt command } {
if { [ string compare "extreme" "$platform" ] } {
if [ regexp -- ".*> .*enable" "$prompt" ] {
send "set length 0\r"
+ # This is ugly, but reduces code duplication, allowing the
+ # subsequent expects to handle everything as normal.
+ set command "set logging session disable;$command"
} else {
send "term length 0\r"
}
@@ -508,7 +603,7 @@ proc run_commands { prompt command } {
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
+ regsub -all {^(.{1,11}).*([#>])$} $reprompt {\1([^#>\r\n]+)?[#>](\\([^)\\r\\n]+\\))?} reprompt
expect {
-re $reprompt {}
-re "\[\n\r]+" { exp_continue }
@@ -534,6 +629,9 @@ proc run_commands { prompt command } {
}
-re "^\[^\n\r]*$reprompt." { send_user -- "$expect_out(buffer)"
exp_continue }
+ -re "^--More--\r\n" { # specific match c1900 pager
+ send " "
+ exp_continue }
-re "\[\n\r]+" { send_user -- "$expect_out(buffer)"
exp_continue }
-re "\[^\r\n]*Press <SPACE> to cont\[^\r\n]*" {
@@ -544,7 +642,7 @@ proc run_commands { prompt command } {
}
exp_continue
}
- -re "^ --More--\[^\n\r]*" {
+ -re "^ *--More--\[^\n\r]*" {
send " "
exp_continue }
-re "^<-+ More -+>\[^\n\r]*" {
@@ -564,6 +662,9 @@ proc run_commands { prompt command } {
}
-re "^\[^\n\r]*$reprompt." { send_user -- "$expect_out(buffer)"
exp_continue }
+ -re "^--More--\r\n" { # specific match c1900 pager
+ send " "
+ exp_continue }
-re "\[\n\r]+" { send_user -- "$expect_out(buffer)"
exp_continue }
-re "\[^\r\n]*Press <SPACE> to cont\[^\r\n]*" {
@@ -574,7 +675,7 @@ proc run_commands { prompt command } {
}
exp_continue
}
- -re "^ --More--\[^\n\r]*" {
+ -re "^ *--More--\[^\n\r]*" {
send " "
exp_continue }
-re "^<-+ More -+>\[^\n\r]*" {
@@ -586,24 +687,34 @@ proc run_commands { prompt command } {
log_user 1
if { [ string compare "extreme" "$platform" ] } {
- send "exit\r"
+ send -h "exit\r"
} else {
- send "quit\r"
+ send -h "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"
+ send -h "exit\r"
exp_continue;
}
+ "Would you like to save them now" { # Force10
+ send "n\r"
+ exp_continue
+ }
+ "Configuration changes have occurred.*" { # Cisco CSS
+ send "n\r"
+ exp_continue
+ }
"Do you wish to save your configuration changes" {
send "n\r"
exp_continue
}
-re "\[\n\r]+" { exp_continue }
- timeout { close; return 0 }
+ timeout { catch {close}; wait
+ return 0
+ }
eof { return 0 }
}
set in_proc 0
@@ -616,12 +727,14 @@ source_password_file $password_file
set in_proc 0
foreach router [lrange $argv $i end] {
set router [string tolower $router]
- send_user "$router\n"
-
- # Figure out prompt.
- # Since autoenable is off by default, if we have it defined, it
- # was done on the command line. If it is not specifically set on the
- # command line, check the password file.
+ # attempt at platform switching.
+ set platform ""
+ send_user -- "$router\n"
+
+ # Figure out the prompt.
+ # 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 $avautoenable {
set autoenable 1
set enable 0
@@ -634,6 +747,7 @@ foreach router [lrange $argv $i end] {
set prompt "(#| \\(enable\\))"
} else {
set autoenable 0
+ set enable $avenable
set prompt ">"
}
}
@@ -647,15 +761,18 @@ foreach router [lrange $argv $i end] {
if { $do_passwd || $do_enapasswd } {
set pswd [find password $router]
if { [llength $pswd] == 0 } {
- send_user "\nError: 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 "\nError: no enable password for $router in $password_file.\n"
+ 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] ""]
+ } else {
+ set passwd $userpasswd
+ set enapasswd $enapasswd
}
# Figure out username
@@ -728,12 +845,13 @@ foreach router [lrange $argv $i end] {
# Login to the router
if {[login $router $ruser $userpswd $passwd $enapasswd $cmethod $cyphertype]} {
+ # if login failed or rsh was unsuccessful, move on to the next device
continue
}
if { $enable } {
if {[do_enable $enauser $enapasswd]} {
if { $do_command || $do_script } {
- close; wait
+ catch {close}; catch {wait}
continue
}
}
@@ -742,7 +860,7 @@ foreach router [lrange $argv $i end] {
send "\r"
expect {
-re "\[\r\n]+" { exp_continue; }
- -re "^(.+:)1 $prompt" { # stoopid extreme cmd-line numbers and
+ -re "^(.+\[:.])1 ($prompt)" { # stoopid extreme cmd-line numbers and
# prompt based on state of config changes,
# which may have an * at the beginning.
set junk $expect_out(1,string)
diff --git a/bin/control_rancid.in b/bin/control_rancid.in
index f51a21b..388bbf4 100644
--- a/bin/control_rancid.in
+++ b/bin/control_rancid.in
@@ -1,8 +1,9 @@
#! /bin/sh
##
-## $Id: control_rancid.in,v 1.61 2004/01/11 05:25:13 hank Exp $
+## $Id: control_rancid.in,v 1.80 2006/12/07 21:14:06 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -24,22 +25,21 @@
# print a usage message to stderr
pr_usage() {
- echo "usage: $0 [-r device_name] [-m mail rcpt] [group [group ...]]" >&2;
+ echo "usage: $0 [-V] [-r device_name] [-m mail rcpt] [group [group ...]]" >&2;
}
# command-line options
-# -r <device name>
+# -V print version string
# -m <mail recipients>
+# -r <device name>
alt_mailrcpt=0
if [ $# -ge 1 ] ; then
while [ 1 ] ; do
case $1 in
- -r)
- shift
- # next arg is the device name
- device="$1"
- shift
+ -V)
+ echo "@PACKAGE@ @VERSION@"
+ exit 0
;;
-m)
shift
@@ -52,6 +52,12 @@ if [ $# -ge 1 ] ; then
fi
shift
;;
+ -r)
+ shift
+ # next arg is the device name
+ device="$1"
+ shift
+ ;;
--)
shift; break;
;;
@@ -81,12 +87,33 @@ DIR=$BASEDIR/$GROUP
TMP=${TMPDIR:=/tmp}/rancid.$GROUP.$$
trap 'rm -fr $TMP;' 1 2 15
-# the receipient(s) of diffs
-mailrcpt=${mailrcpt:-"@MAILPLUS@$GROUP"}; export mailrcpt
-adminmailrcpt=${mailrcpt:-"@ADMINMAILPLUS@$GROUP"}; export adminmailrcpt
+# disable noclobber
+unset noclobber > /dev/null 2>&1
+
+# RCS system
+RCSSYS=${RCSSYS:=cvs};
+if [ $RCSSYS != "cvs" -a $RCSSYS != "svn" ] ; then
+ echo "$RCSSYS is not a valid value for RCSSYS."
+ exit 1
+fi
+
+# the receipient(s) of diffs & mail options
+mailrcpt=${mailrcpt:-"@MAILPLUS@${GROUP}${MAILDOMAIN}"}; export mailrcpt
+adminmailrcpt=${adminmailrcpt:-"@ADMINMAILPLUS@${GROUP}${MAILDOMAIN}"};
+export adminmailrcpt
+set | grep MAILHEADERS= > /dev/null 2>&1
+if [ $? -ne 0 ] ; then
+ MAILHEADERS="Precedence: bulk\n"; export MAILHEADERS
+fi
# Number of things par should run in parallel.
PAR_COUNT=${PAR_COUNT:-5}
+# Number of times failed collections should be retried. Minimum 1.
+MAX_ROUNDS=${MAX_ROUNDS:-4}
+if [ $MAX_ROUNDS -lt 1 ] ; then
+ echo "Error: MAX_ROUNDS must be at least 1."
+ MAX_ROUNDS=1
+fi
# Bail if we do not have the necessary info to run
if [ ! -d $DIR ]
@@ -96,20 +123,36 @@ then
(
echo "To: $adminmailrcpt"
echo "Subject: no $GROUP directory"
- echo "Precedence: bulk"
+ echo "$MAILHEADERS" | awk '{L = "";LN = $0;while (LN ~ /\\n/) { I = index(LN,"\\n");L = L substr(LN,0,I-1) "\n";LN = substr(LN,I+2,length(LN)-I-1);}print L LN;}'
echo ""
echo "$DIR does not exist."
echo "Run bin/rancid-cvs $GROUP to make all of the needed directories."
) | sendmail -t
exit 1
fi
+cd $DIR
+
+# create a .cvsignore
+if [ ! -f .cvsignore ]
+then
+ rm -f .cvsignore
+ cat >.cvsignore <<EOF
+.cvsignore
+routers.all
+routers.down
+routers.up
+EOF
+ if [ $RCSSYS = svn ]
+ then
+ svn propset svn:ignore -F .cvsignore .
+ fi
+fi
# do cvs update of router.db in case anyone has fiddled.
-cd $DIR
-cvs update router.db > $TMP 2>&1
+$RCSSYS update router.db > $TMP 2>&1
grep "^C" $TMP > /dev/null
if [ $? -eq 0 ] ; then
- echo "There were CVS conflicts during update."
+ echo "There were $RCSSYS conflicts during update."
echo ""
cat $TMP
rm -f $TMP
@@ -119,36 +162,34 @@ rm -f $TMP
if [ ! -f $DIR/router.db ]
then
+ echo "$DIR/router.db does not exist."
(
echo "To: $adminmailrcpt"
echo "Subject: no $GROUP/router.db file"
- echo "Precedence: bulk"
+ echo "$MAILHEADERS" | awk '{L = "";LN = $0;while (LN ~ /\\n/) { I = index(LN,"\\n");L = L substr(LN,0,I-1) "\n";LN = substr(LN,I+2,length(LN)-I-1);}print L LN;}'
echo ""
echo "$DIR/router.db does not exist."
) | sendmail -t
exit 1;
-elif [ ! -s $DIR/router.db ]
-then
- exit
fi
# generate the list of all, up, & down routers
cd $DIR
trap 'rm -fr routers.db routers.all.new routers.down.new routers.up.new \
routers.mail routers.added routers.deleted $TMP;' 1 2 15
-sed -e '/^#/d' -e 's/^ *//' -e 's/ *$//' -e 's/ *: */:/g' router.db |
+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=$?
+@DIFF_CMD@ 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 > routers.down.new
if [ ! -f routers.down ] ; then touch routers.down; fi
-diff routers.down routers.down.new > /dev/null 2>&1; RDOWN=$?
+@DIFF_CMD@ 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 > routers.up.new
if [ ! -f routers.up ] ; then touch routers.up; fi
-diff routers.up routers.up.new > /dev/null 2>&1; RUP=$?
+@DIFF_CMD@ routers.up routers.up.new > /dev/null 2>&1; RUP=$?
if [ $RALL -ne 0 -o $RDOWN -ne 0 -o $RUP -ne 0 ]
then
@@ -177,10 +218,10 @@ then
WCDOWN=`comm -13 routers.down routers.down.new | wc -l | \
sed -e 's/^ *\([^ ]*\)/\1/'`
if [ $WCDOWN -eq 1 ] ; then
- echo Routers changed to down:
- comm -13 routers.down routers.down.new | \
+ echo Routers changed to down:
+ comm -13 routers.down routers.down.new | \
sed -e 's/^/ /'
- echo
+ echo
fi
fi
fi
@@ -195,14 +236,14 @@ then
if [ $WCADDED -gt 0 ]
then
- echo Added routers:
- cat routers.added
+ echo Added routers:
+ cat routers.added
echo
fi
if [ $WCDELETED -gt 0 ]
then
- echo Deleted routers:
- cat routers.deleted
+ echo Deleted routers:
+ cat routers.deleted
echo
fi
@@ -214,7 +255,7 @@ then
(
echo "To: $adminmailrcpt"
echo "Subject: changes in $GROUP routers"
- echo "Precedence: bulk"
+ echo "$MAILHEADERS" | awk '{L = "";LN = $0;while (LN ~ /\\n/) { I = index(LN,"\\n");L = L substr(LN,0,I-1) "\n";LN = substr(LN,I+2,length(LN)-I-1);}print L LN;}'
echo ""
cat routers.mail
) | sendmail -t
@@ -233,8 +274,12 @@ then
router=$1
touch $router
- cvs add -ko $router
- cvs commit -m 'new router' $router
+ if [ $RCSSYS = cvs ] ; then
+ cvs add -ko $router
+ else
+ svn add $router
+ fi
+ $RCSSYS commit -m 'new router' $router
echo "Added $router"
done
echo
@@ -257,23 +302,31 @@ rm -f routers.db
trap 'rm -fr $TMP;' 1 2 15
cd $DIR/configs
-# check for 'up' routers missing in cvs. no idea how this happens to some folks
+# check for 'up' routers missing in RCS. no idea how this happens to some folks
for router in `cut -d: -f1 ../routers.up` ; do
- cvs status $router | grep -i 'status: unknown' > /dev/null 2>&1
+ if [ $RCSSYS = cvs ] ; then
+ cvs status $router | grep -i 'status: unknown' > /dev/null 2>&1
+ else
+ svn status $router | grep '^?' > /dev/null 2>&1
+ fi
if [ $? -eq 0 ]; then
touch $router
- cvs add -ko $router
- echo "CVS added missing router $router"
+ if [ $RCSSYS = cvs ] ; then
+ cvs add -ko $router
+ else
+ svn add $router
+ fi
+ echo "$RCSSYS added missing router $router"
fi
done
echo
-# cvs delete configs for routers not listed in routers.up.
-for router in `find . \( -name \*.new -prune -o -name CVS -prune \) -o -type f -print | sed -e 's/^.\///'` ; do
+# delete configs from RCS for routers not listed in routers.up.
+for router in `find . \( -name \*.new -prune -o -name CVS -prune -o -name .svn -prune \) -o -type f -print | sed -e 's/^.\///'` ; do
grep -i "^$router:" ../router.db > /dev/null 2>&1
if [ $? -eq 1 ]; then
rm -f $router
- cvs delete $router
- cvs commit -m 'deleted router' $router
+ $RCSSYS delete $router
+ $RCSSYS commit -m 'deleted router' $router
echo "Deleted $router"
fi
done
@@ -283,7 +336,7 @@ cd $DIR
if [ ! -s routers.up ]
then
# commit router.db
- cvs commit -m updates router.db > /dev/null
+ $RCSSYS commit -m updates router.db
exit;
fi
@@ -311,7 +364,7 @@ par -q -n $PAR_COUNT -c "rancid-fe \{}" $devlistfile
# This section will generate a list of missed routers
# and try to grab them again. It will run through
# $pass times.
-pass=4
+pass=$MAX_ROUNDS
round=1
if [ -f $DIR/routers.up.missed ]; then
rm -f $DIR/routers.up.missed
@@ -349,10 +402,10 @@ echo
# 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
+do
OFS=$IFS
IFS=':'
- set $router
+ set $router
IFS=$OFS
router=$1;
@@ -371,8 +424,12 @@ done
# Diff the directory and then checkin.
trap 'rm -fr $TMP $TMP.diff $DIR/routers.single;' 1 2 15
cd $DIR
-cvs -f @DIFF_CMD@ | sed -e '/^RCS file: /d' -e '/^--- /d' \
+if [ $RCSSYS = "cvs" ] ; then
+ cvs -f @DIFF_CMD@ -ko | sed -e '/^RCS file: /d' -e '/^--- /d' \
-e '/^+++ /d' -e 's/^\([-+ ]\)/\1 /' >$TMP.diff
+else
+ svn diff | sed -e '/^+++ /d' -e 's/^\([-+ ]\)/\1 /' >$TMP.diff
+fi
if [ $alt_mailrcpt -eq 1 ] ; then
subject="router config diffs - courtesy of $mailrcpt"
@@ -380,22 +437,23 @@ else
subject="router config diffs"
fi
if [ "X$device" != "X" ] ; then
- cvs commit -m "updates - courtesy of $mailrcpt"
+ $RCSSYS commit -m "updates - courtesy of $mailrcpt"
subject="$GROUP/$device $subject"
else
- cvs commit -m updates
+ $RCSSYS commit -m updates
subject="$GROUP $subject"
fi
# Mail out the diffs (if there are any).
-if [ -s $TMP.diff ]; then
- sendmail -t <<EMAIL
-To: $mailrcpt
-Subject: $subject
-Precedence: bulk
-
-`cat $TMP.diff`
-EMAIL
+if [ -s $TMP.diff ]
+then
+ (
+ echo "To: $mailrcpt"
+ echo "Subject: $subject"
+ echo "$MAILHEADERS" | awk '{L = "";LN = $0;while (LN ~ /\\n/) { I = index(LN,"\\n");L = L substr(LN,0,I-1) "\n";LN = substr(LN,I+2,length(LN)-I-1);}print L LN;}'
+ echo ""
+ cat $TMP.diff
+ ) | sendmail -t
fi
# If any machines have not been reached within the last $OLDTIME
@@ -412,7 +470,7 @@ then
(
echo "To: $adminmailrcpt"
echo "Subject: config fetcher problems - $GROUP"
- echo "Precedence: bulk"
+ echo "$MAILHEADERS" | awk '{L = "";LN = $0;while (LN ~ /\\n/) { I = index(LN,"\\n");L = L substr(LN,0,I-1) "\n";LN = substr(LN,I+2,length(LN)-I-1);}print L LN;}'
echo ""
echo "The following routers have not been successfully contacted for"
echo "more than $OLDTIME hours."
@@ -422,5 +480,5 @@ then
fi
# Cleanup
-rm -f $TMP.diff $DIR/routers.single
+rm -f $TMP.diff $DIR/routers.single $DIR/routers.failed
trap '' 1 2 15
diff --git a/bin/cssrancid.in b/bin/cssrancid.in
index 27049df..294f400 100644
--- a/bin/cssrancid.in
+++ b/bin/cssrancid.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: cssrancid.in,v 1.4 2004/01/11 03:49:13 heas Exp $
+## $Id: cssrancid.in,v 1.13 2006/10/05 04:27:42 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -21,25 +22,30 @@
#
# RANCID - Really Awesome New Cisco confIg Differ
#
-# usage: rancid [-d] [-l] [-f filename | $host]
+# usage: rancid [-dV] [-l] [-f filename | hostname]
#
use Getopt::Std;
-getopts('dfl');
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
-$timeo = 90; # clogin timeout in seconds
+$timeo = 90; # clogin timeout in seconds
-my(%filter_pwds); # password filtering mode
+my(@commandtable, %commands, @commands);# command lists
+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) {
+ 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;
}
@@ -64,7 +70,7 @@ 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
@@ -77,7 +83,7 @@ sub keynsort {
# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
@@ -90,7 +96,7 @@ sub keysort {
# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
@@ -102,7 +108,7 @@ sub valsort{
# This is a numerical sort routine (ascending).
sub numsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a <=> $b} keys %lines) {
@@ -116,7 +122,7 @@ sub numsort {
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
@@ -129,7 +135,7 @@ sub ipsort {
# 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]));
+ $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
@@ -141,7 +147,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);
@@ -254,6 +259,8 @@ sub ShowVersion {
sub TermLength {
# Dummy subroutine.. need to set term length differently for CSS
# boxes as term length 0 doesnt work correctly. POS.
+ print STDERR " In TermLength: $_" if ($debug);
+ $_ = <INPUT>;
return(0);
}
@@ -264,6 +271,8 @@ sub CopyProfile {
## 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.
+ print STDERR " In CopyProfile: $_" if ($debug);
+ $_ = <INPUT>;
return(0);
}
@@ -283,15 +292,16 @@ 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+:)/;
+ next if (/\*\* BOOT CONFIG /);
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: $_");
@@ -305,17 +315,18 @@ sub ShowBoot {
# This routine processes a "show run"
sub ShowRun {
print STDERR " In ShowRun: $_" if ($debug);
- my($lineauto) = 0;
+ my($lines) = 0;
while (<INPUT>) {
tr/\015//d;
- study;
- last if(/^$prompt/);
+ if(/^$prompt/) {
+ $found_end = 1 if ($lines > 4);
+ return(1);
+ }
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>) {
@@ -335,14 +346,14 @@ sub ShowRun {
/^! (Last configuration|NVRAM config last)/ && next;
## CSS specific....
/Generated on/ && next;
+ $lines++;
# 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
+ /^ speed / && 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");
@@ -360,11 +371,9 @@ sub ShowRun {
}
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");
+ if (/\s*username (\S+)(\s.*)? (des-password|password) (\S+|\S+)/) {
+ if ($filter_pwds >= 1) {
+ ProcessHistory("USER","keysort","$1","! username $1$2 $3 <removed>$'\n");
} else {
ProcessHistory("USER","keysort","$1","$_");
}
@@ -537,11 +546,6 @@ sub ShowRun {
# 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);
}
@@ -550,25 +554,30 @@ sub ShowRun {
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"
+@commandtable = (
+ {'term length 65535' => 'TermLength'},
+ {'copy profile user-profile' => 'CopyProfile'},
+ {'show version' => 'ShowVersion'},
+ {'show boot' => 'ShowBoot'},
+ {'show run' => 'ShowRun'}
);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
+
$cisco_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
@@ -590,7 +599,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;
@@ -599,11 +608,12 @@ if ($ENV{"FILTER_PWDS"} =~ /no/i) {
}
ProcessHistory("","","","!RANCID-CONTENT-TYPE: cisco-css\n!\n");
-ProcessHistory("COMMENTS","keysort","B0","!\n");
-ProcessHistory("COMMENTS","keysort","F0","!\n");
-ProcessHistory("COMMENTS","keysort","G0","!\n");
+#ProcessHistory("COMMENTS","keysort","B0","!\n");
+#ProcessHistory("COMMENTS","keysort","F0","!\n");
+#ProcessHistory("COMMENTS","keysort","G0","!\n");
TOP: while(<INPUT>) {
+NEXT:
tr/\015//d;
if (/\#\s?exit/) {
$clean_run=1;
@@ -615,23 +625,27 @@ TOP: while(<INPUT>) {
$clean_run=0;
last;
}
- while (/#\s*($cmds_regexp)\s*$/) {
+ if (/#\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";
- # $clean_run = 0;
- # last TOP;
- next TOP;
- } else {
- $rval = &{$commands{$cmd}};
- delete($commands{$cmd});
- if ($rval == -1) {
- $clean_run = 0;
- last TOP;
- }
+ $clean_run = 0;
+ last TOP;
+ }
+ $rval = &{$commands{$cmd}};
+ delete($commands{$cmd});
+ if ($rval == -1) {
+ $clean_run = 0;
+ last TOP;
}
+ # the function may have read the next prompt/cmd line
+ goto NEXT;
}
}
print STDOUT "Done $logincmd: $_\n" if ($log);
diff --git a/bin/elogin.in b/bin/elogin.in
index 651d7fb..d581101 100644
--- a/bin/elogin.in
+++ b/bin/elogin.in
@@ -1,8 +1,9 @@
#! @EXPECT_PATH@ --
##
-## $Id: elogin.in,v 1.27 2004/01/11 05:39:15 heas Exp $
+## $Id: elogin.in,v 1.38 2006/12/05 16:50:52 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -40,7 +41,7 @@ set password_file $env(HOME)/.cloginrc
set do_command 0
set do_script 0
# The default is to automatically enable
-set enable 1
+set avenable 1
# The default is that you login non-enabled (tacacs can have you login already
# enabled)
set avautoenable 0
@@ -49,7 +50,7 @@ set avautoenable 0
set do_passwd 1
# Find the user in the ENV, or use the unix userid.
-if {[ info exists env(CISCO_USER) ] } {
+if {[ info exists env(CISCO_USER) ]} {
set default_user $env(CISCO_USER)
} elseif {[ info exists env(USER) ]} {
set default_user $env(USER)
@@ -62,9 +63,12 @@ if {[ info exists env(CISCO_USER) ] } {
if [ catch {exec id} reason ] {
send_error "\nError: could not exec id: $reason\n"
exit 1
- }
+ }
regexp {\(([^)]*)} "$reason" junk default_user
-}
+}
+if {[ info exists env(CLOGINRC) ]} {
+ set password_file $env(CLOGINRC)
+}
# Sometimes routers take awhile to answer (the default is 10 sec)
set timeout 45
@@ -90,13 +94,16 @@ for {set i 0} {$i < $argc} {incr i} {
}
set do_passwd 0
# VTY Password
- } -v* -
- -v* {
+ } -v* {
if {! [ regexp .\[vV\](.+) $arg ignore passwd]} {
incr i
set passwd [ lindex $argv $i ]
}
set do_passwd 0
+ # Version string
+ } -V* {
+ send_user "@PACKAGE@ @VERSION@\n"
+ exit 0
# Enable Username
} -w* -
-W* {
@@ -268,31 +275,44 @@ proc source_password_file { password_file } {
}
# Log into the router.
+# returns: 0 on success, 1 on failure
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
+ 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] {
+ incr progs -1
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} reason ]
+ } else {
set retval [ catch {spawn telnet $router $port} reason ]
}
if { $retval } {
send_user "\nError: telnet failed: $reason\n"
- exit 1
+ return 1
}
+ } elseif ![string compare $prog "ssh"] {
+ send_error "\nError: unsupported method: ssh\n"
+ if { $progs == 0 } {
+ return 1
+ }
+ continue
+ } elseif ![string compare $prog "rsh"] {
+ send_error "\nError: unsupported method: rsh\n"
+ if { $progs == 0 } {
+ return 1
+ }
+ continue
} else {
- puts "\nError: unknown connection method: $prog"
+ send_user "\nError: unknown connection method: $prog\n"
return 1
}
- incr progs -1
sleep 0.3
# This helps cleanup each expect clause.
@@ -394,9 +414,11 @@ proc run_commands { prompt command } {
}
send "exit\r"
expect {
- "\n" { exp_continue }
- timeout { return 0 }
- eof { return 0 }
+ "\n" { exp_continue }
+ timeout { catch {close}; wait
+ return 0
+ }
+ eof { return 0 }
}
set in_proc 0
}
diff --git a/bin/erancid.in b/bin/erancid.in
index 20da43d..a95da84 100644
--- a/bin/erancid.in
+++ b/bin/erancid.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: erancid.in,v 1.18 2004/01/11 03:49:13 heas Exp $
+## $Id: erancid.in,v 1.26 2006/10/05 04:27:42 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -21,25 +22,30 @@
#
# RANCID - Really Awesome New Cisco confIg Differ
#
-# usage: rancid [-d] [-l] [-f filename | $host]
+# usage: rancid [-dV] [-l] [-f filename | hostname]
#
use Getopt::Std;
-getopts('dfl');
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
-$timeo = 90; # clogin timeout in seconds
+$timeo = 90; # elogin timeout in seconds
-my(%filter_pwds); # password filtering mode
+my(@commandtable, %commands, @commands);# command lists
+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) {
+ 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;
}
@@ -61,10 +67,10 @@ sub ProcessHistory {
sub numerically { $a <=> $b; }
-# This is a sort routing that will sort numerically on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
@@ -74,10 +80,10 @@ sub keynsort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
@@ -87,10 +93,10 @@ sub keysort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
@@ -100,9 +106,9 @@ sub valsort{
@sorted_lines;
}
-# This is a numerical sort routing (ascending).
+# This is a numerical sort routine (ascending).
sub numsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a <=> $b} keys %lines) {
@@ -116,7 +122,7 @@ sub numsort {
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
@@ -129,7 +135,7 @@ sub ipsort {
# 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]));
+ $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
@@ -168,8 +174,8 @@ sub ShowModule {
# now just copy it verbatim to the history file
while (<INPUT>) {
- tr/\015//d;
- last if(/Active\) >/);
+ tr/\015//d;
+ last if(/Active\) >/);
last if(/^$/);
chop;
ProcessHistory("SLOT","","","-$_\n");
@@ -186,8 +192,8 @@ sub WriteTerm {
# now just copy it verbatim to the history file
while (<INPUT>) {
- tr/\015//d;
- last if(/Active\) >/);
+ tr/\015//d;
+ last if(/Active\) >/);
chop;
if (/^\s*snmp/ && defined($ENV{'NOCOMMSTR'})) {
/snmp (getcomm|setcomm|trapcomm)(\s+)(\S*)/ &&
@@ -204,21 +210,28 @@ sub WriteTerm {
sub DoNothing {print STDOUT;}
# Main
-%commands=(
- 'version' => "ShowVersion",
- 'equipment' => "ShowModule",
- 'config' => "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=(
- "version",
- "equipment",
- "config",
+@commandtable = (
+ {'version' => 'ShowVersion'},
+ {'equipment' => 'ShowModule'},
+ {'config' => 'WriteTerm'}
);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
+
$cisco_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
@@ -241,7 +254,7 @@ if ($file) {
# determine password filtering mode
if ($ENV{"FILTER_PWDS"} =~ /no/i) {
- $filter_pwds = 0;
+ $filter_pwds = 0;
} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
$filter_pwds = 2;
} else {
diff --git a/bin/f10rancid.in b/bin/f10rancid.in
index 2c4e485..e61d215 100644
--- a/bin/f10rancid.in
+++ b/bin/f10rancid.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: f10rancid.in,v 1.11 2004/01/11 03:49:13 heas Exp $
+## $Id: f10rancid.in,v 1.23 2006/10/05 04:27:42 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -23,25 +24,30 @@
#
# RANCID - Really Awesome New Cisco confIg Differ
#
-# usage: rancid [-d] [-l] [-f filename | $host]
+# usage: rancid [-dV] [-l] [-f filename | hostname]
#
use Getopt::Std;
-getopts('dfl');
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
-$timeo = 90; # clogin timeout in seconds
+$timeo = 90; # clogin timeout in seconds
-my(%filter_pwds); # password filtering mode
+my(@commandtable, %commands, @commands);# command lists
+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) {
+ 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;
}
@@ -63,10 +69,10 @@ sub ProcessHistory {
sub numerically { $a <=> $b; }
-# This is a sort routing that will sort numerically on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
@@ -76,10 +82,10 @@ sub keynsort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
@@ -89,10 +95,10 @@ sub keysort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
@@ -102,9 +108,9 @@ sub valsort{
@sorted_lines;
}
-# This is a numerical sort routing (ascending).
+# This is a numerical sort routine (ascending).
sub numsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a <=> $b} keys %lines) {
@@ -118,7 +124,7 @@ sub numsort {
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
@@ -131,7 +137,7 @@ sub ipsort {
# 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]));
+ $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
@@ -360,41 +366,6 @@ sub ShowEnv {
return(0);
}
-# This routine parses "show gsr chassis-info" for the gsr
-# This will create arrays for hw info.
-sub ShowGSR {
- # Skip if this is not a 1200n.
- print STDERR " In ShowGSR: $_" 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]/);
- /^$/ && next;
- /^\s+Chassis: type (\S+) Fab Ver: (\S+)/ &&
- ProcessHistory("COMMENTS","keysort","D0","!\n") &&
- ProcessHistory("COMMENTS","keysort","D1",
- "!GSR Chassis type: $1 Fab Ver: $2\n") &&
- next;
- /^\s+Chassis S\/N: (.*)$/ &&
- ProcessHistory("COMMENTS","keysort","D2",
- "!GSR Chassis S/N: $1\n") &&
- next;
- /^\s+PCA: (\S+)\s*rev: (\S+)\s*dev: \S+\s*HW ver: (\S+)$/ &&
- ProcessHistory("COMMENTS","keysort","D3",
- "!GSR Backplane PCA: $1, rev $2, ver $3\n") &&
- next;
- /^\s+Backplane S\/N: (\S+)$/ &&
- ProcessHistory("COMMENTS","keysort","D4",
- "!GSR Backplane S/N: $1\n") &&
- next;
- }
- ProcessHistory("COMMENTS","","","!\n");
- return(0);
-}
-
# This routine parses "show boot"
sub ShowBoot {
# Pick up boot variables if 7000/7200/7500/12000/2900/3500;
@@ -416,9 +387,9 @@ sub ShowBoot {
}
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: $_");
@@ -800,41 +771,6 @@ sub ShowModule {
return(0);
}
-# This routine parses "show c7200" for the 7200
-# This will create arrays for hw info.
-sub ShowC7200 {
- # Skip if this is not a 7200.
- print STDERR " In ShowC7200: $_" if ($debug);
-
- while (<INPUT>) {
- tr/\015//d;
- last if (/^$prompt/);
- next if (/^(\s*|\s*$cmd\s*)$/);
- #return(1) if ($type !~ /^72/);
- return(-1) if (/command authorization failed/i);
- /^$/ && next;
- if (/C7200 Midplane EEPROM:/) {
- $_ = <INPUT>;
- /revision\s+(\S+).*revision\s+(\S+)/;
- ProcessHistory("SLOT","","","!Slot Midplane: hvers $1 rev $2\n");
- $_ = <INPUT>;
- /number\s+(\S+)\s+Part number\s+(\S+)/;
- ProcessHistory("SLOT","","","!Slot Midplane: part $2, serial $1\n!\n");
- next;
- }
- if (/C720\d(VXR)? CPU EEPROM:/) {
- $_ = <INPUT>;
- /revision\s+(\S+).*revision\s+(\S+)/ &&
- ProcessHistory("SLOT","","","!Slot CPU: hvers $1 rev $2\n");
- $_ = <INPUT>;
- /number\s+(\S+)\s+Part number\s+(\S+)/ &&
- ProcessHistory("SLOT","","","!Slot CPU: part $2, serial $1\n!\n");
- next;
- }
- }
- return(0);
-}
-
# This routine parses "show vtp status"
sub ShowVTP {
print STDERR " In ShowVTP: $_" if ($debug);
@@ -890,7 +826,7 @@ sub WriteTerm {
# skip the crap
if (/^(##+$|(Building|Current) configuration)/i) {
while (<INPUT>) {
- next if (/^Current configuration\s*:/i);
+ next if (/^!?Current configuration\s*:/i);
next if (/^:/);
next if (/^([%!].*|\s*)$/);
next if (/^ip add.*ipv4:/); # band-aid for 3620 12.0S
@@ -1109,65 +1045,48 @@ sub WriteTerm {
sub DoNothing {print STDOUT;}
# Main
-%commands=(
- 'show version' => "ShowVersion",
- 'show install active' => "ShowInstallActive",
- 'show env all' => "ShowEnv",
- 'show gsr chassis' => "ShowGSR",
- 'show boot' => "ShowBoot",
- 'show bootvar' => "ShowBoot",
- 'show variables boot' => "ShowBoot",
- 'show flash' => "ShowFlash",
- 'dir /all nvram:' => "DirSlotN",
- 'dir /all bootflash:' => "DirSlotN",
- 'dir /all slot0:' => "DirSlotN",
- 'dir /all disk0:' => "DirSlotN",
- 'dir /all slot1:' => "DirSlotN",
- 'dir /all disk1:' => "DirSlotN",
- "dir /all sup-bootflash:"=> "DirSlotN", # cat 6500-ios
- "dir /all sup-microcode:"=> "DirSlotN", # cat 6500-ios
- 'show controllers' => "ShowContAll",
- 'show controllers cbus' => "ShowContCbus",
- 'show diagbus' => "ShowDiagbus",
- 'show diag' => "ShowDiag",
- 'show module' => "ShowModule", # cat 6500-ios
- 'show c7200' => "ShowC7200",
- 'show vtp status' => "ShowVTP",
- 'show vlan' => "ShowVLAN",
- 'show running' => "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 install active",
- "show env all",
- "show gsr chassis",
- "show boot",
- "show bootvar",
- "show variables boot",
- "show flash",
- "dir /all nvram:",
- "dir /all bootflash:",
- "dir /all slot0:",
- "dir /all disk0:",
- "dir /all slot1:",
- "dir /all disk1:",
- "dir /all sup-bootflash:",
- "dir /all sup-microcode:",
- "show controllers",
- "show controllers cbus",
- "show diagbus",
- "show diag",
- "show module",
- "show c7200",
- "show vtp status",
- "show vlan",
- "show running"
+@commandtable = (
+ {'show version' => 'ShowVersion'},
+ {'show install active' => 'ShowInstallActive'},
+ {'show env all' => 'ShowEnv'},
+ {'show boot' => 'ShowBoot'},
+ {'show bootvar' => 'ShowBoot'},
+ {'show variables boot' => 'ShowBoot'},
+ {'show flash' => 'ShowFlash'},
+ {'dir /all nvram:' => 'DirSlotN'},
+ {'dir /all bootflash:' => 'DirSlotN'},
+ {'dir /all slot0:' => 'DirSlotN'},
+ {'dir /all disk0:' => 'DirSlotN'},
+ {'dir /all slot1:' => 'DirSlotN'},
+ {'dir /all disk1:' => 'DirSlotN'},
+ {'dir /all sup-bootflash:' => 'DirSlotN'},
+ {'dir /all sup-microcode:' => 'DirSlotN'},
+ {'show controllers' => 'ShowContAll'},
+ {'show controllers cbus' => 'ShowContCbus'},
+ {'show diagbus' => 'ShowDiagbus'},
+ {'show diag' => 'ShowDiag'},
+ {'show module' => 'ShowModule'},
+ {'show vtp status' => 'ShowVTP'},
+ {'show vlan' => 'ShowVLAN'},
+ {'show running' => 'WriteTerm'}
);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
+
$cisco_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
@@ -1189,7 +1108,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;
diff --git a/bin/flogin.in b/bin/flogin.in
index 169e522..5c8813d 100644
--- a/bin/flogin.in
+++ b/bin/flogin.in
@@ -1,8 +1,9 @@
#! @EXPECT_PATH@ --
##
-## $Id: flogin.in,v 1.32 2004/01/11 05:39:15 heas Exp $
+## $Id: flogin.in,v 1.47 2006/12/08 21:28:26 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -50,7 +51,7 @@ set password_file $env(HOME)/.cloginrc
set do_command 0
set do_script 0
# The default is to automatically enable
-set enable 1
+set avenable 1
# The default is that you login non-enabled (tacacs can have you login already
# enabled)
set avautoenable 0
@@ -60,7 +61,7 @@ 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) ] } {
+if {[ info exists env(CISCO_USER) ]} {
set default_user $env(CISCO_USER)
} elseif {[ info exists env(USER) ]} {
set default_user $env(USER)
@@ -73,9 +74,12 @@ if {[ info exists env(CISCO_USER) ] } {
if [ catch {exec id} reason ] {
send_error "\nError: could not exec id: $reason\n"
exit 1
- }
+ }
regexp {\(([^)]*)} "$reason" junk default_user
-}
+}
+if {[ info exists env(CLOGINRC) ]} {
+ set password_file $env(CLOGINRC)
+}
# Sometimes routers take awhile to answer (the default is 10 sec)
set timeout 45
@@ -101,13 +105,16 @@ for {set i 0} {$i < $argc} {incr i} {
}
set do_passwd 0
# VTY Password
- } -v* -
- -v* {
+ } -v* {
if {! [ regexp .\[vV\](.+) $arg ignore passwd]} {
incr i
set passwd [ lindex $argv $i ]
}
set do_passwd 0
+ # Version string
+ } -V* {
+ send_user "@PACKAGE@ @VERSION@\n"
+ exit 0
# Enable Username
} -w* -
-W* {
@@ -186,11 +193,11 @@ for {set i 0} {$i < $argc} {incr i} {
set do_command 1
# Do we enable?
} -noenable {
- set enable 0
+ set avenable 0
# Does tacacs automatically enable us?
} -autoenable {
set avautoenable 1
- set enable 0
+ set avenable 0
} -* {
send_user "\nError: Unknown argument! $arg\n"
send_user $usage
@@ -244,9 +251,9 @@ proc include {args} {
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
@@ -264,7 +271,7 @@ proc find {var router} {
# 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
+# 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] } {
@@ -283,6 +290,7 @@ proc source_password_file { password_file } {
}
# Log into the router.
+# returns: 0 on success, 1 on failure
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
@@ -292,6 +300,7 @@ proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
# try each of the connection methods in $cmethod until one is successful
set progs [llength $cmethod]
foreach prog [lrange $cmethod 0 end] {
+ incr progs -1
if [string match "telnet*" $prog] {
regexp {telnet(:([^[:space:]]+))*} $prog command suffix port
if {"$port" == ""} {
@@ -301,23 +310,23 @@ proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
}
if { $retval } {
send_user "\nError: telnet failed: $reason\n"
- exit 1
+ return 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
+ return 1
}
} elseif ![string compare $prog "rsh"] {
- if [ catch {spawn rsh -l $user $router} reason ] {
- send_user "\nError: rsh failed: $reason\n"
- exit 1
+ send_error "\nError: unsupported method: rsh\n"
+ if { $progs == 0 } {
+ return 1
}
+ continue;
} else {
- puts "\nError: unknown connection method: $prog"
+ send_user "\nError: unknown connection method: $prog\n"
return 1
}
- incr progs -1
sleep 0.3
# This helps cleanup each expect clause.
@@ -354,15 +363,15 @@ proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
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 closed ($prog): $router\n"
return 1
- }
- }
+ }
+ }
-re "Telnet server disabled" {
catch {close}; wait
if !$progs {
@@ -500,12 +509,14 @@ proc run_commands { prompt command } {
}
send "exit\r"
expect {
- "\n" { exp_continue }
- -re "^\[^ ]+>" {
- send "exit\r"
- exp_continue }
- timeout { return 0 }
- eof { return 0 }
+ "\n" { exp_continue }
+ -re "^\[^ ]+>" { send "exit\r"
+ exp_continue
+ }
+ timeout { catch {close}; wait
+ return 0
+ }
+ eof { return 0 }
}
set in_proc 0
}
@@ -535,6 +546,7 @@ foreach router [lrange $argv $i end] {
set prompt "#"
} else {
set autoenable 0
+ set enable $avenable
set prompt ">"
}
}
@@ -545,23 +557,26 @@ foreach router [lrange $argv $i end] {
if { [llength $pswd] == 0 } {
send_user "\nError: no password for $router in $password_file.\n"
continue
- }
+ }
if { $enable && $do_enapasswd && $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] ""]
+ } else {
+ set passwd $userpasswd
+ set enapasswd $enapasswd
}
# Figure out username
- if {[info exists 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]} {
@@ -569,22 +584,22 @@ foreach router [lrange $argv $i end] {
set userpswd $userpasswd
} else {
set userpswd [join [find userpassword $router] ""]
- if { "$userpswd" == "" } { set userpswd $passwd }
- }
-
+ if { "$userpswd" == "" } { set userpswd $passwd }
+ }
+
# Figure out enable username
- if {[info exists enausername]} {
+ if {[info exists enausername]} {
# command line enausername
set enauser $enausername
} else {
set enauser [join [find enauser $router] ""]
- if { "$enauser" == "" } { set enauser $ruser }
- }
+ if { "$enauser" == "" } { set enauser $ruser }
+ }
# Figure out prompts
set u_prompt [find userprompt $router]
if { "$u_prompt" == "" } {
- set u_prompt "(Username|login|Name|User Name):"
+ set u_prompt "(Username|login|Name|User Name) *:"
} else {
set u_prompt [join [lindex $u_prompt 0] ""]
}
@@ -614,18 +629,18 @@ 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} }
+ # 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
}
- if { $enable } {
+ if { $enable } {
if {[do_enable $enauser $enapasswd]} {
if { $do_command || $do_script } {
- close; wait
+ catch {close}; catch {wait}
continue
}
}
@@ -642,7 +657,7 @@ foreach router [lrange $argv $i end] {
source $sfile
close
} else {
- label $router
+ label $router
log_user 1
interact
}
diff --git a/bin/fnrancid.in b/bin/fnrancid.in
index 815227b..b14906a 100644
--- a/bin/fnrancid.in
+++ b/bin/fnrancid.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: fnrancid.in,v 1.3 2004/01/11 03:49:13 heas Exp $
+## $Id: fnrancid.in,v 1.11 2006/10/05 04:27:42 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -20,29 +21,34 @@
##
#
# A library built on Stephen Gill's Netscreen stuff to accomodate
-# the Fortinet product line. [d_pfleger@juniper.net]
+# the Fortinet product line. [d_pfleger@juniper.net]
#
# RANCID - Really Awesome New Cisco confIg Differ
#
-# usage: rancid [-d] [-l] [-f filename | $host]
+# usage: rancid [-dV] [-l] [-f filename | hostname]
#
use Getopt::Std;
-getopts('dfl');
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
$log = $opt_l;
$debug = $opt_d;
#$debug = 1;
$file = $opt_f;
$host = $ARGV[0];
$found_end = 0;
-$timeo = 90; # nlogin timeout in seconds
+$timeo = 90; # nlogin timeout in seconds
-my(%filter_pwds); # password filtering mode
+my(@commandtable, %commands, @commands);# command lists
+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) {
+ 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;
}
@@ -64,10 +70,10 @@ sub ProcessHistory {
sub numerically { $a <=> $b; }
-# This is a sort routing that will sort numerically on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
@@ -77,10 +83,10 @@ sub keynsort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
@@ -90,22 +96,22 @@ sub keysort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
- $sorted_lines[$i] = $key;
- $i++;
+ $sorted_lines[$i] = $key;
+ $i++;
}
@sorted_lines;
}
-# This is a numerical sort routing (ascending).
+# This is a numerical sort routine (ascending).
sub numsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a <=> $b} keys %lines) {
@@ -119,7 +125,7 @@ sub numsort {
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
@@ -132,7 +138,7 @@ sub ipsort {
# 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]));
+ $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
@@ -146,7 +152,7 @@ sub GetSystem {
tr/\015//d;
next if /^\s*$/;
last if(/$prompt/);
- ProcessHistory("","","","$_");
+ ProcessHistory("","","","$_");
#print STDOUT "$_";
}
print STDOUT "Vendor: $vendor";
@@ -170,9 +176,9 @@ sub GetConf {
next if /^\s*$/;
last if(/$prompt/);
if (/(^set.*)('Enc .*')(.*)/) {
- ProcessHistory("ENC","","","!$1 'Enc **encoding removed**' $3\n");
- next;
- }
+ ProcessHistory("ENC","","","!$1 'Enc **encoding removed**' $3\n");
+ next;
+ }
ProcessHistory("","","","$_");
#print STDOUT "$_";
}
@@ -184,19 +190,27 @@ sub GetConf {
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"
+@commandtable = (
+ {'get system status' => 'GetSystem'},
+ {'get conf' => 'GetConf'}
);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
+
$cisco_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
@@ -218,7 +232,7 @@ if ($file) {
# determine password filtering mode
if ($ENV{"FILTER_PWDS"} =~ /no/i) {
- $filter_pwds = 0;
+ $filter_pwds = 0;
} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
$filter_pwds = 2;
} else {
diff --git a/bin/francid.in b/bin/francid.in
index e1fd284..2967a34 100644
--- a/bin/francid.in
+++ b/bin/francid.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: francid.in,v 1.26 2004/01/11 03:49:13 heas Exp $
+## $Id: francid.in,v 1.42 2006/10/05 05:43:31 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -24,25 +25,30 @@
#
# RANCID - Really Awesome New Cisco confIg Differ
#
-# usage: rancid [-d] [-l] [-f filename | $host]
+# usage: rancid [-dV] [-l] [-f filename | hostname]
#
use Getopt::Std;
-getopts('dfl');
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
-$timeo = 90; # flogin timeout in seconds
+$timeo = 90; # flogin timeout in seconds
-my(%filter_pwds); # password filtering mode
+my(@commandtable, %commands, @commands);# command lists
+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) {
+ 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;
}
@@ -64,10 +70,10 @@ sub ProcessHistory {
sub numerically { $a <=> $b; }
-# This is a sort routing that will sort numerically on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
@@ -77,10 +83,10 @@ sub keynsort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
@@ -90,22 +96,22 @@ sub keysort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
- $sorted_lines[$i] = $key;
- $i++;
+ $sorted_lines[$i] = $key;
+ $i++;
}
@sorted_lines;
}
-# This is a numerical sort routing (ascending).
+# This is a numerical sort routine (ascending).
sub numsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a <=> $b} keys %lines) {
@@ -119,7 +125,7 @@ sub numsort {
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
@@ -132,7 +138,7 @@ sub ipsort {
# 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]));
+ $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
@@ -147,14 +153,17 @@ sub ShowVersion {
while (<INPUT>) {
tr/\015//d;
next if /^\s*$/;
- last if(/^$prompt/);
+ last if (/^$prompt/);
next if (/^(The system |Crash time)/);
+ next if (/^((Active|Standby) Management|LP Slot \d+) uptime is/);
s/^\s*(HW|SW)/$1/;
s/^\s*(Compiled on)/SW: $1/;
+ s/^\s*(\(\d+ bytes\) from )/SW: $1/;
+
#s/^(HW.*)/$1\n/;
- if (/^SL (\d)/) {
+ if (/^SL (\d+)/) {
$slot = "Slot $1";
s/^SL \d+/$slot/;
}
@@ -172,6 +181,8 @@ sub ShowVersion {
# This routine parses "show chassis"
sub ShowChassis {
+ my($skip) = 0;
+
print STDERR " In ShowChassis: $_" if ($debug);
while (<INPUT>) {
@@ -179,6 +190,28 @@ sub ShowChassis {
last if (/^$prompt/);
next if (/ from /);
next if (/current temperature/i);
+
+ if (/^---/ || /^$/) { # next section reached
+ $skip = 0;
+ }
+ if (/(POWERS|TEMPERATURE READINGS)/) {
+ $skip = 1;
+ }
+ if (/fan controlled temperature:/i) {
+ $skip = 1;
+ }
+ if (/THERMAL PLANE/) {
+ $skip = 1;
+ }
+ if (/temperature:/i) {
+ $skip = 1;
+ }
+ s/(Fan \d+ \S+), speed .*/$1/;
+ if (/speed/i) {
+ $skip = 1;
+ }
+ next if $skip;
+
ProcessHistory("CHASSIS","","","! $_");
}
ProcessHistory("CHASSIS","","","!\n");
@@ -191,8 +224,8 @@ sub ShowFlash {
while (<INPUT>) {
tr/\015//d;
- last if(/^$prompt/);
- next if /^\s*$/;
+ last if (/^$prompt/);
+ next if (/^\s*$/);
ProcessHistory("FLASH","","","!Flash: $_");
}
ProcessHistory("","","","!\n");
@@ -205,9 +238,10 @@ sub ShowModule {
while (<INPUT>) {
tr/\015//d;
- last if(/^$prompt/);
- next if /^\s*$/;
- next if /:\s*$/;
+ last if (/^$prompt/);
+ return(1) if (/Invalid input ->/);
+ next if (/^\s*$/);
+ next if (/:\s*$/);
ProcessHistory("MODULE","","","!Module: $_");
}
ProcessHistory("","","","!\n");
@@ -220,17 +254,24 @@ sub WriteTerm {
while (<INPUT>) {
tr/\015//d;
- last if(/^$prompt/);
+ last if (/^$prompt/);
/Current configuration:/i && next;
/^ver \d+\.\d+/ && next;
/^module \d+ / && next;
/^ntp clock-period / && next; # kill ntp clock-period
- /^ length / && next; # kill length on serial lines
- /^ width / && next; # kill width on serial lines
+ /^ length / && next; # kill length on serial lines
+ /^ width / && next; # kill width on serial lines
# filter out any RCS/CVS tags to avoid confusing local CVS storage
s/\$(Revision|Id):/ $1:/;
+ # sort secure-mac-addresses. Note: There is no way to determine which
+ # have been added dynamically vs statically. Thus, sort them?
+ /secure-mac-address (\S+)/ &&
+ ProcessHistory("SECMAC","keysort","$1","$_") && next;
+ # OR filter them? XXX
+ #next if (/secure-mac-address/);
+
# order access-lists
/^access-list\s+(\d+)\s+(perm|deny)\s+(\d\S+)(\/\d+)\s*$/ &&
ProcessHistory("PACL $1 $2","ipsort","$3","$_")
@@ -301,6 +342,23 @@ sub WriteTerm {
next;
}
+ # reorder listing of ports in a vlan
+ if (/^ (?:un)?tagged ethe/) {
+ chomp;
+ s/^\s+//;
+ s/\s+$//;
+
+ my @list = split /\s+ethe\s+/, $_;
+ my $tagtype = shift @list;
+
+ while (@list) {
+ ProcessHistory("","","",
+ " $tagtype ethe " . (shift @list) . "\n");
+ }
+ next;
+ }
+
+
ProcessHistory("","","","$_");
# end of config
if (/^end$/) {
@@ -315,25 +373,30 @@ sub WriteTerm {
sub DoNothing {print STDOUT;}
# Main
-%commands=(
- 'show version' => "ShowVersion",
- 'show chassis' => "ShowChassis",
- 'show module' => "ShowModule",
- 'show flash' => "ShowFlash",
- 'write term' => "WriteTerm"
-);
-# keys() doesnt return things in the order entered and the order of the
-# cmds is important. pita
-@commands=(
- "show version",
- "show chassis",
- "show module",
- "show flash",
- "write term"
+@commandtable = (
+ {'show version' => 'ShowVersion'},
+ {'show chassis' => 'ShowChassis'},
+ {'show module' => 'ShowModule'},
+ {'show flash' => 'ShowFlash'},
+ {'write term' => 'WriteTerm'}
);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
+
$cisco_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
@@ -356,7 +419,7 @@ if ($file) {
# determine password filtering mode
if ($ENV{"FILTER_PWDS"} =~ /no/i) {
- $filter_pwds = 0;
+ $filter_pwds = 0;
} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
$filter_pwds = 2;
} else {
diff --git a/bin/hlogin.in b/bin/hlogin.in
index 6af11b4..8777021 100644
--- a/bin/hlogin.in
+++ b/bin/hlogin.in
@@ -1,8 +1,9 @@
#! @EXPECT_PATH@ --
##
-## $Id: hlogin.in,v 1.21 2004/01/11 05:39:15 heas Exp $
+## $Id: hlogin.in,v 1.40 2006/12/08 21:28:26 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -47,7 +48,7 @@ set password_file $env(HOME)/.cloginrc
set do_command 0
set do_script 0
# The default is to automatically enable
-set enable 1
+set avenable 1
# The default is that you login non-enabled (tacacs can have you login already
# enabled)
set avautoenable 0
@@ -57,9 +58,11 @@ set do_passwd 1
set do_enapasswd 1
# attempt at platform switching.
set platform ""
+#
+set send_human {.4 .4 .7 .3 5}
# Find the user in the ENV, or use the unix userid.
-if {[ info exists env(CISCO_USER) ] } {
+if {[ info exists env(CISCO_USER) ]} {
set default_user $env(CISCO_USER)
} elseif {[ info exists env(USER) ]} {
set default_user $env(USER)
@@ -75,6 +78,9 @@ if {[ info exists env(CISCO_USER) ] } {
}
regexp {\(([^)]*)} "$reason" junk default_user
}
+if {[ info exists env(CLOGINRC) ]} {
+ set password_file $env(CLOGINRC)
+}
# Sometimes routers take awhile to answer (the default is 10 sec)
set timeout 45
@@ -100,13 +106,16 @@ for {set i 0} {$i < $argc} {incr i} {
}
set do_passwd 0
# VTY Password
- } -v* -
- -v* {
+ } -v* {
if {! [ regexp .\[vV\](.+) $arg ignore passwd]} {
incr i
set passwd [ lindex $argv $i ]
}
set do_passwd 0
+ # Version string
+ } -V* {
+ send_user "@PACKAGE@ @VERSION@\n"
+ exit 0
# Enable Username
} -w* -
-W* {
@@ -181,20 +190,20 @@ for {set i 0} {$i < $argc} {incr i} {
}
if [ catch {set cmd_fd [open $cmd_file r]} reason ] {
send_user "\nError: $reason\n"
- exit 1
- }
+ 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
+ set avenable 0
# Does tacacs automatically enable us?
} -autoenable {
# hp does not autoenable
#set autoenable 1
- #set enable 0
+ #set avenable 0
} -* {
send_user "\nError: Unknown argument! $arg\n"
send_user $usage
@@ -244,25 +253,25 @@ proc label { host } {
# add password * hanky-pie
proc add {var args} { global int_$var ; lappend int_$var $args}
proc include {args} {
- global env
- regsub -all "(^{|}$)" $args {} 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
+ upvar int_$var list
if { [info exists list] } {
foreach line $list {
if { [string match [lindex $line 0] $router ] } {
return [lrange $line 1 end]
- }
- }
- }
- return {}
-}
+ }
+ }
+ }
+ 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
@@ -287,6 +296,7 @@ proc source_password_file { password_file } {
}
# Log into the router.
+# returns: 0 on success, 1 on failure
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
@@ -295,37 +305,38 @@ proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
# try each of the connection methods in $cmethod until one is successful
set progs [llength $cmethod]
foreach prog [lrange $cmethod 0 end] {
+ incr progs -1
regexp {(telnet|ssh)(:([^[:space:]]+))*} $prog command suffix junk port
if [string match "telnet*" $prog] {
if {"$port" == ""} {
- set retval [ catch {spawn hpuifilter telnet $router} reason ]
+ set retval [ catch {spawn hpuifilter -- telnet $router} reason ]
} else {
- set retval [ catch {spawn hpuifilter telnet $router $port} reason ]
+ set retval [ catch {spawn hpuifilter -- telnet $router $port} reason ]
}
if { $retval } {
send_user "\nError: telnet failed: $reason\n"
- exit 1
+ return 1
}
} elseif [string match "ssh*" $prog] {
if {"$port" == ""} {
- set retval [ catch {spawn hpuifilter $sshcmd -c $cyphertype -x -l $user $router} reason ]
+ 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 ]
+ 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
+ return 1
}
} elseif ![string compare $prog "rsh"] {
- if [ catch {spawn hpuifilter rsh -l $user $router} reason ] {
- send_user "\nError: rsh failed: $reason\n"
- exit 1
+ send_error "\nError: unsupported method: rsh\n"
+ if { $progs == 0 } {
+ return 1
}
+ continue;
} else {
- puts "\nError: unknown connection method: $prog"
+ send_user "\nError: unknown connection method: $prog\n"
return 1
}
- incr progs -1
sleep 0.3
# This helps cleanup each expect clause.
@@ -367,11 +378,6 @@ proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
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
@@ -392,12 +398,21 @@ proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
send "no\r"
send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\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
+ }
-re "$u_prompt" { send "$user\r"
expect {
eof { send_user "\nError: Couldn't login\n"; wait; return 1 }
"Login invalid" { send_user "\nError: Invalid login\n"; vatch {close}; wait; return 1 }
-re "$p_prompt" { send "$userpswd\r" }
"$prompt" { set in_proc 0; return 0 }
+ "Press any key to continue" {
+ send " "
+ exp_continue
+ }
}
exp_continue
}
@@ -408,9 +423,18 @@ proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
send "$passwd\r"
}
expect {
- eof { send_user "\nError: Couldn't login\n"; wait; return 1 }
+ eof { send_user "\nError: Couldn't login\n";
+ wait;
+ return 1
+ }
+ "Press any key to continue" {
+ send " ";
+ exp_continue
+ }
-re "$e_prompt" { send "$enapasswd\r" }
- "$prompt" { set in_proc 0; return 0 }
+ "$prompt" { set in_proc 0;
+ return 0
+ }
}
exp_continue
}
@@ -454,16 +478,14 @@ proc run_commands { prompt command } {
global in_proc platform
set in_proc 1
- # If the prompt is (enable), then we are on a switch and the
- # command is "set length 0"; otherwise its "term length 0".
- # skip if its and extreme.
+ # Turn off the pager and escape regex meta characters in the $prompt
send "no page\r"
regsub -all "\[)(]" $prompt {\\&} reprompt
- expect {
- -re $reprompt {}
- -re "\[\n\r]+" { exp_continue }
- }
- # this is the only way i see to get rid for more prompts in o/p..grrrrr
+ expect {
+ -re $reprompt {}
+ -re "\[\n\r]+" { exp_continue }
+ }
+ # 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" ] {
@@ -491,6 +513,10 @@ proc run_commands { prompt command } {
}
-re "^<-+ More -+>\[^\n\r]*" { send " "
exp_continue }
+ -re "^-+ MORE -+\[^\n\r]*" { send " "
+ exp_continue }
+ -re "^-+More-+\[^\n\r]*" { send " "
+ exp_continue }
-re "\b+" { exp_continue }
}
}
@@ -516,11 +542,13 @@ proc run_commands { prompt command } {
exp_continue }
-re "^-+ MORE -+\[^\n\r]*" { send " "
exp_continue }
+ -re "^-+More-+\[^\n\r]*" { send " "
+ exp_continue }
-re "\b+" { exp_continue }
}
}
log_user 1
- send "exit\r"
+ send -h "exit\r"
expect {
"Do you want to save current configuration" {
send "n\r"
@@ -536,10 +564,12 @@ proc run_commands { prompt command } {
}
-re "\[\r\n]+" { exp_continue }
-re "^.+>" {
- send "exit\r"
+ send -h "exit\r"
exp_continue
}
- timeout { return 0 }
+ timeout { catch {close}; wait
+ return 0
+ }
eof { return 0 }
}
set in_proc 0
@@ -570,6 +600,7 @@ foreach router [lrange $argv $i end] {
set prompt "#"
} else {
set autoenable 0
+ set enable $avenable
set prompt ">"
}
}
@@ -592,6 +623,9 @@ foreach router [lrange $argv $i end] {
}
set passwd [join [lindex $pswd 0] ""]
set enapasswd [join [lindex $pswd 1] ""]
+ } else {
+ set passwd $userpasswd
+ set enapasswd $enapasswd
}
# Figure out username
@@ -654,9 +688,9 @@ 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} }
+ # 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
@@ -671,17 +705,17 @@ foreach router [lrange $argv $i end] {
if { $enable } {
if {[do_enable $enauser $enapasswd]} {
if { $do_command || $do_script } {
- close; wait
+ catch {close}; catch {wait}
continue
}
}
}
# we are logged in, now figure out the full prompt
- send "\r"
- expect {
+ send "\r"
+ expect {
-re "\[\r\n]+" { exp_continue; }
-re "^.+$prompt" { set prompt $expect_out(0,string); }
- }
+ }
if { $do_command } {
if {[run_commands $prompt $command]} {
diff --git a/bin/hpuifilter.c b/bin/hpuifilter.c
index 8f7005a..c278a3f 100644
--- a/bin/hpuifilter.c
+++ b/bin/hpuifilter.c
@@ -1,7 +1,7 @@
/*
- * $Id: hpuifilter.c,v 1.17 2004/01/11 03:49:13 heas Exp $
+ * $Id: hpuifilter.c,v 1.36 2006/11/29 01:02:27 heas Exp $
*
- * Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+ * Copyright (C) 1997-2006 by Terrapin Communications, Inc.
* All rights reserved.
*
* This software may be freely copied, modified and redistributed
@@ -21,51 +21,117 @@
* point of hpfilter is to filter all the bloody vt100 (curses) escape codes
* that the HP procurve switches belch out, which are a real bitch to handle
* in hlogin.
+ *
+ * Modified openpty() from NetBSD:
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*/
-#define DFLT_TO 60 /* default timeout */
-#include <config.h>
-#include <version.h>
+#include "config.h"
+#include "version.h"
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
#include <stdio.h>
#include <limits.h>
#include <fcntl.h>
+#include <poll.h>
+#if HAVE_PTY_H
+# include <pty.h>
+#endif
+#include <regex.h>
#include <signal.h>
+#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_PTMX && HAVE_STROPTS_H
+# include <stropts.h>
+#endif
+#include <sys/ioctl.h>
+#include <sys/stat.h>
#include <sys/time.h>
-#include <regex.h>
-
#include <termios.h>
+#if HAVE_UTIL_H
+# include <util.h>
+#endif
-char *progname;
-int debug = 0;
+#define BUFSZ (LINE_MAX * 2)
+
+char **environ,
+ *progname;
+int child,
+ debug,
+ drain,
+ timeo = 5; /* default timeout */
int filter __P((char *, int));
+RETSIGTYPE reapchild __P((void));
+#if !HAVE_OPENPTY
+int openpty(int *, int *, char *, struct termios *,
+ struct winsize *);
+#endif
+RETSIGTYPE sighdlr __P((int));
+#if !HAVE_UNSETENV
+int unsetenv __P((const char *));
+#endif
void usage __P((void));
void vers __P((void));
-RETSIGTYPE reapchild __P((void));
int
-main(int argc, char **argv)
+main(int argc, char **argv, char **ev)
{
extern char *optarg;
extern int optind;
char ch,
- hbuf[LINE_MAX * 2], /* hlogin buffer */
- *hbufp,
- tbuf[LINE_MAX * 2], /* telnet buffer */
+ hbuf[BUFSZ], /* hlogin buffer */
+ ptyname[FILENAME_MAX + 1],
+ tbuf[BUFSZ], /* telnet/ssh buffer */
*tbufp;
int bytes, /* bytes read/written */
- child,
- r[2], /* recv pipe */
- s[2]; /* send pipe */
+ devnull,
+ rval = EX_OK,
+ ptym, /* master pty */
+ ptys; /* slave pty */
ssize_t hlen = 0, /* len of hbuf */
tlen = 0; /* len of tbuf */
- struct timeval to = { DFLT_TO, 0 };
- fd_set rfds, /* select() */
- wfds;
+ struct pollfd pfds[3];
struct termios tios;
+ environ = ev;
+
/* get just the basename() of our exec() name and strip a .* off the end */
if ((progname = strrchr(argv[0], '/')) != NULL)
progname += 1;
@@ -74,11 +140,16 @@ main(int argc, char **argv)
if (strrchr(progname, '.') != NULL)
*(strrchr(progname, '.')) = '\0';
- while ((ch = getopt(argc, argv, "dhv")) != -1 )
+ while ((ch = getopt(argc, argv, "dhvt:")) != -1 )
switch (ch) {
case 'd':
debug++;
break;
+ case 't':
+ timeo = atoi(optarg);
+ if (timeo < 1)
+ timeo = 1;
+ break;
case 'v':
vers();
return(EX_OK);
@@ -93,26 +164,41 @@ main(int argc, char **argv)
return(EX_USAGE);
}
- /* reap our children */
- signal(SIGCHLD, (void *) reapchild);
- signal(SIGHUP, (void *) reapchild);
- signal(SIGINT, (void *) reapchild);
- signal(SIGTERM, (void *) reapchild);
+ unsetenv("DISPLAY");
- /* create 2 pipes for send/recv and then fork and exec telnet */
for (child = 3; child < 10; child++)
close(child);
- if (pipe(s) || pipe(r)) {
- fprintf(stderr, "%s: pipe() failed: %s\n", progname,
+
+ /* allocate pty for telnet/ssh, then fork and exec */
+ if (openpty(&ptym, &ptys, ptyname, NULL, NULL)) {
+ fprintf(stderr, "%s: could not allocate pty: %s\n", progname,
strerror(errno));
return(EX_TEMPFAIL);
}
+ /* make the pty raw */
+ if (tcgetattr(ptys, &tios)) {
+ fprintf(stderr, "%s: tcgetattr() failed: %s\n", progname,
+ strerror(errno));
+ return(EX_OSERR);
+ }
+ tios.c_lflag &= ~ECHO;
+ tios.c_lflag &= ~ICANON;
+#ifdef VMIN
+ tios.c_cc[VMIN] = 1;
+ tios.c_cc[VTIME] = 0;
+#endif
+ if (tcsetattr(ptys, TCSANOW, &tios)) {
+ fprintf(stderr, "%s: tcsetattr() failed: %s\n", progname,
+ strerror(errno));
+ return(EX_OSERR);
+ }
- /* if a tty, make it raw as the hp echos _everything_, including
+ /*
+ * if a tty, make it raw as the hp echos _everything_, including
* passwords.
*/
- if (isatty(0)) {
- if (tcgetattr(0, &tios)) {
+ if (isatty(fileno(stdin))) {
+ if (tcgetattr(fileno(stdin), &tios)) {
fprintf(stderr, "%s: tcgetattr() failed: %s\n", progname,
strerror(errno));
return(EX_OSERR);
@@ -123,180 +209,272 @@ main(int argc, char **argv)
tios.c_cc[VMIN] = 1;
tios.c_cc[VTIME] = 0;
#endif
- if (tcsetattr(0, TCSANOW, &tios)) {
+ if (tcsetattr(fileno(stdin), TCSANOW, &tios)) {
fprintf(stderr, "%s: tcsetattr() failed: %s\n", progname,
strerror(errno));
return(EX_OSERR);
}
}
+ /* zero the buffers */
+ memset(hbuf, 0, BUFSZ);
+ memset(tbuf, 0, BUFSZ);
+
+ /* reap our children, must be set-up *after* openpty() */
+ signal(SIGCHLD, (void *) reapchild);
+
if ((child = fork()) == -1) {
- fprintf(stderr, "%s: fork() failed: %s\n", progname,
- strerror(errno));
+ fprintf(stderr, "%s: fork() failed: %s\n", progname, strerror(errno));
return(EX_TEMPFAIL);
}
- /* zero the buffers */
- bzero(hbuf, LINE_MAX * 2);
- bzero(tbuf, LINE_MAX * 2);
-
if (child == 0) {
- /* close the parent's side of the pipes; we write r[1], read s[0] */
- close(s[1]);
- close(r[0]);
+ struct winsize ws;
+
+ /*
+ * Make sure our terminal length and width are something greater
+ * than 1, for pagers on stupid boxes.
+ */
+ ioctl(ptys, TIOCGWINSZ, &ws);
+ ws.ws_row = 24;
+ ws.ws_col = 132;
+ ioctl(ptys, TIOCSWINSZ, &ws);
+
+ signal(SIGCHLD, SIG_DFL);
+ /* close the master pty & std* inherited from the parent */
+ close(ptym);
+ if (ptys != 0)
+ close(0);
+ if (ptys != 1)
+ close(1);
+ if (ptys != 2)
+ close(2);
+#ifdef TIOCSCTTY
+ setsid();
+ if (ioctl(ptys, TIOCSCTTY, NULL) == -1) {
+ snprintf(ptyname, FILENAME_MAX, "%s: could not set controlling "
+ "tty: %s\n", progname, strerror(errno));
+ write(0, ptyname, strlen(ptyname));
+ return(EX_OSERR);
+ }
+#endif
+
/* close stdin/out/err and attach them to the pipes */
- if (dup2(s[0], 0) == -1 || dup2(r[1], 1) == -1 || dup2(r[1], 2) == -1) {
- fprintf(stderr, "%s: dup2() failed: %s\n", progname,
- strerror(errno));
+ if (dup2(ptys, 0) == -1 || dup2(ptys, 1) == -1 || dup2(ptys, 2) == -1) {
+ snprintf(ptyname, FILENAME_MAX, "%s: dup2() failed: %s\n", progname,
+ strerror(errno));
+ write(0, ptyname, strlen(ptyname));
return(EX_OSERR);
}
- close(s[0]);
- close(r[1]);
- /* exec telnet */
- if (execvp(argv[optind], argv + optind)) {
- fprintf(stderr, "%s: execlp() failed: %s\n", progname,
+ if (ptys > 2)
+ close(ptys);
+
+ /* exec telnet/ssh */
+ execvp(argv[optind], argv + optind);
+ snprintf(ptyname, FILENAME_MAX, "%s: execvp() failed: %s\n", progname,
+ strerror(errno));
+ write(0, ptyname, strlen(ptyname));
+ return(EX_TEMPFAIL);
+ /*NOTREACHED*/
+ }
+
+ /* parent */
+ if (debug)
+ fprintf(stderr, "child %d\n", child);
+
+ signal(SIGHUP, (void *) sighdlr);
+
+ /* close the slave pty */
+ close(ptys);
+
+ devnull = open("/dev/null", O_RDWR);
+
+ /* make FDs non-blocking */
+ if (fcntl(ptym, F_SETFL, O_NONBLOCK) ||
+ fcntl(fileno(stdin), F_SETFL, O_NONBLOCK) ||
+ fcntl(fileno(stdout), F_SETFL, O_NONBLOCK)) {
+ fprintf(stderr, "%s: fcntl(NONBLOCK) failed: %s\n", progname,
strerror(errno));
- return(EX_TEMPFAIL);
+ exit(EX_OSERR);
+ }
+
+ /* loop to read on stdin and ptym */
+#define POLLEXP (POLLERR | POLLHUP | POLLNVAL)
+ pfds[0].fd = fileno(stdin);
+ pfds[0].events = POLLIN | POLLEXP;
+ pfds[1].fd = fileno(stdout);
+ pfds[2].fd = ptym;
+ pfds[2].events = POLLIN | POLLEXP;
+
+ while (1) {
+ bytes = poll(pfds, 3, (timeo * 1000));
+ if (bytes == 0) {
+ if (drain)
+ break;
+ /* timeout */
+ continue;
}
- /* not reached */
- } else {
- /* parent */
- if (debug)
- fprintf(stderr, "child %d\n", child);
-
- /* close the child's side of the pipes; we write s[1], read r[0] */
- close(s[0]);
- close(r[1]);
-
- /* make FDs non-blocking */
- if (fcntl(s[1], F_SETFL, O_NONBLOCK) ||
- fcntl(r[0], F_SETFL, O_NONBLOCK) ||
- fcntl(0, F_SETFL, O_NONBLOCK) ||
- fcntl(1, F_SETFL, O_NONBLOCK)) {
- fprintf(stderr, "%s: fcntl(NONBLOCK) failed: %s\n", progname,
- strerror(errno));
- exit(EX_OSERR);
+ if (bytes == -1) {
+ switch (errno) {
+ case EAGAIN:
+ case EINTR:
+ break;
+ default:
+ rval = EX_IOERR;
+ break;
+ }
+ continue;
}
- /* loop to read on stdin and r[0] */
- FD_ZERO(&rfds); FD_ZERO(&wfds);
- hbufp = hbuf; tbufp = tbuf;
+ /*
+ * write buffers first
+ * write hbuf (stdin) -> ptym
+ */
+ if ((pfds[2].revents & POLLOUT) && hlen) {
+ if ((bytes = write(pfds[2].fd, hbuf, hlen)) < 0 &&
+ errno != EINTR && errno != EAGAIN) {
+ fprintf(stderr, "%s: write() failed: %s\n", progname,
+ strerror(errno));
+ hbuf[0] = '\0';
+ hlen = 0;
+ drain = 1;
+ pfds[2].events &= ~POLLOUT;
- while (1) {
- FD_SET(0, &rfds); FD_SET(r[0], &rfds);
- /* if we have stuff in our buffer(s), we select on writes too */
- FD_ZERO(&wfds);
- if (hlen) {
- FD_SET(s[1], &wfds);
- }
- if (tlen) {
- FD_SET(1, &wfds);
+ break;
+ } else if (bytes > 0) {
+ strcpy(hbuf, hbuf + bytes);
+ hlen -= bytes;
+ if (hlen < 1)
+ pfds[2].events &= ~POLLOUT;
}
+ } else if (pfds[2].revents & POLLEXP) {
+ hbuf[0] = '\0';
+ hlen = 0;
+ pfds[2].events &= POLLIN;
+ break;
+ }
- switch (select(r[1], &rfds, &wfds, NULL, &to)) {
- case 0:
- /* timeout */
- /* HEAS: what do i do here? */
+ /* write tbuf -> stdout */
+ if ((pfds[1].revents & POLLOUT) && tlen) {
+ /*
+ * if there is an escape char that didnt get filter()'d,
+ * we need to write only up to that point and wait for
+ * the bits that complete the escape sequence. if at least
+ * two bytes follow it, write it anyway as filter() didnt
+ * match it.
+ */
+ bytes = tlen;
+ if ((tbufp = index(tbuf, 0x1b)) != NULL)
+ if (tlen - (tbufp - tbuf) < 2)
+ bytes = tbufp - tbuf;
+
+ if ((bytes = write(pfds[1].fd, tbuf, bytes)) < 0 &&
+ errno != EINTR && errno != EAGAIN) {
+ fprintf(stderr, "%s: write() failed: %s\n", progname,
+ strerror(errno));
break;
- case -1:
- switch (errno) {
- case EINTR: /* interrupted syscall */
+ tbuf[0] = '\0';
+ tlen = 0;
+ drain = 1;
+ pfds[1].events = 0;
+ } else if (bytes > 0) {
+ strcpy(tbuf, tbuf + bytes);
+ tlen -= bytes;
+ if (tlen < 1)
+ pfds[1].events &= ~POLLOUT;
+ }
+ } else if (pfds[1].revents & POLLEXP) {
+ break;
+ tbuf[0] = '\0';
+ tlen = 0;
+ pfds[1].fd = devnull;
+ pfds[1].events = 0;
+ }
+
+ /* read stdin -> hbuf */
+ if (pfds[0].revents & POLLIN) {
+ if (BUFSZ - hlen > 1) {
+ bytes = read(pfds[0].fd, hbuf + hlen, (BUFSZ - 1) - hlen);
+ if (bytes > 0) {
+ hlen += bytes;
+ hbuf[hlen] = '\0';
+ pfds[2].events |= POLLOUT;
+ } else if (bytes == 0 && errno != EAGAIN && errno != EINTR) {
break;
- default:
- exit(EX_IOERR);
+ /* EOF or read error */
+ drain = 1;
+ pfds[0].fd = devnull;
+ pfds[0].events = 0;
}
- break;
- default:
- /* check exceptions first */
-
- /* which FD is ready? write our buffers asap. */
- /* write hbuf (stdin) -> s[1] */
- if (FD_ISSET(s[1], &wfds) && hlen) {
- if ((hlen = write(s[1], hbuf, hlen)) < 0) {
- fprintf(stderr, "%s: write() failed: %s\n", progname,
- strerror(errno));
- close(s[1]);
- } else
- strcpy(hbuf, hbuf + hlen);
-
- hlen = strlen(hbuf);
- }
- /* write tbuf -> stdout */
- if (FD_ISSET(1, &wfds) && tlen) {
- /* if there is an escape char that didnt get filter()'d,
- * we need to only write up to that point and wait for
- * the bits that complete the escape sequence
- */
- if ((tbufp = index(tbuf, 0x1b)) != NULL)
- tlen = tbufp - tbuf;
-
- if ((tlen = write(1, tbuf, tlen)) < 0) {
- fprintf(stderr, "%s: write() failed: %s\n", progname,
- strerror(errno));
- close(1);
- } else
- strcpy(tbuf, tbuf + tlen);
-
- tlen = strlen(tbuf);
- }
- if (FD_ISSET(0, &rfds)) {
- /* read stdin into hbuf */
- if (LINE_MAX * 2 - hlen > 1) {
- hlen += read(0, hbuf + hlen,
- (LINE_MAX * 2 - 1) - hlen);
- if (hlen > 0) {
- hbuf[hlen] = '\0';
- } else if (hlen == 0 || errno != EAGAIN)
- /* EOF or read error */
- close(0);
-
- hlen = strlen(hbuf);
- }
- } else if (FD_ISSET(r[0], &rfds)) {
- /* read telnet into tbuf, then filter */
- if (LINE_MAX * 2 - tlen > 1) {
- tlen += read(r[0], tbuf + tlen,
- (LINE_MAX * 2 - 1) - tlen);
- if (tlen > 0) {
- tbuf[tlen] = '\0';
- tlen = filter(tbuf, tlen);
- } else if (tlen == 0 || errno != EAGAIN)
- /* EOF or read error */
- close(r[0]);
-
- tlen = strlen(tbuf);
- }
- }
-
- break;
}
+ } else if (pfds[0].revents & POLLEXP) {
+ break;
+ drain = 1;
+ pfds[0].fd = devnull;
+ pfds[0].events = 0;
}
- /* close */
- close(0);
- close(1);
- close(s[1]);
- close(r[0]);
+ /* read telnet/ssh -> tbuf, then filter */
+ if (pfds[2].revents & POLLIN) {
+ if (BUFSZ - tlen > 1) {
+ bytes = read(pfds[2].fd, tbuf + tlen, (BUFSZ - 1) - tlen);
+ if (bytes > 0) {
+ tlen += bytes;
+ tbuf[tlen] = '\0';
+ tlen = filter(tbuf, tlen);
+ if (tlen > 0)
+ pfds[1].events |= POLLOUT;
+ } else if (bytes == 0 && errno != EAGAIN && errno != EINTR) {
+ /* EOF or read error */
+ break;
+ drain = 1;
+ pfds[2].fd = devnull;
+ pfds[2].events = 0;
+ }
+ }
+ } else if (pfds[2].revents & POLLEXP) {
+ break;
+ drain = 1;
+ pfds[2].fd = devnull;
+ pfds[2].events = 0;
+ }
+ }
+ /* try to flush buffers */
+ if (hlen) {
+ (void) write(pfds[2].fd, hbuf, hlen);
+ hlen = 0;
}
+ if (tlen) {
+ (void) write(pfds[1].fd, tbuf, tlen);
+ tlen = 0;
+ }
+ if ((bytes = read(pfds[2].fd, tbuf, (BUFSZ - 1))) > 0) {
+ tbuf[bytes] = '\0';
+ tlen = filter(tbuf, bytes);
+ (void) write(pfds[1].fd, tbuf, tlen);
+ }
+ tcdrain(pfds[1].fd);
+ if ((hlen = read(pfds[0].fd, hbuf, (BUFSZ - 1))) > 0) {
+ (void) write(pfds[2].fd, hbuf, hlen);
+ }
+ tcdrain(pfds[2].fd);
- if (! kill(child, SIGQUIT))
+ if (child && ! kill(child, SIGINT))
reapchild();
- return(EX_OK);
+ return(rval);
}
int
-filter(buf, len)
- char *buf;
- int len;
+filter(char *buf, int len)
{
static regmatch_t pmatch[1];
-#define N_REG 11 /* number of regexes in reg[][] */
+#define N_REG 14 /* number of regexes in reg[][] */
static regex_t preg[N_REG];
static char reg[N_REG][50] = { /* vt100/220 escape codes */
"\e7\e\\[1;24r\e8", /* ds */
"\e8", /* fs */
-
+
"\e\\[2J",
"\e\\[2K", /* kE */
@@ -307,8 +485,12 @@ filter(buf, len)
"\e\\[\\?7l", /* RA */
"\e\\[\\?25h", /* ve */
"\e\\[\\?25l", /* vi */
+ "\e\\[K", /* ce */
+ "\e\\[7m", /* mr - ansi */
- "\eE", /* replace w/ CR */
+ /* replace these with CR */
+ "\e\\[0m", /* me */
+ "\eE",
};
char ebuf[256];
size_t nmatch = 1;
@@ -319,7 +501,7 @@ filter(buf, len)
if (index(buf, 0x1b) == 0 || len == 0)
return(len);
- for (x = 0; x < N_REG - 1; x++) {
+ for (x = 0; x < N_REG - 2; x++) {
if (! init) {
if ((err = regcomp(&preg[x], reg[x], REG_EXTENDED))) {
regerror(err, &preg[x], ebuf, 256);
@@ -342,53 +524,89 @@ filter(buf, len)
/* replace \eE w/ CR NL */
if (! init++) {
- if ((err = regcomp(&preg[N_REG - 1], reg[N_REG - 1], REG_EXTENDED))) {
- regerror(err, &preg[N_REG - 1], ebuf, 256);
- fprintf(stderr, "%s: regex compile failed: %s\n", progname,
- ebuf);
- abort();
- }
+ for (x = N_REG - 2; x < N_REG; x++)
+ if ((err = regcomp(&preg[x], reg[x], REG_EXTENDED))) {
+ regerror(err, &preg[x], ebuf, 256);
+ fprintf(stderr, "%s: regex compile failed: %s\n", progname,
+ ebuf);
+ abort();
+ }
}
- while (1)
- if ((err = regexec(&preg[N_REG - 1], buf, nmatch, pmatch, 0))) {
+ for (x = N_REG - 2; x < N_REG; x++) {
+ if ((err = regexec(&preg[x], buf, nmatch, pmatch, 0))) {
if (err != REG_NOMATCH) {
- regerror(err, &preg[N_REG - 1], ebuf, 256);
+ regerror(err, &preg[x], ebuf, 256);
fprintf(stderr, "%s: regexec failed: %s\n", progname, ebuf);
abort();
- } else
- break;
+ }
} else {
- *(buf + pmatch[0].rm_so) = '\n';
- strcpy(buf + pmatch[0].rm_so + 1, buf + pmatch[0].rm_eo);
- x = 0;
+ *(buf + pmatch[0].rm_so) = '\r';
+ *(buf + pmatch[0].rm_so + 1) = '\n';
+ strcpy(buf + pmatch[0].rm_so + 2, buf + pmatch[0].rm_eo);
+ x = N_REG - 2;
}
-
+ }
return(strlen(buf));
}
-RETSIGTYPE
+RETSIGTYPE
reapchild(void)
{
int status;
pid_t pid;
-
- /* HEAS: this needs to deal with/without wait3 via HAVE_WAIT3 */
+
+ /* XXX this needs to deal with/without wait3 via HAVE_WAIT3 */
while ((pid = wait3(&status, WNOHANG, 0)) > 0)
if (debug)
fprintf(stderr, "reap child %d\n", pid);
-
- /*exit(1);*/
-return;
+ if (pid == child)
+ child = 0;
- /* not reached */
-}
+ return;
+}
+
+RETSIGTYPE
+sighdlr(int sig)
+{
+ if (debug)
+ fprintf(stderr, "GOT SIGNAL %d\n", sig);
+ drain = 1;
+ return;
+}
+
+#if !HAVE_UNSETENV
+int
+unsetenv(const char *name)
+{
+ char **victim,
+ **end;
+ int len;
+ if (environ == NULL)
+ return(0);
+ len = strlen(name);
+ victim = environ;
+ while (*victim != NULL) {
+ if (strncmp(name, *victim, len) == 0 && victim[0][len] == '=')
+ break;
+ victim++;
+ }
+ if (*victim == NULL)
+ return(0);
+ end = victim + 1;
+ while (*end != NULL)
+ end++;
+ end--;
+ *victim = *end;
+ *end = NULL;
+ return(0);
+}
+#endif
void
usage(void)
{
- fprintf(stderr,
-"usage: %s [-hv] <telnet|ssh> [<ssh options>] <hostname> [<telnet_port>]\n",
- progname);
+ fprintf(stderr, "usage: %s [-hv] [-t timeout] <telnet|ssh> [<ssh options>]"
+ " <hostname> [<telnet_port>]\n", progname);
return;
}
@@ -398,3 +616,107 @@ vers(void)
fprintf(stderr, "%s: %s version %s\n", progname, package, version);
return;
}
+
+
+#if !HAVE_OPENPTY
+#include <grp.h>
+#define TTY_LETTERS "pqrstuvwxyzPQRST"
+#define TTY_OLD_SUFFIX "0123456789abcdef"
+#define TTY_NEW_SUFFIX "ghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+
+int
+openpty(int *amaster, int *aslave, char *name, struct termios *term,
+ struct winsize *winp)
+{
+ static char line[] = "/dev/XtyXX";
+ const char *cp1, *cp2, *cp, *linep;
+ int master, slave;
+ gid_t ttygid;
+ mode_t mode;
+ struct group *gr;
+
+#if HAVE_PTMX
+ if ((master =
+#if HAVE_PTMX_BSD
+ open("/dev/ptmx_bsd", O_RDWR))
+#else
+ open("/dev/ptmx", O_RDWR))
+#endif
+ != -1) {
+ linep = ptsname(master);
+ grantpt(master);
+ unlockpt(master);
+#ifndef TIOCSCTTY
+ setsid();
+#endif
+ if ((slave = open(linep, O_RDWR)) < 0) {
+ slave = errno;
+ (void) close(master);
+ errno = slave;
+ return(-1);
+ }
+#if HAVE_PTMX_OSF
+ {
+ char buf[10240];
+ if (ioctl (slave, I_LOOK, buf) != 0)
+ if (ioctl (slave, I_PUSH, "ldterm")) {
+ close(slave);
+ close(master);
+ return(-1);
+ }
+ }
+#elif HAVE_STROPTS_H
+ ioctl(slave, I_PUSH, "ptem");
+ ioctl(slave, I_PUSH, "ldterm");
+ ioctl(slave, I_PUSH, "ttcompat");
+#endif
+ goto gotit;
+ }
+ if (errno != ENOENT)
+ return(-1);
+#endif
+
+ if ((gr = getgrnam("tty")) != NULL) {
+ ttygid = gr->gr_gid;
+ mode = S_IRUSR|S_IWUSR|S_IWGRP;
+ } else {
+ ttygid = getgid();
+ mode = S_IRUSR|S_IWUSR;
+ }
+
+ for (cp1 = TTY_LETTERS; *cp1; cp1++) {
+ line[8] = *cp1;
+ for (cp = cp2 = TTY_OLD_SUFFIX TTY_NEW_SUFFIX; *cp2; cp2++) {
+ line[5] = 'p';
+ line[9] = *cp2;
+ if ((master = open(line, O_RDWR, 0)) == -1) {
+ if (errno != ENOENT)
+ continue; /* busy */
+ if (cp2 - cp + 1 < sizeof(TTY_OLD_SUFFIX))
+ return -1; /* out of ptys */
+ else
+ break; /* out of ptys in this group */
+ }
+ line[5] = 't';
+ linep = line;
+ if (chown(line, getuid(), ttygid) == 0 &&
+ chmod(line, mode) == 0 &&
+ (slave = open(line, O_RDWR, 0)) != -1) {
+gotit:
+ *amaster = master;
+ *aslave = slave;
+ if (name)
+ (void)strcpy(name, linep);
+ if (term)
+ (void)tcsetattr(slave, TCSAFLUSH, term);
+ if (winp)
+ (void)ioctl(slave, TIOCSWINSZ, winp);
+ return 0;
+ }
+ (void)close(master);
+ }
+ }
+ errno = ENOENT; /* out of ptys */
+ return -1;
+}
+#endif
diff --git a/bin/hrancid.in b/bin/hrancid.in
index fa048ce..0feefd0 100644
--- a/bin/hrancid.in
+++ b/bin/hrancid.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: hrancid.in,v 1.17 2004/01/11 03:49:13 heas Exp $
+## $Id: hrancid.in,v 1.27 2006/10/05 04:27:42 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -24,25 +25,30 @@
#
# RANCID - Really Awesome New Cisco confIg Differ
#
-# usage: rancid [-d] [-l] [-f filename | $host]
+# usage: rancid [-dV] [-l] [-f filename | hostname]
#
use Getopt::Std;
-getopts('dfl');
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
-$found_end = 0; # unused - hp lacks an end-of-config tag.
-$timeo = 90; # clogin timeout in seconds
+$found_end = 0; # unused - hp lacks an end-of-config tag
+$timeo = 90; # hlogin timeout in seconds
-my(%filter_pwds); # password filtering mode
+my(@commandtable, %commands, @commands);# command lists
+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) {
+ 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;
}
@@ -64,10 +70,10 @@ sub ProcessHistory {
sub numerically { $a <=> $b; }
-# This is a sort routing that will sort numerically on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
@@ -77,10 +83,10 @@ sub keynsort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
@@ -90,10 +96,10 @@ sub keysort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
@@ -103,9 +109,9 @@ sub valsort{
@sorted_lines;
}
-# This is a numerical sort routing (ascending).
+# This is a numerical sort routine (ascending).
sub numsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a <=> $b} keys %lines) {
@@ -119,7 +125,7 @@ sub numsort {
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
@@ -132,7 +138,7 @@ sub ipsort {
# 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]));
+ $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
@@ -159,8 +165,6 @@ sub ShowVersion {
# This routine parses "show flash"
sub ShowFlash {
- # skip if this is 7000, 7200, 7500, or 12000; else we end up with
- # redundant data from dir /all slot0:
print STDERR " In ShowFlash: $_" if ($debug);
while (<INPUT>) {
@@ -188,8 +192,14 @@ sub ShowSystem {
return(-1) if (/command authorization failed/i);
return(-1) if /^(Invalid|Ambiguous) input:/i;
- /memory\s+-\s+total\s+:\s+(\S+)/i &&
- ProcessHistory("COMMENTS","keysort","B0",";Memory: $1\n");
+ if (/memory\s+-\s+total\s+:\s+(\S+)/i) {
+ my($mem) = $1;
+ $mem =~ s/,//g;
+ $mem /= (1024 * 1024);
+ ProcessHistory("COMMENTS","keysort","B0",";Memory: " . int($mem) .
+ "M\n");
+ next;
+ }
/serial\s+number\s+:\s+(\S+)/i &&
ProcessHistory("COMMENTS","keysort","A1",";Serial Number: $1\n");
/firmware\s+revision\s+:\s+(\S+)/i &&
@@ -230,7 +240,7 @@ sub ShowStack {
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
return(-1) if (/command authorization failed/i);
- return(-1) if /^(Invalid|Ambiguous) input:/i;
+ return(1) if /^(Invalid|Ambiguous) input:/i;
s/stacking - (Stacking Status).*/$1/i;
s/\s*members unreachable .*$//i;
@@ -426,27 +436,31 @@ sub WriteTerm {
sub DoNothing {print STDOUT;}
# Main
-%commands=(
- 'show version' => "ShowVersion",
- 'show flash' => "ShowFlash",
- 'show system-information' => "ShowSystem",
- 'show module' => "ShowModule",
- 'show stack' => "ShowStack",
- 'write term' => "WriteTerm"
-);
-# keys() doesnt return things in the order entered and the order of the
-# cmds is important (show version first and write term last). pita
-@commands=(
- "show version",
- "show flash",
- "show system-information",
- "show module",
- "show stack",
- "write term"
+@commandtable = (
+ {'show version' => 'ShowVersion'},
+ {'show flash' => 'ShowFlash'},
+ {'show system-information' => 'ShowSystem'},
+ {'show module' => 'ShowModule'},
+ {'show stack' => 'ShowStack'},
+ {'write term' => 'WriteTerm'}
);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
+
$cisco_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
@@ -469,7 +483,7 @@ if ($file) {
# determine password filtering mode
if ($ENV{"FILTER_PWDS"} =~ /no/i) {
- $filter_pwds = 0;
+ $filter_pwds = 0;
} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
$filter_pwds = 2;
} else {
diff --git a/bin/htlogin.in b/bin/htlogin.in
index 8e9c5f5..213f028 100644
--- a/bin/htlogin.in
+++ b/bin/htlogin.in
@@ -1,8 +1,9 @@
#! @EXPECT_PATH@ --
##
-## $Id: htlogin.in,v 1.7 2004/01/11 05:39:15 heas Exp $
+## $Id: htlogin.in,v 1.18 2006/12/05 16:50:52 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -42,7 +43,7 @@ set password_file $env(HOME)/.cloginrc
set do_command 0
set do_script 0
# The default is to automatically enable
-set enable 1
+set avenable 1
# The default is that you login non-enabled (tacacs can have you login already
# enabled)
set avautoenable 0
@@ -51,7 +52,7 @@ set avautoenable 0
set do_passwd 1
# Find the user in the ENV, or use the unix userid.
-if {[ info exists env(CISCO_USER) ] } {
+if {[ info exists env(CISCO_USER) ]} {
set default_user $env(CISCO_USER)
} elseif {[ info exists env(USER) ]} {
set default_user $env(USER)
@@ -64,9 +65,12 @@ if {[ info exists env(CISCO_USER) ] } {
if [ catch {exec id} reason ] {
send_error "\nError: could not exec id: $reason\n"
exit 1
- }
+ }
regexp {\(([^)]*)} "$reason" junk default_user
-}
+}
+if {[ info exists env(CLOGINRC) ]} {
+ set password_file $env(CLOGINRC)
+}
# Sometimes routers take awhile to answer (the default is 10 sec)
set timeout 45
@@ -92,13 +96,16 @@ for {set i 0} {$i < $argc} {incr i} {
}
set do_passwd 0
# VTY Password
- } -v* -
- -v* {
+ } -v* {
if {! [ regexp .\[vV\](.+) $arg ignore passwd]} {
incr i
set passwd [ lindex $argv $i ]
}
set do_passwd 0
+ # Version string
+ } -V* {
+ send_user "@PACKAGE@ @VERSION@\n"
+ exit 0
# Enable Username
} -w* -
-W* {
@@ -270,31 +277,44 @@ proc source_password_file { password_file } {
}
# Log into the router.
+# returns: 0 on success, 1 on failure
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
+ 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] {
+ incr progs -1
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} reason ]
+ } else {
set retval [ catch {spawn telnet $router $port} reason ]
}
if { $retval } {
send_user "\nError: telnet failed: $reason\n"
- exit 1
+ return 1
}
+ } elseif ![string compare $prog "ssh"] {
+ send_error "\nError: unsupported method: ssh\n"
+ if { $progs == 0 } {
+ return 1
+ }
+ continue
+ } elseif ![string compare $prog "rsh"] {
+ send_error "\nError: unsupported method: rsh\n"
+ if { $progs == 0 } {
+ return 1
+ }
+ continue
} else {
- puts "\nError: unknown connection method: $prog"
+ send_user "\nError: unknown connection method: $prog\n"
return 1
}
- incr progs -1
sleep 0.3
# This helps cleanup each expect clause.
@@ -376,7 +396,7 @@ proc run_commands { prompt command } {
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 *]*$prompt" {}
-re "\[\n\r]" { exp_continue }
}
@@ -384,16 +404,18 @@ proc run_commands { prompt command } {
} else {
send "$command\r"
expect {
- -re "^\[^\n\r]*$prompt" {}
+ -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 }
+ "\n" { exp_continue }
+ timeout { catch {close}; wait
+ return 0
+ }
+ eof { return 0 }
}
set in_proc 0
}
diff --git a/bin/htrancid.in b/bin/htrancid.in
index 2b2eaaa..d15d569 100644
--- a/bin/htrancid.in
+++ b/bin/htrancid.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: htrancid.in,v 1.5 2004/01/11 03:49:13 heas Exp $
+## $Id: htrancid.in,v 1.13 2006/10/05 04:27:43 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -23,25 +24,30 @@
#
# RANCID - Really Awesome New Cisco confIg Differ
#
-# usage: htrancid [-d] [-l] [-f filename | $host]
+# usage: htrancid [-dV] [-l] [-f filename | hostname]
#
use Getopt::Std;
-getopts('dfl');
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
-$timeo = 90; # blogin timeout in seconds
+$timeo = 90; # htlogin timeout in seconds
-my(%filter_pwds); # password filtering mode
+my(@commandtable, %commands, @commands);# command lists
+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) {
+ 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;
}
@@ -63,10 +69,10 @@ sub ProcessHistory {
sub numerically { $a <=> $b; }
-# This is a sort routing that will sort numerically on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
@@ -76,10 +82,10 @@ sub keynsort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
@@ -89,10 +95,10 @@ sub keysort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
@@ -102,9 +108,9 @@ sub valsort{
@sorted_lines;
}
-# This is a numerical sort routing (ascending).
+# This is a numerical sort routine (ascending).
sub numsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a <=> $b} keys %lines) {
@@ -118,7 +124,7 @@ sub numsort {
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
@@ -131,7 +137,7 @@ sub ipsort {
# 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]));
+ $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
@@ -166,19 +172,27 @@ sub ShowVersion {
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"
+@commandtable = (
+ {'version -a' => 'ShowVersion'},
+ {'cat /config/router.cnf' => 'ShowConfig'}
);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
+
$cisco_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
@@ -201,7 +215,7 @@ if ($file) {
# determine password filtering mode
if ($ENV{"FILTER_PWDS"} =~ /no/i) {
- $filter_pwds = 0;
+ $filter_pwds = 0;
} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
$filter_pwds = 2;
} else {
@@ -224,8 +238,8 @@ TOP: while(<INPUT>) {
while (/command:\s*($cmds_regexp)\s*$/) {
$cmd = $1;
if (!defined($prompt)) {
- $prompt = ($_ =~ /^([^:]+:)/)[0];
- }
+ $prompt = ($_ =~ /^([^:]+:)/)[0];
+ }
print STDERR ("HIT COMMAND:$_") if ($debug);
if (! defined($commands{$cmd})) {
print STDERR "$host: found unexpected command - \"$cmd\"\n";
diff --git a/bin/jerancid.in b/bin/jerancid.in
index 1b72737..c0fb33e 100644
--- a/bin/jerancid.in
+++ b/bin/jerancid.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: jerancid.in,v 1.25 2004/01/11 03:49:13 heas Exp $
+## $Id: jerancid.in,v 1.36 2006/10/05 04:27:43 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -23,25 +24,30 @@
#
# RANCID - Really Awesome New Cisco confIg Differ
#
-# usage: rancid [-d] [-l] [-f filename | $host]
+# usage: rancid [-dV] [-l] [-f filename | hostname]
#
use Getopt::Std;
-getopts('dfl');
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
-$timeo = 90; # clogin timeout in seconds
+$timeo = 90; # clogin timeout in seconds
-my(%filter_pwds); # password filtering mode
+my(@commandtable, %commands, @commands);# command lists
+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) {
+ 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;
}
@@ -63,10 +69,10 @@ sub ProcessHistory {
sub numerically { $a <=> $b; }
-# This is a sort routing that will sort numerically on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
@@ -76,10 +82,10 @@ sub keynsort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
@@ -89,10 +95,10 @@ sub keysort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
@@ -102,9 +108,9 @@ sub valsort{
@sorted_lines;
}
-# This is a numerical sort routing (ascending).
+# This is a numerical sort routine (ascending).
sub numsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a <=> $b} keys %lines) {
@@ -118,7 +124,7 @@ sub numsort {
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
@@ -131,7 +137,7 @@ sub ipsort {
# 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]));
+ $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
@@ -203,6 +209,8 @@ sub ShowEnv {
next if (/^(\s*|\s*$cmd\s*)$/);
next if (/^Please wait/i);
return(-1) if (/command authorization failed/i);
+ # fail if the RP is amid the auto-sync process
+ return(-1) if (/auto-sync enabled/ && !/in sync/);
# skip the temperature goop
if (/processor\s+processor/) {
@@ -260,6 +268,8 @@ sub DirSlotN {
next if (/^(\s*|\s*$cmd\s*)$/);
next if (/^Please wait/i);
next if (/^system\.log/);
+ # fail if the RP is amid the auto-sync process
+ return(-1) if (/active\/standby/i && /not sync/);
ProcessHistory("FLASH","","","!Flash: $_");
}
@@ -303,6 +313,8 @@ sub WriteTerm {
# skip the crap
/^! Configuration script /i && next;
/^! Copyright /i && next;
+ /^Please wait/i && next;
+ /^(\.+)$/ && next; # Skip variable length pausing dot lines
# Dog gone Cool matches to process the rest of the config
/^ntp clock-period / && next; # kill ntp clock-period
@@ -530,29 +542,32 @@ sub WriteTerm {
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"
+@commandtable = (
+ {'show version' => 'ShowVersion'},
+ {'show redundancy' => 'ShowRedundancy'},
+ {'show boot' => 'ShowBoot'},
+ {'show environment all' => 'ShowEnv'},
+ {'dir' => 'DirSlotN'},
+ {'show hardware' => 'ShowHardware'},
+ {'show configuration' => 'WriteTerm'}
);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
+
$jnxe_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
diff --git a/bin/jlogin.in b/bin/jlogin.in
index 31be4f6..729afa7 100644
--- a/bin/jlogin.in
+++ b/bin/jlogin.in
@@ -1,8 +1,9 @@
#! @EXPECT_PATH@ --
##
-## $Id: jlogin.in,v 1.41 2004/01/11 05:39:15 heas Exp $
+## $Id: jlogin.in,v 1.56 2006/12/05 16:50:52 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -42,15 +43,13 @@ set password_file $env(HOME)/.cloginrc
set do_command 0
set do_script 0
# The default is to automatically enable
-set enable 1
+set avenable 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
-# No passphrase by default
-set passphrase ""
# Find the user in the ENV, or use the unix userid.
-if {[ info exists env(CISCO_USER) ] } {
+if {[ info exists env(CISCO_USER) ]} {
set default_user $env(CISCO_USER)
} elseif {[ info exists env(USER) ]} {
set default_user $env(USER)
@@ -66,6 +65,9 @@ if {[ info exists env(CISCO_USER) ] } {
}
regexp {\(([^)]*)} "$reason" junk default_user
}
+if {[ info exists env(CLOGINRC) ]} {
+ set password_file $env(CLOGINRC)
+}
# Sometimes routers take awhile to answer (the default is 10 sec)
set timeout 120
@@ -107,12 +109,16 @@ for {set i 0} {$i < $argc} {incr i} {
set userpasswd [ lindex $argv $i ]
}
set do_passwd 0
+ # Version string
+ } -V* {
+ send_user "@PACKAGE@ @VERSION@\n"
+ exit 0
# passphrase
} -r* -
-R* {
if {! [ regexp .\[rR\](.+) $arg ignore passphrase]} {
incr i
- set passphrase [ lindex $argv $i ]
+ set avpassphrase [ lindex $argv $i ]
}
# Expect script to run.
} -s* -
@@ -254,6 +260,7 @@ proc source_password_file { password_file } {
}
# Log into the router.
+# returns: 0 on success, 1 on failure
proc login { router user passwd cmethod cyphertype identfile} {
global spawn_id in_proc do_command do_script passphrase prompt
global sshcmd
@@ -262,6 +269,7 @@ proc login { router user passwd cmethod cyphertype identfile} {
# try each of the connection methods in $cmethod until one is successful
set progs [llength $cmethod]
foreach prog [lrange $cmethod 0 end] {
+ incr progs -1
if [string match "telnet*" $prog] {
regexp {telnet(:([^[:space:]]+))*} $prog command suffix port
if {"$port" == ""} {
@@ -271,7 +279,7 @@ proc login { router user passwd cmethod cyphertype identfile} {
}
if { $retval } {
send_user "\nError: telnet failed: $reason\n"
- exit 1
+ return 1
}
} elseif ![string compare $prog "ssh"] {
# ssh to the router & try to login with or without an identfile.
@@ -280,24 +288,24 @@ proc login { router user passwd cmethod cyphertype identfile} {
if {$identfile != ""} {
if [ catch {spawn $sshcmd -c $cyphertype -x -l $user -i $identfile $router} reason ] {
send_user "\nError: failed to $sshcmd: $reason\n"
- exit 1
+ return 1
}
} else {
if [ catch {spawn $sshcmd -c $cyphertype -x -l $user $router} reason ] {
send_user "\nError: failed to $sshcmd: $reason\n"
- exit 1
+ return 1
}
}
} elseif ![string compare $prog "rsh"] {
- if [ catch {spawn rsh -l $user $router} reason ] {
- send_user "\nError: rsh failed: $reason\n"
- exit 1
+ send_error "\nError: unsupported method: rsh\n"
+ if { $progs == 0 } {
+ return 1
}
+ continue
} else {
- puts "\nError: unknown connection method: $prog"
+ send_user "\nError: unknown connection method: $prog\n"
return 1
}
- incr progs -1
sleep 0.3
# This helps cleanup each expect clause.
@@ -345,8 +353,12 @@ proc login { router user passwd cmethod cyphertype identfile} {
catch {close};
send_user "\nError: Unknown host\n"; wait; return 1
}
- -re "Enter passphrase for RSA key '\[^'\]*': " {
- send_user "\nKey has passphrase!\n"
+ "Login incorrect" {
+ send_user "\nError: Check your password for $router\n"
+ catch {close}; wait; return 1
+ }
+ -re "Enter passphrase.*: " {
+ # sleep briefly to allow time for stty -echo
sleep 1
send "$passphrase\r"
exp_continue }
@@ -423,9 +435,11 @@ proc run_commands { prompt command } {
}
send "quit\r"
expect {
- "\n" { exp_continue }
- timeout { return 0 }
- eof { return 0 }
+ "\n" { exp_continue }
+ timeout { catch {close}; wait
+ return 0
+ }
+ eof { return 0 }
}
set in_proc 0
}
@@ -465,10 +479,17 @@ foreach router [lrange $argv $i end] {
}
}
- # figure out identity file to use
- set identfile ""
- if {[info exists identity]} {
- set identfile [join [lindex [find identity $router] 0] ""]
+ # Figure out identity file to use
+ set identfile [join [lindex [find identity $router] 0] ""]
+
+ # Figure out passphrase to use
+ if {[info exists avpassphrase]} {
+ set passphrase $avpassphrase
+ } else {
+ set passphrase [join [lindex [find passphrase $router] 0] ""]
+ }
+ if { ! [string length "$passphrase"]} {
+ set passphrase $passwd
}
# Figure out ssh cypher type
@@ -484,9 +505,9 @@ 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} }
+ # 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]} {
diff --git a/bin/jrancid.in b/bin/jrancid.in
index 2793446..252b1a3 100644
--- a/bin/jrancid.in
+++ b/bin/jrancid.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: jrancid.in,v 1.58 2004/01/11 03:49:13 heas Exp $
+## $Id: jrancid.in,v 1.80 2006/12/05 17:14:27 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -24,10 +25,14 @@
#
# RANCID - Really Awesome New Cisco confIg Differ
#
-# usage: jrancid [-d] [-l] [-f filename | $host]
+# usage: jrancid [-dV] [-l] [-f filename | hostname]
#
use Getopt::Std;
-getopts('dfl');
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
$debug = $opt_d;
$log = $opt_l;
$file = $opt_f;
@@ -35,14 +40,17 @@ $host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
+$timeo = 120; # clogin timeout in seconds
-my(%filter_pwds); # password filtering mode
+my(@commandtable, %commands, @commands);# command lists
+my(%filter_pwds); # password filtering mode
+my($ShowChassisSCB); # Only run ShowChassisSCB() once
# 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) {
+ 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;
}
@@ -64,10 +72,10 @@ sub ProcessHistory {
sub numerically { $a <=> $b; }
-# This is a sort routing that will sort numerically on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
@@ -77,10 +85,10 @@ sub keynsort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
@@ -90,22 +98,22 @@ sub keysort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
- $sorted_lines[$i] = $key;
- $i++;
+ $sorted_lines[$i] = $key;
+ $i++;
}
@sorted_lines;
}
-# This is a numerical sort routing (ascending).
+# This is a numerical sort routine (ascending).
sub numsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a <=> $b} keys %lines) {
@@ -119,7 +127,7 @@ sub numsort {
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
@@ -132,7 +140,7 @@ sub ipsort {
# 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]));
+ $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
@@ -150,9 +158,9 @@ sub ShowChassisClocks {
ProcessHistory("","","","# $_");
while (<INPUT>) {
tr/\015//d;
- last if(/^$prompt/);
- next if(/^system (shutdown message from|going down )/i);
- next if(/^\{(master|backup)}/);
+ 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;
@@ -162,10 +170,20 @@ sub ShowChassisClocks {
/syntax error/ && return;
# filter decimal places of m160 measured clock MHz
- /Measured frequency/ && s/\..*MHz/ MHz/;
+ if (/Measured frequency/) {
+ s/\..*MHz/ MHz/;
+ } elsif (/^.+\.[0-9]+ MHz$/) {
+ # filter for the m160 (newer format)
+ s/\.[0-9]+ MHz/ MHz/;
+ } elsif (/^(.+)(\.[0-9]+) MHz/) {
+ # filter for T series
+ my($leadlen) = length($1);
+ $x = sprintf(" MHz%".length($2)."s", " ");
+ substr($_, $leadlen, length($2)+4, $x);
+ }
ProcessHistory("","","","# $_");
}
- return;
+ return(0);
}
# This routine parses "show chassis environment"
@@ -176,9 +194,9 @@ sub ShowChassisEnvironment {
ProcessHistory("","","","# $_");
while (<INPUT>) {
tr/\015//d;
- last if(/^$prompt/);
- next if(/^system (shutdown message from|going down )/i);
- next if(/^\{(master|backup)}/);
+ 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;
@@ -186,6 +204,7 @@ sub ShowChassisEnvironment {
/command is not valid/ && return;
/^\s+\^/ && return;
/syntax error/ && return;
+
/ backplane temperature/ && next;
/(\s*Power supply.*), temperature/ &&
ProcessHistory("","","","# $1\n") && next;
@@ -193,9 +212,11 @@ sub ShowChassisEnvironment {
ProcessHistory("","","","# $1\n") && next;
/(^.*\S)\s+ Spinning at .*$/ &&
ProcessHistory("","","","# $1\n") && next;
+ /(^.*\S)\s+Measurement/ &&
+ ProcessHistory("","","","# $1\n") && next;
ProcessHistory("","","","# $_");
}
- return;
+ return(0);
}
# This routine parses "show chassis firmware"
@@ -206,9 +227,9 @@ sub ShowChassisFirmware {
ProcessHistory("","","","# $_");
while (<INPUT>) {
tr/\015//d;
- last if(/^$prompt/);
- next if(/^system (shutdown message from|going down )/i);
- next if(/^\{(master|backup)}/);
+ 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;
@@ -216,9 +237,10 @@ sub ShowChassisFirmware {
/command is not valid/ && return;
/^\s+\^/ && return;
/syntax error/ && return;
+
ProcessHistory("","","","# $_");
}
- return;
+ return(0);
}
# This routine parses "show chassis fpc detail"
@@ -229,9 +251,9 @@ sub ShowChassisFpcDetail {
ProcessHistory("","","","# $_");
while (<INPUT>) {
tr/\015//d;
- last if(/^$prompt/);
- next if(/^system (shutdown message from|going down )/i);
- next if(/^\{(master|backup)}/);
+ 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;
@@ -239,12 +261,13 @@ sub ShowChassisFpcDetail {
/command is not valid/ && return;
/^\s+\^/ && return;
/syntax error/ && return;
+
/ Temperature/ && next;
/ Start time/ && next;
/ Uptime/ && next;
ProcessHistory("","","","# $_");
}
- return;
+ return(0);
}
# This routine parses "show chassis hardware"
@@ -255,9 +278,9 @@ sub ShowChassisHardware {
ProcessHistory("","","","# $_");
while (<INPUT>) {
tr/\015//d;
- last if(/^$prompt/);
- next if(/^system (shutdown message from|going down )/i);
- next if(/^\{(master|backup)}/);
+ 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;
@@ -265,9 +288,10 @@ sub ShowChassisHardware {
/command is not valid/ && return;
/^\s+\^/ && return;
/syntax error/ && return;
+
ProcessHistory("","","","# $_");
}
- return;
+ return(0);
}
# This routine parses "show chassis routing-engine"
@@ -279,9 +303,9 @@ sub ShowChassisRoutingEngine {
ProcessHistory("","","","# $_");
while (<INPUT>) {
tr/\015//d;
- last if(/^$prompt/);
- next if(/^system (shutdown message from|going down )/i);
- next if(/^\{(master|backup)}/);
+ 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;
@@ -289,15 +313,17 @@ sub ShowChassisRoutingEngine {
/command is not valid/ && return;
/^\s+\^/ && return;
/syntax error/ && return;
+
/^Routing Engine status:/ && ProcessHistory("","","","# $_") && next;
/ Slot / && ProcessHistory("","","","# $_") && next;
/ Current state/ && ProcessHistory("","","","# $_") && next;
/ Election priority/ && ProcessHistory("","","","# $_") && next;
/ DRAM/ && ProcessHistory("","","","# $_") && next;
+ / Model/ && ProcessHistory("","","","# $_") && next;
/ Serial ID/ && ProcessHistory("","","","# $_") && next;
/^\s*$/ && ProcessHistory("","","","# $_") && next;
}
- return;
+ return(0);
}
# This routine parses "show chassis cfeb", "show chassis feb", "show
@@ -310,9 +336,9 @@ sub ShowChassisSCB {
ProcessHistory("","","","# $_");
while (<INPUT>) {
tr/\015//d;
- last if(/^$prompt/);
- next if(/^system (shutdown message from|going down )/i);
- next if(/^\{(master|backup)}/);
+ 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;
@@ -321,7 +347,9 @@ sub ShowChassisSCB {
/command is not valid/ && return;
/^\s+\^/ && return;
/syntax error/ && return;
+
/ Temperature/ && next;
+ / temperature/ && next;
/ utilization/ && next;
/ Start time/ && next;
/ Uptime/ && next;
@@ -330,26 +358,115 @@ sub ShowChassisSCB {
ProcessHistory("","","","# $_");
}
$ShowChassisSCB = 1;
- return;
+ return(0);
}
-# This routine parses "show system boot-messages"
+# This routine parses "show chassis alarms"
sub ShowChassisAlarms {
print STDERR " In ShowChassisAlarms: $_" if ($debug);
+ s/^[a-z]+@//;
+ 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;
+ /command is not valid/ && return;
+ /^\s+\^/ && return;
+ /syntax error/ && return;
+
+ ProcessHistory("","","","# $_");
+ }
+ return(0);
+}
+
+# This routine parses "show system autoinstallation status"
+sub ShowSystemAutoinstall {
+ print STDERR " In ShowSystemAutoinstall: $_" if ($debug);
+
+ s/^[a-z]+@//;
ProcessHistory("","","","# $_");
while (<INPUT>) {
tr/\015//d;
- last if(/^$prompt/);
- next if(/^system (shutdown message from|going down )/i);
- next if(/^\{(master|backup)}/);
+ last if (/^$prompt/);
+ next if (/^system (shutdown message from|going down )/i);
+ next if (/^\{(master|backup)}/);
/Unrecognized command/ && return;
+ /command is not valid/ && return;
/^\s+\^/ && return;
/syntax error/ && return;
+
ProcessHistory("","","","# $_");
}
- return;
+ return(0);
+}
+
+sub ShowSystemCoreDumps {
+ print STDERR " In ShowSystemCoreDumps: $_" if ($debug);
+
+ s/^[a-z]+@//;
+ ProcessHistory("","","","# $_");
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+
+ /Unrecognized command/ && return(1);
+ /^\s+\^/ && return(1);
+ /syntax error/ && return(1);
+ /^JUNOS / && <INPUT> && next;
+ /No such file or directory$/ && next;
+
+ ProcessHistory("","","","# $_");
+ }
+ return(0);
+}
+
+# This routine parses "show system license"
+sub ShowSystemLicense {
+ print STDERR " In ShowSystemLicense: $_" if ($debug);
+
+ s/^[a-z]+@//;
+ 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;
+ /command is not valid/ && return;
+ /^\s+\^/ && return;
+ /syntax error/ && return;
+
+ ProcessHistory("","","","# $_");
+ }
+ return(0);
+}
+
+# This routine parses "show system license keys"
+sub ShowSystemLicenseKeys {
+ print STDERR " In ShowSystemLicenseKeys: $_" if ($debug);
+
+ s/^[a-z]+@//;
+ 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;
+ /command is not valid/ && return;
+ /^\s+\^/ && return;
+ /syntax error/ && return;
+
+ ProcessHistory("","","","# $_");
+ }
+ return(0);
}
# This routine parses "show system boot-messages"
@@ -360,13 +477,15 @@ sub ShowSystemBootMessages {
ProcessHistory("","","","# $_");
while (<INPUT>) {
tr/\015//d;
- last if(/^$prompt/);
- next if(/^system (shutdown message from|going down )/i);
- next if(/^\{(master|backup)}/);
+ last if (/^$prompt/);
+ next if (/^system (shutdown message from|going down )/i);
+ next if (/^\{(master|backup)}/);
/Unrecognized command/ && return;
+ /command is not valid/ && return;
/^\s+\^/ && return;
/syntax error/ && return;
+
/^JUNOS / && <INPUT> && next;
/^Timecounter "TSC" / && next;
/^real memory / && next;
@@ -374,7 +493,7 @@ sub ShowSystemBootMessages {
/^\/dev\// && next;
ProcessHistory("","","","# $_");
}
- return;
+ return(0);
}
# This routine parses "show version"
@@ -385,17 +504,17 @@ sub ShowVersion {
ProcessHistory("","","","# $_");
while (<INPUT>) {
tr/\015//d;
- last if(/^$prompt/);
- next if(/^\s*$/);
- next if(/^system (shutdown message from|going down )/i);
- next if(/^\{(master|backup)}/);
+ 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;
+ return(0);
}
# This routine parses "show configuration"
@@ -409,20 +528,21 @@ sub ShowConfiguration {
while (<INPUT>) {
tr/\015//d;
next if (/^\s*$/);
- # end of config - hopefully. juniper does not have a reliable
+ # end of config - hopefully. juniper does not have a reliable
# end-of-config tag. appears to end with "\nPROMPT>", but not sure.
- if(/^$prompt/) {
+ if (/^$prompt/) {
$found_end++;
last;
}
- next if(/^system (shutdown message from|going down )/i);
- next if(/^\{(master|backup)}/);
+ 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$//;
+ s/ ## SECRET-DATA$//;
# filter snmp community, when in snmp { stanza }
/^snmp/ && $snmp++;
/^}/ && ($snmp = 0);
@@ -435,6 +555,10 @@ sub ShowConfiguration {
ProcessHistory("","","","#$1<removed>$'");
next;
}
+ if (/(\s*md5 \d+ key )[^ ;]+/ && $filter_pwds >= 1) {
+ ProcessHistory("","","","#$1<removed>$'");
+ next;
+ }
if (/(\s*hello-authentication-key )[^ ;]+/ && $filter_pwds >= 1) {
ProcessHistory("","","","#$1<removed>$'");
next;
@@ -464,7 +588,7 @@ sub ShowConfiguration {
return(-1);
}
- return;
+ return(0);
}
###
@@ -475,44 +599,45 @@ sub ShowConfiguration {
sub DoNothing {print STDOUT;}
# Main
-%commands=(
- "show chassis clocks" => "ShowChassisClocks",
- "show chassis environment" => "ShowChassisEnvironment",
- "show chassis firmware" => "ShowChassisFirmware",
- "show chassis fpc detail" => "ShowChassisFpcDetail",
- "show chassis hardware detail" => "ShowChassisHardware",
- "show chassis routing-engine" => "ShowChassisRoutingEngine",
- "show chassis scb" => "ShowChassisSCB",
- "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 detail" => "ShowVersion",
- "show configuration" => "ShowConfiguration"
-);
-@commands=(
- "show chassis clocks",
- "show chassis environment",
- "show chassis firmware",
- "show chassis fpc detail",
- "show chassis hardware detail",
- "show chassis routing-engine",
- "show chassis scb",
- "show chassis sfm detail",
- "show chassis ssb",
- "show chassis feb",
- "show chassis cfeb",
- "show chassis alarms",
- "show system boot-messages",
- "show version detail",
- "show configuration"
+@commandtable = (
+ {'show chassis clocks' => 'ShowChassisClocks'},
+ {'show chassis environment' => 'ShowChassisEnvironment'},
+ {'show chassis firmware' => 'ShowChassisFirmware'},
+ {'show chassis fpc detail' => 'ShowChassisFpcDetail'},
+ {'show chassis hardware detail' => 'ShowChassisHardware'},
+ {'show chassis routing-engine' => 'ShowChassisRoutingEngine'},
+ {'show chassis scb' => 'ShowChassisSCB'},
+ {'show chassis sfm detail' => 'ShowChassisSCB'},
+ {'show chassis ssb' => 'ShowChassisSCB'},
+ {'show chassis feb detail' => 'ShowChassisSCB'},
+ {'show chassis feb' => 'ShowChassisSCB'},
+ {'show chassis cfeb' => 'ShowChassisSCB'},
+ {'show chassis alarms' => 'ShowChassisAlarms'},
+# {'show system autoinstallation status' => 'ShowSystemAutoinstall'},
+ {'show system license' => 'ShowSystemLicense'},
+# {'show system license keys' => 'ShowSystemLicenseKeys'},
+ {'show system boot-messages' => 'ShowSystemBootMessages'},
+ {'show system core-dumps' => 'ShowSystemCoreDumps'},
+ {'show version detail' => 'ShowVersion'},
+ {'show configuration' => 'ShowConfiguration'}
);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
$jnx_commands=join(";",@commands);
$cmds_regexp=join("|",@commands);
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered
@@ -523,21 +648,21 @@ if ($file) {
print STDOUT "opening file $host\n" if ($log);
open(INPUT,"< $host") || die "open failed for $host: $!\n";
} else {
- print(STDERR "executing echo jlogin -c\"$jnx_commands\" $host\n") if ($debug);
- print(STDOUT "executing echo jlogin -c\"$jnx_commands\" $host\n") if ($debug);
+ print(STDERR "executing echo jlogin -t $timeo -c\"$jnx_commands\" $host\n") if ($debug);
+ print(STDOUT "executing echo jlogin -t $timeo -c\"$jnx_commands\" $host\n") if ($debug);
if (defined($ENV{NOPIPE})) {
- system "jlogin -c \"$jnx_commands\" $host </dev/null > $host.raw" || die "jlogin failed for $host: $!\n";
+ system "jlogin -t $timeo -c \"$jnx_commands\" $host </dev/null > $host.raw" || die "jlogin failed for $host: $!\n";
open(INPUT, "< $host.raw") || die "jlogin failed for $host: $!\n";
} else {
- open(INPUT,"jlogin -c \"$jnx_commands\" $host </dev/null |") || die "jlogin failed for $host: $!\n";
+ open(INPUT,"jlogin -t $timeo -c \"$jnx_commands\" $host </dev/null |") || die "jlogin failed for $host: $!\n";
}
}
# determine password filtering mode
if ($ENV{"FILTER_PWDS"} =~ /no/i) {
- $filter_pwds = 0;
+ $filter_pwds = 0;
} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
$filter_pwds = 2;
} else {
@@ -545,7 +670,7 @@ if ($ENV{"FILTER_PWDS"} =~ /no/i) {
}
ProcessHistory("","","","# RANCID-CONTENT-TYPE: juniper\n#\n");
-TOP: while(<INPUT>) {
+TOP: while (<INPUT>) {
tr/\015//d;
if (/^Error:/) {
print STDOUT ("$host jlogin error: $_");
diff --git a/bin/lg.cgi.in b/bin/lg.cgi.in
index ad08c68..4ad6fdd 100644
--- a/bin/lg.cgi.in
+++ b/bin/lg.cgi.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: lg.cgi.in,v 1.47 2004/01/11 03:49:13 heas Exp $
+## $Id: lg.cgi.in,v 1.54 2006/10/05 04:27:43 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -27,8 +28,8 @@
# vars: query, router, args
BEGIN {
-$me = $0;
-$me =~ s/.*\/(\S+)$/$1/;
+ $me = $0;
+ $me =~ s/.*\/(\S+)$/$1/;
}
use CGI qw/:standard escapeHTML/;
@@ -38,6 +39,7 @@ use LockFile::Simple qw(lock trylock unlock);
my($BASEDIR) = "@prefix@";
my($SYSCONFDIR) = "@sysconfdir@";
+my($LOCALSTATEDIR) = "@localstatedir@";
my($pingcmd) = "@LG_PING_CMD@";
my($query, $max_time_diff, $cache_dir, $cloginrc, @results);
@@ -134,23 +136,24 @@ sub readrouters
# if the router.db file does not exist, try to compile the list from
# the rancid group router.db files.
local(*DIR);
- if (! opendir(DIR, $BASEDIR)) {
- dolog(LOG_ERR, "ERROR: couldn\'t read $BASEDIR: $!\n");
+ if (! opendir(DIR, $LOCALSTATEDIR)) {
+ dolog(LOG_ERR, "ERROR: couldn\'t read $LOCALSTATEDIR: $!\n");
} else {
while ($dir = readdir(DIR)) {
- next if ($dir =~ /^(\.|\.\.|CVS|bin|etc|logs|util)$/);
- push(@dirs, $dir) if (-d "$BASEDIR/$dir");
+ next if ($dir =~ /^(\.|\.\.|\.ssh|CVS|bin|etc|logs|util)$/);
+ push(@dirs, $dir) if (-d "$LOCALSTATEDIR/$dir");
}
closedir(DIR);
foreach $dir (@dirs) {
- if (! opendir(DIR, "$BASEDIR/$dir")) {
- dolog(LOG_ERR, "ERROR: couldn\'t read $BASEDIR/$dir: $!\n");
+ if (! opendir(DIR, "$LOCALSTATEDIR/$dir")) {
+ dolog(LOG_ERR,
+ "ERROR: couldn\'t read $LOCALSTATEDIR/$dir: $!\n");
next;
}
closedir(DIR);
- next if (! -f "$BASEDIR/$dir/router.db");
- if (open(RTR, "< $BASEDIR/$dir/router.db")) {
+ next if (! -f "$LOCALSTATEDIR/$dir/router.db");
+ if (open(RTR, "< $LOCALSTATEDIR/$dir/router.db")) {
while (<RTR>) {
next if (/^\s*(#|$)/);
# fqdn:mfg:state
@@ -162,7 +165,7 @@ sub readrouters
close(RTR);
} else {
dolog(LOG_ERR, "ERROR: couldn\'t open the router.db " .
- "file: $BASEDIR/$dir/router.db: $!\n");
+ "file: $LOCALSTATEDIR/$dir/router.db: $!\n");
}
}
}
@@ -430,7 +433,7 @@ $max_lock_hold = 300;
if (defined($LG_CLOGINRC)) {
$cloginrc = $LG_CLOGINRC;
} else {
- $cloginrc = "$ENV(HOME)/.cloginrc";
+ $cloginrc = $ENV{HOME} . "/.cloginrc";
}
$query = new CGI;
@@ -451,7 +454,7 @@ if (!defined($type) || !defined($router) || $router eq "") {
"a clue.\n");
}
-if ($arg !~ /^[-A-Za-z0-9|_\/ \.^\$]*$/) {
+if ($arg !~ /^[-A-Za-z0-9|_\/: \.^\$]*$/) {
&Error("Funny characters in argument; ignoring.\n");
}
if (length($arg) >= 50) {
@@ -678,7 +681,7 @@ if ($type eq "prefix" || $type eq "mbgp" || $type eq "route" ) {
if ($mfg =~ /cisco/i) {
$arg = " | include " . join(' ', @arg);
} elsif ($mfg =~ /juniper/i) {
- $arg = " | match \"" . join(' ', @arg) . "\"";
+ $arg = " | match \\\"" . join(' ', @arg) . "\\\"";
} else {
undef($arg);
}
@@ -736,7 +739,7 @@ if ($type eq "prefix" || $type eq "mbgp" || $type eq "route" ) {
} else {
$arg =~ s/[\$^]/ /g;
}
- $arg = "\"$arg\"";
+ $arg = "\\\"$arg\\\"";
}
# escape any ()s
$arg =~ s/([\(\)])/\\$1/g;
diff --git a/bin/lgform.cgi.in b/bin/lgform.cgi.in
index 461ae68..774d104 100644
--- a/bin/lgform.cgi.in
+++ b/bin/lgform.cgi.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: lgform.cgi.in,v 1.25 2004/01/11 03:49:13 heas Exp $
+## $Id: lgform.cgi.in,v 1.31 2006/10/05 04:27:43 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -26,11 +27,19 @@
# lgform.cgi - Looking glass front-end
# produces html form for calling lg.cgi
+BEGIN {
+ $me = $0;
+ $me =~ s/.*\/(\S+)$/$1/;
+}
+
use CGI qw/:standard/;
+use POSIX qw(strftime);
+use Sys::Syslog;
my(@rtrlist, %rtrlabels);
my($BASEDIR) = "@prefix@";
my($SYSCONFDIR) = "@sysconfdir@";
+my($LOCALSTATEDIR) = "@localstatedir@";
# 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.
@@ -118,23 +127,24 @@ sub readrouters
# if the router.db file does not exist, try to compile the list from
# the rancid group router.db files.
local(*DIR);
- if (! opendir(DIR, $BASEDIR)) {
- dolog(LOG_ERR, "ERROR: couldn\'t read $BASEDIR: $!\n");
+ if (! opendir(DIR, $LOCALSTATEDIR)) {
+ dolog(LOG_ERR, "ERROR: couldn\'t read $LOCALSTATEDIR: $!\n");
} else {
while ($dir = readdir(DIR)) {
- next if ($dir =~ /^(\.|\.\.|CVS|bin|etc|logs|util)$/);
- push(@dirs, $dir) if (-d "$BASEDIR/$dir");
+ next if ($dir =~ /^(\.|\.\.|\.ssh|CVS|bin|etc|logs|util)$/);
+ push(@dirs, $dir) if (-d "$LOCALSTATEDIR/$dir");
}
closedir(DIR);
foreach $dir (@dirs) {
- if (! opendir(DIR, "$BASEDIR/$dir")) {
- dolog(LOG_ERR, "ERROR: couldn\'t read $BASEDIR/$dir: $!\n");
+ if (! opendir(DIR, "$LOCALSTATEDIR/$dir")) {
+ dolog(LOG_ERR,
+ "ERROR: couldn\'t read $LOCALSTATEDIR/$dir: $!\n");
next;
}
closedir(DIR);
- next if (! -f "$BASEDIR/$dir/router.db");
- if (open(RTR, "< $BASEDIR/$dir/router.db")) {
+ next if (! -f "$LOCALSTATEDIR/$dir/router.db");
+ if (open(RTR, "< $LOCALSTATEDIR/$dir/router.db")) {
while (<RTR>) {
next if (/^\s*(#|$)/);
# fqdn:mfg:state
@@ -146,7 +156,7 @@ sub readrouters
close(RTR);
} else {
dolog(LOG_ERR, "ERROR: couldn\'t open the router.db " .
- "file: $BASEDIR/$dir/router.db: $!\n");
+ "file: $LOCALSTATEDIR/$dir/router.db: $!\n");
}
}
}
diff --git a/bin/mrancid.in b/bin/mrancid.in
index 8d52c27..f77779e 100644
--- a/bin/mrancid.in
+++ b/bin/mrancid.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: mrancid.in,v 1.11 2004/01/11 03:49:13 heas Exp $
+## $Id: mrancid.in,v 1.19 2006/10/05 04:27:43 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -24,25 +25,30 @@
#
# RANCID - Really Awesome New Cisco confIg Differ
#
-# usage: rancid [-d] [-l] [-f filename | $host]
+# usage: rancid [-dV] [-l] [-f filename | hostname]
#
use Getopt::Std;
-getopts('dfl');
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
-$timeo = 90; # clogin timeout in seconds
+$timeo = 90; # clogin timeout in seconds
-my(%filter_pwds); # password filtering mode
+my(@commandtable, %commands, @commands);# command lists
+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) {
+ 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;
}
@@ -64,10 +70,10 @@ sub ProcessHistory {
sub numerically { $a <=> $b; }
-# This is a sort routing that will sort numerically on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
@@ -77,10 +83,10 @@ sub keynsort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
@@ -90,10 +96,10 @@ sub keysort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
@@ -103,9 +109,9 @@ sub valsort{
@sorted_lines;
}
-# This is a numerical sort routing (ascending).
+# This is a numerical sort routine (ascending).
sub numsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a <=> $b} keys %lines) {
@@ -119,7 +125,7 @@ sub numsort {
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
@@ -132,7 +138,7 @@ sub ipsort {
# 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]));
+ $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
@@ -292,7 +298,6 @@ sub WriteTerm {
ProcessHistory("IPHOST","numsort","$1","$_") && next;
# end of config
- #if (/^end(\n\[OK])?$/) {
if (/^(: )?end$/) {
$found_end = 1;
return(1);
@@ -305,19 +310,27 @@ sub WriteTerm {
sub DoNothing {print STDOUT;}
# Main
-%commands=(
- 'show version' => "ShowVersion",
- 'show config' => "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 config"
+@commandtable = (
+ {'show version' => 'ShowVersion'},
+ {'show config' => 'WriteTerm'}
);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
+
$cisco_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
@@ -340,7 +353,7 @@ if ($file) {
# determine password filtering mode
if ($ENV{"FILTER_PWDS"} =~ /no/i) {
- $filter_pwds = 0;
+ $filter_pwds = 0;
} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
$filter_pwds = 2;
} else {
diff --git a/bin/nlogin.in b/bin/nlogin.in
index 685c759..53e8812 100644
--- a/bin/nlogin.in
+++ b/bin/nlogin.in
@@ -1,8 +1,9 @@
#! @EXPECT_PATH@ --
##
-## $Id: nlogin.in,v 1.14 2004/01/11 05:39:15 heas Exp $
+## $Id: nlogin.in,v 1.33 2006/12/08 21:28:26 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -20,16 +21,22 @@
##
#
# The login expect scripts were based on Erik Sherk's gwtn, by permission.
+# Netscreen hacks implemented by Stephen Gill <gillsr@yahoo.com>.
#
# nlogin - netscreen login
#
# Most options are intuitive for logging into a netscreen firewall.
#
+# Misc notes
+# netscreen does not have the concept of "enable", once logged in, a
+# users permissions can not change.
# 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"
+set usage "Usage: $argv0 \[-c command\] \[-Evar=x\] \[-f cloginrc-file\] \
+\[-p user-password\] \
+\[-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
@@ -39,18 +46,13 @@ 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) ] } {
+if {[ info exists env(CISCO_USER) ]} {
set default_user $env(CISCO_USER)
} elseif {[ info exists env(USER) ]} {
set default_user $env(USER)
@@ -63,9 +65,12 @@ if {[ info exists env(CISCO_USER) ] } {
if [ catch {exec id} reason ] {
send_error "\nError: could not exec id: $reason\n"
exit 1
- }
+ }
regexp {\(([^)]*)} "$reason" junk default_user
-}
+}
+if {[ info exists env(CLOGINRC) ]} {
+ set password_file $env(CLOGINRC)
+}
# Sometimes firewall take awhile to answer (the default is 10 sec)
set timeout 45
@@ -154,7 +159,6 @@ for {set i 0} {$i < $argc} {incr i} {
# Does tacacs automatically enable us?
} -autoenable {
# ignore autoenable
- #set avautoenable 1
} -* {
send_user "\nError: Unknown argument! $arg\n"
send_user $usage
@@ -208,9 +212,9 @@ proc include {args} {
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
@@ -228,7 +232,7 @@ proc find {var firewall} {
# 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
+# 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] } {
@@ -247,6 +251,7 @@ proc source_password_file { password_file } {
}
# Log into the firewall.
+# returns: 0 on success, 1 on failure
proc login { firewall user userpswd passwd enapasswd prompt cmethod
cyphertype } {
global spawn_id in_proc do_command do_script sshcmd
@@ -256,6 +261,7 @@ cyphertype } {
# Telnet to the firewall & try to login.
set progs [llength $cmethod]
foreach prog [lrange $cmethod 0 end] {
+ incr progs -1
if [string match "telnet*" $prog] {
regexp {telnet(:([^[:space:]]+))*} $prog command suffix port
if {"$port" == ""} {
@@ -265,23 +271,23 @@ cyphertype } {
}
if { $retval } {
send_user "\nError: telnet failed: $reason\n"
- exit 1
+ return 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
- }
+ return 1
+ }
} elseif ![string compare $prog "rsh"] {
- if [ catch {spawn rsh -l $user $firewall} reason ] {
- send_user "\nError: rsh failed: $reason\n"
- exit 1
+ send_error "\nError: unsupported method: rsh\n"
+ if { $progs == 0 } {
+ return 1
}
+ continue;
} else {
- puts "\nError: unknown connection method: $prog"
+ send_user "\nError: unknown connection method: $prog\n"
return 1
}
- incr progs -1
sleep 0.3
@@ -314,10 +320,10 @@ cyphertype } {
# then it will just send the passwd.
# if telnet fails with connection refused, try ssh
expect {
- "Connection refused" {
+ "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" {
+ } "Unknown host\r\n" {
expect eof
send_user "\nError: Unknown host\n"; wait; return 1
} "Host is unreachable" {
@@ -343,17 +349,17 @@ cyphertype } {
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"
+ 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:)" {
+ -re "(login:)" {
sleep 1;
send "$user\r"
set uprompt_seen 1
exp_continue
}
- "@\[^\r\n]+\[Pp]assword:" {
+ -re "@\[^\r\n]+\[Pp]assword:" {
# ssh pwd prompt
sleep 1
send "$userpswd\r"
@@ -368,7 +374,7 @@ cyphertype } {
}
exp_continue
}
- "$prompt" { break; }
+ -- "$prompt" { break; }
}
}
set in_proc 0
@@ -381,7 +387,7 @@ proc run_commands { prompt command } {
set in_proc 1
send "set console page 0\r"
- expect $prompt {}
+ expect -re $prompt {}
# Is this a multi-command?
if [ string match "*\;*" "$command" ] {
@@ -391,26 +397,38 @@ proc run_commands { prompt command } {
for {set i 0} {$i < $num_commands} { incr i} {
send "[subst [lindex $commands $i]]\r"
expect {
- -re "$prompt" {}
+ -re "\[\n\r]+" { exp_continue }
+ -re "$prompt" {}
+ -gl "--- more ---" { send " "
+ exp_continue
+ }
}
}
} else {
send "[subst $command]\r"
expect {
- -re "$prompt" {}
+ -re "\[\n\r]+" { exp_continue }
+ -re "$prompt" {}
+ -gl "--- more ---" { send " "
+ exp_continue
+ }
}
}
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 }
+ -re "$prompt" {
+ send "exit\r"
+ exp_continue
+ }
+ -re "\[\n\r]+" { exp_continue }
+ -gl "Configuration modified, save?" {
+ send "n\r"
+ exp_continue
+ }
+ timeout { catch {close}; wait
+ return 0
+ }
+ eof { return 0 }
}
set in_proc 0
}
@@ -424,7 +442,7 @@ foreach firewall [lrange $argv $i end] {
set firewall [string tolower $firewall]
send_user "$firewall\n"
- set prompt ">"
+ set prompt {-> }
# Figure out passwords
if { $do_passwd || $do_enapasswd } {
@@ -432,19 +450,22 @@ foreach firewall [lrange $argv $i end] {
if { [llength $pswd] == 0 } {
send_user "\nError: no password for $firewall in $password_file.\n"
continue
- }
- set passwd [join [lindex $pswd 0]""]
+ }
+ set passwd [join [lindex $pswd 0] ""]
set enapasswd [join [lindex $pswd 1] ""]
+ } else {
+ set passwd $userpasswd
+ set enapasswd $enapasswd
}
# Figure out username
- if {[info exists 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]} {
@@ -452,17 +473,9 @@ foreach firewall [lrange $argv $i end] {
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 }
- }
+ if { "$userpswd" == "" } { set userpswd $passwd }
+ }
+
# Figure out cypher type
if {[info exists cypher]} {
@@ -477,28 +490,23 @@ foreach firewall [lrange $argv $i end] {
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} }
+ # Figure out the SSH executable name
+ set sshcmd [find sshcmd $firewall]
+ 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;
+ -re "^(.+$prompt)" { set junk $expect_out(0,string);
+ # if it has HA (high avail), the prompt will
+ # be "something-(.)->"
+ regsub -all "\[\]\)\(\[]" $junk {\\&} prompt;
}
}
@@ -508,11 +516,11 @@ foreach firewall [lrange $argv $i end] {
}
} elseif { $do_script } {
send "set console page 0\r"
- expect $prompt {}
+ expect -re $prompt {}
source $sfile
close
} else {
- label $firewall
+ label $firewall
log_user 1
interact
}
diff --git a/bin/nrancid.in b/bin/nrancid.in
index 9b965a2..940bdc8 100644
--- a/bin/nrancid.in
+++ b/bin/nrancid.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: nrancid.in,v 1.13 2004/01/11 03:49:13 heas Exp $
+## $Id: nrancid.in,v 1.28 2006/11/10 21:40:48 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -21,29 +22,34 @@
#
# 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]
+# usage: rancid [-dV] [-l] [-f filename | hostname]
#
use Getopt::Std;
-getopts('dfl');
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$found_end = 0;
-$timeo = 90; # nlogin timeout in seconds
+$timeo = 90; # nlogin timeout in seconds
-my(%filter_pwds); # password filtering mode
+my(@commandtable, %commands, @commands);# command lists
+my(%filter_pwds); # password filtering mode
-# This routine is used to print out the firewall configuration
+# 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) {
+ 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;
}
@@ -65,10 +71,10 @@ sub ProcessHistory {
sub numerically { $a <=> $b; }
-# This is a sort routing that will sort numerically on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
@@ -78,10 +84,10 @@ sub keynsort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
@@ -91,22 +97,22 @@ sub keysort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
- $sorted_lines[$i] = $key;
- $i++;
+ $sorted_lines[$i] = $key;
+ $i++;
}
@sorted_lines;
}
-# This is a numerical sort routing (ascending).
+# This is a numerical sort routine (ascending).
sub numsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a <=> $b} keys %lines) {
@@ -120,7 +126,7 @@ sub numsort {
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
@@ -133,7 +139,7 @@ sub ipsort {
# 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]));
+ $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
@@ -147,24 +153,26 @@ sub GetSystem {
tr/\015//d;
next if /^\s*$/;
last if(/$prompt/);
+ # throw away the pager lines
+ next if /^--- more ---/;
- /^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;
+ /^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");
+ ProcessHistory("SYSTEM","","","#\n");
return(0);
}
@@ -173,7 +181,7 @@ sub GetFile {
while (<INPUT>) {
last if(/$prompt/);
}
- ProcessHistory("FILE","","","!\n");
+ ProcessHistory("FILE","","","#\n");
return(0);
}
@@ -182,21 +190,48 @@ sub GetConf {
while (<INPUT>) {
tr/\015//d;
next if /^\s*$/;
+ next if /^Total Config.+$/i;
last if(/$prompt/);
+ # throw away the pager lines
+ next if /^--- more ---/;
if (/^set admin name "(\S+)"$/ && $filter_pwds >= 1) {
- ProcessHistory("ADMIN","","","!set admin name <removed>\n");
- next;
- }
+ ProcessHistory("ADMIN","","","#set admin name <removed>\n");
+ next;
+ }
if (/^set admin password (\S+)$/ && $filter_pwds >= 1) {
- ProcessHistory("ADMIN","","","!set admin password <removed>\n");
- next;
- }
+ 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("ADMIN","","",
+ "#set admin user $1 password <removed> privilege $3\n");
+ next;
+ }
+ if (/^set auth-server (\S+) radius secret / && $filter_pwds >= 1 ) {
+ ProcessHistory("ADMIN","","",
+ "#set auth-server $1 radius secret <removed>\n");
+ next;
+ }
+ if (/^set ike gateway (.*) username (\S+)(.*) password (\S+)(.*)$/ &&
+ $filter_pwds >= 1) {
+ ProcessHistory("ADMIN","","",
+ "#set ike gateway $1 username <removed>$3 password <removed>$5\n");
+ next;
+ }
+ if (/^set ike gateway (.*) preshare "(\S+)"(.*)$/ &&
+ $filter_pwds >= 1) {
+ ProcessHistory("ADMIN","","",
+ "#set ike gateway $1 preshare <removed>$3\n");
+ next;
+ }
+ if (/^set auth-server (.*) secret "(\S+)"(.*)$/ &&
+ $filter_pwds >= 1) {
+ ProcessHistory("ADMIN","","",
+ "#set auth-server $1 secret <removed>$3\n");
+ next;
+ }
ProcessHistory("","","","$_");
}
$found_end=1;
@@ -207,19 +242,27 @@ sub GetConf {
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"
+@commandtable = (
+ {'get system' => 'GetSystem'},
+ {'get conf' => 'GetConf'}
);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
+
$cisco_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
@@ -242,14 +285,14 @@ if ($file) {
# determine password filtering mode
if ($ENV{"FILTER_PWDS"} =~ /no/i) {
- $filter_pwds = 0;
+ $filter_pwds = 0;
} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
- $filter_pwds = 2;
+ $filter_pwds = 2;
} else {
- $filter_pwds = 1;
+ $filter_pwds = 1;
}
-ProcessHistory("","","","!RANCID-CONTENT-TYPE: netscreen\n!\n");
+ProcessHistory("","","","#RANCID-CONTENT-TYPE: netscreen\n#\n");
TOP: while(<INPUT>) {
tr/\015//d;
if (/^Error:/) {
@@ -260,7 +303,8 @@ TOP: while(<INPUT>) {
while (/>\s*($cmds_regexp)\s*$/) {
$cmd = $1;
if (!defined($prompt)) {
- $prompt = "\-\>\s*";
+ $prompt = ($_ =~ /^([^>]+->)/)[0];
+ $prompt =~ s/([][}{)(\\])/\\$1/g;
print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
}
print STDERR ("HIT COMMAND:$_") if ($debug);
@@ -293,7 +337,6 @@ if (scalar(%commands) || !$found_end) {
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");
diff --git a/bin/nslogin.in b/bin/nslogin.in
index 385f530..6cf4188 100644
--- a/bin/nslogin.in
+++ b/bin/nslogin.in
@@ -1,8 +1,9 @@
#! @EXPECT_PATH@ --
##
-## $Id: nslogin.in,v 1.10 2004/01/11 05:39:15 heas Exp $
+## $Id: nslogin.in,v 1.22 2006/12/08 21:28:26 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -49,7 +50,7 @@ set password_file $env(HOME)/.cloginrc
set do_command 1
set do_script 0
# The default is to automatically enable
-set enable 0
+set avenable 0
# The default is that you login non-enabled (tacacs can have you login already
# enabled)
set avautoenable 0
@@ -61,7 +62,7 @@ set do_enapasswd 1
set platform ""
# Find the user in the ENV, or use the unix userid.
-if {[ info exists env(CISCO_USER) ] } {
+if {[ info exists env(CISCO_USER) ]} {
set default_user $env(CISCO_USER)
} elseif {[ info exists env(USER) ]} {
set default_user $env(USER)
@@ -77,6 +78,9 @@ if {[ info exists env(CISCO_USER) ] } {
}
regexp {\(([^)]*)} "$reason" junk default_user
}
+if {[ info exists env(CLOGINRC) ]} {
+ set password_file $env(CLOGINRC)
+}
# Sometimes routers take awhile to answer (the default is 10 sec)
set timeout 45
@@ -191,11 +195,11 @@ for {set i 0} {$i < $argc} {incr i} {
set do_command 1
# Do we enable?
} -noenable {
- set enable 0
+ set avenable 0
# Does tacacs automatically enable us?
} -autoenable {
set avautoenable 1
- set enable 0
+ set avenable 0
} -* {
send_user "\nError: Unknown argument! $arg\n"
send_user $usage
@@ -288,6 +292,7 @@ proc source_password_file { password_file } {
}
# Log into the router.
+# returns: 0 on success, 1 on failure
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
@@ -297,16 +302,28 @@ proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
# try each of the connection methods in $cmethod until one is successful
set progs [llength $cmethod]
foreach prog [lrange $cmethod 0 end] {
+ incr progs -1
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
+ return 1
+ }
+ } elseif ![string compare $prog "telnet"] {
+ send_error "\nError: unsupported method: telnet\n"
+ if { $progs == 0 } {
+ return 1
+ }
+ continue
+ } elseif ![string compare $prog "rsh"] {
+ send_error "\nError: unsupported method: rsh\n"
+ if { $progs == 0 } {
+ return 1
}
+ continue
} else {
- puts "\nError: unknown connection method: $prog"
+ send_user "\nError: unknown connection method: $prog\n"
return 1
}
- incr progs -1
sleep 0.3
# This helps cleanup each expect clause.
@@ -487,7 +504,9 @@ proc run_commands { prompt command } {
exp_continue
}
"\n" { exp_continue }
- timeout { return 0 }
+ timeout { catch {close}; wait
+ return 0
+ }
eof { return 0 }
}
set in_proc 0
@@ -510,6 +529,8 @@ foreach router [lrange $argv $i end] {
# look for noenable option in .cloginrc
if { [find noenable $router] != "" } {
set enable 0
+ } else {
+ set enable $avenable
}
# Figure out passwords
@@ -525,6 +546,9 @@ foreach router [lrange $argv $i end] {
}
set passwd [join [lindex $pswd 0] ""]
set enapasswd [join [lindex $pswd 1] ""]
+ } else {
+ set passwd $userpasswd
+ set enapasswd $enapasswd
}
# Figure out username
@@ -587,9 +611,9 @@ 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} }
+ # 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]} {
diff --git a/bin/nsrancid.in b/bin/nsrancid.in
index 40a286f..a74cce6 100644
--- a/bin/nsrancid.in
+++ b/bin/nsrancid.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: nsrancid.in,v 1.7 2004/01/11 03:49:13 heas Exp $
+## $Id: nsrancid.in,v 1.14 2006/10/05 04:27:43 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -24,30 +25,34 @@
#
# RANCID - Really Awesome New Cisco confIg Differ
#
-# usage: rancid [-d] [-l] [-f filename | $host]
+# usage: rancid [-dV] [-l] [-f filename | hostname]
#
use Getopt::Std;
-getopts('dfl');
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
-$timeo = 90; # nslogin timeout in seconds
+$timeo = 90; # nslogin timeout in seconds
+my(@commandtable, %commands, @commands);# command lists
+my(%filter_pwds); # password filtering mode
@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) {
+ 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;
}
@@ -69,10 +74,10 @@ sub ProcessHistory {
sub numerically { $a <=> $b; }
-# This is a sort routing that will sort numerically on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
@@ -82,10 +87,10 @@ sub keynsort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
@@ -95,10 +100,10 @@ sub keysort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
@@ -108,9 +113,9 @@ sub valsort{
@sorted_lines;
}
-# This is a numerical sort routing (ascending).
+# This is a numerical sort routine (ascending).
sub numsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a <=> $b} keys %lines) {
@@ -124,7 +129,7 @@ sub numsort {
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
@@ -137,7 +142,7 @@ sub ipsort {
# 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]));
+ $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
@@ -165,9 +170,9 @@ sub ShowConfig {
}
if (/exit$/) {
- $found_end = 1;
- $clean_run = 1;
- return(1);
+ $found_end = 1;
+ $clean_run = 1;
+ return(1);
}
return(0);
}
@@ -205,20 +210,27 @@ sub RunCommand {
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"
+@commandtable = (
+ {'cat /etc/ns.conf' => 'ShowConfig'},
+ {'get log setting' => 'GetLogSet'}
);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
+
$cisco_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
@@ -261,7 +273,7 @@ TOP: while(<INPUT>) {
# if ( (/netscaler#/) || $found_end ) {
#print STDOUT "\n\nhere1\n";
-# $clean_run=1;
+# $clean_run=1;
# last;
# }
diff --git a/bin/par.in b/bin/par.in
index b50bd05..408b36b 100644
--- a/bin/par.in
+++ b/bin/par.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: par.in,v 1.10 2004/01/11 03:49:13 heas Exp $
+## $Id: par.in,v 1.14 2006/11/28 21:21:28 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -44,7 +45,11 @@
# line is assumed to be a command to be run.
#
use Getopt::Std;
-getopts('p:n:l:c:fixedq');
+getopts('p:n:l:c:fixedqV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
$procs=$opt_n; $procs=3 if(!$procs);
$command=$opt_c; #$command="{}" if(!$command);
$parlog=$opt_l; $parlog="par.log.".time() if(!$parlog);
@@ -59,7 +64,7 @@ if ($opt_q && ($opt_x || $opt_l)) {
$signalled=0;
-sub handler {
+sub handler {
$signalled++;
print STDERR "Received signal - ending run ($signalled).\n";
if($signalled>1) {
@@ -145,4 +150,4 @@ $procs=$i if ($i<$procs);
while($procs) {
$procs-- if(finish);
}
-print STDERR "Complete\n" if ($debug);
+print STDERR "Complete\n" if ($debug);
diff --git a/bin/prancid.in b/bin/prancid.in
index 7ded178..4777675 100755
--- a/bin/prancid.in
+++ b/bin/prancid.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: prancid.in,v 1.29 2004/01/11 03:49:13 heas Exp $
+## $Id: prancid.in,v 1.35 2006/10/05 04:27:43 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -23,26 +24,31 @@
#
# RANCID - Really Awesome New Cisco confIg Differ
#
-# usage: rancid [-d] [-l] [-f filename | $host]
+# usage: rancid [-dV] [-l] [-f filename | hostname]
#
use Getopt::Std;
-getopts('dfl');
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
-$timeo = 90; # clogin timeout in seconds
+$timeo = 90; # clogin timeout in seconds
-my($platform); # platform/cpu type
-my(%filter_pwds); # password filtering mode
+my(@commandtable, %commands, @commands);# command lists
+my(%filter_pwds); # password filtering mode
+my($platform); # platform/cpu type
# 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) {
+ 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;
}
@@ -64,10 +70,10 @@ sub ProcessHistory {
sub numerically { $a <=> $b; }
-# This is a sort routing that will sort numerically on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
@@ -77,10 +83,10 @@ sub keynsort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
@@ -90,10 +96,10 @@ sub keysort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
@@ -103,9 +109,9 @@ sub valsort{
@sorted_lines;
}
-# This is a numerical sort routing (ascending).
+# This is a numerical sort routine (ascending).
sub numsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a <=> $b} keys %lines) {
@@ -119,7 +125,7 @@ sub numsort {
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
@@ -132,7 +138,7 @@ sub ipsort {
# 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]));
+ $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
@@ -460,25 +466,30 @@ sub WriteTerm {
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"
+@commandtable = (
+ {'show version all' => 'ShowVersion'},
+ {'show package' => 'ShowPackage'},
+ {'show hardware' => 'ShowHardware'},
+ {'show inventory' => 'ShowInventory'},
+ {'write term' => 'WriteTerm'}
);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
+
$cisco_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
diff --git a/bin/rancid-cvs.in b/bin/rancid-cvs.in
index 22d5fd2..24d555a 100644
--- a/bin/rancid-cvs.in
+++ b/bin/rancid-cvs.in
@@ -1,8 +1,9 @@
#! /bin/sh
##
-## $Id: rancid-cvs.in,v 1.16 2004/01/11 03:49:13 heas Exp $
+## $Id: rancid-cvs.in,v 1.19 2006/10/05 04:27:43 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -20,7 +21,7 @@
##
#
# Create all of the misc files & dirs needed for each group and import them
-# into CVS.
+# into CVS or Subversion.
#
# rancid-cvs
#
@@ -28,6 +29,32 @@
# Read in the environment
ENVFILE="@sysconfdir@/rancid.conf"
+# print a usage message to stderr
+pr_usage() {
+ echo "usage: $0 [-V] [group [group ...]]" >&2;
+}
+
+# command-line options
+# -V print version string
+if [ $# -ge 1 ] ; then
+ while [ 1 ] ; do
+ case $1 in
+ -V)
+ echo "@PACKAGE@ @VERSION@"
+ exit 0
+ ;;
+ -*)
+ echo "unknown option: $1" >&2
+ pr_usage
+ exit 1
+ ;;
+ *)
+ break;
+ ;;
+ esac
+ done
+fi
+
. $ENVFILE
# Base dir
@@ -38,9 +65,20 @@ fi
cd $BASEDIR
+# RCS system
+RCSSYS=${RCSSYS:=cvs};
+if [ $RCSSYS != "cvs" -a $RCSSYS != "svn" ] ; then
+ echo "$RCSSYS is not a valid value for RCSSYS."
+ exit 1
+fi
+
# Top level CVS stuff
if [ ! -d $CVSROOT ]; then
- cvs init
+ if [ $RCSSYS = cvs ]; then
+ cvs -d $CVSROOT init
+ else
+ svnadmin create $CVSROOT
+ fi
fi
# Log dir
@@ -65,15 +103,21 @@ do
if [ ! -d $DIR ]; then
mkdir -p $DIR
cd $DIR
- cvs import -m "$GROUP" $GROUP new rancid
- cd $BASEDIR
- cvs co $GROUP
+ if [ $RCSSYS = cvs ]; then
+ cvs import -m "$GROUP" $GROUP new rancid
+ cd $BASEDIR
+ cvs checkout $GROUP
+ else
+ svn import -m "$GROUP" . file://$CVSROOT/$GROUP
+ cd $BASEDIR
+ svn checkout file://$CVSROOT/$GROUP $GROUP
+ fi
fi
cd $DIR
if [ ! -d configs ]; then
mkdir configs
- cvs add configs
- cvs commit -m 'new' configs
+ $RCSSYS add configs
+ $RCSSYS commit -m 'new' configs
fi
# main files
@@ -88,7 +132,7 @@ do
fi
if [ ! -f router.db ]; then
touch router.db
- cvs add router.db
- cvs commit -m 'new' router.db
+ $RCSSYS add router.db
+ $RCSSYS commit -m 'new' router.db
fi
done
diff --git a/bin/rancid-fe.in b/bin/rancid-fe.in
index b80a194..bed4129 100644
--- a/bin/rancid-fe.in
+++ b/bin/rancid-fe.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: rancid-fe.in,v 1.36 2004/01/11 03:49:13 heas Exp $
+## $Id: rancid-fe.in,v 1.45 2007/01/13 22:01:53 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -19,7 +20,7 @@
## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
-# rancid-FE - front-end to rancid/jrancid/etc. for use with par.
+# rancid-FE - front-end to rancid/jrancid/etc. for use with par.
#
# usage: rancid-fe <router>:<vendor>
#
@@ -27,32 +28,40 @@
require 5;
($router, $vendor) = split('\:', $ARGV[0]);
+$vendor =~ tr/[A-Z]/[a-z]/;
- 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 {
+%vendortable = (
+ 'agm' => 'agmrancid',
+ 'alteon' => 'arancid',
+ 'baynet' => 'brancid',
+ 'cat5' => 'cat5rancid',
+ 'cisco' => 'rancid',
+ 'css' => 'cssrancid',
+ 'enterasys' => 'rivrancid',
+ 'erx' => 'jerancid',
+ 'extreme' => 'xrancid',
+ 'ezt3' => 'erancid',
+ 'force10' => 'f10rancid',
+ 'foundry' => 'francid',
+ 'hitachi' => 'htrancid',
+ 'hp' => 'hrancid',
+ 'juniper' => 'jrancid',
+ 'mrtd' => 'mrancid',
+ 'netscaler' => 'nsrancid',
+ 'netscreen' => 'nrancid',
+ 'procket' => 'prancid',
+ 'redback' => 'rrancid',
+ 'riverstone' => 'rivrancid',
+ 'smc' => 'srancid',
+ 'tnt' => 'tntrancid',
+ 'zebra' => 'zrancid'
+);
+
+if ($vendortable{$vendor} eq "") {
printf(STDERR "unknown router manufacturer for $router: $vendor\n");
exit(-1);
+} else {
+ exec($vendortable{$vendor} . " $router");
}
printf(STDERR "exec failed router manufacturer $vendor: $!\n");
diff --git a/bin/rancid-run.in b/bin/rancid-run.in
index b59b026..42e387a 100644
--- a/bin/rancid-run.in
+++ b/bin/rancid-run.in
@@ -1,8 +1,9 @@
#! /bin/sh
##
-## $Id: rancid-run.in,v 1.28 2004/01/11 06:11:23 hank Exp $
+## $Id: rancid-run.in,v 1.35 2006/10/05 04:27:43 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -23,10 +24,9 @@
# @sysconfdir@/rancid.conf or those specified on the command-line.
#
+# Default ENVFILE, overrideable with -f flag.
ENVFILE="@sysconfdir@/rancid.conf"
-. $ENVFILE
-
TMPDIR=${TMPDIR:=/tmp}; export TMPDIR
# control_rancid argv
@@ -34,19 +34,30 @@ CR_ARGV=""; export CR_ARGV
# print a usage message to stderr
pr_usage() {
- echo "usage: $0 [-r device_name] [-m mail rcpt] [group [group ...]]" >&2;
+ echo "usage: $0 [-V] [-f config_file] [-r device_name] [-m mail rcpt] [group [group ...]]" >&2;
}
# command-line options
+# -V
+# -f <config file name>
+# -m <mailto address>
# -r <device name>
if [ $# -ge 1 ] ; then
while [ 1 ] ; do
case $1 in
- -r)
+ -V)
+ echo "@PACKAGE@ @VERSION@"
+ exit 0
+ ;;
+ -f)
shift
- # next arg is the device name
- CR_ARGV="$CR_ARGV -r $1"; export CR_ARGV
+ # next arg is the alternate config file name
+ ENVFILE="$1"
+ if [ -z $ENVFILE ]; then
+ pr_usage
+ exit 1
+ fi
shift
;;
-m)
@@ -55,6 +66,12 @@ if [ $# -ge 1 ] ; then
CR_ARGV="$CR_ARGV -m $1"; export CR_ARGV
shift
;;
+ -r)
+ shift
+ # next arg is the device name
+ CR_ARGV="$CR_ARGV -r $1"; export CR_ARGV
+ shift
+ ;;
--)
shift; break;
;;
@@ -74,6 +91,9 @@ if [ $# -ge 1 ] ; then
done
fi
+. $ENVFILE
+
+
if [ $# -ge 1 ] ; then
LIST_OF_GROUPS="$*"; export LIST_OF_GROUPS
elif [ "$LIST_OF_GROUPS" = "" ] ; then
@@ -88,49 +108,48 @@ fi
for GROUP in $LIST_OF_GROUPS
do
- LOCKFILE=$TMPDIR/.$GROUP.run.lock
-
- (
- echo starting: `date`
- echo
-
- if [ -f $LOCKFILE ]
- then
- echo hourly config diffs failed: $LOCKFILE exists
- ls -l $LOCKFILE
-
- # Send email if the lock file is old.
- if [ "X$LOCKTIME" = "X" ] ; then
- LOCKTIME=4
- fi
- @PERLV@ -e "\$t = (stat(\"$LOCKFILE\"))[9]; print \"OLD\\n\" if (time() - \$t >= $LOCKTIME*60*60);" > $TMPDIR/.$GROUP.old
- if [ -s $TMPDIR/.$GROUP.old ]
- then
- (
- echo "To: @ADMINMAILPLUS@$GROUP"
- echo "Subject: rancid hung - $GROUP"
- echo "Precedence: bulk"
- echo ""
-
- cat <<END
+ LOCKFILE=$TMPDIR/.$GROUP.run.lock
+
+ (
+ echo starting: `date`
+ echo
+
+ if [ -f $LOCKFILE ]
+ then
+ echo hourly config diffs failed: $LOCKFILE exists
+ ls -l $LOCKFILE
+
+ # Send email if the lock file is old.
+ if [ "X$LOCKTIME" = "X" ] ; then
+ LOCKTIME=4
+ fi
+ @PERLV@ -e "\$t = (stat(\"$LOCKFILE\"))[9]; print \"OLD\\n\" if (time() - \$t >= $LOCKTIME*60*60);" > $TMPDIR/.$GROUP.old
+ if [ -s $TMPDIR/.$GROUP.old ]
+ then
+ (
+ echo "To: @ADMINMAILPLUS@${GROUP}${MAILDOMAIN}"
+ echo "Subject: rancid hung - $GROUP"
+ echo "Precedence: bulk"
+ echo ""
+
+ cat <<END
rancid $GROUP hung on `hostname`? Old lockfile still exists:
`ls -l $LOCKFILE`
END
- ) | sendmail -t
- fi
- rm -f $TMPDIR/.$GROUP.old
-
- else
- trap 'rm -fr $LOCKFILE;exit 1' 1 2 3 6 10 15
- touch $LOCKFILE
- if [ $? -eq 0 ] ; then
- control_rancid $CR_ARGV $GROUP
- rm -f $LOCKFILE
- fi
- trap '' 1 2 3 6 10 15
- fi
-
- echo
- echo ending: `date`
- ) >$LOGDIR/$GROUP.`date +%Y%m%d.%H%M%S` 2>&1
+ ) | sendmail -t
+ fi
+ rm -f $TMPDIR/.$GROUP.old
+ else
+ trap 'rm -fr $LOCKFILE;exit 1' 1 2 3 6 10 15
+ touch $LOCKFILE
+ if [ $? -eq 0 ] ; then
+ control_rancid $CR_ARGV $GROUP
+ rm -f $LOCKFILE
+ fi
+ trap '' 1 2 3 6 10 15
+ fi
+
+ echo
+ echo ending: `date`
+ ) >$LOGDIR/$GROUP.`date +%Y%m%d.%H%M%S` 2>&1
done
diff --git a/bin/rancid.in b/bin/rancid.in
index 27a5a48..4b5b12a 100644
--- a/bin/rancid.in
+++ b/bin/rancid.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: rancid.in,v 1.168 2004/01/12 00:52:47 asp Exp $
+## $Id: rancid.in,v 1.218 2006/10/05 04:27:43 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -21,25 +22,33 @@
#
# RANCID - Really Awesome New Cisco confIg Differ
#
-# usage: rancid [-d] [-l] [-f filename | $host]
+# usage: rancid [-dV] [-l] [-f filename | hostname]
#
use Getopt::Std;
-getopts('dfl');
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
-$timeo = 90; # clogin timeout in seconds
+$found_version = 0;
+$found_env = 0;
+$found_diag = 0;
+$timeo = 90; # clogin timeout in seconds
-my(%filter_pwds); # password filtering mode
+my(@commandtable, %commands, @commands);# command lists
+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) {
+ 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;
}
@@ -61,10 +70,10 @@ sub ProcessHistory {
sub numerically { $a <=> $b; }
-# This is a sort routing that will sort numerically on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
@@ -74,10 +83,10 @@ sub keynsort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
@@ -87,10 +96,10 @@ sub keysort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
@@ -100,9 +109,9 @@ sub valsort{
@sorted_lines;
}
-# This is a numerical sort routing (ascending).
+# This is a numerical sort routine (ascending).
sub numsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a <=> $b} keys %lines) {
@@ -116,7 +125,7 @@ sub numsort {
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
@@ -129,7 +138,7 @@ sub ipsort {
# 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]));
+ $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
@@ -142,11 +151,18 @@ sub ShowVersion {
while (<INPUT>) {
tr/\015//d;
- last if(/^$prompt/);
- next if(/^(\s*|\s*$cmd\s*)$/);
+ if (/^$prompt/) { $found_version=1; last};
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if /Line has invalid autocommand /;
+ return(1) if /(Invalid input detected|Type help or )/;
return(-1) if (/command authorization failed/i);
+ return(0) if ($found_version); # Only do this routine once
# the pager can not be disabled per-session on the PIX
- s/^<-+ More -+>\s*//;
+ if (/^(<-+ More -+>)/) {
+ my($len) = length($1);
+ s/^$1\s{$len}//;
+ }
+
if (/^Slave in slot (\d+) is running/) {
$slave = " Slave:";
$slaveslot = ", slot $1";
@@ -157,10 +173,11 @@ sub ShowVersion {
ProcessHistory("COMMENTS","keysort","F1", "!Image: $_") && next;
/^Cisco Secure PIX /i &&
ProcessHistory("COMMENTS","keysort","F1", "!Image: $_") && next;
- # PIX fail-over license
- /^This PIX has an?\s+(.*)$/ &&
- ProcessHistory("COMMENTS","keysort","C1", "!$_") && next;
- /^(Cisco )?IOS .* Software,? \(([A-Za-z-0-9]*)\), .*Version\s+(.*)$/ &&
+ # PIX 6 fail-over license, as in "This PIX has an Unrestricted (UR)
+ # license." PIX 7 as "his platform has ..."
+ /^This (PIX|platform) has an?\s+(.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","D1", "!$_") && next;
+ /^(Cisco )?IOS .* Software,? \(([A-Za-z-0-9_]*)\), .*Version\s+(.*)$/ &&
ProcessHistory("COMMENTS","keysort","F1",
"!Image:$slave Software: $2, $3\n") && next;
/^([A-Za-z-0-9_]*) Synced to mainline version: (.*)$/ &&
@@ -181,6 +198,17 @@ sub ShowVersion {
}
/^Serial Number:\s+(.*)$/ &&
ProcessHistory("COMMENTS","keysort","C1", "!$_") && next;
+ # More PIX stuff
+ /^Encryption hardware device\s+:\s+(.*)/ &&
+ ProcessHistory("COMMENTS","keysort","A3", "!Encryption: $1\n") &&
+ next;
+ /^running activation key\s*:\s+(.*)/i &&
+ ProcessHistory("COMMENTS","keysort","D2", "!Key: $1\n") &&
+ next;
+ # Flash on the PIX or FWSM (FireWall Switch Module)
+ /^Flash(\s+\S+)+ \@ 0x\S+,\s+(\S+)/ &&
+ ProcessHistory("COMMENTS","keysort","B2", "!Memory: Flash $2\n") &&
+ next;
# CatOS 3500xl stuff
/^System serial number(:\s+.*)$/ &&
ProcessHistory("COMMENTS","keysort","C1", "!Serial Number$1\n") &&
@@ -211,7 +239,7 @@ sub ShowVersion {
next;
/^System image file is "([^\"]*)"$/ &&
ProcessHistory("COMMENTS","keysort","F5","!Image: $1\n") && next;
- if (/(\S+)\s+\((\S+)\)\s+processor.*with (\S+[kK]) bytes/) {
+ if (/(\S+)\s+(?:\((\S+)\)\s+processor|\(revision[^)]+\)).*\s+with (\S+k) bytes/i) {
my($proc) = $1;
my($cpu) = $2;
my($mem) = $3;
@@ -225,7 +253,17 @@ sub ShowVersion {
# incantations. for a slave, we dont get this info and its just a
# blank line.
$_ = <INPUT>;
- $_ = <INPUT> if (/processor board id/i);
+ if (/processor board id/i) {
+ my($sn);
+
+ if (/processor board id (\S+)/i) {
+ $sn = $1;
+ $sn =~ s/,$//;
+ ProcessHistory("COMMENTS","keysort","D9",
+ "!Processor ID: $sn\n");
+ }
+ $_ = <INPUT>;
+ }
$_ = "" if (! /(cpu at |processor: |$cpu processor,)/i);
tr/\015//d;
s/implementation/impl/i;
@@ -234,53 +272,57 @@ sub ShowVersion {
s/^/, /;
}
- if ( $proc eq "CSC") {
+ if ($proc eq "CSC") {
$type = "AGS";
- } elsif ( $proc eq "CSC4") {
+ } elsif ($proc eq "CSC4") {
$type = "AGS+";
- } elsif ( $proc =~ /^(AS)?25[12][12]/) {
+ } elsif ($proc =~ /^(AS)?25[12][12]/) {
$type = "2500";
- } elsif ( $proc =~ /261[01]/ || $proc =~ /262[01]/ ) {
+ } elsif ($proc =~ /261[01]/ || $proc =~ /262[01]/ ) {
$type = "2600";
- } elsif ( $proc =~ /^36[0246][0-9]/) {
+ } elsif ($proc =~ /^36[0246][0-9]/) {
$type = "3600";
- } elsif ( $proc =~ /^37/) {
+ } elsif ($proc =~ /^37/) {
$type = "3700";
- } elsif ( $proc eq "RSP7000") {
+ } elsif ($proc =~ /^38/) {
+ $type = "3800";
+ } elsif ($proc eq "RSP7000") {
$type = "7500";
- } elsif ( $proc =~ /RSP\d/) {
+ } elsif ($proc =~ /RSP\d/) {
$type = "7500";
- } elsif ( $proc eq "RP1") {
+ } elsif ($proc eq "RP1") {
$type = "7000";
- } elsif ( $proc eq "RP") {
+ } elsif ($proc eq "RP") {
$type = "7000";
- } elsif ( $proc =~ /720[246]/) {
+ } elsif ($proc =~ /720[246]/) {
$type = "7200";
- } elsif ( $proc =~ /1200[48]\/GRP/ || $proc =~ /1201[26]\/GRP/) {
+ } elsif ($proc =~ /1200[48]\/GRP/ || $proc =~ /1201[26]\/GRP/) {
$type = "12000";
- } elsif ( $proc =~ /1201[26]-8R\/GRP/) {
+ } elsif ($proc =~ /1201[26]-8R\/GRP/) {
$type = "12000";
- } elsif ( $proc =~ /WS-C29/) {
+ } elsif ($proc =~ /WS-C29/) {
$type = "2900XL";
$device = "switch";
- } elsif ( $proc =~ /WS-C355/) {
+ } elsif ($proc =~ /WS-C355/) {
$type = "3550";
$device = "switch";
- } elsif ( $proc =~ /WS-C35/) {
+ } elsif ($proc =~ /WS-C35/) {
$type = "3500XL";
$device = "switch";
- } elsif ( $proc =~ /WS-C45/) {
+ } elsif ($proc =~ /WS-C45/) {
$type = "4500";
$device = "switch";
- } elsif ( $proc =~ /6000/) {
+ } elsif ($proc =~ /6000/) {
$type = "6000";
$device = "switch";
- } elsif ( $proc =~ /CISCO76/) {
+ } elsif ($proc =~ /CISCO76/) {
$type = "7600";
$device = "router";
- } elsif ( $proc =~ /1900/) {
+ } elsif ($proc =~ /1900/) {
$type = "1900";
$device = "switch";
+ } elsif ( $proc =~ /^73/) {
+ $type = "7300";
} else {
$type = $proc;
}
@@ -289,7 +331,10 @@ sub ShowVersion {
"!Chassis type:$slave $proc - a $type $device\n");
ProcessHistory("COMMENTS","keysort","B1",
"!Memory:$slave main $mem\n");
- ProcessHistory("COMMENTS","keysort","A3","!CPU:$slave $cpu$_$slaveslot\n");
+ if (defined($cpu)) {
+ ProcessHistory("COMMENTS","keysort","A3",
+ "!CPU:$slave $cpu$_$slaveslot\n");
+ }
next;
}
if (/(\S+) Silicon\s*Switch Processor/) {
@@ -316,12 +361,12 @@ sub ShowVersion {
/^(\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) {
+ 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 (/^WARNING/) {
if (!defined($I0)) {
$I0=1;
ProcessHistory("COMMENTS","keysort","I0","!\n");
@@ -332,6 +377,10 @@ sub ShowVersion {
$config_register=$1;
next;
}
+ if (/^Configuration register on node \S+ is (.*)$/) {
+ $config_register=$1 if $config_register eq "";
+ next;
+ }
}
return(0);
}
@@ -342,12 +391,17 @@ sub ShowRedundancy {
while (<INPUT>) {
tr/\015//d;
- last if(/^$prompt/);
- next if(/^(\s*|\s*$cmd\s*)$/);
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if /Line has invalid autocommand /;
+ return(1) if /(Invalid input detected|Type help or )/;
# the pager can not be disabled per-session on the PIX
- s/^<-+ More -+>\s*//;
+ if (/^(<-+ More -+>)/) {
+ my($len) = length($1);
+ s/^$1\s{$len}//;
+ }
- /^IOS .* Software \(([A-Za-z-0-9]*)\), .*Version\s+(.*)$/ &&
+ /^IOS .* Software \(([A-Za-z-0-9_]*)\), .*Version\s+(.*)$/ &&
ProcessHistory("COMMENTS","keysort","F1",
"!Image:$slave Software: $1, $2\n") && next;
/^Compiled (.*)$/ &&
@@ -365,14 +419,18 @@ sub ShowIDprom {
while (<INPUT>) {
tr/\015//d;
- last if(/^$prompt/);
- next if(/^(\s*|\s*$cmd\s*)$/);
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if /Line has invalid autocommand /;
+ return(1) if /(Invalid input detected|Type help or )/;
# the pager can not be disabled per-session on the PIX
- s/^<-+ More -+>\s*//;
+ if (/^(<-+ More -+>)/) {
+ my($len) = length($1);
+ s/^$1\s{$len}//;
+ }
/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]+)/ &&
@@ -396,10 +454,15 @@ sub ShowInstallActive {
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
return(1) if /^\s*\^\s*$/;
+ return(1) if /Line has invalid autocommand /;
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*//;
+ if (/^(<-+ More -+>)/) {
+ my($len) = length($1);
+ s/^$1\s{$len}//;
+ }
+
ProcessHistory("COMMENTS","keysort","F5","!Image: $_") && next;
}
return(0);
@@ -412,12 +475,19 @@ sub ShowEnv {
while (<INPUT>) {
tr/\015//d;
- last if (/^$prompt/);
+ if (/^$prompt/) { $found_env=1; last};
next if (/^(\s*|\s*$cmd\s*)$/);
#return(1) if ($type !~ /^7/);
+ return(1) if /Line has invalid autocommand /;
+ return(1) if /(Invalid input detected|Type help or )/;
return(-1) if (/command authorization failed/i);
+ return(0) if ($found_env); # Only do this routine once
# the pager can not be disabled per-session on the PIX
- s/^<-+ More -+>\s*//;
+ if (/^(<-+ More -+>)/) {
+ my($len) = length($1);
+ s/^$1\s{$len}//;
+ }
+
if (!defined($E0)) {
$E0=1;
ProcessHistory("COMMENTS","keysort","E0","!\n");
@@ -432,6 +502,8 @@ sub ShowEnv {
"!Chassis type: $2 backplane\n");
next;
}
+ /^Power Supply Information$/ && next;
+ /^\s*Power Module\s+Voltage\s+Current$/ && next;
/^\s*(Power [^:\n]+)$/ &&
ProcessHistory("COMMENTS","keysort","E1","!Power: $1\n") && next;
/^\s*(Lower Power .*)/i &&
@@ -457,11 +529,13 @@ sub ShowRSP {
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*//;
+ if (/^(<-+ More -+>)/) {
+ my($len) = length($1);
+ s/^$1\s{$len}//;
+ }
/^$/ && next;
/^\s+Chassis model: (\S+)/ &&
- ProcessHistory("COMMENTS","keysort","D0","!\n") &&
ProcessHistory("COMMENTS","keysort","D1",
"!RSP Chassis model: $1\n") &&
next;
@@ -487,10 +561,13 @@ sub ShowGSR {
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*//;
+ if (/^(<-+ More -+>)/) {
+ my($len) = length($1);
+ s/^$1\s{$len}//;
+ }
/^$/ && next;
+
/^\s+Chassis: type (\S+) Fab Ver: (\S+)/ &&
- ProcessHistory("COMMENTS","keysort","D0","!\n") &&
ProcessHistory("COMMENTS","keysort","D1",
"!GSR Chassis type: $1 Fab Ver: $2\n") &&
next;
@@ -522,12 +599,17 @@ sub ShowBoot {
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 /Line has invalid autocommand /;
return(1) if /(Invalid input detected|Type help or )/;
+ return(1) if /Ambiguous command/i;
return(1) if /(Open device \S+ failed|Error opening \S+:)/;
+ return(-1) if (/command authorization failed/i);
# the pager can not be disabled per-session on the PIX
- s/^<-+ More -+>\s*//;
+ if (/^(<-+ More -+>)/) {
+ my($len) = length($1);
+ s/^$1\s{$len}//;
+ }
+
next if /CONFGEN variable/;
if (!defined($H0)) {
$H0=1; ProcessHistory("COMMENTS","keysort","H0","!\n");
@@ -557,11 +639,17 @@ sub ShowFlash {
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
return(1) if ($type =~ /^(12[40]|7)/);
- return(-1) if (/command authorization failed/i);
return(1) if /^\s*\^\s*$/;
+ return(1) if /Line has invalid autocommand /;
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*//;
+ if (/^(<-+ More -+>)/) {
+ my($len) = length($1);
+ s/^$1\s{$len}//;
+ }
+
+ /\s+(multiple-fs|nv_hdr|vlan\.dat)$/ && next;
ProcessHistory("FLASH","","","!Flash: $_");
}
ProcessHistory("","","","!\n");
@@ -581,6 +669,7 @@ sub DirSlotN {
next if (/^(\s*|\s*$cmd\s*)$/);
# return(1) if ($type !~ /^(12[40]|7|36)/);
return(1) if /^\s*\^\s*$/;
+ return(1) if /Line has invalid autocommand /;
return(1) if /(Invalid input detected|Type help or )/;
return(1) if /(No such device|Error Sending Request)/i;
return(1) if /\%Error: No such file or directory/;
@@ -590,7 +679,11 @@ sub DirSlotN {
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*//;
+ if (/^(<-+ More -+>)/) {
+ my($len) = length($1);
+ s/^$1\s{$len}//;
+ }
+
ProcessHistory("FLASH","","","!Flash: $dev: $_");
}
ProcessHistory("","","","!\n");
@@ -609,7 +702,11 @@ sub ShowContAll {
# 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 (/^(<-+ More -+>)/) {
+ my($len) = length($1);
+ s/^$1\s{$len}//;
+ }
+
if (/^Interface ([^ \n(]*)/) { $INT = "$1, "; next; }
/^(BRI unit \d)/ &&
ProcessHistory("INT","","","!Interface: $1\n") && next;
@@ -669,7 +766,11 @@ sub ShowContCbus {
#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 (/^(<-+ More -+>)/) {
+ my($len) = length($1);
+ s/^$1\s{$len}//;
+ }
+
if (/^\s*slot(\d+): ([^,]+), hw (\S+), sw (\S+), ccb/) {
$slot = $1;
$board{$slot} = $2;
@@ -703,6 +804,34 @@ sub ShowContCbus {
return(0);
}
+# This routine parses "show debug"
+sub ShowDebug {
+ print STDERR " In ShowDebug: $_" if ($debug);
+ my($lines) = 0;
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if /Line has invalid autocommand /;
+ 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
+ if (/^(<-+ More -+>)/) {
+ my($len) = length($1);
+ s/^$1\s{$len}//;
+ }
+
+ /^No matching debug flags set$/ && next;
+ ProcessHistory("COMMENTS","keysort","J1","!DEBUG: $_");
+ $lines++;
+ }
+ if ($lines) {
+ ProcessHistory("COMMENTS","keysort","J0","!\n");
+ }
+ return(0);
+}
+
# This routine parses "show diagbus"
# This will create arrarys for hw info.
sub ShowDiagbus {
@@ -714,9 +843,15 @@ sub ShowDiagbus {
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
#return(1) if ($type !~ /^7[05]/);
+ return(1) if /Line has invalid autocommand /;
+ 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*//;
+ if (/^(<-+ More -+>)/) {
+ my($len) = length($1);
+ s/^$1\s{$len}//;
+ }
+
if (/^\s*Slot (\d+):/i) {
$slot = $1;
next;
@@ -798,14 +933,20 @@ sub ShowDiag {
print STDERR " In ShowDiag: $_" if ($debug);
while (<INPUT>) {
- tr/\015//d;
- last if (/^$prompt/);
+REDUX: tr/\015//d;
+ if (/^$prompt/) { $found_diag=1; last};
next if (/^(\s*|\s*$cmd\s*)$/);
# return(1) if ($type !~ /^(12[40]|720|36|26)/);
+ return(1) if /Line has invalid autocommand /;
+ return(1) if /(Invalid input detected|Type help or )/;
return(-1) if (/command authorization failed/i);
+ return(0) if ($found_diag); # Only do this routine once
/^$/ && next;
# the pager can not be disabled per-session on the PIX
- s/^<-+ More -+>\s*//;
+ if (/^(<-+ More -+>)/) {
+ my($len) = length($1);
+ s/^$1\s{$len}//;
+ }
s/Port Packet Over SONET/POS/;
if (/^\s*SLOT\s+(\d+)\s+\((.*)\): (.*)/) {
@@ -814,8 +955,59 @@ sub ShowDiag {
ProcessHistory("SLOT","keysort","A","!Slot $slot: $3\n");
next;
}
- if (/^\s+MAIN:\s* type \d+,\s+(.*)/) {
- ProcessHistory("SLOT","keysort","AM","!Slot $slot/MAIN: part $1\n");
+ if (/^\s*NODE\s+(\S+) : (.*)/) {
+ $slot = $1;
+ ProcessHistory("SLOT","","","!\n");
+ ProcessHistory("SLOT","keysort","A","!Slot $slot: $2\n");
+ next;
+ }
+ if (/^\s*PLIM\s+(\S+) : (.*)/) {
+ $slot = $1 . " PLIM";
+ ProcessHistory("SLOT","","","!\n");
+ ProcessHistory("SLOT","keysort","A","!Slot $slot: $2\n");
+ next;
+ }
+ if (/^\s*RACK\s+(\S+) : (.*)/) {
+ $slot = "Rack/" . $1;
+ ProcessHistory("SLOT","","","!\n");
+ ProcessHistory("SLOT","keysort","A","!Slot $slot: $2\n");
+ next;
+ }
+ if (/^\s+MAIN:\s* type \S+,\s+(.*)/) {
+ local($part) = $1;
+ $_ = <INPUT>;
+ if (/^\s+(HW version|Design Release) (\S+)\s+S\/N (\S+)/i) {
+ ProcessHistory("SLOT","keysort","AM","!Slot $slot/MAIN: part $part, serial $3\n");
+ ProcessHistory("SLOT","keysort","AM","!Slot $slot/MAIN: hvers $2\n");
+ } else {
+ ProcessHistory("SLOT","keysort","AM","!Slot $slot/MAIN: part $part\n");
+ goto REDUX;
+ }
+ next;
+ }
+ if (/^\s+MAIN:\s* board type \S+$/) {
+ $_ = <INPUT>;
+ tr/\015//d;
+ if (/^\s+(.+)$/) {
+ local($part) = $1;
+ $_ = <INPUT>;
+ tr/\015//d;
+ if (/^\s+dev (.*)$/) {
+ local($dev) = $1;
+ $_ = <INPUT>;
+ if (/^\s+S\/N (\S+)/) {
+ ProcessHistory("SLOT","keysort","AM","!Slot $slot/MAIN: part $part, dev $dev, serial $1\n");
+ } else {
+ ProcessHistory("SLOT","keysort","AM","!Slot $slot/MAIN: part $part, dev $dev\n");
+ goto REDUX;
+ }
+ } else {
+ ProcessHistory("SLOT","keysort","AM","!Slot $slot/MAIN: part $part\n");
+ goto REDUX;
+ }
+ } else {
+ goto REDUX;
+ }
next;
}
if (/^c3700\s+(io-board|mid-plane)/i) {
@@ -831,12 +1023,24 @@ sub ShowDiag {
ProcessHistory("SLOT","keysort","AF","!Slot $slot/FRU: Linecard/Module: $1\n");
next;
}
+ if (/\s+Processor Memory:\s+(\S+)/) {
+ ProcessHistory("SLOT","keysort","AF","!Slot $slot/FRU: Processor Memory: $1\n");
+ next;
+ }
+ if (/\s+Packet Memory:\s+(\S+)/) {
+ ProcessHistory("SLOT","keysort","AF","!Slot $slot/FRU: Packet Memory: $1\n");
+ next;
+ }
if (/^\s+PCA:\s+(.*)/) {
local($part) = $1;
$_ = <INPUT>;
- /^\s+(HW version|design release) (\S+)\s+S\/N (\S+)/i &&
- ProcessHistory("SLOT","keysort","C1","!Slot $slot/PCA: part $part, serial $3\n") &&
+ if (/^\s+(HW version|design release) (\S+)\s+S\/N (\S+)/i) {
+ ProcessHistory("SLOT","keysort","C1","!Slot $slot/PCA: part $part, serial $3\n");
ProcessHistory("SLOT","keysort","C2","!Slot $slot/PCA: hvers $2\n");
+ } else {
+ ProcessHistory("SLOT","keysort","C1","!Slot $slot/PCA: part $part\n");
+ goto REDUX;
+ }
next;
}
if (/^\s+MBUS: .*\)\s+(.*)/) {
@@ -851,10 +1055,22 @@ sub ShowDiag {
ProcessHistory("SLOT","keysort","MB3","!Slot $slot/MBUS: software $1\n");
next;
}
+ if (/^\s+PLD: (.*)/) {
+ ProcessHistory("SLOT","keysort","P","!Slot $slot/PLD: $1\n");
+ next;
+ }
+ if (/^\s+MONLIB: (.*)/) {
+ ProcessHistory("SLOT","keysort","Q","!Slot $slot/MONLIB: $1\n");
+ next;
+ }
if (/^\s+ROM Monitor version (.*)/) {
ProcessHistory("SLOT","keysort","R","!Slot $slot/ROM Monitor: version $1\n");
next;
}
+ if (/^\s+ROMMON: Version (.*)/) {
+ ProcessHistory("SLOT","keysort","R","!Slot $slot/ROMMON: version $1\n");
+ next;
+ }
if (/^\s+Fabric Downloader version used (.*)/) {
ProcessHistory("SLOT","keysort","Z","!Slot $slot/Fabric Downloader: version $1\n");
next;
@@ -867,6 +1083,7 @@ sub ShowDiag {
. $1 / 1024 . " Kbytes SDRAM\n");
} else {
ProcessHistory("SLOT","keysort","MB4","!Slot $slot/MBUS: $dram Mbytes DRAM\n");
+ goto REDUX;
}
next;
}
@@ -880,6 +1097,8 @@ sub ShowDiag {
$WIC = "/$2";
} elsif ($1 eq "WIC/VIC") {
$WIC = "/$2";
+ } elsif ($1 eq "DSP") {
+ $WIC = "/$2";
} elsif ($1 eq "Encryption AIM") {
$slot = "$2";
undef($WIC);
@@ -915,6 +1134,15 @@ sub ShowDiag {
ProcessHistory("SLOT","keysort","B","!Slot $slot$WIC: type $_");
}
next;
+ } elsif (/^\s+(.* (DSP) Module) Slot (\d):/) {
+ # The 1760 (at least) has yet another format...where it has two
+ # dedicated DSP slots, and thus two slot 0s.
+ my($TYPE) = $1;
+ $WIC = "/$3";
+ ProcessHistory("SLOT","","","!\n");
+ ProcessHistory("SLOT","keysort","B",
+ "!Slot $slot$WIC: type $TYPE\n");
+ 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
@@ -929,7 +1157,7 @@ sub ShowDiag {
while (<INPUT>) {
tr/\015//d;
- if (/0x..: /) {
+ if (/0x..: / || /^$/) {
# no effing idea why break does not work there
goto PerlSucks;
}
@@ -953,32 +1181,87 @@ PerlSucks:
return(0);
}
+# This routine parses "show inventory".
+sub ShowInventory {
+ print STDERR " In ShowInventory: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ return if (/^\s*\^$/);
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if /Line has invalid autocommand /;
+ 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
+ if (/^(<-+ More -+>)/) {
+ my($len) = length($1);
+ s/^$1\s{$len}//;
+ }
+
+ if (/^(NAME: "[^"]*",) (DESCR: "[^"]+")/) {
+ ProcessHistory("INVENTORY","","", sprintf("!%-30s %s\n", $1, $2));
+ next;
+ }
+ # split PID/VID/SN line
+ if (/^PID: (\S*)\s*, VID: (\S*)\s*, SN: (\S*)\s*$/) {
+ my($entries) = "";
+ $entries .= "!PID: $1\n" if ($1);
+ $entries .= "!VID: $2\n" if ($2);
+ $entries .= "!SN: $3\n" if ($3);
+ ProcessHistory("INVENTORY","","", "$entries");
+ next;
+ }
+ ProcessHistory("INVENTORY","","","!$_");
+ }
+ ProcessHistory("INVENTORY","","","!\n");
+
+ return(0);
+}
+
# This routine parses "show module".
sub ShowModule {
print STDERR " In ShowModule: $_" if ($debug);
my(@lines);
- my($slot);
+ my($slot, $pa);
while (<INPUT>) {
tr/\015//d;
return if (/^\s*\^$/);
+ last if (/online diag status/i);
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 (/^(<-+ More -+>)/) {
+ my($len) = length($1);
+ s/^$1\s{$len}//;
+ }
# match slot/card info line
if (/^ *(\d+)\s+(\d+)\s+(.*)\s+(\S+)\s+(\S+)\s*$/) {
- $lines[$1] .= "!Slot $1: type $3, $2 ports\n!Slot $1: part $4, serial $5\n";
- $lines[$1] =~ s/\s+,/,/g;
+ $lines[$1 * 1000] .= "!Slot $1: type $3, $2 ports\n!Slot $1: part $4, serial $5\n";
+ $lines[$1 * 1000] =~ s/\s+,/,/g;
+ next;
}
# now match the Revs in the second paragraph of o/p and stick it in
# the array with the previous bits...grumble.
if (/^ *(\d+)\s+\S+\s+to\s+\S+\s+(\S+)\s+(\S*)\s+(\S+)(\s+\S+)?\s*$/) {
- $lines[$1] .= "!Slot $1: hvers $2, firmware $3, sw $4\n";
- $lines[$1] =~ s/\s+,/,/g;
+ $lines[$1 * 1000] .= "!Slot $1: hvers $2, firmware $3, sw $4\n";
+ $lines[$1 * 1000] =~ s/\s+,/,/g;
+ next;
+ }
+ # grab the sub-modules, if any
+ if (/^\s+(\d+)\s(.*)\s+(\S+)\s+(\S+)\s+(\S+)\s+\S+\s*$/) {
+ my($idx);
+ $pa = 0 if ($1 != $slot);
+ $slot = $1;
+ $idx = $1 * 1000 + $1 * 10 + $pa;
+ $lines[$idx] .= "!Slot $1/$pa: type $2\n";
+ $lines[$idx] .= "!Slot $slot/$pa: part $3, serial $4\n";
+ $lines[$idx] .= "!Slot $slot/$pa: hvers $5\n";
+ $pa++;
}
}
foreach $slot (@lines) {
@@ -998,6 +1281,7 @@ sub ShowSpeVersion {
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
return(1) if /^\s*\^\s*$/;
+ return(1) if /Line has invalid autocommand /;
return(1) if /(Invalid input detected|Type help or )/;
return(-1) if (/command authorization failed/i);
@@ -1021,7 +1305,11 @@ sub ShowC7200 {
return(-1) if (/command authorization failed/i);
/^$/ && next;
# the pager can not be disabled per-session on the PIX
- s/^<-+ More -+>\s*//;
+ if (/^(<-+ More -+>)/) {
+ my($len) = length($1);
+ s/^$1\s{$len}//;
+ }
+
if (/^(C7200 )?Midplane EEPROM:/) {
$_ = <INPUT>;
/revision\s+(\S+).*revision\s+(\S+)/;
@@ -1062,12 +1350,17 @@ sub ShowVTP {
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
return(1) if /^\s*\^\s*$/;
+ return(1) if /Line has invalid autocommand /;
return(1) if /(Invalid input detected|Type help or )/;
#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 (/^(<-+ More -+>)/) {
+ my($len) = length($1);
+ s/^$1\s{$len}//;
+ }
+
if (/^VTP Operating Mode\s+:\s+(Transparent|Server)/) {
$DO_SHOW_VLAN = 1;
}
@@ -1087,14 +1380,21 @@ sub ShowVLAN {
tr/\015//d;
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if /^\s*\^\s*$/;
+ return(1) if /Line has invalid autocommand /;
return(1) if /(Invalid input detected|Type help or )/;
+ return(1) if /Ambiguous command/i;
# 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*//;
+ if (/^(<-+ More -+>)/) {
+ my($len) = length($1);
+ s/^$1\s{$len}//;
+ }
+
ProcessHistory("COMMENTS","keysort","IO","!VLAN: $_");
}
ProcessHistory("COMMENTS","keysort","IO","!\n");
@@ -1108,10 +1408,16 @@ sub WriteTerm {
while (<INPUT>) {
tr/\015//d;
- last if(/^$prompt/);
+ last if (/^$prompt/);
+ return(1) if /Line has invalid autocommand /;
+ return(1) if (/(Invalid input detected|Type help or )/i);
return(-1) if (/command authorization failed/i);
# the pager can not be disabled per-session on the PIX
- s/^<-+ More -+>\s*//;
+ if (/^(<-+ More -+>)/) {
+ my($len) = length($1);
+ s/^$1\s{$len}//;
+ }
+
/Non-Volatile memory is in use/ && return(-1); # NvRAM is locked
return(0) if ($found_end); # Only do this routine once
$linecnt++;
@@ -1152,8 +1458,8 @@ sub WriteTerm {
$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");
+ if (/^(enable )?(password|passwd)( level \d+)? / && $filter_pwds >= 1) {
+ ProcessHistory("ENABLE","","","!$1$2$3 <removed>\n");
next;
}
if (/^(enable secret) / && $filter_pwds >= 2) {
@@ -1169,15 +1475,24 @@ sub WriteTerm {
next;
}
if (/^username (\S+)(\s.*)? password ((\d) \S+|\S+)/) {
- if ($filter_pwds == 2) {
+ if ($filter_pwds >= 2) {
ProcessHistory("USER","keysort","$1","!username $1$2 password <removed>\n");
- } elsif ($filter_pwds == 1 && $4 ne "5"){
+ } elsif ($filter_pwds >= 1 && $4 ne "5"){
ProcessHistory("USER","keysort","$1","!username $1$2 password <removed>\n");
} else {
ProcessHistory("USER","keysort","$1","$_");
}
next;
}
+ # cisco AP w/ IOS
+ if (/^(wlccp \S+ username (\S+)(\s.*)? password) (\d \S+|\S+)/) {
+ if ($filter_pwds >= 1) {
+ ProcessHistory("USER","keysort","$2","!$1 <removed>\n");
+ } else {
+ ProcessHistory("USER","keysort","$2","$_");
+ }
+ next;
+ }
if (/^( set session-key (in|out)bound ah \d+ )/ && $filter_pwds >= 1) {
ProcessHistory("","","","!$1<removed>\n");
next;
@@ -1190,6 +1505,10 @@ sub WriteTerm {
ProcessHistory("LINE-PASS","","","!$1password <removed>\n");
next;
}
+ if (/^(\s*)secret / && $filter_pwds >= 2) {
+ ProcessHistory("LINE-PASS","","","!$1secret <removed>\n");
+ next;
+ }
if (/^\s*neighbor (\S*) password / && $filter_pwds >= 1) {
ProcessHistory("","","","! neighbor $1 password <removed>\n");
next;
@@ -1215,11 +1534,15 @@ sub WriteTerm {
if (/^( ip ospf message-digest-key \d+ md5) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
+ # this is also reversable, despite 'md5 encrypted' in the cmd
+ if (/^( message-digest-key \d+ md5 (7|encrypted)) / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
if (/^((crypto )?isakmp key) \S+ / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed> $'"); next;
}
# filter HSRP passwords
- if (/^(\s+standby \d authentication) / && $filter_pwds >= 1) {
+ if (/^(\s+standby \d+ authentication) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
# this appears in "measurement/sla" images
@@ -1230,10 +1553,15 @@ sub WriteTerm {
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 (/^(vpdn username (\S+) password)/) {
+ if ($filter_pwds >= 1) {
+ ProcessHistory("USER","keysort","$2","!$1 <removed>\n");
+ } else {
+ ProcessHistory("USER","keysort","$2","$_");
+ }
+ next;
}
- if (/^( cable shared-secret ) / && $filter_pwds >= 1) {
+ if (/^( cable shared-secret )/ && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n");
next;
}
@@ -1306,6 +1634,11 @@ sub WriteTerm {
while ($token = shift(@tokens)) {
if ($token eq 'version') {
$line .= " " . join(' ', ($token, shift(@tokens)));
+ if ($token eq '3') {
+ $line .= " " . join(' ', ($token, shift(@tokens)));
+ }
+ } elsif ($token eq 'vrf') {
+ $line .= " " . join(' ', ($token, shift(@tokens)));
} elsif ($token =~ /^(informs?|traps?|(no)?auth)$/) {
$line .= " " . $token;
} else {
@@ -1327,12 +1660,9 @@ sub WriteTerm {
}
}
# 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;
+ if (/^((tacacs-server|radius-server)\s(\w*[-\s(\s\S+])*\s?key) \d \w+/
+ && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>$'"); next;
}
# order clns host statements
/^clns host \S+ (\S+)/ &&
@@ -1393,113 +1723,85 @@ sub WriteTerm {
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",
- 'show variables boot' => "ShowBoot",
- 'show flash' => "ShowFlash",
- 'dir /all nvram:' => "DirSlotN",
- 'dir /all bootflash:' => "DirSlotN",
- 'dir /all slot0:' => "DirSlotN",
- 'dir /all disk0:' => "DirSlotN",
- 'dir /all slot1:' => "DirSlotN",
- 'dir /all disk1:' => "DirSlotN",
- 'dir /all slot2:' => "DirSlotN",
- '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",
- "show variables boot",
- "show flash",
- "dir /all nvram:",
- "dir /all bootflash:",
- "dir /all slot0:",
- "dir /all disk0:",
- "dir /all slot1:",
- "dir /all disk1:",
- "dir /all slot2:",
- "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"
+@commandtable = (
+ {'admin show version' => 'ShowVersion'},
+ {'show version' => 'ShowVersion'},
+ {'show redundancy secondary' => 'ShowRedundancy'},
+ {'show idprom backplane', => 'ShowIDprom'},
+ {'show install active' => 'ShowInstallActive'},
+ {'admin show env all' => 'ShowEnv'},
+ {'show env all' => 'ShowEnv'},
+ {'show rsp chassis-info', => 'ShowRSP'},
+ {'show gsr chassis' => 'ShowGSR'},
+ {'show diag chassis-info' => 'ShowGSR'},
+ {'show boot' => 'ShowBoot'},
+ {'show bootvar' => 'ShowBoot'},
+ {'admin show variables boot' => 'ShowBoot'},
+ {'show variables boot' => 'ShowBoot'},
+ {'show flash' => 'ShowFlash'},
+ {'dir /all nvram:' => 'DirSlotN'},
+ {'dir /all bootflash:' => 'DirSlotN'},
+ {'dir /all slot0:' => 'DirSlotN'},
+ {'dir /all disk0:' => 'DirSlotN'},
+ {'dir /all slot1:' => 'DirSlotN'},
+ {'dir /all disk1:' => 'DirSlotN'},
+ {'dir /all slot2:' => 'DirSlotN'},
+ {'dir /all disk2:' => 'DirSlotN'},
+ {'dir /all harddisk:' => 'DirSlotN'},
+ {'dir /all harddiska:' => 'DirSlotN'},
+ {'dir /all harddiskb:' => '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'},
+ {'admin show diag' => 'ShowDiag'},
+ {'show diag' => 'ShowDiag'},
+ {'show module' => 'ShowModule'}, # cat 6500-ios
+ {'show spe version' => 'ShowSpeVersion'},
+ {'show c7200' => 'ShowC7200'},
+ {'show inventory raw' => 'ShowInventory'},
+ {'show vtp status' => 'ShowVTP'},
+ {'show vlan' => 'ShowVLAN'},
+ {'show vlan-switch' => 'ShowVLAN'},
+ {'show debug' => 'ShowDebug'},
+ {'show running-config' => 'WriteTerm'},
+ {'write term' => 'WriteTerm'},
);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
+
$cisco_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
@@ -1522,15 +1824,16 @@ if ($file) {
# determine password filtering mode
if ($ENV{"FILTER_PWDS"} =~ /no/i) {
- $filter_pwds = 0;
+ $filter_pwds = 0;
} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
- $filter_pwds = 2;
+ $filter_pwds = 2;
} else {
- $filter_pwds = 1;
+ $filter_pwds = 1;
}
ProcessHistory("","","","!RANCID-CONTENT-TYPE: cisco\n!\n");
ProcessHistory("COMMENTS","keysort","B0","!\n");
+ProcessHistory("COMMENTS","keysort","D0","!\n");
ProcessHistory("COMMENTS","keysort","F0","!\n");
ProcessHistory("COMMENTS","keysort","G0","!\n");
TOP: while(<INPUT>) {
diff --git a/bin/rivlogin.in b/bin/rivlogin.in
index 12554d5..2d80217 100644
--- a/bin/rivlogin.in
+++ b/bin/rivlogin.in
@@ -1,8 +1,9 @@
#! @EXPECT_PATH@ --
##
-## $Id: rivlogin.in,v 1.15 2004/01/11 05:39:15 heas Exp $
+## $Id: rivlogin.in,v 1.26 2006/12/08 21:28:26 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -24,24 +25,28 @@
# rivlogin - Riverstone (and Enterasys SSR) login
#
# Based upon rscmd (see nmops.org)
-# rscmd - Riverstone Networks Automated login
-# by Mike MacFaden, Kiran Addepalli
+# rscmd - Riverstone Networks Automated login
+# by Mike MacFaden, Kiran Addepalli
# Riverstone Networks, 2000
#
# Returned to the RANCID crowd by andrew fort
-# Global vars section
+# Usage line
+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"
# 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
+# cli command prompt
set my_prompt ">"
set enable_prompt "\#"
@@ -60,18 +65,35 @@ set do_script 0
set log_user 0
# The default CLI mode to login to is "enable" mode
-set enable 1
+set avenable 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"
+#
+set send_human {.4 .4 .7 .3 5}
+
+# 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
+}
+if {[ info exists env(CLOGINRC) ]} {
+ set password_file $env(CLOGINRC)
+}
# Procedures Section
@@ -79,7 +101,6 @@ router \[router...\]\n"
#
# Sets Xterm title if interactive...if its an xterm and the user cares
#
-
proc label { host } {
global env
@@ -97,35 +118,32 @@ proc label { host } {
}
}
-
# 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 } {
+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
-
+# 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] } {
+ if { [info exists read_password_file] } {
return 1
}
- if { [info exists password_file] == 0 } {
+ if { [info exists password_file] == 0 } {
set password_file $env(HOME)/.cloginrc
}
@@ -142,15 +160,14 @@ proc 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] } {
+ upvar $var list
+ if { [info exists list] } {
foreach line $list {
if { [string match [lindex $line 0] $router ] } {
return [lrange $line 1 end]
@@ -160,13 +177,11 @@ proc find { var router } {
return {}
}
-
# pre: login completed ok
# post: terminate login session by closing tcp connection
-
proc auto_exit { } {
- global telnet_id
+ global telnet_id
if { $verbose == 1 } {
puts "DEBUG: auto_exit closing connection to pid $telnet_id\n"
@@ -179,8 +194,7 @@ proc auto_exit { } {
# 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
-
+# and paging of cli output is disabled
proc login { router user userpswd passwd enapasswd } {
global login_array
@@ -212,7 +226,7 @@ proc login { router user userpswd passwd enapasswd } {
expect "*"
send "\r"
- # If password fails 3 times then expect again
+ # If password fails 3 times then expect again
set pass_attempt 0
expect {
@@ -220,7 +234,7 @@ proc login { router user userpswd passwd enapasswd } {
-re ".*> " { }
"Password:" {
- incr pass_attempt
+ incr pass_attempt
send "$passwd\r"
exp_continue
}
@@ -232,13 +246,13 @@ proc login { router user userpswd passwd enapasswd } {
send "$user\r"
expect {
- "Password: " {
+ "Password: " {
incr pattempt
if {$pattempt == 1} {
- send "$userpswd\r";
- } else {
- send "$enapasswd\r";
+ send "$userpswd\r";
+ } else {
+ send "$enapasswd\r";
}
exp_continue
}
@@ -246,8 +260,8 @@ proc login { router user userpswd passwd enapasswd } {
-re ".*> " { exp_continue;}
}
}
-
- "%TELNETD-W-BADPASSWD" {
+
+ "%TELNETD-W-BADPASSWD" {
puts "ERROR: bad userid or password to telnet."
return 1
}
@@ -266,7 +280,7 @@ proc login { router user userpswd passwd enapasswd } {
return 1
}
- "Connection closed *" {
+ "Connection closed *" {
if {$pass_attempt == 3} {
puts "ERROR: Maximum attempts for password reached. Check password. Exiting.";
puts $expect_out(0,string);
@@ -279,7 +293,7 @@ proc login { router user userpswd passwd enapasswd } {
return 1
}
- eof {
+ eof {
puts "ERROR: device closed telnet connection during login"
return 1
}
@@ -298,7 +312,6 @@ proc login { router user userpswd passwd enapasswd } {
# pre: login completed ok
# post: turn off paging of commands
-
proc disable_cli_paging { } {
global my_prompt
@@ -313,7 +326,6 @@ proc disable_cli_paging { } {
# 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
@@ -322,9 +334,9 @@ proc disable_cmd_autocomplete { } {
$my_prompt { }
- timeout {
+ timeout {
puts "ERROR:disable_cmd_autocomplete(TIMEOUT)";
- return 0;
+ return 0;
}
}
@@ -333,8 +345,7 @@ proc disable_cmd_autocomplete { } {
}
# pre: login returned 0, do_enable returned 0, cli is in enable or config mode
-# post: issues logout cli to device, returns 0
-
+# post: issues logout cli to device, returns 0
proc logout { prompt } {
global config_mode enable_prompt
@@ -342,7 +353,7 @@ proc logout { prompt } {
# verify top level prompt state, move to it if necessary
if { $config_mode == 1 } {
-
+
send "exit\r"
expect {
@@ -370,7 +381,6 @@ proc logout { prompt } {
# 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
@@ -380,19 +390,32 @@ proc do_enable { enauser enapasswd userpswd } {
if { $verbose == 1 } {
puts "DEBUG: do_enable: my_prompt = $my_prompt ena_prompt = $enable_prompt"
}
-
+
+ set uses_username 0;
+
send "enable\r"
expect {
- Username: { send "$enauser\r"; exp_continue }
- Password: { send "$userpswd\r"; exp_continue }
+ Username: {
+ set uses_username 1;
+ send "$enauser\r";
+ exp_continue
+ }
+ Password: {
+ if {$uses_username == 1} {
+ send "$userpswd\r";
+ } else {
+ send "$enapasswd\r";
+ }
+ exp_continue
+ }
"$my_prompt" {
puts "ERROR: do_enable failed to gain enable mode."
return 1
}
- "CONS-W-AUTH_PASSWD" { send "$enapasswd\r"; }
+ "CONS-W-AUTH_PASSWD" { send "$enapasswd\r"; }
"$enable_prompt " { }
"%SYS-W-NOPASSWD*" { }
@@ -402,14 +425,13 @@ proc do_enable { enauser enapasswd userpswd } {
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
@@ -419,7 +441,7 @@ proc do_configure { } {
if { $verbose == 1 } {
puts "DEBUG: do_config: my_prompt = $my_prompt cfg_prompt = $config_prompt"
}
-
+
send "configure\r"
expect {
"$config_prompt " { }
@@ -438,15 +460,14 @@ proc do_configure { } {
# 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
+ global logging
if { [ string length $output_file ] != 0 } {
- set rc [ catch {
+ 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
@@ -458,7 +479,7 @@ proc start_logfile { output_file } {
}
proc run_commands { prompt cmdstring } {
- global sendstring
+ global sendstring
set commands [split $cmdstring \;]
set num_commands [llength $cmdstring]
@@ -474,13 +495,11 @@ proc run_commands { prompt cmdstring } {
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
@@ -498,7 +517,7 @@ proc run_single_command { prompt cmdstring } {
set need_ays 1
set delay 1
if {$verbose == 1} {
- puts "DEBUG: save startup cmd seen, set need_ays = 1"
+ puts "DEBUG: save startup cmd seen, set need_ays = 1"
}
}
@@ -511,7 +530,7 @@ proc run_single_command { prompt cmdstring } {
if { $delay == 1} {
sleep 1
- }
+ }
expect {
@@ -542,7 +561,7 @@ proc run_single_command { prompt cmdstring } {
"want to overwrite " {
send "yes\r"
if {$verbose == 1} {
- puts "DEBUG: got overwrite question, set need_ays to 0"
+ puts "DEBUG: got overwrite question, set need_ays to 0"
}
set need_ays 0
}
@@ -551,7 +570,7 @@ proc run_single_command { prompt cmdstring } {
"%CONFIG-E-DUPLICATE,*" {
}
- "$prompt" {
+ "$prompt" {
if { $seen_prompt == 0 } {
set seen_prompt 1
}
@@ -571,7 +590,7 @@ proc run_single_command { prompt cmdstring } {
}
- timeout {
+ timeout {
if {$verbose == 1} {
puts "DEBUG: timeout occured for the $seen_time time\n"
}
@@ -586,8 +605,8 @@ proc run_single_command { prompt cmdstring } {
set rc 1
}
- eof {
- puts "ERROR:run_commands(connection closed by device)\n"
+ eof {
+ puts "ERROR:run_commands(connection closed by device)\n"
set rc 1
}
@@ -602,15 +621,14 @@ proc run_single_command { prompt cmdstring } {
# 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 -
+ # 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
}
@@ -631,14 +649,13 @@ proc source_script_file { filename } {
# 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 rc [ catch {
set ifile [ open $filename r]
} errMsg ]
@@ -650,16 +667,16 @@ proc process_script_file { filename } {
set line_cnt 0
while { [eof $ifile] != 1 } {
-
+
set bytes [ gets $ifile cmd ]
incr line_cnt
- if { $bytes < 0 } {
- break
+ if { $bytes < 0 } {
+ break
} elseif { $bytes == 0 } {
continue
}
-
+
if { $verbose == 1 } {
puts "DEBUG: line:$line_cnt cmd = $cmd\n"
}
@@ -693,12 +710,11 @@ proc process_script_file { filename } {
# 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 rc [ catch {
set ifile [ open $filename r]
} errMsg ]
@@ -706,7 +722,7 @@ proc strip_log { filename router } {
puts "ERROR: strip_log: open script file $filename for read access failed. $errMsg\n"
return 1
}
- set rc [ catch {
+ set rc [ catch {
set ofile [ open $tempfile w]
} errMsg ]
@@ -718,12 +734,11 @@ proc strip_log { filename router } {
set nl 0
puts $ofile "rscmd: $router : [exec date]"
-
+
while { [eof $ifile] != 1 } {
-
set bytes [ gets $ifile cmd ]
- if { $bytes <= 0 } {
- break
+ if { $bytes <= 0 } {
+ break
}
incr nl
if { $nl <= 2 } {
@@ -801,6 +816,10 @@ for {set idx 0} {$idx < $argc} {incr idx} {
}
set do_script 1
+ # Version string
+ } -V* {
+ send_user "@PACKAGE@ @VERSION@\n"
+ exit 0
# Command file
} -x* -
-X {
@@ -832,22 +851,21 @@ for {set idx 0} {$idx < $argc} {incr idx} {
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
+ # Timeout
+ } -t* -
+ -T* {
+ incr idx
+ set timeout [ lindex $argv $idx ]
+ # Do we enable?
+ } -noenable {
+ set avenable 0
+ } -* {
+ send_user "Error: Unkown argument! $arg\n"
+ send_user $usage
exit 1
-
- } default {
+ } default {
break
- }
+ }
}
}
@@ -859,146 +877,139 @@ if { $idx == $argc } {
}
# 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 passwords
+ if {$verbose == 1} {
+ puts "DEBUG: do_passwd = $do_passwd\n"
+ puts "DEBUG: do_enablepasswd = $do_enapasswd\n"
+ }
-# Figure out enable username
+ # look for noenable option in .cloginrc
+ if { [find noenable $router] != "" } {
+ set enable 0
+ } else {
+ set enable $avenable
+ }
-if {[info exists enausername]} {
- # command line enausername
- set enauser $enausername
-} else {
- set enauser [join [find enauser $router] ""]
- if { "$enauser" == "" } { set enauser $user }
-}
+ 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
+ }
-# Login to the router, set my_prompt to router's cmd prompt
+ set passwd [join [lindex $pswd 0] ""]
+ set enapasswd [join [lindex $pswd 1] ""]
+ } else {
+ set passwd $userpasswd
+ set enapasswd $enapasswd
+ }
-if {[login $router $user $userpswd $passwd $enapasswd ]} {
- if { $verbose == 1 } {
- puts "DEBUG: login to $router failed\n"
+ # 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 }
}
- exit 1
-}
-if {$verbose == 1 } {
- puts "DEBUG: login completed ok\n"
-}
+ # 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 }
+ }
-if { $enable == 1 } {
+ # 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 }
+ }
- if { [do_enable $enauser $enapasswd $userpswd] == 1} {
+ # Login to the router, set my_prompt to router's cmd prompt
+ if {[login $router $user $userpswd $passwd $enapasswd ]} {
if { $verbose == 1 } {
- puts "DEBUG: switch to enable mode on $router failed\n"
+ puts "DEBUG: login to $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 {$verbose == 1 } {
+ puts "DEBUG: login completed ok\n"
}
- if {[ run_commands $my_prompt $command ]} {
-
- log_file
- exit 1
+ 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
+ }
+ }
- } else {
+ # run in one of three modes
+ if { $do_command } {
+ disable_cmd_autocomplete
+ disable_cli_paging
- logout $my_prompt
+ if { [start_logfile $output_file] != 0 } {
+ exit 1
+ }
- }
-
-} elseif { $do_script } {
-
- 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 { [process_script_file $sfile] == 1} {
-# puts "DEBUG: logfile $output_file closed on error\n"
-# logout $my_prompt
-# exit 1
-# }
+ if {[ start_logfile $output_file] != 0 } {
+ exit 1
+ }
- source_script_file $sfile
+# if { [process_script_file $sfile] == 1} {
+# puts "DEBUG: logfile $output_file closed on error\n"
+# logout $my_prompt
+# exit 1
+# }
- logout $my_prompt
+ source_script_file $sfile
-} else {
-
- label $router
- log_user 1
+ logout $my_prompt
+ } else {
+ label $router
+ log_user 1
- if {[ start_logfile $output_file] != 0 } {
- exit 1
+ if {[ start_logfile $output_file] != 0 } {
+ exit 1
+ }
+ interact
+ log_file
}
- interact
- log_file
-}
-if { $verbose == 1 } {
- puts "DEBUG: exiting normally.\n"
-}
+ if { $verbose == 1 } {
+ puts "DEBUG: exiting normally.\n"
+ }
-if { $logging == 1} {
- log_file
- strip_log $output_file $router
-}
+ if { $logging == 1} {
+ log_file
+ strip_log $output_file $router
+ }
}
# puts "\n"
diff --git a/bin/rivrancid.in b/bin/rivrancid.in
index 8b9ae03..d6625b6 100644
--- a/bin/rivrancid.in
+++ b/bin/rivrancid.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: rivrancid.in,v 1.9 2004/01/11 03:49:13 heas Exp $
+## $Id: rivrancid.in,v 1.17 2006/10/05 04:27:44 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -21,31 +22,36 @@
#
# 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
+# Jim Meehan -- jmeehan@vpizza.org
#
# RANCID - Really Awesome New Cisco confIg Differ
#
-# usage: rivrancid [-d] [-l] [-f filename | $host]
+# usage: rivrancid [-dV] [-l] [-f filename | hostname]
#
use Getopt::Std;
-getopts('dfl');
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
-$timeo = 90; # flogin timeout in seconds
+$timeo = 90; # rivlogin timeout in seconds
-my(%filter_pwds); # password filtering mode
+my(@commandtable, %commands, @commands);# command lists
+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) {
+ 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;
}
@@ -67,10 +73,10 @@ sub ProcessHistory {
sub numerically { $a <=> $b; }
-# This is a sort routing that will sort numerically on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
@@ -80,10 +86,10 @@ sub keynsort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
@@ -93,22 +99,22 @@ sub keysort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
- $sorted_lines[$i] = $key;
- $i++;
+ $sorted_lines[$i] = $key;
+ $i++;
}
@sorted_lines;
}
-# This is a numerical sort routing (ascending).
+# This is a numerical sort routine (ascending).
sub numsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a <=> $b} keys %lines) {
@@ -122,7 +128,7 @@ sub numsort {
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
@@ -135,7 +141,7 @@ sub ipsort {
# 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]));
+ $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
@@ -179,7 +185,7 @@ sub ShowUptime {
tr/\015//d;
last if(/^$prompt/);
next if /^\s*$/;
- next if /System up/;
+ next if /System up/;
ProcessHistory("UPTIME","","","!UPTIME: $_");
}
ProcessHistory("","","","!\n");
@@ -197,13 +203,13 @@ sub ShowActive {
s/^\s*(\d+\D: )*//;
# Riverstone/Cabletron doesn't have an "end" line, so
- # we need to set $clean_run here
+ # we need to set $clean_run here
if (/^$prompt/) {
- $clean_run = 1;
- last;
- }
+ $clean_run = 1;
+ last;
+ }
- next if (/Running system configuration/);
+ next if (/Running system configuration/);
# filter out any RCS/CVS tags to avoid confusing local CVS storage
s/\$(Revision|Id):/ $1:/;
@@ -227,26 +233,29 @@ sub ShowActive {
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"
+@commandtable = (
+ {'system show uptime' => 'ShowUptime'},
+ {'system show version' => 'ShowVersion'},
+ {'system show hardware' => 'ShowHardware'},
+ {'system show active-config' => 'ShowActive'}
);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
$cisco_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
@@ -269,7 +278,7 @@ if ($file) {
# determine password filtering mode
if ($ENV{"FILTER_PWDS"} =~ /no/i) {
- $filter_pwds = 0;
+ $filter_pwds = 0;
} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
$filter_pwds = 2;
} else {
diff --git a/bin/rrancid.in b/bin/rrancid.in
index 7674452..87ea7c4 100644
--- a/bin/rrancid.in
+++ b/bin/rrancid.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: rrancid.in,v 1.18 2004/01/11 03:49:13 heas Exp $
+## $Id: rrancid.in,v 1.26 2006/10/05 04:27:44 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -23,25 +24,30 @@
#
# RANCID - Really Awesome New Cisco confIg Differ
#
-# usage: rancid [-d] [-l] [-f filename | $host]
+# usage: rancid [-dV] [-l] [-f filename | hostname]
#
use Getopt::Std;
-getopts('dfl');
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
-$timeo = 90; # clogin timeout in seconds
+$timeo = 90; # clogin timeout in seconds
-my(%filter_pwds); # password filtering mode
+my(@commandtable, %commands, @commands);# command lists
+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) {
+ 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;
}
@@ -63,10 +69,10 @@ sub ProcessHistory {
sub numerically { $a <=> $b; }
-# This is a sort routing that will sort numerically on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
@@ -76,10 +82,10 @@ sub keynsort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
@@ -89,22 +95,22 @@ sub keysort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
- $sorted_lines[$i] = $key;
- $i++;
+ $sorted_lines[$i] = $key;
+ $i++;
}
@sorted_lines;
}
-# This is a numerical sort routing (ascending).
+# This is a numerical sort routine (ascending).
sub numsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a <=> $b} keys %lines) {
@@ -118,7 +124,7 @@ sub numsort {
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
@@ -131,7 +137,7 @@ sub ipsort {
# 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]));
+ $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
@@ -245,7 +251,7 @@ sub WriteTerm {
s/\$(Revision|Id):/ $1:/;
# order access-lists
/^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ &&
- ProcessHistory("ACL $1 $2","ipsort","$3","$_") && next;
+ ProcessHistory("ACL $1 $2","ipsort","$3","$_") && next;
# prune snmp community statements
if (/^snmp (group|community) (\S+)/) {
if (defined($ENV{'NOCOMMSTR'})) {
@@ -255,7 +261,7 @@ sub WriteTerm {
}
}
ProcessHistory("","","","$_");
- # end of config
+ # end of config
if (/^end$/) {
$found_end = 1;
last;
@@ -283,30 +289,33 @@ sub FlailHelplessly {
}
# Main
-%commands=(
- 'show version' => "ShowVersion",
- "dir /flash" => "DirFlash",
- "dir /pcmcia0" => "DirFlash",
- "dir /pcmcia1" => "DirFlash",
- 'show hardware' => "ShowHardware",
- 'show chassis' => "ShowChassis",
- 'show slot table' => "ShowSlotTable",
- 'show config' => "WriteTerm"
-);
-@commands=(
- "show version",
- "dir /flash",
- "dir /pcmcia0",
- "dir /pcmcia1",
- "show hardware",
- "show chassis",
- "show slot table",
- "show config"
+@commandtable = (
+ {'show version' => 'ShowVersion'},
+ {'dir /flash' => 'DirFlash'},
+ {'dir /pcmcia0' => 'DirFlash'},
+ {'dir /pcmcia1' => 'DirFlash'},
+ {'show hardware' => 'ShowHardware'},
+ {'show chassis' => 'ShowChassis'},
+ {'show slot table' => 'ShowSlotTable'},
+ {'show config' => 'WriteTerm'}
);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
$redback_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered
@@ -330,7 +339,7 @@ if ($file) {
# determine password filtering mode
if ($ENV{"FILTER_PWDS"} =~ /no/i) {
- $filter_pwds = 0;
+ $filter_pwds = 0;
} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
$filter_pwds = 2;
} else {
diff --git a/bin/srancid.in b/bin/srancid.in
new file mode 100755
index 0000000..63c2e92
--- /dev/null
+++ b/bin/srancid.in
@@ -0,0 +1,404 @@
+#! @PERLV_PATH@
+##
+## Pretty huge hack to take care of Dell Switch configs
+## d_pfleger@juniper.net
+##
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Henry Kilmer.
+## All rights reserved.
+##
+## This software may be freely copied, modified and redistributed
+## fee for non-commerical purposes provided that this copyright notice
+## preserved intact on all copies and modified copies.
+##
+## There is no warranty or other guarantee of fitness of this software.
+## It is provided solely "as is". The author(s) disclaim(s) all
+## responsibility and liability with respect to this software's usage
+## or its effect upon hardware, computer systems, other software, or
+## anything else.
+##
+##
+#
+# RANCID - Really Awesome New Cisco confIg Differ
+#
+# usage: rancid [-dV] [-l] [-f filename | hostname]
+#
+use Getopt::Std;
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
+$log = $opt_l;
+$debug = $opt_d;
+$file = $opt_f;
+$host = $ARGV[0];
+$found_end = 0;
+$timeo = 90; # hlogin timeout in seconds
+
+my(@commandtable, %commands, @commands);# command lists
+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 "dir"
+sub Dir {
+ print STDERR " In Dir: $_" if ($debug);
+
+ while (<INPUT>) {
+ s/^\s+\015//g;
+ tr/\015//d;
+ next if /^\s*$/;
+ last if(/$prompt/);
+ # pager remnants like: ^H^H^H ^H^H^H content
+ s/[\b]+\s*[\b]*//g;
+
+ ProcessHistory("COMMENTS","keysort","D1","! $_");
+ }
+ return(0);
+}
+
+
+sub ShowVer {
+ print STDERR " In ShowVer: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ next if /^\s*$/;
+ last if(/$prompt/);
+ # pager remnants like: ^H^H^H ^H^H^H content
+ s/[\b]+\s*[\b]*//g;
+
+ ProcessHistory("COMMENTS","keysort","B1","! $_");
+ }
+ return(0);
+}
+
+sub ShowSys {
+ print STDERR " In ShowSys: $_" if ($debug);
+
+ while (<INPUT>) {
+ s/^\s+\015//g;
+ tr/\015//d;
+ next if /^\s*$/;
+ last if(/$prompt/);
+ # pager remnants like: ^H^H^H ^H^H^H content
+ s/[\b]+\s*[\b]*//g;
+
+ # Remove Uptime
+ / Up time/ && next;
+
+ /system description: (.*)/i &&
+ ProcessHistory("COMMENTS","keysort","A1", "!Chassis type: $1\n") &&
+ next;
+
+ ProcessHistory("COMMENTS","keysort","C1","! $_");
+ }
+ return(0);
+}
+
+sub ShowVlan {
+ print STDERR " In ShowVlan: $_" if ($debug);
+
+ while (<INPUT>) {
+ s/^\s+\015//g;
+ tr/\015//d;
+ next if /^\s*$/;
+ last if(/$prompt/);
+ # pager remnants like: ^H^H^H ^H^H^H content
+ s/[\b]+\s*[\b]*//g;
+
+ # Remove Uptime
+ / Up time/ && next;
+ ProcessHistory("COMMENTS","keysort","D1","! $_");
+ }
+ return(0);
+}
+
+# This routine processes a "write term" (aka show running-configuration)
+sub WriteTerm {
+ my($comment) = (0);
+ print STDERR " In ShowRun: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ next if /^\s*$/;
+ last if(/$prompt/);
+ # pager remnants like: ^H^H^H ^H^H^H content
+ s/[\b]+\s*[\b]*//g;
+
+ # skip consecutive comment lines
+ if (/^!/) {
+ next if ($comment);
+ ProcessHistory("","","",$_);
+ $comment++;
+ next;
+ }
+ $comment = 0;
+
+ /^building running-config/ && next;
+ /^------+/ && ProcessHistory("","","","!$_") && next;
+ /^router configuration/i && ProcessHistory("","","","!$_") && next;
+ /^oob host config/i && ProcessHistory("","","","!$_") && next;
+ /^empty configuration/i && ProcessHistory("","","","!$_") && next;
+
+ if (/^password (\S+) encrypted/ && $filter_pwds > 1) {
+ ProcessHistory("","","","!password <removed> encrypted\n");
+ next;
+ }
+ if (/^password (\S+)$/ && $filter_pwds >= 1) {
+ ProcessHistory("","","","!password <removed>\n");
+ next;
+ }
+
+ if (/^(enable password level \d+) (\S+) encrypted/ && $filter_pwds > 1){
+ ProcessHistory("","","","!$1 <removed> encrypted\n");
+ next;
+ }
+ if (/^(enable password level \d+) (\S+)$/ && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed> $'\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+) (\S+)/) {
+ if (defined($ENV{'NOCOMMSTR'})) {
+ ProcessHistory("SNMPSERVERHOST","ipsort",
+ "$2","!$1 $2 <removed>$'");
+ } else {
+ ProcessHistory("SNMPSERVERHOST","ipsort","$2","$_");
+ }
+ next;
+ }
+ if (/^(snmp-server community) (\S+)/) {
+ if (defined($ENV{'NOCOMMSTR'})) {
+ ProcessHistory("SNMPSERVERCOMM","keysort",
+ "$_","!$1 <removed>$'") && next;
+ } else {
+ ProcessHistory("SNMPSERVERCOMM","keysort","$2","$_") && next;
+ }
+ }
+
+ # prune tacacs/radius server keys
+ if (/^(tacacs-server|radius-server) key \w+/ && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>$'"); next;
+ }
+
+ ProcessHistory("","","","$_");
+ }
+ $found_end = 1;
+ return(1);
+}
+
+# dummy function
+sub DoNothing {print STDOUT;}
+
+# Main
+@commandtable = (
+ {'show system' => 'ShowSys'},
+ {'show version' => 'ShowVer'},
+ {'dir' => 'Dir'},
+ {'show vlan' => 'ShowVlan'},
+ {'show running-config' => 'WriteTerm'}
+);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
+
+$cisco_cmds=join(";",@commands);
+$cmds_regexp=join("|",@commands);
+
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
+open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
+select(OUTPUT);
+# make OUTPUT unbuffered if debugging
+if ($debug) { $| = 1; }
+
+if ($file) {
+ print STDERR "opening file $host\n" if ($debug);
+ print STDOUT "opening file $host\n" if ($log);
+ open(INPUT,"<$host") || die "open failed for $host: $!\n"; } else {
+ print STDERR "executing hlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug);
+ print STDOUT "executing hlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log);
+ if (defined($ENV{NOPIPE})) {
+ system "hlogin -t $timeo -c \"$cisco_cmds\" $host </dev/null > $host.raw 2>&1" || die "hlogin failed for $host: $!\n";
+ open(INPUT, "< $host.raw") || die "hlogin failed for $host: $!\n";
+ } else {
+ open(INPUT,"hlogin -t $timeo -c \"$cisco_cmds\" $host </dev/null |") || die "hlogin failed for $host: $!\n";
+ }
+}
+
+# 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: dell\n!\n");
+ProcessHistory("COMMENTS","keysort","A0","!\n");
+ProcessHistory("COMMENTS","keysort","B0","!\n");
+ProcessHistory("COMMENTS","keysort","C0","!\n");
+ProcessHistory("COMMENTS","keysort","D0","!\n");
+TOP: while(<INPUT>) {
+ tr/\015//d;
+ if (/^Error:/) {
+ print STDOUT ("$host dlogin error: $_");
+ print STDERR ("$host dlogin error: $_") if ($debug);
+ 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";
+ 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/tntlogin.in b/bin/tntlogin.in
index 021f0d2..57fbfc0 100644
--- a/bin/tntlogin.in
+++ b/bin/tntlogin.in
@@ -1,8 +1,9 @@
#! @EXPECT_PATH@ --
##
-## $Id: tntlogin.in,v 1.11 2004/01/11 05:39:15 heas Exp $
+## $Id: tntlogin.in,v 1.22 2006/12/05 16:50:53 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -39,16 +40,16 @@ set password_file $env(HOME)/.cloginrc
set do_command 0
set do_script 0
# The default is to automatically enable
-set enable 0
+set avenable 0
# The default is that you login non-enabled (tacacs can have you login already
# enabled)
-set avautoenable 1
+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) ] } {
+if {[ info exists env(CISCO_USER) ]} {
set default_user $env(CISCO_USER)
} elseif {[ info exists env(USER) ]} {
set default_user $env(USER)
@@ -61,9 +62,12 @@ if {[ info exists env(CISCO_USER) ] } {
if [ catch {exec id} reason ] {
send_error "\nError: could not exec id: $reason\n"
exit 1
- }
+ }
regexp {\(([^)]*)} "$reason" junk default_user
-}
+}
+if {[ info exists env(CLOGINRC) ]} {
+ set password_file $env(CLOGINRC)
+}
# Sometimes routers take awhile to answer (the default is 10 sec)
set timeout 45
@@ -81,13 +85,16 @@ for {set i 0} {$i < $argc} {incr i} {
set username [ lindex $argv $i ]
}
# VTY Password
- } -v* -
- -v* {
+ } -v* {
if {! [ regexp .\[vV\](.+) $arg ignore passwd]} {
incr i
set passwd [ lindex $argv $i ]
}
set do_passwd 0
+ # Version string
+ } -V* {
+ send_user "@PACKAGE@ @VERSION@\n"
+ exit 0
# Enable Username
} -w* -
-W* {
@@ -260,6 +267,7 @@ proc source_password_file { password_file } {
}
# Log into the router.
+# returns: 0 on success, 1 on failure
proc login { router user userpswd passwd prompt cmethod cyphertype } {
global spawn_id in_proc do_command do_script
global u_prompt p_prompt sshcmd
@@ -269,6 +277,7 @@ proc login { router user userpswd passwd prompt cmethod cyphertype } {
# try each of the connection methods in $cmethod until one is successful
set progs [llength $cmethod]
foreach prog [lrange $cmethod 0 end] {
+ incr progs -1
if [string match "telnet*" $prog] {
regexp {telnet(:([^[:space:]]+))*} $prog command suffix port
if {"$port" == ""} {
@@ -278,24 +287,24 @@ proc login { router user userpswd passwd prompt cmethod cyphertype } {
}
if { $retval } {
send_user "\nError: telnet failed: $reason\n"
- exit 1
+ return 1
}
- } elseif ![string compare $prog "ssh"] {
+ } 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
+ return 1
}
- } else {
- puts "\nError: unknown connection method: $prog"
+ } elseif ![string compare $prog "rsh"] {
+ send_error "\nError: unsupported method: rsh\n"
+ if { $progs == 0 } {
+ return 1
+ }
+ continue;
+ } else {
+ send_user "\nError: unknown connection method: $prog\n"
return 1
- }
- incr progs -1
- sleep 0.3
+ }
+ sleep 0.3
# This helps cleanup each expect clause.
expect_after {
@@ -387,7 +396,7 @@ proc run_commands { prompt command } {
send "lines 0\r"
expect -re $prompt {}
regsub -all "\[)(]" $prompt {\\&} reprompt
-
+
# Is this a multi-command?
if [ string match "*\;*" "$command" ] {
set commands [split $command \;]
@@ -409,7 +418,7 @@ proc run_commands { prompt command } {
-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]"
@@ -417,10 +426,12 @@ proc run_commands { prompt command } {
# send "y\r"
exp_continue
}
- "\n" { exp_continue }
- "\[^\n\r *]*Session terminated" { return 0 }
- timeout { return 0 }
- eof { return 0 }
+ "\n" { exp_continue }
+ "\[^\n\r *]*Session terminated" { return 0 }
+ timeout { catch {close}; wait
+ return 0
+ }
+ eof { return 0 }
}
set in_proc 0
}
@@ -496,9 +507,9 @@ 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} }
+ # 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]} {
diff --git a/bin/tntrancid.in b/bin/tntrancid.in
index 88520fd..e16d57b 100644
--- a/bin/tntrancid.in
+++ b/bin/tntrancid.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: tntrancid.in,v 1.8 2004/01/11 03:49:13 heas Exp $
+## $Id: tntrancid.in,v 1.17 2006/10/05 04:27:44 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -24,29 +25,33 @@
#
# RANCID - Really Awesome New Cisco confIg Differ
#
-# usage: tntrancid [-d] [-l] [-f filename | $host]
+# usage: tntrancid [-dV] [-l] [-f filename | hostname]
#
use Getopt::Std;
-getopts('dfl');
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
-$timeo = 90; # tntlogin timeout in seconds
+$timeo = 90; # tntlogin timeout in seconds
$prompt = "admin> ";
-$always_y = "y"; # cause its a pain.
+$always_y = "y"; # cause its a pain.
-my(%filter_pwds); # password filtering mode
+my(@commandtable, %commands, @commands);# command lists
+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) {
+ 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)) {
@@ -67,10 +72,10 @@ sub ProcessHistory {
sub numerically { $a <=> $b; }
-# This is a sort routing that will sort numerically on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
@@ -80,10 +85,10 @@ sub keynsort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
@@ -93,10 +98,10 @@ sub keysort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
@@ -106,9 +111,9 @@ sub valsort{
@sorted_lines;
}
-# This is a numerical sort routing (ascending).
+# This is a numerical sort routine (ascending).
sub numsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a <=> $b} keys %lines) {
@@ -122,7 +127,7 @@ sub numsort {
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
@@ -135,45 +140,40 @@ sub ipsort {
# 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]));
+ $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
+ # Leave software revision, but strip out saved date,
+ # which causes rancid to think it changes each poll
if (/^; saved from /) {
- ProcessHistory("","","","$_");
- next;
+ 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);
+ return(1);
}
- $found_end = 1;
+ # XXX what is the purpose of this?
+ $found_end = 1;
#### print STDOUT "$found_end = found_end at test\n";
}
$found_end = 1;
@@ -189,18 +189,26 @@ print STDOUT "$found_end = found_end at end test\n";
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"
+@commandtable = (
+ {'save con' => 'SaveConf'}
);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
+
$tnt_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);
-$tnt_cmds="save con";
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
@@ -223,7 +231,7 @@ if ($file) {
# determine password filtering mode
if ($ENV{"FILTER_PWDS"} =~ /no/i) {
- $filter_pwds = 0;
+ $filter_pwds = 0;
} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
$filter_pwds = 2;
} else {
@@ -234,8 +242,8 @@ ProcessHistory("","","","#RANCID-CONTENT-TYPE: tnt\n#\n");
ProcessHistory("COMMENTS","keysort","X0",";\n");
TOP: while(<INPUT>) {
tr/\015//d;
-
- if (/^Error:/) {
+
+ if (/^Error:/) {
print STDOUT ("$host tntlogin error: $_");
print STDERR ("$host tntlogin error: $_") if ($debug);
$clean_run=0;
diff --git a/bin/xrancid.in b/bin/xrancid.in
index 4aeb1d3..96b99ef 100644
--- a/bin/xrancid.in
+++ b/bin/xrancid.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: xrancid.in,v 1.32 2004/01/11 03:49:13 heas Exp $
+## $Id: xrancid.in,v 1.41 2006/10/05 04:27:44 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -21,25 +22,30 @@
#
# RANCID - Really Awesome New Cisco confIg Differ
#
-# usage: rancid [-d] [-l] [-f filename | $host]
+# usage: rancid [-dV] [-l] [-f filename | hostname]
#
use Getopt::Std;
-getopts('dfl');
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
-$timeo = 90; # clogin timeout in seconds
+$timeo = 90; # clogin timeout in seconds
-my(%filter_pwds); # password filtering mode
+my(@commandtable, %commands, @commands);# command lists
+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) {
+ 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;
}
@@ -61,10 +67,10 @@ sub ProcessHistory {
sub numerically { $a <=> $b; }
-# This is a sort routing that will sort numerically on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
@@ -74,10 +80,10 @@ sub keynsort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
@@ -87,10 +93,10 @@ sub keysort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
@@ -100,9 +106,9 @@ sub valsort{
@sorted_lines;
}
-# This is a numerical sort routing (ascending).
+# This is a numerical sort routine (ascending).
sub numsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a <=> $b} keys %lines) {
@@ -116,7 +122,7 @@ sub numsort {
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
@@ -129,7 +135,7 @@ sub ipsort {
# 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]));
+ $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
@@ -180,7 +186,7 @@ sub ShowMemory {
return(0);
}
-# This routine parses "show diagnostics"
+# This routine parses "show diag"
sub ShowDiag {
print STDERR " In ShowDiag: $_" if ($debug);
@@ -373,29 +379,32 @@ sub WriteTerm {
sub DoNothing {print STDOUT;}
# Main
-%commands=(
- '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
-@commands=(
- "show version",
- "show memory",
- "show diagnostics",
- "show switch",
- "show slot",
- "show configuration detail",
- "show configuration"
+@commandtable = (
+ {'show version' => 'ShowVersion'},
+ {'show memory' => 'ShowMemory'},
+ {'show diag' => 'ShowDiag'},
+ {'show switch' => 'ShowSwitch'},
+ {'show slot' => 'ShowSlot'},
+ {'show configuration detail' => 'WriteTerm'},
+ {'show configuration' => 'WriteTerm'},
);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
+
$cisco_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
@@ -418,7 +427,7 @@ if ($file) {
# determine password filtering mode
if ($ENV{"FILTER_PWDS"} =~ /no/i) {
- $filter_pwds = 0;
+ $filter_pwds = 0;
} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
$filter_pwds = 2;
} else {
@@ -453,7 +462,7 @@ TOP: while(<INPUT>) {
if (!defined($prompt)) {
$prompt = ($_ =~ /^([^#]+#)/)[0];
$prompt =~ s/([][}{)(\\])/\\$1/g;
- $prompt =~ s/:(\d+ ?)#/:\\d+ ?#/;
+ $prompt =~ s/[:.](\d+ ?)#/:\\d+ ?#/;
$prompt =~ s/\*/\\\*/;
print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
}
diff --git a/bin/zrancid.in b/bin/zrancid.in
index a969553..c8a926f 100755
--- a/bin/zrancid.in
+++ b/bin/zrancid.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: zrancid.in,v 1.8 2004/01/11 03:49:13 heas Exp $
+## $Id: zrancid.in,v 1.14 2006/10/05 04:27:44 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -23,25 +24,30 @@
#
# RANCID - Really Awesome New Cisco confIg Differ
#
-# usage: rancid [-d] [-l] [-f filename | $host]
+# usage: rancid [-dV] [-l] [-f filename | hostname]
#
use Getopt::Std;
-getopts('dfl');
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
-$timeo = 90; # clogin timeout in seconds
+$timeo = 90; # clogin timeout in seconds
-my(%filter_pwds); # password filtering mode
+my(@commandtable, %commands, @commands);# command lists
+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) {
+ 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;
}
@@ -63,10 +69,10 @@ sub ProcessHistory {
sub numerically { $a <=> $b; }
-# This is a sort routing that will sort numerically on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
@@ -76,10 +82,10 @@ sub keynsort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
@@ -89,10 +95,10 @@ sub keysort {
@sorted_lines;
}
-# This is a sort routing that will sort on the
+# 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(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
@@ -102,9 +108,9 @@ sub valsort{
@sorted_lines;
}
-# This is a numerical sort routing (ascending).
+# This is a numerical sort routine (ascending).
sub numsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a <=> $b} keys %lines) {
@@ -118,7 +124,7 @@ sub numsort {
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
@@ -131,7 +137,7 @@ sub ipsort {
# 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]));
+ $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
@@ -306,19 +312,27 @@ sub WriteTerm {
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"
+@commandtable = (
+ {'show version' => 'ShowVersion'},
+ {'write term' => 'WriteTerm'}
);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
+
$cisco_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging