#!/bin/bash

### BEGIN INIT INFO
# Provides:          fdtsds
# Required-Start:    autossh mosquitto
# Required-Stop:     autossh mosquitto
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: fdtsds
# Description:       fdtsds
### 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/sds.conf

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

start_daemon()
{	# Debug
	#ls -la /dev |grep -e "-> tty" >> $logfile

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

		# Prüfen ob benötigte Binaries vorhanden sind
		missedfiles=0
		log "$myname" "prüfe Existenz nötiger Programme"
		test_if_exist=()
		test_if_exist+=($stty)
		test_if_exist+=($mysql)
		test_if_exist+=($awk)
		#test_if_exist+=($sds_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}/$SdsMonitor)
		for i in "${!test_if_exist[@]}"; do
			if [ -e "${test_if_exist[$i]}" ]; then
				log "$myname" "  found: \"${test_if_exist[$i]}\""
			else
				log "$myname" "  missed: \"${test_if_exist[$i]}\""
				((missedfiles++))
			fi
		done
		if (( $missedfiles > 0 )); then
			log "$myname" "failed"
			echo "failed!"
			#stop_daemon
			exit 5
		fi
		log "$myname" "done"
		
		log "$myname" "initialisiere serielle Schnittstellen"
		# für alle seriellen Interfaces im configfile (SdsSerialDev_X_name)
		ret=0
		ret_serialinit=0
		i=1
		while [ -n "$(eval echo '$'SdsSerialDev_${i}_name)" ]; do
			# Initialisierungskommandos ausführen
			j=1
			while [ -n "$(eval echo '$'SdsSerialDev_${i}_init_${j})" ]; do
				$(eval echo '$'SdsSerialDev_${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 '$'SdsSerialDev_${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" "  failed: \"$(eval echo '$'SdsSerialDev_${i}_name)\""
			else
				log "$myname" "  ok: \"$(eval echo '$'SdsSerialDev_${i}_name)\""
			fi
			((i++))
		done
		if (( $ret_serialinit > 0 )); then
			log "$myname" "Start ${myname} failed"
			log "$myname" "--------------------------"
			echo "failed!"
			exit 1
		fi
		log "$myname" "done"
		
		# userdefinierbare Initialisierungskommandos ausführen
		ret=0
		ret_userinit=0
		l=1
		while [ -n "$(eval echo '$'SdsUserinit_${l})" ]; do
			log "$myname" "\"$(eval echo '$'SdsUserinit_${l}) start\""
			"$(eval echo '$'SdsUserinit_${l})" start > /dev/null 2>&1
			ret=$? 
			ret_userinit=$(($ret_userinit+$ret))
			log "$myname" "\"$(eval echo '$'SdsUserinit_${l}) start\" done"
			((l++))
		done
		# Wenn Initialisierung nicht erfolgreich war
		if (( $ret_userinit > 0 )); then
			# Fehlermeldung ins Logfile schreiben und Skript beenden
			log "$myname" "Stop! Userdefinierbares Init-Kommando fehlgeschlagen"
			echo "failed!"
			stop_daemon
			exit 1
		fi
		
		# Whitelist-Directories erstellen und Whitelist-Einträge laden
		log "$myname" "creating allow/deny list directories"
		if ([ -e "$SdsAllowRxConfdir" ] && [ -n "$useSdsAllowRx" ]); then
			if !([ -e "$SdsAllowRxRundir" ]); then
				log "$myname" "  creating \"$SdsAllowRxRundir\""
				mkdir -p "$SdsAllowRxRundir"
			fi
			for file in $(find $SdsAllowRxConfdir -maxdepth 1 -xtype f); do
				log "$myname" "    loading list entries from \"$file\""
				while read -r line; do
					touch "$SdsAllowRxRundir/$(echo $line | awk -F: '{ print $1 }')"
				done < "$file"
			done
		fi
		if ([ -e "$SdsAllowTxConfdir" ] && [ -n "$useSdsAllowTx" ]); then
			if !([ -e "$SdsAllowTxRundir" ]); then
				log "$myname" "  creating \"$SdsAllowTxRundir\""
				mkdir -p "$SdsAllowTxRundir"
			fi
			for file in $(find $SdsAllowTxConfdir -maxdepth 1 -xtype f); do
				log "$myname" "    loading list entries from \"$file\""
				while read -r line; do
					touch "$SdsAllowTxRundir/$(echo $line | awk -F: '{ print $1 }')"
				done < "$file"
			done
		fi
		if ([ -e "$SdsDenyRxConfdir" ] && [ -n "$useSdsDenyRx" ]); then
			if !([ -e "$SdsDenyRxRundir" ]); then
				log "$myname" "  creating \"$SdsDenyRxRundir\""
				mkdir -p "$SdsDenyRxRundir"
			fi
			for file in $(find $SdsDenyRxConfdir -maxdepth 1 -xtype f); do
				log "$myname" "    loading list entries from \"$file\""
				while read -r line; do
					touch "$SdsDenyRxRundir/$(echo $line | awk -F: '{ print $1 }')"
				done < "$file"
			done
		fi
		if ([ -e "$SdsDenyTxConfdir" ] && [ -n "$useSdsDenyTx" ]); then
			if !([ -e "$SdsDenyTxRundir" ]); then
				log "$myname" "  creating \"$SdsDenyTxRundir\""
				mkdir -p "$SdsDenyTxRundir"
			fi
			for file in $(find $SdsDenyTxConfdir -maxdepth 1 -xtype f); do
				log "$myname" "    loading list entries from \"$file\""
				while read -r line; do
					touch "$SdsDenyTxRundir/$(echo $line | awk -F: '{ print $1 }')"
				done < "$file"
			done
		fi
		log "$myname" "done"
		
		# auf jedem konfigurierten Interface Read-Spooler, Write-Spooler, fdtsds und PEI-Init starten
		k=1
		while [ -n "$(eval echo '$'SdsTtyToBind_${k}_name)" ]; do
			runVAR="$(eval echo '$'SdsTtyToBind_${k}_name)"
			trxtype="$(eval echo '$'SdsTtyToBind_${k}_trxtype)"
			gssiStart="$(eval echo '$'SdsTtyToBind_${k}_gssistart)"
			#gssiStop="$(eval echo '$'SdsTtyToBind_${k}_gssistop)"
	 
			log "$myname" "starte Read-Logger auf \"$runVAR\""
			cp "$sds_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" "done"
			
			log "$myname" "starte Read-Spooler auf \"$runVAR\""
			cp "$sds_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" "done"
			
			log "$myname" "starte Write-Logger auf \"$runVAR\""
			cp "$sds_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" "done"
			
			log "$myname" "starte Write-Spooler auf \"$runVAR\""
			cp "$sds_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" "done"
			
			log "$myname" "starte ${trxtype}.rx auf \"$runVAR\""
			cp "${sds_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" "done"
			
			log "$myname" "starte ${trxtype}.tx auf \"$runVAR\""
			cp "${sds_program}/${trxtype}.tx" "${rundir}/${myname}.${trxtype}.tx.$runVAR"
			start-stop-daemon --start --quiet --pidfile "${rundir}/${myname}.${trxtype}.tx.$runVAR.pid" --make-pidfile --background --exec  "${rundir}/${myname}.${trxtype}.tx.$runVAR"
			log "$myname" "done"
			
			log "$myname" "\"${sds_program}/${trxtype}.init start $runVAR\""
			"${sds_program}/${trxtype}.init" start $runVAR
			log "$myname" "done"
			
			if [ -n "${gssiStart}" ]; then
				log "$myname" "erstelle start-GSSI Runfile auf $runVAR"
				echo "${gssiStart}" > "${rundir}/${runVAR}.start_gssi"
			fi

			
			((k++))
		done

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

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

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

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

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

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

		# Read-Spooler beenden
		if [ -e "$rundir/$myname.$devicereader.$runVAR.pid" ]; then
			pid=$(cat "$rundir/$myname.$devicereader.$runVAR.pid")
			log "$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" "done"
		fi

		# Read-Logger beenden
		if [ -e "$rundir/$myname.$devicelogger.$devicereader.$runVAR.pid" ]; then
			pid=$(cat "$rundir/$myname.$devicelogger.$devicereader.$runVAR.pid")
			log "$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" "done"
		fi		
	
		# Write-Spooler beenden
		if [ -e "$rundir/$myname.$devicewriter.$runVAR.pid" ]; then
			pid=$(cat "$rundir/$myname.$devicewriter.$runVAR.pid")
			log "$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" "done"
		fi
	
		# Write-Logger beenden
		if [ -e "$rundir/$myname.$devicelogger.$devicewriter.$runVAR.pid" ]; then
			pid=$(cat "$rundir/$myname.$devicelogger.$devicewriter.$runVAR.pid")
			log "$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" "done"
		fi

		# Hauptprogramm beenden
		if [ -e "${rundir}/${myname}.${trxtype}.rx.$runVAR.pid" ]; then
			pid=$(cat "${rundir}/${myname}.${trxtype}.rx.$runVAR.pid")
			log "$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" "done"
		fi
		if [ -e "${rundir}/${myname}.${trxtype}.tx.$runVAR.pid" ]; then
			pid=$(cat "${rundir}/${myname}.${trxtype}.tx.$runVAR.pid")
			log "$myname" "beende ${trxtype}.tx 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}.tx.$runVAR"
			rm -f "${rundir}/${myname}.${trxtype}.tx.$runVAR.pid"
			log "$myname" "done"
		fi
		
		# zur Identitätsbestimmung des angeschlossenen Funkgerätes werden beim Initialisieren issi,gssi,opta ausgelesen
		# hier werden sie beim Beenden wieder gelöscht
		#
		log "$myname" "deleting status files for \"$runVAR\""
		if [ -e "$rundir/$runVAR.last_vital" ]; then
			log "$myname" "  \"$rundir/$runVAR.last_vital\""
			rm -f "$rundir/$runVAR.last_vital"
		fi		
		if [ -e "$rundir/$runVAR.issi" ]; then
			log "$myname" "  \"$rundir/$runVAR.issi\""
			rm -f "$rundir/$runVAR.issi"
		fi		
		if [ -e "$rundir/$runVAR.gssi" ]; then
			log "$myname" "  \"$rundir/$runVAR.gssi\""
			rm -f "$rundir/$runVAR.gssi"
		fi		
		if [ -e "$rundir/$runVAR.opta" ]; then
			log "$myname" "  \"$rundir/$runVAR.opta\""
			rm -f "$rundir/$runVAR.opta"
		fi		
		if [ -e "$rundir/$runVAR.signal_strength_dBm" ]; then
			log "$myname" "  \"$rundir/$runVAR.signal_strength_dBm\""
			rm -f "$rundir/$runVAR.signal_strength_dBm"
		fi		
		if [ -e "$rundir/$runVAR.registration_status" ]; then
			log "$myname" "  \"$rundir/$runVAR.registration_status\""
			rm -f "$rundir/$runVAR.registration_status"
		fi		
		if [ -e "$rundir/$runVAR.location_area" ]; then
			log "$myname" "  \"$rundir/$runVAR.location_area\""
			rm -f "$rundir/$runVAR.location_area"
		fi		
		if [ -e "$rundir/$runVAR.network_identifier" ]; then
			log "$myname" "  \"$rundir/$runVAR.network_identifier\""
			rm -f "$rundir/$runVAR.network_identifier"
		fi		
		if [ -e "${rundir}/${runVAR}.startgssi" ]; then
			log "$myname" "  \"$rundir/$runVAR.start_gssi\""
			rm -f "${rundir}/${runVAR}.startgssi"
		fi
		log "$myname" "done"
		
		((l++))
	done

	# allow/deny list Verzeichnisse löschen
	log "$myname" "deleting allow/deny list directories"
	if [ -e "$SdsAllowRxRundir" ]; then
		log "$myname" "  \"$SdsAllowRxRundir\""
		rm -rf "$SdsAllowRxRundir"
	fi
	if [ -e "$SdsAllowTxRundir" ]; then
		log "$myname" "  \"$SdsAllowTxRundir\""
		rm -rf "$SdsAllowTxRundir"
	fi
	if [ -e "$SdsDenyRxRundir" ]; then
		log "$myname" "  \"$SdsDenyRxRundir\""
		rm -rf "$SdsDenyRxRundir"
	fi
	if [ -e "$SdsDenyTxRundir" ]; then
		log "$myname" "  \"$SdsDenyTxRundir\""
		rm -rf "$SdsDenyTxRundir"
	fi
	log "$myname" "done"
	
	# userdefinierbares Init-Skript beim Stop ausführen
	l=1
	while [ -n "$(eval echo '$'SdsUserinit_${l})" ]; do
		log "$myname" "\"$(eval echo '$'SdsUserinit_${l}) stop\""
		"$(eval echo '$'SdsUserinit_${l})" stop > /dev/null 2>&1
		log "$myname" "\"$(eval echo '$'SdsUserinit_${l}) stop\" done"
		((l++))
	done

	log "$myname" "Stop ${myname} abgeschlossen"
	log "$myname" "-------------------------"
	echo "done!"

 }

 status_daemon(){
	# Prüfen ob Daemon bereits läuft
	instances=0
	#for runVAR in $ttyToListenTo; do
	k=1
	while [ -n "$(eval echo '$'SdsTtyToBind_${k}_name)" ]; do
		runVAR="$(eval echo '$'SdsTtyToBind_${k}_name)"
		trxtype="$(eval echo '$'SdsTtyToBind_${k}_trxtype)"
		if ([ -e "${rundir}/${myname}.${trxtype}.rx.${runVAR}.pid" ] || [ -e "${rundir}/${myname}.${trxtype}.tx.${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_daemon
    ;;
  restart)
    stop_daemon
	sleep 6
    start_daemon
    ;;
  status)
    status_daemon
    ;;
  *)
     echo "Usage: $0 {start|stop|restart|status}" >&2
     exit 2
esac
exit 0
