#!/bin/sh
#-------------------------------------------------------------------------------
# charon_cmdline
#-------------------------------------------------------------------------------
# Copyright (C) 2013-2022 STROMASYS.
# All rights reserved.
#
#set -x
VERSION=1.18

. `dirname $0`/charon_common
. `dirname $0`/charon_common_menu

LOGFLIST="${CHARONDIR}/utils/charon_logchk.list"
BOOTLIST="${CHARONDIR}/utils/charon_gstart.boot"

get_lastused

get_preferences

function The_End
{
  case "$1"
  in
    "I")
      echo -n "[INFO ] "
      RET=0
      ;;
    "W")
      echo -n "[46m[30m[WARN ][0m "
      RET=1
      ;;
    "E")
      echo -n "[41m[30m[ERROR][0m "
      RET=2
      ;;
    *)
      echo -n "[45m[30m[UNKN ][0m "
      RET=3
      ;;
  esac
  echo "$2"
  tput sgr0
  exit ${RET}
}

function Find_Lastlog
{
  RET=0
  LOGLIST="/tmp/`basename $0`_$$.tmp"
  rm -f ${LOGLIST} 2>/dev/null
  if test -s ${BOOTLIST}
  then
    cat ${BOOTLIST} | while read LINE
    do
      CFG=`echo ${LINE} | cut -f2 -d';'`
      get_logfile ${CFG}
      test -n "${LOGF}" && echo "${CFG};${LOGF}" >>${LOGLIST}
    done
    NBLOGS=`wc -l ${LOGLIST} 2>/dev/null | awk '{print $1}'`
    case ${NBLOGS:-0}
    in
      0)
        RET=1
        ;;
      1)
        RET=0
        SLOG=`cat ${LOGLIST} | cut -f2 -d';'`
        ;;
      *)
        echo -n "[44m[37m Log files found [0m"
        if test "${SEMIGRAPH}" = "enabled"
        then
          tput smacs
          echo "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"
          tput rmacs
        else
          echo "---------------------------------------------------------------"
        fi
        typeset -i I=0
        cat ${LOGLIST} | while read LINE
        do
          I=I+1
          CFG=`echo ${LINE} | cut -f1 -d';'`
          LOGF=`echo ${LINE} | cut -f2 -d';'`
          printf "%2d - " $I
          echo "${FGBLUE}${LOGF}[0m"
          echo -n "     Configuration: ${CFG}   Service state: "
          CHARONSVC="charon_`basename ${CFG}|sed 's=\.cfg$==g'`"
          SVC_IS_ACTIVE=`systemctl is-active ${CHARONSVC} 2>/dev/null | cut -f1 -d'-' | tr [:lower:] [:upper:]`
          case "${SVC_IS_ACTIVE}"
          in
            ACTIVE)
              echo "[42m[30m ${SVC_IS_ACTIVE} [0m"
              ;;
            ACTIVATING)
              echo "[40m[32m[1m ${SVC_IS_ACTIVE} [0m"
              ;;
            INACTIVE)
              echo "[40m[37m[1m ${SVC_IS_ACTIVE} [0m"
              ;;
            DEACTIVATING)
              echo "[46m[30m ${SVC_IS_ACTIVE} [0m"
              ;;
            FAILED)
              echo "[41m[37m[1m ${SVC_IS_ACTIVE} [0m"
              ;;
            UNKNOWN)
              #--Workaround for CentOS7: on RHEL7 services go "inactive", on CentOS7, it's "unknown" !
              CHK_IS_ACTIVE=`systemctl show -p ActiveState ${CHARONSVC} 2>/dev/null | cut -f2 -d'=' | tr [:lower:] [:upper:]`
              test "${CHK_IS_ACTIVE}" = "INACTIVE" && SVC_IS_ACTIVE=${CHK_IS_ACTIVE}
              echo "[45m[37m[1m ${SVC_IS_ACTIVE} [0m"
              ;;
            *)
              echo "[1m ${SVC_IS_ACTIVE} [0m"
              ;;
          esac
          if test -e ${LOGF}
          then
            LOGNBL=`wc -l ${LOGF} | awk '{print $1}'`
            LOGDAT=`ls -l --full-time ${LOGF} | awk '{print $6,$7}' | awk -F '.' '{print $1}'`
            echo -n "     Lines: ${LOGNBL} - Dated ${LOGDAT}"
          else
            echo -n "     [35mFile does not exist[0m"
          fi
          test -L ${LOGF} && echo " (rotating log file)" || echo
          if test "${SEMIGRAPH}" = "enabled"
          then
            tput smacs
            echo "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"
            tput rmacs
          else
            echo "--------------------------------------------------------------------------------"
          fi
        done
        while test 1
        do
          echo -n "Select the log file (q to quit): "
          read ANS
          if test "${ANS}" = "q"
          then
            RET=2
            break
          else
            if test -n "${ANS}"
            then
              if test -z "`echo ${ANS} | tr -d [0123456789]`"
              then
                if test ${ANS} -lt 1 -o ${ANS} -gt `cat ${LOGLIST} | wc -l`
                then
                  tput bold
                  echo "Incorrect value, out of range."
                  tput sgr0
                  sleep 1
                else
                  SLOG=`head -${ANS} ${LOGLIST} | tail -1 | cut -f2 -d';'`
                  RET=0
                  break
                fi
              else
                tput bold
                echo "Incorrect value, must be numeric."
                tput sgr0
                sleep 1
              fi
            fi
          fi
          tput cuu1;tput el
        done
        ;;
    esac
  else
    RET=1
  fi
  rm -f ${LOGLIST} 2>/dev/null
  return ${RET}
}

