#!/bin/sh
#
# bb-page1.sh
# BIG BROTHER PAGER SCRIPT
# Sean MacGuire - The MacLawran Group Inc.
# Version 1.4
# Mar 05th, 2000
#
# This program is Copyright (c) 1997-2000
# The MacLawran Group Inc.
# All Rights Reserved
#
# Format: bb-page1.sh <NUMERIC-MESSAGE> <ALPHA-MESSAGE>
#
# Modified to be generic front-end for all paging systems
# and gets all info out of etc/bbdef.sh file
#

#
# Changed 970111 by Jacob Lundqvist jaclu@ibk.se
#
#  Included working SMS and improved NUMERIC paging
#  
#  Now kermit attempts are queued!
#

if test "$#" = "1"	# CALLED AS A SINGLE ARG FROM bbd
then
	set -f
	set $1		# PUT ARGS INTO ENVIRONMENT
	# 2ND ARGUMENT IS THE FILE NAME WHERE THE MESSAGE IS SAVED
	PAGEMSG=$2
	set $1 `cat $2` # PUT ALL ERROR MSG INTO ENV
	set +f
fi

if test "$#" -lt "2"	# IF THERE AREN'T AT LEAST TWO ARGUMENTS
then
	echo "bb-page1.sh:	Incorrect number of arguments"
	echo "Format:		bb-page1.sh <NUMERIC-MESSAGE> <ALPHA-MESSAGE>"
	exit 1
fi

BBNUMERIC=`echo $1 | $SED 's/[^0-9.]//g'`	# THE NUMERIC MESSAGE
shift;
BBALPHA="`$CAT $PAGEMSG`"		# THE ALPHA MESSAGE
BBHOSTSVC=`echo "$1" | $SED 's/[^A-Za-z0-9.\,_-]//g'`
BBCOLORLEVEL=$2

# Build the real numeric, BBHOSTIP is required for HOST notification
OLDIFS=$IFS
IFS='.'
set $BBNUMERIC
BBSVCNUM=$1
BBHOSTIP=$2
BBNUMERIC=${BBSVCNUM}${BBHOSTIP}

# Build a copy of the host.service name is ',' delimited format
# IFS is still '.'
set $BBHOSTSVC
BBHOSTSVCCOMMAS="$1"
shift
while [ "$#" -gt 1 ]
do
	BBHOSTSVCCOMMAS=${BBHOSTSVCCOMMAS},$1
	BBHOSTSVCDOTS=${BBHOSTSVCDOTS}.$1
	shift
done
BBSVCNAME=$1
BBHOSTSVCCOMMAS=${BBHOSTSVCCOMMAS}.$1
# Reset IFS
IFS=$OLDIFS

if test ! "$BBTMP" 			# GET DEFINITIONS IF NEEDED
then
	. $BBHOME/etc/bbdef.sh          # INCLUDE STANDARD DEFINITIONS
fi

#
# GET THE NUMERIC PREFIX/SUFFIX TO DIAL
#

PREFIX=""
prefixline=`$GREP "^prefix:" $BBHOME/etc/bbwarnsetup.cfg` 2>/dev/null
if [ "$?" -eq 0 ]
then
	set $prefixline >/dev/null 2>&1
	if [ "$#" -gt 1 ]
	then
		shift           # remove prefix token from line
		PREFIX="$*"
	fi      
fi

SUFFIX=""
suffixline=`$GREP "^suffix:" $BBHOME/etc/bbwarnsetup.cfg` 2>/dev/null
if [ "$?" -eq 0 ]
then
	set $suffixline >/dev/null 2>&1
	if [ "$#" -gt 1 ]
	then
		shift           # remove suffix token from line
		SUFFIX="$*"
	fi      
fi

#
# GET THE PAGEDELAY VALUE
#

PAGEDELAY=15
pagedelayline=`$GREP "^pagedelay:" $BBHOME/etc/bbwarnsetup.cfg` 2>/dev/null
if [ "$?" -eq 0 ]
then
	set $pagedelayline >/dev/null 2>&1
	if [ "$#" -gt 1 ]
	then
		shift           # remove pagedelay token from line
		param="$1"
		# Check if it's a valid parameter
		$EXPR "$param" + 0 >/dev/null 2>&1
		if [ "$?" -eq 0 ]
		then
			PAGEDELAY="$param"
		fi
	fi      
