#!/bin/sh
#set -x
#
# boom_agt: Management of the BOOM Agent Processes
#
# For manual installations without the install script 
# just set in 'boom_agt.cfg' file:
#   BOOM_ROOT - agent's installation directory (mandatory)
#   JAVA_PATH - NOT default 'java' path (if necessary)
#   PERL_PATH - NOT default 'perl' path (if necessary)
#   USER      - if necessary
#   JAVA_OPTS - if any
#################

# BOOM agent config file, 
# where values of the below listed variables have to be taken from.
AGT_CFG_FILE="./boom_agt.cfg"
# OS name
OSNAME=
# JAVA arguments
JAVA_OPTS="-Xmx512M"
# BOOM agent root directory
BOOM_ROOT=
# Java path (if not default java has to be used)
JAVA_PATH=
# Perl path (if not default perl has to be used)
PERL_PATH=
# Boom agent user
USER=
#Variable to hold active PIDS of Agent
AGT_PIDS=
#Variable to hold Program Directory
PROG_DIR=
#Variable to set if only known PID should be used for stop
PID_ONLY=
# Variable to hold init system (initd, systemd etc.)
SYS_INIT=
# Java process label
LABEL="BOOMAGENTPROC"

PATH=/sbin:/usr/sbin:/bin:/usr/bin:${PATH}
export PATH

# getdir: identify the path to the program and set
#         it as PROG_DIR
# Params: program-name and $0 from call
getdir() {
  prog="$1"
  call="$2"
  if [ -z "$prog" ]
  then
    return
  fi
#   newdir=${0%/*}
  newdir=`echo "${call}"|sed "s/${prog}$//"`
  if [ -z "$newdir" ]
  then
    whichstr=`which ${prog}|grep -v "no ${prog}"`
    newdir=`echo "$whichstr"|sed "s/${prog}$//"`
    if [ -z "$newdir" ]
    then
      return
    fi
  fi
  if [ -d "$newdir" ]
  then
    PROG_DIR="$newdir"
  fi
}

set_agt_pids() {
  if [ -z "$PID_ONLY" ]
  then
    if [ "$OSNAME" = "freebsd" ]; then
      AGT_PIDS=`ps -ao pid,args | grep ${LABEL} | grep java | $AWK '{print $1}'`
    else
      AGT_PIDS=`UNIX95=1 COLUMNS=254 ps -eo pid,args | grep ${LABEL} | grep java | $AWK '{print $1}'`
    fi
  else
    if [ -f "$BOOM_ROOT/boom_agent.pid" ]
    then
      AGTPID=`cat "$BOOM_ROOT/boom_agent.pid"`
      if [ -z "$AGTPID" ]
      then
        AGT_PIDS=
      else
        if [ "$OSNAME" = "freebsd" ]; then
          AGT_PIDS=`ps -p $AGTPID -o pid,args | grep ${LABEL} | grep java | $AWK '{print $1}'`
        else
          AGT_PIDS=`UNIX95=1 COLUMNS=254 ps -p $AGTPID -o pid,args | grep ${LABEL} | grep java | $AWK '{print $1}'`
        fi
      fi
    else
      AGT_PIDS=
    fi
  fi
  return 0
}

# check if "classic" redirections are working
chk_redir() {
  ret=
  echo 0 2>&1 >/dev/null
  ret=$?
  return $ret
}

# check if "classic" redirections are working with su command
chk_redir_su() {
  ret=
  if [ -n "$1" ]; then
     su $1 -c "echo 0 2>&1 >/dev/null"
     ret=$?
     return $ret
  fi
  echo "user is not defined."
  return 2
}

