#!/bin/bash
# Copyright 2014-2018 VMware, Inc. 
# SPDX-License-Identifier: BSD-2-Clause
#

# The following section provides information for chkconfig tool
# 35 are the run-levels which the daemon runs at.
# 13 and 87 are start and stop priorities correspondingly.

# chkconfig: 35 13 87
# description: Log Insight Agent
# processname: liagentd

### BEGIN INIT INFO
# Provides:          liagentd
# Required-Start:    $syslog $network
# Required-Stop:     $syslog $network
# Default-Start:     3 5
# Default-Stop:      0 6
# Short-Description: Log Insight Agent
### END INIT INFO

ProductName="VMware Log Insight Agent"
BinaryName="liagent"

User="root"
AdditionalParams=""
StartCommand="--daemon --user $User $AdditionalParams"

DaemonName=`basename $0`

ProductDir="/usr/lib"
ProductPath="$ProductDir/loginsight-agent"
BinaryPath="$ProductPath/bin/$BinaryName"
pidDir="/var/run/liagent"
pidPath="$pidDir/$BinaryName.pid"

# Application status codes
ERRORCODE_USAGE=2
ERRORCODE_CANNOT_STOP=151

# LSB status codes
ERRORCODE_IS_RUNNING=0
ERRORCODE_DEAD_PID_EXISTS=1
ERRORCODE_DEAD_LOCKFILE_EXISTS=2
ERRORCODE_NOT_RUNNING=3
ERRORCODE_STATUS_UNKNOWN=4

RETVAL=0

# Sourcing environment variables from external files if exist
if [ -f /etc/sysconfig/liagentd ]; then
   . /etc/sysconfig/liagentd
elif [ -f /etc/default/liagentd ]; then
   . /etc/default/liagentd
fi

if [ ! "$LIAGENT_SSL_CA_PATH" == "" ]; then
   export LIAGENT_SSL_CA_PATH=$LIAGENT_SSL_CA_PATH
fi

if [ -e /lib/lsb/init-functions ]; then
   LSB_EXISTS="yes"
# Including LSB init script functions
   . /lib/lsb/init-functions
   start_daemon=start_daemon
elif [ -e /etc/init.d/functions ]; then
# RedHat style
   . /etc/init.d/functions
   start_daemon=daemon
elif [ `command -v startproc 2> /dev/null ` ]; then
# SUSE style
   start_daemon=startproc
else
# Run the bare command (e.g. on Photon)
   start_daemon=""
fi

if [ ! `command -v killproc 2> /dev/null` ]; then
# LSB killproc implementation, see "Init Script Functions" section in LSB for details
   killproc () {
      while [[ $# -gt 0 ]]; do
         local key=$1
         case $key in
            -p)
               local pidFilePath=$2
               shift 2
               ;;
            -*)
               local signal=$key
               shift
               ;;
            *)
               local pathName=$key
               shift
               ;;
         esac
      done

      if [ "$pathName" == "" ]; then
         return 2
      fi

      if [ ! "$pidFilePath" = "" ]; then
         if [ -f "$pidFilePath" ]; then
            local pidFile=$pidFilePath
            read -r pid<$pidFile
         else
            return 0
         fi
      else
         # This is the default path according to LSB
         local pidFile=/var/run$(basename $pathName)
         if [ -f "$pidFile" ]; then
            read -r pid<$pidFile
         else
            pid=$(pgrep -o "\b$(basename $pathName)\b")
         fi
      fi

      kill $signal $pid
      pgrep -o "\b$(basename $pathName)\b" > /dev/null
      retval=$?
      if [ ! "$signal" = "" ]; then
         if [ $retval -eq 0 ]; then
            return 0
         fi
      else
         sleepTime=10
         while [ $sleepTime -gt 0 ]; do
            pgrep -o "\b$(basename $pathName)\b" > /dev/null
            if [ $? -ne 0 ]; then
               break
            fi
            sleep 1
            let sleepTime--
         done
         kill -KILL $pid
         retval=0
      fi
      rm -f $pidFile
      return $retval
   }
fi

if [ ! `command -v pidofproc 2> /dev/null` ]; then
   pidofproc () {
      local pidFile
      while [[ $# -gt 0 ]]; do
         local key=$1
         case $key in
            -p)
               pidFile=$2
               shift 2
               ;;
            *)
               local pathName=$key
               shift
               ;;
         esac
      done
      if [ "$pathName" == "" ]; then
         return 2
      fi

      local pid;
      if [ ! "$pidFile" == "" ]; then
         if [ -f "$pidFile" ]; then
            read -r pid<$pidFile
         fi
      else
         pidFile=pidFile=/var/run/$(basename $pathName)
         if [ -f "$pidFile" ]; then
            read -r pid<$pidFile
         else
            pid=$(pgrep -o "\b$(basename $pathName)\b")
         fi
      fi
      if [ ! "$pid" == "" ]; then
         echo $pid
         return $ERRORCODE_IS_RUNNING
      fi
      return $ERRORCODE_NOT_RUNNING
   }