function Find_Guest
{
  RET=0
  CFGLIST="/tmp/`basename $0`_$$.tmp"
  rm -f ${CFGLIST} 2>/dev/null
  if test -s ${BOOTLIST}
  then
    NBGUESTS=`wc -l ${BOOTLIST} 2>/dev/null | awk '{print $1}'`
    if test ${NBGUESTS} -eq 1
    then
      CFG=`cat ${BOOTLIST} | cut -f2 -d';'`
      ANS=1
    else
      if test -n "$1"
      then
        CFG=`echo $1 | sed "s=\.cfg$==g"`
        test "`echo ${CFG}|cut -c1`" = "/" && CFG=`echo ${CFG}|cut -c2-`
        ANS=`grep -n -e "/${CFG}\.cfg;" -e "/${CFG}\.cfg$" ${BOOTLIST} | cut -f1 -d':'`
        CFG=`grep -e "/${CFG}\.cfg;" -e "/${CFG}\.cfg$" ${BOOTLIST} | cut -f2 -d';'`
        test -z "${ANS}" && The_End W "There is no virtual machine corresponding to $1"
        echo ${ANS} >${LASTUSED}
      else
        VMUSE=`cat ${LASTUSED} 2>/dev/null`
        test -z "${VMUSE}" && The_End W "Please specify the configuration file name (shortened)"
        ANS=${VMUSE}
      fi
    fi
  else
    The_End W "No virtual machine defined. Cannot continue."
  fi
}

function Usage
{
  case "$1"
  in
    vmlist)
      cat <<EOF
`tput bold`USAGE`tput sgr0`:
  vmlist [-l | --lite]

`tput bold`DESCRIPTION`tput sgr0`:
  Display the list of managed virtual machines and their status

`tput bold`PARAMETERS`tput sgr0`:
  `tput bold`-h`tput sgr0`           : display help text
  `tput bold`-l`tput sgr0` or `tput bold`--lite`tput sgr0` : display only configuration file name, service status, model
                 and description.

`tput bold`EXAMPLES`tput sgr0`:
  # `tput bold`vmlist`tput sgr0`

EOF
      ;;
    taillogfile)
      cat <<EOF
`tput bold`USAGE`tput sgr0`:
  logtail [options] [logfile]

`tput bold`DESCRIPTION`tput sgr0`:
  Continuous view of a CHARON virtual machine log file with highlights.
  Press <CTRL-C> to stop the view.

  If <logfile> is empty, the script will look for available log files in the
  virtual machines list managed by the Toolkit. If only one is managed, the
  current log will be selected, if more than one virtual machine is present,
  a selection menu will appear.

  Note: it is recommended to enlarge the terminal window to at least 132 
        columns