get_osname() {
  OSNAME=
  osn=`uname | grep -i "Linux"`
  if [ -n "$osn" ]; then
    OSNAME="linux"
    osn=`uname -r | grep -i ELvmnix`
    if [ -n "$osn" ]; then
      OSNAME="esx"
    fi
    return
  fi
  osn=`uname | grep -i "Sun"`
  if [ -n "$osn" ]; then
    OSNAME="sun"
    return
  fi
  osn=`uname | grep -i "HP-UX"`
  if [ -n "$osn" ]; then
    OSNAME="hp-ux"
    return
  fi
  osn=`uname | grep -i "FreeBSD"`
  if [ -n "$osn" ]; then
    OSNAME="freebsd"
    return
  fi
  osn=`uname | grep -i "Darwin"`
  if [ -n "$osn" ]; then
    OSNAME="darwin"
    return
  fi
  osn=`uname | grep -i "AIX"`
  if [ -n "$osn" ]; then
    OSNAME="aix"
    return
  fi
  if [ -z "$OSNAME" ]; then
    OSNAME=`uname`
    echo "This Operating System ($OSNAME) is not or not fully supported by this install skript"
    echo "Some manual installation steps might be required"
    OSNAME="unkown"
  fi
}

#Send kill to all processes of AGT_PIDS
#Parameter $1 is empty or the kill signal
stop_pids() {
  if [ -z "$1" ]
  then
    KSIG=""
  else
    KSIG=$1
  fi
  if [ -z "$AGT_PIDS" ]
  then
    return 0
  fi
  KILL_OK="YES"
  for i in "$AGT_PIDS"
  do
    if kill $KSIG $i
    then
      continue
    else
      KILL_OK="NO"
      echo "Unable to stop process $i"
    fi
  done
  if [ "$KILL_OK" = "YES" ]
  then
    if [ -f /var/lock/subsys/boom_agt ]
    then
      rm -f /var/lock/subsys/boom_agt
    fi
    return 0
  else
    return 1
  fi
}

force_stop() {
  set_agt_pids
  if [ -z "$AGT_PIDS" ]
  then
    return 0
  fi

#  sleep 2
  stop_pids
  sleep 10
  set_agt_pids

  if [ -z "$AGT_PIDS" ]
  then
    return 0
  fi
  stop_pids -9
  set_agt_pids
  if [ -z "$AGT_PIDS" ]
  then
    return 0
  else
    echo "BOOM Agent could not be stopped."
    return 1
  fi
}

stop_agent() {
  set_agt_pids
  if [ -z "$AGT_PIDS" ]
  then
    return 0
  fi
  stop_pids
  return $?
}

