#!/bin/sh
#-------------------------------------------------------------------------
# charon_common_menu for Charon-AXP/VAX
#-------------------------------------------------------------------------
# Copyright (C) 2013-2022 STROMASYS.
# All rights reserved.
#
VERSION=1.56

#=============================================================================
# Function: Press_Enter
#=============================================================================
function Press_Enter
{
  echo
  echo -n "[44m[37mPress enter[0m"
  read ENTER
  tput cuu1;tput el
}

#=============================================================================
# Function: display_guestslist
#=============================================================================
function display_guestslist
{
  if test ! -e /usr/bin/bc
  then
    tput bold
    echo "[46m[30m WARNING [0m 'bc' is not installed on this system".
    echo "          Please install the missing package before continuing."
    tput sgr0
    echo
    Press_Enter
    exit 1
  fi
  LITEON="$1"
  test "${LITEON}" = "-num" && LITEON=""
  get_preferences
  
  get_lastused
  VMSEL=`cat ${LASTUSED} 2>/dev/null`
  
  CR=`echo -e "\r"`
  if test -e ${NCUBIN}
  then
    NCUDIR=`dirname ${NCUBIN}`
    eval `grep ^NCU_CFG= ${NCUDIR}/* | cut -f2 -d':' | sort -u | head -1`
  fi
  PORTCF=/tmp/charon_chkport_conflict.tmp.$$
  NICCF=/tmp/charon_chknic_conflict.tmp.$$
  LOGCF=/tmp/charon_chklog_conflict.tmp.$$
  CONSCF=/tmp/charon_chkcons_conflict.tmp.$$
  rm -f ${PORTCF} ${NICCF} ${LOGCF} ${CONSCF} 2>/dev/null
  SRVBOOT=`who -b | sed "s=.*system boot ==g"`
  SRVBOOT=`date +"%d-%b-%Y %H:%M" -d "${SRVBOOT}"`

  echo -n "${FGBLUEBOLD}Server boot:[0m ${SRVBOOT}"
  echo -n "  ${FGBLUEBOLD}CPUs:[0m "
  echo -n `grep -w ^processor /proc/cpuinfo | wc -l`
  echo -n "  ${FGBLUEBOLD}Memory(free/tot):[0m "
  MEMFREE=`free -m | grep ^Mem: | awk '{print $4}'`
  MEMTOTA=`free -m | grep ^Mem: | awk '{print $2}'`
  typeset -i MEMPCTFREE=`echo ${MEMFREE}*100/${MEMTOTA} | bc`
  free -h >/dev/null 2>&1
  if test $? = 0
  then
    MEMFREE=`free -h | grep ^Mem: | awk '{print $4}'`
    MEMTOTA=`free -h | grep ^Mem: | awk '{print $2}'`
  fi
  test ${MEMPCTFREE} -ge 20 && MEMCOLOR="2"
  test ${MEMPCTFREE} -lt 20 && MEMCOLOR="5"
  test ${MEMPCTFREE} -lt 10 && MEMCOLOR="1"
  echo "${MEMFREE}/${MEMTOTA} ([3${MEMCOLOR}m${MEMPCTFREE}%[0m)"
  echo
  tput sgr0
  tput bold
  echo -n "${FGBLUE}"
  echo "Configuration File                           Cpu Memory State/Uptime[0m${FGBLUE}: d hh:mm:ss[0m"
  tput sgr0
  test ! -e ${BOOTLIST} && touch ${BOOTLIST}
  if test `grep -v ^# ${BOOTLIST} | wc -l` -eq 0
  then
    if test "${SEMIGRAPH}" = "enabled"
    then
      tput smacs
      echo "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq qqq qqqqqq qqqqqqqqqqqqqqqqqqqqqqqq"
      tput rmacs
    else
      echo "-------------------------------------------- --- ------ ------------------------"
    fi
    echo "No virtual machine defined."
  else
    INSBLD=`rpm -q charon-license 2>/dev/null | cut -f4 -d'-' | cut -f1 -d'.'`
    INSBLD=${INSBLD:-0}
    typeset -i I=0
    NICALERT1=0
    NICALERT2=0
    NICALERT3=0
    NICALERT4=0
    NICALERT5=0
    for LINE in `grep -v ^# ${BOOTLIST}`
    do
      I=I+1

      if test $I -eq 1
      then
        if test "${SEMIGRAPH}" = "enabled"
        then
          tput smacs
          echo "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq qqq qqqqqq qqqqqqqqqqqqqqqqqqqqqqqq"
          tput rmacs
        else
          echo "-------------------------------------------- --- ------ ------------------------"
        fi
      else
        case "${LISTSEPAR}"
        in
          "line")
            if test "${SEMIGRAPH}" = "enabled"
            then
              tput smacs
              echo "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq qqq qqqqqq qqqqqqqqqqqqqqqqqqqqqqqq"
              tput rmacs
            else
              echo "-------------------------------------------- --- ------ ------------------------"
            fi
            ;;
          "blank")
            echo
            ;;
        esac
      fi
      tput sgr0

      test "$1" = "-num" && printf "%2d" $I
      CHARON_EXE=`echo ${LINE} | cut -f1 -d';'`
      CHARON_CFG=`echo ${LINE} | cut -f2 -d';'`
      if test -s ${CHARON_CFG}
      then
        if test `grep -c "${CR}$" ${CHARON_CFG}` -gt 0
        then
          cat ${CHARON_CFG} | tr -d "\r" >${CHARON_CFG}.noCR
          mv -f ${CHARON_CFG} ${CHARON_CFG}.bak
          mv -f ${CHARON_CFG}.noCR ${CHARON_CFG}
        fi

        CHARON_CFGBAS=`basename ${CHARON_CFG}|sed "s=\.cfg==g"`
        CHARON_BOO=`echo ${LINE} | cut -f3 -d';'`

        EMUX1=`basename ${CHARON_EXE}`
        EMUX1=`echo ${EMUX1} | cut -c1-14`
        test "$1" = "-num" && EMUX1=`echo ${EMUX1} | cut -c1-12`
        #EMUX2=${CHARON_CFGBAS}
        EMUX2=${CHARON_CFG}
        #test `echo ${EMUX2} | wc -c` -gt 23 && EMUX2="..${CHARON_CFGBAS}.cfg"
        #EMUX2=`echo ${EMUX2} | cut -c1-23`

        test $I -eq ${VMSEL:-0} && IDN="*" || IDN="-"

        echo -n "[1m"
        echo -n "${IDN} "
        echo -n `dirname ${EMUX2}`
        echo -n "/${FGBLUEBOLD}"
        echo -n `basename ${EMUX2} | sed "s=\.cfg$=[0m[1m.cfg=g"`
        echo -n "[0m"

        HWM=`grep -w hw_model ${CHARON_CFG} | grep session | grep set | grep -v ^# | awk -F'=' '{print $2}' | tr -d "'\"" | tr -d " "`
        EMUCPU=`grep -w n_of_cpus ${CHARON_CFG} | grep -v ^# | cut -f2 -d'='`
        if test -z "${EMUCPU}"
        then
          EMUCPU=`grep "^${HWM}=" ${CHARONDIR}/utils/charon_hwmodel.cpus 2>/dev/null | cut -f2 -d'='`
        fi
        EMUMEM=`grep -w ram ${CHARON_CFG} | grep -v ^# | cut -f2 -d'='`
        if test -n "${EMUMEM}"
        then
          if test ${EMUMEM} -lt 1000
          then
            EMUMEM="${EMUMEM}M"
          else
            EMUMEM="`echo ${EMUMEM}/1024|bc`G"
          fi
        else
          EMUMEM=`grep "^${HWM}=" ${CHARONDIR}/utils/charon_hwmodel.memory 2>/dev/null | cut -f2 -d'='`
        fi

        tput hpa 44
        echo -n " "
        printf "%3s %6s" "${EMUCPU:--}" "${EMUMEM:--}"

        PORTLINE=`grep -v ^# ${CHARON_CFG} | grep -w load | grep -w virtual_serial_line | grep OPA`
        PORTMODE=""
        if test -n "${PORTLINE}"
        then
          PORTMODE="load"
        else
          if test ${INSBLD} -ge 19103
          then
            PORTLINE=`grep -v ^# ${CHARON_CFG} | grep -w set | grep -w alias | grep -w OPA0 | grep -w port`
            if test -n "${PORTLINE}"
            then
              PORTMODE="alias"
            else
              PORTLINE=`grep -v ^# ${CHARON_CFG} | grep -w set | grep -w OPA0 | grep -w port`
              test -n "${PORTLINE}" && PORTMODE="v412"
            fi
          fi
        fi          
        PORT=`echo ${PORTLINE} | sed "s/[ \t]\{1,\}/ /g" | sed "s/ =/=/g" | sed "s/= /=/g" | sed "s=\(^.*port\=\)\([0-9]\{1,\}\)\(.*$\)=\2=g"`
        echo "${PORT}" >>${PORTCF}

        RMCPLINE=`grep -v ^# ${CHARON_CFG} | grep -w remote_management_console | grep -w port`
        RMCP=`echo ${RMCPLINE} | sed "s/[ \t]\{1,\}/ /g" | sed "s/ =/=/g" | sed "s/= /=/g" | sed "s=\(^.*port\=\)\([0-9]\{1,\}\)\(.*$\)=\2=g"`
        test -n "${RMCP}" && echo "${RMCP}" >>${PORTCF}

        GETIME=""
        CSTATE1=""
        CSTATE2=""
        CSTATE3=""

        OOMKPROT=""
        if test "${SEMIGRAPH}" = "enabled"
        then
          OOMKD1="`tput smacs`l`tput rmacs`"
          OOMKD2="`tput smacs`m`tput rmacs`"
          OOMKDM="`tput smacs`x`tput rmacs`"
        else
          OOMKD1="+"
          OOMKD2="+"
          OOMKDM="|"
        fi

        SVC_IS_ACTIVE=`systemctl is-active charon_${CHARON_CFGBAS}.service 2>/dev/null | cut -f1 -d'-' | tr [:lower:] [:upper:]`
        case "${SVC_IS_ACTIVE}"
        in
          ACTIVE)
            CSTATE1="[42m[30m${SVC_IS_ACTIVE}[0m"
            GSTA=`systemctl show -p ActiveEnterTimestamp charon_${CHARON_CFGBAS}.service | cut -f2 -d'='`
            GPID=`systemctl show -p ExecMainPID charon_${CHARON_CFGBAS}.service | cut -f2 -d'='`
            GETIME=`ps -o etime -p ${GPID} | tail -1 | sed -e "s=-= =g"`

            OOMKPROT=""
            get_preferences
            if test "${OOMPRVPIDKILL}" = "enabled"
            then
              if test "`cat /proc/${GPID}/oom_score_adj 2>/dev/null`" = "-1000"
              then
                OOMKPROT="Protected against OOM Killer."
              else
                echo "-1000" >/proc/${GPID}/oom_score_adj
                OOMKPROT="[36mProtection set against OOM Killer."
              fi
            else
              echo "0" >/proc/${GPID}/oom_score_adj 2>/dev/null
              OOMKPROT="[90mNot protected against OOM Killer."
            fi

            GMEM=`pmap ${GPID} | tail -1 | awk '{print $2}' | tr -d "K"`
            GMEM=`echo ${GMEM} / 1024 | bc | sed ':a;s/\B[0-9]\{3\}\>/,&/;ta'`
            CSTATE2="${FGBLUE}Started:[0m        ${OOMKD1} ${GSTA} PID=${GPID} Memory=${GMEM}M"

            GSTADAT=`systemctl show -p ActiveEnterTimestamp charon_${CHARON_CFGBAS}.service | awk '{print $2,$3}'`
            GCFGDAT=`date +"%Y%m%d%H%M%S" -r ${CHARON_CFG}`
            if test "${GCFGDAT}" -gt "`echo ${GSTADAT} | tr -dc [:digit:]`"
            then
              CSTATE3="                  [46m[30mConfiguration file updated after process started ![0m"
            fi
            ;;
          ACTIVATING)
            CSTATE1="[40m[32m[1m${SVC_IS_ACTIVE}[0m"
            GSUB=`systemctl show -p SubState charon_${CHARON_CFGBAS}.service | cut -f2 -d'='`
            CSTATE2="${FGBLUE}Substate:[0m [1m[32m${GSUB}[0m"
            ;;
          INACTIVE)
            if test -s /etc/systemd/system/charon_${CHARON_CFGBAS}.service
            then
              CSTATE1="[40m[37m[1m${SVC_IS_ACTIVE}[0m"
            else
              CSTATE1="[40m[37m[1m${SVC_IS_ACTIVE}[0m [41m[30mUNKNOWN[0m"
              CHARON_BOO="-"
            fi
            GSTO=`systemctl show -p InactiveEnterTimestamp charon_${CHARON_CFGBAS}.service | cut -f2 -d'='`
            if test -n "${GSTO}"
            then
              GSIG=`systemctl show -p Result charon_${CHARON_CFGBAS}.service | cut -f2 -d'='`
              CSTATE2="${FGBLUE}Stopped:[0m          ${GSTO} (${GSIG})"
            else
              CSTATE2="${FGBLUE}Stopped:[0m          Not started since server booted"
            fi
            ;;
          DEACTIVATING)
            CSTATE1="[36m${SVC_IS_ACTIVE}[0m"
            ;;
          FAILED)
            CSTATE1="[41m[37m[1m${SVC_IS_ACTIVE}[0m"
            GSTO=`systemctl show -p InactiveEnterTimestamp charon_${CHARON_CFGBAS}.service | cut -f2 -d'='`
            GSIG=`systemctl show -p Result charon_${CHARON_CFGBAS}.service | cut -f2 -d'='`
            GMST=`systemctl show -p ExecMainStatus charon_${CHARON_CFGBAS}.service | cut -f2 -d'='`
            if test ${GMST:-0} = 0
            then
              GMST=`systemctl show -p ExecStart charon_${CHARON_CFGBAS}.service | cut -f8 -d';' | tr -d '{ }' | cut -f2 -d'='`
            else
              GMST=`kill -l ${GMST} 2>/dev/null`
            fi
            CSTATE2="${FGBLUE}Stopped:[0m          ${GSTO} ([31m${GSIG}[0m/${GMST:-unknown})"
            ;;
          UNKNOWN)
            CSTATE1="[45m[37m[1m${SVC_IS_ACTIVE}[0m"
            if test "${CHARON_BOO}" != "N"
            then
              CSTATE2="[31mWarning:[0m Service not defined in systemd -> remove guest and add again"
            else
              SVC_IS_ACTIVE=`systemctl show -p ActiveState charon_${CHARON_CFGBAS}.service 2>/dev/null | cut -f2 -d'=' | tr [:lower:] [:upper:]`
              if test "${SVC_IS_ACTIVE}" = "INACTIVE"
              then
                CSTATE1="[40m[37m[1m${SVC_IS_ACTIVE}[0m"

                #--Workaround for CentOS7: on RHEL7 services go "inactive", on CentOS7, it's "unknown" !
                GSTO=`systemctl -o short-iso status charon_${CHARON_CFGBAS}.service 2>/dev/null |grep -w systemd | grep -w Stopped | awk '{print $1}'`
                if test -n "${GSTO}"
                then
                  GSTO=`date -d ${GSTO} +"%d-%b-%Y %H:%M:%S"`
                  GSIG=`systemctl show -p Result charon_${CHARON_CFGBAS}.service | cut -f2 -d'='`
                  CSTATE2="${FGBLUE}Stopped:[0m          ${GSTO} (${GSIG})"
                else
                  CSTATE2="${FGBLUE}Stopped:[0m          <unknown>"
                fi
              else
                SVC_IS_ENABLED=`systemctl is-enabled charon_${CHARON_CFGBAS}.service 2>/dev/null | cut -f1 -d'-' | tr [:lower:] [:upper:]`
                CSTATE2="${FGBLUE}State:[0m            ${SVC_IS_ACTIVE} / ${SVC_IS_ENABLED}"
              fi
            fi
            ;;
          *)
            CSTATE1="${SVC_IS_ACTIVE}"
            ;;
        esac

        #--- systemctl correction if needed
        if test "${SVC_IS_ACTIVE}" != "UNKNOWN"
        then
          SVC_IS_ENABLED=`systemctl is-enabled charon_${CHARON_CFGBAS}.service 2>/dev/null | cut -f1 -d'-' | tr [:lower:] [:upper:]`
          if test "${CHARON_BOO}" = "N" -a "${SVC_IS_ENABLED}" = "ENABLED"
          then
            systemctl disable charon_${CHARON_CFGBAS}.service 2>/dev/null
          fi
          if test "${CHARON_BOO}" = "Y" -a "${SVC_IS_ENABLED}" = "DISABLED"
          then
            systemctl enable charon_${CHARON_CFGBAS}.service 2>/dev/null
          fi
        fi

        tput hpa 56
        echo -n "${CSTATE1}"

        tput hpa 68
        printf "%12s\n" "${GETIME}"

        if test -x ${CHARONDIR}/utils/charon_gstart.stop
        then
          CHK=`grep "${CHARON_CFG})" ${CHARONDIR}/utils/charon_gstart.stop`
          if test -n "${CHK}"
          then
            CSEQ="[31mTo customize[0m"
            ACFG=`echo ${CHARON_CFG} | sed "s=/=\\\\\\/=g"`
            awk "/${ACFG})/,/;;/" ${CHARONDIR}/utils/charon_gstart.stop >/tmp/display_guests$$.tmp1
            grep -v -e "#\\$" -e "^#" -e "#/" -e "#--" /tmp/display_guests$$.tmp1 | grep -v -e "${CHARON_CFG})" -e ";;" >/tmp/display_guests$$.tmp2
            ACFG=`cat /tmp/display_guests$$.tmp2`
            rm -f /tmp/display_guests$$.tmp[12] >/dev/null 2>&1
            if test -n "`echo ${ACFG} | grep '/utils/charon_gstop_rsh'`"
            then
              CSEQ="[32m[Using RSH][0m"
            else
              if test -n "`echo ${ACFG} | grep '/utils/charon_gstop_ssh'`"
              then
                CSEQ="[32m[Using SSH][0m"
              else
                if test -n "`echo ${ACFG} | grep '/utils/charon_gstop_expect'`"
                then
                  CSEQ="[32m[Using EXPECT][0m"
                else
                  if test "`echo ${ACFG} | tr -dc [:alnum:]`" = "exit1"
                  then
                    CSEQ="[31mEXIT 1 ![0m"
                  else
                    if test -z "${ACFG}"
                    then
                      CSEQ="[35mNo action![0m"
                    else
                      CSEQ="${FGBLUE}Customized[0m"
                    fi
                  fi
                fi
              fi
            fi
          else
            CSEQ="[35mCase not set[0m"
          fi
        else
          CSEQ="[35mNot found[0m"
        fi

        test "$1" = "-num" && echo -n "  "
        echo "  ${FGBLUE}Model:[0m            [1m${EMUX1}[0m"

        if test ! -x ${CHARON_EXE}
        then
          test "$1" = "-num" && echo -n "  "
          echo "  [31mThe virtual machine exe file is not installed![0m"
        fi

        GSTOPOST="ExecStopPost=${CHARONDIR}/utils/charon_gstart check ${CHARON_CFG}"
        GCHKPOST=`systemctl cat charon_${CHARON_CFGBAS}.service 2>/dev/null | grep ^ExecStopPost=`
        if test "${GCHKPOST}" != "${GSTOPOST}"
        then
          test "$1" = "-num" && echo -n "  "
          echo "  [31mThe 'ExecStopPost' line is missing in service definition![0m"
          test "$1" = "-num" && echo -n "  "
          echo "  [31mPlease edit service and add:[0m"
          test "$1" = "-num" && echo -n "  "
          echo "  ExecStopPost=${CHARONDIR}/utils/charon_gstart check ${CHARON_CFG}"
          test "$1" = "-num" && echo -n "  "
          echo "  [31mfollowed by a 'systemctl daemon-reload' command.[0m"
        fi

        GSTA=`systemctl show -p LoadState charon_${CHARON_CFGBAS}.service 2>/dev/null | cut -f2 -d'='`
        if test "${GSTA}" = "loaded"
        then
          test "$1" = "-num" && echo -n "  "
          echo -n "  ${FGBLUE}Description:[0m      "
          systemctl show -p Description charon_${CHARON_CFGBAS}.service | cut -f2 -d'='

          if test "${LITEON}" = ""
          then
            GRESTART=`systemctl show -p Restart charon_${CHARON_CFGBAS}.service | cut -f2 -d'='`
            if test "${GRESTART}" != "no"
            then
              GRESTARTUSEC=`systemctl show -p RestartUSec charon_${CHARON_CFGBAS}.service | cut -f2 -d'='`
              GRESTARTLBUR=`systemctl show -p StartLimitBurst charon_${CHARON_CFGBAS}.service | cut -f2 -d'='`
              GRESTARTLINT=`systemctl show -p StartLimitInterval charon_${CHARON_CFGBAS}.service | cut -f2 -d'='`
              GRESTARTLINT=`echo ${GRESTARTLINT}/1000000 | bc`
              test "$1" = "-num" && echo -n "  "
              echo "  ${FGBLUE}Auto-restart:[0m     ${GRESTART} after ${GRESTARTUSEC}, max ${GRESTARTLBUR} times in ${GRESTARTLINT} seconds"
            fi
            GTIMEOUT1=""
            if test -n "`grep ^TimeoutStartSec= /etc/systemd/system/charon_${CHARON_CFGBAS}.service 2>/dev/null`" -o \
                    -n "`grep ^TimeoutSec= /etc/systemd/system/charon_${CHARON_CFGBAS}.service 2>/dev/null`"
            then
              GTIMEOUT1=`systemctl show -p TimeoutStartUSec charon_${CHARON_CFGBAS}.service | cut -f2 -d'='`
            fi
            GTIMEOUT2=""
            if test -n "`grep ^TimeoutStopSec= /etc/systemd/system/charon_${CHARON_CFGBAS}.service 2>/dev/null`" -o \
                    -n "`grep ^TimeoutSec= /etc/systemd/system/charon_${CHARON_CFGBAS}.service 2>/dev/null`"
            then
              GTIMEOUT2=`systemctl show -p TimeoutStopUSec charon_${CHARON_CFGBAS}.service | cut -f2 -d'='`
            fi
            test "$1" = "-num" && echo -n "  "
            echo -n "  ${FGBLUE}Startup type:[0m     "
            case "${CHARON_BOO:-Y}"
            in
              Y|y) echo -n "[32mAutomatic[0m";;
              *)   echo -n "Manual";;
            esac
            if test -n "${GTIMEOUT1}${GTIMEOUT2}"
            then
              test "$1" = "-num" && echo -n "  "
              echo -n "  / ${FGBLUE}Service Timeouts:[0m "
              test -n "${GTIMEOUT1}" && echo -n "Start=${GTIMEOUT1} "
              test -n "${GTIMEOUT2}" && echo -n "Stop=${GTIMEOUT2} "
              echo
            else
              echo
            fi
          fi
        fi

        if test "${LITEON}" = ""
        then
          test "$1" = "-num" && echo -n "  "
          echo -n "  ${FGBLUE}Stop script:[0m      "
          echo "${CSEQ}"

          if test -x ${CHARONDIR}/utils/charon_gstart.prestart
          then
            CHK=`grep "${CHARON_CFG})" ${CHARONDIR}/utils/charon_gstart.prestart`
            if test -n "${CHK}"
            then
              CSEQ=""
              ACFG=`echo ${CHARON_CFG} | sed "s=/=\\\\\\/=g"`
              awk "/${ACFG})/,/;;/" ${CHARONDIR}/utils/charon_gstart.prestart >/tmp/display_guests$$.tmp1
              grep -v -e "#\\$" -e "^#" -e "#/" -e "#--" /tmp/display_guests$$.tmp1 | grep -v -e "${CHARON_CFG})" -e ";;" >/tmp/display_guests$$.tmp2
              ACFG=`cat /tmp/display_guests$$.tmp2`
              if test -n "${ACFG}"
              then
                typeset -i P=0
                cat /tmp/display_guests$$.tmp2 | while read PST
                do
                  PSC=`echo ${PST} | cut -c1`
                  if test "${PSC}" != "#" -a -n "`echo ${PST} | tr -d "\t" | tr -d " "`"
                  then
                    P=P+1
                    test "$1" = "-num" && echo -n "  "
                    case $P
                    in
                      1)    echo "  ${FGBLUE}Pre-start:[0m        [95m${PST}[0m";;
                      2|3)  echo "                    [95m${PST}[0m";;
                      4)    echo "                    [95m${PST}[0m [32m(truncated)[0m";;
                    esac
                  fi
                done
              fi
              rm -f /tmp/display_guests$$.tmp[12] >/dev/null 2>&1
            fi
          fi

          if test -n "${CSTATE2}"
          then
            test "$1" = "-num" && echo -n "  "
            echo "  ${CSTATE2}"

            if test -n "${OOMKPROT}"
            then
              test "$1" = "-num" && echo -n "  "
              echo "                  ${OOMKD2} ${OOMKPROT}[0m"
            fi

            if test -x ${CHARONDIR}/utils/charon_gstart.chkrun
            then
              CHK=`grep "${CHARON_CFG})" ${CHARONDIR}/utils/charon_gstart.chkrun`
              if test -n "${CHK}"
              then
                if test "${SVC_IS_ACTIVE}" = "ACTIVE"
                then
                  CHK=`${CHARONDIR}/utils/charon_gstart.chkrun ${CHARON_CFG}|tr -d "\r"|grep -v ^$`
                  CHKDISP=`echo ${CHK} | sed "s:\(^.*\)\(==RETVAL=.*$\):\1:g"`
                  CHKRETV=`echo ${CHK} | sed "s:\(^.*==RETVAL=\)\(.*\)\(==.*$\):\2:g"`
                  test "$1" = "-num" && echo -n "  "
                  case "${CHKRETV}"
                  in
                    "0")
                      echo "  ${FGBLUE}Guest OS answer:[0m  [1m${CHKDISP}[0m"
                      ;;
                    "")
                      echo "  ${FGBLUE}Guest OS answer:[0m  [46m[30mScript misconfigured, RETVAL missing[0m"
                      ;;
                    *)
                      test -z "${CHKDISP}" && CHKDISP="Return code ${CHKRETV}"
                      echo "  [31mGuest OS answer:[0m  [1m${CHKDISP}[0m"
                      ;;
                  esac
                fi
              fi
            fi
          fi
          if test -n "${CSTATE3}"
          then
            test "$1" = "-num" && echo -n "  "
            echo "  ${CSTATE3}"
          fi

          test "$1" = "-num" && echo -n "  "
          echo -n "  ${FGBLUE}Console port:[0m     ${PORT:-<Unknown>}"

          CNXOVERRIDE=`grep -v ^# ${CHARON_CFG} | grep -w set | grep -w OPA0 | sed "s/[ \t]\{1,\}/ /g" | sed "s/ =/=/g" | sed "s/= /=/g" | tr [:upper:] [:lower:] | grep "connection_override=enable"`
          if test -n "${CNXOVERRIDE}"
          then
            if test "${PORTMODE}" != "load"
            then
              echo -n " ([32mCNX override ON[30m)"
            else
              echo -n " ([31mCNX override misconfigured[30m)"
            fi
          fi

          if test -n "${PORT}" -a -n "`netstat -an 2>/dev/null | grep -w ${PORT:-UNKNOWN} | grep ESTABLISHED`" 
          then
            CHKP=`ps -ef | grep SCREEN | grep telnet | grep localhost | grep -w ${PORT}`
            if test -n "${CHKP}"
            then
              echo " / [31mLocked by AUTOCONNECT utility[0m"
            else
              CHKP=`ps -ef | grep telnet | grep localhost | grep ${PORT}$ | awk '{print $2}' | tr "\n" " "`
              if test -n "${CHKP}"
              then
                echo " / [31mLocked by 'telnet' pid(s) ${CHKP}[0m"
              else
                CHKP=`ps -ef | grep putty | grep "\-P ${PORT}" | awk '{print $2}' | tr "\n" " "`
                if test -n "${CHKP}"
                then
                  echo " / [31mLocked by 'putty' pid(s) ${CHKP}[0m"
                else
                  CHKP=`netstat -an | grep -w ${PORT} | grep ESTABLISHED | awk '{print $5}'`
                  echo " / [31mLocked by foreign host `echo ${CHKP}|cut -f1 -d':'`, port `echo ${CHKP}|cut -f2 -d':'`[0m"
                fi
              fi
            fi
          else
            echo
          fi

          CHK=`grep -v ^# ${CHARON_CFG} | grep "set.*OPA[0-9].*log.*="`
          if test -n "${CHK}"
          then
            get_logfile ${CHARON_CFG} OPA0
            test "$1" = "-num" && echo -n "  "
            echo "  ${FGBLUE}Console log:[0m      ${LOGCONS:-<Unknown>}"
            LOGUNIQ=`grep "^${LOGCONS};" ${CONSCF} 2>/dev/null`
            if test -n "${LOGUNIQ}"
            then
              test "$1" = "-num" && echo -n "  "
              echo "  [31mThe log file is already used in `echo ${LOGUNIQ}|cut -f2 -d";"` virtual machine. Please check[0m"
            else
              echo "${LOGCONS};${EMUCFG}" >>${CONSCF}
            fi
          fi

          if test "$2" = "-console"
          then
            if test -n "${RMCP}"
            then
              test "$1" = "-num" && echo -n "  "
              echo -n "  ${FGBLUE}RMC port:[0m         ${RMCP:-<Unknown>}"
              if test -n "${RMCP}" -a -n "`netstat -an 2>/dev/null | grep -w ${RMCP:-UNKNOWN} | grep ESTABLISHED`" 
              then
                CHKP=`ps -ef | grep telnet | grep localhost | grep ${RMCP}$ | awk '{print $2}' | tr "\n" " "`
                if test -n "${CHKP}"
                then
                  echo " / [31mLocked by 'telnet' pid(s) ${CHKP}[0m"
                else
                  CHKP=`ps -ef | grep putty | grep "\-P ${RMCP}" | awk '{print $2}' | tr "\n" " "`
                  if test -n "${CHKP}"
                  then
                    echo " / [31mLocked by 'putty' pid(s) ${CHKP}[0m"
                  else
                    CHKP=`netstat -an | grep -w ${RMCP} | grep ESTABLISHED | awk '{print $5}'`
                    echo " / [31mLocked by foreign host `echo ${CHKP}|cut -f1 -d':'`, port `echo ${CHKP}|cut -f2 -d':'`[0m"
                  fi
                fi
              else
                echo
              fi
            fi
          else
            if test -n "${RMCP}"
            then
              test "$1" = "-num" && echo -n "  "
              echo -n "  ${FGBLUE}RMC port:[0m         ${RMCP:-<Unknown>}"
              if test -n "${RMCP}" -a -n "`netstat -an 2>/dev/null | grep -w ${RMCP:-UNKNOWN} | grep ESTABLISHED`" 
              then
                CHKP=`ps -ef | grep telnet | grep localhost | grep ${RMCP}$ | awk '{print $2}' | tr "\n" " "`
                if test -n "${CHKP}"
                then
                  echo " / [31mLocked by 'telnet' pid(s) ${CHKP}[0m"
                else
                  CHKP=`ps -ef | grep putty | grep "\-P ${RMCP}" | awk '{print $2}' | tr "\n" " "`
                  if test -n "${CHKP}"
                  then
                    echo " / [31mLocked by 'putty' pid(s) ${CHKP}[0m"
                  else
                    CHKP=`netstat -an | grep -w ${RMCP} | grep ESTABLISHED | awk '{print $5}'`
                    echo " / [31mLocked by foreign host `echo ${CHKP}|cut -f1 -d':'`, port `echo ${CHKP}|cut -f2 -d':'`[0m"
                  fi
                fi
              else
                echo
              fi
            fi

            get_logfile ${CHARON_CFG}
            LOGUNIQ=`grep "^${LOGF};" ${LOGCF} 2>/dev/null`

            test "$1" = "-num" && echo -n "  "
            echo "  ${FGBLUE}Log file:[0m         ${LOGF}"

            if test -s ${LOGF}
            then
              typeset -i LOGISSUES=0
              typeset -i LOGNBWARN=`grep ':WARN :' ${LOGF} | wc -l`
              typeset -i LOGNBERRO=`grep ':ERROR:' ${LOGF} | wc -l`
              typeset -i LOGNBFATA=`grep ':FATAL:' ${LOGF} | wc -l`
              LOGISSUES=LOGNBWARN+LOGNBERRO+LOGNBFATA
              if test ${LOGISSUES} -gt 0
              then
                test "$1" = "-num" && echo -n "  "
                echo -n "                    [31mIssues found[m: "
                test ${LOGNBWARN} -gt 0 && echo -n "Warning:${LOGNBWARN} "
                test ${LOGNBERRO} -gt 0 && echo -n "Error:${LOGNBERRO} "
                test ${LOGNBFATA} -gt 0 && echo -n "Fatal:${LOGNBFATA} "
                echo
              fi
            fi

            if test -n "${LOGUNIQ}"
            then
              test "$1" = "-num" && echo -n "  "
              echo "                    [31mAlready used in `echo ${LOGUNIQ}|cut -f2 -d";"` virtual machine.[0m"
              echo "                    [31mPlease check[0m"
            else
              echo "${LOGF};${EMUCFG}" >>${LOGCF}
            fi

            if test -z "`echo ${LOGF} | grep '/'`"
            then
              test "$1" = "-num" && echo -n "  "
              echo "                    [31mNo full path specified: not monitored![0m"
            fi

            if test -z "`echo ${LOGF} | grep \.log$`"
            then
              test "$1" = "-num" && echo -n "  "
              echo "                    [36mNo '.log' extension defined for log file ![0m"
              if ! test -d ${LOGF}
              then
                test "$1" = "-num" && echo -n "  "
                echo "                    [36mThe file specified is not an existing folder (no log rotation)[0m"
              fi
            fi

            if test -z "`grep ^${LOGF}$ ${LOGFLIST:-/opt/charon/utils/charon_logchk.list} 2>/dev/null`"
            then
              test "$1" = "-num" && echo -n "  "
              if test "${GLOBALLOGMON}" = "enabled"
              then
                echo "                    [31mLog file is not monitored![0m"
              fi
            else
              if test -s /etc/systemd/system/charon_logmon_${CHARON_CFGBAS}.service
              then
                EXECTOP=0
                for EX in ExecStart ExecStop
                do
                  SVCLOGF=`grep ^${EX}= /etc/systemd/system/charon_logmon_${CHARON_CFGBAS}.service 2>/dev/null | awk '{print $3}'`
                  if test -s ${LOGF} -a "${LOGF}" != "${SVCLOGF}"
                  then
                    if test ${EXECTOP} = 0
                    then
                      test "$1" = "-num" && echo -n "  "
                      echo "                    [31mLog monitor service: log file monitored does[0m"
                      test "$1" = "-num" && echo -n "  "
                      echo "                    [31mnot match configuration file[0m"
                      test "$1" = "-num" && echo -n "  "
                      echo "                    Please update the log monitoring service definition file:"
                      test "$1" = "-num" && echo -n "  "
                      echo "                    Use 'Manage monitored guests logs' option and 'Update"
                      test "$1" = "-num" && echo -n "  "
                      echo "                    log files list' then the \"Manage 'systemd' services\""
                      test "$1" = "-num" && echo -n "  "
                      echo "                    option. Finally restart the service."
                      EXECTOP=1
                    fi
                    test "$1" = "-num" && echo -n "  "
                    echo "                    ${FGBLUE}Check log file definition in \"${EX}=\" line[0m"
                  fi
                done
              fi
              SVCL_IS_ACTIVE=`systemctl is-active charon_logmon_${CHARON_CFGBAS}.service 2>/dev/null | cut -f1 -d'-' | tr [:lower:] [:upper:]`
              if test "${SVCL_IS_ACTIVE}" != "ACTIVE" -a "${GLOBALLOGMON}" = "enabled"
              then
                test "$1" = "-num" && echo -n "  "
                echo "                    [31mLog monitor service state: ${SVCL_IS_ACTIVE:-unknown}[0m"
              fi
              if test "${SVCL_IS_ACTIVE}" != "UNKNOWN"
              then
                SVC_IS_ENABLED=`systemctl is-enabled charon_logmon_${CHARON_CFGBAS}.service 2>/dev/null | cut -f1 -d'-' | tr [:lower:] [:upper:]`
                if test "${SVC_IS_ENABLED}" != "ENABLED"
                then
                  test "$1" = "-num" && echo -n "  "
                  echo "                    [31mLog monitor is not enabled at system startup![0m"
                else
                  if test "${SVC_IS_ACTIVE}" = "ACTIVE" -a "${GLOBALLOGMON}" = "enabled"
                  then
                    if test -s ${CHARONDIR}/utils/events/${CHARON_CFGBAS}.license_status
                    then
                      test "$1" = "-num" && echo -n "  "
                      echo -n "  ${FGBLUE}License:[0m        "
                      if test "${SEMIGRAPH}" = "enabled"
                      then
                        tput smacs;echo -n "l";tput rmacs;echo -n " "
                      else
                        echo -n "+ "
                      fi
                      LICST=`cat ${CHARONDIR}/utils/events/${CHARON_CFGBAS}.license_status`
                      case "`echo ${LICST} | cut -f2 -d';'`"
                      in
                        "WARN")  echo -n "[46m[30m";;
                        "ERROR") echo -n "[41m[30m";;
                      esac
                      LICSTM=`echo ${LICST} | cut -f3 -d';'`
                      if test -z "`echo ${LICSTM} | grep 'Application will stop'`"
                      then
                        if test -z "`echo ${LICSTM} | grep 'Communication restored'`"
                        then
                          if test -z "`echo ${LICSTM} | grep 'Communication lost with'`"
                          then
                            echo "${LICSTM}`tput sgr0`"
                          else
                            echo "`echo ${LICSTM} | cut -f1 -d','``tput sgr0`"
                            test "$1" = "-num" && echo -n "  "
                            echo -n "                  "
                            if test "${SEMIGRAPH}" = "enabled"
                            then
                              tput smacs;echo -n "x";tput rmacs
                            else
                              echo -n "|"
                            fi
                            echo "`echo ${LICSTM} | sed "s=license=License=g" | cut -f2 -d','`."
                          fi
                        else
                          echo "`echo ${LICSTM} | cut -f1 -d','``tput sgr0`"
                          test "$1" = "-num" && echo -n "  "
                          echo -n "                  "
                          if test "${SEMIGRAPH}" = "enabled"
                          then
                            tput smacs;echo -n "x";tput rmacs
                          else
                            echo -n "|"
                          fi
                          echo "`echo ${LICSTM} | sed "s=license=License=g" | cut -f2 -d','`."
                        fi
                      else
                        LICSTM1=`echo ${LICSTM} | sed "s=\(^.*\)\( Application.*$\)=\1=g"`
                        LICSTM2=`echo ${LICSTM} | sed "s=\(^.*\)\( Application.*$\)=\2=g"`
                        echo "${LICSTM1}`tput sgr0`"
                        test "$1" = "-num" && echo -n "  "
                        echo -n "                  "
                        if test "${SEMIGRAPH}" = "enabled"
                        then
                          tput smacs;echo -n "x";tput rmacs
                        else
                          echo -n "|"
                        fi
                        echo "${LICSTM2}"
                      fi
                      test "$1" = "-num" && echo -n "  "
                      echo -n "                  "
                      if test "${SEMIGRAPH}" = "enabled"
                      then
                        tput smacs;echo -n "m";tput rmacs;echo -n " "
                      else
                        echo -n "+ "
                      fi
                      echo -n "Event date/time: "
                      echo ${LICST} | cut -f1 -d';'                     
                    fi
                  fi
                fi
              else
                if test "${GLOBALLOGMON}" = "enabled"
                then
                  echo "                    [31mLog monitor is not configured ! (${LOGF})[0m"
                fi
              fi

            fi
          fi

          test "$1" = "-num" && echo -n "  "
          echo -n "  ${FGBLUE}Network:[0m          "
          for LOADPKT in `grep -w ^load ${CHARON_CFG} | grep -w -e packet_port -e tap_port | grep -w interface | sed "s:=: :g" | awk '{print $3,$5}' | tr -d "'\"" | tr " " "/"`
          do
            PKP=`echo ${LOADPKT} | cut -f1 -d"/"`
            ETH=`echo ${LOADPKT} | cut -f2 -d"/"`
            test -z "${ETH}" && ETH="UNKNOWN"
            echo -n "${PKP}/"
            if test "${ETH}" = "(disabled)"
            then
              echo -n "[36m${ETH}[0m "
            else
              # ifconfig ${ETH} >/dev/null 2>&1
              ip a | grep -q -w ${ETH}:
              if test $? = 0
              then
                # IFADDR=`ifconfig ${ETH} | grep -w inet | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" | head -1`
                IFADDR=`ip -o a show ${ETH} | grep -w inet | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" | head -1`
                if test -n "${IFADDR}"
                then
                  NICALERT4=1
                  echo -n "[31m${ETH}[0m(4) "
                else
                  if test -e ${NCUBIN}
                  then
                    if test -z "`grep -w ${ETH} ${NCU_CFG} 2>/dev/null`"
                    then
                      NICALERT2=1
                      if test -z "`grep ^${ETH}$ ${NICCF} 2>/dev/null`"
                      then
                        echo -n "[31m${ETH}[0m(2) "
                        echo ${ETH} >>${NICCF}
                      else
                        NICALERT3=1
                        echo -n "[31m${ETH}[0m(2,3) "
                      fi
                    else
                      if test -z "`grep ^${ETH}$ ${NICCF} 2>/dev/null`"
                      then
                        echo -n "[32m${ETH}[0m "
                        echo ${ETH} >>${NICCF}
                      else
                        NICALERT3=1
                        echo -n "[35m${ETH}[0m(3) "
                      fi
                    fi
                  else
                    if test -z "`grep ^${ETH}$ ${NICCF} 2>/dev/null`"
                    then
                      echo -n "[32m${ETH}[0m "
                      echo ${ETH} >>${NICCF}
                    else
                      NICALERT3=1
                      echo -n "[35m${ETH}[0m(3) "
                    fi
                  fi
                fi
              else
                if test -n "`echo ${ETH} | grep 'connection:'`"
                then
                  NICALERT5=1
                  echo -n "[31m[1m${ETH}[0m(5) "
                else
                  NICALERT1=1
                  echo -n "[31m[1m${ETH}[0m(1) "
                fi
              fi
            fi
          done
          echo
        fi
      else
        EMUX1=`basename ${CHARON_EXE}`
        EMUX1=`echo ${EMUX1} | cut -c1-15`
        EMUX2="${CHARON_CFG} : file does not exist!"

        test $I -eq ${VMSEL:-0} && IDN="*" || IDN="-"

        echo -n "[1m"
        if test "$1" = "-num"
        then
          printf "%-12s %-15s" "${IDN} ${EMUX1}" "${EMUX2}"
        else
          printf "%-14s %-15s" "${IDN} ${EMUX1}" "${EMUX2}"
        fi
        echo "[0m"

      fi
    done

    if test ${NICALERT1} = 1 -o ${NICALERT2} = 1 -o ${NICALERT3} = 1 -o ${NICALERT4} = 1 -o ${NICALERT5} = 1
    then
      echo
      echo -n "${FGBLUEBOLD}Caption[0m: "
      test ${NICALERT1} = 1 && echo -n "(1)=NIC does not exist "
      test ${NICALERT2} = 1 && echo -n "(2)=NIC not managed by ncu "
      test ${NICALERT3} = 1 && echo -n "(3)=NIC already used "
      test ${NICALERT4} = 1 && echo -n "(4)=NIC has an IP address "
      test ${NICALERT5} = 1 && echo -n "(5)=Windows syntax used "
      echo
    fi

    sort    ${PORTCF} >${PORTCF}.sorted
    sort -u ${PORTCF} >${PORTCF}.sortedunique
    if test -n "`diff ${PORTCF}.sorted ${PORTCF}.sortedunique`"
    then
      echo
      echo "[41m[37m[1m WARNING [0m [31mFound duplicated console ports. Please check![0m"
    fi
    rm -f ${PORTCF} ${PORTCF}.sorted ${PORTCF}.sortedunique ${NICCF} ${LOGCF} ${CONSCF} 2>/dev/null
    
  fi

  #-- Displays an alert if the root password has expired
  if test `id -u` -eq 0
  then
    chage -l root | grep "^Password expires" | grep -q "password must be changed"
    if test $? = 0
    then
      echo
      echo "[41m[37m[1m WARNING [0m Root password has expired. Some functionalities could be inoperative!"
    fi
  fi
}

