#! /bin/sh
##
## $Id: rancid-run.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.
#
# Run rancid for each of the rancid groups defined by $LIST_OF_GROUPS in
# /etc/rancid/rancid.conf or those specified on the command-line.
#

# Default ENVFILE, overrideable with -f flag.
ENVFILE="/etc/rancid/rancid.conf"

TMPDIR=${TMPDIR:=/tmp}; export TMPDIR

# control_rancid argv
CR_ARGV=""; export CR_ARGV

# print a usage message to stderr
pr_usage() {
    echo "usage: $0 [-V] [-c commit_msg] [-f config_file] [-r device_name] [-m mail rcpt] [group [group ...]]" >&2;
}

# command-line options
# -V
# -c <SCM commit msg>
# -f <config file name>
# -m <mailto address>
# -r <device name>
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
	    CR_ARGV="$CR_ARGV -c \"$1\""; export CR_ARGV
	    shift
	    ;;
	-f)
	    shift
	    # next arg is the alternate config file name
	    ENVFILE="$1"
	    if [ -z $ENVFILE ]; then
		pr_usage
		exit 1
	    fi
	    CR_ARGV="$CR_ARGV -f $1"; export CR_ARGV
	    shift
	    ;;
	-m)
	    shift
	    # next arg is the mailto name
	    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;
	    ;;
	-h)
	    pr_usage
	    exit
	    ;;
	-*)
	    echo "unknown option: $1" >&2
	    pr_usage
	    exit 1
	    ;;
	*)
	    break;
	    ;;
	esac
    done
fi

. $ENVFILE

# SENDMAIL location
SENDMAIL=${SENDMAIL:=sendmail};

if [ $# -ge 1 ] ; then
    LIST_OF_GROUPS="$*"; export LIST_OF_GROUPS
elif [ "$LIST_OF_GROUPS" = "" ] ; then
    echo "LIST_OF_GROUPS is empty in $ENVFILE"
    exit 1
fi

# LOGDIR location
LOGDIR=${LOGDIR:=$BASEDIR/logs};
if [ ! -d $LOGDIR ] ; then
    mkdir -p $LOGDIR || (echo "Could not create log directory: $LOGDIR" >&2;
			 exit 1)
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
	    GRPOLDFILE=`mktemp -q $TMPDIR/.$GROUP.XXXXXX`
	    if [ $? -ne 0 ] ; then
		echo "Could not create temporary file for error email" >&2
		exit 1
	    fi
	    perl -e "\$t = (stat(\"$LOCKFILE\"))[9]; print \"OLD\\n\" if (time() - \$t >= $LOCKTIME*60*60);" > $GRPOLDFILE
	    if [ -s $TMPDIR/.$GROUP.old ]
	    then
		(
		  echo "To: rancid-admin-${GROUP}${MAILDOMAIN}"
		  echo "Subject: rancid hung - $GROUP"
		  echo "Precedence: bulk"
		  echo "Auto-submitted: auto-generated"
		  echo "X-Auto-Response-Suppress: All"
		  echo ""

		  cat <<END
rancid $GROUP hung on `hostname`?  Old lockfile still exists:
`ls -l $LOCKFILE`
END
		) | $SENDMAIL -t $MAILOPTS
	    fi
	    rm -f $GRPOLDFILE
	    exit 1
	else
	    trap 'rm -fr $LOCKFILE;exit 1' 1 2 3 6 10 15
	    perl -e 'use POSIX;sysopen(FH, $ARGV[1], O_RDWR|O_CREAT|O_EXCL, 0660) or exit 1;print FH "$ARGV[0]\n";' -- $$ $LOCKFILE
	    if [ $? -eq 0 ] ; then
		sh -c "control_rancid $CR_ARGV $GROUP"
		trap ''  1 2 3 6 10 15
		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