`tput bold`PARAMETERS`tput sgr0`:
  `tput bold`-h`tput sgr0` : display help text

`tput bold`EXAMPLES`tput sgr0`:
  # `tput bold`logtail`tput sgr0`

  # `tput bold`logtail /charon/logs/pluto.log`tput sgr0`

EOF
      ;;
    viewlogvim)
      TVIM="`tput cuu1`"
      test -z "`which vim 2>/dev/null`" && TVIM="  ('vim' must be installed)"
      cat <<EOF
`tput bold`USAGE`tput sgr0`:
  logview [options] [logfile]

`tput bold`DESCRIPTION`tput sgr0`:
  Uses 'vim' editor to view a CHARON virtual machine log file with highlights.
${TVIM}

  If <logfile> is empty, the script will look for available log files in the
  virtual machines list managed by the Toolkit. If only one is managed, the
  current log will be selected, if more than one virtual machine is present,
  a selection menu will appear.

  Notes: - It is recommended to enlarge the terminal window to at least 132
           columns
         - If using the graphical version of 'vim', the window size is set
           to 32 lines and 160 columns by default

`tput bold`PARAMETERS`tput sgr0`:
  `tput bold`-h`tput sgr0`          : display help text
  `tput bold`-g`tput sgr0`, `tput bold`--gui`tput sgr0`   : use 'gvim' instead of 'vim' (if installed)
  `tput bold`-s`tput sgr0`, `tput bold`--short`tput sgr0` : edit a copy of the log file without 'regular license check'
                  messages

`tput bold`EXAMPLES`tput sgr0`:
  # `tput bold`logview`tput sgr0`

  # `tput bold`logview -g`tput sgr0`

  # `tput bold`logview -s /charon/logs/pluto.log`tput sgr0`

EOF
      ;;
    vmstart)
      cat <<EOF
`tput bold`USAGE`tput sgr0`:
  vmstart [configuration file]

`tput bold`DESCRIPTION`tput sgr0`:
  Starts the virtual machine specified. The specified file can be
  shortened. For example if the configuration file name is
  '/charon/pluto.cfg', specifying 'pluto' is enough.
  If there's only one virtual machine defined, there is no need to specify it.
  On next command, the virtual machine used is remembered so no need to specify
  it again unless you want to select another virtual machine.

`tput bold`PARAMETERS`tput sgr0`:
  `tput bold`-h`tput sgr0` : display help text

`tput bold`EXAMPLES`tput sgr0`:
  # `tput bold`vmstart`tput sgr0`

  # `tput bold`vmstart pluto`tput sgr0`

`tput bold`SEE ALSO`tput sgr0`:
  vmlist, vmstop, vmcfg, vmconsole

EOF
      ;;
    vmstop)
      cat <<EOF
`tput bold`USAGE`tput sgr0`:
  vmstop [configuration file]

`tput bold`DESCRIPTION`tput sgr0`:
  Stops the virtual machine specified. The specified file can be
  shortened. For example if the configuration file name is
  '/charon/pluto.cfg', specifying 'pluto' is enough.
  If there's only one virtual machine defined, there is no need to specify it.
  On next command, the virtual machine used is remembered so no need to specify
  it again unless you want to select another virtual machine.

`tput bold`PARAMETERS`tput sgr0`:
  `tput bold`-f`tput sgr0` : forces the stop of the virtual machine without confirmation request
  `tput bold`-h`tput sgr0` : display help text

`tput bold`EXAMPLES`tput sgr0`:
  # `tput bold`vmstop`tput sgr0`

  # `tput bold`vmstop pluto`tput sgr0`

`tput bold`SEE ALSO`tput sgr0`:
  vmlist, vmstart, vmcfg, vmconsole

EOF
      ;;
    vmconsole)
      cat <<EOF
`tput bold`USAGE`tput sgr0`:
  vmconsole [configuration file]