#=============================================================================
# Function: display_licfound
#=============================================================================
function display_licfound
{
  echo "[1mLocal licenses found (on this server)[0m:"
  echo -n "- ${FGBLUE}USB dongles: "
  /usr/bin/lsusb -d 0529: 2>/dev/null | wc -l
  echo -n "[0m"
  if test "$1" = "full"
  then
    /usr/bin/lsusb -d 0529:0001 -v 2>/dev/null | grep -e ^Bus -e iProduct | sed "s=^=    =g"
  fi

  echo -n "- ${FGBLUE}Software licenses (SL): "
  ls /var/hasplm/installed/68704/*.v2c 2>/dev/null | cut -f1 -d "_" | sort -u | wc -l
  echo -n "[0m"
  if test "$1" = "full"
  then
    for LIC in `ls /var/hasplm/installed/68704/*_base.v2c 2>/dev/null`
    do
      LICID=`basename ${LIC} | cut -f1 -d "_"`
      echo -n "    License Id: ${LICID} "
      NBUPD=`ls /var/hasplm/installed/68704/${LICID}_update*.v2c 2>/dev/null | wc -l`
      test ${NBUPD:-0} -eq 0 && echo || echo "(updates: ${NBUPD})"      
    done
  fi

  echo
}

#=============================================================================
# Function: select_logfile
#=============================================================================
function select_logfile
{
  # Input field = $LOGF
  LOGLISTFIL=/tmp/charon.loglist.tmp
  LOGFSAV=${LOGF}

  while test 1
  do
    rm -f ${LOGLISTFIL} 2>/dev/null
    LOGF=${LOGFSAV}

    if test -L ${LOGF}
    then
      FILFCURR=`dirname ${LOGF}`"/"`file ${LOGF}|cut -f2 -d'\`'|tr -d "'"`
      FILFLIST="`echo ${LOGF} | sed "s=\.log==g"`-????-??-??-??-??-??-?????????.log"
    else
      FILFCURR=${LOGF}
      FILFLIST="${LOGF}.upto* ${LOGF}"
    fi    

    ls -1tr ${FILFLIST} | tail -16 | while read FILF
    do
      ls -l --full-time ${FILF} 2>/dev/null | tail -15 | while read LINE
      do
        LOGNAME=`echo ${LINE} | awk '{print $9}'`
        echo ${LOGNAME} >>${LOGLISTFIL}
        NBF=`cat ${LOGLISTFIL} | wc -l`
        if test ${NBF} -eq 1
        then
          echo "${FGBLUEBOLD}Log files found (most recent ones)[0m:"
          echo
          echo "No  From                      To                        Size          Lines"
          if test "${SEMIGRAPH}" = "enabled"
          then
            tput smacs
            echo "qq  qqqqqqqqqqqqqqqqqqqqqqqq  qqqqqqqqqqqqqqqqqqqqqqqq  qqqqqqqqqqqq  qqqqqqqqq"
            tput rmacs
          else
            echo "--  ------------------------  ------------------------  ------------  ---------"
          fi
        fi
        echo -n "[0m"
        test `echo ${NBF}%2 | bc` = 1 && echo -n "${FGBLUE}"
        test "${FILF}" = "${FILFCURR}" && tput smso

        printf "%2d  " ${NBF}
        LOGFROM=`head -24 ${LOGNAME} | grep ^[0-9]*:[0-9]*: | head -1 | sed "s=\(^........\):\(..\)\(..\)\(..\):\(.*$\)=\1 \2:\3:\4=g"`
        test -z "${LOGFROM}" && LOGFROM=`echo ${LINE} | awk '{print $6,$7}' | awk -F '.' '{print $1}'`
        LOGFROM=`date +"%a %d-%b-%Y %H:%M:%S" -d "${LOGFROM}"`

        #LOGTO=`echo ${LINE} | awk '{print $9}' | sed "s=\(^.*upto\)\(.*$\)=\2=g" | sed "s=\(^....-..-..\)\(\-\)\(..\)\(..\)\(..\)=\1 \3:\4:\5=g"`
        LOGTO=`tail -24 ${LOGNAME} | grep ^[0-9]*:[0-9]*: | tail -1 | sed "s=\(^........\):\(..\)\(..\)\(..\):\(.*$\)=\1 \2:\3:\4=g"`
        if test -z "${LOGTO}"
        then
          LOGTO="<unknown>"
        else
          LOGTO=`date +"%a %d-%b-%Y %H:%M:%S" -d "${LOGTO}"`
        fi
        LOGSIZE=`echo ${LINE} | awk '{print $5}'`
        LOGLINES=`wc -l ${LOGNAME} | awk '{print $1}'`
        printf "%-24s  %-24s  %'12d  %9d[0m\n" "${LOGFROM}" "${LOGTO}" "${LOGSIZE}" "${LOGLINES}"
        tput rmso
        tput sgr0
        LOGFLOCK=`fuser ${LOGNAME} 2>/dev/null | cut -f2 -d':'`
        if test -n "${LOGFLOCK}"
        then
          echo -n "    Lock status: "
          for P in ${LOGFLOCK}
          do
            ps -P ${P} | grep "${TAILCMD}" >/dev/null 2>&1
            test $? = 0 && echo -n "[32m<Monitored>[0m "
            ps -P ${P} | grep -w "\-d" | grep "\.cfg$" >/dev/null 2>&1
            test $? = 0 && echo -n "[32m<Guest running>[0m "
          done
          echo
        fi
      done
    done
    echo
  
    if test -s ${LOGLISTFIL}
    then
      while test 1
      do
        echo -n "Select the log file you want to view (q to quit, r to refresh): "
        read ANS
        test "${ANS}" = "q" && break 2
        test "${ANS}" = "r" && break
        if test -n "${ANS}"
        then
          if test -z "`echo ${ANS} | tr -d [0123456789]`"
          then
            if test ${ANS} -lt 1 -o ${ANS} -gt `cat ${LOGLISTFIL} | wc -l`
            then
              tput bold
              echo "Incorrect value, out of range."
              tput sgr0
              sleep 2
              tput cuu1;tput el
            else
              LOGF=`head -${ANS} ${LOGLISTFIL} | tail -1`
              if test -e ${LOGF}
              then
                if test -s ${LOGF}
                then
                  echo
                  echo "File selected: ${FGBLUE}${LOGF}[0m"
                  echo
                  ask_editor
                  if test -n "${EDI}"
                  then
                    SPEC=""
                    CVIMRC="${CHARONDIR}/utils/charonlog.vimrc"
                    test -n "`echo ${EDI} | grep -w gvim`"                 && SPEC="-m"
                    test -n "`echo ${EDI} | grep -w gvim`" -a -e ${CVIMRC} && SPEC="-m -u ${CVIMRC}"
                    test "${EDI}" = "/usr/bin/vim"                         && SPEC="-m"
                    test "${EDI}" = "/usr/bin/vim"  -a -e ${CVIMRC}        && SPEC="-m -u ${CVIMRC}"
                    test "${EDI}" = "/bin/vi"                              && SPEC="-m"
                    if test -n "`grep ':ll_sentine' ${LOGF}`"
                    then
                      echo
                      while test 1
                      do
                        echo "Do you want the full log or its shortened version without 'regular license"
                        echo -n "check' messages ['f' for full (default), 's' for short, 'q' to quit] ? "
                        read ANS
                        case "${ANS}"
                        in
                          ""|"f")
                            ${EDI} ${SPEC} ${LOGF} 2>/dev/null
                            break
                            ;;
                          "s")
                            cat ${LOGF} | grep -v -e ":000003BA:" -e ":000003DC:" -e ":000003E6:" -e ":000003E7:" \
                                >/tmp/`basename ${LOGF}`.short
                            ${EDI} ${SPEC} /tmp/`basename ${LOGF}`.short 2>/dev/null
                            break
                            ;;
                          "q")
                            break
                            ;;
                          *)
                            tput cuu1;tput el;tput cuu1;tput el
                            ;;
                        esac
                      done
                    else
                      ${EDI} ${SPEC} ${LOGF} 2>/dev/null
                    fi
                  fi
                  break
                else
                  tput bold
                  echo "Log file is empty."
                  tput sgr0
                  sleep 2
                  tput cuu1;tput el
                fi
              else
                tput bold
                echo "Log file ${LOGF} does not exist."
                tput sgr0
                sleep 2
                tput cuu1;tput el
              fi
            fi
          else
            tput bold
            echo "Incorrect value, must be numeric."
            tput sgr0
            sleep 2
            tput cuu1;tput el
          fi
        fi
        tput cuu1;tput el
      done
    else
      echo "No log file found."
      sleep 1
      break
    fi
  done
}

#=============================================================================
# Function: tail_log_colored
#=============================================================================
function end_tail
{
  echo
  echo "[44m[37m Continuous view of ${LOGT} aborted [0m"
  kill -9 `ps -f|grep 'tail -Fn12'|grep -v grep|awk '{print $2}'` 2>/dev/null
  sleep 1
  echo
}

function tail_log_colored
{ 
  LOGT=$1
  TAMO=$2
  tput clear
  typeset -i NBL=0
  echo "[44m[37m Continuous view of ${LOGT} [0m"
  echo -n "[31mPress CTRL-C to stop[0m"
  if test `tput cols` -lt 132
  then
    echo " (it is recommended to enlarge screen to 132 cols minimum)"
  else
    echo
  fi
  if test "${SEMIGRAPH}" = "enabled"
  then
    tput smacs
    echo "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"
    tput rmacs
  else
    echo "--------------------------------------------------------------------------------"
  fi
  trap 'end_tail' 1 2 9 14 15
  STADAT=`grep :000003A5: ${LOGT} | tail -1  | awk -F':' '{print $1 $2}'`
  test -z "${STADAT}" && STADAT=`date +%Y%m%d%H%M%S`
  CHKSTA=0
  CHKSTO=0
  tail -Fn12 --retry ${LOGT} | while read LINE
  do
    case "`echo ${LINE} | cut -f4 -d:`"
    in
      0)
        case "`echo ${LINE} | cut -f5 -d:`"
        in
          0000009[789])
            #--- HW configuration details
            echo -n "${FGBLUE}"
            ;;
          000003A5)
            #--- session is loading built-in configuration
            echo -n "[42m[30m"
            ;;
          0000032B)
            #--- Start request received & Started
            echo -n "[42m[30m"
            ;;
          0000032C)
            #--- Started
            echo -n "[42m[30m"
            CURDAT=`echo $LINE | awk -F':' '{print $1 $2}'`
            test ${CURDAT} -gt ${STADAT} && CHKSTA=1
            ;;
          0000032D)
            #--- Stop request received
            echo -n "[31m"
            ;;
          0000032E)
            #--- Stopped
            echo -n "[31m"
            CURDAT=`echo $LINE | awk -F':' '{print $1 $2}'`
            test ${CURDAT} -gt ${STADAT} && CHKSTO=1
            ;;
          00000350)
            #--- Product version & license number
            echo -n "[44m[37m"
            ;;
          00000351|0000002A)
            #--- session: Detected removal of the license
            echo -n "[45m[37m"
            ;;
          0000039D)
            #--- License detected and online
            echo -n "[42m[37m"
            ;;
          0000040B)
            #--- License has changed
            echo -n "[100m[33m"
            ;;
          000003BA|000003DC|000003E6|000003E7)
            #--- Looking for license / ll_sentine
            echo -n "[90m"
            ;;
          0000024D)
            #--- License Manager
            echo -n "[94m"
            ;;
          *)
            test -n "`echo ${LINE} | grep 'HALT INSTRUCTION'`" && echo -n "[31m"
            ;;
        esac
        ;;
      1)
        echo -n "[46m[30m"
        ;;
      2)
        echo -n "[41m[37m"
        ;;
      3)
        echo -n "[45m[37m"
        ;;
      *)
        if test "`echo ${LINE} | cut -c1-4`" = '. . '
        then
          echo -n "[35m"
        else
          if test "`echo ${LINE} | cut -c1-2`" = '. '
          then
            echo -n "[100m[37m"
          fi
        fi
        ;;
    esac
    echo "${LINE}[0m"
    NBL=NBL+1
    if test ${NBL} -gt `tput lines`
    then
      NBL=0
      get_preferences
      if test "${LOGTAILCT}" = "enabled"
      then
        echo "[100m[37m ------ Press CTRL-C to stop the continuous log view ------ [0m"
      fi
    fi

    if test ${AUTOSTOPLOGTAIL:-1} = 1 -a "${TAMO}" != "NOSTOP"
    then
      if test ${CHKSTA} = 1
      then
        kill -9 `ps -f|grep 'tail -Fn12'|grep -v grep|awk '{print $2}'` 2>/dev/null
        echo
        echo "Emulator started, use the '[1mvmconsole[0m' command or use the '[1mConnect to guest[0m"
        echo "[1mconsole[0m' menu option to open the console."
      fi
      if test ${CHKSTO} = 1
      then
        tput smso
        echo "Emulator stopped!"
        tput rmso
        kill -9 `ps -f|grep 'tail -Fn12'|grep -v grep|awk '{print $2}'` 2>/dev/null
      fi
    fi

  done
  trap 'exit' 1 2 9 14 15
}

#=============================================================================
# Function: FollowServiceStatus
#=============================================================================
function FollowServiceStatus {
  case "$1"
  in 
    "start")
      kill -9 `ps | grep journalctl | awk '{print $1}'` 2>/dev/null
      trap "echo" 9
      ( journalctl -lfu $2 -qn0 -o export 2>/dev/null | while read JL
        do
          JLP=`echo ${JL} | cut -f1 -d'='`
          case "${JLP}"
          in
            "__REALTIME_TIMESTAMP")
               JLV=`echo ${JL} | cut -f2 -d'='`
               TSTAMP=`echo ${JLV} / 1000000 | bc`
               ;;
            "MESSAGE")
               JLV=`echo ${JL} | cut -c9-`
               case "`echo ${JLV} | cut -c1-7`"
               in
                 "Startin")  echo -n "[32m";;
                 "Started")  echo -n "[42m";;
                 "Stoppin")  echo -n "[31m";;
                 "Stopped")  echo -n "[41m[37m";;
                 "Failed ")  echo -n "[31m[1m";;
                 *)          echo -n "${FGBLUE}";;
               esac
               if test -n "`echo ${JL} | grep -w EXPECT`"
               then
                 EXPLVL=`echo ${JL} | sed "s=^.*%EXPECT-\([A-Z]\)-.*$=\1=g"`
                 case "${EXPLVL}"
                 in
                   "S") echo -n "[42m[30m";;
                   "I") echo -n "[32m";;
                   "W") echo -n "[46m[30m";;
                   "E") echo -n "[31m";;
                   "F") echo -n "[41m[37m";;
                 esac
                 echo `date +"%b %d %T" -d @${TSTAMP}`" ${JLV}[0m"
               else
                 echo `date +"%b %d %T" -d @${TSTAMP}`"[0m ${JLV}"
               fi
               ;;
          esac
        done ) &
      ;;
    "stop")
      sleep 3
      kill -9 `ps | grep journalctl | awk '{print $1}'` 2>/dev/null
      trap "exit" 9
      ;;
  esac
}