fi

#
# GET PAGELEVELSMAIL
#

PAGELEVELSMAIL="nocolordefined"
# Apr 29 99 - Bug fix by SALAPATI@altera.com
pagelevelsmailline=`$GREP "^pagelevelsmail:" $BBHOME/etc/bbwarnsetup.cfg` 2>/dev/null
if [ "$?" -eq 0 ]
then
	set $pagelevelsmailline >/dev/null 2>&1
	if [ "$#" -gt 1 ]
	then
		shift           # remove pagelevelsmail token from line
		param="$*"

		# Check if it's a valid parameter, remove bad values

		for color in $param
		do
			case $color in

			yellow | red | purple )

				if [ "$PAGELEVELSMAIL" = "nocolordefined" ]
				then
					PAGELEVELSMAIL="$color"
				else
					PAGELEVELSMAIL="$PAGELEVELSMAIL | $color"
				fi
				;;

			* )
				;;

			esac
		done
	fi      
fi

#
# GET PAGETYPE
# THIS CODE IS ALSO IN bb-doack.sh
# ANY CHANGES HERE MUST BE DONE THERE

PAGETYPE="RCPT"
pagetypeline=`$GREP "^pagetype:" $BBHOME/etc/bbwarnsetup.cfg` 2>/dev/null
if [ "$?" -eq 0 ]
then
	set $pagetypeline >/dev/null 2>&1
	if [ "$#" -gt 1 ]
	then
		shift           # remove pagertype token from line
		param="$1"

		# Check if it's a valid parameter, 
		# Set it if it's valid

		case $param in

		RCPT | GROUP | HOST | EVENT )

			PAGETYPE=$param
			;;

		* )
			;;

		esac
	fi      
fi

#
# Add the HTML status path to email notification ?
#                
PAGEADDHTMLPATH=TRUE		# Default is TRUE
pageaddhtmlpathline=`$GREP "^pageaddhtmlpath:" $BBHOME/etc/bbwarnsetup.cfg` 2>/dev/null
if [ "$?" -eq 0 ] 
then                    
        set $pageaddhtmlpathline >/dev/null 2>&1
        if [ "$#" -gt 1 ]
        then    
                shift           # remove pagedelay token from line
                PAGEADDHTMLPATH="$1"      
        fi              
fi                              

# Create a file that contains all the group/hosts relationships
if [ "$PAGETYPE" = "GROUP" ]
then
	# Get the service name
	OLDIFS=$IFS
	IFS="."
	set $BBHOSTSVC
	shift `$EXPR $# - 1`
	svc=$1
	IFS=$OLDIFS

	# Build a file with group/hosts tag
	$RM -f $BBTMP/BBGRP.$$
	gblgrp="global-grp"
	currgrp=$gblgrp
	# Read all entries of bb-hosts file
	$CAT $BBHOSTS | $GREP -v "^#" |
	while read line
	do
		# Is it a host definition ?
		hostsline=`echo "$line" | $GREP "^[0-9]" 2>/dev/null`
		if [ "$?" -eq 0 ]
		then
			set $hostsline
			if [ "$FQDN" != "TRUE" ]
			then
				OLDIFS=$IFS
				IFS="."
				set $2
				IFS=$OLDIFS
			else
				# Position at the host name
				shift
			fi
			echo "$currgrp $1.$svc" >> $BBTMP/BBGRP.$$
		else
			# Is it a group definition ?
			grpline=`echo "$line" | $GREP "^group" 2>/dev/null`
			if [ "$?" -eq 0 ]
			then
				set $grpline
				shift
				currgrp=`echo $* | $SED 's/[^a-zA-Z0-9]//g'`
				if [ "$currgrp" = "" ]
				then
					currgrp=$gblgrp
				fi
			fi
		fi
	done

	# At this point there must be at least one entry
	# in the $BBGRP.$$ file
	grpline=`$GREP $BBHOSTSVC $BBTMP/BBGRP.$$` 2>/dev/null
	if [ "$?" -eq 0 ]
	then
		set $grpline
		bbgroup=$1
	else
		# Just in case that nothing matches set in global group
		bbgroup=$gblgrp
	fi
	$RM -f $BBTMP/BBGRP.$$