`tput bold`DESCRIPTION`tput sgr0`:
  Connect to the console of the virtual machine specified. The specified file
  can be shortened if unique in the virtual machines list (for example if the
  configuration file name is '/charon/pluto.cfg', specifying 'pluto' is
  enough).
  If there's only one virtual machine defined, there is no need to specify it.
  If the virtual machine is not started, you will be prompted to start it.
  On next command, the virtual machine used is remembered so no need to specify
  it again unless you want to select another virtual machine.

`tput bold`PARAMETERS`tput sgr0`:
  `tput bold`-h`tput sgr0` : display help text

`tput bold`EXAMPLES`tput sgr0`:
  # `tput bold`vmconsole`tput sgr0`

  # `tput bold`vmconsole pluto`tput sgr0`

`tput bold`SEE ALSO`tput sgr0`:
  vmlist, vmstart, vmstop, vmcfg

EOF
      ;;
    vmcfg)
      cat <<EOF
`tput bold`USAGE`tput sgr0`:
  vmcfg [configuration file]

`tput bold`DESCRIPTION`tput sgr0`:
  Edit the configuration file specified. The specified file can be shortened
  if unique in the virtual machines list (for example if the configuration
  file name is '/charon/pluto.cfg', specifying 'pluto' is enough).
  If there's only one virtual machine defined, there is no need to specify it.
  On next command, the virtual machine used is remembered so no need to specify
  it again unless you want to select another virtual machine.

`tput bold`PARAMETERS`tput sgr0`:
  `tput bold`-h`tput sgr0` : display help text

`tput bold`EXAMPLES`tput sgr0`:
  # `tput bold`vmcfg`tput sgr0`

  # `tput bold`vmcfg pluto`tput sgr0`

`tput bold`SEE ALSO`tput sgr0`:
  vmlist, vmstart, vmstop, vmconsole

EOF
      ;;
    *)
      cat <<EOF
`tput bold`USAGE`tput sgr0`:
  $0 taillogfile [options] [logfile]
  $0 viewlogvim [options] [logfile]
  $0 vmlist
  $0 vmstart [configuration file (name)]
  $0 vmstop [configuration file (name)]
  $0 vmconsole [configuration file (name)]
  $0 vmcfg [configuration file (name)]

`tput bold`DESCRIPTION`tput sgr0`:
  Usually called using 'logtail', 'logview', 'vmlist', 'vmstart', 'vmstop',
  'vmconsole' or 'vmcfg' aliases.

  If the aliases above are not defined, please run:
  # `tput bold`${CHARONDIR}/utils/menusetup --alias`tput sgr0`

EOF
      ;;
  esac
  exit
}

if test `id -u` -ne 0
then
  if test "${ENABLESUDO}" = "1"
  then
    sudo $0 $1 $2
  else
    echo "[46m[30m WARNING [0m"
    tput bold
    echo "You must be root or execute the command. It is also possible to enable 'sudo'"
    echo "from the menu/Preferences option."
    tput sgr0
    echo "Please contact your system administrator for 'sudo' settings."
  fi
  exit
fi


