#!/bin/sh
#-------------------------------------------------------------------------------
# charon_logchk - CHARON guest log file monitoring
#----------------------------------------------------------
# Copyright (C) 2013-2022 STROMASYS.
# All rights reserved.
#
# Notes:
# Script must be installed in the "utils" directory of the CHARON installation
# folder
#
# Parameters:
# $1 = start|stop|status|force-reload|restart|check|resetlog
# $2 = log filename: optional, full path or completion /opt/charon/log/$2.log
#-------------------------------------------------------------------------------
# chkconfig: 345 98 00
# description: CHARON guest log monitoring for key removal

VERSION=2.17
LOCKFILE=/var/lock/subsys/charon_logchk

# Source function library.
. /etc/rc.d/init.d/functions

for P in `ls /etc/profile.d/charon*`;do . $P;done
. /opt/charon/utils/charon_common

if test `id -u` -ne 0
then
  echo "Must be root !"
  exit 1
fi

GLOG=$2
if test -n "${GLOG}"
then
  if test ! -e "${GLOG}"
  then
    if test -z "`echo ${GLOG} | grep '/'`" -a -z "`echo ${GLOG} | grep '\.log$'`"
    then
      GLOG="/opt/charon/log/${GLOG}.log"
    fi
  fi
fi
CHKHOST=`basename ${GLOG} 2>/dev/null | cut -f1 -d.`

SCRIPT=`basename $0 | sed "s=[KS][0-9][0-9]==g"`

LOGFILE="${CHARONDIR}/log/${SCRIPT}.log"
LOGDATE=`date +"%Y%m%d;%H%M%S"`
INFOTERM=""
STARTLIST="${CHARONDIR}/utils/${SCRIPT}.list"
BOOTLIST="${CHARONDIR}/utils/charon_gstart.boot"
DONGLESFILE="${CHARONDIR}/utils/charon_licenses.list"
ALERTEXPLOGFILE="/root/.charon.expiration.alertsfromlog"
HWSPECWARNIGNORE="/root/.charon.hwspecwarning.ignore"
LESSWARNONREMOVAL="/root/.charon.less.warn.on.dongle.removal"
DISABLEMONUSBALRT="/root/.charon.disable.monusb.immediate.alert"
MONBUGCHECK="/root/.charon.logmon.no.bugcheck"
MONCPUHALTED="/root/.charon.logmon.no.cpuhalted"

ANSI_TO_HEX="FF2020 00D200 FFFF00 2020FF FF00FF 00FFFF C0C0C0"

test -d ${CHARONDIR}/utils/events || mkdir ${CHARONDIR}/utils/events
CHKEVENT=/root/.charonlogevent
test -e ${CHKEVENT} || echo 2 >${CHKEVENT}

#TAILCMD="tail -Fn0 --retry --max-unchanged-stats=1"
TAILCMD="tail -Fn0 --retry"

function get_usbbusdev
{
  USBBUSDEV=`/usr/bin/lsusb|grep HASP|cut -f1 -d:|awk '{print $2"/"$4}'`
  TIM=`date +"%Y%m%d;%H%M%S"`
  echo "${TIM};USB_DEVICE;Bus/Dev ${USBBUSDEV}" >>${LOGFILE}

  USBHCI=`/bin/dmesg | grep 'Vendor=0529,' | tail -1 | cut -f2 -d']' | cut -f1 -d: | sed "s=^ ==g"`
  USBHCIMODE=`/bin/dmesg | grep "${USBHCI}:" | grep hci_hcd | grep -w using | tail -1 | sed "s=\(^.* using \)\(.*$\)=\2=g"`
  echo "${TIM};USB_HCI;${USBHCI};${USBHCIMODE}" >>${LOGFILE}
}

function get_licensenum
{
  OPTKEY=""
  if test -n "`strings /opt/charon/bin/hasp_srm_view | grep ^-key`"
  then
    test -n "${LICENSE_KEY_ID}" && OPTKEY="-key ${LICENSE_KEY_ID}"
  fi
  LICENSENUM=`hasp_srm_view ${OPTKEY} | grep "^The License Number" | cut -f2 -d: | tr -d [:cntrl:] | tr -d " "`
  if test -z "${LICENSENUM}"
  then
    #--- Retry once
    sleep 10
    LICENSENUM=`hasp_srm_view ${OPTKEY} | grep "^The License Number" | cut -f2 -d: | tr -d [:cntrl:] | tr -d " "`
    test -z "${LICENSENUM}" && LICENSENUM="UNKNOWN_LIM"
  fi
}

function format_datetime
{
  FDD=`echo ${LINE} | cut -f1 -d':'`
  FDD=`date -d ${FDD} +"%d-%b-%Y"`
  FDT=`echo ${LINE} | cut -f2 -d':'`
  FDT=`echo ${FDT} | cut -c1-2`":"`echo ${FDT} | cut -c3-4`":"`echo ${FDT} | cut -c5-6`
  FMTDAT="${FDD} ${FDT}"
}


if test `id -u` -ne 0
then
  echo "$0 must be run as root"
  exit 1