fi

#
# NOW WE DECIDE HOW TO HANDLE THINGS
# PAGERS CONTAINS A LIST OF PAGERS TO CALL, ARGS AS FOLLOWS
#
#	NUMBER 		SEND DUMB OLDNUMERIC MESSAGE
#	XXX@YYYY	SEND e-mail TO THIS ADDRESS
#	sms-NUMBER 	SEND sms MESSAGE
#	alpha-NUMBER	SEND alpha MESSAGE
#
# EXAMPLE:
#
# 	PAGERS="123123 sean@MacLawran.ca sms-123123"
# 	THIS SHOULD SEND A NUMERIC PAGE TO 123123, 
#	MAIL TO sean@MacLawran.ca
# 	AND AN SMS-PAGE TO 123123
#
# SMM 1.07c: CHANGED THE if STATEMENTS TO A case STATEMENT
#	SHOULD BE MUCH EASIER TO MODIFY NOW.
#

pagefilepfx="np_"

# Remove recipients that have an np_* file associated with them
# but haven't been notified because they are in the state of
# an initial delay or the waiting period before been escalated to
if [ "$RECOVERED" = "TRUE" ]
then
	NEWPAGER=""
	for inpage in `echo $PAGERS`
	do
		OLDIFS=$IFS
		IFS=':'
		set $inpage
		rcpt=$1
		IFS=$OLDIFS

		# Only notify the recipients that have already been notified
		for file in  $BBTMP/${pagefilepfx}${rcpt}*
		do
			$GREP "$rcpt" $file | $GREP "$BBHOSTSVC" | $GREP -v "0000000" >/dev/null 2>&1
			if [ "$?" -eq 0 ]
			then
				NEWPAGER="$NEWPAGER $rcpt"
				break
			fi
		done
	done
	PAGERS="$NEWPAGER"
fi

