#!/usr/bin/env sh
###############################################################################
#   afick_cron
#      it's a part of the afick project
#
#    Copyright (C) 2002, 2003 by Eric Gerbier
#    Bug reports to: eric.gerbier@tutanota.com
#    $Id$
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
###############################################################################
# script for cron job
# this script use the "macro" lines of afick configuration file
# the goals are :
# - set the nice priority
# - truncate too long reports to avoid big mails
# - avoid mails if no changes detected
# - sent report to the specicified email adress
# - write reports to /var/log/afick
# - archive retention management

AFICK="/usr/bin/afick.pl"
PATH="/bin:/usr/bin"
LOGDIR="/var/log/afick"
LOGFILE="$LOGDIR/afick.log"
ERRORLOG="$LOGDIR/error.log"
CONFFILE="/etc/afick.conf"

# the default action is "update" (-u), you can also use "compare" (-k)
ACTION="-u"

###############################################################################
treat_log() {
	if [ -n "$VERBOSE_AFICK" ]
	then
		echo "# This is an automated report generated by Another File Integrity Checker on $FQDN $DATE."
	fi

	# "normal" afick output : changes result
	if [ -s $LOGFILE ]; then
		loglines=`wc -l $LOGFILE | awk '{ print $1 }'`
		if [ ${loglines:=0} -gt $LINES ]; then
			echo "# TRUNCATED (!) output of the daily afick run:"
			echo "# Output is $loglines lines, truncated to $LINES."
			head -$LINES $LOGFILE
			echo "# The full output can be found in $LOGFILE."
		else
			echo "# Output of the daily afick run:"
			cat $LOGFILE
		fi
	elif [ -n "$VERBOSE_AFICK" ]
	then
		echo "# afick detected no changes."
	fi

	# afick errors
	if [ -s $ERRORLOG ]; then
		errorlines=`wc -l $ERRORLOG | awk '{ print $1 }'`
		if [ ${errorlines:=0} -gt $LINES ]; then
			echo "# TRUNCATED (!) output of errors produced:"
			echo "# Error output is $errorlines lines, truncated to $LINES."
			head -$LINES $ERRORLOG
			echo "# The full output can be found in $ERRORLOG."
		else
			echo "# Errors produced:"
			cat $ERRORLOG
		fi
	elif [ -n "$VERBOSE_AFICK" ]
	then
		echo "# afick produced no errors."
	fi

	# check end of report (summary)
	if [ -s $LOGFILE ]; then
		summary=` grep "MD5 hash of" $LOGFILE `
		if [ -z "$summary" ]
		then
			echo "WARNING: truncated report (no summary)"
		fi
	fi

}
###############################################################################
# extract macro value from config file
macro () {
	key=$1
	grep -m 1 "^@@define $key" $CONFFILE |  sed -e "s/^@@define $key *//"
}
###############################################################################
send_mail() {
	echo "$OUTPUT" | mail -s "[AFICK] Daily report for $FQDN" $MAILTO
}
###############################################################################
send_nagios() {
	NAGIOS_STATUS=3 # UNKNOWN initial status
	if [ -s $LOGFILE ]
	then
		NAGIOS_MSG=`tail -4 $LOGFILE | head -1 | sed -e "s/^[^0-9]*\(.*changed\) (.*$/\1/ "`
		NUM_CHANGES=`echo $NAGIOS_MSG | cut -d " " -f 4`
		if [ $NUM_CHANGES -gt 0 ]
		then
			if [ $NUM_CHANGES -ge $NAGIOS_CRITICAL_CHANGES ]
			then
				NAGIOS_STATUS=2 # CRITICAL
			else
				NAGIOS_STATUS=1 # WARNING
			fi
		else
			NAGIOS_STATUS=0 # OK
		fi
	fi
	HOST=`hostname`
	echo "${HOST}\t${NAGIOS_CHECK_NAME}\t${NAGIOS_STATUS}\t${NAGIOS_MSG}\n" | $NAGIOS_NSCA -H $NAGIOS_SERVER -c $NAGIOS_CONFIG >/dev/null
}
###############################################################################
# MAIN
###############################################################################