start_agent() {
  cd "$BOOM_ROOT"

  chk_redir
  rc_chk_redir=$?

  if [ -f "boom_agent.jar.tmp" ]
  then
    mv -f boom_agent.jar.tmp boom_agent.jar
  fi

  set_agt_pids

  if [ -z "$AGT_PIDS" ]
  then
    if [ -z "$USER" ]
    then
       if [ -z "$1" ]; then
          if [ "$rc_chk_redir" != "0" ]; then
             nohup ${JAVA_PATH}java -D${LABEL} ${JAVA_OPTS} -jar boom_agent.jar > boom_agent_start.log </dev/null &
          else
             nohup ${JAVA_PATH}java -D${LABEL} ${JAVA_OPTS} -jar boom_agent.jar > boom_agent_start.log 2>&1 </dev/null &
          fi
       else
          if [ "$rc_chk_redir" != "0" ]; then
             ${JAVA_PATH}java -D${LABEL} ${JAVA_OPTS} -jar boom_agent.jar > boom_agent_start.log
          else
             ${JAVA_PATH}java -D${LABEL} ${JAVA_OPTS} -jar boom_agent.jar > boom_agent_start.log 2>&1
          fi
       fi
    else
      rc=
      # get current user name
      str_CURRENT_USER=`id -un`
      rc=$?

      if [ "$rc" != "0" ]; then
         str_CURRENT_USER=`id | cut -d "(" -f2 | cut -d ")" -f1`
      fi

      # start boom agent
      if [ "X${str_CURRENT_USER}Y" = "X${USER}Y" ]
      then
        if [ -z "$1" ]; then
           if [ "$rc_chk_redir" != "0" ]; then
              nohup ${JAVA_PATH}java -D${LABEL} ${JAVA_OPTS} -jar boom_agent.jar > boom_agent_start.log </dev/null &
           else
              nohup ${JAVA_PATH}java -D${LABEL} ${JAVA_OPTS} -jar boom_agent.jar > boom_agent_start.log 2>&1 </dev/null &
           fi
        else
           if [ "$rc_chk_redir" != "0" ]; then
              ${JAVA_PATH}java -D${LABEL} ${JAVA_OPTS} -jar boom_agent.jar > boom_agent_start.log
           else
              ${JAVA_PATH}java -D${LABEL} ${JAVA_OPTS} -jar boom_agent.jar > boom_agent_start.log 2>&1
           fi
        fi
      else

         WHICH_SU=
         WHICH_SU=`which su`
         if [ -n "$WHICH_SU" ]; then
            chk_redir_su $USER
            rc_chk_redir_su=$?

            if [ -z "$1" ]; then
               if [ "$rc_chk_redir_su" != "0" ]; then
                 $WHICH_SU $USER -c "nohup ${JAVA_PATH}java -D${LABEL} ${JAVA_OPTS} -jar boom_agent.jar > boom_agent_start.log </dev/null &"
               else
                 $WHICH_SU $USER -c "nohup ${JAVA_PATH}java -D${LABEL} ${JAVA_OPTS} -jar boom_agent.jar > boom_agent_start.log 2>&1 </dev/null &"
               fi
            else
              if [ "$OSNAME" = "darwin" ]; then
                 ${JAVA_PATH}java -D${LABEL} ${JAVA_OPTS} -jar boom_agent.jar > boom_agent_start.log 2>&1
              else 
                 if [ "$rc_chk_redir_su" != "0" ]; then
                    $WHICH_SU $USER -c "${JAVA_PATH}java -D${LABEL} ${JAVA_OPTS} -jar boom_agent.jar > boom_agent_start.log"
                 else
                    $WHICH_SU $USER -c "${JAVA_PATH}java -D${LABEL} ${JAVA_OPTS} -jar boom_agent.jar > boom_agent_start.log 2>&1"
                 fi
              fi
            fi
         else
            echo "Cannot start agent as user '$USER', 'su' command is not found -> exit."
         fi
      fi
    fi

    cd "$curdir"

    if [ -d /var/lock/subsys ]
    then
      sh -c "touch /var/lock/subsys/boom_agt" 1>/dev/null 2>&1
    fi

    return 0
  else
    echo "BOOM Agent is already running."
  fi
  cd "$curdir"
  return 0
}

#get_init_sys
#determine which init mechanism is used on the current system
get_init_sys() {
  SYS_INIT=
  if [ "$OSNAME" = "freebsd" ]; then
    init_s=`ps -aux | grep "init" | grep -v grep | awk '{print $2}' | grep -w "1"`
  else
    init_s=`ps -ef | grep "init" | grep -v grep | awk '{print $2}' | grep -w "1"`
  fi
  if [ "$init_s" = "1" ]; then
     SYS_INIT="init"
     return 0
  fi
  
  if [ "$OSNAME" = "sun" ]; then
     SYS_INIT="init"
     return 0
  fi

  if [ "$OSNAME" = "freebsd" ]; then
    init_s=`ps -aux | grep "systemd" | grep -v grep | awk '{print $2}' | grep -w "1"`
  else
    init_s=`ps -ef | grep "systemd" | grep -v grep | awk '{print $2}' | grep -w "1"`
  fi
  if [ "$init_s" = "1" ]; then
     SYS_INIT="systemd"
     return 0
  fi

  if [ -z "$SYS_INIT" ]; then
    echo "The Init System used on this server is not or not fully supported by this install skript"
    echo "Some manual installation steps might be required"
    SYS_INIT="unknown"
    return 1
  fi

  return 0
}

