#!/bin/bash

### BEGIN INIT INFO
# Provides:          poc
# Required-Start:    autossh mosquitto
# Required-Stop:     autossh mosquitto
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: pocsag transceiver plugin
# Description:       pocsag transceiver plugin
### END INIT INFO

# Return values acc. to LSB for all commands but status:
# 0 - success
# 1 - misc error
# 2 - invalid or excess args
# 3 - unimplemented feature (e.g. reload)
# 4 - insufficient privilege
# 5 - program not installed
# 6 - program not configured
# 7 - program is not running
#
# Note that starting an already running service, stopping
# or restarting a not-running service as well as the restart
# with force-reload (in case signalling is not supported) are
# considered a success.

# Config-Datei einlesen
source /usr/local/smi/trx/etc/poc.conf

myname=$(echo $0 | $awk -F/ '{ print $NF }')

start_daemon()
{
	# Prüfen ob Daemon bereits läuft
	instances=0
	#for runVAR in $ttyToListenTo; do
	k=1
	while [ -n "$(eval echo '$'PocTtyToBind_${k}_name)" ]; do
		runVAR="$(eval echo '$'PocTtyToBind_${k}_name)"
		trxtype="$(eval echo '$'PocTtyToBind_${k}_trxtype)"
		if [ -e "${rundir}/${myname}.${trxtype}.rx.${runVAR}.pid" ]; then ((instances++)); fi
		((k++))
	done
	if [ ! $instances -gt '0' ]; then
		echo -n "Starting ${myname}... "
		# Start des Skripts im Logfile vermerken
		log "$myname" "$myname" "--------------------------"
		log "$myname" "$myname" "Start ${myname} begonnen"

		# Prüfen ob benötigte Binaries vorhanden sind
		missedfiles=0
		log "$myname" "$myname" "prüfe Existenz nötiger Programme"
		test_if_exist=()
		test_if_exist+=($stty)
		test_if_exist+=($awk)
		test_if_exist+=($jq)
		test_if_exist+=($bc)
		test_if_exist+=($base64)
		test_if_exist+=($md5sum)
		#test_if_exist+=($poc_program)
		test_if_exist+=($mosquitto_pub)	
		test_if_exist+=($mosquitto_sub)
		#test_if_exist+=($bindir/${myname}/$devicereader)
		#test_if_exist+=($bindir/${myname}/$devicewriter)
		#test_if_exist+=($bindir/${myname}/$PocMonitor)
		for i in "${!test_if_exist[@]}"; do
			if [ -e "${test_if_exist[$i]}" ]; then
				log "$myname" "$myname" "  found: \"${test_if_exist[$i]}\""
			else
				log "$myname" "$myname" "  missed: \"${test_if_exist[$i]}\""
				((missedfiles++))
			fi
		done
		if (( $missedfiles > 0 )); then
			log "$myname" "$myname" "failed"
			echo "failed!"
			#stop_daemon
			exit 5
		fi
		log "$myname" "$myname" "done"

		log "$myname" "$myname" "initialisiere serielle Schnittstellen"
		# für alle seriellen Interfaces im configfile (PocSerialDev_X_name)
		ret=0
		ret_serialinit=0
		i=1
		while [ -n "$(eval echo '$'PocSerialDev_${i}_name)" ]; do
			# Initialisierungskommandos ausführen
			j=1
			while [ -n "$(eval echo '$'PocSerialDev_${i}_init_${j})" ]; do
				$(eval echo '$'PocSerialDev_${i}_init_${j}) > /dev/null 2>&1
				ret=$?
				# ein fehlgeschlagenes Initialisierungskommando wird einmal wiederholt (weil stty nach einem Rechner-Neustart beim 1. Aufruf fehlschlägt)
				if (( $ret > 0 ));then
					$(eval echo '$'PocSerialDev_${i}_init_${j}) > /dev/null 2>&1
						ret=$?
				fi
				ret_serialinit=$(($ret_serialinit+$ret))
				((j++))
			done
                
			# Wenn Initialisierung nicht erfolgreich war
			if (( $ret_serialinit > 0 )); then
				# Fehlermeldung ins Logfile schreiben und Skript beenden
				log "$myname" "$myname" "  failed: \"$(eval echo '$'PocSerialDev_${i}_name)\""
			else
				log "$myname" "$myname" "  ok: \"$(eval echo '$'PocSerialDev_${i}_name)\""
			fi
			((i++))
		done
		if (( $ret_serialinit > 0 )); then
			log "$myname" "$myname" "Start ${myname} failed"
			log "$myname" "$myname" "--------------------------"
			echo "failed!"
			exit 1
		fi
		log "$myname" "$myname" "done"

		# userdefinierbare Initialisierungskommandos ausführen
		ret=0
		ret_userinit=0
		l=1
		while [ -n "$(eval echo '$'PocUserinit_${l})" ]; do
			log "$myname" "$myname" "\"$(eval echo '$'PocUserinit_${l}) start\""
			"$(eval echo '$'PocUserinit_${l})" start > /dev/null 2>&1
			ret=$? 
			ret_userinit=$(($ret_userinit+$ret))
			log "$myname" "$myname" "\"$(eval echo '$'PocUserinit_${l}) start\" done"
			((l++))
		done
		# Wenn Initialisierung nicht erfolgreich war
		if (( $ret_userinit > 0 )); then
			# Fehlermeldung ins Logfile schreiben und Skript beenden
			log "$myname" "$myname" "Stop! Userdefinierbares Init-Kommando fehlgeschlagen"
			echo "failed!"
			stop_daemon
			exit 1
		fi

		# Whitelist-Directories erstellen und Whitelist-Einträge laden
		log "$myname" "$myname" "creating allow/deny list directories"
		if ([ -e "$PocAllowRxConfdir" ] && [ -n "$usePocAllowRx" ]); then
			if !([ -e "$PocAllowRxRundir" ]); then
				log "$myname" "$myname" "  creating \"$PocAllowRxRundir\""
				mkdir -p "$PocAllowRxRundir"
				#log "$myname" "$myname" "done"
			fi
			for file in $(find $PocAllowRxConfdir -maxdepth 1 -xtype f); do
				log "$myname" "$myname" "    loading list entries from \"$file\""
				while read -r line; do
					touch "$PocAllowRxRundir/$(echo $line | awk -F: '{ print $1 }')"
				done < "$file"
				#log "$myname" "$myname" "done"
			done
		fi
		if ([ -e "$PocAllowTxConfdir" ] && [ -n "$usePocAllowTx" ]); then
			if !([ -e "$PocAllowTxRundir" ]); then
				log "$myname" "$myname" "  creating \"$PocAllowTxRundir\""
				mkdir -p "$PocAllowTxRundir"
				#log "$myname" "$myname" "done"
			fi
			for file in $(find $PocAllowTxConfdir -maxdepth 1 -xtype f); do
				log "$myname" "$myname" "    loading list entries from \"$file\""
				while read -r line; do
					touch "$PocAllowTxRundir/$(echo $line | awk -F: '{ print $1 }')"
				done < "$file"
				#log "$myname" "$myname" "done"
			done
		fi
		if ([ -e "$PocDenyRxConfdir" ] && [ -n "$usePocDenyRx" ]); then
			if !([ -e "$PocDenyRxRundir" ]); then
				log "$myname" "$myname" "  creating \"$PocDenyRxRundir\""
				mkdir -p "$PocDenyRxRundir"
				#log "$myname" "$myname" "done"
			fi
			for file in $(find $PocDenyRxConfdir -maxdepth 1 -xtype f); do
				log "$myname" "$myname" "    loading list entries from \"$file\""
				while read -r line; do
					touch "$PocDenyRxRundir/$(echo $line | awk -F: '{ print $1 }')"
				done < "$file"
				#log "$myname" "$myname" "done"
			done
		fi
		if ([ -e "$PocDenyTxConfdir" ] && [ -n "$usePocDenyTx" ]); then
			if !([ -e "$PocDenyTxRundir" ]); then
				log "$myname" "$myname" "  creating \"$PocDenyTxRundir\""
				mkdir -p "$PocDenyTxRundir"
				#log "$myname" "$myname" "done"
			fi
			for file in $(find $PocDenyTxConfdir -maxdepth 1 -xtype f); do
				log "$myname" "$myname" "    loading list entries from \"$file\""
				while read -r line; do
					touch "$PocDenyTxRundir/$(echo $line | awk -F: '{ print $1 }')"
				done < "$file"
				#log "$myname" "$myname" "done"
			done
		fi
		log "$myname" "$myname" "done"

		# auf jedem konfigurierten Interface Read-Spooler, Write-Spooler, fdtpoc und Decoder-Init starten 
		k=1
		while [ -n "$(eval echo '$'PocTtyToBind_${k}_name)" ]; do
			runVAR="$(eval echo '$'PocTtyToBind_${k}_name)"
			trxtype="$(eval echo '$'PocTtyToBind_${k}_trxtype)"
	 
			log "$myname" "$myname" "starte Read-Logger auf \"$runVAR\""
			cp "$poc_program/$devicelogger" "$rundir/$myname.$devicelogger.$devicereader.$runVAR"
			start-stop-daemon --start --quiet --pidfile "$rundir/$myname.$devicelogger.$devicereader.$runVAR.pid" --make-pidfile --background --exec  "$rundir/$myname.$devicelogger.$devicereader.$runVAR"
			log "$myname" "$myname" "done"
	 
			log "$myname" "$myname" "starte Read-Spooler auf \"$runVAR\""
			cp "$poc_program/$devicereader" "$rundir/$myname.$devicereader.$runVAR"
			start-stop-daemon --start --quiet --pidfile "$rundir/$myname.$devicereader.$runVAR.pid" --make-pidfile --background --exec  "$rundir/$myname.$devicereader.$runVAR"
			log "$myname" "$myname" "done"
  
			log "$myname" "$myname" "starte Write-Logger auf \"$runVAR\""
			cp "$poc_program/$devicelogger" "$rundir/$myname.$devicelogger.$devicewriter.$runVAR"
			start-stop-daemon --start --quiet --pidfile "$rundir/$myname.$devicelogger.$devicewriter.$runVAR.pid" --make-pidfile --background --exec  "$rundir/$myname.$devicelogger.$devicewriter.$runVAR"
			log "$myname" "$myname" "done"
  
			log "$myname" "$myname" "starte Write-Spooler auf \"$runVAR\""
			cp "$poc_program/$devicewriter" "$rundir/$myname.$devicewriter.$runVAR"
			start-stop-daemon --start --quiet --pidfile "$rundir/$myname.$devicewriter.$runVAR.pid" --make-pidfile --background --exec  "$rundir/$myname.$devicewriter.$runVAR"
			log "$myname" "$myname" "done"

			log "$myname" "$myname" "starte ${trxtype}.rx auf \"$runVAR\""
			cp "${poc_program}/${trxtype}.rx" "${rundir}/${myname}.${trxtype}.rx.$runVAR"
			start-stop-daemon --start --quiet --pidfile "${rundir}/${myname}.${trxtype}.rx.$runVAR.pid" --make-pidfile --background --exec  "${rundir}/${myname}.${trxtype}.rx.$runVAR"
			log "$myname" "$myname" "done"
			
			log "$myname" "$myname" "\"${poc_program}/${trxtype}.init start $runVAR\""
			"${poc_program}/${trxtype}.init" start $runVAR &
			
			((k++))
		done

		# Cronjob für regular run skript anlegen
		log "$myname" "$myname" "erstelle Cronjob für monitor skript"
		echo "*/1 *    * * *   root	${poc_program}/${PocMonitor} >/dev/null 2>&1" > "$crondir/${myname}"

		log "$myname" "$myname" "Start ${myname} abgeschlossen"
		log "$myname" "$myname" "--------------------------"
		echo "done!"
	else
		echo "Daemon is still running! Nothing to do."
	fi
}