[ -x $AFICK ] || exit 0

# hostname -f only exists on GNU systems, 
# on others (HPUX, AIX, Solaris, Tru64), it return an error on stderr 
# and a usage message on stdout
FQDN=`( hostname -f  || hostname ) 2>/dev/null |tail -1`
DATE=`date +"at %X on %x"`
MAILTO=`macro MAILTO`
LINES=`macro LINES`
VERBOSE=`macro VERBOSE`
REPORT=`macro REPORT`
NICE=`macro NICE`
BATCH=`macro BATCH`
MOUNT=`macro MOUNT`
NAGIOS=`macro NAGIOS`
NAGIOS_SERVER=`macro NAGIOS_SERVER`
NAGIOS_CONFIG=`macro NAGIOS_CONFIG`
NAGIOS_CHECK_NAME=`macro NAGIOS_CHECK_NAME`
NAGIOS_CRITICAL_CHANGES=`macro NAGIOS_CRITICAL_CHANGES`
NAGIOS_NSCA=`macro NAGIOS_NSCA`
ARCHIVE_RETENTION=`macro ARCHIVE_RETENTION`

# default values
[ -z "$FQDN" ] && FQDN=`hostname`
[ -z "$MAILTO" ] && MAILTO="root"
[ -z "$LINES" ] && LINES="1000"
[ -z "$VERBOSE" ] && VERBOSE=0
[ -z "$REPORT" ] && REPORT=1
[ -z "$NICE" ] && NICE=15
[ -z "$BATCH" ] && BATCH=1
[ -z "$NAGIOS" ] && NAGIOS=0
[ -z "$NAGIOS_SERVER" ] && NAGIOS="localhost"
[ -z "$NAGIOS_CONFIG" ] && NAGIOS_CONFIG="/etc/send_nsca.cfg"
[ -z "$NAGIOS_CHECK_NAME" ] && NAGIOS_CHECK_NAME="Another File Integrity Checker"
[ -z "$NAGIOS_CRITICAL_CHANGES" ] && NAGIOS_CRITICAL_CHANGES=2
[ -z "$NAGIOS_NCSA" ] && NAGIOS_NCSA="/usr/sbin/send_nsca"
[ -z "$ARCHIVE_RETENTION" ] && ARCHIVE_RETENTION=0

#echo "MAILTO=$MAILTO LINES=$LINES VERBOSE=$VERBOSE NICE=$NICE BATCH=$BATCH"

if [ "$BATCH" = "0" ]
then
	exit 0
fi

if [ "$VERBOSE" = "1" ]
then
	# verbose mail
	export VERBOSE_AFICK=1
fi

# the mount point must be already defined in /etc/fstab
if [ -n "$MOUNT" ]
then
	mount $MOUNT
fi

# launch command
nice -n $NICE $AFICK -c $CONFFILE $ACTION > $LOGFILE 2> $ERRORLOG

# archive retention
if [ "$ARCHIVE_RETENTION" != "0" ]
then
	echo "###############" >> $LOGFILE
	echo "# afick_archive" >> $LOGFILE
	/usr/bin/afick_archive.pl -c $CONFFILE -H -k $ARCHIVE_RETENTION >> $LOGFILE 2>> $ERRORLOG
fi

if [ -n "$MOUNT" ]
then
	umount $MOUNT
fi

# nagios ?
if [ "$NAGIOS" = "1" ]
then
	send_nagios
fi

if [ "$REPORT" = "0" ]
then
	# no report
	exit
fi

# filter output to send by mail
OUTPUT=`treat_log`
if [ "$VERBOSE" = "1" ]
then
	send_mail
else
	# skip comments and empty lines
	OUTPUT_FILTRE=`echo "$OUTPUT" | grep -v "^#" | grep -v "^$"`
	if [ -n "$OUTPUT_FILTRE" ]
	then
		send_mail
	fi
fi