fi

RETVAL=0
case "$1" in
  start)
    echo "${LOGDATE};COMMAND;$1;${GLOG}" >>${LOGFILE}
    touch ${LOCKFILE}
    if test -z "${2}"
    then
      if test -s ${STARTLIST}
      then
        cat ${STARTLIST} | while read LINE
        do
          OKSTART=1
          PRC=`ps -ef | grep "${TAILCMD} ${LINE}" | grep -v grep`
          if test -n "${PRC}"
          then
            PRC=`echo ${PRC} | awk '{print $3}'`
            test -n "`ps -P ${PRC} | tail -1`" && OKSTART=0
          fi
          echo -n $"Starting charon_logchk `basename ${LINE}`: "
          if test ${OKSTART} = 1
          then
            echo $0 check ${LINE} | at now 2>/dev/null
            success	
          else
            echo -n "already running"
            failure
          fi
          echo
        done
      else
        echo -n $"Starting charon_logchk/ALL: "
        failure
        echo
      fi
      $0 monusbstart
    else
      if test -n "`grep ^${GLOG}$ ${STARTLIST}`"
      then
        OKSTART=1
        PRC=`ps -ef | grep "${TAILCMD} ${GLOG}" | grep -v grep`
        if test -n "${PRC}"
        then
          PRC=`echo ${PRC} | awk '{print $3}'`
          test -n "`ps -P ${PRC} | tail -1`" && OKSTART=0
        fi
        echo -n $"Starting charon_logchk `basename ${GLOG}`: "
        if test ${OKSTART} = 1
        then
          echo $0 check ${GLOG} | at now 2>/dev/null
          success	
        else
          echo -n "already running"
          failure
        fi
      else
        echo -n $"Starting charon_logchk `basename ${GLOG}`: not in list"
        failure
      fi
    fi
    echo
    ;;
  restart)
    $0 stop ${GLOG}
    $0 start ${GLOG}
    ;;
  stop)
    echo "${LOGDATE};COMMAND;$1;${GLOG:-ALL}" >>${LOGFILE}
    if test -z "${GLOG}"
    then
      echo
      cat ${STARTLIST} | while read LINE
      do
        #--- force to full path and not $0 for Fedora compatibility
        ${CHARONDIR}/utils/${SCRIPT} stop ${LINE}
      done  
      echo
      ${CHARONDIR}/utils/${SCRIPT} monusbstop
    else
      echo -n $"Stopping charon_logchk for `basename ${GLOG}`: "
      ps -ef | grep "${TAILCMD} ${GLOG}" | grep -v grep | awk '{print $2}' | xargs -i kill -15 {}
      test -z "`ps -ef | grep "${TAILCMD} ${GLOG}" | grep -v grep`" && success || failure   
      echo
    fi
    #  rm -f ${LOCKFILE} 2>/dev/null
    ;;
  monusbstart)
    echo -n $"Starting charon_monusb: "
    PRC=`ps -ef | grep "${TAILCMD} /var/log/messages" | grep -v grep`
    if test -n "${PRC}"
    then
      PRC=`echo ${PRC} | awk '{print $3}'`
      if test -n "`ps -P ${PRC} | tail -1 | grep 'charon_logchk monusb'`"
      then
        echo -n "already running"
        failure
      else
        echo $0 monusb | at now 2>/dev/null
        success
      fi
    else
      echo $0 monusb | at now 2>/dev/null
      success
    fi
    echo
    ;;      
  monusbstop)
    # MONCMD="${TAILCMD} /var/log/messages"
    MONCMD="journalctl -lfn0"

    PRCT=`ps -ef | grep -e "${MONCMD}" | grep -v grep`
    if test -n "${PRCT}"
    then
      ps -ef | grep "${MONCMD}" | grep -v grep | while read LINE
      do
        PRC=`echo ${LINE} | awk '{print $2}'`
        PRCF=`echo ${LINE} | awk '{print $3}'`
        echo -n $"Stopping charon_monusb: pid ${PRC}"
        if test -n "`ps -P ${PRCF} | tail -1 | grep 'charon_logchk monusb'`"
        then
          kill -15 ${PRC}
          sleep 1
          ps -P ${PRC} >/dev/null
          test $? = 0 && failure || success
        else
          echo -n "/not related"
          passed
        fi
      done
    else
      echo -n $"Stopping charon_monusb: "
      echo -n "not running"
      warning
    fi
    echo
    ;;
  monusb)
    get_licensenum
    test -z "${LICENSENUM}" && LICENSENUM="UNKNOWN_MONUSB"
    # MONCMD="${TAILCMD} /var/log/messages"
    MONCMD="journalctl -lfn0"
    echo "[INFO ] Starting monitoring (journalctl/aksusbd)"
    ${MONCMD} | while read LINE
    do
      LOGDATE=`date +"%Y%m%d;%H%M%S"`
      if test -z "`echo ${LINE} | grep 'failed:'`" -a -n "`echo ${LINE} | grep 'aksusbd_'`"
      then
        DONGLEFND=`lsusb 2>/dev/null | grep HASP | wc -l`
        if test -n "`echo ${LINE} | grep '_dev_remove:'`"
        then
          if test -e ${DISABLEMONUSBALRT}
          then
            echo "${LOGDATE};COMMAND;$1;remove (silent mode)" >>${LOGFILE}
          else
            echo "[WARN ] Detected removal of a dongle: ${DONGLEFND} connected"
            echo "${LOGDATE};COMMAND;$1;remove" >>${LOGFILE}
            test -x ${CHARONDIR}/utils/charon_check.alertcmd && \
              echo ${CHARONDIR}/utils/charon_check.alertcmd USBDISCONNECT ${DONGLEFND} | at now >/dev/null 2>&1
          fi
        else
          if test -n "`echo ${LINE} | grep '_dev_connect:'`"
          then
            if test -e ${DISABLEMONUSBALRT}
            then
              echo "${LOGDATE};COMMAND;$1;connect (silent mode)" >>${LOGFILE}
            else
              echo "[INFO ] Detected dongle connection: ${DONGLEFND} connected"
              echo "${LOGDATE};COMMAND;$1;connect" >>${LOGFILE}
              get_licensenum
              test -x ${CHARONDIR}/utils/charon_check.alertcmd && \
                echo ${CHARONDIR}/utils/charon_check.alertcmd USBCONNECT ${DONGLEFND} | at now >/dev/null 2>&1
            fi
          fi
        fi
      fi  
    done
    ;;
  aksusbrestart)
    typeset -i N=0
    while test $N -lt 15
    do
      N=N+1
      TIM=`date +"%Y%m%d;%H%M%S"`
      echo "${TIM};AKSUSBD_RESTART;Restarting try#${N}" >>${LOGFILE}
      systemctl restart aksusbd >>${LOGFILE} 2>&1
      sleep 2
      if test -n "`ps -ef | grep aksusbd | grep -v grep`"
      then
        #TODO (low): this check will have to be improved as there are also hasplm and winehasp to check
        echo "${TIM};AKSUSBD_RESTART;Restart successful" >>${LOGFILE}
        #echo "[INFO ] aksusbd service restart successful."
        break
      fi
      sleep 18
    done
    if test -z "`ps -ef | grep aksusbd | grep -v grep`"
    then
      echo "${TIM};AKSUSBD_RESTART;Restart failed" >>${LOGFILE}
      echo "[ERROR] aksusbd service restart failed !"
      test -x ${CHARONDIR}/utils/charon_check.alertcmd && \
        echo ${CHARONDIR}/utils/charon_check.alertcmd AKSUSBFAIL | at now >/dev/null 2>&1
    fi
    ;;
  check)
    echo "${LOGDATE};COMMAND;$1;${GLOG}" >>${LOGFILE}
    LICENSE_KEY_ID=""
    get_usbbusdev
    get_licensenum
    test -z "${LICENSENUM}" && LICENSENUM="UNKNOWN_BEG"

    echo "[INFO ] Starting monitoring of ${GLOG} file"
    #touch ${GLOG}
    KEYID=""
    INSBLD=`rpm -q charon-license 2>/dev/null | cut -f4 -d'-' | cut -f1 -d'.'`
    INSBLD=${INSBLD:-0}
    SVCCFG=`systemctl -l status $$ | head -1 | sed "s=\(^.*charon_logmon_\)\(.*\)\(\.service.*$\)=\2=g"`

    ${TAILCMD} ${GLOG} 2>/dev/null | while read LINE
    do
      TOPEVT=1
      MSGCODE=`echo ${LINE} | cut -f5 -d:`
      if test -n "`echo ${LINE}|cut -c1-8|tr -d [0123456789]`"
      then
        TIM=`date +"%Y%m%d;%H%M%S"`
      else
        TIM=`echo ${LINE}|awk -F: '{print $1";"$2}'`
      fi

      #--- Get Charon product version
      if test "${MSGCODE}" = "00000350" -o "${MSGCODE}" = "00000408"
      then
        CHVERSION=`echo ${LINE} | cut -f2 -d',' | awk '{print $2}'`
        INSBLD=`echo ${LINE} | cut -f2 -d',' | awk '{print $4}'`
        echo "${TIM};INFO;${CHKHOST};${LICENSENUM};Charon Version = ${CHVERSION} Build = ${INSBLD}" >>${LOGFILE}
      fi

      #--- Get license keyid from 3BB and 3BC error lines
      if test "${MSGCODE}" = "000003BB" -o "${MSGCODE}" = "000003BC"
      then
        KEYID=`echo ${LINE} | sed "s=\(^.* license key \)\(.*\)\( ...$\)=\2=g"`
        KEYMOD=`echo ${LINE} | sed "s=\(^.* Looking for \)\(.*\)\( license key .*\)=\2=g"`
      fi

      #--- No license matched
      if test ${INSBLD} -ge 19103
      then
        if test -n "`echo ${LINE} | grep 'No license in the key matched'`"
        then
          INFOTERM=`echo ${LINE} | sed "s=\(^.*licenseman(1830): \)\(.*$\)=\2=g"`
          echo "[WARN ] ${INFOTERM}"
          format_datetime
          echo "${FMTDAT};WARN;${INFOTERM}" >${CHARONDIR}/utils/events/${SVCCFG}.license_status
        fi
      fi

      #--- Entry added before emulator termination (license terminated)
      if test -n "`echo ${LINE} | grep 'Product or license has terminated'`"
      then
        INFOTERM="Product or license has terminated"
        echo "[ERROR] ${INFOTERM}"
      fi

      #--- Entry added before emulator termination (license expired)
      if test ${INSBLD} -lt 19103
      then
        if test -n "`echo ${LINE} | grep 'Product or license has expired'`" -a "${MSGCODE}" = "0000024D"
        then
          INFOTERM="Product or license has expired"
          echo "[ERROR] ${INFOTERM}"
        fi
      else
        if test -n "`echo ${LINE} | grep 'The license has expired'`" -a "${MSGCODE}" = "0000024D"
        then
          INFOTERM=`echo ${LINE} | sed "s=\(^.*licenseman(1830): \)\(.*$\)=\2=g"`
          echo "[ERROR] ${INFOTERM}"
          format_datetime
          echo "${FMTDAT};ERROR;${INFOTERM}" >${CHARONDIR}/utils/events/${SVCCFG}.license_status
        fi

        if test -n "`echo ${LINE} | grep 'License expiration is expected'`" -a "${MSGCODE}" = "0000024D"
        then
          INFOTERM=`echo ${LINE} | sed "s=\(^.*licenseman(18.*): \)\(.*$\)=\2=g"`
          echo "[WARN ] ${INFOTERM}"
          format_datetime
          echo "${FMTDAT};WARN;${INFOTERM}" >${CHARONDIR}/utils/events/${SVCCFG}.license_status

          TOPEVT=0
          test -x ${CHARONDIR}/utils/charon_check.alertcmd && \
            echo ${CHARONDIR}/utils/charon_check.alertcmd LICEXP ${CHKHOST} \"${INFOTERM}\" | at now >/dev/null 2>&1

        fi

      fi

      #--- V4.9+ : No license in the key matched application parameters.
      if test ${INSBLD} -ge 19103
      then
        if test -n "`echo ${LINE} | grep 'No license in the key matched application parameters'`" -a "${MSGCODE}" = "0000024D"
        then
          INFOTERM=`echo ${LINE} | sed "s=\(^.*licenseman(18.*): \)\(.*$\)=\2=g"`
          echo "[ERROR] ${INFOTERM}"
          format_datetime
          echo "${FMTDAT};ERROR;${INFOTERM}" >${CHARONDIR}/utils/events/${SVCCFG}.license_status
        fi
      fi

      #--- Entry added before emulator termination (dead battery)
      if test -n "`echo ${LINE} | grep 'Dead battery'`"
      then
        INFOTERM="Dead battery"
        echo "[ERROR] ${INFOTERM}"
      fi

      #--- Entry added by the service stop request
      if test -n "`echo ${LINE} | grep ':SERVICE STOP REQUEST'`"
      then
        INFOTERM="Service stop requested by user or shutdown."
        echo "[INFO ] ${INFOTERM}"
      fi

      #--- Entry added by the systemd stop request when service died
      if test -n "`echo ${LINE} | grep ':SERVICE FAILED'`"
      then
        INFOTERM="Service failed."
        SVCNAME="charon_`systemctl -l status $$ | head -1 | sed "s=\(^.*charon_logmon_\)\(.*\)\(\.service.*$\)=\2=g"`.service"
        INFOSTOP="Emulator stopped at "`echo ${LINE} | awk -F: '{print $1 $2}' | sed "s=\(^....\)\(..\)\(..\)\(..\)\(..\)\(..\)=\1-\2-\3 \4:\5:\6=g"`
        LVLINFO="STOPPED"
        echo "[ERROR] ${INFOTERM}"
        TOPEVT=0
        echo "${TIM};FAILURE;${CHKHOST};${LICENSENUM};" >>${LOGFILE}
        USBCON=`/usr/bin/lsusb | grep HASP | wc -l`
        if test ${USBCON:-0} -gt 0
        then
          LSUSBINFO="CONNECTED:${USBCON:-unknown}"
        else
          if test -n "`/bin/rpm -q -a | grep aksusbd`"
          then
            LSUSBINFO="DISCONNECTED"
          else
            LSUSBINFO="SOFTWARE LICENSE"
          fi
        fi
        if test -x ${CHARONDIR}/utils/charon_check.alertcmd
        then
          echo ${CHARONDIR}/utils/charon_check.alertcmd ${LVLINFO} ${CHKHOST} ${LICENSENUM} \"${INFOSTOP}\" \"${INFOTERM}\" \"${LSUSBINFO}\" | at now >/dev/null 2>&1
          INFOTERM=""
        fi
      fi

      #--- Invalid configuration
      if test -n "`echo ${LINE} | grep 'Configuration is invalid'`"
      then
        echo "[ERROR] Configuration is invalid"
        TOPEVT=0
        echo "${TIM};INVALID;${CHKHOST};${LICENSENUM};" >>${LOGFILE}
        INFOINV=`echo ${LINE} | sed "s=\(^.*session: \)\(.*$\)=Session: \2=g"`
        test -x ${CHARONDIR}/utils/charon_check.alertcmd && \
          echo ${CHARONDIR}/utils/charon_check.alertcmd INVALID ${CHKHOST} ${LICENSENUM} \"${INFOINV}\" | at now >/dev/null 2>&1
      fi

      #--- Emulator stop
      if test -n "`echo ${LINE} | grep 'Emulator stopped at'`" -o -n "`echo ${LINE} | grep ' Stopped.'`" -o "${MSGCODE}" = "0000032E"
      then
        TOPEVT=0
        echo "${TIM};STOPPED;${CHKHOST};${LICENSENUM};" >>${LOGFILE}
        INFOSTOP="Emulator stopped at "`echo ${LINE} | awk -F: '{print $1 $2}' | sed "s=\(^....\)\(..\)\(..\)\(..\)\(..\)\(..\)=\1-\2-\3 \4:\5:\6=g"`
        echo "[INFO ] ${INFOSTOP}"
        USBCON=`/usr/bin/lsusb | grep HASP | wc -l`
        if test ${USBCON:-0} -gt 0
        then
          LSUSBINFO="CONNECTED:${USBCON:-unknown}"
        else
          if test -n "`/bin/rpm -q -a | grep aksusbd`"
          then
            LSUSBINFO="DISCONNECTED"
          else
            LSUSBINFO="SOFTWARE LICENSE"
          fi
        fi

        LVLINFO="STOPPED"

        if test -x ${CHARONDIR}/utils/charon_check.alertcmd
        then
          # In this case alert is not using 'at' cause in case of server shutdown, the alert is not sent
          ${CHARONDIR}/utils/charon_check.alertcmd ${LVLINFO} ${CHKHOST} ${LICENSENUM} "${INFOSTOP}" "${INFOTERM}" "${LSUSBINFO}"
          INFOTERM=""
          TIM=`date +"%Y%m%d;%H%M%S"`
          echo "${TIM};STOPPED;${CHKHOST};ALERT_SENT" >>${LOGFILE}
        fi
      fi

      #--- Emulator is about to exit
      if test -n "`echo ${LINE} | grep 'Emulator is about to exit'`"
      then
        echo "[WARN ] Emulator is about to exit"
        TOPEVT=0
        TIM=`date +"%Y%m%d;%H%M%S"`
        echo "${TIM};TOEXIT;${CHKHOST};${LICENSENUM};" >>${LOGFILE}
        INFOSTOP=`echo ${LINE} | sed "s=\(^.*Emulator \)\(.*$\)=Emulator \2=g"`
        if test -x ${CHARONDIR}/utils/charon_check.alertcmd
        then
          echo ${CHARONDIR}/utils/charon_check.alertcmd TOEXIT ${CHKHOST} ${LICENSENUM} \"${INFOSTOP}\" \"${INFOTERM}\" | at now >/dev/null 2>&1
          INFOTERM=""
        fi
      fi

      #--- Emulator start request
      if test -n "`echo ${LINE} | grep '[Ss]tart request received'`" -o "${MSGCODE}" = "0000032B"
      then
        get_licensenum
        test -z "${LICENSENUM}" && LICENSENUM="UNKNOWN_EMULSTART"
        EMULSTART="Emulator start request on "`echo ${LINE} | awk -F: '{print $1 $2}' | sed "s=\(^....\)\(..\)\(..\)\(..\)\(..\)\(..\)=\1-\2-\3 \4:\5:\6=g"`
        echo "[INFO ] ${EMULSTART}"
        rm -f ${CHARONDIR}/utils/events/${SVCCFG}.license_status 2>/dev/null
        echo "${TIM};EMULATORSTART;${CHKHOST};${LICENSENUM};${EMULSTART}" >>${LOGFILE}
        test -x ${CHARONDIR}/utils/charon_check.alertcmd && \
          echo ${CHARONDIR}/utils/charon_check.alertcmd EMULSTART ${CHKHOST} ${LICENSENUM} \"${EMULSTART}\" | at now >/dev/null 2>&1
      fi

      #--- ... found license key <key_id> (before V4.9)
      if test ${INSBLD} -lt 19103
      then
        test "${MSGCODE}" = "000003DC" && LICENSE_KEY_ID=`echo ${LINE} | sed "s=\(^.*found license key \)\(.*\)\(\.\)=\2=g"`
      else
        if test "${MSGCODE}" = "0000024D"
        then
          if test -n "`echo ${LINE} | grep 'Found license key:'`"
          then
            LICENSE_KEY_ID=`echo ${LINE} | cut -f2 -d'"'`
          else
            if test -n "`echo ${LINE} | grep 'License number:'`"
            then
              LICENSENUM=`echo ${LINE} | cut -f2 -d'"'`
              format_datetime
              echo "${FMTDAT};INFO;Found license key ${LICENSE_KEY_ID}, license number ${LICENSENUM}" \
                   >${CHARONDIR}/utils/events/${SVCCFG}.license_status
            fi
          fi
        fi
      fi

      #--- USB key license mode: date or runtime limited
      if test -n "`echo ${LINE} | grep '^.* limited license,'`"
      then
        #--- If the 1st line of the log is not 3A5 (loading configuration) and if
        #--- there is only one "limited license" line then it's a log rotation so
        #--- no alert is sent.
        MSGCODE1=`head -1 ${GLOG} | cut -f5 -d:`
        NBLIMLIC=`grep '^.* limited license,' ${GLOG} | wc -l`
        if test "${MSGCODE1}" != "000003A5" -a ${NBLIMLIC:-0} = 1
        then
          echo "${TIM};INFORMATION;${CHKHOST};LOG ROTATION DETECTED;no alert on license detected to send" >>${LOGFILE}
        else
          get_usbbusdev

          test ${INSBLD} -lt 19103 && get_licensenum

          test -z "${LICENSENUM}" && LICENSENUM="UNKNOWN_LIM"

          LICDESC=`grep "^${LICENSENUM};" ${DONGLESFILE} 2>/dev/null | cut -f2 -d';'`
          COLDESC=`grep "^${LICENSENUM};" ${DONGLESFILE} 2>/dev/null | cut -f3 -d';'`
          test -n "${LICDESC}" && COLHEX=`echo ${ANSI_TO_HEX} | cut -f${COLDESC} -d' ' 2>/dev/null`

          LICENSEMOD=`echo ${LINE}`
          test -n "`echo ${LICENSEMOD} | grep :0000024D:`" && LICENSEMOD=`echo ${LICENSEMOD} | sed "s=\(^.*):\)\(.*$\)=\2=g"`

          echo "${TIM};INFORMATION;${CHKHOST};${LICENSENUM};${LICENSEMOD}" >>${LOGFILE}
          #test -z "${INFOFOUND}" && INFOFOUND="Hostname: ${CHKHOST}"
          test -x ${CHARONDIR}/utils/charon_check.alertcmd && \
            echo ${CHARONDIR}/utils/charon_check.alertcmd FOUND ${CHKHOST} ${LICENSENUM} \"${LICENSEMOD}\" \"${INFOFOUND}\" ${LICENSE_KEY_ID:-NA} \"${LICDESC:-None}\" \"${COLHEX:-000000}\" | at now >/dev/null 2>&1
          INFOFOUND=""
       
          if test -e ${ALERTEXPLOGFILE}
          then
            test -x ${CHARONDIR}/utils/charon_expchk && \
              echo ${CHARONDIR}/utils/charon_expchk | at now >/dev/null 2>&1
          fi

        fi
      fi

      #--- Communication lost/restored with the license key (V4.9 and above)
      if test ${INSBLD} -ge 19103
      then
        #--- Alerts to send / communication lost or restored
        if test "${MSGCODE}" = "0000024D"
        then
          if test -n "`echo ${LINE} | grep 'Communication with the license key'`"
          then
            TOPEVT=0
            LICKEYID=`echo ${LINE} | cut -f2 -d'"'`
            if test -n "`echo ${LINE} | grep ' lost.'`"
            then
              echo "${TIM};WARN;${CHKHOST};Communication lost with key id ${LICKEYID};License number ${LICENSENUM}" >>${LOGFILE}
              test -x ${CHARONDIR}/utils/charon_check.alertcmd && \
                echo ${CHARONDIR}/utils/charon_check.alertcmd COMMLOST ${CHKHOST} ${LICENSENUM} ${LICKEYID} | at now >/dev/null 2>&1

              format_datetime
              echo "${FMTDAT};WARN;Communication lost with key id ${LICKEYID}, license number ${LICENSENUM}" \
                   >${CHARONDIR}/utils/events/${SVCCFG}.license_status
            else
              if test -n "`echo ${LINE} | grep ' restored.'`"
              then
                echo "${TIM};INFO;${CHKHOST};Communication restored with key id ${LICKEYID};License number ${LICENSENUM}" >>${LOGFILE}
                test -x ${CHARONDIR}/utils/charon_check.alertcmd && \
                  echo ${CHARONDIR}/utils/charon_check.alertcmd COMMREST ${CHKHOST} ${LICENSENUM} ${LICKEYID} | at now >/dev/null 2>&1

                format_datetime
                echo "${FMTDAT};INFO;Communication restored with key id ${LICKEYID}, license number ${LICENSENUM}" \
                     >${CHARONDIR}/utils/events/${SVCCFG}.license_status
              fi
            fi
          fi
        fi
        #--- Alerts to filter or not
        if test -e ${LESSWARNONREMOVAL}
        then
          if test "${MSGCODE}" = "0000024D"
          then
            test -n "`echo ${LINE} | grep 'Unable to log in to the key' | grep ', feature'`" && TOPEVT=0
            test -n "`echo ${LINE} | grep 'HASP runtime (7)' | grep 'Sentinel protection key not available.'`" && TOPEVT=0
            test -n "`echo ${LINE} | grep 'Failed to login at the Sentinel HASP key:'`" && TOPEVT=0
          fi
        fi
      fi

      #--- Detected removal of the license 
      TOPREMLIC=0
      if test ${INSBLD} -ge 19103
      then
        if test "${MSGCODE}" = "0000024D"
        then
          if test -n "`echo ${LINE} | grep 'Connection to license key:' | grep 'lost.'`"
          then
            TOPEVT=0
            NORMOPER=`echo ${LINE} | sed "s=\(^.* lost. \)\(.*$\)=\2=g"`
            TOPREMLIC=1

            format_datetime
            APPSTO=`echo ${LINE} | sed "s=\(^.*licenseman(1830): \)\(.*$\)=\2=g"`
            echo "${FMTDAT};ERROR;${APPSTO}" >${CHARONDIR}/utils/events/${SVCCFG}.license_status
          fi
        fi
      else
        if test -n "`echo ${LINE} | grep -w INFO | grep 'Detected removal of the license'`" \
                -o "${MSGCODE}" = "00000351" -o "${MSGCODE}" = "0000002A"
        then
          NORMOPER=`echo ${LINE} | sed "s=\(^.*of the license. \)\(.*$\)=\2=g"`
          TOPEVT=0
          TOPREMLIC=1
        fi
      fi

      if test ${TOPREMLIC} = 1
      then
        TOPEVT=0
        echo "${TIM};KEY_REMOVED;${CHKHOST};${LICENSENUM};${LICENSEMOD}" >>${LOGFILE}
        AKSUSBINFO="Service state/aksusbd: `/usr/bin/systemctl is-active aksusbd`"
        sleep 1
        if test -z "`/usr/bin/lsusb | grep HASP`"
        then
          echo "[ERROR] Detected removal of the license"
          test -x ${CHARONDIR}/utils/charon_check.alertcmd && \
            echo ${CHARONDIR}/utils/charon_check.alertcmd REMOVED ${CHKHOST} ${LICENSENUM} \"${LICENSEMOD}\" \"${NORMOPER}\" \"${AKSUSBINFO}\" | at now >/dev/null 2>&1
        else
          echo "[ERROR] Detected removal of the license whereas dongle is connected"

          USBCON=`/usr/bin/lsusb | grep HASP | wc -l`
          test -x ${CHARONDIR}/utils/charon_check.alertcmd && \
            echo ${CHARONDIR}/utils/charon_check.alertcmd REMOVRESET ${CHKHOST} ${LICENSENUM} \"${LICENSEMOD}\" \"${NORMOPER}\" \"${AKSUSBINFO}\" \"CONNECTED:${USBCON:-0}\" | at now >/dev/null 2>&1
        fi
        if test -n "${USBHCIMODE}"
        then
          echo "[INFO ] Trying to solve the problem with unbind/bind"
          ls /sys/bus/pci/drivers/${USBHCIMODE} | grep : | while read L
          do
            TIM=`date +"%Y%m%d;%H%M%S"`
            echo "${TIM};USB_UNBIND;Unbinding ${USBHCI}/${USBHCIMODE}/${L}" >>${LOGFILE}
            echo "[INFO ] Unbinding ${USBHCIMODE} / ${L}"
            echo ${L} >/sys/bus/pci/drivers/${USBHCIMODE}/unbind
            sleep 1
            TIM=`date +"%Y%m%d;%H%M%S"`
            echo "${TIM};USB_BIND;Binding ${USBHCI}/${USBHCIMODE}/${L}" >>${LOGFILE}
            echo "[INFO ] Binding ${USBHCIMODE} / ${L}"
            echo ${L} >/sys/bus/pci/drivers/${USBHCIMODE}/bind
          done
        else
          echo "[ERROR] Cannot Unbind, USBHCI variable is empty"
          TIM=`date +"%Y%m%d;%H%M%S"`
          echo "${TIM};USB_UNBIND;Cannot Unbind, USBHCI variable is empty" >>${LOGFILE}
        fi

        #-----------------------------------------------
        # Restarting Sentinel runtime due to some hangs
        #-----------------------------------------------
        echo "[INFO ] Restarting aksusbd service"
        ATJ=`echo $0 aksusbrestart | at now 2>&1`
        echo "${TIM};AKSUSBD_RESTART;${ATJ}" >>${LOGFILE}
        #-----------------------------------------------
      else
        #--- License dongle back online: valid for V4.5
        if test -n "`echo ${LINE} | grep -w INFO | grep 'Detected the license'`"
        then
          TOPEVT=0
          echo "${TIM};KEY_FOUND;${CHKHOST};${LICENSENUM};" >>${LOGFILE}
          INFOFOUND="License detected"
          echo "[INFO ] ${INFOFOUND}"
        else
          #--- License dongle back online
          if test -n "`echo ${LINE} | grep -w INFO | grep 'License detected and online'`" -o "${MSGCODE}" = "0000039D"
          then
            TOPEVT=0
            get_usbbusdev
            get_licensenum
            test -z "${LICENSENUM}" && LICENSENUM="UNKNOWN_DET"
            echo "${TIM};KEY_FOUND;${CHKHOST};${LICENSENUM};" >>${LOGFILE}
            INFOFOUND="License detected and online"
            echo "[INFO ] ${INFOFOUND}"
          fi
        fi
      fi

      #--- Warning: License approaching termination
      if test -n "`echo ${LINE} | grep 'is approaching termination'`" -o "${MSGCODE}" = "000002E4"
      then
        test -e ${ALERTEXPLOGFILE} || TOPEVT=0
      fi

      #--- Sentinel HASP RunTime Error xxx.
      if test -n "`echo ${LINE} | grep 'Sentinel HASP RunTime Error'`"
      then
        if test -s ${HASPERRCODES}
        then
          HASPERR=`echo ${LINE} | sed "s=\(^.*Sentinel HASP RunTime Error \)\(.*\)\(\..*$\)=\2=g" | cut -f1 -d '.'`
          LINE="${LINE} "`grep "^${HASPERR};" ${HASPERRCODES} 2>/dev/null | cut -f2 -d';' | sed -e "s=<KEYID>=${KEYID}=g" -e "s=<KEYMOD>=${KEYMOD}=g"`"."
        fi
      fi

      #--- Hardware specifications warning messages
      if test "${MSGCODE}" = "0000024C" -o "${MSGCODE}" = "00000353" -o "${MSGCODE}" = "00000354"
      then
        #--- If there is a low HW specs message and the 1st line of the log is not
        #--- 3A5 (loading configuration) then it's a log rotation and no alert is sent.
        MSGCODE1=`head -1 ${GLOG} | cut -f5 -d:`
        if test "${MSGCODE1}" != "000003A5"
        then
          echo "${TIM};INFORMATION;${CHKHOST};LOG ROTATION DETECTED;no alert on low hardware specs to send" >>${LOGFILE}
          TOPEVT=0
        fi
        #--- Check if the user requested Warning messages to be ignored
        if test -e ${HWSPECWARNIGNORE}
        then
          TOPEVT=0
        fi
      fi

      if test ${TOPEVT} = 1
      then
        typeset -i LVLEVENT=`cat ${CHKEVENT}`

        if test -n "`echo ${LINE} | grep ':INFO :' | grep CPU | grep -w BUGCHECK`"
        then
          if test ! -e ${MONBUGCHECK}
          then
            if test ${LVLEVENT:-0} -ne 3
            then
              echo "${LINE}" >>${CHARONDIR}/utils/events/${CHKHOST}.partlog
            fi
          fi
        fi

        if test -n "`echo ${LINE} | grep ':INFO :' | grep CPU | grep -w Halted`"
        then
          if test ! -e ${MONCPUHALTED}
          then
            if test ${LVLEVENT:-0} -ne 3
            then
              echo "${LINE}" >>${CHARONDIR}/utils/events/${CHKHOST}.partlog
            fi
          fi
        fi

        case ${LVLEVENT}
        in
          1)
            test -n "`echo ${LINE} | grep ':INFO :'`" && echo "${LINE}" >>${CHARONDIR}/utils/events/${CHKHOST}.partlog
            test -n "`echo ${LINE} | grep ':WARN :'`" && echo "${LINE}" >>${CHARONDIR}/utils/events/${CHKHOST}.partlog
            test -n "`echo ${LINE} | grep ':ERROR:'`" && echo "${LINE}" >>${CHARONDIR}/utils/events/${CHKHOST}.partlog
            test -n "`echo ${LINE} | grep ':FATAL:'`" && echo "${LINE}" >>${CHARONDIR}/utils/events/${CHKHOST}.partlog
            ;;
          2)
            test -n "`echo ${LINE} | grep ':WARN :'`" && echo "${LINE}" >>${CHARONDIR}/utils/events/${CHKHOST}.partlog
            test -n "`echo ${LINE} | grep ':ERROR:'`" && echo "${LINE}" >>${CHARONDIR}/utils/events/${CHKHOST}.partlog
            test -n "`echo ${LINE} | grep ':FATAL:'`" && echo "${LINE}" >>${CHARONDIR}/utils/events/${CHKHOST}.partlog
            ;;
          3)
            test -n "`echo ${LINE} | grep ':ERROR:'`" && echo "${LINE}" >>${CHARONDIR}/utils/events/${CHKHOST}.partlog
            test -n "`echo ${LINE} | grep ':FATAL:'`" && echo "${LINE}" >>${CHARONDIR}/utils/events/${CHKHOST}.partlog
            ;;
        esac
      fi

    done
    ;;
  resetlog)
    echo "${LOGDATE};COMMAND;$1" >>${LOGFILE}
    mv -f ${LOGFILE} ${LOGFILE}.old
    touch ${LOGFILE}
    ;;
  -v)
    echo "Version ${VERSION}"
    ;;
  *)
    echo "$0, wrong parameter1: $1"
    ;;
esac
exit $RETVAL