case "$1"
in
  "-h"|"--help")
    Usage
    ;;
  vmlist)
    test "$2" = "-h" -o "$2" = "--help" && Usage $1
    LITEON=""
    test "$2" = "-l" -o "$2" = "--lite" && LITEON="LITE"

    RPMINSTPAR=`rpm -q charon-par | grep -v 'not installed' | \
                sed "s=\(^charon-par-\)\(.*\)-\(.*\)\(\..*$\)=Charon-PAR V\2 B\3=g"`
    if test -z "${RPMINSTPAR}"
    then
      RPMINST=""
    else
      RPMINST=${RPMINSTPAR}
      tput bold
      echo -n "${FGBLUE}Installed: "
      tput sgr0
      echo ${RPMINST}
    fi

    display_guestslist ${LITEON}
    ABS=""
    RPMCONTENT=`rpm -q -l aksusbd 2>/dev/null | grep /usr/sbin`
    for AK in aksusbd winehasp hasplmd
    do
      if test -n "`echo ${RPMCONTENT} | grep -w ${AK}`"
      then
        ps -ef | grep /usr/sbin/${AK} | grep -v grep >/dev/null 2>&1
        test $? = 0 || ABS="${ABS} ${AK}"
      fi
    done
    if test -n "${ABS}"
    then
      echo
      echo "[41m[30m[ERROR][0m License driver issue, missing daemons:${ABS}"
    fi
    ;;
  taillogfile)
    test "$2" = "-h" -o "$2" = "--help" && Usage $1
    SLOG="$2"
    if test -z "${SLOG}"
    then
      Find_Lastlog
    else
      true
    fi
    RET=$?
    if test ${RET} = 0
    then
      if test -e ${SLOG}
      then
        tail_log_colored ${SLOG} "NOSTOP"
      else
        The_End E "The log file '${SLOG}' does not exist"
      fi
    else
      test ${RET} != 2 && The_End E "Log file not specified or not found"
    fi
    ;;
  viewlogvim)
    EDI="/usr/bin/vim"
    NO_LLSENTINE=0
    shift
    while test $# -ne 0
    do
      case "$1"
      in
        "-h"|"--help")
          Usage viewlogvim
          ;;
        "-g"|"--gui")
          if test -x /usr/bin/gvim
          then
            EDI="/usr/bin/gvim"
          else
            The_End E "'gvim' is not installed. Please install to use '-g' option"
          fi
          ;;
        "-s"|"--short")
          NO_LLSENTINE=1
          ;;
        -*)
          The_End E "Invalid parameter. Use 'logview -h'"
          ;;
        *)
          SLOG="$1"
          ;;
      esac
      shift
    done
    if test -z "${SLOG}"
    then
      Find_Lastlog
    else
      true
    fi
    RET=$?
    if test ${RET} = 0
    then
      if test -e ${SLOG}
      then
        if test -s ${SLOG}
        then
          if test -x ${EDI}
          then
            CVIMRC="${CHARONDIR}/utils/charonlog.vimrc"
            P="";test -e ${CVIMRC} && P="-u ${CVIMRC}"
            echo "Editing '${SLOG}' file..."
            if test ${NO_LLSENTINE} = 1
            then
              cat ${SLOG} | grep -v -e ":000003BA:" -e ":000003DC:" -e ":000003E6:" -e ":000003E7:" \
                  >/tmp/`basename ${SLOG}`.short
              SLOG=/tmp/`basename ${SLOG}`.short
            fi
            ${EDI} -m ${P} ${SLOG}
          else
            The_End W "'vim' must be installed to use this option"
          fi
        else
          The_End W "Log file '${SLOG}' is empty"
        fi
      else
        The_End E "The log file '${SLOG}' does not exist"
      fi
    else
      test ${RET} != 2 && The_End E "Log file not specified or not found"
    fi
    ;;
  vmstart|vmstop)
    VMX=$1
    VMFORCE=0
    VMDEF=""
    shift
    while test $# -ne 0
    do
      case "$1"
      in
        -h|--help)
          Usage ${VMX}
          ;;
        -f|--force)
          VMFORCE=1
          ;;
        *)
          VMDEF=$1
          ;;
       esac
       shift
    done

    Find_Guest ${VMDEF}
    if test -n "${ANS}"
    then
      if test ${VMFORCE} -eq 0
      then
        ${CHARONDIR}/utils/charon_menu_gstart cmd ${ANS} ${VMX}
      else
        echo y | ${CHARONDIR}/utils/charon_menu_gstart cmd ${ANS} ${VMX}
      fi
    fi
    ;;
  vmconsole)
    test "$2" = "-h" -o "$2" = "--help" && Usage $1
    Find_Guest $2
    test -n "${ANS}" && ${CHARONDIR}/utils/charon_menu_console cmd ${ANS}
    ;;
  vmcfg)
    test "$2" = "-h" -o "$2" = "--help" && Usage $1
    Find_Guest $2
    test -n "${ANS}" && ${CHARONDIR}/utils/charon_menu_editcfg cmd ${ANS}
    ;;
  *)
    The_End E "incorrect parameter '$1'"
    ;;
esac

exit
