diff --git a/bin/control_rancid b/bin/control_rancid deleted file mode 100755 index 5d3371c..0000000 --- a/bin/control_rancid +++ /dev/null @@ -1,794 +0,0 @@ -#! /bin/sh -## -## $Id: control_rancid.in 3763 2018-02-02 19:38:21Z heas $ -## -## rancid 3.9 -## Copyright (c) 1997-2018 by Henry Kilmer and John Heasley -## All rights reserved. -## -## This code is derived from software contributed to and maintained by -## Henry Kilmer, John Heasley, Andrew Partan, -## Pete Whiting, Austin Schutz, and Andrew Fort. -## -## 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 RANCID 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 Henry Kilmer, John Heasley 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 COMPANY 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. -## -## It is the request of the authors, but not a condition of license, that -## parties packaging or redistributing RANCID NOT distribute altered versions -## of the etc/rancid.types.base file nor alter how this file is processed nor -## when in relation to etc/rancid.types.conf. The goal of this is to help -## suppress our support costs. If it becomes a problem, this could become a -## condition of license. -# -# The expect login scripts were based on Erik Sherk's gwtn, by permission. -# -# The original looking glass software was written by Ed Kern, provided by -# permission and modified beyond recognition. -# -# control_rancid $GROUP -# - -# print a usage message to stderr -pr_usage() { - echo "usage: $0 [-V] [-c commit_msg] [-f group_config_file] [-r device_name] [-m mail rcpt] group" >&2; -} - -# command-line options -# -V print version string -# -c -# -f -# -m -# -r -alt_mailrcpt=0 -alt_commitmsg=0 -if [ $# -ge 1 ] ; then - - while [ 1 ] ; do - case $1 in - -V) - echo "rancid 3.9" - exit 0 - ;; - -c) - shift - # next arg is the commit message - alt_commitmsg=1 - if [ -z "$commitmsg" ] ; then - commitmsg="$1" - else - commitmsg="$commitmsg,$1" - fi - shift - ;; - -f) - shift - # next arg is the alternate config file name - ENVFILE="$1" - if [ -z $ENVFILE ]; then - pr_usage - exit 1 - fi - shift - ;; - -m) - shift - # next arg is the mail recipient - alt_mailrcpt=1 - if [ -z "$mailrcpt" ] ; then - mailrcpt="$1" - else - mailrcpt="$mailrcpt,$1" - fi - shift - ;; - -r) - shift - # next arg is the device name - device="$1" - shift - ;; - --) - shift; break; - ;; - -h) - pr_usage - exit 0 - ;; - -*) - echo "unknown option: $1" >&2 - pr_usage - exit 1 - ;; - *) - break; - ;; - esac - done -fi - -# Must specify a group on which to run rancid -if [ $# -lt 1 ] ; then - echo 'must specify group'; exit 1 -else - GROUP=$1 -fi -TMP=${TMPDIR:=/tmp}/rancid.$GROUP.$$ -if [ -z "$ENVFILE" ] ; then - ENVFILE="/home/testranc/etc/rancid.conf" -fi -if [ -f "$ENVFILE" ] ; then - . $ENVFILE -fi -trap 'rm -fr $TMP;' 1 2 15 -DIR=$BASEDIR/$GROUP - -# disable noclobber -unset noclobber > /dev/null 2>&1 - -# SENDMAIL location -SENDMAIL=${SENDMAIL:=sendmail}; -# default MAILHEADERS -set | grep MAILHEADERS= > /dev/null 2>&1 -if [ $? -ne 0 ] ; then - MAILHEADERS="Precedence: bulk\nAuto-submitted: auto-generated\nX-Auto-Response-Suppress: All"; export MAILHEADERS -fi - -# Bail if we do not have the necessary info to run -if [ ! -d $DIR ] ; then - adminmailrcpt=${adminmailrcpt:-"rancid-admin-${GROUP}${MAILDOMAIN}"}; - echo "$DIR does not exist." - echo "Run bin/rancid-cvs $GROUP to make all of the needed directories." - ( - echo "To: $adminmailrcpt" - echo "Subject: no $GROUP directory" - 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 $MAILOPTS - exit 1 -fi -cd $DIR -if [ -f "rancid.conf" ] ; then - . ./rancid.conf -fi - -# RCS system -RCSSYS=${RCSSYS:=cvs}; -if [ $RCSSYS != "cvs" -a $RCSSYS != "svn" -a $RCSSYS != "git" ] ; then - echo "$RCSSYS is not a valid value for RCSSYS. See rancid.conf(5)." >&2 - exit 1 -fi - -# the recipient(s) of diffs & mail options -mailrcpt=${mailrcpt:-"rancid-${GROUP}${MAILDOMAIN}"}; export mailrcpt -adminmailrcpt=${adminmailrcpt:-"rancid-admin-${GROUP}${MAILDOMAIN}"}; -export adminmailrcpt -if [ -z "$commitmsg" ] ; then - commitmsg="updates" - if [ $alt_mailrcpt -eq 1 ] ; then - commitmsg="$commitmsg - courtesy of $mailrcpt" - fi - export commitmsg -fi - -# Number of things par should run in parallel. -PAR_COUNT=${PAR_COUNT:-5} -# Number of times failed collections should be retried. Minimum 0. -MAX_ROUNDS=${MAX_ROUNDS:-4} -if [ $MAX_ROUNDS -lt 0 ] ; then - echo "Error: MAX_ROUNDS must be at least 0 or greater." >&2 - MAX_ROUNDS=1 -fi - -# Check for missing configs dir. -if [ ! -d $DIR/configs ] ; then - mkdir $DIR/configs - if [ $? -ne 0 ] ; then - echo "Error: could not create missing configs directory" >&2 - exit - fi - case $RCSSYS in - cvs | svn) - $RCSSYS add configs - ;; - esac -fi - -# create a .cvsignore/.gitignore -case $RCSSYS in -git ) - if [ ! -f .gitignore ] ; then - touch .gitignore - git add .gitignore - else - git ls-files .gitignore --error-unmatch > /dev/null 2>&1 - if [ $? -ne 0 ] ; then - git add .gitignore - fi - fi - rm -rf .gitignore - cat > .gitignore <> .gitignore - fi - ;; -cvs | svn ) - if [ ! -f .cvsignore ] ; then - touch .cvsignore - $RCSSYS add .cvsignore - fi - rm -rf .cvsignore - cat >.cvsignore <> .cvsignore - fi - if [ ! -f configs/.cvsignore ] ; then - touch configs/.cvsignore - $RCSSYS add configs/.cvsignore - fi - rm -rf configs/.cvsignore - cat > configs/.cvsignore <> configs/.cvsignore - fi - if [ $RCSSYS = svn ] ; then - svn propset svn:ignore -F .cvsignore . - svn propset svn:ignore -F configs/.cvsignore configs - svn update . - svn commit -m 'set svn:ignores' . - fi - ;; -esac - -# if there is a rancid.conf, check if it needs to be added to the RCS -if [ -f rancid.conf ] ; then - case $RCSSYS in - cvs ) - cvs log -rHEAD rancid.conf > /dev/null 2>&1 - if [ $? -eq 0 ] ; then LN=1; else LN=0; fi - ;; - svn ) - LN=`(svn ls rancid.conf | wc -l) 2>/dev/null` - ;; - git ) - git ls-files rancid.conf --error-unmatch > /dev/null 2>&1 - if [ $? -eq 0 ] ; then LN=1; else LN=0; fi - ;; - esac - if [ $LN -eq 0 ] ; then - $RCSSYS add rancid.conf - fi -fi - -# do RCS update of router.db in case anyone has fiddled. -case $RCSSYS in -git ) - # git doesnt make this easy. XXX - #git fetch > $TMP 2>&1 - #git checkout FETCH_HEAD -- router.db - #grep "^C" $TMP > /dev/null # XXX right for git? - touch $TMP - ;; -cvs | svn ) - $RCSSYS update router.db > $TMP 2>&1 - grep "^C" $TMP > /dev/null - if [ $? -eq 0 ] ; then - echo "There were $RCSSYS conflicts during update." - echo "" - cat $TMP - rm -f $TMP - exit 1 - fi - ;; -esac -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 "$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 $MAILOPTS - exit 1; -fi - -# IQ test -perl -F\; -ane '{if ($F[0] !~ /^\s*#/ && $F[0] !~ /^\s*$/ && $#F < 2 && $F[0] =~ /:/) {print "WARNING: Have you forgotten to update the FS in router.db?\n"; exit;}}' router.db - -# 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 | -# tr '[A-Z]' '[a-z]' | sort -u > routers.db -perl -ne '{s/^\s*//; s/\s*$//; s/\s*;\s*/;/g; next if (/^(#|;|$)/); - @F = split /\;/; - $F[2] =~ s/\s*\$//; - $F[0] =~ tr@A-Z@a-z@; - if (defined($A{$F[0]})) { - printf STDERR "WARNING: %s appears in routers.db multiple times\n", $F[0]; - next; - } $A{$F[0]} = "$F[1];$F[2]";} - END { foreach $k (sort((keys(%A)))) {print "$k;$A{$k}\n";} }' \ - router.db > routers.db -cut -d\; -f1,2 routers.db > routers.all.new -if [ ! -f routers.all ] ; then touch routers.all; fi -diff -u -4 routers.all routers.all.new > /dev/null 2>&1; RALL=$? -perl -F\; -ane '{$F[2] =~ s/\s*\$//; ($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 -u -4 routers.down routers.down.new > /dev/null 2>&1; RDOWN=$? -perl -F\; -ane '{$F[2] =~ s/\s*\$//; ($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 -u -4 routers.up routers.up.new > /dev/null 2>&1; RUP=$? - -if [ $RALL -ne 0 -o $RDOWN -ne 0 -o $RUP -ne 0 ] ; then - ( - if [ $RUP -ne 0 ] ; then - if [ ! -s routers.up ] ; then - echo Routers changed to up: - sed -e 's/^/ /' routers.up.new - echo - else - WCUP=`comm -13 routers.up routers.up.new | wc -l | \ - sed -e 's/^ *\([^ ]*\)/\1/'` - if [ $WCUP -gt 0 ] ; then - echo Routers changed to up: - comm -13 routers.up routers.up.new | sed -e 's/^/ /' - echo - fi - fi - fi - if [ $RDOWN -ne 0 ] ; then - if [ ! -s routers.down ] ; then - echo Routers changed to down: - sed -e 's/^/ /' routers.down.new - echo - else - WCDOWN=`comm -13 routers.down routers.down.new | wc -l | \ - sed -e 's/^ *\([^ ]*\)/\1/'` - if [ $WCDOWN -eq 1 ] ; then - echo Routers changed to down: - comm -13 routers.down routers.down.new | \ - sed -e 's/^/ /' - echo - fi - fi - fi - if [ $RALL -eq 1 ] ; then - comm -13 routers.all routers.all.new | sed -e 's/^/ /' \ - > routers.added - comm -23 routers.all routers.all.new | sed -e 's/^/ /' \ - > routers.deleted - - WCADDED=`wc -l routers.added | sed -e 's/^ *\([^ ]*\) .*$/\1/'` - WCDELETED=`wc -l routers.deleted | sed -e 's/^ *\([^ ]*\) .*$/\1/'` - - if [ $WCADDED -gt 0 ] ; then - echo Added routers: - cat routers.added - echo - fi - if [ $WCDELETED -gt 0 ] ; then - echo Deleted routers: - cat routers.deleted - echo - fi - - rm -f routers.added routers.deleted - fi - ) > routers.mail - - if [ -s routers.mail ] ; then - ( - echo "To: $adminmailrcpt" - echo "Subject: changes in $GROUP routers" - 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 $MAILOPTS - fi - rm -f routers.mail - - cd $DIR/configs - - # Add new routers to the CVS structure. - for router in `comm -13 $DIR/routers.up $DIR/routers.up.new` - do - OFS=$IFS - IFS=';' - set $router - IFS=$OFS - router=$1 - - touch $router - case $RCSSYS in - cvs ) - cvs add -ko $router - ;; - svn | git ) - $RCSSYS add $router - ;; - esac - $RCSSYS commit -m 'new router' $router - echo "Added $router" - done - echo - cd $DIR - -fi -mv -f routers.all.new routers.all -if [ $? -ne 0 ] ; then - echo "Error: could not rename routers.all.new" >&2 -fi -mv -f routers.down.new routers.down -if [ $? -ne 0 ] ; then - echo "Error: could not rename routers.down.new" >&2 -fi -mv -f routers.up.new routers.up -if [ $? -ne 0 ] ; then - echo "Error: could not rename routers.up.new" >&2 -fi -rm -f routers.db -trap 'rm -fr $TMP;' 1 2 15 - -cd $DIR/configs -# check for 'up' routers missing in RCS. no idea how this happens to some folks -for router in `cut -d\; -f1 ../routers.up` ; do - case $RCSSYS in - cvs ) - cvs status $router | grep -i 'status: unknown' > /dev/null 2>&1 - if [ $? -eq 0 ] ; then - touch $router - cvs add -ko $router - cvs commit -m 'new router' $router - echo "$RCSSYS added missing router $router" - fi - ;; - svn ) - if [ ! -f $router ] ; then - touch $router - fi - svn status $router | grep '^?' > /dev/null 2>&1 - if [ $? -eq 0 ] ; then - svn add $router - svn commit -m 'new router' $router - echo "$RCSSYS added missing router $router" - fi - ;; - git ) - if [ ! -f $router ] ; then - touch $router - fi - git status $router | grep '^?' > /dev/null 2>&1 - if [ $? -eq 0 ] ; then - git add $router - git commit -m 'new router' $router - echo "$RCSSYS added missing router $router" - fi - ;; - esac -done -echo -# 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 -name .cvsignore -prune -o -name .gitignore -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 - case $RCSSYS in - cvs | svn ) - $RCSSYS delete $router - $RCSSYS commit -m "deleted router $router" $router - ;; - git ) - git rm $router - git commit -m "deleted router $router" $router - ;; - esac - echo "Deleted $router" - fi -done -cd $DIR - -# no routers, empty list or all 'down' -if [ ! -s routers.up ] ; then - # commit router.db, etc - message="updates of group $GROUP" - case $RCSSYS in - cvs | svn ) - $RCSSYS commit -m "$message" - ;; - git ) - git add router.db - git commit -am "$message" - git push - ;; - esac - exit; -fi - -# if a device (-r) was specified, see if that device is in this group -if [ "X$device" != "X" ] ; then - trap 'rm -fr $TMP $DIR/routers.single;' 1 2 15 - devlistfile="$DIR/routers.single" - grep -i "^$device\;" routers.up > $devlistfile - if [ $? -eq 1 ] ; then - exit; - fi -else - devlistfile="$DIR/routers.up" -fi - -# Now we can actually try to get the configs -cd $DIR/configs - -# The number of processes running at any given time can be -# tailored to the specific installation. -echo "" -echo "Trying to get all of the configs." -par -q -n $PAR_COUNT -c 'rancid-fe "{}"' $devlistfile - -# This section will generate a list of missed routers -# and try to grab them again. It will run through -# $pass times. -pass=$MAX_ROUNDS -round=1 -if [ -f $DIR/routers.up.missed ] ; then - rm -f $DIR/routers.up.missed -fi -while [ $round -le $pass ] -do - for router in `cat $devlistfile` - do - OFS=$IFS - IFS=';' - set $router - IFS=$OFS - router=$1; mfg=$2 - - if [ ! -s $router.new ] - then - echo "$router;$mfg" >> $DIR/routers.up.missed - rm -f $router.new - fi - done - - if [ -f $DIR/routers.up.missed ] ; then - echo "=====================================" - echo "Getting missed routers: round $round." - par -q -n $PAR_COUNT -c 'rancid-fe "{}"' $DIR/routers.up.missed - rm -f $DIR/routers.up.missed - round=`expr $round + 1` - else - echo "All routers successfully completed." - round=`expr $pass + 1` - fi -done -echo - -# Make sure that no empty/truncated configs are accepted. The remainder are -# renamed from device_name.new -> device_name. -for router in `cat $devlistfile | cut -d\; -f1` -do - if [ ! -s $router.new ] ; then - rm -f $router.new - else - notcomment=`egrep -v "^[-*\!\;#]|\/\*" $router.new | wc -l` - if [ $notcomment -gt 10 ]; then - lines=1; - else - lines=0; - fi - - if [ ! $lines ] ; then - rm -f $router.new - else - mv -f $router.new $router - if [ $? -ne 0 ] ; then - echo "Error: could not rename $router.new to $router" >&2 - rm -f $router.new - fi - fi - fi -done - -# This has been different for different machines... -# Diff the directory and then checkin. -trap 'rm -fr $TMP $TMP.diff $DIR/routers.single;' 1 2 15 -cd $DIR -if [ "X$DIFFSCRIPT" = "X" ]; then - case $RCSSYS in - cvs ) - cvs -f diff -u -4 -ko | sed -e '/^RCS file: /d' -e '/^--- /d' \ - -e '/^+++ /d' -e 's/^\([-+ ]\)/\1 /' >$TMP.diff - ;; - svn | git ) - $RCSSYS diff | sed -e '/^+++ /d' -e 's/^\([-+ ]\)/\1 /' >$TMP.diff - ;; - esac -else - case $RCSSYS in - cvs ) - cvs -f diff -u -4 -ko | (eval $DIFFSCRIPT) 2>&1 >$TMP.diff - ;; - svn | git ) - $RCSSYS diff | (eval $DIFFSCRIPT) 2>&1 >$TMP.diff - ;; - esac -fi - -if [ $alt_mailrcpt -eq 1 ] ; then - subject="router config diffs - courtesy of $mailrcpt" -else - subject="router config diffs" -fi -if [ $RCSSYS = git ] ; then - $RCSSYS commit -am "$commitmsg" -else - $RCSSYS commit -m "$commitmsg" -fi -if [ "X$device" != "X" ] ; then - subject="$GROUP/$device $subject" -else - subject="$GROUP $subject" -fi - -# working-directory maintenance & cleanup every 100 runs -if [ -f "runcount" ] ; then - read RUNCOUNT < ./runcount - RUNCOUNT=`expr $RUNCOUNT + 1` -else - RUNCOUNT=1 -fi -case $RCSSYS in -svn ) - svn cleanup - ;; -git ) - git push - if [ $RUNCOUNT -gt 100 ] ; then - git gc --quiet - RUNCOUNT=0 - fi - ;; -esac -rm -f ./runcount -echo $RUNCOUNT > ./runcount - -# Mail out the diffs (if there are any). -if [ -s $TMP.diff ] ; then - MAXSZ=${MAILSPLIT:=0} - if [ $MAXSZ -ne 0 ] ; then - BLOCKSIZE=1024; export BLOCKSIZE - tmpk=`perl -e "my(@S) = stat(\"$TMP.diff\"); print int(\\$S[7] / 1024);"` - unset BLOCKSIZE - if [ $tmpk -lt $MAXSZ ] ; then - MAXSZ=0 - fi - fi - if [ $MAXSZ -eq 0 ] ; 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 "" - if [ $alt_commitmsg -eq 1 ] ; then - echo "Commit message: $commitmsg" - echo "" - fi - cat $TMP.diff - ) | $SENDMAIL -t $MAILOPTS - else - CDIR=`pwd` - SDIR=${TMPDIR:=/tmp}/rancid.$GROUP.$$.mail - error=`mkdir $SDIR` - if [ $? -ne 0 ] ; then - echo "Could not create $SDIR directory" >&2 - echo $error >&2 - else - cd $SDIR - split -b${MAXSZ}k $TMP.diff - nfiles=`ls | wc -l | sed -e 's/^ *//' |cut -d' ' -f1` - n=0 - dt=`perl -e 'print time();'` - for file in `ls`; do - n=`expr $n + 1` - MSGID="<$dt.RANCID$GROUP$$${nfiles}${n}@`hostname`>" - ( - echo "To: $mailrcpt" - echo "Subject: $n of ${nfiles}: $subject" - echo "Message-Id: $MSGID" - if [ $n -gt 1 ] ; then - echo "References: $LASTIDS" - fi - 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 "" - if [ $alt_commitmsg -eq 1 ] ; then - echo "Commit message: $commitmsg" - echo "" - fi - cat $file - ) | $SENDMAIL -t $MAILOPTS - LASTIDS="$LASTIDS $MSGID" - if [ $n -lt $nfiles ]; then - # this just tries to make the msgs order right in MUAs - sleep 1 - fi - done - cd $CDIR - rm -rf $SDIR - fi - fi -fi - -# If any machines have not been reached within the last $OLDTIME -# hours, mail out a list of them. -cd $DIR/configs -rm -f $DIR/routers.failed -if [ "X$OLDTIME" = "X" ] ; then - OLDTIME=24 -fi -perl -F\; -ane "{\$t = (stat(\$F[0]))[9]; print \`ls -ld \$F[0]\` - if (time() - \$t >= $OLDTIME*60*60);}" $devlistfile | sort -u > $DIR/routers.failed -if [ -s $DIR/routers.failed ] ; then - ( - echo "To: $adminmailrcpt" - echo "Subject: config fetcher problems - $GROUP" - 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." - - cat $DIR/routers.failed - ) | $SENDMAIL -t $MAILOPTS -fi - -# Cleanup -rm -f $TMP.diff $DIR/routers.single $DIR/routers.failed -trap '' 1 2 15 diff --git a/bin/hrancid b/bin/hrancid deleted file mode 100755 index 26da632..0000000 --- a/bin/hrancid +++ /dev/null @@ -1,624 +0,0 @@ -#! /usr/bin/perl -## -## $Id: hrancid.in 3767 2018-02-20 18:13:30Z heas $ -## -## rancid 3.9 -## Copyright (c) 1997-2018 by Henry Kilmer and John Heasley -## All rights reserved. -## -## This code is derived from software contributed to and maintained by -## Henry Kilmer, John Heasley, Andrew Partan, -## Pete Whiting, Austin Schutz, and Andrew Fort. -## -## 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 RANCID 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 Henry Kilmer, John Heasley 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 COMPANY 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. -## -## It is the request of the authors, but not a condition of license, that -## parties packaging or redistributing RANCID NOT distribute altered versions -## of the etc/rancid.types.base file nor alter how this file is processed nor -## when in relation to etc/rancid.types.conf. The goal of this is to help -## suppress our support costs. If it becomes a problem, this could become a -## condition of license. -# -# The expect login scripts were based on Erik Sherk's gwtn, by permission. -# -# The original looking glass software was written by Ed Kern, provided by -# permission and modified beyond recognition. -# -# Amazingly hacked version of Hank's rancid - this one tries to -# deal with HP procurves. -# -# RANCID - Really Awesome New Cisco confIg Differ -# -# usage: hrancid [-dltCV] [-f filename | hostname] -# -use 5.010; -use strict 'vars'; -use warnings; -no warnings 'uninitialized'; -use Exporter; -use Getopt::Std; -our($opt_d, $opt_f, $opt_h, $opt_l, $opt_t, $opt_C, $opt_V); -$opt_t = "hp"; -getopts('dflt:CV'); -BEGIN { - push(@INC, "/home/testranc/lib64/rancid"); -} -use rancid; -our @ISA = qw(Exporter rancid); - -if ($opt_V) { - print "rancid 3.9\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; # hlogin timeout in seconds - -my(@commandtable, %commands, @commands);# command lists -my($aclsort) = ("ipsort"); # ACL sorting mode -my($filter_commstr); # SNMP community string filtering -my($filter_osc); # oscillating data filtering mode -my($filter_pwds); # password filtering mode - -my($systeminfo) = 0; # show system-information -our $cmd; -our @EXPORT = qw($cmd); - -# This routine parses "show config files" -sub ShowConfigFiles { - print STDERR " In ShowConfigFiles: $_" if ($debug); - - while () { - tr/\015//d; - last if (/^$prompt/); - next if (/^(\s*|\s*$cmd\s*)$/); - return(-1) if (/command authorization failed/i); - return(1) if /^(Invalid|Ambiguous) input:/i; - - ProcessHistory("COMMENTS","keysort","H0",";$_"); - } - return(0); -} - -# This routine parses "show version" -sub ShowVersion { - print STDERR " In ShowVersion: $_" if ($debug); - - while () { - tr/\015//d; - last if(/^$prompt/); - next if(/^(\s*|\s*$cmd\s*)$/); - return(-1) if (/command authorization failed/i); - return(-1) if /^(Invalid|Ambiguous) input:/i; - - next if /^uptime/i; - s/^image//i; - s/^\s*//g; - - ProcessHistory("COMMENTS","keysort","C1", ";Image: $_") && next; - } - return(0); -} - -# This routine parses "show flash" -sub ShowFlash { - print STDERR " In ShowFlash: $_" if ($debug); - - while () { - tr/\015//d; - 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 /^\s*\^\s*$/; - - ProcessHistory("COMMENTS","keysort","D0",";Flash: $_"); - } - - return; -} - -# This routine parses "show system-information" or "show system information" -sub ShowSystem { - print STDERR " In ShowSystem: $_" if ($debug); - - if ($systeminfo) { - $_ = ; - return(0); - } - - while () { - tr/\015//d; - last if (/^$prompt/); - next if (/^(\s*|\s*$cmd\s*)$/); - return(-1) if (/command authorization failed/i); - return(0) if /^(Invalid|Ambiguous) input:/i; - return(0) if /^% Unknown command/i; - - 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 && - ProcessHistory("COMMENTS","keysort","C0",";Image: Firmware $1\n"); - /rom\s+version\s+:\s+(\S+)/i && - ProcessHistory("COMMENTS","keysort","C1",";Image: ROM $1\n"); - } - $systeminfo = 1; - - return(0); -} - -# This routine parses "show module". -sub ShowModule { - print STDERR " In ShowModule: $_" if ($debug); - - my(@lines); - my($slot); - - while () { - tr/\015//d; - return if (/^\s*\^$/); - last if (/^$prompt/); - next if (/^(\s*|\s*$cmd\s*)$/); - return(-1) if (/command authorization failed/i); - return(1) if /^(Invalid|Ambiguous) input:/i; - - ProcessHistory("COMMENTS","keysort","E0","; $_") && next; - } - - return(0); -} - -# This routine parses "show stack" -sub ShowStack { - print STDERR " In ShowStack: $_" if ($debug); - - while () { - tr/\015//d; - last if (/^$prompt/); - next if (/^(\s*|\s*$cmd\s*)$/); - return(-1) if (/command authorization failed/i); - return(1) if /^(Invalid|Ambiguous) input:/i; - - s/stacking - (Stacking Status).*/$1/i; - s/\s*members unreachable .*$//i; - next if /^uptime/i; - - ProcessHistory("COMMENTS","keysort","F0",";$_"); - - /auto grab/i && last; - } - return(0); -} - -# This routine parses "show tech transceivers" -sub ShowTechTransceivers { - print STDERR " In ShowTransceivers: $_" if ($debug); - - while () { - tr/\015//d; - last if (/^$prompt/); - next if (/^(\s*|\s*$cmd\s*)$/); - return(-1) if (/command authorization failed/i); - return(1) if /^(Invalid|Ambiguous) input:/i; - - s/ Technical Information//i; - if (/^ATTENTION: You are entering a diagnostic mode/) { - while () { - tr/\015//d; - return(1) if (/^$prompt/); - last if (/^(\s*)$/); - } - next; - } - # KB.16.05.0003 5406R firmware bug - next if (/^\s*show time\s*$/i); - next if (/^\s*\S{3} \S{3}\s+\d+\s+\d+:\d+:\d+\s+\d+\s*$/); - - ProcessHistory("COMMENTS","keysort","G0",";$_"); - } - return(0); -} - -# This routine parses "show config status" -sub ShowConfigStatus { - print STDERR " In ShowConfigStatus: $_" if ($debug); - - while () { - tr/\015//d; - last if (/^$prompt/); - next if (/^(\s*|\s*$cmd\s*)$/); - return(-1) if (/command authorization failed/i); - return(1) if /^(Invalid|Ambiguous) input:/i; - - next if (/^Running configuration is same as /); - next if (/^$/); - - ProcessHistory("COMMENTS","keysort","H0","; $_"); - } - return(0); -} - -# This routine processes a "write term" -sub WriteTerm { - print STDERR " In WriteTerm: $_" if ($debug); - - while () { - tr/\015//d; - if (/$prompt\s*(exit|logout)\s*$/i) { - $clean_run=1; - last; - } - last if(/^$prompt/); - return(-1) if (/command authorization failed/i); - # the pager can not be disabled per-session - s/^<-+ More -+>\s*//; - s/^$/;/; - - # skip the crap - /^running configuration:/i && next; - - # filter out any RCS/CVS tags to avoid confusing local CVS storage - s/\$(Revision|Id):/ $1:/; - /^; (\S+) configuration editor;/i && - ProcessHistory("COMMENTS","keysort","A0",";Chassis type: $1\n") && - ProcessHistory("","","",";\n;Running config file:\n$_") && - next; - - # order logging statements - doesnt appear to do syslog as of right now - /^logging (\d+\.\d+\.\d+\.\d+)/ && - ProcessHistory("LOGGING","ipsort","$1","$_") && next; - - # no so sure this match is correct. show running doesnt seem to - # actually o/p anything after "password (manager|operator)" - if (/^(\s*)password (manager|operator)?/ && $filter_pwds >= 1) { - ProcessHistory("LINE-PASS","","",";$1password $2 \n"); - next; - } - - if (/^(snmp-server community) (\S+)/) { - if ($filter_commstr) { - ProcessHistory("SNMPSERVERCOMM","keysort","$_", - ";$1 $'") && next; - } else { - ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next; - } - } - # order/prune snmp-server host statements - it actually appears to do - # the sortting for us, but just in case it changes ... - # we only prune lines of the form - # snmp-server host a.b.c.d - if (/^snmp-server host (\d+\.\d+\.\d+\.\d+) /) { - if ($filter_commstr) { - my($ip) = $1; - my($line) = "snmp-server host $ip"; - my(@tokens) = split(' ', $'); - my($token); - while ($token = shift(@tokens)) { - if ($token eq 'version') { - $line .= " " . join(' ', ($token, shift(@tokens))); - } elsif ($token =~ /^(informs?|traps?|(no)?auth)$/) { - $line .= " " . $token; - } else { - $line = ";$line " . join(' ', ("", join(' ',@tokens))); - last; - } - } - ProcessHistory("SNMPSERVERHOST","ipsort","$ip","$line\n"); - } else { - ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_"); - } - next; - } - - # order/prune tacacs/radius server statements - if (/^(tacacs-server|radius-server) key / && $filter_pwds >= 1) { - ProcessHistory("","","",";$1 key \n"); - next; - } - if (/^(tacacs-server host \d+\.\S+) key / && $filter_pwds >= 1) { - ProcessHistory("","","",";$1 key \n"); - next; - } - - # prune passwords from stack member statements - if (/^(stack member .* password )\S+/ && $filter_pwds >= 1) { - ProcessHistory("","","",";$1$'"); - next; - } - - # order arp lists - /^ip arp\s+(\d+\.\d+\.\d+\.\d+)/ && - ProcessHistory("ARP","$aclsort","$1","$_") && next; - - /^ip prefix-list\s+(\S+)\s+seq\s+(\d+)\s+(permit|deny)\s+(\d\S+)(\/.*)$/ && - ProcessHistory("PACL $1 $3","$aclsort","$4","ip prefix-list $1 $3 $4$5\n") - && next; - - # blech!!!! - /^auto-tftp / && - ProcessHistory("","","",";$_") && next; - - - # the rest are from rancid (i.e.: cisco), but suspect they will someday - # be applicable or close to it. - - /^tftp-server flash / && next; # kill any tftp remains - /^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|passwd) / && $filter_pwds >= 1) { - ProcessHistory("ENABLE","","",";$1$2 \n"); - next; - } - if (/^username (\S+)(\s.*)? password /) { - if ($filter_pwds >= 1) { - ProcessHistory("USER","keysort","$1",";username $1$2 password \n"); - } else { - ProcessHistory("USER","keysort","$1","$_"); - } - next; - } - - if (/^(ip ftp password) / && $filter_pwds >= 1) { - ProcessHistory("","","",";$1 \n"); next; - } - if (/^( ip ospf authentication-key) / && $filter_pwds >= 1) { - ProcessHistory("","","",";$1 \n"); next; - } - if (/^( ip ospf message-digest-key \d+ md5) / && $filter_pwds >= 1) { - ProcessHistory("","","",";$1 \n"); next; - } - # sort route-maps - if (/^route-map (\S+)/) { - my($key) = $1; - my($routemap) = $_; - while () { - tr/\015//d; - last if (/^$prompt/ || ! /^(route-map |[ !])/); - if (/^route-map (\S+)/) { - ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); - $key = $1; - $routemap = $_; - } else { - $routemap .= $_; - } - } - ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); - } - # order access-lists - /^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ && - ProcessHistory("ACL $1 $2","$aclsort","$3","$_") && next; - # order extended access-lists - /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+host\s+(\S+)/ && - ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; - /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+(\d\S+)/ && - ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; - /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+any/ && - ProcessHistory("EACL $1 $2","$aclsort","0.0.0.0","$_") && next; - - # order alias statements - /^alias / && ProcessHistory("ALIAS","keysort","$_","$_") && next; - # delete ntp auth password - if (/^(ntp authentication-key \d+ md5) / && $filter_pwds >= 1) { - ProcessHistory("","","",";$1 \n"); next; - } - # order ntp peers/servers - if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) { - my($sortkey) = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5); - ProcessHistory("NTP","keysort",$sortkey,"$_"); - next; - } - # order ip host line statements - /^ip host line(\d+)/ && - ProcessHistory("IPHOST","numsort","$1","$_") && next; - # order ip nat source static statements - /^ip nat (\S+) source static (\S+)/ && - ProcessHistory("IP NAT $1","ipsort","$2","$_") && next; - # order ip rcmd lines - /^ip rcmd/ && ProcessHistory("RCMD","keysort","$_","$_") && next; - - # catch anything that wasnt match above. - ProcessHistory("","","","$_"); - } - return(0); -} - -# Main -rancidinit(); - -@commandtable = ( - {'show version' => 'ShowVersion'}, - {'show flash' => 'ShowFlash'}, - {'show system-information' => 'ShowSystem'}, - {'show system information' => 'ShowSystem'}, - {'show module' => 'ShowModule'}, - {'show stack' => 'ShowStack'}, - {'show tech transceivers' => 'ShowTechTransceivers'}, - {'show config files' => 'ShowConfigFiles'}, - {'show config status' => 'ShowConfigStatus'}, - {'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); -$commandcnt = scalar(keys %commands); - -$commandstr=join(";",@commands); -$cmds_regexp = join("|", map quotemeta($_), @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); - } -} -if ($opt_C) { - print "hlogin -t $timeo -c\'$commandstr\' $host\n"; - exit(0); -} -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 || $log); - open(INPUT,"<$host") || die "open failed for $host: $!\n"; -} else { - print(STDERR "executing hlogin -t $timeo -c\"$commandstr\" $host\n") if ($debug || $log); - if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { - system "hlogin -t $timeo -c \"$commandstr\" $host $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 \"$commandstr\" $host ) { - tr/\015//d; - if (/$prompt\s*(exit|logout)\s*$/i) { - $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; - $prompt .= "[#>]"; - print STDERR ("PROMPT MATCH: $prompt\n") if ($debug); - } - print STDERR ("HIT COMMAND:$_") if ($debug); - if (! defined($commands{$cmd})) { - print STDERR "$host: found unexpected command - \"$cmd\"\n"; - $clean_run = 0; - last TOP; - } - my($rval) = &{$commands{$cmd}}(*INPUT, *OUTPUT, $cmd); - delete($commands{$cmd}); - if ($rval == -1) { - $clean_run = 0; - last TOP; - } - } -} -print STDOUT "Done $lscript: $_\n" if ($log); -# Flush History -ProcessHistory("","","",""); -# Cleanup -close(INPUT); -close(OUTPUT); - -if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { - unlink("$host.raw") if (! $debug); -} - -# check for completeness -if (scalar(%commands) || !$clean_run) { - if (scalar(keys %commands) eq $commandcnt) { - printf(STDERR "$host: missed cmd(s): all commands\n"); - } elsif (scalar(%commands)) { - my($count, $i) = 0; - for ($i = 0; $i < $#commands; $i++) { - if ($commands{$commands[$i]}) { - if (!$count) { - printf(STDERR "$host: missed cmd(s): %s", $commands[$i]); - } else { - printf(STDERR ", %s", $commands[$i]); - } - $count++; - } - } - if ($count) { - printf(STDERR "\n"); - } - } - if (!$clean_run) { - print(STDERR "$host: End of run not found\n"); - if ($debug) { - print(STDERR "$host: clean_run is false\n") if (!$clean_run); - print(STDERR "$host: found_end is false\n") if (!$found_end); - } - system("/usr/bin/tail -1 $host.new"); - } - unlink "$host.new" if (! $debug); -}