rcptnum=10			# Start at 10, no need for leading zeros
for inpage in `echo $PAGERS`		# FOR EACH PAGERS ARGUMENT...
do

	#
	# SMM: NEW IN 1.05 - PAGE ONLY IF THE REQUIRED PAGEDELAY
	# HAS PASSED ALREADY...
	#
	# SMM: NEW IN 1.08a - AND ISN'T FROM THE BBDISPLAY PAGE BUTTON
	# Thanks to: "Eric J. Frisch" <efrisch@magi.com>
	#

	# IS there an overiding PAGEDELAY value ?
	OLDIFS=$IFS
	IFS=':'
	set $inpage
	page=$1
	IFS=$OLDIFS

	echo $BBNUMERIC | $GREP "^${PAGEHELPCODE}" > /dev/null
	if [ $? != 0 -a "$RECOVERED" != "TRUE" ]
	then
		$BBHOME/bin/touchtime 0  ${BBTMP}/timenow.$$

		# Notification tagfile always has the recipient
		pagefile="${pagefilepfx}${page}"
		if [ "$PAGETYPE" = "EVENT" ]
		then
			pagefile="${pagefile}_${BBNUMERIC}"
		elif [ "$PAGETYPE" = "GROUP" ]
		then
			pagefile="${pagefile}_${bbgroup}"
		elif [ "$PAGETYPE" = "HOST" ]
		then
			pagefile="${pagefile}_${BBHOSTIP}"
		fi

		# Thanks to Khoi Dinh <dinh@nas.nasa.gov>
		# who found out that $FIND $BBTMP won't work on a symbolic link
		# RAC found the simple fix: $BBTMP/*
		$FIND $BBTMP/* -name "${pagefile}" -newer ${BBTMP}/timenow.$$ -print | $GREP "${pagefile}" > /dev/null 2>&1
		retcode=$?
		$RM -f  ${BBTMP}/timenow.$$
		if test $retcode = 0
		then
			# echo "Page delay not expired... page cancelled..."
			continue
		fi

		# Create Ack number
		# Process ID + recipient ID (10-99)
		# processes id are zero filled, this allows easy
		# checking for invalid ack numbers in bb-ack.html
		# by using $num == `$EXPR $num + 0`
		# AIX PID's can be > 99999, so make sure < 100000
		pid=`$EXPR $$ % 100000`
		if [ "$pid" -lt 10 ]
		then
			randval="${pid}0000${rcptnum}"
		elif [ "$pid" -lt 100 ]
		then
			randval="${pid}000${rcptnum}"
		elif [ "$pid" -lt 1000 ]
		then
			randval="${pid}00${rcptnum}"
		elif [ "$pid" -lt 10000 ]
		then
			randval="${pid}0${rcptnum}"
		else
			randval="${pid}${rcptnum}"
		fi	

		# 
		#
		# IT'S OK TO PAGE, SO SET THE TIME WE CAN SEND THE NEXT ONE...
		#
		DELAY=$PAGEDELAY
		shift >/dev/null 2>&1
		if [ "$#" -gt 0 ]	# Is there another arg ?
		then
			# now, parse PAGEDELAY arg
			# can be:
			# XX Next page after XX minutes
			# ~ is initial delay
			# ~XX First page after XX minutes, then page every PAGEDELAY minutes
			# ~XX-YY First page after XX and page every YY minutes
			# ^ is escalation
			# !XX First page after XX minutes, then page every PAGEDELAY minutes
			# !XX-YY First page after XX and page every YY minutes
			# ^ is an escalation procedure while ~ is an initial delay
			# the difference is that acknowledgements will reset the initial delay
			# (if another recipient acknoledges for all recipients) 
			# while the escalation delay is not changed

			case $1 in

				[0-9]* )
					delay=$1
					;;

				# it didn't like [^~][0-9]* or [^\~][0-9]* 
				[\~\^][0-9]* )

					OLDIFS=$IFS

					case $1 in
 		                               \^[0-9]* )
							IFS='\^'
							DELAYTYPE=ESCALATION
							;;
                		               \~[0-9]* )
							IFS='\~'
							DELAYTYPE=INITIAL
							;;
					esac

					# remove ~^! from specification
					set $1             
					IFS=$OLDIFS

					# just make sure that the set did not create an empty 1st argument
					if [ -z "$1" ]
					then
						shift
					fi

					case $1 in

						# [~^]XX-YY format
						[0-9]*-[0-9]* )

							OLDIFS=$IFS     
							IFS='-'
							set $1
							initdelay=$1
							delay=$2
							IFS=$OLDIFS

							;;

						# [~^]XX format
						*)
							initdelay=$1
							delay=$PAGEDELAY
							;;
					esac

					# 
					# Are there any np_* file for this escalated recipient ?
					# if so, is it about the same problem ?
					# if so, is has the previous notification expired less than 10 minutes ago
					# if so, time to notify again
					# if not, it's the initial escalation

					$BBHOME/bin/touchtime -10  ${BBTMP}/timenow.$$

					# Thanks to Khoi Dinh <dinh@nas.nasa.gov>
					# who found out that $FIND $BBTMP won't work on a symbolic link
					# RAC found the simple fix: $BBTMP/*
					$FIND $BBTMP/* -name "${pagefile}" -newer ${BBTMP}/timenow.$$ -print | $GREP "${pagefile}" > /dev/null 2>&1
					retcode=$?
					$RM -f  ${BBTMP}/timenow.$$
					if [ "$retcode" -ne 0 ]
					then
						# echo "initial notification delayed by $initdelay minutes
						# set up a dumb ack # so nobody can ack this delay
						# the remainder of the data is required to remove the
						# file after the problem has been fixed
			                        INITDELAY=`echo $initdelay|$SED 's/[0-9]//g'`
                        			if [ -n "$INITDELAY" ]  # Was delay properly formed ?
                        			then
							echo "bb-page1.sh: Delay in bbwarnrules.cfg file is invalid for **$inpage**"
                        			else
							if [ "$DELAYTYPE" = "INITIAL" ]
							then
								echo "${randval}0000000 $BBHOSTSVC $BBCOLORLEVEL $page" > ${BBTMP}/${pagefile}
							else
								echo "0000000 $BBHOSTSVC $BBCOLORLEVEL $page" > ${BBTMP}/${pagefile}
							fi
							$BBHOME/bin/touchtime $initdelay "$BBTMP/${pagefile}"
						fi
						continue
					fi	
					;;

				*)
					echo "recipient **$inpage** in bbwarnrules.cfg is invalid/incorrect"
					continue
			esac

			TESTDELAY=`echo $delay|$SED 's/[0-9]//g'`
			if [ -n "$TESTDELAY" ]	# Was delay properly formed ?
			then
				DELAY=$PAGEDELAY
				echo "bb-page1.sh: Delay in bbwarnrules.cfg file is invalid for **$inpage** using $DELAY"
			else
				DELAY=$delay
			fi
		fi

		echo "$randval $BBHOSTSVC $BBCOLORLEVEL $page" > ${BBTMP}/${pagefile}
		$BBHOME/bin/touchtime $DELAY ${BBTMP}/${pagefile}
		rcptnum=`$EXPR $rcptnum + 1`
	fi

	if [ "$RECOVERED" = "TRUE" ]
	then
		randval=0000000
	fi

	if [ "$randval" != "" ]
	then
		randvaltag="[$randval] "
		randvalsubjtag=" - $randval"
	else
		randvaltag=""
		randvalsubjtag=""
	fi

	if [ "$PAGEADDHTMLPATH" = "TRUE" ]
	then
		case $BBHOSTSVC in

		notify-admin* | unmatched-* )

			htmllink=""
			;;

		* )


			case $BBLOGSTATUS
			in
				STATIC )
					htmllink="

Please see: ${BBWEBHTMLLOGS}${BBHOSTSVC}.html"
					;;

				DYNAMIC )
					htmllink="

Please see: ${CGIBINURL}/bb-hostsvc.sh?HOSTSVC=${BBHOSTSVCCOMMAS}"

					;;

				TEXT )
					htmllink="

Please see: ${BBWEB}/logs/${BBHOSTSVCCOMMAS}"
					;;

				* )
					# Default is TEXT
					htmllink="

Please see: ${BBWEB}/logs/${BBHOSTSVCCOMMAS}"
					;;
			esac
		esac
	else
		htmllink=""
	fi

        if [ "$RECOVERED" = "TRUE" ] 
        then
                notiflog="$BBHOME/www/acks/recoverymsgs.log" 
                set ${BBALPHA}
                shift `$EXPR $# - 2`
                DOWNSECS="-- Event Duration: $1 seconds"
        else 
                notiflog="$BBHOME/www/acks/notifications.log"
                DOWNSECS=""
        fi

	BBALPHAMSG="${randvaltag}${BBALPHA}${htmllink}"
               
	#
	# Should the current recipient receive a brief message
	#                
	briefrcptline=`$GREP "^briefrcpt:" $BBHOME/etc/bbwarnsetup.cfg` 2>/dev/null
	if [ "$?" -eq 0 ] 
	then                    
       		echo "$briefrcptline" | $GREP "$page" >/dev/null 2>&1
		if [ "$?" -eq 0 ] 
        	then
			BBALPHAMSG="${BBHOSTSVC} - ${BBNUMERIC}
${htmllink}"
        	fi              
	fi                              

	case $BBCOLORLEVEL in

	$PAGELEVELSMAIL )

		# Send only e-mail for if the status message color matches one
		# color in PAGELEVELSMAIL (set in bbwarnsetup.cfg)

		case $page in

		*@* )		# echo "EMAIL"		# NOTIFY BY e-mail
				echo "${BBALPHAMSG}" | $MAIL "!BB${randvalsubjtag}! $BBHOSTSVC - $BBNUMERIC" "$page"
				echo "`$DATE` $BBHOSTSVC ($BBHOSTIP) $page `$BBHOME/bin/touchtime -e` $BBSVCNUM $DOWNSECS" >> $notiflog
				;;
		* )
				# Color should only be sent by mail and this recipient isn't mail ...
				;;
		esac
		;;

	* )

		case $page in

		*@* )		# echo "EMAIL"		# NOTIFY BY e-mail
				echo "${BBALPHAMSG}" | $MAIL "!BB${randvalsubjtag}! $BBHOSTSVC - $BBNUMERIC" "$page"
				echo "`$DATE` $BBHOSTSVC ($BBHOSTIP) $page `$BBHOME/bin/touchtime -e` $BBSVCNUM $DOWNSECS" >> $notiflog
				;;

		[0-9]* )	# echo "NUMERIC PAGING"
				$BBHOME/bin/sendmsg $BBHOME/etc/numeric.scr ${PREFIX}$page ${BBNUMERIC}${randval}${SUFFIX}
				echo "`$DATE` $BBHOSTSVC ($BBHOSTIP) $page `$BBHOME/bin/touchtime -e` $BBSVCNUM $DOWNSECS" >> $notiflog
				;;

		sms-* )		# echo "SMS"
				set `echo $page | $SED "s/-/ /"`
				NUMBER=$2
				#
				# Message must be stored in a file, 
				# for the sms kermit script
				#
				SMSFILE=${BBTMP}/sms-$$
				echo "${BBALPHAMSG}" > $SMSFILE
				#
				# Note!!!
				# =======
				# If you use a dialing prefix, it must be manually set in
				# sms.scr
				# Here we only send the numbers to page, not the paging
				# server
				#
				$BBHOME/bin/sendmsg $BBHOME/etc/sms.scr $SMSFILE $NUMBER
				echo "`$DATE` $BBHOSTSVC ($BBHOSTIP) $page `$BBHOME/bin/touchtime -e` $BBSVCNUM $DOWNSECS" >> $notiflog
				$RM -f $SMSFILE
				;;

		alpha-* )	# echo "ALPHA PAGING"
				# SMM BB 1.3 - ALPHA PAGING SUPPORT
				# ARGS BASED ON qpage http://qpage.org
				# MUST BE SET IN etc/bbinc.sh
				#
				if test -x "$ALPHAPGR"
				then
					set `echo $page | $SED "s/-/ /"`
					PGRCODE=$2
					$ALPHAPGR $PGRCODE "${BBALPHAMSG}"
					echo "`$DATE` $BBHOSTSVC ($BBHOSTIP) $page `$BBHOME/bin/touchtime -e` $BBSVCNUM $DOWNSECS" >> $notiflog
				fi
				;;

		qp-* )		# Qpage notification
				# RAC BB 1.3 -  Qpage PAGING SUPPORT
				# QPAGE/QPAGEUSER MUST BE SET IN etc/bbsys.sh or etc/bbsys.local
				# Based on code by Mike Volk <Mike_Volk@pupress.princeton.edu>
                		#
				if test -x "$QPAGE"
				then
					set `echo $page | $SED "s/-/ /"`
					# set the From field to bb and send page to user
					PAGERUSER="${QPAGEARGS} -p $2"
					echo ${BBALPHAMSG} | $QPAGE $PAGERUSER
					echo "`$DATE` $BBHOSTSVC ($BBHOSTIP) $page `$BBHOME/bin/touchtime -e` $BBSVCNUM $DOWNSECS" >> $notiflog
				else
					echo "<$QPAGE> was not found"
				fi
				;;

		sp-* )		# sendpage notification
				# RAC BB 1.3 -  sendpage PAGING SUPPORT
				# SENDPAGE MUST BE SET IN etc/bbsys.sh or etc/bbsys.local
				# Thanks to  Josh Rivel <jrivel@dti.net>  & others
                		#
				if test -x "$SENDPAGE"
				then
					set `echo $page | $SED "s/-/ /"`
					# set the From field to bb and send page to user
					PAGERUSER="${SENDPAGEARGS} $2"
					echo ${BBALPHAMSG} | $SENDPAGE $PAGERUSER
					echo "`$DATE` $BBHOSTSVC ($BBHOSTIP) $page `$BBHOME/bin/touchtime -e` $BBSVCNUM $DOWNSECS" >> $notiflog
				else
					echo "<$SENDPAGE> was not found"
				fi
				;;

		* )		# echo "DEFAULT"
				;;
		esac
		;;
	esac
done

exit $?