#wait4pid
#wait untill the pid file gets updated
wait4pid() {
  i=0
  while [ $i -le 120 ]
  do
    (( i++ ))
    sleep 1

    AGTPID_NEW=
    if [ -f "$BOOM_ROOT/boom_agent.pid" ]; then
      AGTPID_NEW=`cat "$BOOM_ROOT/boom_agent.pid"`
      if [ -n "$AGTPID_NEW" ]; then
        if [ "$AGTPID_OLD" != "$AGTPID_NEW" ]; then
           sleep 1
           return 0
        fi
      fi
    fi
  done

  echo "PID file is not created. Timeout (120 sec) is exceeded. Exit. "
  exit 2
}

getdir boom_agt "$0"
if [ -z "$PROG_DIR" ] || [ ! -d "$PROG_DIR" ]
then
  echo "Error: Failed to identify the path for BOOM_ROOT."
  echo "Error: Please set the BOOM_ROOT variable to the Agent directory and rerun the script."
  exit 2
fi

get_osname

if [ "$OSNAME" = "sun" ]
then
  TAIL="tail -1"
  AWK="nawk"
else
  TAIL="tail -n 1"
  AWK="awk"
fi
 
cd $PROG_DIR
BOOM_ROOT=`pwd`

AGT_CFG_FILE="$BOOM_ROOT/boom_agt.cfg"

# get values from the boom_agt.cfg config file
if [ -f "$AGT_CFG_FILE" ]
then
  JAVA_OPTS_TMP=`sed '/^\#/d' ${AGT_CFG_FILE} | grep 'JAVA_OPTS' | $TAIL | cut -d "=" -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | sed 's/^\"\(.*\)\"$/\1/'`
  BOOM_ROOT_TMP=`sed '/^\#/d' ${AGT_CFG_FILE} | grep 'BOOM_ROOT' | $TAIL | cut -d "=" -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | sed 's/^\"\(.*\)\"$/\1/'`
  JAVA_PATH_TMP=`sed '/^\#/d' ${AGT_CFG_FILE} | grep 'JAVA_PATH' | $TAIL | cut -d "=" -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | sed 's/^\"\(.*\)\"$/\1/'`
  JAVA_BIN_TMP=`sed '/^\#/d' ${AGT_CFG_FILE} | grep 'JAVA_BIN' | $TAIL | cut -d "=" -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | sed 's/^\"\(.*\)\"$/\1/'`
  PERL_PATH_TMP=`sed '/^\#/d' ${AGT_CFG_FILE} | grep 'PERL_PATH' | $TAIL | cut -d "=" -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | sed 's/^\"\(.*\)\"$/\1/'`
  USER=`sed '/^\#/d' ${AGT_CFG_FILE} | grep 'USER' | $TAIL | cut -d "=" -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | sed 's/^\"\(.*\)\"$/\1/'`
else
  echo "Configuration file 'boom_agt.cfg' does not exist."
  echo "Default values will be used."
fi

if [ -n "$BOOM_ROOT_TMP" ]
then 
  BOOM_ROOT=$BOOM_ROOT_TMP
fi

if [ -n "$JAVA_OPTS_TMP" ]
then
  JAVA_OPTS=$JAVA_OPTS_TMP
fi

# JAVA_PATH is deprecated. We expect JAVA_BIN - which is the same but should not have trailing slash
if [ -n "$JAVA_PATH_TMP" ]
then
  JAVA_PATH=$JAVA_PATH_TMP
fi

# JAVA_BIN - same as JAVA_PATH, but should not have trailing slash 
if [ -n "$JAVA_BIN_TMP" ]
then
  JAVA_PATH="${JAVA_BIN_TMP}/"
fi

if [ -n "$PERL_PATH_TMP" ]
then
  PERL_PATH=$PERL_PATH_TMP
fi
# check if JAVA_PATH ends with '/'
case $JAVA_PATH in
     '') ;;
     */) ;;
     *) JAVA_PATH="${JAVA_PATH}/";;
esac

#echo BOOM_ROOT=$BOOM_ROOT
#echo JAVA_OPTS=$JAVA_OPTS
#echo JAVA_PATH=$JAVA_PATH
#echo JAVA_BIN=$JAVA_BIN
#echo PERL_PATH=$PERL_PATH
#echo USER=$USER

