#! /bin/sh
#
# netborder-ss7: Sarts netborder-ss7 daemon
#
# chkconfig: 345 96 02
# processname: nsg
# description: Netborder SS7 init script
# config:
# Author: Sangoma

NSG_PROD_NAME="Netborder SS7 Gateway"
NSG_SERVICE_NAME=nsg
NSG_CONF=/etc/nsg/nsg.conf
#NSG_OPTIONS="-core -hp -nc -nonat"
NSG_OPTIONS="-core -hp -nonat"
NSG_USLEEP=500000
NSG_USLEEP_TIMEOUT=$(((15*1000000)/$NSG_USLEEP))

NSG_TMPFS_OPTIMIZATION=NO
NSG_TMPFS_LOG_BACKUP=NO
NSG_TMPFS_LOG_BACKUP_LIMIT=20
NSG_TMPFS_LOG_DIR=/dev/shm/nsg/log
NSG_TMPFS_DB_DIR=/dev/shm/nsg/db


# Source function library.
. /etc/init.d/functions

# pull in sysconfig settings only if NSG_INSTALLDIR is not already present
if [ -z "$NSG_INSTALLDIR" ]
then
	if [ ! -f $NSG_CONF ]
	then
		echo "FATAL: There is no $NSG_CONF file!!"
		exit
	fi
	. $NSG_CONF
fi

export LD_LIBRARY_PATH="$NSG_INSTALLDIR/lib"
PID_FILE=$NSG_INSTALLDIR/run/nsg.pid
NSG_BINARY=$NSG_INSTALLDIR/bin/$NSG_SERVICE_NAME
NSG_STOPFILE=$NSG_INSTALLDIR/.stopping

nsg_tmpfs_optimization()
{
	local home=$(pwd)
	if [ "$NSG_TMPFS_OPTIMIZATION" != "YES" ]; then
		cd $NSG_INSTALLDIR;	
		if [ -h log ] || [ ! -e log ]; then
			eval "rm -f log 2> /dev/null"
			mkdir log
		fi
		if [ -h db ] || [ ! -e db ]; then
			eval "rm -f db 2> /dev/null"
			mkdir db
		fi
		cd $home
		return 0
	fi
	if [ ! -e /dev/shm ]; then
		return 0
	fi
	
	cd $NSG_INSTALLDIR;	
	if [ ! -e $NSG_TMPFS_LOG_DIR ]; then
		mkdir -p $NSG_TMPFS_LOG_DIR
	fi
	if [ ! -e $NSG_TMPFS_DB_DIR ]; then
		mkdir -p $NSG_TMPFS_DB_DIR
	fi
	if [ ! -h log ]; then
		if [ -e log ]; then
			rm -rf log_persist;
			mv log log_persist;
		fi
		ln -s $NSG_TMPFS_LOG_DIR log
	fi
	if [ ! -h db ]; then
		if [ -e db ]; then
			rm -rf db_persist;
			mv db db_persist;
		fi
		ln -s $NSG_TMPFS_DB_DIR db
	fi

	cd $home

  echo -n $"Starting TMPFS optimization:"
  success
  echo 

	return 0
}