stop_deamon()
{
	echo -n "Stopping ${myname}... "
	log "$myname" "$myname" "--------------------------"
	log "$myname" "$myname" "Stop ${myname} begonnen"

	# Cronjob löschen, der beim Starten angelegt wurde
	if [ -e "$crondir/${myname}" ]; then
		log "$myname" "$myname" "lösche Cronjob für monitor skript"
		rm -f "$crondir/${myname}"
		log "$myname" "$myname" "done"
	fi

	# auf allen konfigurierten Interfaces
	l=1
	while [ -n "$(eval echo '$'PocTtyToBind_${l}_name)" ]; do
		runVAR="$(eval echo '$'PocTtyToBind_${l}_name)"
		trxtype="$(eval echo '$'PocTtyToBind_${l}_trxtype)"

		# Schnittstelleninitialisierungsskript mit "stop" ausführen
		log "$myname" "$myname" "\"${bindir}/${myname}/${trxtype}.init stop $runVAR\""
		"${bindir}/${myname}/${trxtype}.init" stop $runVAR &

		# Read-Spooler beenden
		if [ -e "$rundir/$myname.$devicereader.$runVAR.pid" ]; then
			pid=$(cat "$rundir/$myname.$devicereader.$runVAR.pid")
			log "$myname" "$myname" "beende Read-Spooler auf \"$runVAR\" mit PID \"$pid\""
			for k in $(pstree -p $(echo $pid) | sed 's/(/\n(/g' | grep '(' | sed 's/(\(.*\)).*/\1/' | tr "\n" " "); do
				kill $k > /dev/null 2>&1
			done
			rm -f "$rundir/$myname.$devicereader.$runVAR"
			rm -f "$rundir/$myname.$devicereader.$runVAR.pid"
			log "$myname" "$myname" "done"
		fi
		
		# Read-Logger beenden
		if [ -e "$rundir/$myname.$devicelogger.$devicereader.$runVAR.pid" ]; then
			pid=$(cat "$rundir/$myname.$devicelogger.$devicereader.$runVAR.pid")
			log "$myname" "$myname" "beende Read-Logger auf \"$runVAR\" mit PID \"$pid\""
			for k in $(pstree -p $(echo $pid) | sed 's/(/\n(/g' | grep '(' | sed 's/(\(.*\)).*/\1/' | tr "\n" " "); do
				kill $k > /dev/null 2>&1
			done
			rm -f "$rundir/$myname.$devicelogger.$devicereader.$runVAR"
			rm -f "$rundir/$myname.$devicelogger.$devicereader.$runVAR.pid"
			log "$myname" "$myname" "done"
		fi		

		# Write-Spooler beenden
		if [ -e "$rundir/$myname.$devicewriter.$runVAR.pid" ]; then
			pid=$(cat "$rundir/$myname.$devicewriter.$runVAR.pid")
			log "$myname" "$myname" "beende Write-Spooler auf \"$runVAR\" mit PID \"$pid\""
			for k in $(pstree -p $(echo $pid) | sed 's/(/\n(/g' | grep '(' | sed 's/(\(.*\)).*/\1/' | tr "\n" " "); do
				kill $k > /dev/null 2>&1
			done
			rm -f "$rundir/$myname.$devicewriter.$runVAR"
			rm -f "$rundir/$myname.$devicewriter.$runVAR.pid"
			log "$myname" "$myname" "done"
		fi
		
		# Write-Logger beenden
		if [ -e "$rundir/$myname.$devicelogger.$devicewriter.$runVAR.pid" ]; then
			pid=$(cat "$rundir/$myname.$devicelogger.$devicewriter.$runVAR.pid")
			log "$myname" "$myname" "beende Write-Logger auf \"$runVAR\" mit PID \"$pid\""
			for k in $(pstree -p $(echo $pid) | sed 's/(/\n(/g' | grep '(' | sed 's/(\(.*\)).*/\1/' | tr "\n" " "); do
				kill $k > /dev/null 2>&1
			done
			rm -f "$rundir/$myname.$devicelogger.$devicewriter.$runVAR"
			rm -f "$rundir/$myname.$devicelogger.$devicewriter.$runVAR.pid"
			log "$myname" "$myname" "done"
		fi

		# Hauptprogramm beenden
		if [ -e "${rundir}/${myname}.${trxtype}.rx.$runVAR.pid" ]; then
			pid=$(cat "${rundir}/${myname}.${trxtype}.rx.$runVAR.pid")
			log "$myname" "$myname" "beende ${trxtype}.rx auf \"$runVAR\" mit PID \"$pid\""
			for k in $(pstree -p $(echo $pid) | sed 's/(/\n(/g' | grep '(' | sed 's/(\(.*\)).*/\1/' | tr "\n" " "); do
				kill $k > /dev/null 2>&1
			done
			rm -f "${rundir}/${myname}.${trxtype}.rx.$runVAR"
			rm -f "${rundir}/${myname}.${trxtype}.rx.$runVAR.pid"
			log "$myname" "$myname" "done"
		fi
		
		# Status Files löschen
		log "$myname" "$myname" "deleting status files for \"$runVAR\""
		if [ -e "$rundir/$runVAR.last_vital" ]; then
			log "$myname" "$myname" "  \"$rundir/$runVAR.last_vital\""
			rm -f "$rundir/$runVAR.last_vital"
		fi		
		if [ -e "$rundir/$runVAR.inode" ]; then
			log "$myname" "$myname" "  \"$rundir/$runVAR.inode\""
			rm -f "$rundir/$runVAR.inode"
		fi
		log "$myname" "$myname" "done"
		
		((l++))
	done

	# allow/deny list Verzeichnisse löschen
	log "$myname" "$myname" "deleting allow/deny list directories"
	if [ -e "$PocAllowRxRundir" ]; then
		log "$myname" "$myname" "  \"$PocAllowRxRundir\""
		rm -rf "$PocAllowRxRundir"
	fi
	if [ -e "$PocAllowTxRundir" ]; then
		log "$myname" "$myname" "  \"$PocAllowTxRundir\""
		rm -rf "$PocAllowTxRundir"
	fi
	if [ -e "$PocDenyRxRundir" ]; then
		log "$myname" "$myname" "  \"$PocDenyRxRundir\""
		rm -rf "$PocDenyRxRundir"
	fi
	if [ -e "$PocDenyTxRundir" ]; then
		log "$myname" "$myname" "  \"$PocDenyTxRundir\""
		rm -rf "$PocDenyTxRundir"
	fi
	log "$myname" "$myname" "done"

	# userdefinierbares Init-Skript beim Stop ausführen
	l=1
	while [ -n "$(eval echo '$'PocUserinit_${l})" ]; do
		log "$myname" "$myname" "\"$(eval echo '$'PocUserinit_${l}) stop\""
		"$(eval echo '$'PocUserinit_${l})" stop > /dev/null 2>&1
		log "$myname" "$myname" "\"$(eval echo '$'PocUserinit_${l}) stop\" done"
		((l++))
	done
	
	log "$myname" "$myname" "Stop ${myname} abgeschlossen"
	log "$myname" "$myname" "-------------------------"
	echo "done!"
	
 }

 status_daemon(){
	# Prüfen ob Daemon bereits läuft
	instances=0
	k=1
	while [ -n "$(eval echo '$'PocTtyToBind_${k}_name)" ]; do
		runVAR="$(eval echo '$'PocTtyToBind_${k}_name)"
		trxtype="$(eval echo '$'PocTtyToBind_${k}_trxtype)"
		if [ -e "${rundir}/${myname}.${trxtype}.rx.${runVAR}.pid" ]; then ((instances++)); fi
		((k++))
	done
	if [ $instances -gt '0' ]; then
		echo "Daemon is running"
	else
		echo "Daemon is not running"
	fi
 }

case "$1" in
	start)
		start_daemon
		;;
	stop)
		stop_deamon
		;;
	restart)
		stop_deamon
		start_daemon
		;;
	status)
		status_daemon
		;;
	*)
		echo "Usage: $0 {start|stop|restart|status}" >&2
		exit 2
esac
exit 0