curdir=`pwd`
whoami=`whoami`
if [ -z "$BOOM_ROOT" ] || [ ! -d "$BOOM_ROOT" ]
then
  echo "BOOM_ROOT='$BOOM_ROOT' is not defined correctly. Please either run install script"
  echo "first or define the BOOM_ROOT value in 'boom_agt.cfg' and rerun this script."
  exit 2
fi
PATH=${BOOM_ROOT}:${BOOM_ROOT}/spi:${PATH}
export PATH 

if [ -n "$JAVA_PATH" ]
then
  if [ -d "$JAVA_PATH" ]
  then
    PATH=${JAVA_PATH}:${PATH}
    export PATH
  else
    if [ $1 = "-start" ]
    then
      echo "JAVA_PATH='$JAVA_PATH' is not a directory."
      echo "Default 'java' will be used."
      echo "If you need a special 'java' version either run install script first or"
      echo "correct the corresponding value in 'boom_agt.cfg' and rerun this script."
    fi
  fi
fi

if [ -n "$PERL_PATH" ]
then
  if [ -d "$PERL_PATH" ]
  then
    PATH=${PERL_PATH}:${PATH}
    export PATH
  else
    if [ $1 = "-start" ]
    then
      echo "PERL_PATH='$PERL_PATH' is not a directory."
      echo "Default 'perl' will be used."
      echo "If you need a special 'perl' version either run install script first or"
      echo "correct the corresponding value in 'boom_agt.cfg' and rerun this script."
    fi
  fi
fi

get_init_sys

case "$1" in

  "-start_msg")
    echo "Starting BOOM Agent"
  ;;

  "-start")
    echo "Starting BOOM Agent"

    if [ "$OSNAME" = "darwin" ]; then
       if [ "$whoami" = "root" ]; then
         launchctl start com.blixx.boom.agent
       else
         sudo launchctl start com.blixx.boom.agent
       fi
       exit 0
    fi

    if [ "$SYS_INIT" = "systemd" ]; then
       if [ "$whoami" = "root" ]; then
         systemctl restart boom_agt.service
       else
         sudo systemctl restart boom_agt.service
       fi
       exit $?
    fi

    start_agent
    exit 0
  ;;

  "-startfg")
    echo "Starting BOOM Agent"
    start_agent "fg"
    exit 0
  ;;

  "-status")
    set_agt_pids
    if [ -z "$AGT_PIDS" ]
    then
      echo "Boom Agent is stopped"
      exit 3
    else
      echo "Boom Agent is running"
    fi
    exit 0
  ;;

  "-restart")
    if [ "$OSNAME" = "darwin" ]; then
       $BOOM_ROOT/restart.sh
    else
       if [ "$SYS_INIT" = "systemd" ]; then
         if [ "$whoami" = "root" ]; then
           systemctl restart boom_agt.service
         else
           sudo systemctl restart boom_agt.service
         fi
         exit $?
       else
         force_stop
         start_agent
       fi
    fi
    exit 0
  ;;

  "-start_wait")
    echo "Starting BOOM Agent"
    AGTPID_OLD=
    if [ -f "$BOOM_ROOT/boom_agent.pid" ]; then
      AGTPID_OLD=`cat "$BOOM_ROOT/boom_agent.pid"`
    fi

    start_agent
    wait4pid
    exit 0
  ;;


  "-stop_msg")
     echo "Stopping BOOM Agent"
  ;;

  "-stop")
    echo "Stopping BOOM Agent"

    if [ "$OSNAME" = "darwin" ]; then
       if [ "$whoami" = "root" ]; then
         launchctl stop com.blixx.boom.agent
       else
         sudo launchctl stop com.blixx.boom.agent
       fi
       exit 0
    fi

    stop_agent
    exit $?
  ;;

  *) echo "Usage: boom_agt -start|-startfg|-start_wait|-restart|-status|-stop"
  ;;

esac

exit 0;