nsg_tmpfs_log_backup()
{
	local home=$(pwd)
	local cnt=0
	if [ "$NSG_TMPFS_LOG_BACKUP" != "YES" ]; then
		return 0
	fi

	cd $NSG_INSTALLDIR;

	if [ ! -d log_persist ]; then
		mkdir log_persist
	fi

	if [ -h log ] && [ -d log_persist ]; then
		cp -rf log/* log_persist/ 2> /dev/null
		cd log_persist
		logs=`ls -lt sangomagw.log.* | awk {'print $9'} | xargs`
		cnt=0	
		for log in $logs
		do
			cnt=$((cnt+1))
			if [ $cnt -gt $NSG_TMPFS_LOG_BACKUP_LIMIT ]; then
				rm -f $log;
			fi
		done
		
	fi

	cd $home
  echo -n $"Backing up logs:"
  success
  echo 
	return 0
}


run_nsg()
{
	local nsgcmd="$NSG_BINARY -base $NSG_INSTALLDIR -conf $NSG_INSTALLDIR/conf -log $NSG_INSTALLDIR/log -run $NSG_INSTALLDIR/run -db $NSG_INSTALLDIR/db -mod $NSG_INSTALLDIR/mod $NSG_OPTIONS"

	mydate=`date`
	echo "[$mydate] Starting $nsgcmd" >> $NSG_INSTALLDIR/init.log
	while :; do
		# note that we stopped using 1 as module loading error
		# there were reports of the application sometimes exiting abnormally and not restarted
		# although in theory 1 is a non-std exit status (see /usr/include/sysexits.h), it is fairly
		# normal for developers to use EXIT_SUCCESS and EXIT_FAILURE (/usr/include/stdlib.h) as exit()
		# status when something abnormal happens (ie, custom/non-std assert code)
		# we are using here therefore status EX_DATAERR (65), which is supposed to indicate user input error
		# which is the closest to file configuration error I could find
		$nsgcmd &> /dev/null
		EXITSTATUS=$?
		mydate=`date`
		if test "x$EXITSTATUS" = "x0" ; then
			exit 0
		elif test "x$EXITSTATUS" = "x65" ; then
			echo "[$mydate] $nsgprog ended due module loading error" >> $NSG_INSTALLDIR/init.log
			exit 1
		elif test "0$EXITSTATUS" -gt "128" ; then
			EXITSIGNAL=$(($EXITSTATUS - 128))
			echo "[$mydate] $nsgprog ended with status $EXITSTATUS with signal $EXITSIGNAL" >> $NSG_INSTALLDIR/init.log
		else
			echo "[$mydate] $nsgprog ended with status $EXITSTATUS" >> $NSG_INSTALLDIR/init.log
		fi

		# if the app segfaults or errors on shutdown, no point in restarting
		if [ -f $NSG_STOPFILE ] ; then
			echo "[$mydate] Not restarting $nsgprog ($nsgcmd) due to stop file" >> $NSG_INSTALLDIR/init.log
			rm -f $NSG_STOPFILE
			if [ -f $PID_FILE ] ; then
				# the process most likely died violently, we must clean the PID ourselves
				rm $PID_FILE
			fi
			nsg_tmpfs_log_backup
			exit 0
		fi

		# if there is no PID file, then this is a clean exit (most likely)
		if [ ! -f $PID_FILE ]; then
			echo "[$mydate] $nsgprog ended with no pid file" >> $NSG_INSTALLDIR/init.log
			exit $EXITSTATUS
		fi

		sleep 1
		mydate=`date`
		echo "[$mydate] Restarting $nsgcmd" >> $NSG_INSTALLDIR/init.log
		# the process most likely died violently, we must clean the PID ourselves
		rm $PID_FILE

		nsg_tmpfs_log_backup
	done
		
	nsg_tmpfs_log_backup
	exit 0
}

nsg_setlimits() {
        ulimit -c unlimited
        ulimit -d unlimited
        ulimit -f unlimited
        ulimit -i unlimited
        ulimit -n 999999
        ulimit -q unlimited
        ulimit -u unlimited
        ulimit -v unlimited
        ulimit -x unlimited
        ulimit -s 244
        ulimit -l unlimited
        return 0
}


start()
{
	nsgpid=`pidof $NSG_SERVICE_NAME`
	if [ ! -z "$nsgpid" ]
	then
		echo -n $"$NSG_PROD_NAME is already started:"
		failure
		echo 
		exit 1
	fi

	rm -f $NSG_STOPFILE
	nsg_setlimits	
	nsg_tmpfs_optimization
	nsg_tmpfs_log_backup

	echo -n $"Starting $NSG_PROD_NAME:"
	#$NSG_BINARY -base $NSG_INSTALLDIR -conf $NSG_INSTALLDIR/conf -log $NSG_INSTALLDIR/log -run $NSG_INSTALLDIR/run -db $NSG_INSTALLDIR/db -mod $NSG_INSTALLDIR/mod $NSG_OPTIONS
	run_nsg &
	RETVAL=$?
	[ "$RETVAL" = 0 ] && touch /var/lock/subsys/$NSG_SERVICE_NAME

	
	if [ "$RETVAL" = 0 ]
	then
		# just finish the routine if we stop seeing the process or the pid file
		# is created. If the pid file is never created by the app this script will
		# hang forever (or more likely until the user stops us)
		while true
		do
			nsgpid=`pidof $NSG_SERVICE_NAME`
			if [ -z "$nsgpid" ]
			then
				RETVAL=1
				rm -f /var/lock/subsys/$NSG_SERVICE_NAME
				failure
				break
			fi
			if [ -f $PID_FILE ]
			then
				success
				break
			fi
			usleep $NSG_USLEEP
		done
	else
		failure
	fi

	echo 
  if [ -f "$NSG_INSTALLDIR/bin/nsg-qos" ] && [ -f $NSG_INSTALLDIR/conf/qos.conf ]
  then
    echo -n $"Starting QOS:"
    $NSG_INSTALLDIR/bin/nsg-qos $NSG_INSTALLDIR/conf/qos.conf start
    success
    echo 
  fi
}

stop()
{
  if [ -f "$NSG_INSTALLDIR/bin/nsg-qos" ] && [ -f $NSG_INSTALLDIR/conf/qos.conf ]
  then
    echo -n $"Stopping QOS:"
    $NSG_INSTALLDIR/bin/nsg-qos $NSG_INSTALLDIR/conf/qos.conf stop
    success
    echo 
  fi
	nsgpid=`pidof $NSG_SERVICE_NAME`
	if [ -z "$nsgpid" ]
	then
		echo -n $"$NSG_PROD_NAME is not started:"
		failure
		echo 
		return 1
	fi

	echo -n $"Stopping $NSG_PROD_NAME:"

	touch $NSG_STOPFILE
	$NSG_BINARY -stop -base $NSG_INSTALLDIR -conf $NSG_INSTALLDIR/conf -log $NSG_INSTALLDIR/log -run $NSG_INSTALLDIR/run -db $NSG_INSTALLDIR/db -mod $NSG_INSTALLDIR/mod > /dev/null 2> /dev/null
	RETVAL=$?
	if [ "$RETVAL" = 0 ]
	then
		tcnt=0;
		# at this point just finish the routine if we stop seeing the process 
		while true
		do
			nsgpid=`pidof $NSG_SERVICE_NAME`
			if [ -z "$nsgpid" ]
			then
				success
				break
			fi
			usleep $NSG_USLEEP
			tcnt=$((tcnt+1))
			if [ $tcnt -gt $NSG_USLEEP_TIMEOUT ]; then
				eval "kill -9 $nsgpid > /dev/null 2> /dev/null"
				success
        break
			fi	  
			#echo "Waiting for pid down $tcnt/$NSG_USLEEP_TIMEOUT"
		done
		rm -f /var/lock/subsys/$NSG_SERVICE_NAME
    echo
		nsg_tmpfs_log_backup
	else
		rm -f $NSG_STOPFILE
    failure
    echo 
	fi

}

case "$1" in
	start)
		start
		;;
	stop)
		stop
		;;
	status)
		status $NSG_BINARY
		RETVAL=$?
		;;
	restart)
		stop
		start
		;;
	*)
		echo $"Usage: $0 {start|stop|status}"
		RETVAL=1
esac
exit $RETVAL


