#!/bin/bash
#
# Service control script for the TRIP Daemon (tripd) and the
# TRIPnet Daemon (tripnetd)
#
# Copyright (C) 2022 Smaser AG
#
# This script is intended for use together with the SystemV init system and
# the systemd service units for tripd and tripnetd. Any other use except for
# status checking is NOT supported.
#
# Use the install_services script for installing tripd and tripnetd for
# automatic start with SystemD or the SystemV init system, according to
# which one the current operating system supports. Use the service or the
# systemctl commands as appropriate to start and stop tripd and tripnetd.
#

usage()
{
   echo "USAGE: tripctl [COMMAND] SERVICE"
   echo ""
   echo "COMMANDS:"
   echo "   help                 Show this help text"
   echo "   status               Check whether a service is running"
   echo ""
   echo "SERIVCES:"
   echo "   tripd                TRIP Kernel Daemon"
   echo "   tripnetd             TRIP Network Daemon"
   echo ""
   echo "This script is intended for use together with the SystemV init system"
   echo "and the systemd service units for tripd and tripnetd. Any other use"
   echo "except for status checking is NOT supported."
   echo ""
   echo "Use the install_services script for installing tripd and tripnetd for"
   echo "automatic start with SystemD or the SystemV init system, according to"
   echo "which one the current operating system supports. Use the service or the"
   echo "systemctl commands as appropriate to start and stop tripd and tripnetd."
   echo ""

}

OPMODE=0
CTL_TRIPD=0
CTL_TRIPNETD=0

case "$1" in
   -h|--help|help|"")
      usage
      exit 0
      ;;
   start)
      OPMODE=1
      ;;
   stop)
      OPMODE=2
      ;;
   status)
      OPMODE=3
      ;;
   *)
      echo "ERROR: Invalid command argument $1"
      echo ""
      usage
      exit 1
      ;;
esac

if [ -e /usr/local/trip/sys/lib ]; then
   TDBS_HOME=$(dirname `readlink /usr/local/trip/sys/lib 2>/dev/null` 2> /dev/null)
   TDBS_EXE=$TDBS_HOME/bin
fi

if [ "$TDBS_HOME" = "" ] || [ ! -d "$TDBS_HOME" ]; then
   echo "ERROR: TRIPsystem is not properly installed."
   echo ""
   exit 1
fi

TDBS_LOG=`$TDBS_EXE/queryrcs -q TDBS_LOG | sed 's/<nil>//g'`
if [ ! -d "$TDBS_LOG" ]; then
   TDBS_LOG=/tmp
fi

case "$2" in
   tripd)
      CTL_TRIPD=1
      DAEMON_OPTS=${DAEMON_OPTS:-"-C -v${DAEMON_LOGLEVEL} -l $TDBS_LOG/tripd.log"}
      ;;
   tripnetd):
      CTL_TRIPNETD=1
      DAEMON_OPTS=${DAEMON_OPTS:-"console -l $TDBS_LOG/tripnetd.log"}
      ;;
   *)
      echo "ERROR: Invalid service name argument $2"
      echo ""
      usage
      exit 1
      ;;
esac


DAEMON_NAME=$2
DAEMON_FILE=$TDBS_EXE/$DAEMON_NAME
PIDFILE=/var/run/$DAEMON_NAME.pid



# Abort on any error in the script
set -e


##
# Remove oldest backup log if there are at least ten present
#
prune_logs()
{
   DAEMON_LOGFILES=`find $TDBS_LOG -maxdepth 1 -name "$DAEMON_NAME.log-*" -printf "%T@ %p\n" | sort -n | awk '{print $2}'`
   DAEMON_LOGCOUNT=`echo $DAEMON_LOGFILES | wc -w`
   if [ $DAEMON_LOGCOUNT -ge 10 ]; then
      DAEMON_OLDLOG=`echo $DAEMON_LOGFILES|tr ' ' '\n'| head -n1`
      rm -f $DAEMON_OLDLOG
   fi
}



##
# Back up the previous daemon log file, keeping the ten last
# logs as backup.
#
backup_logs()
{
   # Back up the previous log file
   if [ -f $TDBS_LOG/$DAEMON_NAME.log ]; then
      prune_logs
      if [ "$TDBS_LOG" = "/tmp" ]; then
         # Don't keep backups if /tmp is used as log dir
         rm -f $TDBS_LOG/$DAEMON_NAME.log 2> /dev/null
      else
         mv -f $TDBS_LOG/$DAEMON_NAME.log $TDBS_LOG/$DAEMON_NAME.log-`date '+%Y%m%d%H%M%S'` 2> /dev/null
      fi
   fi
}


##
# Check if the daemon is running based on the PID file and the process'
# command line.
#
is_running()
{
   if [ ! -f "$PIDFILE" ]; then
      return 1
   fi
   pid=`cat $PIDFILE`
   if [ -z "$pid" ]; then
      return 1
   fi
   if [ ! -d /proc/$pid ]; then
      if [ -f $PIDFILE ]; then
         rm -f $PIDFILE
      fi
      return 1
   fi
   cmd=`cat /proc/$pid/cmdline | tr "\000" "\n"  | head -n1 | cut -d: -f1`
   if [ "$cmd" != "$DAEMON_FILE" ]; then
      if [ -f $PIDFILE ]; then
         rm -f $PIDFILE
      fi
      return 1
   else
      return 0
   fi
}


##
# Wait for up to ten seconds for the daemon process to exit.
#
waitpid()
{
   TIMELEFT=10
   while is_running
   do
      if [ $TIMELEFT -eq 0 ]; then
         return 1
      fi
      TIMELEFT=`expr $TIMELEFT - 1`
      sleep 1s
   done
   return 0
}


##
# Start the daemon
#
if [ $OPMODE -eq 1 ]; then
   if is_running ; then
      echo "$DAEMON_NAME is already running"
      exit 0
   fi
   ulimit -n 64000
   ulimit -f unlimited
   export TDBS_TOTAL_SHUTDOWN=TRUE
   backup_logs
   printf $$ > $PIDFILE
   exec -a $DAEMON_FILE $DAEMON_FILE $DAEMON_OPTS
   rm $PIDFILE
   unset TDBS_TOTAL_SHUTDOWN
   exit 9


##
# Stop the daemon
#
elif [ $OPMODE -eq 2 ]; then
   if is_running ; then
      if [ $CTL_TRIPD -eq 1 ]; then
         $TDBS_EXE/tripd -k 0 > /dev/null 2>&1
      else
         kill -TERM $pid
      fi
      waitpid
      if is_running ; then
         kill -9 $pid
         waitpid
         if is_running ; then
            echo "ERROR: Unable to stop $DAEMON_NAME (pid $pid)"
            exit 1
         fi
      fi
   fi
   if [ -f $PIDFILE ]; then
      rm -f $PIDFILE
   fi


##
# Check if the daemon is running
#

elif [ $OPMODE -eq 3 ]; then
   if is_running ; then
      echo "$DAEMON_NAME is running"
   else
      echo "$DAEMON_NAME is stopped"
   fi

fi