fi

usage () {
   echo "Usage: $DaemonName {start | stop | restart | force-reload | status}"
   RETVAL=$ERRORCODE_USAGE
}

start () {
   echo -n $"Starting $ProductName: "
   status --silent
   status_code=$?
   # Unknown status almost always indicates that the process exists but the pid file is missing
   if [ "$status_code" = "$ERRORCODE_IS_RUNNING" ] || [ "$status_code" = "$ERRORCODE_STATUS_UNKNOWN" ]; then
      RETVAL=0
      echo -n "Already started."
   else
      $start_daemon $BinaryPath $StartCommand $*
      RETVAL=$?
   fi
   if [ "$LSB_EXISTS" = "yes" ]; then
      if [ "$RETVAL" = 0 ]; then
         log_success_msg
      else
         log_failure_msg
      fi
   else
      echo
   fi
   return $RETVAL
}

stop () {
   echo -n $"Stopping $ProductName: "
   status --silent # This changes the value of 'RETVAL'
   if [ "$RETVAL" = "$ERRORCODE_NOT_RUNNING" ] || [ "$RETVAL" = "$ERRORCODE_DEAD_PID_EXISTS" ]; then
      RETVAL=0
      echo -n "Already stopped."
   else
      # LSB killproc function does not specify delay time
      sleep_time=5
      killproc -p $pidPath $BinaryName -TERM
      # Being sceptical to killproc retcode (platform dependent)
      RETVAL=$ERRORCODE_IS_RUNNING
      while [ ! "$RETVAL" = "$ERRORCODE_NOT_RUNNING" ] && [ $sleep_time -ne 0 ]; do
         sleep 1
         let sleep_time--
         status --silent
      done
      # if not stopped yet
      if [ ! "$RETVAL" = "$ERRORCODE_NOT_RUNNING" ]; then
         pid=$(pidofproc $BinaryName)
         kill -KILL $pid &> /dev/null
         sleep 1
         status --silent
         if [ ! "$RETVAL" = "$ERRORCODE_NOT_RUNNING" ] && [ ! "$RETVAL" = "$ERRORCODE_DEAD_PID_EXISTS" ]; then
            RETVAL=$ERRORCODE_CANNOT_STOP
         fi
      fi
   fi
   if [ "$RETVAL" == "$ERRORCODE_NOT_RUNNING" ]; then
      RETVAL=0
   fi
   if [ "$LSB_EXISTS" = "yes" ]; then
      if [ "$RETVAL" = 0 ]; then
         log_success_msg
      else
         log_failure_msg
      fi
   else
      echo
   fi
   return $RETVAL
}

restart () {
   stop
   RETVAL=$?
   if [ "$RETVAL" = 0 ]; then
      start $*
   fi
}

status () {
# Implementing LSB-compatible status action
   process=`pgrep -o "\b$BinaryName\b"`
   if [ -f $pidPath ]; then
      if [ ! "$process" == "" ]; then
         RETVAL=$ERRORCODE_IS_RUNNING
      else
         RETVAL=$ERRORCODE_DEAD_PID_EXISTS
      fi;
   else
      if [ "$process" == "" ]; then
         RETVAL=$ERRORCODE_NOT_RUNNING
      else
         RETVAL=$ERRORCODE_STATUS_UNKNOWN
      fi;
   fi;
   if [ ! "$1" == "--silent" ]; then
      if [ $RETVAL -eq $ERRORCODE_STATUS_UNKNOWN ]; then
         echo "Warning: Unable to locate the pid file: $pidPath"
      elif [ $RETVAL -eq $ERRORCODE_IS_RUNNING ]; then
         pid=`pgrep -o "\b$BinaryName\b"`
         echo "$BinaryName (pid $pid) is running..."
      else
         echo "$BinaryName is stopped"
      fi
   fi
   return $RETVAL
}

user () {
   echo $User
}

params () {
   echo $AdditionalParams
}

case "$1" in
start)
   shift
   start $*
   ;;
stop)
   stop
   ;;
restart|force-reload)
   shift
   restart $*
   ;;
status)
   shift
   status $*
   ;;
user)
   user
   ;;
params)
   params
   ;;
*)
   usage
esac

exit $RETVAL