#!/bin/bash
if [[ "$1" == 'debug'  ]]; then set -x;		_DEBUG=$1; shift; fi
if [[ "$1" == 'debug2' ]]; then set -xvT;	_DEBUG=$1; shift; fi
if [[ "$1" == 'trace'  ]]; then 		_TRACE=$1; shift; fi
####################################################################
declare -Ax watchermap

#-------------------------------------------------------------------
# - watcher -
# Master startup for log watchers 
# Shoot-up watcher modules & run dynloaders once for fresh external
# firewall data ...
#-------------------------------------------------------------------
REALPATH=`realpath $0`
WHERE=`dirname $REALPATH`
ME=`basename $REALPATH`
cd $WHERE
export MASTER_PATH=$WHERE
watchermap[master_path]=$MASTER_PATH

export WATCHER_MODE=startup	# Not for resale!;i.e. does'nt go to watchermap
#-------------------------
. $MASTER_PATH/system.conf
. $MASTER_PATH/watcher.conf	# Note: Thats me, don't call twice!
. $MASTER_PATH/common.conf
. $MASTER_PATH/common.bashlib
. $MASTER_PATH/watcher.bashlib	# pick our private bashlib

watchermap[product]=$PRODUCT
watchermap[revision]=$REVISION
watchermap[log_dir]=$LOG_DIR
watchermap[fifo_base]=$FIFO_BASE
watchermap[pool]=$POOL

trap cleanup 0 1 2 9 15
cleanup() {
local funtag="[${FUNCNAME[0]}]"
	logger "$ME[$$]: Terminating - Startup job done"
}

get_count() {
local funtag="[${FUNCNAME[0]}]"
local	lists="`ipset -n list`"
local	number l
local	total=0

	for l in $lists
	do
		number=`ipset -t list $l | grep '^Number' | cut -f2 -d":"`
		(( total += $number ))
	done
	echo $total
}

#
### Dump the watchermap to the Watcher world
#
dump_map() {
local funtag="[${FUNCNAME[0]}]"
local	k

	echo "#$funtag Autogenerated Watcher Map - $(date +%F\ %T)"
	for k in "${!watchermap[@]}"
	do echo "${k^^}=${watchermap[$k]}"
	done
} > $MASTER_PATH/watchermap.conf


echo "$PRODUCT V$REVISION ... Running on $SYSTEM $SYSVERS $HOSTNAME"
: echo "Language $LANG, LC_ALL: $LC_ALL"

rm -f RAMDISK
if [ -n "$USE_RAMDISK" ]
then
	already=`df -lh | grep $RDNAME`
	if [ -z "$already" ]
#	then 	/mkramdisk
	then	mkramdisk
	else	echo "RAMdisk: |$already|"
	fi

	if [ -n "$USE_RDCOPIES" ]
	then
		if [ ! -d $POOL/bin ]; then mkdir -m 700 -p $POOL/bin; fi

		for c in `echo $RDCOPIES`
		do
			if [ ! -f $POOL/bin/$c ]
			then cp `which $c` $POOL/bin
			fi	
		done

		export POOLBIN=$POOL/bin
		watchermap[poolbin]=$POOLBIN

		export PATH=$POOLBIN:$PATH
		watchermap[path]=$PATH

		export IPSET=ipset
		watchermap[ipset]=$IPSET

		# Having the PATH extended to prefer RAMDisk copies
		# we can link them in ...
		for c in `echo $RDCOPIES`
		do watchermap[_$c]=$(which $c)
		done
	fi

	if [ -e RAMDISK ]
	then
		watchermap[ramdisk]=$POOL
		watchermap[rdname]=$RDNAME
		watchermap[rdsize]=$RDSIZE
	else
		watchermap[ramdisk]="-"
		watchermap[rdname]="-"
		watchermap[rdsize]="-"
	fi
fi

# Let tools and modules know where we are
# `locate MASTER_PATH' and cat on the result are the same ...
echo $WHERE > MASTER_PATH

#
# Put tools in place
#
if [ ! -d $TOOLS_LINK ]; then mkdir -m 750 -p $TOOLS_LINK; fi

# Provide the tools in $TOOLSLINK
# 'TOOLS' are defined in watcher.conf
for tool in `echo $TOOLS`
do ln -sf $MASTER_PATH/bin/$tool $TOOLS_LINK
done

DYNLOADERS="`echo dynload/*`"
MODSINSTALLED="`echo modules/*`"
echo
echo -n "Present DynLoaders: "
for d in `echo $DYNLOADERS`
do echo -n "`basename $d` "
done
echo

echo -n "Present Modules   : "
for m in `echo $MODSINSTALLED`
do echo -n "`basename $m` "
done
echo

logger "$ME[$$]: Starting ..."
sleep 1 	# To supress a silly div-by-zero!

mk_watchercounters
#bin/Blackouts	# Experimental/Temporary

#########################################
# Loader section
#########################################
echo
echo "Loading firewall '$FIREWALL' ..."
FILL_START=`date +%s%N`
./FillFW
FILL_END=`date +%s%N`

Blacklist
Whitelist
mk_myrouters

count=`get_count`
diff=`echo "scale=3; ($FILL_END-$FILL_START)/10^9" | bc`
rate=`echo "$count/$diff" | bc`

printf "\t%8s %8.4f seconds\n" "Took" $diff
printf "\t%8s %8d total firewall records\n" "for" $count
printf "\t%8s %8d records per second\n" "Loadrate" $rate


####################################################
# Module startups
####################################################
dump_map	# Provide watchermap to components

#
## Everything is prepared ...
## Fire up modules after firewall is loaded
#
if [ ! -d $FIFO_BASE ]
then mkdir -m 700 -p $FIFO_BASE
fi

for mod in $MODULES
do
#	STARTMOD="Watch"$mod
	STARTMOD=$mod
	MODPATH=modules/$STARTMOD
	if [ ! -d modules/$STARTMOD ]
	then 	echo "$mod configured but $STARTMOD _not_ installed"
		echo "... skipping ..."
		continue
	else
		if [ ! -p $FIFO_BASE/$STARTMOD ]
		then mkfifo -m 600 $FIFO_BASE/$STARTMOD
		fi

		echo "Starting module $STARTMOD ..."
		# Fork module into background ...
		### Do not start modules with 'nohup' any longer
		### or the filter refresh triggered by a HUP
		### signal does not work!
		### Use pure and simple backgrounding!
		# nohup $MODPATH/$STARTMOD >/dev/null 2>&1 &
		$MODPATH/$STARTMOD >/dev/null 2>&1 &
	fi
done

echo "`date +%s`" > START_TIME

#
# First of all after modules were started ...
#
dump_runtime

# Fire some external tools ...
./.poststart
