#!/bin/bash
#------------------------------------------------------------------------------------------
# CharonReport.sh
#------------------------------------------------------------------------------------------------------------
# Copyright (C) 2021-2023 STROMASYS.
# All rights reserved.
#
#------------------------------------------------------------------------------------------------------------
# History: 
# 30-Aug-21 V0.1 : - Initial version
# 01-Oct-21 V1.0 : - If the Linux Toolkit is not installed or installed but not
#                    used, the name of a .cfg file or a folder containing .cfg
#                    files is requested so that .cfg and .log files can be
#                    added to the zip file
# 13-Oct-21 V1.1 : - Added SElinux settings
#                  - For Charon-SSP:
#                    - Added charon-agentd-ssp service status for Charon-SSP
#                      versions before 4.x
#                    - Added version from executable
#                    - The /opt/charon-agent/ssp-agent/ssp/vm.dat file is added to
#                      the zip file
#                    - Added all crash.log* and _tty*.log* files
#                  - To preserve file attributes, files copied to the zip file
#                    use now 'cp -p'
#                  - Processor table with model name and vendor id reviewed
#                  - Added system UUID
#                  - Added information on GUI / CUI
# 05-Nov-21 V1.2 : - If the Linux server is running as a VMware, if the VMware tools
#                    are not installed, a warning message is displayed
# 08-Nov-21 V1.3 : - For Charon-HPA/PAR:
#                    - added charon-report zip file to the main zip file
#                    - added log file to the zip file (works only if Toolkit is used)
# 09-Nov-21 V1.4 : - For Charon-HPA/PAR: if the Toolkit is not used, to get the log file
#                    name, the script assumes it is in the same folder as the .cfg file
# 15-Nov-21 V1.5 : - For Charon-SSP: error code 101 is now managed
# 17-Nov-21 V1.6 : - Added reboot and shutdown history
# 24-Nov-21 V1.7 : - Bug solved with NetworkManager in case the service is not active
# 08-Dec-21 V1.8 : - Bug detected in Sentinel Admin Control Center parameters table
#                    (minor display bug, not yet solved)
#                  - Bug solved: /etc/hasplm and /var/hasplm folders were not added to
#                    the zip file
#                  - Rotating log files for AXP/VAX: if the 1st log file, at emulator 
#                    startup was not found, only the last log was added to the zip file.
#                    Now all log files are added.
# 09-Dec-21 V1.9 : - Rotating log files for SAP and PAR: if the 1st log file, at emulator 
#                    startup was not found, only the last log was added to the zip file.
#                    Now all log files are added.
# 16-Dec-21 V1.10: - Log file size limit added
#                  - Bug solved for Charon-PAR not adding the charon-report utility to the
#                    zip file
#                  - Charon-SSP console and crash files were not always taken from the
#                    correct folder.
# 17-Dec-21 V1.11: - Added information on log files extraction
#                  - Solved bug introduced in 1.10 and log file selection for AXP/VAX
#                  - Solved bug with console log files selection for AXP/VAX
#                  - Charon-PAR: increased allowed execution time for charon-report to
#                    2 minutes before timeout
# 20-Dec-21 V1.12: - AXP/VAX: NIC log files are now added if they exist
# 24-Dec-21 V1.13: - When displaying licenses content, the 'License Manager running at
#                    host' line now tells if the host corresponds to the current one
#                    (useful when several licenses are available via the network)
# 18-Jan-22 V1.14: - If the reboot history is empty (last -x), a message is added
#                  - 'uname -a' added also in 'Operating System' chapter
#                  - Charon-SSP log files: log files with extension .log.<n> are renamed
#                    in the .zip file to .log.<n>.log for ease of reading on Windows hosts
#                  - Information note added for Ticket/Opportunity/Project
#                  - Customer name must be at least 2 characters, cannot be empty anymore
#                  - If a software license has expired or is possibly in cloned state, a message
#                    asking to remove it is displayed in the HTML report
#                  - Zip file name changed to CharonReport-<customer name>-<hostname>-<date>.zip
#                    Note: customer name is truncated to 16 characters, all accents and non
#                          alphanumeric characters are removed
# 26-Jan-22 V1.15: - More entries in table of contents added for ease of reading
#                  - HASP error log file(s) added to the HTML report
# 28-Feb-22 V1.16: - License content heading name changed
#                  - AXP/VAX: if the toolkit is not used, the .cfg file name is asked. The
#                    .cfg files list is now sorted unique to avoid duplicates
#                  - Progress bar replaced by a spinner without 'tput civis' as sometimes its
#                    counter part the 'tput cvvis' (cursor visible) command does not work
#                    (case where TERM=screen for example)
#                  - journalctl data added to the zip file since the date specified for the
#                    files
# 04-Apr-22 V1.17: - Stromasys logo update
#                  - Table of contents replaced by a navigation bar
#                  - rpm list file is now sorted
# 13-Apr-22 V1.18: - HTML report: minor update in the navigation bar / Charon virtual machines
#                  - HTML report: missing 'Created on' part added
#                  - Added information on VE license
# 29-Apr-22 V1.19: - 'hostname -a' replaced by 'hostname -s' to define the zip file name
#                    ('hostname -a' is deprecated)
#                  - Problem fixed with the rotating wheel (progressbar) display
# 03-May-22 V1.20: - Added 'dmidecode' output to the .zip file
#                  - Added software licenses folder content to the HTML report
# 19-May-22 V1.21: - Minor update in The_End function to suppport integration in Linux Toolkit
#                  - Help added with -h or --help parameters
#                  - Added automatic check for script new version (once in a week)
#                  - Added option to permanently enable/disable automatic checks for updates
#                  - Fixed error message displayed if hasplm log files are not enabled
#                  - HTML report: when displaying USB devices (lsusb), if the vendor is 0529,
#                    it is highlighted (HASP dongle)
#                  - HTML report: added current server time before uptime
#                  - HTML report: if the Toolkit is installed and no virtual machine is configured,
#                    the report will mention it. If the Toolkit is not installed and the user did
#                    not specify any configuration file, it is mentionned too
#                  - If the Toolkit is not installed and the user do not specify any configuration
#                    file, a WARNING is displayed and the user needs to confirm to continue
#                  - If a license dongle does not contain any license, the message is highlighted
# 20-May-22 V1.22: - HTML report: display bug fixed in 'CPU details' table
#                  - Automatic check for script new version is done once per day now
# 15-Jun-22 V1.23: - Toolkit preferences files has been moved to /etc/charon.d/CharonToolkit.config
#                    for kits 2.0+ (coming versions)
#                  - Time service information added: ntpd and/or chronyd
#                  - Bug solved where VMware settings where not always present in the HTML report
# 16-Jun-22 V1.24: - Solved a bug with 'dirname' errors reported during execution after checking for update
# 21-Jun-22 V1.25: - Added Charon Toolkit log files and script files in the zip folder
#                  - Reports (.zip files) are purged once execution is complete: last 7 days kept
# 27-Jun-22 V1.26: - Minor display update: colored warning and error messages
#                  - HTML report: if the 'SEH UTN service' is installed (seh_vhcd), information is displayed (USB/network box)
# 28-Jun-22 V1.27: - If the resulting zip file size is greater than 100Mb, a warning is displayed
#                  - Charon-SSP: log files with last line date greater than the specified date are also included
# 05-Jul-22 V1.28: - Added option to not include IP addresses in Network chapter: 'ip' and 'netstat -r'
#                  - Removed check for update limitation to once per day. Check will be performed each time unless disabled
#                  - Added option to run the script without check for update (one time)
#                  - 'netstat -s' and 'netstat -an' added in attachment as for the Windows version of the report (unless IP addresses are not included)
#                  - HTML report layout updated (removed unnecessary tables)
# 06-Jul-22 V1.29: - Filter added when zipping the /opt/charon/utils folder, was causing too many problems
#                  - Option to run the script without IP addresses reworked (--noip parameter)
# 18-Jul-22 V1.30: - Issue with License anchor not working in the navigation bar when aksusbd is not installed solved
#                  - License: trying to read its content even if aksusbd is not installed (VE)
# 19-Jul-22 V1.31: - License content: if a license is empty, a warning message is displayed
#                  - Bug solved: if NetworkManager is not used and IP addresses were excluded, they were printed anyway
# 28-Jul-22 V1.32: - If include file folder is not specified, /opt/charon/cfg is used as default folder
#                  - Bug solved: if NetworkManager is not used and IP addresses were excluded, GATEWAY and DNS addresses were printed anyway
#                  - Bug solved: 'License Manager running at host' could not display '(this host)' if hostname was 'short' (hostname -s)
#                    with recent aksusbd version
# 05-Aug-22 V1.33: - Added 'dmesg' output to the .zip file
#                  - Containers are now checked and displayed in the HTML report: for vdisk, size and if available model are displayed, for
#                    vtape, size only, for other file type only
#                  - Bug solved for old versions of Charon-PAR (kit could not be found)
# 30-Aug-22 V1.34: - vconsole on Charon-SSP is now taken into account
#                  - if a mandatory package is missing for the script execution, a text is displayed telling how-to install it
#                  - usbutils package is optional (lsusb)
#                  - case managed in case dmidecode is not installed
# 01-Sep-22 V1.35: - all information from the Charon-SSP configuration files are now added in the HTML report
#                  - Charon-VAX: bug solved with containers display in HTML report (specific syntax)
# 03-Oct-22 V1.36: - The 'Memory' chapter now contains the top 20 processes consuming it
#                  - 'chkconfig' existence is tested before displaying its output (deprecated on Linux 9 / not installed by default)
#                  - checks updated for 'ncu' due to changes in Charon-AXP/VAX V4.12
#                  - Resulting zip file comment contains report type and number and is now sorted differently (visible using 'unzip -l'
#                    command). All system folders (/etc, /opt and /var) are renamed with leading underscore character
#                  - Charon product release date is now displayed to identify non official versions
# 13-Oct-22 V1.37: - Added support for Linux 9
#                  - Added agent.log files (current and older ones) if Charon-SSP is installed
# 04-Nov-22 V1.38: - Added warning if no virtual machine is defined with Charon-SSP
#                  - Added /var/log/messages in the resulting zip file
# 24-Nov-22 V1.39: - Added check on supported operating systems
#                  - If a new version of the script has been downloaded during execution, it is immediately executed (instead of 'exit')
#                  - If Charon-SSP is installed but no emulator is defined in the SSP Manager interface, the location of the .cfg
#                    file(s) is/are requested (then the log file is located)
#                  - Charon-SSP rotated console log files are added to the zip file
#                  - Several minor changes (HTML layout, questions, etc...)
# 16-Dec-22 V1.40: - For better compatibility, 'locale' settings are forced to 'C'
#                  - If the Linux toolkit is not installed and used, the script will try to find valid .cfg
#                    files based on running processes before asking the location of the .cfg file(s) used on
#                    the server
#                  - Charon products and versions table updated (SSP 5.6.1)
#                  - If the Linux toolkit is installed but not used to run the Charon emulator(s), user has
#                    to specify location of the .cfg file(s) if not already known by the CharonReport utility
#                  - Results chapter now contains all warning and errors found (duplicate messages are removed)
#                  - Added check for duplicate license number (with different keyid)
#                  - If Out of Memory killer killed a Charon process, this is reported in the HTML report
#                  - Bug solved: could not always get history of reboot and shutdown on Linux 8 & 9. Now retrieving latest 12 entries.
# 21-Dec-22 V1.41: - It is possible to answer 'q' to quit the CharonReport for questions asked at the beginning of the script execution
#                  - Update in OOM kills tracking: all kills are now reported and the report highlights known Charon processes when possible
#                    (as Linux reports a process name that can be different from executable file name)
# 12-Jan-23 V1.42: - Added more information on memory (banks)
#                  - Solved 'sort' bug in top 20 processes using memory chapter
#                  - 'Running processes (grep charon)' chapter reworked
#                  - CPU details: more information added
#                  - OPA0 syntax (for AXP/VAX) is checked depending on Charon version: reports warning if old syntax is used
# 25-Jan-23 V1.43: - HTML layout issue solved for OPA0 console (for AXP/VAX)
#                  - OPA0 console check for AXP/VAX: message updated if console does not use telnet port
#                  - Rewording: replaced 'Caption' by 'Legend' in some chapters
#                  - Using 'hostnamectl' instead of 'hostname' to get more information
#                  - Several chapters layout reviewed or corrected
#                  - Results chapter: added the 'Id' column where clicking leads to the details of the event
#                    in the HTML file
#                  - Bug solved with OPA0 console syntax check for AXP/VAX if the Linux toolkit is not installed
#                    reporting unknown syntax used for OPA0
# 27-Jan-23 V1.44: - Missing 'Back to top' added (end of report)
#                  - Filter added in memory banks to exclude 'No Module Installed' lines
#                  - Bug solved in 'Results' table: hyperlinks could point to the wrong location
# 08-Feb-23 V1.45: - Started update for multi-Charon products on the same server
#                  - Added -s option (--short) for short report version
#                  - Removed -x option (--noip), replaced by short version
# 10-Feb-23 V1.46: - Update for multi-Charon products on the same server
#                  - Clicking Stromasys logo now brings to top of HTML report, no more to www.stromasys.com
#                  - Minor display bugs solved
#                  - Charon-SSP: Charon version from executables chapter updated
#                  - Bug solved in sorted/unique errors in the Results chapter
# 08-Mar-23 V1.47: - Bug solved when user was asked twice to specify the .cfg file (bug introduced in V1.46
#                    and multi-products support)
#                  - NUMA balancing chapter reworked. Now generates an error alert if set to ON and Charon-PAR
#                    is installed
#                  - Added timedatectl output in all cases in 'Time service settings' chapter
#                  - 'at' package is now required only if aksusbd is installed (HASP license) and if 'at' is
#                    installed a check if performed to verify 'atd' service is running
#                  - Charon-PAR: bug solved / always looking for log file in 'logs' subfolder if Toolkit is
#                    not used
#                  - Charon-PAR: if log file is not found in the same folder as the .cfg file, the log file
#                    is searched in .cfg file 'log.name' parameter and if not found, search default one with
#                    'find' command, not NFS mounted, most recent. As this is not 100% sure the correct log
#                    file will be found, please specify log file name in .cfg file if Toolkit is not used
#                  - Added '-r' or '--reset' option to reset already known emulators list (useful in case of
#                    migration from non Toolkit to Toolkit emulators management)
#                  - Added support for AXP/VAX baremetal version (Charon Manager)
#                  - Reworked checks on several (systemd) services
#                  - HTML report: headings color change (not the same as navigation bar) for ease of reading
#                  - Minor display issue solved in crontab checks
#                  - Submenu added for 'Charon Toolkit', 'HASP license settings' and 'VE license settings'
#                    if installed
#                  - Reworked Charon virtual machines discovery: Charon Manager -> Toolkit -> Running
#                    processes (Note: discovery can be turned off using '-x' or '--nodiscovery' option)
#                  - Charon-SSP virtual machines: if power scheme is not set to Performance a warning message
#                    is generated (recommended mode)
#                  - Inside the CharonReport zip file, emulators child folders have a 3 digit number in their
#                    name to avoid overwriting (before folders where based on .cfg file name so duplicates
#                    were possible)
# 10-Mar-23 V1.48: - Added missing submenu entry for 'HASP License settings'
#                  - Charon Manager: virtual machines reported as stopped in the HTML report whereas they are
#                    running bug solved
#                  - Charon Manager: virtual machines stopped date was not displayed
# 14-Mar-23 V1.49: - Default date to gather log files is now one month ago and no more one week ago
#                  - option to remove automatic emulators discovery is hidden, was confusing
#                  - Top 20 processes consuming memory chapter updated: the 'command' column contains now
#                    the executable and its parameters (parameters were missing in previous versions)
#                  - Bug solved for discovered or user specified emulators in 'stopped' state whereas they are
#                    running. Case occurs when cfg file is passed as emulator parameter without full path.
#                    Recommendation: cfg and log files path must be specified 
#                  - Charon-PAR: 'charon-report' utility execution output is added to the zip file for debugging
#                    (sometimes the report.tgz file cannot be found)
#                  - Zip file: Charon virtual machines child folder name is added in HTML report (due to added
#                    incremental number)
#                  - Zip file: added /var/log/audit/audit.log* files if SElinux is set to Enforcing
#                  - HTML report: corrected bug in number of services and running ones in Results chapter
# 15-Mar-23 V1.50: - Log files added to the zip file: for session log files, now shows begin and end date in
#                    the HTML report (this information is not available for console and network log files)
#                  - Minor bug solved with 'lsusb' empty file generated during script execution in current folder
#                  - Enhanced containers check following issue found on customer site with Charon-SSP
#                  - Containers check: now allows use of white spaces in file names 
#                  - HASP license: enhanced tests for cases where aksusbd package was installed and removed
#                    leaving traces
#                  - Corrected display issue in 'Time service settings' chapter when escape sequences are
#                    returned by the timedatectl command output (warning message)
#                  - Charon-PAR: increased charon-report utility execution timeout to 180 seconds
#                  - Added alternate way to check for Charon Report script update if 1st attempt fails with
#                    'cannot verify fileserver.stromasys.com's certificate' error
# 22-Mar-23 V1.51: - Solved minor display issue when script execution ends
#                  - If VE license servers are defined in emulators configuration files, it is asked at the
#                    end of execution of this script to run the CharonReport on the VE license servers too
#                  - Solved bug with Charon-SSP configuration file: cpu information, except idle mode, was no
#                    more displayed in the HTML file
# 18-Apr-23 V1.52: - It is now possible to skip the configuration file(s) request when asked to give the list
#                    (for pure HASP and/or VE license servers with no emulator configured)
#                  - Bug solved with anchors when 2 emulators have the same file name but in different folders
# 28-Apr-23 V1.53: - Systemd service files protection is checked (following a case where protections were
#                    changed by the customer). This produces a warning message only as this does not prevent the
#                    service from starting
#                  - Updated check for parameter '-all' in hasp_srm_view if '/usr/bin/strings' is not installed
#                  - Charon-PAR: increased charon-report utility execution timeout to 600 seconds (10 minutes)
#                  - Charon-PAR: if emulator found is not defined using the toolkit and if the log file cannot
#                    be found, a check is added to verify 'log.disable' is set to 'true' (not recommended)
# 05-May-23 V1.54: - hasp_srm_view output text file is added to the zip file so the content of the license
#                    is not only visible in the HTML report
# 21-Jun-23 V1.55: - 'bc' package is not more mandatory
#                  - If 'netstat' is not installed, it is skipped (no more mandatory package)
#                  - In some cases, the log file name could not be correctly evaluated for Charon-SSP due to CRLF
#                    in the configuration file. This is now solved
#------------------------------------------------------------------------------------------------------------
RVERSION="1.55"
RVERDATE="07-Jun-23"
#set -x
ABORT=0
LANGORI=${LANG}
export LANG="C"
export LANG_ALL="C"
export LC_MESSAGE="C"
export LC_ALL="C"  

ESC=$(echo -e "\033")
ESCWARN="${ESC}[38;5;208m"
ESCERROR="${ESC}[41;37m"
ESCBLUE="${ESC}[38;5;27m"
ESCGREEN="${ESC}[38;5;77m"
ICOWARNING="&#9888;"

HTMLFILE="CharonReport.html"
TMPRPMFILE="/tmp/CharonReport_all-packages.txt"
TMPSVCLIST="/tmp/CharonReport_serviceslist.txt"
TMPVESVRLIST="/tmp/CharonReport_VEserverslist.txt"
rm -f ${TMPVESVRLIST} 2>/dev/null
HASPLMINI="/etc/hasplm/hasplm.ini"
HASPLMDIR="/var/hasplm"
ETCCHARON="/etc/charon.d"
SHORTVERSION=0
DODISCOVERY=1

VMWARETOOLBOXCMD="/usr/bin/vmware-toolbox-cmd"

typeset -i PBARPOS=0
echo 0 >/tmp/CharonReportProgBar.cnt

test -f ${ETCCHARON} && mv -f ${ETCCHARON} ${ETCCHARON}.old
test -d ${ETCCHARON} || mkdir ${ETCCHARON}

#--- Log file max size in KB
LOGMAXSIZ=100000
LOGMAXDIS=$(printf "%'.f\n" ${LOGMAXSIZ})

CHECKFORUPDATE="${ETCCHARON}/Check_for_updates.disabled"
CHECKFORUPDRUN=1

#--- Removed starting with version 1.28
test -s ${ETCCHARON}/Check_for_updates.lastexec && rm -f ${ETCCHARON}/Check_for_updates.lastexec 2>/dev/null

FILESERVERLINK="https://fileserver.stromasys.com/files/list?apikey=Charon-utils_720398af&name=/Linux/CharonReportUtility/"

SEHUTNSERVICE="seh_vhcd"

#--- Emulators without ROM container hash table definition
declare -A NoROMservers
NoROMservers["MicroVAX_3600"]=1
NoROMservers["MicroVAX_3900"]=1
NoROMservers["MicroVAX_II"]=1
NoROMservers["VAX_6310"]=1
NoROMservers["VAX_6610"]=1
NoROMservers["VAX_6620"]=1
NoROMservers["VAX_6630"]=1
NoROMservers["VAX_6640"]=1
NoROMservers["VAX_6650"]=1
NoROMservers["VAX_6660"]=1
NoROMservers["VAXserver_3600"]=1
NoROMservers["VAXserver_3600_128"]=1
NoROMservers["VAXserver_3600_512"]=1
NoROMservers["VAXserver_3900"]=1
NoROMservers["VAXserver_3900_128"]=1
NoROMservers["VAXserver_3900_512"]=1
NoROMservers["VAXstation_4000_Model_90"]=1

#--- Products release date hash table definition
declare -A CharonProd
CharonProd["axp12904"]="25-Aug-2011"
CharonProd["axp14701"]="28-Nov-2012"
CharonProd["axp14707"]="23-Apr-2014"
CharonProd["axp15504"]="17-Oct-2013"
CharonProd["axp15505"]="26-Nov-2014"
CharonProd["axp15506"]="08-Sep-2014"
CharonProd["axp15507"]="14-Nov-2014"
CharonProd["axp16803"]="22-Apr-2015"
CharonProd["axp16804"]="04-Jun-2015"
CharonProd["axp16900"]="Internal only[W]"
CharonProd["axp17101"]="23-Nov-2015"
CharonProd["axp17103"]="27-Apr-2016"
CharonProd["axp17104"]="30-May-2016"
CharonProd["axp17107"]="28-Sep-2016"
CharonProd["axp17109"]="26-Apr-2017"
CharonProd["axp17111"]="21-Jul-2017"
CharonProd["axp17113"]="05-Apr-2018"
CharonProd["axp18302"]="01-Mar-2017"
CharonProd["axp18303"]="28-Apr-2017"
CharonProd["axp18304"]="28-Jul-2017"
CharonProd["axp18305"]="18-Aug-2017"
CharonProd["axp18306"]="07-Nov-2017"
CharonProd["axp18309"]="05-Apr-2018"
CharonProd["axp19402"]="23-Oct-2018"
CharonProd["axp19404"]="21-Feb-2019"
CharonProd["axp19407"]="02-Jul-2019"
CharonProd["axp19408"]="29-Jul-2019"
CharonProd["axp20203"]="09-Oct-2019"
CharonProd["axp20205"]="14-Apr-2020"
CharonProd["axp20206"]="01-Jun-2020"
CharonProd["axp20207"]="22-Dec-2020"
CharonProd["axp20409"]="12-Jan-2121, replaced by 20410[W]"
CharonProd["axp20410"]="23-Feb-2021"
CharonProd["axp20411"]="16-Sep-2021"
CharonProd["axp20413"]="21-Jan-2022"
CharonProd["axp20415"]="31-May-2022"
CharonProd["axp21002"]="08-Sep-2022, replaced by 21003[W]"
CharonProd["axp21003"]="21-Sep-2022"
CharonProd["axp21004"]="06-Dec-2022"
CharonProd["axp21005"]="10-Mar-2023"

CharonProd["vax16502"]="13-Nov-2014"
CharonProd["vax16803"]="Internal only[W]"
CharonProd["vax16900"]="Internal only[W]"
CharonProd["vax17101"]="23-Nov-2015"
CharonProd["vax17103"]="27-Apr-2016"
CharonProd["vax17104"]="30-May-2016"
CharonProd["vax17107"]="28-Sep-2016"
CharonProd["vax17109"]="26-Apr-2017"
CharonProd["vax17111"]="21-Jul-2017"
CharonProd["vax17113"]="05-Apr-2018"
CharonProd["vax18302"]="01-Mar-2017"
CharonProd["vax18303"]="28-Apr-2017"
CharonProd["vax18304"]="28-Jul-2017"
CharonProd["vax18305"]="18-Aug-2017"
CharonProd["vax18306"]="07-Nov-2017"
CharonProd["vax18309"]="05-Apr-2018"
CharonProd["vax19402"]="23-Oct-2018"
CharonProd["vax19404"]="21-Feb-2019"
CharonProd["vax19407"]="02-Jul-2019"
CharonProd["vax19408"]="29-Jul-2019"
CharonProd["vax20203"]="09-Oct-2019"
CharonProd["vax20205"]="14-Apr-2020"
CharonProd["vax20206"]="01-Jun-2020"
CharonProd["vax20207"]="22-Dec-2020"
CharonProd["vax20409"]="12-Jan-2121, replaced by 20410[W]"
CharonProd["vax20410"]="24-Feb-2021"
CharonProd["vax20411"]="16-Sep-2021 (suspended)[W]"
CharonProd["vax20413"]="21-Jan-2022"
CharonProd["vax20415"]="31-May-2022"
CharonProd["vax21002"]="08-Sep-2022, replaced by 21003[W]"
CharonProd["vax21003"]="21-Sep-2022"
CharonProd["vax21004"]="06-Dec-2022"
CharonProd["vax21005"]="10-Mar-2023"

CharonProd["par3.0.4"]="21-Oct-2021"
CharonProd["par3.0.6"]="Never released[W]"
CharonProd["par3.0.7"]="18-Jul-2022"
CharonProd["par3.0.8"]="30-Sep-2022 (for rp54xx models)"
CharonProd["par3.0.9"]="13-Mar-2023 (for rp54xx models)"

CharonProd["ssp1.0.25"]="01-May-2015"
CharonProd["ssp1.0.34"]="18-Dec-2015"
CharonProd["ssp1.0.36"]="11-Apr-2016"
CharonProd["ssp1.4.1"]="27-Dec-2016"
CharonProd["ssp1.4.5"]="17-Aug-2017"
CharonProd["ssp1.4.6"]="03-Dec-2017"
CharonProd["ssp1.5.1"]="Test version[W]"
CharonProd["ssp2.0.1"]="29-Mar-2018 (not released)[W]"
CharonProd["ssp2.0.5"]="18-Jun-2018"
CharonProd["ssp3.0.2"]="17-Sep-2019"
CharonProd["ssp4.0.4"]="28-Jan-2020"
CharonProd["ssp4.0.5"]="30-Mar-2020"
CharonProd["ssp4.2.5"]="05-Jan-2021 (suspended)[W]"
CharonProd["ssp4.2.6"]="26-Jan-2021"
CharonProd["ssp4.2.7"]="29-Mar-2021"
CharonProd["ssp5.0.1"]="29-Mar-2021"
CharonProd["ssp5.0.2"]="07-Jun-2021"
CharonProd["ssp5.2.5"]="11-Aug-2021"
CharonProd["ssp5.4.3"]="20-Jun-2022"
CharonProd["ssp5.4.5"]="23-Sep-2022 (internal only)"
CharonProd["ssp5.4.6"]="26-Sep-2022 (internal only)"
CharonProd["ssp5.6.1"]="16-Dec-2022"

#--- Discovery sources hash table definition
declare -A DSPSOURCE
DSPSOURCE["manager"]="Charon Manager"
DSPSOURCE["toolkit"]="Linux Toolkit"
DSPSOURCE["discovered"]="Discovered/running processes"
DSPSOURCE["user"]="Specified by user"


#=============================================================================
#--- Usage
#=============================================================================
function Usage {
  cat <<EOF

  This script collects information on the Charon server running on Linux.
  By default, when the script is executed, it will check for new version
  available once per day.

  $(tput bold)Note$(tput sgr0):
    It must be executed as root.

  $(tput bold)Parameters$(tput sgr0):
    -h or --help           : display this help text
    -n or --noupdate       : execute script without update check (one time)
    -d or --disablecheck   : permanently disable automatic update check
    -e or --enablecheck    : permanently enable automatic update check
                             (enabled by default)
    -s or --short          : short version report with sensitive data
                             removed
    -r or --reset          : reset already known virtual machines list
                             and generates the report (useful when migrating
                             for non Toolkit to Toolkit emulators management)
EOF
}

#=============================================================================
#--- Check for update...
#=============================================================================
function Check_Update {
  URETURN=0
  FVERSION=""
  if test ! -e ${CHECKFORUPDATE}
  then
    if test -x /usr/bin/wget
    then
      typeset -i NRETRIES=0
      NOCERT=""
      while test ${NRETRIES} -lt 2
      do
        URETURN=0
        FVERSION=""
        content=$(wget "${FILESERVERLINK}" -t 3 -T 10 -nv -O - ${NOCERT} 2>&1)
        if test $? -eq 0
        then
          if test -n "$(echo $content |grep '<p>No files were found')"
          then
            FVERSION="File not found on Stromasys file server"
            URETURN=1
          else
            OLDIFS=${IFS}
            IFS=$'\n' array=($content)
            typeset -i IA=0
            while test $IA -lt ${#array[@]}
            do
              item=${array[$IA]}
              if test -n "$(echo $item | grep \.sh\<)"
              then
                FVERSION=$(echo $item | sed "s=^.*</i> CharonReport\.\(.*\)\.sh.*$=\1=g")
                IA=${#array[@]}
              fi
              IA=IA+1
            done
            IFS=${OLDIFS}
            break
          fi
        else
          #--- if "--no-check-certificate" is displayed or "cannot verify fileserver.stromasys.com's certificate", retry the wget command with this parameter once
          if test -n "$(echo $content | grep '\--no-check-certificate')" -o -n "$(echo $content | grep 'cannot verify' | grep -w 'certificate')" 
          then
            NOCERT="--no-check-certificate"
          fi
          URETURN=5
        fi
        NRETRIES=NRETRIES+1
      done
      test -z "${FVERSION}" && URETURN=2
    else
      FVERSION="wget not found"
      URETURN=3
    fi
  fi
  if test ${URETURN} -ne 0 -a -z "${FVERSION}"
  then
    FVERSION=${content}
  fi
  return ${URETURN}
}

function Exec_Check_Update {
  EXECEND=0
  echo "Checking for updates..."
  tput sc
  Check_Update
  if test $? -eq 0
  then
    if test -n "${FVERSION}"
    then
      RVCHK=$(printf '%04d' $(echo ${RVERSION}|cut -f1 -d'.'))$(printf '%04d' $(echo ${RVERSION}|cut -f2 -d'.'))
      FVCHK=$(printf '%04d' $(echo ${FVERSION}|cut -f1 -d'.'))$(printf '%04d' $(echo ${FVERSION}|cut -f2 -d'.'))
      if test ${FVCHK} -gt ${RVCHK}
      then
        tput bold
        echo "${ESCWARN}A new version is available: ${FVERSION}"
        tput sgr0
        while test 1
        do
          echo -n "Do you want to download it (y/n) ? "
          read ANS
          case "${ANS}"
          in
            y|Y)
              APIKEY=$(echo ${FILESERVERLINK} | sed "s=^.*\/list?\(.*\)\&name.*$=\1=g")
              FSNAME=$(echo ${FILESERVERLINK} | sed "s:^.*\&\(name=.*\)$:\1:g")
              DOWNLOADLINK=$(echo ${FILESERVERLINK} | sed "s=\(^.*\)\/list.*$=\1=g")"/transfer?${FSNAME}CharonReport.${FVERSION}.sh&${APIKEY}"
              TARGETSH="$(dirname $0)/CharonReport.${FVERSION}.sh"
              wget "${DOWNLOADLINK}" -t 3 -T 10 -nv -O ${TARGETSH}
              if test $? -eq 0
              then
                chmod u+x ${TARGETSH}
                echo
                echo -n "The new version is available: "
                tput bold
                echo ${TARGETSH}
                tput sgr0
                echo
                ${TARGETSH}
                EXECEND=1
              else
                echo
                echo "${ESCERROR}Error trying to download the new version. Please check.${ESC}[0m"
              fi
              break
              ;;
            n|N)
              break
              ;;
            *)
              tput cuu1
              tput el
              ;;
          esac
        done
      else
        tput rc
        tput ed
        if test ${FVCHK} -eq ${RVCHK}
        then
          echo "${ESCGREEN}You're running the latest version of CharonReport${ESC}[0m"
        else
          tput bold
          echo "${ESCWARN}You're running a 'work in progress' version of CharonReport${ESC}[0m"
          tput sgr0
        fi
      fi
    fi
  else
    test -n "${FVERSION}" && echo "[${ESCWARN}WARN ${ESC}[0m] ${ESCWARN}${FVERSION}${ESC}[0m"
  fi
  test ${EXECEND} -eq 1 && The_End
}

#=============================================================================
#--- Trap / End
#=============================================================================
function The_End {
  tput rmacs
  tput sgr0
  echo
  tput ed
  if test ${ABORT:-0} -eq 1
  then
    echo "${ESCERROR}Aborted at $(date +"%H:%M:%S").${ESC}[0m"
  else
    echo "${ESC}[1mCompleted at $(date +"%H:%M:%S").${ESC}[0m"
  fi
  rm -f  ${TMPRPMFILE} ${TMPSVCLIST} ${TMPVESVRLIST} /tmp/CharonReport.navbar.tmp     \
         /tmp/CharonReport*.view /tmp/CharonReportProgBar.cnt /tmp/CharonReport_*.tmp \
         2>/dev/null
  rm -rf ${ZIPFOLDER}/CharonReport.d 2>/dev/null
  exit $1
}

trap 'ABORT=1;The_End 1' 1 2 14 15

echo "${ESC}[44;37m STROMASYS - Charon Report Utility V${RVERSION} - ${RVERDATE} ${ESC}[0m"

#-------------------------------------------------------------
# Check if executed as root
#-------------------------------------------------------------
if test $(id -u) -ne 0
then
  if test "${TERM}" != "dumb"
  then
    echo "${ESCERROR} Must be root ${ESC}[0m"
  else
    echo "Must be root !"
  fi
  echo
  exit 1
fi

#-------------------------------------------------------------
# Check if a parameter is passed (only one allowed)
#-------------------------------------------------------------
case "$1"
in
  "-h"|"--help")
    Usage
    The_End
    ;;
  "-n"|"--noupdate")
    CHECKFORUPDRUN=0
    if test -e ${CHECKFORUPDATE}
    then
      echo "[${ESCWARN}WARN${ESC}[0m ] Check for updates is already disabled."
    fi
    ;;
  "-d"|"--disablecheck")
    if test -e ${CHECKFORUPDATE}
    then
      echo "[INFO ] Check for updates is already disabled ."
    else
      touch ${CHECKFORUPDATE}
      echo "[INFO ] Check for updates is now disabled."
    fi
    The_End
    ;;
  "-e"|"--enablecheck")
    if test ! -e ${CHECKFORUPDATE}
    then
      echo "[INFO ] Check for updates is already enabled."
    else
      rm -f ${CHECKFORUPDATE} 2>/dev/null
      echo "[INFO ] Check for updates is now enabled."
    fi
    The_End
    ;;
  "-s"|"--short")
    SHORTVERSION=1
    echo "${ESCGREEN}Short version selected.${ESC}[0m"
    ;;
  "-r"|"--reset")
    rm -f ${ETCCHARON}/CharonReport_cfgselected*.txt 2>/dev/null
    echo "[INFO ] Known Charon virtual machines (emulators) list by the Charon Report"
    echo "        has been reset."
    ;;
  "-x"|"--nodiscovery")
    DODISCOVERY=0
    ;;
  "")
    ;;
  *)
    echo "[${ESCWARN}WARN${ESC}[0m ] Unknown parameter '$1'"
    exit 13
    ;;
esac

#---------------------------------------------------------------------
# Rename "charon_report_*" files in /etc/charon.d (old versions) to
# "CharonReport_*" 
#---------------------------------------------------------------------
for oldname in "customer" "reporttype" "reportnumb" "folder"
do
  if test -e ${ETCCHARON}/charon_report_${oldname}.txt
  then
    mv -f ${ETCCHARON}/charon_report_${oldname}.txt ${ETCCHARON}/CharonReport_${oldname}.txt
  fi
done

CUSTOMERNAME=$(cat ${ETCCHARON}/CharonReport_customer.txt 2>/dev/null)

#-------------------------------------------------------------
# Check for update
#-------------------------------------------------------------
test ${CHECKFORUPDRUN:-1} -eq 1 && Exec_Check_Update

#-------------------------------------------------------------
# Check for required packages
#-------------------------------------------------------------
if test -x /usr/bin/dnf
then
  YUMM="dnf"
else
  YUMM="yum"
fi

CHK=1
for XP in zip:zip
do
  X=$(echo ${XP} | cut -f1 -d':')
  P=$(echo ${XP} | cut -f2 -d':')
  XW=$(which $X 2>/dev/null)
  if test -z "${XW}"
  then
    test $CHK -eq 1 && echo "${ESC}[1mRequired packages${ESC}[0m:"
    CHK=0
    echo "'$X' is not installed. Please install using '${YUMM} install ${P}' command."
  fi
done

#-------------------------------------------------------------
# Check for required 'at' package for HASP license view
#-------------------------------------------------------------
OKAT=0
if test -x /usr/sbin/aksusbd
then
  #--- if HASP license (aksusbd), 'at' must be installed and service
  #    running to read the license content
  if test -x /usr/bin/at
  then
    systemctl -q is-active atd
    if test $? -ne 0
    then
      CHK=1
      echo
      echo "${ESCWARN}'at' is installed but 'atd' service is not started${ESC}[0m"
      echo "This service must be running to read the HASP license content."
      echo
      while test 1
      do
        echo -n "Do you want to start it before continuing (y/n) ? "
        read ANS
        case "${ANS}"
        in
          y|Y)
            echo "Starting 'atd' service..."
            systemctl start atd
            sleep 1
            systemctl -q is-active atd
            if test $? -eq 0
            then
              echo "${ESCGREEN}Started.${ESC}[0m"
              OKAT=1
            else
              echo "${ESCWARN}Could not be started${ESC}[0m"
            fi
            break
            ;;
          n|N)
            break
            ;;
          *)
            tput cuu1;tput ed
            ;;
        esac
      done
    else
      OKAT=1
    fi
  else
    test $CHK -eq 1 && echo "${ESC}[1mRequired packages${ESC}[0m:"
    CHK=0
    echo "'at' is not installed. Please install using '${YUMM} install at' command."
  fi
else
  if test -x /usr/bin/at
  then
    systemctl -q is-active atd
    test $? -eq 0 && OKAT=1
  fi
fi

if test $CHK -eq 0
then
  echo "${ESCERROR} Please install the missing package(s) then restart the utility ${ESC}[0m"
  exit 2
fi


#-------------------------------------------------------------
# About this script
#-------------------------------------------------------------
cat <<README1
${ESC}[1mSupported Operating Systems${ESC}[0m:
 - Red Hat Enterprise Linux 7, 8 and 9
 - CentOS 7 & 8
 - Rocky Linux 8 and 9
README1


cat <<README2
${ESC}[1mSupported products${ESC}[0m:
- Charon-AXP (with or without Charon Toolkit installed)
- Charon-VAX (with or without Charon Toolkit installed)
- Charon-PAR (preferably with Charon Toolkit installed)
- Charon-SSP

README2

OKOS=0
OS_RELEASE=/etc/system-release
test -e /etc/redhat-release && OS_RELEASE=/etc/redhat-release
if test -s ${OS_RELEASE}
then
  case "$(cat ${OS_RELEASE} | awk '{print $1}')"
  in
    "Red")
      test -z "$(uname -r | grep '\.el6\.')" && OKOS=1
      ;;
    "CentOS")
      test -z "$(uname -r | grep '\.el6\.')" && OKOS=1
      ;;
    "Rocky")
      OKOS=1
      ;;
    "Charon")
      OKOS=1
      ;;
  esac
fi
if test ${OKOS} -eq 0
then
  echo "${ESCERROR} This operating system is not supported ${ESC}[0m"
  echo 
  echo "Please note this script must be executed on the Linux server where Charon is"
  echo "running, not on the legacy OS (Tru64, HPUX, Solaris)"
  exit 1
fi

#-------------------------------------------------------------
# Initial preparation
#-------------------------------------------------------------
echo "Please wait..."

#--- Store all rpm in temp file
rpm -q -a >${TMPRPMFILE}

#--- Store all services list in a temp file
systemctl --all --type service >${TMPSVCLIST}

#--- Clear stdin buffer
while read -r -t 0; do read -r; done
tput cuu1;tput el

#-------------------------------------------------------------
# Ask customer name, log set date, report type and folder
#-------------------------------------------------------------
CHK=0
SAVEDCN=${CUSTOMERNAME}
while test ${CHK} -eq 0
do
  if test -z "${CUSTOMERNAME}"
  then
    echo -n "${ESC}[1mCustomer name${ESC}[0m: "
    read CUSTOMERNAME
  else
    echo -n "${ESC}[1mCustomer name${ESC}[0m [${CUSTOMERNAME}]: "
    read ANS
    test -n "${ANS}" && CUSTOMERNAME=${ANS}
    test "${ANS}" = "q" && exit 7
  fi
  if test -n "${CUSTOMERNAME}"
  then
    CN=$(echo ${CUSTOMERNAME} | tr -dc [:alnum:] | wc -c)
    if test ${CN} -ge 2
    then
      echo "${CUSTOMERNAME}" >${ETCCHARON}/CharonReport_customer.txt
      CHK=1
    else
      echo "${ESCWARN}This field must contain at least 2 characters.${ESC}[0m"
      CUSTOMERNAME=${SAVEDCN}
    fi
  else
    echo "${ESCWARN}This field cannot be empty.${ESC}[0m"
  fi
done
tput cuu1;tput ed
echo -n "${ESC}[1m"
printf "%-18s" "Customer name"
echo "${ESC}[0m: ${CUSTOMERNAME}"

LOGSETDAT=$(date +'%d-%b-%Y' -d "-1 month")
grep -e ^charon\- -e ^hpa\- -q ${TMPRPMFILE}
if test $? -eq 0
then
  CHK=0
  while test ${CHK} -eq 0
  do
    echo -n "${ESC}[1mLog files since${ESC}[0m [${LOGSETDAT}]: "
    read ANS
    test -n "${ANS}" && LOGSETDAT=${ANS}
    test "${ANS}" = "q" && exit 7
    CHKDAT=$(date +'%d-%b-%Y' -d "${LOGSETDAT}" 2>/dev/null)
    if test -n "${CHKDAT}"
    then
      if test $(date +'%s' -d "${LOGSETDAT}") -gt $(date +'%s')
      then
        echo "${ESCWARN}Date cannot be in the future.${ESC}[0m"
        LOGSETDAT=$(date +'%d-%b-%Y' -d "-1 month")
      else
        LOGSETDAT=$(date +'%d-%b-%Y' -d "${LOGSETDAT}")
        CHK=1
      fi
    else
      echo "${ESCWARN}Invalid date.${ESC}[0m"
      LOGSETDAT=$(date +'%d-%b-%Y' -d "-1 month")
    fi
  done
  tput cuu1;tput ed
  echo -n "${ESC}[1m"
  printf "%-18s" "Log files since"
  echo "${ESC}[0m: ${LOGSETDAT}"
fi
JDAT=$(date -d ${LOGSETDAT} +%Y-%m-%d)

CHK=0
REPDEF=$(cat ${ETCCHARON}/CharonReport_reporttype.txt 2>/dev/null)
test -z "${REPDEF}" && REPDEF=1
while test ${CHK} -eq 0
do
  echo
  echo "${ESC}[48;5;27m${ESC}[37m Note for report type ${ESC}[0m"
  echo "${ESC}[38;5;27m'Ticket' is used for opening a support case or when one is already opened.${ESC}[0m"
  echo "${ESC}[38;5;27m'Opportunity' and 'Project' are more for Stromasys and its partners (this${ESC}[0m"
  echo "${ESC}[38;5;27mis cosmetic only and does not change the content of the report).${ESC}[0m"
  echo 
  echo -n "${ESC}[1mReport type${ESC}[0m (1=Ticket, 2=Opportunity, 3=Project) [${REPDEF}]: "
  read ANS
  test -z "${ANS}" && ANS=${REPDEF}
  case "${ANS}"
  in
    "1")
      REPORTTYPE="Ticket"
      CHK=1
      ;;
    "2")
      REPORTTYPE="Opportunity"
      CHK=1
      ;;
    "3")
      REPORTTYPE="Project"
      CHK=1
      ;;
    "q")
      exit 7
      ;;
    *)
      echo "${ESCWARN}Invalid choice.${ESC}[0m"
      ;;
  esac
done
tput cuu1;tput cuu1;tput cuu1;tput cuu1;tput cuu1;tput cuu1;tput cuu1
tput ed
echo "${ANS}" >${ETCCHARON}/CharonReport_reporttype.txt 2>/dev/null
echo -n "${ESC}[1m"
printf "%-18s" "Report type"
echo "${ESC}[0m: ${REPORTTYPE}"

REPNUMDEF=$(cat ${ETCCHARON}/CharonReport_reportnumb.txt 2>/dev/null)
if test -z "${REPNUMDEF}"
then
  echo -n "${ESC}[1m${REPORTTYPE} number${ESC}[0m (optional): "
else
  echo -n "${ESC}[1m${REPORTTYPE} number${ESC}[0m (optional) [${REPNUMDEF}]: "
fi
read REPORTNUMB
test "${REPORTNUMB}" = "q" && exit 7
if test -z "${REPORTNUMB}"
then
  if test -z "${REPNUMDEF}"
  then
    REPORTNUMB="None specified."
    echo "" >${ETCCHARON}/CharonReport_reportnumb.txt
  else
    REPORTNUMB=${REPNUMDEF}
    echo "${REPORTNUMB}" >${ETCCHARON}/CharonReport_reportnumb.txt
  fi
else
  echo "${REPORTNUMB}" >${ETCCHARON}/CharonReport_reportnumb.txt
fi
tput cuu1;tput ed
echo -n "${ESC}[1m"
printf "%-18s" "${REPORTTYPE} number"
echo "${ESC}[0m: ${REPORTNUMB}"

CHK=0
REPFOLDEF=$(cat ${ETCCHARON}/CharonReport_folder.txt 2>/dev/null)
test -z "${REPFOLDEF}" && REPFOLDEF="/tmp"
while test ${CHK} -eq 0
do
  echo -n "${ESC}[1mZip file folder${ESC}[0m [${REPFOLDEF}]: "
  read ANS
  test -z "${ANS}" && ANS=${REPFOLDEF}
  test "${ANS}" = "q" && exit 7
  if test -d "${ANS}"
  then
    if test -z "$(echo ${ANS} | tr -dc [:space:])"
    then
      ZIPFOLDER=${ANS}
      CHK=1
    else
      echo "${ESCWARN}Cannot use '${ANS}': spaces in folder names are not accepted.${ESC}[0m"
    fi
  else
    echo "${ESCWARN}'${ANS}' is not a valid folder.${ESC}[0m"
  fi
done
echo "${ZIPFOLDER}" >${ETCCHARON}/CharonReport_folder.txt

#--- Zip file name is like: CharonReport-<customer name>-<hostname>-<date>.zip
CN=$(echo "${CUSTOMERNAME}" | iconv -f utf8 -t ascii//TRANSLIT | tr -dc [:alpha:] | cut -c1-16)
ZIPFILE="${ZIPFOLDER}/CharonReport-${CN}-$(hostname -s)-$(date +%Y%m%d-%H%M%S).zip"

tput cuu1;tput ed
echo -n "${ESC}[1m"
printf "%-18s" "Zip file folder"
echo "${ESC}[0m: ${ZIPFOLDER}"

mkdir -p ${ZIPFOLDER}/CharonReport.d 2>/dev/null

TMPSVCNUM=/tmp/CharonReport_svcnum.tmp
echo 0 >${TMPSVCNUM}
TMPSVCRUN=/tmp/CharonReport_svcrun.tmp
echo 0 >${TMPSVCRUN}

TMPFILWARN=/tmp/CharonReport_nbwarn.tmp
echo 0 >${TMPFILWARN}
TMPFILERR=/tmp/CharonReport_nberr.tmp
echo 0 >${TMPFILERR}
TMPFILRES=/tmp/CharonReport_endresults.tmp
>${TMPFILRES}

TMPFILCONT=/tmp/CharonReport_nbcontainers.tmp
echo 0 >${TMPFILCONT}

CHARONDIR=/opt/charon
if test -e ${CHARONDIR}/utils/charon_common
then
  . ${CHARONDIR}/utils/charon_common
  OUTOFLTK=0
else
  OUTOFLTK=1
fi

if test -z "$(echo ${PERL5LIB} | grep '/opt/charon/utils')"
then
  export PERL5LIB=${PERL5LIB}:/opt/charon/utils
fi

#=============================================================================
#--- Progress Bar
#=============================================================================
function ProgressBar {
  SPINNER="|/-\\|"
  case "$1"
  in
    "begin")
      echo 0 >/tmp/CharonReportProgBar.cnt
      tput hpa 0
      echo -n "$2 ...  "
      tput ed
      ;;
    "end")
      tput sgr0
      tput hpa 0
      tput ed
      ;;
    *)
      typeset -i SPINPOS=$(cat /tmp/CharonReportProgBar.cnt)
      SPINPOS=SPINPOS+1
      test ${SPINPOS} -gt 4 && SPINPOS=1
      echo ${SPINPOS} >/tmp/CharonReportProgBar.cnt
      SPINDIS=$(echo ${SPINNER} | cut -c${SPINPOS})
      ROTACOL=""
      test -n "$1" && ROTACOL=${ESCWARN}
      echo -ne "\b${ROTACOL}${SPINDIS}${ESC}[0m$(tput sc) $1$(tput ed)$(tput rc)"
      sleep 0.01
      ;;
  esac
}

#=============================================================================
#--- RESULTS
#=============================================================================
function add_results
{
  ProgressBar begin "Preparing end results"
  Echo "<a name='Results'></a>"
  Echo "<br><h1>Results</h1>"
  SVCNUM=$(cat ${TMPSVCNUM} 2>/dev/null)
  SVCRUN=$(cat ${TMPSVCRUN} 2>/dev/null)
  Echo "<h2>Services</h2>"
  Echo "<font style='font-family:monospace;'>"
  Echo "Number of services found: ${SVCNUM}<br>"
  Echo "Running: ${SVCRUN}<br><br>"
  Echo "</font>"
  Echo "<h2>Configuration issues</h2>"
  Echo "<font style='font-family:monospace;'>"
  NBWARN=$(cat ${TMPFILWARN})
  Echo "<span class=msgwarn>Warning</span>&nbsp;: ${NBWARN}<br>"
  NBERR=$(cat ${TMPFILERR})
  Echo "<span class=msgerr>Errors</span>&nbsp;: ${NBERR}<br><br>"
  Echo "</font>"

  if test -s ${TMPFILRES}
  then
    Echo "<h2>Warning and error messages found (duplicates removed)</h2>"
    Echo "<font style='font-family:monospace;'>"
    Echo "<table border=1>"
    Echo "<tr><th>Severity</th><th>Id</th><th align=left>Message</th></tr>"
    typeset -i NBA=0
    sort -u -t';' -k4 ${TMPFILRES} | sort -t';' -nk1 -nk3 | while read RL
    do
      ProgressBar
      Echo "<tr>"
      NBA=NBA+1
      case "$(echo ${RL} | cut -f2 -d';')"
      in
        W)
          NBW=$(echo ${RL} | cut -f3 -d';')
          Echo "<td class=msgwarn>Warning</td>"
          Echo "<td align=right><a href='#EventWarn${NBW}'>${NBA}</a></td>"
          ;;
        E)
          NBE=$(echo ${RL} | cut -f3 -d';')
          Echo "<td class=msgerr>Error</td>"
          Echo "<td align=right><a href='#EventError${NBE}'>${NBA}</a></td>"
          ;;
        *)
          Echo "<td>Unknown</td>"
          Echo "<td align=right>${NBA}</td>"
          ;;
      esac
      Echo "<td>$(echo ${RL} | cut -f4 -d';')</td>"
      Echo "</tr>"
    done
    Echo "</table>"
    Echo "</font><br>"
  fi
}

#=============================================================================
#--- Increase NBWARN, NBERR, SVCNUM, SVCRUN
#=============================================================================
function Incr_NBWARN {
  typeset -i NBWARN=$(cat ${TMPFILWARN})
  NBWARN=NBWARN+1
  if test -n "$1"
  then
    echo "$(date +%s);W;${NBWARN};$1" >>${TMPFILRES}
    Echo "<a name='EventWarn${NBWARN}'></a>"
  fi
  echo ${NBWARN} >${TMPFILWARN}
}

function Incr_NBERR {
  typeset -i NBERR=$(cat ${TMPFILERR})
  NBERR=NBERR+1
  if test -n "$1"
  then
    echo "$(date +%s);E;${NBERR};$1" >>${TMPFILRES}
    Echo "<a name='EventError${NBERR}'></a>"
  fi
  echo ${NBERR} >${TMPFILERR}
}

function Incr_SVCNUM {
  typeset -i SVCNUM=$(cat ${TMPSVCNUM})
  SVCNUM=SVCNUM+1
  echo ${SVCNUM} >${TMPSVCNUM}
}

function Incr_SVCRUN {
  typeset -i SVCRUN=$(cat ${TMPSVCRUN})
  SVCRUN=SVCRUN+1
  echo ${SVCRUN} >${TMPSVCRUN}
}

function Incr_NBCONT {
  typeset -i NBCONT=$(cat ${TMPFILCONT})
  NBCONT=NBCONT+1
  echo ${NBCONT} >${TMPFILCONT}
}

#=============================================================================
#--- echo line to HTML file
#=============================================================================
function Echo {
  if test -z "$2"
  then
    echo "$1" >>${ZIPFOLDER}/${HTMLFILE}
  else
    echo "$1 $2" >>${ZIPFOLDER}/${HTMLFILE}
  fi
}


#=============================================================================
#--- Collect Charon Toolkit information
#=============================================================================
function collect_charontoolkit
{
  #-----------------------------------------------------------------------------
  # Toolkit version and settings
  #-----------------------------------------------------------------------------
  Echo "<a name='Toolkit'></a><h2>Charon Toolkit</h2>"

  if test ${OUTOFLTK} = 1
  then
    Echo "<font style='font-family:monospace;'>"
    Echo "Not applicable, Charon Linux Toolkit not installed.<br>"
    Echo "</font>"
    return
  fi

  ProgressBar begin "Collecting Charon Toolkit data"

  KITP=$(cat ${CHARONDIR}/utils/kit.product 2>/dev/null)
  KITV=$(cat ${CHARONDIR}/utils/kit.version 2>/dev/null)
  test -n "${KITV}" && KITV=$(echo ${KITV}|sed "s=\(^.*\);\(.*$\)=\1 (\2)=g")

  Echo "<a name='Toolkit_1'></a><h3>Kit contents and versions</h3>"

  Echo "<font style='font-family:monospace;'>"
  test -n "${KITP}" && Echo "Product: ${KITP}"
  Echo "Version: ${KITV:-UNKNOWN}"
  Echo "</font>"

  Echo "<br><br><table border='1' style='font-family:monospace;'>"
  Echo "<tr>"
  Echo "<th>Script</th><th>Version</th>"
  Echo "</tr>"

  N=0
  grep ^VERSION= ${CHARONDIR}/utils/* 2>/dev/null | grep :VERSION= | grep -v "~:" | sort | while read LINE
  do
    ProgressBar
    if test $N -eq 1
    then
      Echo "<tr class=bggray0><td>"
      N=0
    else
      Echo "<tr><td>"
      N=1
    fi
    V=$(echo ${LINE} | cut -f1 -d':')
    Echo "${V}"
    Echo "</td><td>"
    V=$(echo ${LINE} | cut -f2 -d'=')
    Echo "${V}"
    INITFIL=$(echo ${LINE} | cut -f1 -d':')
    Echo "</td></tr>"
  done

  if test -e ${CHARONDIR}/utils/menu_mod.pl
  then
    if test -x ${CHARONDIR}/utils/menu_mod.pl
    then
      Echo "<tr class=bglightcyan><td>"
      Echo "${CHARONDIR}/utils/menu_mod.pl"
      Echo "</td><td>"
      Echo $(${CHARONDIR}/utils/menu_mod.pl -v | head -1 | cut -f2 -d '=')
      Echo "</td></tr>"
    else
      Echo "<tr class=bglightcyan><td>${CHARONDIR}/utils/menu_mod.pl</td>"
      Echo "<td>not executable!</td></tr>"
    fi
  else
    Echo "<tr class=bglightcyan><td>${CHARONDIR}/utils/menu_mod.pl</td>"
    Echo "<td>not found!</td></tr>"
  fi
  Echo "<br>"
  ProgressBar

  if test -e ${CHARONDIR}/utils/guest_shutdown.exp
  then
    if test -x ${CHARONDIR}/utils/guest_shutdown.exp
    then
      INITVER=$(grep "^#VERSION=" ${CHARONDIR}/utils/guest_shutdown.exp|tr -d '#' | cut -f2 -d'=')
      Echo "<tr class=bglightcyan>"
      Echo "<td>${CHARONDIR}/utils/guest_shutdown.exp</td>"
      Echo "<td>${INITVER:-version not found}</td>"
      Echo "</tr>"
    else
      Echo "<tr class=bglightcyan>"
      Echo "<td>${CHARONDIR}/utils/guest_shutdown.exp</td>"
      Echo "<td>not executable!</td>"
      Echo "</tr>"
    fi
  else
    Echo "<tr class=bglightcyan>"
    Echo "<td>${CHARONDIR}/utils/guest_shutdown.exp</td>"
    Echo "<td>not found!</td>"
    Echo "</tr>"
  fi
  ProgressBar
  Echo "</table><br>"
  Insert_back_to_top

  Echo "<a name='Toolkit_2'></a><h3>Configuration files</h3>"

  cat <<EOCFG | grep -v ^$ | while read F
/opt/charon/utils/charon_gstart.boot;Managed CHARON virtual machines: emulator exe, configuration file, start at boot Y/N
/opt/charon/utils/charon_gstart.stop;Clean shutdown script executed at service stop
/opt/charon/utils/charon_gstart.chkrun;Optional script executed when displaying running virtual machines to gather information from the Tru64 or OpenVMS system
/opt/charon/utils/charon_gstart.prestart;Optional script executed before the virtual machine starts
/opt/charon/utils/charon_logchk.list;Monitored CHARON virtual machines log files

${ETCCHARON}/CharonToolkit.config;File containing the preferences (optional)
${ETCCHARON}/CharonToolkit_check.mailto;Recipients list for email alerts
${ETCCHARON}/CharonToolkit_check.mailfrom;Sender of email alerts
${ETCCHARON}/CharonToolkit_check.mailfooter;Mail footer added to email alerts
${ETCCHARON}/CharonToolkit_check.mailmode;Mail mode for email alerts (HTML/TEXT)
${ETCCHARON}/CharonToolkit_check.mailrecipients;Mail recipients list for email alerts
${ETCCHARON}/CharonToolkit.kitfolder;File containing the folder name used to store the CHARON installation kits (with Install/Upgrade/Remove CHARON menu option)
${ETCCHARON}/CharonToolkit.licensefolder;File containing the folder name used to contain the license files (.v2c)
${ETCCHARON}/CharonToolkit.monusbpaused;Immediate alerts are paused for USB dongles connections/disconnections monitoring if the file exists ('menu' then 'Manage monitored guests logs' then 'Restart aksusbd log monitor' to resume)

/root/.charon.expchk.nodongle;Exists if nodongle is detected to prevent from sending license expiration alerts
/root/.charoncronNOcheck;File that can be created manually to prevent from checks in the crontab entries when using the Manage recursive jobs option

/root/.charonsoftlicfolder;File containing the folder name used to store the software license kit (optional)

/root/.telnetrc;telnet configuration file
EOCFG
  do
    ProgressBar
    FDESC=$(echo $F | cut -f2 -d';')
    F=$(echo $F | cut -f1 -d';')

    Echo "<h4>File: ${F}</h4>"
    Echo "Description: <span class=textblue1>${FDESC}</span><br>"
    Echo "<table border='1'><tr><td>"
    if test -e ${F}
    then
      if test -s ${F}
      then
        IFS=''
        cat ${F} | sed -e "s=$=</font><br>=g" -e "s=;=\&#59;=g" | while read LF
        do
          LFH=$(echo ${LF} | sed "s= =\&nbsp=g")
          Echo "<font style='font-family:monospace;'>"
          if test -n "$(echo ${LF} | grep '^ *#')"
          then
            Echo "<span class=textgray0>${LFH}</span>"
          else
            Echo "${LFH}"
          fi
        done
      else
        Echo "<span class=textgray>Empty.</span>"
      fi
    else
      Echo "<span class=textgray>Does not exist.</span>"
    fi
    Echo "</td></tr></table><br>"
    Insert_back_to_top
  done
  Echo "<br>"

  Echo "<a name='Toolkit_3'></a><h3>Scheduled jobs (cron)</h3>"
  Echo "<font style='font-family:monospace;'>"
  ProgressBar
  if test -n "$(crontab -l 2>/dev/null | grep charon)"
  then
    Echo "<h4>crontab -l</h4>"
    crontab -l | grep charon | while read LINE
    do
      ProgressBar
      if test "$(echo ${LINE}|cut -c1)" = "#"
      then
        Echo "<span class=textgray>"
      else
        Echo "<span>"
      fi
      Echo "${LINE}"
      Echo "</span><br>"
    done
  fi
  Echo "</font><br>"
  Echo "<h4>/etc/cron.d/charon</h4>"
  Echo "<font style='font-family:monospace;'>"
  if test -n "$(grep charon /etc/cron.d/charon 2>/dev/null)"
  then
    grep charon /etc/cron.d/charon | while read LINE
    do
      ProgressBar
      if test "$(echo ${LINE}|cut -c1)" = "#"
      then
        Echo "<span class=textgray>"
      else
        Echo "<span>"
      fi
      Echo "${LINE}"
      Echo "</span><br>"
    done
  else
    Incr_NBWARN "No scheduled job found for Charon in /etc/cron.d/charon"
    Echo "<span class=msgwarn>&nbsp;No scheduled job found for Charon&nbsp;</span><br>"
  fi
  Echo "</font>"
  Insert_back_to_top

  Echo "<a name='Toolkit_4'></a><h3>Running processes (grep charon)</h3>"
  if test -n "$(ps -ef | grep [c]haron)"
  then
    ps -ef | grep [c]haron | sed "s= =\&nbsp;=g" | while read LINE
    do
      ProgressBar
      Echo "<font style='font-family:monospace;'>"
      if test -n "$(echo ${LINE} | grep '/opt/charon/bin')" -o -n "$(echo ${LINE} | grep '/opt/charon-ssp/ssp')"
      then
        Echo "<span class=textblue1>${LINE}</span>"
      else
        Echo "${LINE}"
      fi
      Echo "</font><br>"
    done
  else
    Incr_NBWARN "No processes found for Charon"
    Echo "<span class=msgwarn>&nbsp;No processes found for Charon&nbsp;</span><br>"
  fi
  Insert_back_to_top

  vmlist_to_html
}

#=============================================================================
#--- Display containers information (all products)
#=============================================================================
function check_containers_line
{
  #-- $1 = product ('axpvax' or 'par' or 'ssp')
  #-- $2 = configuration file
  case "$1"
  in
    "axpvax")
      CHKCTRL=$(echo ${CHKLINE} | awk '{print $2}')
      CHKNLUN=$(echo ${CHKLINE} | cut -f2 -d'[' | cut -f1 -d']')
      test "${CHKNLUN}" = "${CHKLINE}" && CHKNLUN=""
      ;;
    "par")
      CHKCTRL=$(echo ${CHKLINE})
      CHKCTRL=$(echo ${CHKCTRL} | cut -f1 -d'.')
      ;;
    "ssp")
      CHKCTRL=$(echo ${CHKLINE} | cut -f1 -d'=')
      ;;
  esac

  CHKINEX=0
  CHKCONT=$(echo ${CHKLINE} | cut -f2 -d'=' | cut -f1 -d'#')
  CHKCONT=$(echo ${CHKCONT} | tr -d '"' | tr -d "'")

  if test -b "${CHKCONT}"
  then
    CHKTYPE="(block special)&nbsp;<span class=textgreen2>&#10003;</span>"
  else
    if test -f "${CHKCONT}"
    then
      #CHKSIZE=$(echo $(find "${CHKCONT}" -printf '%k')/1024 | bc)
      CHKSIZE=$(echo $(( $(find "${CHKCONT}" -printf '%k') / 1024 )) )
      if test ${CHKSIZE:-0} -eq 0
      then
        CHKSIZE=$(find "${CHKCONT}" -printf '%k')
        CHKSIZE="$(printf "%'.f\n" ${CHKSIZE})&nbsp;Kb"
      else
        CHKSIZE="$(printf "%'.f\n" ${CHKSIZE})&nbsp;Mb"
      fi
      CHKTYPE=""
      case "$1"
      in
        "axpvax"|"ssp")
          CHKAVDK=$(echo ${CHKCONT} | sed "s=\.vdisk=\.avdisk=g")
          if test -s "${CHKAVDK}"
          then
            CHKAVDK=$(grep "<Description>" "${CHKAVDK}" | cut -f2 -d'>' | cut -f1 -d '<')
            if test -n "${CHKAVDK}"
            then
              CHKTYPE=" - ${CHKAVDK} "
            fi
          fi
          ;;
      esac
      CHKTYPE="${CHKTYPE}(<span class=textblue1>${CHKSIZE}</span>)&nbsp;<span class=textgreen2>&#10003;</span>"
    else
      if test "${CHKCONT}" = ".vtape"
      then
        CHKTYPE="(<span class=textblue1>CHARONCP</span>)&nbsp;<span class=textgreen2>&#10003;</span>"
      else
        CHKTYPE="<span class=msgwarn>&nbsp;File does not exist</span>"
        CHKINEX=1
      fi
    fi
  fi

  case "$1"
  in
    "axpvax")
      if test -n "${CHKNLUN}"
      then
        test ${CHKINEX} -eq 1 && Incr_NBWARN "$2: ${CHKCTRL} container[${CHKNLUN}], file '${CHKCONT}' does not exist."
        Echo "&nbsp;&nbsp;${CHKCTRL} container[${CHKNLUN}] = ${CHKCONT} ${CHKTYPE}<br>"
      else
        test ${CHKINEX} -eq 1 && Incr_NBWARN "$2: ${CHKCTRL} container, file '${CHKCONT}' does not exist."
        Echo "&nbsp;&nbsp;${CHKCTRL} container = ${CHKCONT} ${CHKTYPE}<br>"
      fi
      ;;
    "par")
      test ${CHKINEX} -eq 1 && Incr_NBWARN "$2: ${CHKCTRL}, file '${CHKCONT}' does not exist."
      Echo "&nbsp;&nbsp;${CHKCTRL} = ${CHKCONT} ${CHKTYPE}<br>"
      ;;
    "ssp")
      test ${CHKINEX} -eq 1 && Incr_NBWARN "$2: ${CHKCTRL}, file '${CHKCONT}' does not exist."
      Echo "&nbsp;&nbsp;&nbsp;&nbsp;${CHKCTRL} = <span class=textblue1>${CHKCONT}</span> ${CHKTYPE}<br>"
      ;;
  esac
}

#=============================================================================
#--- Check containers exist (AXP/VAX/PAR, not for SSP)
#=============================================================================
function check_containers
{
  #-- $1 = product (axpvax or par)
  #-- $2 = configuration file
  #-- Note: 'ssp' uses directly a call to check_containers_line
  CHKPRD=$1
  CHKCFG=$2
  Echo "<font style='font-family:monospace;'>"
  Echo "<b>Disks and tapes check</b>:<br>"
  if test -e ${CHKCFG}
  then
    echo 0 >${TMPFILCONT}
    if test ${CHKPRD} = "axpvax"
    then
      grep -w set ${CHKCFG} | grep -e "container\[" -e "container*=" | grep -v "#" | grep -vw -e toy -e rom | while read CHKLINE
      do
        Incr_NBCONT
        check_containers_line ${CHKPRD} ${CHKCFG}
      done
    else
      grep "\.image.*=" ${CHKCFG} | grep -v "#" | while read CHKLINE
      do
        Incr_NBCONT
        check_containers_line ${CHKPRD} ${CHKCFG}
      done
    fi
    NBCONT=$(cat ${TMPFILCONT})
    if test ${NBCONT:-0} -eq 0
    then
      Incr_NBERR "${CHKCFG}: no container found"
      Echo "&nbsp;&nbsp;<span class=msgerr>&nbsp;No container found</span><br>"
    fi
  else
    Incr_NBERR "Configuration file '${CHKCFG}' does not exist"
    Echo "&nbsp;&nbsp;<span class=msgerr>&nbsp;Configuration file does not exist&nbsp;</span><br>"
  fi
  Echo "</font><br>"
}

#=============================================================================
#--- Check syntax for OPA0 console (AXP/VAX/PAR)
#=============================================================================
function check_axpvax_consolesyntax
{
  Echo "<b>Console check</b>:<br>"
  if test -z "${INSBLD}"
  then
    INSBLD=$(rpm -q charon-axp charon-vax 2>/dev/null | grep -v 'not installed' | tail -1 | cut -f4 -d'-' | cut -f1 -d'.')
    INSBLD=${INSBLD:-0}
  fi
  CONSCHK=0
  PORTCFG=$(echo $1 | cut -f2 -d';')
  PORTMODE=""
  NBSPALIGN="&nbsp;&nbsp;"
  PORTLINE=$(grep -v "^#" ${PORTCFG} | grep -w load | grep -w virtual_serial_line | grep OPA)
  if test -n "${PORTLINE}"
  then
    PORTMODE="load"
  else
    if test ${INSBLD} -ge 19103
    then
      PORTLINE=$(grep -v "^#" ${PORTCFG} | grep -w set | grep -w alias | grep -w OPA0 | grep -w port)
      if test -n "${PORTLINE}"
      then
        PORTMODE="alias"
      else
        PORTLINE=$(grep -v "^#" ${PORTCFG} | grep -w set | grep -w OPA0 | grep -w port)
        test -n "${PORTLINE}" && PORTMODE="v412"
      fi
    fi          
  fi
  Echo "${NBSPALIGN}Syntax used: <span class=textblue1>${PORTLINE}</span>"

  case "${PORTMODE}"
  in
    load)
      #--- Starting AXP/VAX V4.11
      if test ${INSBLD} -ge 20400
      then
        CONSCHK=1
        Incr_NBWARN "Configuration file '${PORTCFG}' uses old syntax for OPA0 with 'load' (${PORTLINE}). Please update to new syntax."
        Echo "<br>${NBSPALIGN}<span class=msgwarn>&nbsp;Defined using old syntax with 'load' (${PORTLINE})&nbsp;</span>"
        Echo "<br>${NBSPALIGN}<span class=msgwarn>&nbsp;Not all functionalities are enabled (connection_override, access_control, ...)&nbsp;</span>"
      fi
      ;;
    alias)
      #--- Starting AXP/VAX V4.12
      if test ${INSBLD} -ge 21000
      then
        CONSCHK=1
        Incr_NBWARN "Configuration file '${PORTCFG}' uses old syntax for OPA0 with 'alias' (${PORTLINE}). Please update to new syntax."
        Echo "<br>${NBSPALIGN}<span class=msgwarn>&nbsp;Defined using old syntax with 'alias' (${PORTLINE})&nbsp;</span>"
      fi
      ;;
    v412)
      #--- Before AXP/VAX V4.11 B20408
      if test ${INSBLD} -lt 20408
      then
        CONSCHK=1
        Incr_NBWARN "Configuration file '${PORTCFG}' uses version 4.12+ syntax for OPA0 (${PORTLINE}) whereas current build is ${INSBLD}. Please update."
        Echo "<br>${NBSPALIGN}<span class=msgwarn>&nbsp;Defined using V4.12+ syntax (${PORTLINE}) whereas current build is ${INSBLD}&nbsp;</span>"
      fi
      ;;
    *)
      Incr_NBWARN "Configuration file '${PORTCFG}': OPA0 console is not defined using telnet port (${PORTLINE}). Please check."
      ;;
  esac
  test ${CONSCHK} = 0 && Echo " <span class=textgreen2>&#10003;</span>"
}

#=============================================================================
#--- Check service file protection
#=============================================================================
function check_svcprot
{
  # $1 = service definition file
  if test -x /usr/bin/stat
  then
    if test -e $1
    then
      if test $(/usr/bin/stat -c '%a' $1) -ne 644
      then
        Incr_NBWARN "Service file '$1' has not correct protection 644."
      fi
      if test $(/usr/bin/stat -c '%U:%G' $1) != "root:root"
      then
        Incr_NBWARN "Service file '$1' has not correct owner/group."
      fi
    fi
  fi
}

#=============================================================================
#--- Collect Charon Toolkit information (AXP/VAX/PAR)
#=============================================================================
function update_svclist
{
  #-- $1 = <cfgfile>;<origin>;<logfile>;<rotation>;<executable>
  #-- $2 = empty or 'donotreplace' (case for running emulators discovery)
  UPCFG=$(echo $1 | cut -f1 -d';')
  grep -q "^${UPCFG};" ${SVCLIST} 2>/dev/null
  if test $? -eq 0
  then
    test "$2" = "donotreplace" && return
    grep -v "^${UPCFG};" ${SVCLIST} >>${SVCLIST}.tmp
    mv -f ${SVCLIST}.tmp ${SVCLIST}
  fi
  echo "$1" >>${SVCLIST}
}

function vmlist_to_html
{
  case "${KITP}"
  in
    "PAR")  PRD="par";;
    *)      PRD="axpvax";;
  esac
  Echo "<a name='Toolkit_5'></a><h3>Virtual machines list and status</h3>"
  Echo "<br><font style='font-family:monospace;'>"
  ProgressBar begin "Gathering Charon toolkit 'vmlist' output"
  /opt/charon/utils/charon_cmdline vmlist | sed -e "s=\[m=</b>=g" -e "s=\[0m=</b>=g" -e "s=\[1m=<b>=g" -e "s=\[31m=<b>=g" -e "s=\[38;5;27m==g" -e "s=\[38;5;32m==g" -e "s=\[38;5;208m==g" -e "s=\[.m==g" -e "s=\[..m==g" -e "s=(0l(B=\&#9484=g" -e "s=(0x(B=\&#9474=g" -e "s=(0m(B=\&#9492=g" -e "s=(0==g" -e "s=(B==g" -e "s=\[..G=|=g" -e "s=\[K==g" -e "s= =\&nbsp;=g" | while read N
  do
    ProgressBar
    if test -n "$(echo ${N} | grep '|')"
    then
      SVCNUM=$(cat ${TMPSVCNUM})
      N=$(echo ${N} | sed -e "s=<b>==g" -e "s=</b>==g")
      N1=$(echo ${N} | cut -f1 -d'|')
      echo ${N1} | cut -f2 -d';' >/tmp/CharonReport-currentcfg.tmp
      N2=$(echo ${N} | cut -f2 -d'|')
      N3=$(echo ${N} | cut -f3 -d'|')
      N4=$(echo ${N} | cut -f4 -d'|')
      N0=$(printf "%-48s %-12s %-12s%-12s" "${N1}" "${N2}" "${N3}" "${N4}" | sed -e "s= =\&nbsp;=g" -e "s=^.==g")
      case "${N3}"
      in
        "ACTIVE")
          Echo "<span class=textgreen2>&#9654;</span><b><span class=textgreen2>${N0}</span></b><br>"
          ;;
        "INACTIVE")
          Echo "<span class=textred>&#9632;</span><b><span class=textgray>${N0}</span></b><br>"
          ;;
        "FAILED")
          Incr_NBERR "Emulator '$(echo ${N1} | cut -f2 -d';')' service state is FAILED"
          Echo "<span class=msgerr>&#9660;<b>${N0}</b></span><br>"
          ;;
        *)
          Echo "<span class=textgray>&#8265;</span><b><span class=textorange>${N0}</span></b><br>"
          ;;
      esac
    else
      if test -n "$(echo ${N} | grep 'qqqqqqqq')"
      then
        Echo "<hr>"
      else
        if test "$(echo ${N} | cut -c1-7)" = "Caption" -o "$(echo ${N} | cut -c1-6)" = "Legend"
        then
          echo ${N} >/tmp/CharonReport-caption.tmp
        else
          Echo "${N}<br>"
        fi
      fi
    fi
  done
  N=$(cat /tmp/CharonReport-caption.tmp 2>/dev/null)
  N1=$(cat /tmp/CharonReport-currentcfg.tmp 2>/dev/null)
  rm -f /tmp/CharonReport-currentcfg.tmp /tmp/CharonReport-caption.tmp 2>/dev/null
  SVCNUM=$(cat ${TMPSVCNUM})
  test -n "${N}" && Echo "<span class=textgray>${N}</span><br>"
  Echo "</font><br>"
  Insert_back_to_top

  Echo "<a name='Toolkit_6'></a><h3>Services details</h3>"
  Echo "<font style='font-family:monospace;'>"
  ProgressBar begin "Gathering virtual machines services details"
  if test -s ${CHARONDIR}/utils/charon_gstart.boot
  then
    cat ${CHARONDIR}/utils/charon_gstart.boot | while read L
    do
      ProgressBar
      LEXE=$(echo ${L} | cut -f1 -d';')
      LCFG=$(echo ${L} | cut -f2 -d';')
      LCFGBAS=$(basename ${LCFG}|sed "s=\.cfg==g")
      Echo "<br>"
      Echo "<a name='charon${PRD}_toolkit_${LCFGBAS}'></a>"
      Echo "<h4>Config file: ${LCFG}</h4>"
      Echo "Executable: <span class=textblue1>${LEXE}</span><br>"
      Echo "<br><table border='1'>"
      Echo "<tr>"
      Echo "<th width='50%'>charon_${LCFGBAS}.service</th>"
      Echo "<th width='50%'>charon_logmon_${LCFGBAS}.service</th>"
      Echo "</tr>"
      Echo "<tr valign='top'>"
      Echo "<td>"
      if test -s /etc/systemd/system/charon_${LCFGBAS}.service
      then
        check_svcprot /etc/systemd/system/charon_${LCFGBAS}.service
        Echo "<b>File:</b><br>"
        cat /etc/systemd/system/charon_${LCFGBAS}.service | while read N
        do
          if test "$(echo $N | cut -c1)" = "["
          then
            Echo "<span class=textblue1><b>${N}</b></span><br>"
          else
            Echo "${N}<br>"
          fi
        done
      else
        Incr_NBERR "Service 'charon_${LCFGBAS}' is not defined"
        Echo "<span class=msgerr>&nbsp;Service not defined&nbsp;</span>"
      fi
      Echo "</td>"
      Echo "<td class=bggray0>"
      if test -s /etc/systemd/system/charon_logmon_${LCFGBAS}.service
      then
        check_svcprot /etc/systemd/system/charon_logmon_${LCFGBAS}.service
        Echo "<b>File:</b><br>"
        cat /etc/systemd/system/charon_logmon_${LCFGBAS}.service | while read N
        do
          ProgressBar
          if test "$(echo $N | cut -c1)" = "["
          then
            Echo "<span class=textblue1><b>${N}</b></span><br>"
          else
            Echo "${N}<br>"
          fi
        done
      else
        if test -n "$(grep ^GLOBALLOGMON=enabled$ /etc/charon.d/CharonToolkit.config 2>/dev/null)"
        then
          Incr_NBWARN "Service 'charon_logmon_${LCFGBAS}' is not defined"
          Echo "<span class=msgwarn>&nbsp;Service not defined&nbsp;</span>"
        else
          Echo "Service not defined as global log monitoring is disabled"
        fi
      fi
      Echo "</td>"
      Echo "</tr>"

      Echo "<tr valign='top'>"
      Echo "<td>"
      Echo "<b>Status:</b><br>"
      ProgressBar
      if test -s /etc/systemd/system/charon_${LCFGBAS}.service
      then
        systemctl -l --lines=20 status charon_${LCFGBAS}.service 2>&1 | sed \
          -e "s=|-=\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&#9500;\&#9472;=g" \
          -e "s=\`-=\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&#9492;\&#9472;=g" \
          -e "s=* =\&diams;\&nbsp;=g" | while read N
        do
          Echo "${N}<br>"
        done
      else
        Incr_NBERR "Service 'charon_${LCFGBAS}' is not defined"
        Echo "<span class=msgerr>&nbsp;Service not defined&nbsp;</span>"
      fi
      Echo "</td>"
      Echo "<td class=bggray0><font style='font-family:monospace;'>"
      Echo "<b>Status:</b><br>"
      ProgressBar
      if test -s /etc/systemd/system/charon_logmon_${LCFGBAS}.service
      then
        systemctl -l --lines=20 status charon_logmon_${LCFGBAS}.service 2>&1 | sed \
          -e "s=|-=\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&#9500;\&#9472;=g" \
          -e "s=\`-=\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&#9492;\&#9472;=g" \
          -e "s=* =\&diams;\&nbsp;=g" | while read N
        do
          Echo "${N}<br>"
        done
      else
        if test -n "$(grep ^GLOBALLOGMON=enabled$ /etc/charon.d/CharonToolkit.config 2>/dev/null)"
        then
          Incr_NBWARN "Service 'charon_logmon_${LCFGBAS}' is not defined"
          Echo "<span class=msgwarn>&nbsp;Service not defined&nbsp;</span>"
        else
          Echo "Service not defined as global log monitoring is disabled"
        fi
      fi
      Echo "</td>"
      Echo "</tr>"
      Echo "</table>"
      Insert_back_to_top
    done
  else
    Echo "No guest managed by the Charon Toolkit<br>"
    Insert_back_to_top
  fi
  Echo "</font>"
}

function collect_charonservices
{
  ProgressBar begin "Searching for Charon virtual machines"
  PRD=$1

  #--- Define values and files depending on Charon product
  case "${PRD}"
  in
    "axpvax")
      PRDNAM="Charon-AXP/VAX"
      VMDAT="/opt/charon-agent/axp-vax-agent/axp_vax/vm.dat"
      TKITDAT="/opt/charon/utils/charon_gstart.boot"
      INSBLD=$(rpm -q charon-axp charon-vax 2>/dev/null | grep -v 'not installed' | tail -1 | cut -f4 -d'-' | cut -f1 -d'.')
      INSBLD=${INSBLD:-0}
      ;;
    "par")
      PRDNAM="Charon-PAR"
      VMDAT=""
      TKITDAT="/opt/charon/utils/charon_gstart.boot"
      ;;
    "ssp")
      PRDNAM="Charon-SSP"
      VMDAT="/opt/charon-agent/ssp-agent/ssp/vm.dat"
      TKITDAT=""
      ;;
    *)
      PRDNAM=""
      VMDAT=""
      Echo "<h1><a name='Charon_services'></a>Charon virtual machines</h1>"
      Echo "<span class=msgerr>&nbsp;Unknown case. Product = '${PRD}'&nbsp;</span><br>"
      return 1
      ;;
  esac

  #--- File containing already known cfg files and their origin per Charon product
  #    Format = <cfgfile>;<origin>;<logfile>;<rotation>;<executable>;<name for Charon Manager>
  #    origin = "manager" or "toolkit" or "user" or "discovered" (=saw process running)
  SVCLIST="${ETCCHARON}/CharonReport_cfgselected_${PRD}.txt"

  #--- Emulator discovery: if exists, read the vm.dat file / Charon Manager and add emulators to the list
  if test -e "${VMDAT}" -a ${DODISCOVERY} -eq 1
  then
    SOURCE="manager"
    case "${PRD}"
    in
      "axpvax")
        #--- Charon Manager case (baremetal)
        ProgressBar begin "Searching for Charon virtual machines in 'Charon-AXP/VAX Manager'"
        VMNUM=""
        VMNAM=""
        VMCFG=""
        VMLOG=""
        #--- Copy the vm.dat file in the zip folder
        cp -p ${VMDAT} ${ZIPFOLDER}/CharonReport.d/
        if test -s ${VMDAT}
        then
          cat ${VMDAT} | while read N
          do
            ProgressBar
            case "$(echo ${N} | cut -c1)"
            in
              "[")
                VMNUM=${N}
                VMLOG=""
                ;;
              "")
                DONOTHING=1
                ;;
              *)
                NPAR=$(echo $N | cut -f1 -d'=')
                NPAR=$(echo ${NPAR})
                NVAL=$(echo $N | cut -f2 -d'=')
                NVAL=$(echo ${NVAL})
                case "${NPAR}"
                in
                  "name")
                    VMNAM=${NVAL}
                    ;;
                  "file")
                    VMCFG=${NVAL}
                    ;;
                  "bin")
                    VMBIN=${NVAL}
                    get_logfile_axpvax ${VMCFG}
                    update_svclist "${VMCFG};${SOURCE};${LOGF};${SESSROTA};/opt/charon/bin/${VMBIN};${VMNAM}"
                    ;;
                esac
                ;;
            esac
          done
        fi
        ;;
      "ssp")
        ProgressBar begin "Searching for Charon virtual machines in 'Charon-SSP Manager'"
        VMNUM=""
        VMNAM=""
        VMCFG=""
        VMLOG=""
        rm -f /tmp/CharonReport_stanzadsp.tmp 2>/dev/null
        #--- Copy the vm.dat file in the zip folder
        cp -p ${VMDAT} ${ZIPFOLDER}/CharonReport.d/
        CHKPRD="ssp"
        if test -s ${VMDAT}
        then
          cat ${VMDAT} | while read N
          do
            ProgressBar
            case "$(echo ${N} | cut -c1)"
            in
              "[")
                VMNUM=${N}
                VMLOG=""
                ;;
              "")
                DONOTHING=1
                ;;
              *)
                NPAR=$(echo $N | cut -f1 -d'=')
                NPAR=$(echo ${NPAR})
                NVAL=$(echo $N | cut -f2 -d'=')
                NVAL=$(echo ${NVAL})
                case "${NPAR}"
                in
                  "name")
                    VMNAM=${NVAL}
                    ;;
                  "file")
                    VMCFG=${NVAL}
                    ;;
                  "bin")
                    VMBIN=${NVAL}
                    VMBINFULL=$(find /opt/charon-ssp/ssp* -name ${VMBIN} 2>/dev/null)
                    test -z "${VMBINFULL}" && VMBINFULL=${VMBIN}
                    get_logfile_ssp ${VMCFG}
                    update_svclist "${VMCFG};${SOURCE};${LOGF};X;${VMBINFULL};${VMNAM}"
                    ;;
                esac
                ;;
            esac
          done
        fi
        ;;
    esac
  fi

  #--- Emulator discovery: if exists, read the toolkit virtual machines list file and add emulators to the list
  if test -e "${TKITDAT}" -a ${DODISCOVERY} -eq 1
  then
    ProgressBar begin "Searching for Charon virtual machines in 'Linux Toolkit'"
    SOURCE="toolkit"
    case "${PRD}"
    in
      "axpvax")
        if test -n "$(grep -v '^#' ${TKITDAT} 2>/dev/null)"
        then
          cat ${TKITDAT} | while read LINE
          do
            ProgressBar
            VMBIN=$(echo ${LINE} | cut -f1 -d';')
            VMCFG=$(echo ${LINE} | cut -f2 -d';')
            get_logfile_axpvax ${VMCFG}
            update_svclist "${VMCFG};${SOURCE};${LOGF};${SESSROTA};${VMBIN}"
          done
        fi
        ;;
      "par")
        if test -n "$(grep -v '^#' ${TKITDAT} 2>/dev/null)"
        then
          cat ${TKITDAT} | while read LINE
          do
            ProgressBar
            VMBIN=$(echo ${LINE} | cut -f1 -d';')
            VMCFG=$(echo ${LINE} | cut -f2 -d';')
            get_logfile_par ${VMCFG} "toolkit"
            update_svclist "${VMCFG};${SOURCE};${LOGF};X;${VMBIN}"
          done
        fi
        ;;
    esac
  fi

  #--- Emulator discovery: scan running emulators
  if test ${DODISCOVERY} -eq 1
  then
    ProgressBar begin "Searching for running Charon virtual machines"
    SOURCE="discovered"
    ps -eo pid,cmd | grep \.cf[g] | grep -vw -e grep -e vi -e vim -e gedit -e emacs -e xemacs -e sh | while read LINE
    do
      ProgressBar
      VMPID=$(echo ${LINE} | awk '{print $1}')
      VMCFG=""
      VMBIN=""
      #--- Find the .cfg file in the command line
      for ITEM in ${LINE}
      do
        #--- Check ITEM is not a parameter and is not the PID
        if test -z "$(echo ${ITEM} | grep '^-')" -a ${ITEM} != ${VMPID}
        then
          #--- Check if ITEM is a .cfg file
          if test -n "$(echo ${ITEM} | grep "\.cfg$")"
          then
            VMCFG=${ITEM}
            #--- If configuration file full path is not specified, use current process folder (cwd)
            if test -z "$(echo ${VMCFG} | grep '/')"
            then
              VMCFG="$(readlink -f /proc/${VMPID}/cwd)/${VMCFG}"
            fi
            VMPRD=""
            #--- Check cfg file is Charon-AXP/VAX
            test -n "$(grep 'set.*session.*hw_model' ${VMCFG})" && VMPRD="axpvax"
            #--- Check cfg file is Charon-PAR
            test $(grep -w -e ^model -e ^memory ${VMCFG} | wc -l) -eq 2 && VMPRD="par"
            #--- Check cfg file is Charon-SSP
            test $(grep -e '^\[system]' -e '^\[cpu]' -e '^\[ram]' ${VMCFG} | wc -l) -eq 3 && VMPRD="ssp"
          fi
        fi
      done
      ProgressBar
      if test "${VMPRD}" = "${PRD}"
      then
        #--- Once cfg file and Charon product are known, find the executable file in the command line
        for ITEM in ${LINE}
        do
          #--- If not a cfg file, not a parameter and not PID, check it's a Charon emulator
          if test -z "$(echo ${ITEM} | grep "\.cfg$")" -a -z "$(echo ${ITEM} | grep '^-')" -a ${ITEM} != ${VMPID}
          then
            VMBIN=""
            case "${VMPRD}"
            in
              "axpvax")
                if test -z "$(echo ${ITEM} | grep '/')"
                then
                  VMBIN=$(find /opt/charon/bin -name "${ITEM}" -type l 2>/dev/null)
                else
                  if test -n "$(readlink -f ${ITEM})"
                  then
                    VMBIN=${ITEM}
                  fi
                fi
                if test -n "${VMCFG}" -a -n "${VMBIN}"
                then
                  get_logfile_axpvax ${VMCFG}
                  update_svclist "${VMCFG};${SOURCE};${LOGF};${SESSROTA};${VMBIN}" donotreplace
                fi
                ;;
              "par")
                if test -z "$(echo ${ITEM} | grep '/')" 
                then
                  VMBIN=$(find /opt/charon/bin -name "${ITEM}" 2>/dev/null)
                else
                  VMBIN=${ITEM}
                fi
                test -z "$(echo ${VMBIN} | grep -e "^/opt/charon/bin/hppa$" -e "^/opt/charon/bin/charon-par$")" && VMBIN=""
                if test -n "${VMCFG}" -a -n "${VMBIN}"
                then
                  get_logfile_par ${VMCFG}
                  update_svclist "${VMCFG};${SOURCE};${LOGF};X;${VMBIN}" donotreplace
                fi
                ;;
              "ssp")
                if test -z "$(echo ${ITEM} | grep '/')" 
                then
                  VMBIN=$(find /opt/charon-ssp -name "${ITEM}" 2>/dev/null)
                else
                  VMBIN=${ITEM}
                fi
                test -z "$(echo ${SSPEXELIST} | grep -w ${VMBIN:-XXX})" && VMBIN=""
                if test -n "${VMCFG}" -a -n "${VMBIN}"
                then
                  get_logfile_ssp ${VMCFG}
                  update_svclist "${VMCFG};${SOURCE};${LOGF};X;${VMBIN}" donotreplace
                fi
                ;;
            esac
          fi
        done
      fi
    done
  fi

  #--- Show the cfg files found and ask user for list reset, add more emulators or continue
  ProgressBar end
  ask_cfgfile ${PRD}

  if test -s ${SVCLIST}
  then
    #--- Update HTML file navigation bar (Charon virtual machines)
    ProgressBar begin "Updating HTML report navigation bar"
    rm -f ${ZIPFOLDER}/${HTMLFILE}.part 2>/dev/null
    typeset -i NB=0
    cat ${ZIPFOLDER}/${HTMLFILE} | while read -r LINE
    do
      echo "${LINE}" >>${ZIPFOLDER}/${HTMLFILE}.part
      if test "${LINE}" = "<!-- DEF:charon_${PRD}_services -->"
      then
        NB=NB+1
        if test ${NB} -ge 5
        then
          ProgressBar
          NB=0
        fi
        typeset -i IDX=0
        cat ${SVCLIST} | while read LINE
        do
          ProgressBar
          VMCFG=$(echo ${LINE} | cut -f1 -d';')
          VMEXE=$(echo ${LINE} | cut -f5 -d';')
          IDX=IDX+1
          case "${PRD}"
          in
            "axpvax")
              #--- Get hw_name from cfg file
              VMHWM=$(grep -w hw_model ${VMCFG} | grep session | grep set | grep -v "^#" | awk -F'=' '{print $2}' | tr -d "'\"" | tr -d " ")
              test -n "${VMHWM}" && VMEXE=${VMHWM}
              VMCFGBAS=$(basename ${VMCFG}|sed "s=\.cfg==g")
              echo "     <li><a href='#charonaxpvax${IDX}_${VMCFGBAS}'>${VMCFGBAS} <span style='font-size:9pt'>($(basename ${VMEXE}))</span></a></li>" >>${ZIPFOLDER}/${HTMLFILE}.part
              ;;
            "par")
              #--- Get emulator model from cfg file
              VMMOD=$(grep -w model ${VMCFG} | grep -v '#' | sed "s=model==g" | tr -d "'" | tr -d '"')
              VMMOD=$(echo ${VMMOD})
              VMCFGBAS=$(basename ${VMCFG}|sed "s=\.cfg==g")
              echo "     <li><a href='#charonpar${IDX}_${VMCFGBAS}'>${VMCFGBAS} <span style='font-size:9pt'>(${VMMOD})</span></a></li>" >>${ZIPFOLDER}/${HTMLFILE}.part
              ;;
            "ssp")
              VMBIN=$(basename ${VMEXE})
              VMCFGBAS=$(basename ${VMCFG}|sed "s=\.cfg==g")
              echo "     <li><a href='#charonssp${IDX}_${VMCFGBAS}'>${VMCFGBAS} <span style='font-size:9pt'>(${VMBIN})</span></a></li>" >>${ZIPFOLDER}/${HTMLFILE}.part
              ;;
          esac
        done
      fi
    done
    mv -f ${ZIPFOLDER}/${HTMLFILE}.part ${ZIPFOLDER}/${HTMLFILE}

    #--- Update HTML report part with Charon virtual machines
    ProgressBar begin "Adding virtual machines settings to HTML report"
    if test ${CHARONSVCH1:-0} -eq 0
    then
      Echo "<h1><a name='Charon_services'></a>Charon virtual machines</h1>"
      CHARONSVCH1=1
    fi

    #--- Add virtual machines details from the list in the HTML report
    typeset -i IDX=0
    cat ${SVCLIST} | while read LINE
    do
      ProgressBar
      Incr_SVCNUM
      VMCFG=$(echo ${LINE} | cut -f1 -d';')
      VMCFGBAS=$(basename ${VMCFG}|sed "s=\.cfg==g")
      SOURCE=$(echo ${LINE} | cut -f2 -d';')
      VMLOG=$(echo ${LINE} | cut -f3 -d';')
      VMROT=$(echo ${LINE} | cut -f4 -d';')
      VMEXE=$(echo ${LINE} | cut -f5 -d';')
      VMNAM=$(echo ${LINE} | cut -f6 -d';')
      test -z "${VMNAM}" && VMNAM=$(basename ${VMCFG} | sed "s=\.cfg==g")

      IDX=IDX+1
      Echo "<a name='charon${PRD}${IDX}_${VMCFGBAS}'></a>"
      Echo "<h2>${VMCFGBAS} - ${PRDNAM}</h2>"
      Echo "<h3>${VMCFGBAS} - Details</h3>"

      if test "${SOURCE}" = "toolkit"
      then
        Echo "Source = <span class=textgreen2><b><a href='#charon${PRD}_toolkit_${VMCFGBAS}'>${DSPSOURCE["${SOURCE}"]} &#9650;</a></b></span>"
      else
        Echo "Source = <span class=textgreen2><b>${DSPSOURCE["${SOURCE}"]}</b></span>"
      fi
      Echo "<br>"

      #--- Display emulator state (running, stopped, etc..) + other info
      case "${SOURCE}"
      in
        "manager")
          if test -s ${VMDAT}
          then
            FNDVMNAM=""
            cat ${VMDAT} | while read N
            do
              ProgressBar
              case "$(echo ${N} | cut -c1)"
              in
                "[")
                  VMNUM=${N}
                  ;;
                "")
                  DONOTHING=1
                  ;;
                *)
                  NPAR=$(echo $N | cut -f1 -d'=')
                  NPAR=$(echo ${NPAR})
                  NVAL=$(echo $N | cut -f2 -d'=')
                  NVAL=$(echo ${NVAL})
                  case "${NPAR}"
                  in
                    "name")
                      FNDVMNAM=${NVAL}
                      ;;
                    "file")
                      DONOTHING=1
                      ;;
                    "bin")
                      DONOTHING=1
                      ;;
                    "auto-boot")
                      if test "${FNDVMNAM}" = "${VMNAM}"
                      then
                        if test "${NVAL}" = "off"
                        then
                          Echo "${NPAR} = <span class=textred>${NVAL}</span><br>"
                        else
                          Echo "${NPAR} = <span class=textgreen2>${NVAL}</span><br>"
                        fi
                      fi
                      ;;
                    "status")
                      # 'status' does not reflect the real state of the VM, it is managed by agent, but doesn't necessarily reflect real time status
                      # of configured VM because agent has an in-memory copy.
                      if test "${FNDVMNAM}" = "${VMNAM}"
                      then
                        NPAR="State"
                        ps -ef | grep -w ${VMCFG} | grep "\-a ${VMNAM}" | grep -q -v crash.log
                        if test $? -eq 0
                        then
                          Incr_SVCRUN
                          VMPID=$(ps -ef | grep -w ${VMCFG} | grep "\-a ${VMNAM}" | grep -v crash.log | grep -vw grep | awk '{print $2}')
                          Echo "${NPAR} = <span class=textgreen2>&#9654;&nbsp;<b>Running</b></span> (pid: ${VMPID})<br>"
                          VMSTARDAT=$(ps -p ${VMPID} -o lstart -h)
                          VMELAPSED=$(ps -p ${VMPID} -o etime -h)
                          Echo "&nbsp;&nbsp;Started: <span class=textblue1>${VMSTARDAT}</span><br>"
                          Echo "&nbsp;&nbsp;Elapsed: <span class=textblue1>${VMELAPSED}</span><br>"
                        else
                          Echo "${NPAR} = <span class=textred>&#9632;&nbsp;<b>Stopped</b></span><br>"
                          if test -z "${VMLOG}"
                          then
                            case "${PRD}"
                            in
                              "axpvax")
                                get_logfile_axpvax ${VMCFG}
                                VMLOG=${LOGF}
                                ;;
                              "par")
                                get_logfile_par ${VMCFG}
                                VMLOG=${LOGF}
                                ;;
                              "ssp")
                                get_logfile_ssp ${VMCFG}
                                VMLOG=${LOGF}
                                ;;
                            esac
                          fi
                          if test -n "${VMLOG}"
                          then
                            if test -s ${VMLOG}
                            then
                              VMSTOPDAT=""
                              case "${PRD}"
                              in
                                "axpvax")
                                  STOPDAT1=$(tail -1 ${VMLOG} | cut -f1 -d':')
                                  STOPDAT2=$(tail -1 ${VMLOG} | cut -f2 -d':')
                                  VMSTOPDAT="${STOPDAT1} $(echo ${STOPDAT2} | sed "s=^\([0-9][0-9]\)\([0-9][0-9]\)\([0-9][0-9]$\)=\1:\2:\3=g")"
                                  ;;
                                "par")
                                  STOPDAT1=$(tail -1 ${VMLOG} | cut -f1 -d':')
                                  STOPDAT2=$(tail -1 ${VMLOG} | cut -f2 -d':' | cut -f1 -d'.')
                                  VMSTOPDAT="${STOPDAT1} $(echo ${STOPDAT2} | sed "s=^\([0-9][0-9]\)\([0-9][0-9]\)\([0-9][0-9]$\)=\1:\2:\3=g")"
                                  ;;
                                "ssp")
                                  VMSTOPDAT=$(tail -1 ${VMLOG} | awk '{print $1,$2}')
                                  ;;
                              esac
                              if test -n "${VMSTOPDAT}"
                              then
                                VMSTOPDAT=$(date -d "${VMSTOPDAT}" +"%d-%b-%Y %H:%M:%S" 2>/dev/null)
                                Echo "&nbsp;&nbsp;Stopped: <span class=textblue1>${VMSTOPDAT:-Unknown date}</span><br>"
                              fi
                            fi
                          fi
                        fi
                      fi
                      ;;
                    "jit"|"vt-x")
                      if test "${PRD}" = "ssp"
                      then
                        if test "${FNDVMNAM}" = "${VMNAM}"
                        then
                          Echo "${NPAR} = <span class=textblue1>${NVAL}</span><br>"
                        fi
                      fi
                      ;;
                    *)
                      if test "${FNDVMNAM}" = "${VMNAM}"
                      then
                        Echo "${NPAR} = <span class=textblue1>${NVAL}</span><br>"
                      fi
                      ;;
                  esac
                  ;;
              esac
            done
          fi
          ;;
        "toolkit"|"user"|"discovered")
          ps -eo pid,command | grep -w $(basename ${VMEXE}) | grep -w $(basename ${VMCFG}) | grep -vw -e grep -e vi -e vim -e gedit -e emacs -e xemacs | grep -qvw sh
          if test $? -eq 0
          then
            ps -eo pid,command | grep -w $(basename ${VMEXE}) | grep -w $(basename ${VMCFG}) | grep -vw -e grep -e vi -e vim -e gedit -e emacs -e xemacs | grep -vw sh | while read LPS
            do
              Incr_SVCRUN
              VMPID=$(echo ${LPS} | awk '{print $1}')
              LCMD=$(echo ${LPS} | sed "s=^${VMPID} ==g")
              Echo "<b>State</b> = <span class=textgreen2>&#9654;&nbsp;<b>Running</b></span><br>"
              Echo "&nbsp;&nbsp;Pid: <span class=textblue1>${VMPID}</span><br>"
              Echo "&nbsp;&nbsp;Command: <span class=textblue1>${LCMD}</span><br>"
              VMSTARDAT=$(ps -p ${VMPID} -o lstart -h)
              VMELAPSED=$(ps -p ${VMPID} -o etime -h)
              Echo "&nbsp;&nbsp;Started: <span class=textblue1>${VMSTARDAT}</span><br>"
              Echo "&nbsp;&nbsp;Elapsed: <span class=textblue1>${VMELAPSED}</span><br>"
            done
          else
            Echo "<b>State</b> = <span class=textred>&#9632;&nbsp;<b>Stopped</b></span><br>"
            if test -n "${VMLOG}"
            then
              if test -s ${VMLOG}
              then
                VMSTOPDAT=""
                case "${PRD}"
                in
                  "axpvax")
                    STOPDAT1=$(tail -1 ${VMLOG} | cut -f1 -d':')
                    STOPDAT2=$(tail -1 ${VMLOG} | cut -f2 -d':')
                    VMSTOPDAT="${STOPDAT1} $(echo ${STOPDAT2} | sed "s=^\([0-9][0-9]\)\([0-9][0-9]\)\([0-9][0-9]$\)=\1:\2:\3=g")"
                    ;;
                  "par")
                    STOPDAT1=$(tail -1 ${VMLOG} | cut -f1 -d':')
                    STOPDAT2=$(tail -1 ${VMLOG} | cut -f2 -d':' | cut -f1 -d'.')
                    VMSTOPDAT="${STOPDAT1} $(echo ${STOPDAT2} | sed "s=^\([0-9][0-9]\)\([0-9][0-9]\)\([0-9][0-9]$\)=\1:\2:\3=g")"
                    ;;
                  "ssp")
                    VMSTOPDAT=$(tail -1 ${VMLOG} | awk '{print $1,$2}')
                    ;;
                esac
                if test -n "${VMSTOPDAT}"
                then
                  VMSTOPDAT=$(date -d "${VMSTOPDAT}" +"%d-%b-%Y %H:%M:%S" 2>/dev/null)
                  Echo "&nbsp;&nbsp;Stopped: <span class=textblue1>${VMSTOPDAT:-Unknown date}</span><br>"
                fi
              fi
            fi
          fi
          ;;
        *)
          Incr_NBWARN "${VMCFG}: unknown '${SOURCE}' case"
          Echo "<span class=msgwarn>&nbsp;Unknown '${SOURCE}' case&nbsp;</span><br>"
          ;;
      esac

      Echo "<br>"
      Echo "<h3>${VMCFGBAS} - Configuration file</h3>"
      Echo "<font style='font-family:monospace;'>"
      Echo "<b>Name</b> = <span class=textblue1><b>${VMCFG}</b></span><br>"
      if test -e ${VMCFG}
      then
        if test -s ${VMCFG}
        then
          CFGUPD=$(date +"%-d-%b-%Y %H:%M:%S" -r ${VMCFG})
          Echo "&nbsp;&nbsp;Updated: <span class=textblue1>${CFGUPD}</span><br>"

          case "${PRD}"
          in
            "axpvax")
              #--- Display information from Charon-AXP/VAX .cfg file
              check_axpvax_consolesyntax "X;${VMCFG}"
              Echo "<br>"
              check_containers ${PRD} ${VMCFG}

              #--- Search for VE license servers (set session license_key_id = "VE://<primary-licserv-IP>[:<port>]/<passphrase>/, VE://<backup-licserv-IP>[:<port>]/<passphrase>/")
              LKEYID=$(grep -w license_key_id ${VMCFG} | grep -v "^#" | grep -w set | grep -w session | grep "VE://")
              if test -n "${LKEYID}"
              then
                LKEYID=$(echo ${LKEYID} | cut -f2 -d'=' | tr -d "'" | tr -d '"')
                LKEYID=$(echo ${LKEYID})
                LSVR=$(echo ${LKEYID} | cut -f1 -d',' | sed "s=.*VE://\(.*\)$=\1=g" | cut -f1 -d':' | cut -f1 -d'/')
                test -n "${LSVR}" && echo "1SVR;${LSVR}" >>${TMPVESVRLIST}
                if test -n "$(echo ${LKEYID} | grep ',')"
                then
                  LBKP=$(echo ${LKEYID} | cut -f2 -d',' | sed "s=.*VE://\(.*\)$=\1=g" | cut -f1 -d':' | cut -f1 -d'/')
                  test -n "${LBKP}" && echo "2BKP;${LBKP}" >>${TMPVESVRLIST}
                fi
              fi
              ;;
            "par")
              #--- Display information from Charon-PAR .cfg file
              check_containers ${PRD} ${VMCFG}

              #--- Search for VE license servers (license_key_id "VE://<license-server-IP>[:port]/<passphrase>/")
              typeset -i I=0
              grep -w license_key_id ${VMCFG} | grep -v "^#" | grep "VE://" | while read LKEYID
              do
                I=I+1
                LSVR=$(echo ${LKEYID} | sed "s=.*VE://\(.*\)$=\1=g" | cut -f1 -d':' | cut -f1 -d'/' | tr -d "'" | tr -d '"')
                if test $I -eq 1
                then
                  echo "1SVR;${LSVR}" >>${TMPVESVRLIST}
                else
                  echo "2BKP;${LSVR}" >>${TMPVESVRLIST}
                fi
              done
              ;;
            "ssp")
              #--- Display information from Charon-SSP .cfg file
              CFGTYP=""
              grep -v '^#' ${VMCFG} | tr -d "\r" | grep -v ^$ | while read N
              do
                ProgressBar
                case "$(echo $N | cut -c1)"
                in
                  "[")
                    if test -n "${CFGTYP}"
                    then
                      if test ! -e /tmp/CharonReport_stanzadsp.tmp
                      then
                        Echo "&nbsp;&nbsp;&nbsp;&nbsp;<span class=textgray0>Empty section</span><br>"
                      fi
                    fi
                    CFGTYP=$(echo $N | tr -d "[]")
                    Echo "&nbsp;&nbsp;<b>${CFGTYP}</b>:<br>"
                    rm -f /tmp/CharonReport_stanzadsp.tmp 2>/dev/null
                    ;;
                  *)
                    touch /tmp/CharonReport_stanzadsp.tmp
                    NPAR=$(echo $N | cut -f1 -d'=')
                    NPAR=$(echo ${NPAR})
                    NVAL=$(echo $N | cut -f2 -d'=')
                    NVAL=$(echo ${NVAL})
                    case "${CFGTYP}"
                    in
                      "cpu")
                        case "${NPAR}"
                        in
                          "idle")
                            case "${NVAL}"
                            in
                              "pause")
                                Incr_NBWARN "${VMCFG}: power scheme for '${VMNAM}' is set to 'Balanced' (${NVAL}). Performance (none) mode is recommended."
                                Echo "&nbsp;&nbsp;&nbsp;&nbsp;${NPAR} = <span class=msgwarn>&nbsp;${NVAL}&nbsp;</span> (balanced)<br>"
                                ;;
                              "none")
                                Echo "&nbsp;&nbsp;&nbsp;&nbsp;${NPAR} = <span class=textblue1>${NVAL}</span> (performance)<br>"
                                ;;
                              "sleep")
                                Incr_NBWARN "${VMCFG}: power scheme for '${VMNAM}' is set to 'Power save' (${NVAL}). Performance (none) mode is recommended."
                                Echo "&nbsp;&nbsp;&nbsp;&nbsp;${NPAR} = <span class=msgwarn>&nbsp;${NVAL}&nbsp;</span> (power save)<br>"
                                ;;
                              *)
                                Echo "&nbsp;&nbsp;&nbsp;&nbsp;${NPAR} = <span class=textblue1>${NVAL}</span><br>"
                                ;;
                            esac
                            ;;
                          *)
                            Echo "&nbsp;&nbsp;&nbsp;&nbsp;${NPAR} = <span class=textblue1>${NVAL}</span><br>"
                            ;;
                        esac
                        ;;
                      "log")
                        case "${NPAR}"
                        in
                          "path")
                            Echo "&nbsp;&nbsp;&nbsp;&nbsp;Log file: <span class=textblue1>${NVAL}</span><br>"
                            VMLOG=${NVAL}
                            echo ${VMLOG} >/tmp/CharonReport_vmlog.tmp
                            if test -s ${VMLOG}
                            then
                              LOGSIZ=$(find ${VMLOG} -printf '%k')
                              LOGLINES=$(wc -l ${VMLOG} | awk '{print $1}')
                              Echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Size: <span class=textblue1>${LOGSIZ}kb</span> (${LOGLINES} lines)<br>"
                              typeset -i LOGISSUES=0
                              typeset -i LOGNBWARN=$(grep ' WARN ' ${VMLOG} | wc -l)
                              typeset -i LOGNBERRO=$(grep ' ERROR ' ${VMLOG} | wc -l)
                              typeset -i LOGNBFATA=$(grep ' FATAL ' ${VMLOG} | wc -l)
                              LOGISSUES=LOGNBWARN+LOGNBERRO+LOGNBFATA
                              if test ${LOGISSUES} -gt 0
                              then
                                Echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Issues found: "
                                if test ${LOGNBWARN} -gt 0
                                then
                                  Incr_NBWARN "Found ${LOGNBWARN} warning message$(test ${LOGNBWARN} -gt 1 && echo 's') in ${VMLOG}"
                                  Echo "<span class=msgwarn>&nbsp;Warning:${LOGNBWARN}&nbsp;</span> "
                                fi
                                if test ${LOGNBERRO} -gt 0
                                then
                                  Incr_NBERR "Found ${LOGNBERRO} error message$(test ${LOGNBERRO} -gt 1 && echo 's') in ${VMLOG}"
                                  Echo "<span class=msgerr>&nbsp;Error:${LOGNBERRO}&nbsp;</span> "
                                fi
                                if test ${LOGNBFATA} -gt 0
                                then
                                  Incr_NBERR "Found ${LOGNBFATA} fatal message$(test ${LOGNBFATA} -gt 1 && echo 's') in ${VMLOG}"
                                  Echo "<span class=msgfatal>&nbsp;Fatal:${LOGNBFATA}&nbsp;</span> "
                                fi
                                Echo "<br>"
                              fi
                            else
                              Echo "&nbsp;&nbsp;&nbsp;&nbsp;Size: <span class=textorange>File is empty or does not exist.</span><br>"
                            fi
                            ;;
                          *)
                            Echo "&nbsp;&nbsp;&nbsp;&nbsp;${NPAR}: <span class=textblue1>${NVAL}</span><br>"
                            ;;
                        esac
                        ;;
                      scsi*_*)
                        case "${NPAR}"
                        in
                          lun_*)
                            CHKLINE="${NPAR}=${NVAL}"
                            check_containers_line ${PRD} ${VMCFG}
                            ;;
                          *)
                            Echo "&nbsp;&nbsp;&nbsp;&nbsp;${NPAR}: <span class=textblue1>${NVAL}</span><br>"
                            ;;
                        esac
                        ;;
                      "license")
                        case "${NPAR}"
                        in
                          "server")
                            echo "1SVR;${NVAL}" >>${TMPVESVRLIST}
                            ;;
                          "backup_server")
                            echo "2BKP;${NVAL}" >>${TMPVESVRLIST}
                            ;;
                        esac
                        Echo "&nbsp;&nbsp;&nbsp;&nbsp;${NPAR}: <span class=textblue1>${NVAL}</span><br>"
                        ;;
                      *)
                        Echo "&nbsp;&nbsp;&nbsp;&nbsp;${NPAR}: <span class=textblue1>${NVAL}</span><br>"
                        ;;
                    esac
                    ;;
                esac
              done
              if test ! -e /tmp/CharonReport_stanzadsp.tmp
              then
                Echo "&nbsp;&nbsp;&nbsp;&nbsp;<span class=textgray0>Empty section</span><br>"
              else
                rm -f /tmp/CharonReport_stanzadsp.tmp 2>/dev/null
              fi
              ;;
          esac
        else
          Incr_NBERR "Configuration file '${VMCFG}' is empty"
          Echo "&nbsp;&nbsp;<span class=msgerr>&nbsp;Configuration file is empty&nbsp;</span><br>"
        fi
      else
        Incr_NBERR "Configuration file '${VMCFG}' not found"
        Echo "&nbsp;&nbsp;<span class=msgerr>&nbsp;Configuration file not found!&nbsp;</span><br>"
      fi

      #--- Collect configuration and log files of the  virtual machine
      case "${PRD}"
      in
        "axpvax")  collect_cfglogaxpvax ${VMCFG};;
        "par")     collect_cfglogpar ${VMCFG} ${SOURCE};;
        "ssp")     collect_cfglogssp ${VMCFG};;
      esac
      Insert_back_to_top
    done
  else
    Echo "<h1><a name='Charon_services'></a>Charon virtual machines</h1>"
    Echo "<span class=textorange>No virtual machine (emulator) detected nor specified by user</span><br>"
    Insert_back_to_top
  fi
  return 0
}

#=============================================================================
#--- get_logfile_axpvax - gets log file name from configuration file (AXP/VAX)
#=============================================================================
function get_logfile_axpvax
{
  #--- $1 = configuration file
  BLD=$(rpm -q charon-base charon-axp-base charon-axp charon-vax | grep -v 'not installed' | head -1 | sed "s=\(^.*-\)\([0-9][0-9][0-9][0-9][0-9]\)\(.*$\)=\2=g")

  #--- Get session log file name -> LOGF
  LOGF=""
  LOGW=""
  SESSROTA=0
  GETLOG=$(grep "^set[ \t]\+session[ \t]\+log" $1 | grep -v "^#" | tr "	" " " | sed "s/  //g" | sed "s: = :=:g" | sed "s: =:=:g" | sed "s:= :=:g")
  for T in ${GETLOG}
  do
    if test "$(echo ${T} | cut -c1-4)" = "log="
    then
      LOGW=$(echo ${T} | sed "s:log=::g" | tr -d '"' | tr -d "'")
      # Starting with V4.7 B17101
      if test ${BLD:-0} -ge 17100 -a -d ${LOGW}
      then
        SESSROTA=1
        GETCFGNAM=$(grep "^set[ \t]\+session[ \t]\+configuration_name" $1|grep -v "^#"|cut -f2 -d'='|sed "s=\s==g"|tr -d "'"|tr -d '"')
        if test -n "${GETCFGNAM}"
        then
          LOGW="${LOGW}/${GETCFGNAM}.log"
        else
          GETHWMOD=$(grep "^set[ \t]\+session[ \t]\+hw_model" $1|grep -v "^#"|cut -f2 -d'='|sed "s=\s==g"|tr -d "'"|tr -d '"')
          LOGW="${LOGW}/${GETHWMOD}.log"
        fi
      fi
    fi
  done
  LOGF=${LOGW}

  #--- Get OPA0 log file name -> LOGFCONSOLE
  LOGFCONSOLE=""
  LOGW=""
  CONSROTA=0
  GETLOG=$(grep "^set[ \t]\+OPA0[ \t]\+log" $1|grep -v "^#"|tr "	" " "|sed "s/  //g"|sed "s: = :=:g"|sed "s: =:=:g"|sed "s:= :=:g")
  for T in ${GETLOG}
  do
    if test "$(echo ${T} | cut -c1-4)" = "log="
    then
      LOGW=$(echo ${T} | sed "s:log=::g" | tr -d '"' | tr -d "'")
      # Starting with V4.7 B17101
      if test ${BLD:-0} -ge 17100 -a -d ${LOGW}
      then
        CONSROTA=1
        GETCFGNAM=$(grep "^set[ \t]\+session[ \t]\+configuration_name" $1|grep -v "^#"|cut -f2 -d'='|sed "s=\s==g"|tr -d "'"|tr -d '"')
        if test -n "${GETCFGNAM}"
        then
          LOGW="${LOGW}/${GETCFGNAM}-OPA0.log"
        else
          GETHWMOD=$(grep "^set[ \t]\+session[ \t]\+hw_model" $1|grep -v "^#"|cut -f2 -d'='|sed "s=\s==g"|tr -d "'"|tr -d '"')
          LOGW="${LOGW}/${GETHWMOD}-OPA0.log"
        fi
      fi
    fi
  done
  LOGFCONSOLE=${LOGW}
}

#=============================================================================
#--- get_logfile_par - gets log file name from configuration file (PAR)
#=============================================================================
function get_logfile_par
{
  #--- $1 = configuration file 
  #--- $2 = empty or "toolkit"
  LOGF=""
  if test "$2" = "toolkit"
  then
    if test -n "$(grep ";$1;" ${CHARONDIR}/utils/charon_gstart.boot)"
    then
      #--- Using Toolkit so log file is easy to find
      LOGF="$(dirname $1)/logs/"$(basename $1 | sed "s=cfg$=log=g")
    fi
    return
  fi
  #--- Let's assume the log file is in the same folder as the configuration file
  #    (cannot be 100% sure as it depends from which folder the emulator was started)
  LOGN="charon-par.log"
  if test -z "${LOGF}"
  then
    grep ^hpa\- -q ${TMPRPMFILE}
    test $? -eq 0 && LOGN="hppa_log.log"
    LOGF="$(dirname $1)/${LOGN}"
  fi
  if test ! -e "${LOGF}"
  then
    #--- If the log file does not exist, search for log.name= in the .cfg file
    LOGF=$(grep 'log\.name=' $1 2>/dev/null | grep -v '^#' | cut -f2 -d'=' | cut -f1 -d'#' | tr -d "'" | tr -d '"')
    LOGF=$(echo ${LOGF})
    if test -n "${LOGF}"
    then
      if test "$(echo ${LOGF} | cut -c1)" != "/"
      then
        #--- If relative path, assume it's in same folder as .cfg (could be elsewhere)
        LOGF="$(dirname $1)/${LOGF}"
      fi
    fi
  fi
  if test -z "${LOGF}" -o ! -e "${LOGF}"
  then
    #--- If the log file does not exist, search default one with find, not NFS mounted, most recent
    tput sc
    echo -n "Searching for log file..."
#    LOGF=$(find / -name ${LOGN} -printf "%T+ %p\n" -not -fstype nfs 2>/dev/null | sort | awk '{print $2}' | tail -1)
    LOGFIND=$(find / -name ${LOGN} -printf "%T+ %p\n" -not -fstype nfs 2>/dev/null | sort -r | awk '{print $2}')
    CHK=0
    for LOGF in ${LOGFIND}
    do
      LOADCFG=$(grep ":config load:" ${LOGF} 2>/dev/null | sed "s=^.*:config load: \(.*$\)=\1=g")
      if test "${LOADCFG}" = "$1"
      then
        CHK=1
        break
      fi
    done
    if test ${CHK} -eq 0
    then
      for LOGF in ${LOGFIND}
      do
        LOADCFG=$(grep ":config load:" ${LOGF} 2>/dev/null | sed "s=^.*:config load: \(.*$\)=\1=g")
        if test "$(basename ${LOADCFG})" = "$(basename $1)"
        then
          CHK=1
          break
        fi
      done
    fi
    tput rc
    tput ed
  fi
  if test -z "${LOGF}"
  then
    #--- If no log file found, give a default name
    LOGF="$(dirname $1)/${LOGN}"
  fi
  LOGFCONSOLE=""
}

#=============================================================================
#--- get_logfile_ssp - gets log file name from configuration file (SSP)
#=============================================================================
function get_logfile_ssp
{
  #--- $1 = configuration file
  LOGF=$(grep -v "^#" $1 | awk 'sub(/\[log\] */,""){f=1} f{if ( sub(/^path.*=/,"") ) f=0; print}' | tail -1)
  LOGF=$(echo ${LOGF} | tr -d "\n\r")
  LOGFCONSOLE=$(grep -v "^#" $1 | awk 'sub(/\[ttya\] */,""){f=1} f{if ( sub(/^log_path.*=/,"") ) f=0; print}' | tail -1)
  if test -z "${LOGFCONSOLE}"
  then
    LOGFCONSOLE=$(grep -v "^#" $1 | awk 'sub(/\[vconsole\] */,""){f=1} f{if ( sub(/^log_path.*=/,"") ) f=0; print}' | tail -1)
  fi
}

#=============================================================================
#--- Collect ncu information (AXP/VAX)
#=============================================================================
function collect_ncu
{
  Echo "<a name='ncu_configuration'></a><h2>ncu configuration (Charon-AXP/VAX)</h2>"
  which ncu >/dev/null 2>&1
  if test $? = 0
  then
    ProgressBar begin "Collecting 'ncu' data"
    Echo "<h3>ncu -l</h3>"
    Echo "<font style='font-family:monospace;'>"
    ncu -l | sed "s= =\&nbsp;=g" | while read N
    do
      ProgressBar
      if test "$(echo $N | sed "s=\&nbsp;= =g" | awk '{print $2}')" = "CHARON"
      then
        Echo "<span class=textblue1>${N}</span><br>"
      else
        if test -n "$(echo $N | grep ';connected')"
        then
          Echo "<span class=textgreen2>${N}</span><br>"
        else
          if test -n "$(echo $N | grep ';unmanaged')"
          then
            Echo "<span class=textgray>${N}</span><br>"
          else
            if test "$(echo $N | sed "s=\&nbsp;= =g" | awk '{print $1}')" = "Interfaces"
            then
              Echo "<b>${N}</b><br>"
            else
              Echo "${N}<br>"
            fi
          fi
        fi
      fi
    done
    Echo "</font>"
    Insert_back_to_top

    ProgressBar
    Echo "<h3>chkconfig --list ncusrv</h3>"
    Echo "<font style='font-family:monospace;'>"
    if test -x /usr/sbin/chkconfig
    then
      chkconfig --list ncusrv >/dev/null 2>&1
      if test $? = 0
      then
        chkconfig --list ncusrv 2>/dev/null | while read N
        do
          Echo "${N}<br>"
        done
      else
        Echo "$(chkconfig --list ncusrv 2>&1 | tail -1)<br>"
      fi      
    else
      Echo "<span class=textgray>'chkconfig' is not installed on this server ('chkconfig' is deprecated and no more used since Charon-AXP/VAX V4.12).</span><br>"
    fi
    Echo "</font><br>"
    ProgressBar
    Echo "<h3>ncu service</h3>"
    Echo "<font style='font-family:monospace;'>"

    if test -n "$(grep -w "ncu.service" ${TMPSVCLIST} | grep -vw 'not-found')"
    then
      systemctl -q is-enabled ncu 2>/dev/null
      if test $? -eq 0
      then
        check_svcprot /usr/lib/systemd/system/ncu.service
        SVCNAM="ncu"
        ISACT=$(systemctl is-active ${SVCNAM} 2>/dev/null)
        if test -n "${ISACT}"
        then
          Echo "Service is in "
          if test "${ISACT}" = "active"
          then
            Echo "<span class=textgreen2>${ISACT}</span> state,"
          else
            Echo "${ISACT} state,"
          fi
          ISENA=$(systemctl is-enabled ${SVCNAM} 2>/dev/null)
          if test -n "${ISENA}"
          then
            if test "${ISENA}" = "enabled"
            then
              Echo " <span class=textgreen2>${ISENA}</span>.<br>"
            else
              Echo " ${ISENA}.<br>"
            fi
          else
            Echo ".<br>"
          fi
          Echo "<br><table border='1'><tr><td>"
          systemctl -l status ${SVCNAM}.service | sed \
            -e "s=|-=\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&#9500;\&#9472;=g" \
            -e "s=\`-=\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&#9492;\&#9472;=g" \
            -e "s=* =\&diams;\&nbsp;=g" | while read N
          do
            Echo "${N}<br>"
          done
          Echo "</tr></td></table>"
        else
          Incr_NBWARN "Service 'ncu' not found"
          Echo "<span class=msgwarn>&nbsp;Service not found.&nbsp;</span><br>"
        fi
      else
        if test -n "$(grep -w "ncusrv.service" ${TMPSVCLIST} | grep -vw 'not-found')"
        then
          systemctl is-enabled ncusrv 2>&1 | while read N
          do
            Echo "${N}<br>"
          done
        else
          Echo "<span class=msgwarn>&nbsp;Service 'ncusrv' not found.&nbsp;</span><br>"
        fi
      fi
    else
      Echo "<span class=textorange>ncu service is not installed.</span><br>"
    fi
    Echo "</font>"
  else
    Echo "<span class=textorange>ncu is not installed.</span><br>"
  fi
  Insert_back_to_top
}

#=============================================================================
#--- Collect axp-vax-agentd information (AXP/VAX)
#=============================================================================
function collect_axpvax_agentd
{
  ProgressBar begin "Collecting 'Charon Manager' service details"
  SVCNAM="axp-vax-agentd"
  Echo "<br><a name='axpvax-agentd'></a><h2>Charon Agent for Charon-AXP/VAX</h2>"
  Echo "<font style='font-family:monospace;'>"
  Echo "<span class=textgray>This relates to Charon Manager GUI</span><br><br>"
  Echo "</font>"
  Echo "<h3>${SVCNAM} service state (Charon-AXP/VAX)</h3>"
  Echo "<font style='font-family:monospace;'>"
  if test -n "$(grep -w "${SVCNAM}.service" ${TMPSVCLIST} | grep -vw 'not-found')"
  then
    ProgressBar
    ISACT=$(systemctl is-active ${SVCNAM} 2>/dev/null)
    if test -n "${ISACT}"
    then
      Echo "Service is in "
      if test "${ISACT}" = "active"
      then
        Echo "<span class=textgreen2>${ISACT}</span> state,"
      else
        Echo "${ISACT} state,"
      fi
      ISENA=$(systemctl is-enabled ${SVCNAM} 2>/dev/null)
      if test -n "${ISENA}"
      then
        if test "${ISENA}" = "enabled"
        then
          Echo " <span class=textgreen2>${ISENA}</span>.<br>"
        else
          Echo " ${ISENA}.<br>"
        fi
      else
        Echo ".<br>"
      fi
      ProgressBar
      Echo "<br><table border='1'><tr><td>"
      systemctl -l status ${SVCNAM}.service | sed \
        -e "s=|-=\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&#9500;\&#9472;=g" \
        -e "s=\`-=\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&#9492;\&#9472;=g" \
        -e "s=* =\&diams;\&nbsp;=g" | while read N
      do
        Echo "${N}<br>"
      done
      Echo "</tr></td></table>"
      Echo "</font>"
      Insert_back_to_top

      Echo "<br><h3>${SVCNAM} service settings (Charon-AXP/VAX)</h3>"
      Echo "<table border='1'><tr><td>"
      Echo "<font style='font-family:monospace;'>"
      check_svcprot /etc/systemd/system/axp-vax-agentd.service
      systemctl cat ${SVCNAM}.service | while read N
      do
        ProgressBar
        if test "$(echo $N | cut -c1)" = "["
        then
          Echo "<span class=textblue1><b>${N}</b></span><br>"
        else
          Echo "${N}<br>"
        fi
      done
      Echo "</tr></td></table>"
    else
      Incr_NBWARN "Cannot get service '${SVCNAM}' state"
      Echo "<span class=msgwarn>&nbsp;Cannot get service state.&nbsp;</span><br>"
    fi
  else
    #--- Service is not mandatory so only display, no warning count increase
    Echo "<span class=textorange>Service not found.</span><br>"
  fi
  Echo "</font>"
  Insert_back_to_top
}

#=============================================================================
#--- Collect Charon-SSP information
#=============================================================================
function collect_charonssp
{
  #-----------------------------------------------------------------------------
  # Installed versions checks
  #-----------------------------------------------------------------------------
  ProgressBar begin "Collecting Charon-SSP installation details"
  Echo "<br><h2>Charon version from executables (Charon-SSP)</h2>"
  Echo "<table border=1>"
  Echo "<tr><th>Executable</th><th>Version</th></tr>"
  Echo "<font style='font-family:monospace;'>"

  N=0
  (find /opt/charon-ssp -name "ssp4[umv]";find /opt/charon-ssp -name "ssp4[umv]-plus";find /opt/charon-ssp -name "ssp4[umv]*jit") | while read EXE
  do
    if test $N -eq 1
    then
      Echo "<tr class=bggray0>"
      N=0
    else
      Echo "<tr>"
      N=1
    fi
    EXV=$(${EXE} -v 2>/dev/null | grep -i Charon-SSP | grep -vw Goodbye)
    Echo "<td>${EXE}</td>"
    if test -n "${EXV}"
    then
      EXV=$(echo ${EXV})
      Echo "<td>${EXV}</td>"
    else
      EXV=$(${EXE} -v 2>&1 | grep -vw Goodbye)
      if test -z "${EXV}"
      then
        Incr_NBERR "Cannot get the SSP version! Looks like error code 101"
        Echo "<td class=msgerr>Cannot get the SSP version! Looks like error code 101, please contact Stromasys support.</td>"
      else
        Incr_NBERR "Command '${EXE} -v' failed with error '${EXV}'"
        Echo "<td class=msgerr>${EXV}</td>"
      fi
    fi
    Echo "</tr>"
  done
  Echo "</font></table>"
  Insert_back_to_top

  #-----------------------------------------------------------------------------
  # SSP-agent service
  #-----------------------------------------------------------------------------
  ProgressBar
  systemctl -q is-enabled charon-agentd-ssp 2>/dev/null
  if test $? -eq 0
  then
    SVCNAM="charon-agentd-ssp"
  else
    SVCNAM="ssp-agentd"
  fi
  Echo "<br><a name='ssp-agentd'></a><h2>Charon Agent for Charon-SSP</h2>"
  Echo "<font style='font-family:monospace;'>"
  Echo "<span class=textgray>This relates to Charon Manager GUI</span><br><br>"
  Echo "</font>"
  Echo "<h3>${SVCNAM} service state (Charon-SSP)</h3>"
  Echo "<font style='font-family:monospace;'>"
  if test -n "$(grep -w "${SVCNAM}.service" ${TMPSVCLIST} | grep -vw 'not-found')"
  then
    ISACT=$(systemctl is-active ${SVCNAM} 2>/dev/null)
    if test -n "${ISACT}"
    then
      Echo "Service is in "
      if test "${ISACT}" = "active"
      then
        Echo "<span class=textgreen2>${ISACT}</span> state,"
      else
        Echo "${ISACT} state,"
      fi
      ISENA=$(systemctl is-enabled ${SVCNAM} 2>/dev/null)
      if test -n "${ISENA}"
      then
        if test "${ISENA}" = "enabled"
        then
          Echo " <span class=textgreen2>${ISENA}</span>.<br>"
        else
          Echo " ${ISENA}.<br>"
        fi
      else
        Echo ".<br>"
      fi
      Echo "<br><table border='1'><tr><td>"
      systemctl -l status ${SVCNAM}.service | sed \
        -e "s=|-=\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&#9500;\&#9472;=g" \
        -e "s=\`-=\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&#9492;\&#9472;=g" \
        -e "s=* =\&diams;\&nbsp;=g" | while read N
      do
        Echo "${N}<br>"
      done
      Echo "</tr></td></table>"
      Echo "</font>"
      Insert_back_to_top

      Echo "<br><h3>${SVCNAM} service settings (Charon-SSP)</h3>"
      Echo "<table border='1'><tr><td>"
      Echo "<font style='font-family:monospace;'>"
      check_svcprot /etc/systemd/system/${SVCNAM}.service
      systemctl cat ${SVCNAM}.service | while read N
      do
        ProgressBar
        if test "$(echo $N | cut -c1)" = "["
        then
          Echo "<span class=textblue1><b>${N}</b></span><br>"
        else
          Echo "${N}<br>"
        fi
      done
      Echo "</tr></td></table>"
    else
      Incr_NBWARN "Cannot get service '${SVCNAM}' state"
      Echo "<span class=msgwarn>&nbsp;Cannot get service state.&nbsp;</span><br>"
    fi
  else
    #--- Service is not mandatory so only display, no warning count increase
    Echo "<span class=textorange>Service not found.</span><br>"
  fi
  Echo "</font>"

  Insert_back_to_top

  #-----------------------------------------------------------------------------
  # User interface settings
  #-----------------------------------------------------------------------------
  Echo "<br><h2>User interface configuration (Charon-SSP)</h2>"
  Echo "<font style='font-family:monospace;'>"
  UICONF=/opt/charon-agent/ssp-agent/etc/ui.conf
  if test -e ${UICONF}
  then
    Echo "<table border='1'><tr><td>"
    cat ${UICONF} | while read N
    do
      ProgressBar
      if test "$(echo $N | cut -c1)" = "["
      then
        Echo "<span class=textblue1><b>${N}</b></span><br>"
      else
        Echo "${N}<br>"
      fi
    done
    Echo "</tr></td></table>"
  else
    Incr_NBWARN "User interface configuration file '${UICONF}' does not exist"
    Echo "<span class=msgwarn>&nbsp;User interface configuration file does not exist&nbsp;</span><br>"
    Echo "File: ${UICONF}<br>"
  fi
  Echo "</font>"
  Insert_back_to_top
}

#=============================================================================
#--- Ask for more cfg files to add after discovery process (all products)
#=============================================================================
function ask_cfgfile
{
  PRD=$1
  DSPKNOWN=1
  typeset -i NCFG=0
  while test 1
  do
    if test ${DSPKNOWN} -eq 1
    then
      if test -s ${SVCLIST}
      then
        NCFG=0
        echo "${ESC}[44m${ESC}[37m Known and discovered virtual machines for ${PRDNAM} ${ESC}[0m"
        cat ${SVCLIST} | while read LINE
        do
          NCFG=NCFG+1
          VMCFG=$(echo ${LINE} | cut -f1 -d';')
          VMSOU=$(echo ${LINE} | cut -f2 -d';')
          VMLOG=$(echo ${LINE} | cut -f3 -d';')
          VMEXE=$(echo ${LINE} | cut -f5 -d';')
          VMNAM=$(echo ${LINE} | cut -f6 -d';')
          case "${PRD}"
          in
            "axpvax")
              #--- Get hw_name from cfg file
              VMHWM=$(grep -w hw_model ${VMCFG} | grep session | grep set | grep -v "^#" | awk -F'=' '{print $2}' | tr -d "'\"" | tr -d " ")
              test -n "${VMHWM}" && VMEXE=${VMHWM}
              #--- Get configuration_name from cfg file (same as VMNAM is Charon Manager is used)
              VMCFN=$(grep -w configuration_name ${VMCFG} | grep session | grep set | grep -v "^#" | awk -F'=' '{print $2}' | tr -d "'\"" | tr -d " ")
              test -z "${VMCFN}" && VMCFN="$(basename ${VMCFG} | sed "s=\.cfg$==g")"
              echo "${ESC}[1m$(printf "%2d" ${NCFG})-${ESC}[0m ${ESCBLUE}${VMCFN}${ESC}[0m: ${VMCFG}, model $(basename ${VMEXE}), source '${DSPSOURCE["${VMSOU}"]}'"
              ;;
            "par")
              #--- Get emulator model from cfg file
              VMMOD=$(grep -w model ${VMCFG} | grep -v '#' | sed "s=model==g" | tr -d "'" | tr -d '"')
              VMMOD=$(echo ${VMMOD})
              test -z "${VMMOD}" && VMMOD=$(basename ${VMEXE})
              VMCFN="$(basename ${VMCFG} | sed "s=\.cfg$==g")"
              echo "${ESC}[1m$(printf "%2d" ${NCFG})-${ESC}[0m ${ESCBLUE}${VMCFN}${ESC}[0m: ${VMCFG}, model $(basename ${VMMOD}), source '${DSPSOURCE["${VMSOU}"]}'"
              ;;
            "ssp")
              test -z "${VMNAM}" && VMNAM="$(basename ${VMCFG} | sed "s=\.cfg$==g")"
              echo "${ESC}[1m$(printf "%2d" ${NCFG})-${ESC}[0m ${ESCBLUE}${VMNAM}${ESC}[0m: ${VMCFG}, model $(basename ${VMEXE}), source '${DSPSOURCE["${VMSOU}"]}'"
              ;;
          esac
        done
        echo
      else
        echo "${ESCWARN}No virtual machine detected for ${PRDNAM}.${ESC}[0m"
        echo
      fi
    fi

    typeset -i NCFG=$(wc -l ${SVCLIST} | awk '{print $1}')
    if test ${NCFG} -gt 0
    then
      echo -n "Do you want to add more .cfg files (y/n) or to reset the list (r) ? "
      read WANTADD
    else
      WANTADD="y"
    fi
    tput cuu1;tput ed

    case "${WANTADD}"
    in
      "y"|"Y")
        SOURCE="user"
        echo
        echo "Please enter ${PRDNAM} configuration file full path or a folder containing"
        echo "one or more Charon configuration files ('${ESC}[1m.${ESC}[0m' for current folder)."
        echo "$(tput smul)Note$(tput rmul): if a folder is specified, subfolders will be scanned too."
        echo "Enter 'q' to quit."
        echo
        while test 1
        do
          echo -n "${ESC}[1m.cfg file name${ESC}[0m: "
          read ANS
          test "${ANS}" = "q" && break 2
          test "${ANS}" = ""  && break 
          test "${ANS}" = "." && ANS=${PWD}
          CHK=$(echo "${ANS}" | grep -e '*' -e '?')
          if test -n "${CHK}"
          then
            echo "${ESCWARN}Wilcard not allowed${ESC}[0m"
          else
            ANS=$(echo ${ANS} | sed "s=/$==g")
            if test -d ${ANS}
            then
              #--- Search for .cfg files in the folder
              if test -n "$(ls ${ANS}/*.cfg 2>/dev/null)"
              then
                typeset -i NFND=0
                typeset -i ALRD=0
                # for ACFG in $(ls ${ANS}/*.cfg 2>/dev/null)
                for ACFG in $(find ${ANS} -name "*.cfg" 2>/dev/null)
                do
                  case "${PRD}"
                  in
                    axpvax)
                      if test -n "$(grep -w set ${ACFG} | grep -w session | grep -w hw_model)"
                      then
                        grep -q "^${ACFG};" ${SVCLIST} 2>/dev/null
                        if test $? -eq 1
                        then
                          ACFN=$(grep -w configuration_name ${ACFG} | grep session | grep set | grep -v "^#" | awk -F'=' '{print $2}' | tr -d "'\"" | tr -d " ")
                          test -z "${ACFN}" && ACFN="$(basename ${ACFG} | sed "s=\.cfg$==g")"
                          get_logfile_axpvax ${ACFG}
                          update_svclist "${ACFG};${SOURCE};${LOGF};${SESSROTA};X;${ACFN}"
                          NFND=NFND+1
                        else
                          ALRD=ALRD+1
                        fi
                      fi
                      ;;
                    par)
                      if test -n "$(grep -w model ${ACFG} | grep -v '#')" -a -n "$(grep -w memory ${ACFG} | grep -v '#')"
                      then
                        grep -q "^${ACFG};" ${SVCLIST} 2>/dev/null
                        if test $? -eq 1
                        then
                          AMOD=$(grep -w model ${ACFG} | grep -v '#' | sed "s=model==g" | tr -d "'" | tr -d '"')
                          AMOD=$(echo ${AMOD})
                          test -z "${AMOD}" && AMOD="charon-par"
                          grep ^hpa\- -q ${TMPRPMFILE}
                          if test $? -eq 0
                          then
                            AEXE="/opt/charon/bin/hppa"
                          else
                            AEXE="/opt/charon/bin/charon-par"
                          fi
                          get_logfile_par ${ACFG}
                          update_svclist "${ACFG};${SOURCE};${LOGF};X;${AEXE};${AMOD}"
                          NFND=NFND+1
                        else
                          ALRD=ALRD+1
                        fi
                      fi
                      ;;
                    ssp)
                      if test -n "$(grep '^\[system\]' ${ACFG} | grep -v '#')" -a -n "$(grep '^\[ram\]' ${ACFG} | grep -v '#')"
                      then
                        grep -q "^${ACFG};" ${SVCLIST} 2>/dev/null
                        if test $? -eq 1
                        then
                          #--- Trying to get executable name (not 100% sure as no idea if jit or plus)
                          AEXE=$(grep ^machine ${ACFG} | cut -f2 -d'=' | tr -d "\n\r")
                          AEXE=$(echo ${AEXE} | sed "s=SUN-=ssp=g" | tr [:upper:] [:lower:])
                          AEXE=$(find /opt/charon-ssp -name "${AEXE}")
                          get_logfile_ssp ${ACFG}
                          update_svclist "${ACFG};${SOURCE};${LOGF};X;${AEXE};X" donotreplace
                          NFND=NFND+1
                        else
                          ALRD=ALRD+1
                        fi
                      fi
                      ;;
                  esac
                done
                if test ${NFND} -eq 0
                then
                  echo "${ESCWARN}No valid configuration file found in folder ${ANS}${ESC}[0m"
                else
                  echo "Configuration files found: ${NFND}, already in the list: ${ALRD}"
                fi
                echo
              else
                echo "${ESCWARN}No configuration file (.cfg) found in folder ${ANS}${ESC}[0m"
              fi
              break
            else
              if test -e ${ANS}
              then
                #--- Check if the file is a valid .cfg file
                case "${PRD}"
                in
                  axpvax)
                    if test -n "$(grep -w set ${ANS} | grep -w session | grep -w hw_model)"
                    then
                      grep -q "^${ANS};" ${SVCLIST} 2>/dev/null
                      if test $? -eq 1
                      then
                        ACFN=$(grep -w configuration_name ${ANS} | grep session | grep set | grep -v "^#" | awk -F'=' '{print $2}' | tr -d "'\"" | tr -d " ")
                        test -z "${ACFN}" && ACFN="$(basename ${ANS} | sed "s=\.cfg$==g")"
                        get_logfile_axpvax ${ANS}
                        update_svclist "${ANS};${SOURCE};${LOGF};${SESSROTA};X;${ACFN}"
                      else
                        echo "File '${ANS}' is already in the list."
                      fi
                      break
                    else
                      echo "${ESCWARN}The specified file '${ANS}' is not a valid Charon-AXP/VAX configuration file${ESC}[0m"
                    fi
                    ;;
                  par)
                    if test -n "$(grep -w model ${ANS} | grep -v '#')" -a -n "$(grep -w memory ${ANS} | grep -v '#')"
                    then
                      grep -q "^${ANS};" ${SVCLIST} 2>/dev/null
                      if test $? -eq 1
                      then
                        AMOD=$(grep -w model ${ANS} | grep -v '#' | sed "s=model==g" | tr -d "'" | tr -d '"')
                        AMOD=$(echo ${AMOD})
                        test -z "${AMOD}" && AMOD="charon-par"
                        grep ^hpa\- -q ${TMPRPMFILE}
                        if test $? -eq 0
                        then
                          AEXE="/opt/charon/bin/hppa"
                        else
                          AEXE="/opt/charon/bin/charon-par"
                        fi
                        get_logfile_par ${ANS}
                        update_svclist "${ANS};${SOURCE};${LOGF};X;${AEXE};${AMOD}"
                      else
                        echo "File '${ANS}' is already in the list."
                      fi
                      break
                    else
                      echo "${ESCWARN}The specified file '${ANS}' is not a valid Charon-PAR configuration file${ESC}[0m"
                    fi
                    ;;
                  ssp)
                    if test -n "$(grep '^\[system\]' ${ANS} | grep -v '#')" -a -n "$(grep '^\[ram\]' ${ANS} | grep -v '#')"
                    then
                      grep -q "^${ANS};" ${SVCLIST} 2>/dev/null
                      if test $? -eq 1
                      then
                        #--- Trying to get executable name (not 100% sure as no idea if jit or plus)
                        AEXE=$(grep ^machine ${ANS} | cut -f2 -d'=' | tr -d "\n\r")
                        AEXE=$(echo ${AEXE} | sed "s=SUN-=ssp=g" | tr [:upper:] [:lower:])
                        AEXE=$(find /opt/charon-ssp -name "${AEXE}")
                        get_logfile_ssp ${ANS}
                        update_svclist "${ANS};${SOURCE};${LOGF};X;${AEXE};X" donotreplace
                      else
                        echo "File '${ANS}' is already in the list."
                      fi
                      break
                    else
                      echo "${ESCWARN}The specified file '${ANS}' is not a valid Charon-SSP configuration file${ESC}[0m"
                    fi
                    ;;
                esac
              else
                #--- File does not exist
                echo "${ESCERROR} The specified file '${ANS}' does not exist ${ESC}[0m"
              fi
            fi
          fi
        done
        DSPKNOWN=1
        ;;
      "n"|"N")
        if test -s ${SVCLIST}
        then
          break
        else
          echo "${ESCWARN}${ESC}[1mWARNING: you did not specify any configuration file!${ESC}[0m"
          echo "This means configuration and log files will not be included in the report."
          while test 1
          do
            echo -n "Please confirm (y/n) : "
            read ANS
            case "${ANS}"
            in
              "y"|"Y")
                break 2
                ;;
              "n"|"N")
                break
                ;;
              *)
                tput cuu1;tput ed
                ;;
            esac
          done
        fi
        DSPKNOWN=1
        ;;
      "r"|"R")
        >${SVCLIST}
        echo "${ESCWARN}List emptied.${ESC}[0m"
        echo "If you want the script to perform an automatic discovery of the virtual"
        echo "machines, please stop it using CTRL-C and restart the script."
        echo
        DSPKNOWN=1
        ;;
      *)
        DSPKNOWN=0
        ;;
    esac
  done
  if test -s ${SVCLIST}
  then
    sort -u ${SVCLIST} >${SVCLIST}.sorted.unique
    mv -f ${SVCLIST}.sorted.unique ${SVCLIST}
  fi
  echo
}

#=============================================================================
#--- Collect configuration and log file (AXP/VAX)
#=============================================================================
function collect_cfglogaxpvax {
  # $1 = configuration file

  ProgressBar begin "Collecting Charon-AXP/VAX cfg and log files"
  LOGDATSIN=$(date +'%Y%m%d' -d ${LOGSETDAT})

  CFG=$1
  SVC=$(basename ${CFG}|sed "s=\.cfg$==g")
  get_logfile_axpvax ${CFG}

  typeset -i NF=0
  while test 1
  do
    NF=NF+1
    ZIPFOLSVC=${ZIPFOLDER}/CharonReport.d/$(printf "%03d" ${NF})
    if test ! -d ${ZIPFOLSVC}_*
    then
      ZIPFOLSVC=${ZIPFOLDER}/CharonReport.d/$(printf "%03d" ${NF})_${SVC}
      mkdir -p ${ZIPFOLSVC}
      break
    fi
  done

  Echo "<h3>${VMCFGBAS} - Attached configuration and log files</h3>"
  Echo "Zip file child folder: <span class=textblue1>$(basename ${ZIPFOLSVC})</span><br><br>"

  Echo "<h4>Configuration file with include files</h4>"

  Echo "<li class=charon>${CFG}"
  if test -e ${CFG}
  then
    Echo " (Last updated on $(date -r ${CFG} +'%d-%b-%Y %H:%M:%S'))</li>"
    cp -p ${CFG} ${ZIPFOLSVC}/
    grep -w include ${CFG} | grep -v "#" | while read ICFG
    do
      ICFG=$(echo ${ICFG} | sed "s=include==g" | tr -d [:space:])
      if test -e ${ICFG}
      then
        Echo "<li class=charon><span class=textblue1>Include file</span> ${ICFG}</li>"
        cp -p ${ICFG} ${ZIPFOLSVC}/
      elif test -e /opt/charon/cfg/${ICFG}
      then
        Echo "<li class=charon><span class=textblue1>Include file</span> /opt/charon/cfg/${ICFG}</li>"
        cp -p /opt/charon/cfg/${ICFG} ${ZIPFOLSVC}/
      else
        Incr_NBERR "${CFG}: include file '${ICFG}' does not exist"
        Echo "<li class=charon><span class=textblue1>Include file</span> ${ICFG} <span class=msgerr>&nbsp;File does not exist&nbsp;</span></li>"
      fi
    done
  else
    Incr_NBERR "Configuration file '${CFG}' does not exist"
    Echo " <span class=msgerr>&nbsp;File does not exist&nbsp;</span></li>"
  fi

  Echo "<br><h4>Session log file(s)</h4>"
  Echo "<font style='font-family:monospace;'>"
  if test -n "${LOGF}"
  then
    if test -e ${LOGF}
    then
      typeset -i LOGNBWARN=$(grep ':WARN :' ${LOGF} | wc -l)
      typeset -i LOGNBERRO=$(grep ':ERROR:' ${LOGF} | wc -l)
      typeset -i LOGNBFATA=$(grep ':FATAL:' ${LOGF} | wc -l)
      if test ${LOGNBWARN} -gt 0
      then
        Incr_NBWARN "Found ${LOGNBWARN} warning message$(test ${LOGNBWARN} -gt 1 && echo 's') in ${LOGF}"
      fi
      if test ${LOGNBERRO} -gt 0
      then
        Incr_NBERR "Found ${LOGNBERRO} error message$(test ${LOGNBERRO} -gt 1 && echo 's') in ${LOGF}"
      fi
      if test ${LOGNBFATA} -gt 0
      then
        Incr_NBERR "Found ${LOGNBFATA} fatal message$(test ${LOGNBFATA} -gt 1 && echo 's') in ${LOGF}"
      fi

      if test -h ${LOGF}
      then
        #--- Symbolic link so rotating log file
        LOGDATTMP="/tmp/CharonReport_logdat.tmp"
        echo "" >${LOGDATTMP}
        LOGFDIR=$(dirname ${LOGF})
        LOGFNAM=$(basename ${LOGF})
        find ${LOGFDIR} -name $(echo ${LOGFNAM} | sed "s=\.log$==g")-????-??-??-??-??-??-?????????.log -size -${LOGMAXSIZ}c | sort | while read LOGFNAM
        do
          ProgressBar
          LOG32B=$(grep :0000032B: ${LOGFNAM} | head -1)
          if test -n "${LOG32B}"
          then
            LOG32BD=$(echo ${LOG32B} | cut -f1 -d':')
            if test ${LOG32BD} -ge ${LOGDATSIN}
            then
              echo "${LOGFNAM}" >${LOGDATTMP}
              break
            fi
          fi
        done

        LOG32BF=$(cat ${LOGDATTMP})
        if test -z "${LOG32BF}"
        then
          #--- if 1st file (on emulator startup) is not found, add all log files
          Echo "<font style='font-family:monospace;'>"
          Echo "<span class=textgray>Emulator startup sequence not found (0000032B) at the requested date, adding all log files:</span>"
          Echo "</font>"
          ls $(echo ${LOGF} | sed "s=\.log$==g")-????-??-??-??-??-??-?????????.log 2>/dev/null | while read LOG32B
          do
            ProgressBar
            LOGSIZ=$(find ${LOG32B} -printf '%k')
            LOGSIZDSP=$(printf "%'.f\n" ${LOGSIZ})

            LOGLIN=$(head -1 ${LOG32B})
            LOGDAT=$(echo ${LOGLIN} | cut -f1 -d':')
            LOGTIM=$(echo ${LOGLIN} | cut -f2 -d':' | sed "s=^\(..\)\(..\)\(..\)$=\1:\2:\3=g")
            LOGDATBEG=$(date +'%d-%b-%Y %H:%M:%S' -d "${LOGDAT} ${LOGTIM}")
            LOGLIN=$(tail -100 ${LOG32B} | grep "^........:......:.*" | tail -1)
            if test -n "${LOGLIN}"
            then
              LOGDAT=$(echo ${LOGLIN} | cut -f1 -d':')
              LOGTIM=$(echo ${LOGLIN} | cut -f2 -d':' | sed "s=^\(..\)\(..\)\(..\)$=\1:\2:\3=g")
              LOGDATEND=$(date +'%d-%b-%Y %H:%M:%S' -d "${LOGDAT} ${LOGTIM}")
            else
              LOGDATEND="unknown date"
            fi
            Echo "<li class=charon>${LOG32B} (from ${LOGDATBEG} to ${LOGDATEND}, size ${LOGSIZDSP}kb)"

            if test ${LOGSIZ} -le ${LOGMAXSIZ}
            then
              if test -n "$(grep :0000032B: ${LOG32B})"
              then
                Echo " <span class=bggreen2>&nbsp;STARTED&nbsp;</span>"
              else
                Echo " <span class=bggreen3>&nbsp;ROTATED&nbsp;</span>"
              fi
              Echo "</li>"
              cp -p ${LOG32B} ${ZIPFOLSVC}/

              #--- if the file contains log counters (:00000194:) then create a version of it without counters
              if test $(grep -c :00000194: ${LOG32B}) -gt 0
              then
                LOGFNOCNT="$(echo ${LOG32B} | sed 's=\.log$==g').nocounters.log"
                grep -v :00000194: ${LOG32B} >${ZIPFOLSVC}/$(basename ${LOGFNOCNT})
                Echo "<li class=charon><span class=textgreen1>${LOG32B}</span> (counters removed)</li>"
              fi
            else
              Echo " <span class=bgorange>&nbsp;SKIPPED&nbsp;</span>"
              Echo "</li>"
              LOG32BSKP=$(echo ${LOG32B} | sed "s=\.log$=.skipped.log=g")
              LOG32BSKP=$(basename ${LOG32BSKP})
              echo "Skipped log file, size is ${LOGSIZDSP} bytes. Limit is ${LOGMAXDIS}" >${ZIPFOLSVC}/${LOG32BSKP}
            fi
          done
        else
          #--- if 1st file (on emulator startup) is found, add it and all next log files
          DATDSP=$(date -r ${LOG32BF} +%d-%b-%Y)
          Echo "<span class=textgray>Closest emulator startup sequence found (0000032B) on ${DATDSP}, adding log files since this date:</span>"
          CHK=0
          ls $(echo ${LOGF} | sed "s=\.log$==g")-????-??-??-??-??-??-?????????.log 2>/dev/null | while read LOG32B
          do
            test "${LOG32B}" = "${LOG32BF}" && CHK=1
            if test ${CHK} -eq 1
            then
              ProgressBar
              LOGSIZ=$(find ${LOG32B} -printf '%k')
              LOGSIZDSP=$(printf "%'.f\n" ${LOGSIZ})

              LOGLIN=$(head -1 ${LOG32B})
              LOGDAT=$(echo ${LOGLIN} | cut -f1 -d':')
              LOGTIM=$(echo ${LOGLIN} | cut -f2 -d':' | sed "s=^\(..\)\(..\)\(..\)$=\1:\2:\3=g")
              LOGDATBEG=$(date +'%d-%b-%Y %H:%M:%S' -d "${LOGDAT} ${LOGTIM}")
              LOGLIN=$(tail -100 ${LOG32B} | grep "^........:......:.*" | tail -1)
              if test -n "${LOGLIN}"
              then
                LOGDAT=$(echo ${LOGLIN} | cut -f1 -d':')
                LOGTIM=$(echo ${LOGLIN} | cut -f2 -d':' | sed "s=^\(..\)\(..\)\(..\)$=\1:\2:\3=g")
                LOGDATEND=$(date +'%d-%b-%Y %H:%M:%S' -d "${LOGDAT} ${LOGTIM}")
              else
                LOGDATEND="unknown date"
              fi
              Echo "<li class=charon>${LOG32B} (from ${LOGDATBEG} to ${LOGDATEND}, size ${LOGSIZDSP}kb)"

              if test ${LOGSIZ} -le ${LOGMAXSIZ}
              then
                if test -n "$(grep :0000032B: ${LOG32B})"
                then
                  Echo " <span class=bggreen2>&nbsp;STARTED&nbsp;</span>"
                else
                  Echo " <span class=bggreen3>&nbsp;ROTATED&nbsp;</span>"
                fi
                Echo "</li>"
                cp -p ${LOG32B} ${ZIPFOLSVC}/

                #--- if the file contains log counters (:00000194:) then create a version of it without counters
                if test $(grep -c :00000194: ${LOG32B}) -gt 0
                then
                  LOGFNOCNT="$(echo ${LOG32B} | sed 's=\.log$==g').nocounters.log"
                  grep -v :00000194: ${LOG32B} >${ZIPFOLSVC}/$(basename ${LOGFNOCNT})
                  Echo "<li class=charon><span class=textgreen1>${LOG32B}</span> (counters removed)</li>"
                fi
              else
                Echo " <span class=bgorange>&nbsp;SKIPPED&nbsp;</span>"
                Echo "</li>"
                LOG32BSKP=$(echo ${LOG32B} | sed "s=\.log$=.skipped.log=g")
                LOG32BSKP=$(basename ${LOG32BSKP})
                echo "Skipped log file, size is ${LOGSIZDSP} bytes. Limit is ${LOGMAXDIS}" >${ZIPFOLSVC}/${LOG32BSKP}
              fi
            fi
          done
        fi
      else
        #--- Plain file
        ProgressBar
        Echo "<span class=textgray>Non rotating log file:</span>"
        LOGSIZ=$(find ${LOGF} -printf '%k')
        LOGSIZDSP=$(printf "%'.f\n" ${LOGSIZ})

        LOGLIN=$(head -1 ${LOGF})
        LOGDAT=$(echo ${LOGLIN} | cut -f1 -d':')
        LOGTIM=$(echo ${LOGLIN} | cut -f2 -d':' | sed "s=^\(..\)\(..\)\(..\)$=\1:\2:\3=g")
        LOGDATBEG=$(date +'%d-%b-%Y %H:%M:%S' -d "${LOGDAT} ${LOGTIM}")
        LOGLIN=$(tail -100 ${LOGF} | grep "^........:......:.*" | tail -1)
        if test -n "${LOGLIN}"
        then
          LOGDAT=$(echo ${LOGLIN} | cut -f1 -d':')
          LOGTIM=$(echo ${LOGLIN} | cut -f2 -d':' | sed "s=^\(..\)\(..\)\(..\)$=\1:\2:\3=g")
          LOGDATEND=$(date +'%d-%b-%Y %H:%M:%S' -d "${LOGDAT} ${LOGTIM}")
        else
          LOGDATEND="unknown date"
        fi
        Echo "<li class=charon>${LOGF} (from ${LOGDATBEG} to ${LOGDATEND}, size ${LOGSIZDSP}kb)"

        if test ${LOGSIZ} -le ${LOGMAXSIZ}
        then
          cp -p ${LOGF} ${ZIPFOLSVC}/
        else
          Echo " <span class=bgorange>&nbsp;SKIPPED&nbsp;</span>"
          LOG32BSKP=$(echo ${LOGF} | sed "s=\.log$=.skipped.log=g")
          LOG32BSKP=$(basename ${LOG32BSKP})
          echo "Skipped log file, size is ${LOGSIZDSP} bytes. Limit is ${LOGMAXDIS}" >${ZIPFOLSVC}/${LOG32BSKP}
        fi
        Echo "</li>"

        #--- If the file contains log counters (:00000194:) then create a version of it without counters
        if test $(grep -c :00000194: ${LOGF}) -gt 0
        then
          LOGFNOCNT="$(echo ${LOGF} | sed 's=\.log$==g').nocounters.log"
          grep -v :00000194: ${LOGF} >${ZIPFOLSVC}/$(basename ${LOGFNOCNT})
          Echo "<li class=charon><span class=textgreen1>${LOGF}</span> (counters removed)</li>"
        fi

        #--- Check if <log>.upto* exist, if yes, add the ones since LOGDATSIN
        ls ${LOGF}.upto* 2>/dev/null | grep -v \.gz$ | while read LOGUPTO
        do
          ProgressBar
          LOGYMD=$(echo ${LOGUPTO} | sed "s=^.*\.upto\(....-..-..\)-......$=\1=g" | tr -d '-')
          if test ${LOGYMD} -ge ${LOGDATSIN}
          then
            LOGSIZ=$(find ${LOGUPTO} -printf '%k')
            LOGSIZDSP=$(printf "%'.f\n" ${LOGSIZ})

            LOGLIN=$(head -1 ${LOGUPTO})
            LOGDAT=$(echo ${LOGLIN} | cut -f1 -d':')
            LOGTIM=$(echo ${LOGLIN} | cut -f2 -d':' | sed "s=^\(..\)\(..\)\(..\)$=\1:\2:\3=g")
            LOGDATBEG=$(date +'%d-%b-%Y %H:%M:%S' -d "${LOGDAT} ${LOGTIM}")
            LOGLIN=$(tail -100 ${LOGUPTO} | grep "^........:......:.*" | tail -1)
            if test -n "${LOGLIN}"
            then
              LOGDAT=$(echo ${LOGLIN} | cut -f1 -d':')
              LOGTIM=$(echo ${LOGLIN} | cut -f2 -d':' | sed "s=^\(..\)\(..\)\(..\)$=\1:\2:\3=g")
              LOGDATEND=$(date +'%d-%b-%Y %H:%M:%S' -d "${LOGDAT} ${LOGTIM}")
            else
              LOGDATEND="unknown date"
            fi
            Echo "<li class=charon>${LOGUPTO} (from ${LOGDATBEG} to ${LOGDATEND}, size ${LOGSIZDSP}kb)"

            if test ${LOGSIZ} -le ${LOGMAXSIZ}
            then
              cp -p ${LOGUPTO} ${ZIPFOLSVC}/
            else
              Echo " <span class=bgorange>&nbsp;SKIPPED&nbsp;</span>"
              LOG32BSKP=$(echo ${LOGUPTO} | sed "s=\.log$=.skipped.log=g")
              LOG32BSKP=$(basename ${LOG32BSKP})
              echo "Skipped log file, size is ${LOGSIZDSP} bytes. Limit is ${LOGMAXDIS}" >${ZIPFOLSVC}/${LOG32BSKP}
            fi
            Echo "</li>"
          fi
        done
      fi
    else
      Incr_NBWARN "${CFG}: session log file '${LOGF}' does not exist"
      Echo " <span class=msgwarn>&nbsp;File does not exist or cannot be determined&nbsp;</span><br>"
    fi
  else
    Incr_NBWARN "${CFG}: session log file name and location cannot be determined"
    Echo " <span class=msgwarn>&nbsp;File name and location cannot be determined&nbsp;</span><br>"
  fi
  Echo "</font>"

  Echo "<br><h4>Console log file(s)</h4>"
  Echo "<font style='font-family:monospace;'>"
  if test -n "${LOGFCONSOLE}"
  then
    if test -e ${LOGFCONSOLE}
    then
      if test -h ${LOGFCONSOLE}
      then
        #--- Symbolic link so rotating log file
        echo "" >${LOGDATTMP}

        LOGFCUT=$(echo ${LOGFCONSOLE} | sed "s=\.log$=-=g")
        ls -r $(echo ${LOGFCONSOLE} | sed "s=\.log$==g")-????-??-??-??-??-??-?????????.log 2>/dev/null | while read LOGCONS
        do
          ProgressBar
          LOGCONSDAT=$(echo ${LOGCONS} | sed "s=^${LOGFCUT}==g"| awk -F "-" '{print $1$2$3}')
          if test ${LOGCONSDAT} -ge ${LOGDATSIN}
          then
            echo "${LOGCONSDAT}" >${LOGDATTMP}
          fi
        done

        LOGCONSSIN=$(cat ${LOGDATTMP})
        if test -z "${LOGCONSSIN}"
        then
          #--- if no log file corresponding to the date selected (since) is not found, add all log files
          Echo "<span class=textgray>No console log file corresponding to the date selected, adding all log files:</span>"
          ls $(echo ${LOGFCONSOLE} | sed "s=\.log$==g")-????-??-??-??-??-??-?????????.log 2>/dev/null | while read LOGCONS
          do
            ProgressBar
            Echo "<li class=charon>${LOGCONS}"
            LOGSIZ=$(find ${LOGCONS} -printf '%k')
            LOGSIZDSP=$(printf "%'.f\n" ${LOGSIZ})
            Echo " (Last updated on $(date -r ${LOGCONS} +'%d-%b-%Y %H:%M:%S'), size ${LOGSIZDSP}kb)"
            if test ${LOGSIZ} -le ${LOGMAXSIZ}
            then
              cp -p ${LOGCONS} ${ZIPFOLSVC}/
            else
              Echo " <span class=bgorange>&nbsp;SKIPPED&nbsp;</span>"
              LOG32BSKP=$(echo ${LOGCONS} | sed "s=\.log$=.skipped.log=g")
              LOG32BSKP=$(basename ${LOG32BSKP})
              echo "Skipped log file, size is ${LOGSIZDSP} bytes. Limit is ${LOGMAXDIS}" >${ZIPFOLSVC}/${LOG32BSKP}
            fi
            Echo "</li>"
          done
        else
          #--- if a log file corresponding to the date selected (since) is found, add it and all next ones
          DATDSP=$(date -d ${LOGCONSSIN} +%d-%b-%Y)
          Echo "<span class=textgray>Adding console log files since ${DATDSP}:</span>"
          ls $(echo ${LOGFCONSOLE} | sed "s=\.log$==g")-????-??-??-??-??-??-?????????.log 2>/dev/null | while read LOGCONS
          do
            ProgressBar
            LOGCONSDAT=$(echo ${LOGCONS} | sed "s=^${LOGFCUT}==g"| awk -F "-" '{print $1$2$3}')
            if test ${LOGCONSDAT} -ge ${LOGCONSSIN}
            then
              Echo "<li class=charon>${LOGCONS}"
              LOGSIZ=$(find ${LOGCONS} -printf '%k')
              LOGSIZDSP=$(printf "%'.f\n" ${LOGSIZ})
              Echo " (Last updated on $(date -r ${LOGCONS} +'%d-%b-%Y %H:%M:%S'), size ${LOGSIZDSP}kb)"
              if test ${LOGSIZ} -le ${LOGMAXSIZ}
              then
                cp -p ${LOGCONS} ${ZIPFOLSVC}/
              else
                Echo " <span class=bgorange>&nbsp;SKIPPED&nbsp;</span>"
                LOG32BSKP=$(echo ${LOGCONS} | sed "s=\.log$=.skipped.log=g")
                LOG32BSKP=$(basename ${LOG32BSKP})
                echo "Skipped log file, size is ${LOGSIZDSP} bytes. Limit is ${LOGMAXDIS}" >${ZIPFOLSVC}/${LOG32BSKP}
              fi
              Echo "</li>"
            fi
          done
        fi
      else
        #--- Plain file
        Echo "<span class=textgray>Non rotating log file:</span>"
        Echo "<li class=charon>${LOGFCONSOLE}"
        LOGSIZ=$(find ${LOGFCONSOLE} -printf '%k')
        LOGSIZDSP=$(printf "%'.f\n" ${LOGSIZ})
        Echo " (Last updated on $(date -r ${LOGFCONSOLE} +'%d-%b-%Y %H:%M:%S'), size ${LOGSIZDSP}kb)"
        Echo "</li>"
        if test ${LOGSIZ} -le ${LOGMAXSIZ}
        then
          cp -p ${LOGFCONSOLE} ${ZIPFOLSVC}/
        else
          Echo " <span class=bgorange>&nbsp;SKIPPED&nbsp;</span>"
          LOG32BSKP=$(echo ${LOGFCONSOLE} | sed "s=\.log$=.skipped.log=g")
          LOG32BSKP=$(basename ${LOG32BSKP})
          echo "Skipped log file, size is ${LOGSIZDSP} bytes. Limit is ${LOGMAXDIS}" >${ZIPFOLSVC}/${LOG32BSKP}
        fi
      fi
    else
      Incr_NBWARN "${CFG}: console log file '${LOGFCONSOLE}' does not exist"
      Echo " <span class=msgwarn>&nbsp;File does not exist or cannot be determined&nbsp;</span><br>"
    fi
  else
    Echo "<li class=charon>No console log file defined</li>"
  fi
  Echo "</font>"

  Echo "<br><h4>Network Interface(s) log file(s)</h4>"
  Echo "<font style='font-family:monospace;'>"
  if test -e ${CFG}
  then
    LOGNICTMP="/tmp/CharonReport_nic.tmp"
    echo 0 >${LOGNICTMP}
    grep "^set[ \t]\+.*[ \t]\+log" ${CFG} | grep -vw session | grep -vw OPA0 | grep -v ^# | tr "	" " " | sed "s/  //g" | \
        sed "s: = :=:g" | sed "s: =:=:g" | sed "s:= :=:g" | while read LINENIC
    do
      LOGNIC=$(echo ${LINENIC} | sed "s:^.*log=::g" | tr -d '"' | tr -d "'")
      NAMNIC=$(echo ${LINENIC} | awk '{print $2}')

      # Starting with V4.7 B17101
      NICROTA=0
      if test ${BLD:-0} -ge 17100 -a -d ${LOGNIC}
      then
        NICROTA=1
        GETCFGNAM=$(grep "^set[ \t]\+session[ \t]\+configuration_name" ${CFG}|grep -v "^#"|cut -f2 -d'='|sed "s=\s==g"|tr -d "'"|tr -d '"')
        if test -n "${GETCFGNAM}"
        then
          LOGNIC="${LOGNIC}/${GETCFGNAM}-${NAMNIC}.log"
        else
          GETHWMOD=$(grep "^set[ \t]\+session[ \t]\+hw_model" ${CFG}|grep -v "^#"|cut -f2 -d'='|sed "s=\s==g"|tr -d "'"|tr -d '"')
          LOGNIC="${LOGNIC}/${GETHWMOD}-${NAMNIC}.log"
        fi
      fi
      if test -n "${LOGNIC}"
      then
        if test -e ${LOGNIC}
        then
          echo 1 >${LOGNICTMP}
          if test -h ${LOGNIC}
          then
            #--- Symbolic link so rotating log file
            echo "" >${LOGDATTMP}

            LOGFCUT=$(echo ${LOGNIC} | sed "s=\.log$=-=g")
            ls -r $(echo ${LOGNIC} | sed "s=\.log$==g")-????-??-??-??-??-??-?????????.log 2>/dev/null | while read LOGN
            do
              ProgressBar
              LOGCONSDAT=$(echo ${LOGN} | sed "s=^${LOGFCUT}==g"| awk -F "-" '{print $1$2$3}')
              if test ${LOGCONSDAT} -ge ${LOGDATSIN}
              then
                echo "${LOGCONSDAT}" >${LOGDATTMP}
              fi
            done

            LOGNICSIN=$(cat ${LOGDATTMP})
            if test -z "${LOGNICSIN}"
            then
              #--- if no log file corresponding to the date selected (since) is not found, add all log files
              Echo "<span class=textgray>No NIC log file corresponding to the date selected, adding all log files:</span>"
              ls $(echo ${LOGNIC} | sed "s=\.log$==g")-????-??-??-??-??-??-?????????.log 2>/dev/null | while read LOGN
              do
                ProgressBar
                Echo "<li class=charon>${LOGN}"
                LOGSIZ=$(find ${LOGN} -printf '%k')
                LOGSIZDSP=$(printf "%'.f\n" ${LOGSIZ})
                Echo " (Last updated on $(date -r ${LOGN} +'%d-%b-%Y %H:%M:%S'), size ${LOGSIZDSP}kb)"
                if test ${LOGSIZ} -le ${LOGMAXSIZ}
                then
                  cp -p ${LOGN} ${ZIPFOLSVC}/
                else
                  Echo " <span class=bgorange>&nbsp;SKIPPED&nbsp;</span>"
                  LOG32BSKP=$(echo ${LOGN} | sed "s=\.log$=.skipped.log=g")
                  LOG32BSKP=$(basename ${LOG32BSKP})
                  echo "Skipped log file, size is ${LOGSIZDSP} bytes. Limit is ${LOGMAXDIS}" >${ZIPFOLSVC}/${LOG32BSKP}
                fi
                Echo "</li>"
              done
            else
              #--- if a log file corresponding to the date selected (since) is found, add it and all next ones
              DATDSP=$(date -d ${LOGNICSIN} +%d-%b-%Y)
              Echo "<span class=textgray>Adding console log files since ${DATDSP}:</span>"
              ls $(echo ${LOGNIC} | sed "s=\.log$==g")-????-??-??-??-??-??-?????????.log 2>/dev/null | while read LOGN
              do
                ProgressBar
                LOGNICDAT=$(echo ${LOGN} | sed "s=^${LOGFCUT}==g"| awk -F "-" '{print $1$2$3}')
                if test ${LOGNICDAT} -ge ${LOGNICSIN}
                then
                  Echo "<li class=charon>${LOGN}"
                  LOGSIZ=$(find ${LOGN} -printf '%k')
                  LOGSIZDSP=$(printf "%'.f\n" ${LOGSIZ})
                  Echo " (Last updated on $(date -r ${LOGN} +'%d-%b-%Y %H:%M:%S'), size ${LOGSIZDSP}kb)"
                  if test ${LOGSIZ} -le ${LOGMAXSIZ}
                  then
                    cp -p ${LOGN} ${ZIPFOLSVC}/
                  else
                    Echo " <span class=bgorange>&nbsp;SKIPPED&nbsp;</span>"
                    LOG32BSKP=$(echo ${LOGN} | sed "s=\.log$=.skipped.log=g")
                    LOG32BSKP=$(basename ${LOG32BSKP})
                    echo "Skipped log file, size is ${LOGSIZDSP} bytes. Limit is ${LOGMAXDIS}" >${ZIPFOLSVC}/${LOG32BSKP}
                  fi
                  Echo "</li>"
                fi
              done
            fi
          else
            #--- Plain file
            Echo "<span class=textgray>Non rotating log file:</span>"
            Echo "<li class=charon>${LOGNIC}"
            LOGSIZ=$(find ${LOGNIC} -printf '%k')
            LOGSIZDSP=$(printf "%'.f\n" ${LOGSIZ})
            Echo " (Last updated on $(date -r ${LOGNIC} +'%d-%b-%Y %H:%M:%S'), size ${LOGSIZDSP}kb)"
            Echo "</li>"
            if test ${LOGSIZ} -le ${LOGMAXSIZ}
            then
              cp -p ${LOGNIC} ${ZIPFOLSVC}/
            else
              Echo " <span class=bgorange>&nbsp;SKIPPED&nbsp;</span>"
              LOG32BSKP=$(echo ${LOGNIC} | sed "s=\.log$=.skipped.log=g")
              LOG32BSKP=$(basename ${LOG32BSKP})
              echo "Skipped log file, size is ${LOGSIZDSP} bytes. Limit is ${LOGMAXDIS}" >${ZIPFOLSVC}/${LOG32BSKP}
            fi
          fi
        fi
      else
        Echo "<li class=charon>No NIC log file defined.</li>"
      fi
    done
    if test $(cat ${LOGNICTMP}) -eq 0
    then
      Echo "<li class=charon>No NIC log file defined.</li>"
    fi
  else
    Echo "Cannot find network interface, configuration file not found.<br>"
  fi
  Echo "</font>"
}

#=============================================================================
#--- Collect configuration and log file (PAR)
#=============================================================================
function collect_cfglogpar {
  # $1 = configuration file
  # $2 = source
  ProgressBar begin "Collecting Charon-PAR cfg and log files"
  LOGDATSIN=$(date +'%y%m%d' -d ${LOGSETDAT})

  CFG=$1
  SVC=$(basename ${CFG}|sed "s=\.cfg$==g")
  get_logfile_par ${CFG} $2

  typeset -i NF=0
  while test 1
  do
    NF=NF+1
    ZIPFOLSVC=${ZIPFOLDER}/CharonReport.d/$(printf "%03d" ${NF})
    if test ! -d ${ZIPFOLSVC}_*
    then
      ZIPFOLSVC=${ZIPFOLDER}/CharonReport.d/$(printf "%03d" ${NF})_${SVC}
      mkdir -p ${ZIPFOLSVC}
      break
    fi
  done

  Echo "<h3>${VMCFGBAS} - Attached configuration and log files</h3>"
  Echo "Zip file child folder: <span class=textblue1>$(basename ${ZIPFOLSVC})</span><br><br>"

  Echo "<h4>Configuration file</h4>"

  Echo "<li class=charon>${CFG}"
  if test -e ${CFG}
  then
    Echo " (Last updated on $(date -r ${CFG} +'%d-%b-%Y %H:%M:%S'))</li>"
    cp -p ${CFG} ${ZIPFOLSVC}/
  else
    Incr_NBERR "Configuration file '${CFG}' does not exist"
    Echo " <span class=msgerr>&nbsp;File does not exist&nbsp;</span></li>"
  fi

  Echo "<br><h4>Session log file(s)</h4>"
  Echo "<font style='font-family:monospace;'>"
  if test -e ${LOGF}
  then
    typeset -i LOGNBWARN=$(grep ':warn:' ${LOGF} | wc -l)
    typeset -i LOGNBERRO=$(grep ':err:' ${LOGF} | wc -l)
    typeset -i LOGNBFATA=$(grep ':ERR:' ${LOGF} | wc -l)
    if test ${LOGNBWARN} -gt 0
    then
      Incr_NBWARN "Found ${LOGNBWARN} warning message$(test ${LOGNBWARN} -gt 1 && echo 's') in ${LOGF}"
    fi
    if test ${LOGNBERRO} -gt 0
    then
      Incr_NBERR "Found ${LOGNBERRO} error message$(test ${LOGNBERRO} -gt 1 && echo 's') in ${LOGF}"
    fi
    if test ${LOGNBFATA} -gt 0
    then
      Incr_NBERR "Found ${LOGNBFATA} fatal message$(test ${LOGNBFATA} -gt 1 && echo 's') in ${LOGF}"
    fi

    if test -h ${LOGF}
    then
      #--- Symbolic link so rotating log file
      LOGDATTMP="/tmp/CharonReport_logdat.tmp"
      echo 0 >${LOGDATTMP}

      CHK=0
      ls $(echo ${LOGF} | sed "s=\.log$==g").??????-??????-????.log 2>/dev/null | while read LOGFL
      do
        ProgressBar
        LOGYMD=$(echo ${LOGFL} | sed "s=\(^.*\)\.\(......\)\(-......-....\.log$\)=\2=g")
        if test ${LOGYMD} -ge ${LOGDATSIN}
        then
          if test ${CHK} -eq 0
          then
            DATDSP=$(date -d ${LOGYMD} +%d-%b-%Y)
            Echo "<span class=textgray>Adding log files since ${DATDSP}:</span>"
          fi
          CHK=1
          LOGSIZ=$(find ${LOGFL} -printf '%k')
          LOGSIZDSP=$(printf "%'.f\n" ${LOGSIZ})

          LOGLIN=$(head -1 ${LOGFL})
          LOGDAT=$(echo ${LOGLIN} | cut -f1 -d':')
          LOGTIM=$(echo ${LOGLIN} | cut -f2 -d':' | cut -f1 -d'.' | sed "s=^\(..\)\(..\)\(..\)$=\1:\2:\3=g")
          LOGDATBEG=$(date +'%d-%b-%Y %H:%M:%S' -d "${LOGDAT} ${LOGTIM}")
          LOGLIN=$(tail -100 ${LOGFL} | grep "^........:.*:.*" | tail -1)
          if test -n "${LOGLIN}"
          then
            LOGDAT=$(echo ${LOGLIN} | cut -f1 -d':')
            LOGTIM=$(echo ${LOGLIN} | cut -f2 -d':' | cut -f1 -d'.' | sed "s=^\(..\)\(..\)\(..\)$=\1:\2:\3=g")
            LOGDATEND=$(date +'%d-%b-%Y %H:%M:%S' -d "${LOGDAT} ${LOGTIM}")
          else
            LOGDATEND="unknown date"
          fi
          Echo "<li class=charon>${LOGFL} (from ${LOGDATBEG} to ${LOGDATEND}, size ${LOGSIZDSP}kb)"

          if test ${LOGSIZ} -le ${LOGMAXSIZ}
          then
            cp -p ${LOGFL} ${ZIPFOLSVC}/
          else
            Echo " <span class=bgorange>&nbsp;SKIPPED&nbsp;</span>"
            LOG32BSKP=$(echo ${LOGFL} | sed "s=\.log$=.skipped.log=g")
            LOG32BSKP=$(basename ${LOG32BSKP})
            echo "Skipped log file, size is ${LOGSIZDSP} bytes. Limit is ${LOGMAXDIS}" >${ZIPFOLSVC}/${LOG32BSKP}
          fi
          Echo "</li>"
          echo 1 >${LOGDATTMP}
        fi
      done

      CHK=$(cat ${LOGDATTMP})
      if test ${CHK} -eq 0
      then
        #--- If no log file since the specified date, add all log files
        DATDSP=$(date -d ${LOGDATSIN} +%d-%b-%Y)
        Echo "<span class=textgray>No log file found after ${DATDSP}, adding all log files:</span>"
        ls $(echo ${LOGF} | sed "s=\.log$==g").??????-??????-????.log 2>/dev/null | while read LOGFL
        do
          ProgressBar
          LOGSIZ=$(find ${LOGFL} -printf '%k')
          LOGSIZDSP=$(printf "%'.f\n" ${LOGSIZ})

          LOGLIN=$(head -1 ${LOGFL})
          LOGDAT=$(echo ${LOGLIN} | cut -f1 -d':')
          LOGTIM=$(echo ${LOGLIN} | cut -f2 -d':' | cut -f1 -d'.' | sed "s=^\(..\)\(..\)\(..\)$=\1:\2:\3=g")
          LOGDATBEG=$(date +'%d-%b-%Y %H:%M:%S' -d "${LOGDAT} ${LOGTIM}")
          LOGLIN=$(tail -100 ${LOGFL} | grep "^........:.*:.*" | tail -1)
          if test -n "${LOGLIN}"
          then
            LOGDAT=$(echo ${LOGLIN} | cut -f1 -d':')
            LOGTIM=$(echo ${LOGLIN} | cut -f2 -d':' | cut -f1 -d'.' | sed "s=^\(..\)\(..\)\(..\)$=\1:\2:\3=g")
            LOGDATEND=$(date +'%d-%b-%Y %H:%M:%S' -d "${LOGDAT} ${LOGTIM}")
          else
            LOGDATEND="unknown date"
          fi
          Echo "<li class=charon>${LOGFL} (from ${LOGDATBEG} to ${LOGDATEND}, size ${LOGSIZDSP}kb)"

          if test ${LOGSIZ} -le ${LOGMAXSIZ}
          then
            cp -p ${LOGFL} ${ZIPFOLSVC}/
          else
            Echo " <span class=bgorange>&nbsp;SKIPPED&nbsp;</span>"
            LOG32BSKP=$(echo ${LOGFL} | sed "s=\.log$=.skipped.log=g")
            LOG32BSKP=$(basename ${LOG32BSKP})
            echo "Skipped log file, size is ${LOGSIZDSP} bytes. Limit is ${LOGMAXDIS}" >${ZIPFOLSVC}/${LOG32BSKP}
          fi
          Echo "</li>"
        done
      fi

    else
      #--- Plain file
      ProgressBar
      Echo "<span class=textgray>Non rotating log file:</span>"
      LOGSIZ=$(find ${LOGF} -printf '%k')
      LOGSIZDSP=$(printf "%'.f\n" ${LOGSIZ})

      LOGLIN=$(head -1 ${LOGF})
      LOGDAT=$(echo ${LOGLIN} | cut -f1 -d':')
      LOGTIM=$(echo ${LOGLIN} | cut -f2 -d':' | cut -f1 -d'.' | sed "s=^\(..\)\(..\)\(..\)$=\1:\2:\3=g")
      LOGDATBEG=$(date +'%d-%b-%Y %H:%M:%S' -d "${LOGDAT} ${LOGTIM}")
      LOGLIN=$(tail -100 ${LOGF} | grep "^........:.*:.*" | tail -1)
      if test -n "${LOGLIN}"
      then
        LOGDAT=$(echo ${LOGLIN} | cut -f1 -d':')
        LOGTIM=$(echo ${LOGLIN} | cut -f2 -d':' | cut -f1 -d'.' | sed "s=^\(..\)\(..\)\(..\)$=\1:\2:\3=g")
        LOGDATEND=$(date +'%d-%b-%Y %H:%M:%S' -d "${LOGDAT} ${LOGTIM}")
      else
        LOGDATEND="unknown date"
      fi
      Echo "<li class=charon>${LOGF} (from ${LOGDATBEG} to ${LOGDATEND}, size ${LOGSIZDSP}kb)"

      if test ${LOGSIZ} -le ${LOGMAXSIZ}
      then
        cp -p ${LOGF} ${ZIPFOLSVC}/
      else
        Echo " <span class=bgorange>&nbsp;SKIPPED&nbsp;</span>"
        LOG32BSKP=$(echo ${LOGF} | sed "s=\.log$=.skipped.log=g")
        LOG32BSKP=$(basename ${LOG32BSKP})
        echo "Skipped log file, size is ${LOGSIZDSP} bytes. Limit is ${LOGMAXDIS}" >${ZIPFOLSVC}/${LOG32BSKP}
      fi
      Echo "</li>"

      #--- Check if <log>.upto* exist, if yes, add the ones since LOGDATSIN
      LOGDATSIN=$(date +'%Y%m%d' -d ${LOGSETDAT})
      ls ${LOGF}.upto* 2>/dev/null | grep -v \.gz$ | while read LOGUPTO
      do
        ProgressBar
        LOGYMD=$(echo ${LOGUPTO} | sed "s=^.*\.upto\(....-..-..\)-......$=\1=g" | tr -d '-')
        if test ${LOGYMD} -ge ${LOGDATSIN}
        then
          LOGSIZ=$(find ${LOGUPTO} -printf '%k')
          LOGSIZDSP=$(printf "%'.f\n" ${LOGSIZ})

          LOGLIN=$(head -1 ${LOGUPTO})
          LOGDAT=$(echo ${LOGLIN} | cut -f1 -d':')
          LOGTIM=$(echo ${LOGLIN} | cut -f2 -d':' | cut -f1 -d'.' | sed "s=^\(..\)\(..\)\(..\)$=\1:\2:\3=g")
          LOGDATBEG=$(date +'%d-%b-%Y %H:%M:%S' -d "${LOGDAT} ${LOGTIM}")
          LOGLIN=$(tail -100 ${LOGUPTO} | grep "^........:.*:.*" | tail -1)
          if test -n "${LOGLIN}"
          then
            LOGDAT=$(echo ${LOGLIN} | cut -f1 -d':')
            LOGTIM=$(echo ${LOGLIN} | cut -f2 -d':' | cut -f1 -d'.' | sed "s=^\(..\)\(..\)\(..\)$=\1:\2:\3=g")
            LOGDATEND=$(date +'%d-%b-%Y %H:%M:%S' -d "${LOGDAT} ${LOGTIM}")
          else
            LOGDATEND="unknown date"
          fi
          Echo "<li class=charon>${LOGUPTO} (from ${LOGDATBEG} to ${LOGDATEND}, size ${LOGSIZDSP}kb)"

          if test ${LOGSIZ} -le ${LOGMAXSIZ}
          then
            cp -p ${LOGUPTO} ${ZIPFOLSVC}/
          else
            Echo " <span class=bgorange>&nbsp;SKIPPED&nbsp;</span>"
            LOG32BSKP=$(echo ${LOGUPTO} | sed "s=\.log$=.skipped.log=g")
            LOG32BSKP=$(basename ${LOG32BSKP})
            echo "Skipped log file, size is ${LOGSIZDSP} bytes. Limit is ${LOGMAXDIS}" >${ZIPFOLSVC}/${LOG32BSKP}
          fi
          Echo "</li>"
        fi
      done

      #--- Check if <log>.<N> exist, if yes, add the ones since LOGDATSIN
      LOGDATSIN=$(date +'%Y%m%d' -d ${LOGSETDAT})
      ls ${LOGF}.[1-9] ${LOGF}.[1-9][0-9] 2>/dev/null | grep -v \.gz$ | while read LOGN
      do
        ProgressBar
        LOGYMD=$(grep :Copyright ${LOGN} | cut -f1 -d':')
        if test ${LOGYMD:-00000000} -ge ${LOGDATSIN}
        then
          LOGSIZ=$(find ${LOGN} -printf '%k')
          LOGSIZDSP=$(printf "%'.f\n" ${LOGSIZ})

          LOGLIN=$(head -1 ${LOGN})
          LOGDAT=$(echo ${LOGLIN} | cut -f1 -d':')
          LOGTIM=$(echo ${LOGLIN} | cut -f2 -d':' | cut -f1 -d'.' | sed "s=^\(..\)\(..\)\(..\)$=\1:\2:\3=g")
          LOGDATBEG=$(date +'%d-%b-%Y %H:%M:%S' -d "${LOGDAT} ${LOGTIM}")
          LOGLIN=$(tail -100 ${LOGN} | grep "^........:.*:.*" | tail -1)
          if test -n "${LOGLIN}"
          then
            LOGDAT=$(echo ${LOGLIN} | cut -f1 -d':')
            LOGTIM=$(echo ${LOGLIN} | cut -f2 -d':' | cut -f1 -d'.' | sed "s=^\(..\)\(..\)\(..\)$=\1:\2:\3=g")
            LOGDATEND=$(date +'%d-%b-%Y %H:%M:%S' -d "${LOGDAT} ${LOGTIM}")
          else
            LOGDATEND="unknown date"
          fi
          Echo "<li class=charon>${LOGN} (from ${LOGDATBEG} to ${LOGDATEND}, size ${LOGSIZDSP}kb)"

          if test ${LOGSIZ} -le ${LOGMAXSIZ}
          then
            cp -p ${LOGN} ${ZIPFOLSVC}/
          else
            Echo " <span class=bgorange>&nbsp;SKIPPED&nbsp;</span>"
            LOG32BSKP=$(echo ${LOGN} | sed "s=\.log$=.skipped.log=g")
            LOG32BSKP=$(basename ${LOG32BSKP})
            echo "Skipped log file, size is ${LOGSIZDSP} bytes. Limit is ${LOGMAXDIS}" >${ZIPFOLSVC}/${LOG32BSKP}
          fi
          Echo "</li>"
        fi
      done

    fi
  else
    Incr_NBWARN "${CFG}: session log file name and location cannot be determined"
    Echo " <span class=msgwarn>&nbsp;File does not exist or cannot be determined&nbsp;</span><br>"
    CHKLOGDIS=$(grep log.disable ${CFG} | tr -d "\t " | tr -d "'" | tr -d '"')
    if test -n "$(echo ${CHKLOGDIS} | grep ^#)"
    then
      if test -n "$(echo ${CHKLOGDIS} | grep -w "log\.disable=true")"
      then
        Incr_NBWARN "${CFG}: log file is disabled (log.disable=true)"
        Echo " <span class=msgwarn>&nbsp;Log file is disabled (log.disable=true)&nbsp;</span><br>"
      fi
    fi
  fi
  Echo "</font>"

  #---------------------------------------------
  # Attaching charon-report file (if available)
  #---------------------------------------------
  if test -x ${CHARONDIR}/bin/charon-report
  then
    ProgressBar
    Echo "<br><h4>charon-report for Charon-PAR</h4>"
    Echo "<font style='font-family:monospace;'>"

    D=$(date +%Y%m%d)
    grep ^hpa\- -q ${TMPRPMFILE}
    if test $? -eq 0
    then
      ( (echo 'Charon Report';echo) | ${CHARONDIR}/bin/charon-report -f $(dirname ${CFG}) >${ZIPFOLSVC}/charon-report.log 2>&1 ) &
      ZIPD="/root"
    else
      ( (echo 'Charon Report')      | ${CHARONDIR}/bin/charon-report -f $(dirname ${CFG}) >${ZIPFOLSVC}/charon-report.log 2>&1 ) &
      ZIPD="/tmp"
    fi

    CRTIMOUT=0
    REPORTTIMOUT=600
    typeset -i I=${REPORTTIMOUT}
    while test 1
    do
      ProgressBar "[$I]"
      sleep .5
      ProgressBar "[$I]"
      sleep .5
      I=I-1
      test ! -e /proc/$! && break
      if test $I -le 0
      then
        ProgressBar "Timeout creating charon-report tgz file"
        CRTIMOUT=1
        sleep 2
        break
      fi
    done
    sleep 1

    if test ${CRTIMOUT} -eq 0
    then
      ZIPF=$(ls -tr ${ZIPD}/report-${D}-*.tgz 2>/dev/null | tail -1)
      if test -n "${ZIPF}"
      then
        if test -e ${ZIPF}
        then
          LOGSIZ=$(find ${ZIPF} -printf '%k')
          LOGSIZDSP=$(printf "%'.f\n" ${LOGSIZ})
          Echo "<li class=charon>$(basename ${ZIPF}) (Size ${LOGSIZDSP}kb)</li>"
          mv -f ${ZIPF} ${ZIPFOLSVC}/
        else
          Incr_NBWARN "${CFG}: cannot find report file ${ZIPD}/report-${D}-*.tgz generated by charon-report"
          Echo "<span class=msgwarn>&nbsp;Cannot find report file ${ZIPD}/report-${D}-\*.tgz&nbsp;</span></li>"
        fi
      else
        Incr_NBWARN "${CFG}: cannot find report file ${ZIPD}/report-${D}-*.tgz generated by charon-report"
        Echo "<span class=msgwarn>&nbsp;Cannot find report file ${ZIPD}/report-${D}-\*.tgz&nbsp;</span></li>"
      fi
    else
      Incr_NBWARN "${CFG}: timeout (${REPORTTIMOUT} sec.) creating report file ${ZIPD}/report-${D}-\*.tgz (generated by charon-report)"
      Echo "<span class=msgwarn>&nbsp;Timeout creating report file ${ZIPD}/report-${D}-*.tgz&nbsp;</span></li>"
    fi
    Echo "</font><br>"
  fi
}

#=============================================================================
#--- Collect configuration and log file (SSP)
#=============================================================================
function collect_cfglogssp {
  # $1 = configuration file
  ProgressBar begin "Collecting Charon-SSP cfg and log files"
  LOGDATSIN=$(date +'%Y%m%d' -d ${LOGSETDAT})

  CFG=$1
  SVC=$(basename ${CFG}|sed "s=\.cfg$==g")
  get_logfile_ssp ${CFG}

  typeset -i NF=0
  while test 1
  do
    NF=NF+1
    ZIPFOLSVC=${ZIPFOLDER}/CharonReport.d/$(printf "%03d" ${NF})
    if test ! -d ${ZIPFOLSVC}_*
    then
      ZIPFOLSVC=${ZIPFOLDER}/CharonReport.d/$(printf "%03d" ${NF})_${SVC}
      mkdir -p ${ZIPFOLSVC}
      break
    fi
  done

  Echo "<h3>${VMCFGBAS} - Attached configuration and log files</h3>"
  Echo "Zip file child folder: <span class=textblue1>$(basename ${ZIPFOLSVC})</span><br><br>"

  Echo "<h4>Configuration file</h4>"

  Echo "<li class=charon>${CFG}"
  if test -e ${CFG}
  then
    Echo " (Last updated on $(date -r ${CFG} +'%d-%b-%Y %H:%M:%S'))</li>"
    cp -p ${CFG} ${ZIPFOLSVC}/
  else
    Incr_NBERR "Configuration file '${CFG}' does not exist"
    Echo " <span class=msgerr>&nbsp;File does not exist&nbsp;</span></li>"
  fi

  #--- Check if <log> and <log>.<N> exist, if yes, add the ones since LOGDATSIN
  Echo "<br><h4>Session log file(s)</h4>"
  Echo "<font style='font-family:monospace;'>"
  LOGDATTMP="/tmp/CharonReport_logdat.tmp"
  echo 0 >${LOGDATTMP}
  CHK=0
  for LOGEXT in "" .1 .2 .3 .4 .5 .6 .7 .8 .9 .10 .11 .12 .13 .14 .15 .16 .17 .18 .19 .20
  do
    LOGN=${LOGF}${LOGEXT}
    if test -e ${LOGN}
    then
      ProgressBar
      LOGYMD=$(grep -w Version: ${LOGN} | cut -f1 -d' ' | tr -d '-')
      LOGLST=$(tail -1 ${LOGN} | cut -f1 -d' ' | tr -d '-')
      if [[ ${LOGYMD:-00000000} -ge ${LOGDATSIN} || ${LOGLST:-99999999} -ge ${LOGDATSIN} ]]
      then
        test ${CHK} -eq 0 && Echo "<span class=textgray>Adding log files since ${LOGSETDAT}:</span>"
        CHK=1
        LOGSIZ=$(find ${LOGN} -printf '%k')
        LOGSIZDSP=$(printf "%'.f\n" ${LOGSIZ})
        LOGHMSBEGIN=$(grep -w Version: ${LOGN} | cut -f2 -d' ')
        LOGHMSLAST=$(tail -1 ${LOGN} | cut -f2 -d' ' | tr -d '-')
        LOGDATBEG=$(date +'%d-%b-%Y %H:%M:%S' -d "${LOGYMD} ${LOGHMSBEGIN}")
        LOGDATEND=$(date +'%d-%b-%Y %H:%M:%S' -d "${LOGLST} ${LOGHMSLAST}")

        if test $(echo ${LOGEXT:-0} | tr -d '.') -eq 0
        then
          Echo "<li class=charon>${LOGN}&nbsp;&nbsp;&nbsp;&nbsp;(from ${LOGDATBEG} to ${LOGDATEND}, size ${LOGSIZDSP}kb)"
        elif test $(echo ${LOGEXT:-0} | tr -d '.') -gt 9
        then
          Echo "<li class=charon>${LOGN}&nbsp;(from ${LOGDATBEG} to ${LOGDATEND}, size ${LOGSIZDSP}kb)"
        else
          Echo "<li class=charon>${LOGN}&nbsp;&nbsp;(from ${LOGDATBEG} to ${LOGDATEND}, size ${LOGSIZDSP}kb)"
        fi

        if test ${LOGSIZ} -le ${LOGMAXSIZ}
        then
          if test -n "$(echo ${LOGN} | grep log$)"
          then
            cp -p ${LOGN} ${ZIPFOLSVC}/
          else
            #--- if .log.<n> then rename to .log.<n>.log, more easy to read on Windows hosts
            cp -p ${LOGN} ${ZIPFOLSVC}/$(basename ${LOGN}).log
          fi
        else
          Echo " <span class=bgorange>&nbsp;SKIPPED&nbsp;</span>"
          LOG32BSKP=$(echo ${LOGN} | sed "s=\.log$=.skipped.log=g")
          LOG32BSKP=$(basename ${LOG32BSKP})
          echo "Skipped log file, size is ${LOGSIZDSP} bytes. Limit is ${LOGMAXDIS}" >${ZIPFOLSVC}/${LOG32BSKP}
        fi
        Echo "</li>"
        echo 1 >${LOGDATTMP}
      fi
    fi
  done

  CHK=$(cat ${LOGDATTMP})
  if test ${CHK} -eq 0
  then
    #--- If no log file since the specified date, add all log files
    DATDSP=$(date -d ${LOGDATSIN} +%d-%b-%Y)
    if test $(ls ${LOGF} ${LOGF}.[1-9] ${LOGF}.[1-9][0-9] 2>/dev/null | grep -v \.gz$ | wc -l) -gt 0
    then
      Echo "<span class=textgray>No log file found after ${DATDSP}, adding all log files:</span>"
      for LOGEXT in "" .1 .2 .3 .4 .5 .6 .7 .8 .9 .10 .11 .12 .13 .14 .15 .16 .17 .18 .19 .20
      do
        LOGN=${LOGF}${LOGEXT}
        if test -e ${LOGN}
        then
          ProgressBar
          LOGSIZ=$(find ${LOGN} -printf '%k')
          LOGSIZDSP=$(printf "%'.f\n" ${LOGSIZ})

          LOGYMD=$(grep -w Version: ${LOGN} | cut -f1 -d' ' | tr -d '-')
          LOGLST=$(tail -1 ${LOGN} | cut -f1 -d' ' | tr -d '-')
          LOGHMSBEGIN=$(grep -w Version: ${LOGN} | cut -f2 -d' ')
          LOGHMSLAST=$(tail -1 ${LOGN} | cut -f2 -d' ' | tr -d '-')
          LOGDATBEG=$(date +'%d-%b-%Y %H:%M:%S' -d "${LOGYMD} ${LOGHMSBEGIN}")
          LOGDATEND=$(date +'%d-%b-%Y %H:%M:%S' -d "${LOGLST} ${LOGHMSLAST}")

          if test $(echo ${LOGEXT:-0} | tr -d '.') -eq 0
          then
            Echo "<li class=charon>${LOGN}&nbsp;&nbsp;&nbsp;&nbsp;(from ${LOGDATBEG} to ${LOGDATEND}, size ${LOGSIZDSP}kb)"
          elif test $(echo ${LOGEXT:-0} | tr -d '.') -gt 9
          then
            Echo "<li class=charon>${LOGN}&nbsp;(from ${LOGDATBEG} to ${LOGDATEND}, size ${LOGSIZDSP}kb)"
          else
            Echo "<li class=charon>${LOGN}&nbsp;&nbsp;(from ${LOGDATBEG} to ${LOGDATEND}, size ${LOGSIZDSP}kb)"
          fi

          if test ${LOGSIZ} -le ${LOGMAXSIZ}
          then
            if test -n "$(echo ${LOGN} | grep log$)"
            then
              cp -p ${LOGN} ${ZIPFOLSVC}/
            else
              #--- if .log.<n> then rename to .log.<n>.log, more easy to read on Windows hosts
              cp -p ${LOGN} ${ZIPFOLSVC}/$(basename ${LOGN}).log
            fi
          else
            Echo " <span class=bgorange>&nbsp;SKIPPED&nbsp;</span>"
            LOG32BSKP=$(echo ${LOGN} | sed "s=\.log$=.skipped.log=g")
            LOG32BSKP=$(basename ${LOG32BSKP})
            echo "Skipped log file, size is ${LOGSIZDSP} bytes. Limit is ${LOGMAXDIS}" >${ZIPFOLSVC}/${LOG32BSKP}
          fi
          Echo "</li>"
        fi
      done
    else
      Echo "No file found.<br>"
    fi
  fi
  Echo "</font>"

  #--- Crash files are located in the same folder as the .cfg
  LOGFCRASH=$(echo ${CFG} | sed "s=\.cfg$=.crash.log=g")
  Echo "<br><h4>Crash log file(s) (all)</h4>"
  Echo "<font style='font-family:monospace;'>"
  if test $(ls ${LOGFCRASH}* 2>/dev/null | wc -l) -gt 0
  then
    for LOGEXT in "" .1 .2 .3 .4 .5 .6 .7 .8 .9 .10 .11 .12 .13 .14 .15 .16 .17 .18 .19 .20
    do
      LOGN=${LOGFCRASH}${LOGEXT}
      if test -e ${LOGN}
      then
        ProgressBar
        LOGSIZ=$(find ${LOGN} -printf '%k')
        LOGSIZDSP=$(printf "%'.f\n" ${LOGSIZ})

        if test $(echo ${LOGEXT:-0} | tr -d '.') -eq 0
        then
          Echo "<li class=charon><span class=textgray>${LOGN}</span>&nbsp;&nbsp;&nbsp;&nbsp;(Last updated on $(date -r ${LOGN} +'%d-%b-%Y %H:%M:%S'), size ${LOGSIZDSP}kb)"
        elif test $(echo ${LOGEXT:-0} | tr -d '.') -gt 9
        then
          Echo "<li class=charon><span class=textgray>${LOGN}</span>&nbsp;(Last updated on $(date -r ${LOGN} +'%d-%b-%Y %H:%M:%S'), size ${LOGSIZDSP}kb)"
        else
          Echo "<li class=charon><span class=textgray>${LOGN}</span>&nbsp;&nbsp;(Last updated on $(date -r ${LOGN} +'%d-%b-%Y %H:%M:%S'), size ${LOGSIZDSP}kb)"
        fi

        Echo " "
        if test ${LOGSIZ} -le ${LOGMAXSIZ}
        then
          if test -n "$(echo ${LOGN} | grep log$)"
          then
            cp -p ${LOGN} ${ZIPFOLSVC}/
          else
            #--- if .log.<n> then rename to .log.<n>.log, more easy to read on Windows hosts
            cp -p ${LOGN} ${ZIPFOLSVC}/$(basename ${LOGN}).log
          fi
        else
          Echo " <span class=bgorange>&nbsp;SKIPPED&nbsp;</span>"
          LOG32BSKP=$(echo ${LOGN} | sed "s=\.log$=.skipped.log=g")
          LOG32BSKP=$(basename ${LOG32BSKP})
          echo "Skipped log file, size is ${LOGSIZDSP} bytes. Limit is ${LOGMAXDIS}" >${ZIPFOLSVC}/${LOG32BSKP}
        fi
        Echo "</li>"
      fi
    done
  else
    Echo "No file found.<br>"
  fi
  Echo "</font>"

  #--- Read .cfg file to find possible tty log files
  Echo "<br><h4>Consoles log file(s) (all)</h4>"
  Echo "<font style='font-family:monospace;'>"
  echo 0 >${LOGDATTMP}
  LASTCHAP=""
  if test -e ${CFG}
  then
    cat ${CFG} | while read CFGL
    do
      if test "$(echo ${CFGL} | cut -c1)" = "["
      then
        LASTCHAP=$(echo ${CFGL} | tr -d "[]")
      fi
      if test "$(echo ${CFGL} | cut -c1-8)" = "log_path"
      then
        if test "$(echo ${LASTCHAP} | cut -c1-3)" = "tty" -o "${LASTCHAP}" = "vconsole"
        then
          LOGFCONSOLE=$(echo ${CFGL} | cut -f2 -d '=' | tr -d "\r\n")
          for LOGEXT in "" .1 .2 .3 .4 .5 .6 .7 .8 .9 .10 .11 .12 .13 .14 .15 .16 .17 .18 .19 .20
          do
            LOGN=${LOGFCONSOLE}${LOGEXT}
            if test -e ${LOGN}
            then
              ProgressBar
              echo 1 >${LOGDATTMP}
              LOGSIZ=$(find ${LOGN} -printf '%k')
              LOGSIZDSP=$(printf "%'.f\n" ${LOGSIZ})

              if test $(echo ${LOGEXT:-0} | tr -d '.') -eq 0
              then
                Echo "<li class=charon><span class=textgreen3>${LOGN}</span>&nbsp;&nbsp;&nbsp;&nbsp;(Last updated on $(date -r ${LOGN} +'%d-%b-%Y %H:%M:%S'), size ${LOGSIZDSP}kb)"
              elif test $(echo ${LOGEXT:-0} | tr -d '.') -gt 9
              then
                Echo "<li class=charon><span class=textgreen3>${LOGN}</span>&nbsp;(Last updated on $(date -r ${LOGN} +'%d-%b-%Y %H:%M:%S'), size ${LOGSIZDSP}kb)"
              else
                Echo "<li class=charon><span class=textgreen3>${LOGN}</span>&nbsp;&nbsp;(Last updated on $(date -r ${LOGN} +'%d-%b-%Y %H:%M:%S'), size ${LOGSIZDSP}kb)"
              fi

              if test ${LOGSIZ} -le ${LOGMAXSIZ}
              then
                if test -n "$(echo ${LOGN} | grep log$)"
                then
                  cp -p ${LOGN} ${ZIPFOLSVC}/
                else
                  #--- if .log.<n> then rename to .log.<n>.log, more easy to read on Windows hosts
                  cp -p ${LOGN} ${ZIPFOLSVC}/$(basename ${LOGN}).log
                fi
              else
                Echo " <span class=bgorange>&nbsp;SKIPPED&nbsp;</span>"
                LOG32BSKP=$(echo ${LOGN} | sed "s=\.log$=.skipped.log=g")
                LOG32BSKP=$(basename ${LOG32BSKP})
                echo "Skipped log file, size is ${LOGSIZDSP} bytes. Limit is ${LOGMAXDIS}" >${ZIPFOLSVC}/${LOG32BSKP}
              fi
              Echo "</li>"
            fi
          done
        fi
      fi
    done
  fi
  CHK=$(cat ${LOGDATTMP})
  if test ${CHK} -eq 0
  then
    Echo "No file found.<br>"
  fi
  Echo "</font>"
}

#=============================================================================
#--- HASP error log to HTML report
#=============================================================================
function hasplog_to_report
{
  #--- Note: DATMIN is defined before calling this function
  if test -s $1
  then
    Echo "<table border=1>"
    Echo "<tr><th>Date time</th><th>Pid</th><th>Message</th></tr>"
    LASTPIDLOG=0
    TRBG="bggray0"
    DATMINX=$(echo ${DATMIN} | tr -d '-')

    cat $1 | while read HASPL
    do
      DATLOG=$(echo ${HASPL} | awk '{print $1}' | tr -d "-")
      if test -z "$(echo $DATLOG | tr -d [:digit:])"
      then
        if test ${DATLOG} -ge ${DATMINX}
        then
          DATLOG=$(echo ${HASPL} | awk '{print $1,$2}')
          PIDLOG=$(echo ${HASPL} | cut -f2 -d '[' | cut -f1 -d ']')
          if test ${PIDLOG:-0} -ne ${LASTPIDLOG}
          then
            if test -n "${TRBG}"
            then
              TRBG=""
              Echo "<tr>"
            else
              TRBG="bggray0"
              Echo "<tr class=bggray0>"
            fi
          fi
          LASTPIDLOG=${PIDLOG}
          
          MSGLOG=$(echo ${HASPL} | cut -f2 -d ']')
          MSGBG=""
          if test -n "$(echo ${MSGLOG} | grep 'clone detected')"
          then
            MSGBG="textred"
            Incr_NBERR "HASP error log: ${MSGLOG}"
          fi
          if test -n "$(echo ${MSGLOG} | grep 'not valid license')"
          then
            MSGBG="textorange"
            Incr_NBWARN "HASP error log: ${MSGLOG}"
          fi
          Echo "<td><span style='font-family:monospace'>${DATLOG}</span></td>"
          Echo "<td align=center><span style='font-family:monospace;text-align:center'>${PIDLOG}</span></td>"
          Echo "<td class=${MSGBG}><span style='font-family:monospace'>${MSGLOG}</span></td>"
          Echo "</tr>"
        fi
      fi
    done
    Echo "</table>"
  else
    Echo "Empty file.<br>"
  fi
}

#=============================================================================
#--- Insert Back to Top in the HTML report
#=============================================================================
function Insert_back_to_top {
  Echo "<a href='#TOP'><p style='text-align:right;font-size:12px;'>Back to top &#9650;</p></a>"
}

#=============================================================================
#--- Generate the HTML report
#=============================================================================
function Generate_Report {
  rm -f ${ZIPFOLDER}/${HTMLFILE} 2>/dev/null
  ProgressBar

  cat >>${ZIPFOLDER}/${HTMLFILE} <<EOF1
<!DOCTYPE html>
<style type='text/css'> 
* {
  margin-left: 1px;
  margin-right: 1px;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: arial;
  margin-top: 0px; 
}
a {
  text-decoration: none;
  margin-left: -1px;
}

html {
  scroll-padding-top: 64px;
}

/* --- NAVBAR STYLING STARTS --- */
.navbar {
  height: 64px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px;
  background-color: #0A71B4;
  color: #ffffff;
  position: -webkit-sticky;
  position: sticky;
  top: 0;
}
.nav-links a {
  color: #fff;
}

/* --- LOGO --- */
.logo {
  font-family: verdana;
}

/* --- NAVBAR MENU --- */
.menu {
  display: flex;
  gap: 0.5em;
  font-family: verdana;
  font-size: 15px;
  text-align: center;
}
.menu li:hover {
  background-color: #3EA650;
  border-radius: 5px;
  transition: 0.3s ease;
}
.menu li {
  list-style: none;
  padding: 5px 10px;
}

/* --- DROPDOWN MENU --- */
.dropdownlist {
  position: relative; 
}
.dropdownlist li {
  list-style: none;
}
.dropdownlist:hover .dropdown {
  display: block;
}

.dropdown {
  background-color: #0062AB;
  padding: 1em 0;
  position: absolute; /*WITH RESPECT TO PARENT*/
  display: none;
  border-radius: 8px;
  top: 28px;
  font-size: 14px;
  font-family: verdana;
}
.dropdown li + li {
  margin-top: 6px;
  list-style: none;
}
.dropdown li {
  list-style: none;
  padding: 0.5em 0.5em;
  width: 18em;
  text-align: left;
}
.dropdown li:hover {
  background-color: #3EA650;
}

.dropdownlistsub {
  position: relative; 
}
.dropdownlistsub li {
  list-style: none;
}
.dropdownlistsub:hover .dropdownsub {
  display: block;
}

.dropdownsub {
  background-color: #3AAADC;
  padding: 1em 1em;
  position: absolute; /*WITH RESPECT TO PARENT*/
  display: none;
  border-radius: 8px;
  top: 26px;
  left: 80px;
  font-size: 12px;
  font-family: verdana;
  z-index:1;
}
.dropdownsub li + li {
  margin-top: 6px;
  list-style: none;
}
.dropdownsub li {
  list-style: none;
  padding: 0.2em 0.2em;
  width: 21em;
  text-align: left;
}
.dropdownsub li:hover {
  background-color: #0062AB;
}

table.cfglog { 
  border: 2px solid #0A71B4; 
  width: 100% 
} 
th.cfglog, td.cfglog { 
  padding: 5px; 
  border: 1px solid #0062AB; 
}

h1 {
  margin-top: 3px;
  margin-bottom: 3px;
  color: #FFFFFF;
  font-size: 20px;
  background-color: #0062AB;
  padding: 3px;
  border-style: double;
  border-color: #FFFFFF;
}
h2 {
  margin-top: 3px;
  margin-bottom: 3px;
  color: #FFFFFF;
  background-color: #3AAADC;
  font-size: 15px;
  padding: 3px;
}
h3 {
  margin-top: 2px;
  margin-bottom: 2px;
  color: #000000;
  background-color: #EDEDEE;
  font-size: 14px;
  padding: 2px;
}
h4 {
  margin-top: 2px;
  margin-bottom: 2px;
  color: #00A096;
  font-size: 13px;
}
h5 {
  margin-top: 8px;
  margin-bottom: 2px;
  color: #97BE0D;
  font-size: 12px;
}

table.logo { 
  border: 0;
  width: 100%;
} 
th.logo, td.logo { 
  border-width: 0px;
}
table.geninfo { 
  border: 0;
  color: #00A096;
  width: 20%;
} 
th.geninfo { 
  border-width: 0px;
  padding: 4px; 
  color: #00A096; 
  font-size: 13px;
}
td.geninfo, tr.geninfo { 
  border-width: 0px;
  padding: 4px; 
  color: black; 
  font-size: 15px;
}

table.noborder { 
  border: 0;
} 
td.noborder, tr.noborder { 
  border: 0;
  padding: 4px;
}

table.svcinfo { 
  border: 0;
  color: #00A096;
} 
td.svcinfo, tr.svcinfo { 
  border: 0;
  padding: 4px; 
  color: black; 
  font-size: 15px;
}
th.svcinfo { 
  border-width: 0;
  padding: 4px; 
  color: #00A096; 
  font-size: 13px;
}

table {
  border-width: 1px;
  border-style: solid;
  border-color: black;
  border-collapse: collapse;
}
th {
  border-width: 1px;
  padding: 6px;
  border-style: solid;
  border-color: black;
  background-color: #00A096;
  color: #FFFFFF;
  font-size: 14px;
}
td {
  border-width: 1px;
  padding: 6px;
  border-style: solid;
  border-color: black;
  font-size: 13px;
}

ul.charon {
  list-style: none;
  padding-left: 1em;
}
li.charon {
  font-family:monospace;
}
li.charon::before {
  content: '\27A4';
  color: #00A096;
  display: inline-block;
  width: 1em;
  margin-left: 0.5em;
  padding-right: 4;
} 

.msgok      { background-color: #3EA650; }
.msgwarn    { background-color: #F5A634; }
.msgerr     { background-color: #E95F40; }
.msgfatal   { background-color: #FF0000; }

.bgblue1    { background-color: #0A71B4; }
.bgblue2    { background-color: #0062AB; }
.bgblue3    { background-color: #3AAADC; }
.bggreen1   { background-color: #00A096; }
.bggreen2   { background-color: #3EA650; }
.bggreen3   { background-color: #97BE0D; }
.bgorange   { background-color: #F5A634; }
.bgred      { background-color: #E95F40; }
.bggray     { background-color: #3E3E40; }
.bggray0    { background-color: #F6F6F6; }
.bglightcyan { background-color: #E0FFFF; }
.bgghostwhite { background-color: #F8F8FF; }

.textwhite  { color: #FFFFFF; }
.textblack  { color: #000000; }
.textblue1  { color: #0A71B4; }
.textblue2  { color: #0062AB; }
.textblue3  { color: #3AAADC; }
.textgreen1 { color: #00A096; }
.textgreen2 { color: #3EA650; }
.textgreen3 { color: #97BE0D; }
.textorange { color: #F5A634; }
.textred    { color: #E95F40; }
.textgray   { color: #3E3E40; }
.textgray0  { color: #A0A0A0; }
</style>

<head>
	<meta charset='UTF-8' />
	<meta http-equiv='X-UA-Compatible' content='IE=edge' />
	<meta name='viewport' content='width=device-width, initial-scale=1.0' />
	<link rel='stylesheet' href='style.css' />
	<title>Charon Report</title>
</head>
	
<body style='background-color:#FFFFFF'>

<nav class=navbar>
<!-- LOGO -->
<div class=logo>
<table class=logo>
<tr class=logo>
<td class=logo valign=center>
  <a href='#TOP'>
  <img src='data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAEMAAAA4CAYAAACmL0VxAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH5gMeEwoXnPN4JwAAAAd0RVh0QXV0aG9yAKmuzEgAAAAMdEVYdERlc2NyaXB0aW9uABMJISMAAAAKdEVYdENvcHlyaWdodACsD8w6AAAADnRFWHRDcmVhdGlvbiB0aW1lADX3DwkAAAAJdEVYdFNvZnR3YXJlAF1w/zoAAAALdEVYdERpc2NsYWltZXIAt8C0jwAAAAh0RVh0V2FybmluZwDAG+aHAAAAB3RFWHRTb3VyY2UA9f+D6wAAAAh0RVh0Q29tbWVudAD2zJa/AAAABnRFWHRUaXRsZQCo7tInAAAPoElEQVRogc1ba5BdVZX+1n6dc+69/QzBdIISyQMZGZzK+ChEoIGh1NLBGaIBEdIQIWZ8AEJAoQiCAQXCQ0FRHoZMwiNkdBytQmQGMCgK1oAyDM5gCEkgk27SkPTrPs5j773mR5OQx72de5ruKr+q++eetfde5ztrrb3WOvsQM2MyMWfVhveNbOq7uLp9qKaVJsDnGC3giRVL1JJAX1O74eS+SVMUAE0mGbPXvnSYlOHauJx+YOi5jSAHkBTNT8AMZueoVJDeZ+tcUl488p1/GJosfXNolg9H/nzTwSSilRSVPhC2hmh9zwwHwRlnKeCyA/wsYFPP3lY5VA5gyKBlgTbF79KyZTRZOk8KGX/90KvtSYVul2HheF8tg51FdHC7bJ0zTRDBsz+ANTKDCSkHSgspDbwDZzVAhz3tSfeKySJkUsiIK/RtWWqb7+MywB5ggJ1H2NWJ0qzplohcQ/dkvEmE1kIrjV1y3gHeQWhzcVty7AWTofeEkkHLQHMe2HSDkGqJj6vAnjfMDGaS0SGdyszoiJnZ1p+EPRvFQkuJfQnzDswMIfR1nZc+et5E6g5MMBlz3vvKxcKEl4B59EnuC+8BEqJ19oxATeuMbeYsYZfFExiw3siMtNRo5EkuAykdQJlr27/+2CcnUv8JI2PO/Vv+iZT+JkBglzWUY+9BglT7nK5ITm1NrHUWIIDZspIJaa0INKZenMUgIacKppVtSx89fqLuYUK21llrt3xMKn0vKTOFk2pTY4QUsGnmdr7wauYHqyEFCqJQAITAfu7RABQU4WpDryDLTh9Y8XdPv517ACaAjLlrN32EdLiOlO7ycXNE7IJQClk1xeALW553WdortDTghg5SBwRSJvQu/T1CeeXA1d2VnOrvBfV2Bs/5ly3vI6F/RDro8rURAPl2PAqKkNY9Zua+Y1H1uVcGrJGUbwoGV3eQL0zRVXSmuRavp894LWPmfZvfZZR4SBRajvTVkdzjRViEj6u/A/HnNiw4dMu4lJhgjCuAzl23dbqR4h4RFo70tXL+RaMSfFrbAOcX/aUQAYzDTWas2xoWnf2hKLWd6GuVpoPdLoiwAB9XX/FJcvbGs2b/uZ7Mn/50RHEYZEwU1tmfx4YcdlTTkfjF2pMHly9fnku5XG5y2L0vtUipb5NRoYezFFwvlxhrMROCbbYT3p654bSZD9eTueq3J3e9O6jdenjrcKcEwJQnoAKeiYq6pqcGO34xbfqO6/KMzWUZUqqvyWKpxydx/aRqDJAJ4W1aJu++2IiI76w/vq3FqNsqQXF+X+owq6UCqQUOVMrsAoNgE4uuthGE5D7Y39fee3DX4OqmdWzWMuasfflSIYNvQ5BgWz+TbgipABIZsvTyDacfemM9kVPXnSo+3LVzZdSqe+KaBzz7OS1lOyOqCs9CHUhLBnkBH3cV3qCirgbGCGEdj1RTeU5X146fNKNmUwF07rrNC4UuXA2lx0GEhNAB2KXfbEQELSM6esbAch2pnjT2gGd4kNg40mL6qhGkGLshxCAAbKeGO0XJVCPPQsQJYIxoibS/beD1jo80o+oByTh87cYFIH07iEJO42bm3GN2CaEMfDxy+8b/PvTaRmIrTj7ha2FBXc6e4R2/qRjDMePlSon64zCTor5tvEXEALUFldD5t26pWmUEAbqY+cGhvrZ5B1R3rItzHtx6rFfhTaSDImfJgebaG0SQUQk+je8tzXr3Bby8fiBc8dvuJTLAVd4xnN1bRBCQeiE3DLeIoVRniva1EAIzfGcwhI5gRDPvn7FVq0CxKKY7Ie7Ytq04ZyyVG5Jx+AOv/i3B3yd1eEiz9cZbOhJEWIQtDzxklbnoD+9HXd+66Tfdn5JS3iylCGxa3xUEMWIv5EvlIkasyiS9RZhn+I5g2HaYYWKg4bZTrjBaWun9odJ39/cf9I5GatclY+7qLe9hSXeKqPROH+dN92k0qYorT3m4JZtOnfZ6PakVT3afREb8UGkRZQ2I2AVJjMHU6D+PtCLxIpWC4T35kqrWpgRDQgqW9axiNxgolxmlkjhOwd0+sKm1tZ7YfmQc/tNtnTC0UoSFefmJAEQYwVVGnrdZtvjl02f/Xz2Z6x4/8SipxG0mkNOypLktWr1JyIvDrSJ2EiVTS6cVd2gpvPJjEfEmvB+NIaUSTnWRvOWZZ2i/tGIvMmb+22CbT92dIioevV+nqglQEMEncZ8X/IVNn5v1Qj2ZG544fraOeHUQqSOSar5cRZLHThepV8vRpqnhziQKnHG++cpulBCgUKBFMw9pv37f67vJmHfHM8rEgytksXW+T2ujvcscEEEBnMSDDu6clxfMrNtb+NbDHzlIBep7UVG/L67m3KIBhEUJtvaljSOdnyiZ6oXOSxuG+eZwDrCOEYa4qH9b29K97gEAjvvVr2S5bcoNFBTO41p5lMIcIG3AzlUY/KWXF8x8pJ7MVc/+fRS06h8FBfnRuGIbR7sGCCKJNPGbAbFw2fEPvVicUl2Vxu4aAFA5K6wsG33WYSSu2dHb/uVd/wsA6Nt+xMUiaPsqWAAsQcI09yMD0gWwtc6ltQtfOu3Q++stfscz81RrVvmuidQpSdXm8j5mwIQSaeIGkzj78iXHPLrb6h5/cnh5XMXNJgCU8RCq+Z9lDxNwQIZX9O+I5gMAvevBX5+puPB9Iik4b+XFLIUppJTqWzecPvvqRmI3PnnijVGLujiN3e6kqlmoQMB7DPnMLrn4w+vX7nu9FxSF2zu/p7w5zaZwlKOwYwBKQbtEDMo4OlXB9yHhYWJJueMEMYPZgGEBzK4rc9NTJ1ymjDg/S/ITIRXBO/Yu46uWHrM/EQDQddN8TmcMgCI7mrTlfL0kJShjl1FH6oiZ0fXA3RdKo29holGHyjOjFCAi5xN7Ue8Zn791z0srftvdI6W8SyrSNvG5phWSIBUhqfllw4/86trly+s417pTRbW245pCZC5zKedzPwBaC6SpH+ZUnR2c+8uf7q5ap9939/WiEF7KWTaOAKoARoUz+5Vtn/38PQBw42+655tI3QWijmZzid3zCYI2hLjq7nqqd/2Sf11Q32Qrq7uvCAO1nDwjy2l1Rgk4z2ni3BeKZ61fBeyxtfZt2HoF12rfJWNG2/U5wJkFhCiywK1TVj940qrff+hDQtAPhKKOLM5LBBAUJJLY3ytk7fxGRFT/+fjzQi2vIGBcRFjHSC0u3UUEsE8/o+3he1tKw8k9FIbzOU5yJl0Mrwoocn9vz7SHfWchOyTOWdsBQFCUSKr2kcRmZ15+7JNv1JOpreo+U2lxl1YiTLJ8ViwFQRmBatVdX1j4+Nf3vLaXCQx9/MwRNnqxr9b+Q4QhQM07OUNB+aE0VJumvlhrOThNkIicwSwqKcRl+3ufcE8jIuLV3SeZQN6stRwHEYAKJJKavbXwV4NX7Ht9P3/o/ceFO7PULfG12rMUBE0twpAQSLJO8z9ZJIfl/8Yd5o/lTieYE0HNWVdQkEhq7nn47JxLutdvrydTW3Pc0UKK+6USU5M0p/sRQRmJtGZ/3B/Uvob3/2G/FLhh22/GgyuPAuNnIgxm+rhxU4chQUiz9uCltKheD5mlHH1ehHnFHemR0U7hSKiGVSUDpiCRxq5XeH/KV49Z/2w9sXRN93uJxP06lEcleeMQASZSSKr2340f+Swt/M+d9eQaRsptpy163nnb49J0a2MLESA412Y2u5LsjwAp95z0uUqneTHugHqzH1UPJpLIUvcaeZzbiIjaPR89xEOs1JE6Ks1JBACYQCKu2Gc4FUsaEbGn3nXx2hmLf40k+wpbWyGtsXdBQfBgV9JbXEm/FjKk2NPIBBgOhOcqnbQ1bkml8PsRorSAsz5xKS296JjH63bMh1d/oFOa7AdhQX0wjW3ekgZBKJHGdotz/txw0aObx5I94B7ae9bin7Gz54FRIWPe/JfgIVDQ22yr3qpGX27s/+wlGDEL+bvyQeK1pFhT5HcX3FILMHNmM1xwybGP3Vd38VXHBQal20ykPpnF+WoaAAgCCZe6V1zmzyqevf6/DiTfVELRe/q5D/g0uYqd91AKHgKR6s069WZBINHYCQAFRpWVenrkILEjjWIJ74UkEAGZ5W8tPeaxO+qPXEaJkjeHkTrD1lzT7052ITACaebK1vkLonOeeLKZMbneqE1/4EdXiyi6MqQ+dOgXoTTBs0Az9XgGiSm+hu7WPkwpWlSr/qaLjn58aSP52uoTlkWR+qazHjZHUsUAjBZgRi1N/eJo4eP3Njs2VyfAW3O9Sd/oKJnNf0M2ybJMM6G5gCZgsZ0VPUdtap7f8WJrh/9GI9lkzQmXaE1X+pxEAKPZpWc4l9ll0cL1TRMBjONIwrxn5im59b2triXK36oC8Odeow4aFOVXzr+17nmK2poTzhBEqwItdJ6kigFoSZBSoFKz3yhuXL8c9Yq7MTCpJ4TzIlnT/Smh5D1aUMe40mxFSFK3st/UvvTOBU/nfOP1F0RGbc2JRwvgx0Eopyc5q1xBgA4V4lr2kzDgHnxm/biOM72tY0wAsPXTnw6DUrWtypV4ZqAZ6Gh67AAGQP0lCj8xPE8W+E4TqOm5s0sA2kgkVftooMQX8ZnHxn2u622T0dlZbnegW9pU6/RhazNQ8yd5JAeMqRXh+pJZZlZwaJbTNQDAFBTiiv2j99RDn32sP/cEe+Dtu8kyoqH+j83XQqwuBCZymW2uo8UETx4cDCLlBDRFVeShYSgEyWa7j0GkkKX2T+zd6eZzT9R9T5MHExYzBs/7+CItxfeVoDB2+6feey0KAsM7ikZi0nEgWCjn2Yp36EQdEgYEqLHUYgbCSCKJ3eteuFOiM55422dAgQk8Idx+18MrM+8vc+xtMMY3JaNEsBVhuQYdBwShPABBpHh7Ztz2JGOCH6uVEoYSNvN91rueiSICmOCz4+13PvydzPJNAqNbXT14ZkdBOWEdhwJitwUwAUSkXW8WuP7UNTKtQAukmU+TzF1ZXPhE3eJuvJjwTyxunPbLy2LL3ysqBbHH4yUQwOTJVDMytUAQ7ecKTAB5CLctlXYocyT3ZkRLgmN2nPlLigvX3z3Ruk9KnvHGolNKRtmVLYH6TCWz8AwwkxemliEoayFYjHmEwLNnRVYfFgrRrhVbhhIEKQlxZq8Pz1z/9caDx49J+fjmoJU/L6d2cFEls4+UAj1qFTrxCCskBcYmAgAJEmRh7JY482Wbai0gjUCSudtC03n5ZOgMTHIGOtTz8cMQ0JqWgv9wrAegclBPANgBacC2OLekMkPrqold3H72E5P2wd6kp+M7lpx0RBAlS71KvOAGp9TGgodGp+wvzm25jhY8MjAJKu7G/wNk4qRBbhvLOgAAAABJRU5ErkJggg==' alt='Stromasys - Midrange System Emulation'/>
  </a>
</td>
<td class=logo style='font-size: 30px;padding-right:30px'>
Charon Report
</td>
<td class=logo style='font-size: 14px;font-family: arial;'>
Company name: ${CUSTOMERNAME}<br>
EOF1

  ProgressBar
  case "${REPORTTYPE}"
  in
    "Ticket")
      Echo "Ticket number"
      ;;
    "Opportunity")
      Echo "Opportunity reference"
      ;;
    "Project")
      Echo "Project number"
      ;;
    *)
      Echo "Other"
      ;;
  esac
  Echo ":&nbsp;<span style='font-family:monospace'>${REPORTNUMB:-None}</span><br>"

  HWMANUF=$(cat /sys/devices/virtual/dmi/id/sys_vendor)
  HWMODEL=$(cat /sys/devices/virtual/dmi/id/product_name)
  UUID=$(cat /sys/class/dmi/id/product_serial 2>/dev/null)

  cat >>${ZIPFOLDER}/${HTMLFILE} <<EOF1a
Log files since:&nbsp;${LOGSETDAT}
</td>
</tr>
</table>
</div>
<!-- NAVIGATION MENU -->
<ul class='nav-links'>
  <!-- NAVIGATION MENUS -->
  <div class=menu>

	  <li class=dropdownlist>
	  	<a href='#Server_configuration'>Server configuration</a>
		  <ul class=dropdown>
        <li><a href='#Hostname'>Hostname</a></li>
        <li><a href='#Operating system'>Operating system</a></li>
        <li><a href='#CPU'>CPU details</a></li>
        <li><a href='#Memory'>Memory</a></li>
        <li><a href='#Storage'>Storage</a></li>
        <li><a href='#Network'>Network</a></li>
        <li><a href='#USB'>USB devices</a></li>
EOF1a

  systemctl -q is-enabled ${SEHUTNSERVICE} 2>/dev/null
  if test $? -eq 0 -o -x /usr/sbin/utnservice
  then
    Echo "        <li><a href='#SEHUTN'>SEH UTN service information</a></li>"
  fi

  Echo "        <li><a href='#NTP'>Time service settings</a></li>"

  if test -n "$(echo ${HWMANUF} | grep -w VMware)" && test -n "$(echo ${HWMODEL} | grep VMware)"
  then
    Echo "        <li><a href='#VMware'>VMware settings</a></li>"
  fi

  cat >>${ZIPFOLDER}/${HTMLFILE} <<EOF1b
        <li><a href='#path'>PATH</a></li>
        <li><a href='#Linux_updates'>Linux updates</a></li>
        <li><a href='#Linux_RebootHistory'>Linux shutdown and reboot history</a></li>
        <li><a href='#OOM'>Out of Memory Killer settings</a></li>
      </ul>
		</li>

		<li class=dropdownlist>
			<a href='#Charon_configuration'>Charon configuration</a>
			<ul class=dropdown>
EOF1b

  grep -e ^charon\- -e ^hpa\- -q ${TMPRPMFILE}
  if test $? -eq 0
  then
    Echo "        <li><a href='#Packages_Installed'>Packages installed</a></li>"
    grep -e ^charon-axp -e ^charon-vax -q ${TMPRPMFILE}
    if test $? -eq 0
    then
      #------ Charon-AXP or Charon-VAX installed
      if test ${OUTOFLTK} = 1
      then
        Echo "        <li><a href='#Toolkit'>Charon Toolkit</a></li>"
      else
        Echo "        <li class=dropdownlistsub>"
        Echo "          <a href='#Toolkit'>Charon Toolkit</a>"
        Echo "          <ul class=dropdownsub>"
        Echo "            <li><a href='#Toolkit_1'>Kit contents and versions</a></li>"
        Echo "            <li><a href='#Toolkit_2'>Configuration files</a></li>"
        Echo "            <li><a href='#Toolkit_3'>Scheduled jobs (cron)</a></li>"
        Echo "            <li><a href='#Toolkit_4'>Running processes (grep charon)</a></li>"
        Echo "            <li><a href='#Toolkit_5'>Virtual machines list and status (vmlist)</a></li>"
        Echo "            <li><a href='#Toolkit_6'>Services details</a></li>"
        Echo "          </ul>"
        Echo "        </li>"
      fi
      Echo "        <li><a href='#ncu_configuration'>ncu configuration</a></li>"
      Echo "        <li><a href='#axpvax-agentd'>Charon Agent for AXP/VAX</a></li>"
    fi
    grep -e ^charon-par -e ^hpa\- -q ${TMPRPMFILE}
    if test $? -eq 0
    then
      #------ Charon-PAR installed
      if test ${OUTOFLTK} = 1
      then
        Echo "        <li><a href='#Toolkit'>Charon Toolkit</a></li>"
      else
        Echo "        <li class=dropdownlistsub>"
        Echo "          <a href='#Toolkit'>Charon Toolkit</a>"
        Echo "          <ul class=dropdownsub>"
        Echo "            <li><a href='#Toolkit_1'>Kit contents and versions</a></li>"
        Echo "            <li><a href='#Toolkit_2'>Configuration files</a></li>"
        Echo "            <li><a href='#Toolkit_3'>Scheduled jobs (cron)</a></li>"
        Echo "            <li><a href='#Toolkit_4'>Running processes (grep charon)</a></li>"
        Echo "            <li><a href='#Toolkit_5'>Virtual machines list and status (vmlist)</a></li>"
        Echo "            <li><a href='#Toolkit_6'>Services details</a></li>"
        Echo "          </ul>"
        Echo "        </li>"
      fi
    fi
    grep ^charon-ssp -q ${TMPRPMFILE}
    if test $? -eq 0
    then
      #------ Charon-SSP installed
      Echo "        <li><a href='#ssp-agentd'>Charon Agent for SSP</a></li>"
    fi
  fi

  rpm -q aksusbd >/dev/null
  if test $? -eq 0
  then
    Echo "        <li class=dropdownlistsub>"
    Echo "          <a href='#HASP_licsettings'>HASP license settings</a>"
    Echo "          <ul class=dropdownsub>"
    Echo "            <li><a href='#aksusbd_service'>aksusbd service</a></li>"
    systemctl -q is-enabled hasplmd 2>/dev/null
    test $? -eq 0 && Echo "        <li><a href='#hasplmd_service'>hasplmd service</a></li>"
    Echo "        <li><a href='#HASP_runtime'>Sentinel HASP Run-Time environment</a></li>"
    if test -n "$(grep -w "aksusbd.service" ${TMPSVCLIST} | grep -vw 'not-found')"
    then
      Echo "        <li><a href='#SACC'>Sentinel Admin Control Center settings</a></li>"
    fi
    Echo "          </ul>"
    Echo "        </li>"
  fi

  rpm -q license-server >/dev/null
  if test $? -eq 0
  then
    Echo "        <li class=dropdownlistsub>"
    Echo "          <a href='#VE_licsettings'>VE license settings</a>"
    Echo "          <ul class=dropdownsub>"
    Echo "            <li><a href='#licensed_service'>VE License server ('licensed' service)</a></li>"
    for ITEM in "Actual status of license server;s" "Registered clients (AutoVE only);r" "Connected clients;c" "License utilisation;u"
    do
      VEwhat=$(echo $ITEM | cut -f1 -d';')
      VEchap=$(echo $VEwhat | tr " " "_" | tr -d "()")
      Echo "            <li><a href='#${VEchap}'>${VEwhat}</a></li>"
    done
    Echo "            <li><a href='#VElicense_log'>License server log file</a></li>"
    Echo "            <li><a href='#VElicense_cfg'>License server configuration file</a></li>"
    Echo "          </ul>"
    Echo "        </li>"
  fi

  cat >>${ZIPFOLDER}/${HTMLFILE} <<EOF1c
			</ul>
		</li>

	  <li class=dropdownlist>
			<a href='#License'>License</a>
		  <ul class=dropdown>
        <li><a href='#Charon_license'>License content</a></li>
        <li><a href='#Software_license'>Software license files list</a></li>
			</ul>
		</li>

		<li class=dropdownlist>
			<a href='#Charon_services'>Charon virtual machines</a>
			<ul class=dropdown>
EOF1c

  #-------------------------------------------------------------
  # CHARON SERVICES
  #-------------------------------------------------------------
  grep -e ^charon-axp -e ^charon-vax -q ${TMPRPMFILE}
  if test $? -eq 0
  then
    #------ Charon-AXP or Charon-VAX installed
    Echo "<!-- DEF:charon_axpvax_services -->"
  fi

  grep -e ^charon-par -e ^hpa\- -q ${TMPRPMFILE}
  if test $? -eq 0
  then
    #------ Charon-PAR or hppa installed
    Echo "<!-- DEF:charon_par_services -->"
  fi

  grep ^charon-ssp -q ${TMPRPMFILE}
  if test $? -eq 0
  then
    #------ Charon-SSP installed
    Echo "<!-- DEF:charon_ssp_services -->"
  fi

  cat >>${ZIPFOLDER}/${HTMLFILE} <<EOF1d

			</ul>
		</li>

		<li>
			<a href='#Results'>Results</a>
		</li>
	</div>
</ul>
</nav>

<a name='top'></a>
<span class=textblue2>Created on:</span>&nbsp;
$(date +'%d-%b-%Y %H:%M:%S')
EOF1d

	if test ${SHORTVERSION} -eq 1
	then
		Echo "<br><br><span class=textorange>${ICOWARNING} <b>Short version requested by user</b></span><br>"
	fi

	if test ${DODISCOVERY} -eq 0
	then
		Echo "<br><br><span class=textorange>${ICOWARNING} <b>Charon virtual machines (emulators) automatic discovery has been disabled by user</b></span><br>"
	fi

  Echo "<a name='Server_configuration'></a>"

  #-------------------------------------------------------------
  # Hostname
  #-------------------------------------------------------------
  Echo "<br><a name='Hostname'></a>"
  Echo "<h1>Hostname</h1>"
  if test -x /usr/bin/hostnamectl
  then
    Echo "<table class=noborder>"
    Echo "<font style='font-family:monospace;'>"
    hostnamectl | while read LINE
    do
      LPAR=$(echo ${LINE} | cut -f1 -d':')
      LVAL=$(echo ${LINE} | sed "s=${LPAR}:==g")
      LVAL=$(echo ${LVAL})
      Echo "<tr class=noborder>"
      Echo "<td class=noborder>${LPAR}:</td><td class=noborder style='color:#0A71B4'>${LVAL}</td>"
      Echo "</tr>"
    done
    if test ${SHORTVERSION} -eq 0
    then
      Echo "<tr class=noborder>"
      Echo "<td class=noborder>UUID:</td><td class=noborder style='color:#0A71B4'>${UUID:-Unknown}</td>"
      Echo "</tr>"
    fi
    Echo "</font></table>"
  else
    Echo "<span style='font-family:monospace'>$(hostname)<br><br>"
    if test ${SHORTVERSION} -eq 0
    then
      Echo "UUID: <span class=textblue1>${UUID:-Unknown}</span></span><br>"
    fi
  fi

  #-------------------------------------------------------------
  # OPERATING SYSTEM
  #-------------------------------------------------------------
  ProgressBar begin "Gathering operating system details"
  UPT1=$(uptime)
  UPTS=$(uptime -s)
  UPT2=$(date -d "${UPTS}" +"%A %d-%b-%Y %H:%M:%S")
  ENFORCECUR=$(/usr/sbin/getenforce 2>/dev/null)
  ENFORCECFG=$(grep ^SELINUX= /etc/selinux/config 2>/dev/null | cut -f2 -d '=')
  ENFORCETYP=$(grep ^SELINUXTYPE= /etc/selinux/config 2>/dev/null | cut -f2 -d '=')

  Echo "<br>"
  Echo "<a name='Operating system'></a>"
  Echo "<h1>Operating system</h1>"
  Echo "<h2>General settings</h2>"
  Echo "<table class=noborder>"
  Echo "<font style='font-family:monospace;'>"

  Echo "<tr class=noborder>"
  Echo "<td class=noborder>System release:</td><td class=noborder style='color:#0A71B4'>$(cat /etc/system-release)</td>"
  Echo "</tr>"

  Echo "<tr class=noborder>"
  Echo "<td class=noborder>uname -a:</td><td class=noborder style='color:#0A71B4'>$(uname -a)</td>"
  Echo "</tr>"

  Echo "<tr class=noborder>"
  Echo "<td class=noborder>System-locale:</td><td class=noborder style='color:#0A71B4'>${LANGORI}</td>"
  Echo "</tr>"

  CURDAT=$(date +"%d-%b-%Y %H:%M:%S")
  Echo "<tr class=noborder>"
  Echo "<td class=noborder>Date/time:</td><td class=noborder style='color:#0A71B4'>${CURDAT}</td>"
  Echo "</tr>"

  Echo "<tr class=noborder>"
  Echo "<td class=noborder>Uptime:</td><td class=noborder style='color:#0A71B4'>${UPT1}</td>"
  Echo "</tr>"

  Echo "<tr class=noborder>"
  Echo "<td class=noborder>Booted:</td><td class=noborder style='color:#0A71B4'>${UPT2}</td>"
  Echo "</tr>"

  Echo "</font></table>"

  Echo "<br>"
  Echo "<h2>SElinux</h2>"
  Echo "<font style='font-family:monospace;'>"
  Echo "Current (getenforce): <span class=textblue1>${ENFORCECUR:-Unknown}</span><br>"
  Echo "<u>Configuration</u>:<br>"
  Echo "&nbsp;&nbsp;SELINUX: <span class=textblue1>${ENFORCECFG:-Not defined}</span><br>"
  Echo "&nbsp;&nbsp;SELINUXTYPE: <span class=textblue1>${ENFORCETYP:-Not defined}</span><br>"
  Echo "</font><br>"
  Echo "<h2>User interface</h2>"
  Echo "<font style='font-family:monospace;'>"

  ISTHEREGUI=$(ls /usr/share/xsessions 2>/dev/null)
  if test -n "${ISTHEREGUI}"
  then
    Echo "Current desktop: <span class=textblue1>${XDG_CURRENT_DESKTOP:-CUI}</span><br>"
  else
    Echo "No graphical user interface installed on this server<br>"
  fi
  Echo "</font>"
  Insert_back_to_top

  #-------------------------------------------------------------
  # HARDWARE
  #-------------------------------------------------------------
  ProgressBar begin "Gathering hardware details"

  Echo "<a name='CPU'></a>"
  Echo "<h1>CPU details</h1>"
  Echo "<font style='font-family:monospace;'>"
  Echo "Product Name : <span class=textblue1>${HWMODEL}</span><br>"
  Echo "System Vendor : <span class=textblue1>${HWMANUF}</span><br>"

  #------ CPU details
  ProgressBar
  NPROC=$(grep ^processor /proc/cpuinfo | wc -l)
  Echo "Number of processors : <span class=textblue1>${NPROC}</span><br>"

  PHYCORE=$(egrep "core id|physical id" /proc/cpuinfo | tr -d "\n" | sed s/physical/\nphysical/g | grep -v ^$ | sort | uniq | wc -l)
  Echo "Number of physical cores: <span class=textblue1>${PHYCORE}</span><br>"

  PHYCOR2=$(( ${PHYCORE} * 2 ))
  #if test -z "$(echo "$PHYCORE *2" | bc | grep -w $NPROC)"
  if test -z "$(echo ${PHYCOR2} | grep -w $NPROC)"
  then
    Echo "Hyperthreading: <span class=textblue1>Disabled</span>"
    if test -x /usr/sbin/dmidecode
    then
      if test -z "$(dmidecode -t processor | grep HTT)"
      then
        Echo "&nbsp;(not possible on this server)"
      else
        Echo "&nbsp;(this server is HT capable)"
      fi
    else
      Echo "&nbsp;('dmidecode' is not installed on this server)"
    fi
  else
    Echo "Hyperthreading: <span class=textblue1>Enabled</span>"
  fi
  Echo "</font>"
  Echo "<br><br>"

  Echo "<table border=1>"
  Echo "<tr>"
  Echo "<th>Processor</th><th>Vendor Id</th><th>Model name</th><th>CPU Mhz</th>"
  Echo "<th>Node</th><th>Socket</th><th>Core</th><th>L1d:L1i:L2:L3</th><th>Online</th>"
  Echo "</tr>"
  N=0
  PN=0
  grep -i -e ^Vendor_id -e ^processor -e "^CPU Mhz" -e "^Model name" -e ^$ /proc/cpuinfo | while read LINE
  do
    ProgressBar
    ITEMP=$(echo ${LINE} | awk -F':' '{print $1}' | tr -dc [:alpha:] | tr [:upper:] [:lower:])
    ITEMP=$(echo ${ITEMP})
    ITEMV=$(echo ${LINE} | awk -F':' '{print $2}')
    ITEMV=$(echo ${ITEMV})

    case "${ITEMP}"
    in
      "processor")
        if test $N -eq 1
        then
          N=0
          Echo "<tr class=bggray0>"
        else
          N=1
          Echo "<tr>"
        fi
        Echo "<td align=center>${ITEMV}</td>"
        PN=${ITEMV}
        ;;
      "cpumhz")
        Echo "<td align=right>${ITEMV}</td>"
        ;;
      "")
        LSCPU=$(lscpu -p=cpu,node,socket,core,cache,online | grep "^${PN},")
        #---Node
        Echo "<td align=right>$(echo ${LSCPU} | cut -f2 -d',')</td>"
        #---Socket
        Echo "<td align=right>$(echo ${LSCPU} | cut -f3 -d',')</td>"
        #---Core
        Echo "<td align=right>$(echo ${LSCPU} | cut -f4 -d',')</td>"
        #---Cache L1d:L1i:L2:L3
        Echo "<td align=center>$(echo ${LSCPU} | cut -f5 -d',')</td>"
        #---Online
        Echo "<td align=center>$(echo ${LSCPU} | cut -f6 -d',')</td>"
        Echo "</tr>"
        ;;
      *)
        Echo "<td align=left>${ITEMV}</td>"
        ;;
    esac
  done
  Echo "</table>"
  Echo "<br>"

  #------ Memory
  ProgressBar
  Echo "<br><a name='Memory'></a><h1>Memory</h1>"
  Echo "<font style='font-family:monospace;'>"
  Echo "<h2>Details</h2>"
  /usr/bin/free | sed "s= =\&nbsp;=g" | while read LINE
  do
    if test -n "$(echo ${LINE} | grep ';total')"
    then
      Echo "<b>${LINE}</b><br>"
    else
      Echo "${LINE}<br>"
    fi
  done
  Echo "</font>"

  if test -x /usr/sbin/dmidecode
  then
    Echo "<table>"
    Echo "<tr><th>Banklabel</th><th>Capacity</th><th>Clock speed</th></tr>"
    /usr/sbin/dmidecode -t memory | grep -e 'Size:' -e 'Bank Locator:' -e 'Speed:' | while read LINE
    do
      ProgressBar
      MPAR=$(echo ${LINE} | awk -F':' '{print $1}')
      MVAL=$(echo ${LINE} | awk -F':' '{print $2}')
      case "${MPAR}"
      in
        "Size")
          DIMMSIZE=${MVAL}
          ;;
        "Bank Locator")
          DIMMNAME=${MVAL}
          ;;
        "Speed")
          DIMMSPEE=${MVAL}
          if test -z "$(echo ${DIMMSIZE} | grep 'No Module Installed')"
          then
            Echo "<tr>"
            Echo "<td>${DIMMNAME}</td>"
            Echo "<td align=right>${DIMMSIZE}</td>"
            Echo "<td>${DIMMSPEE}</td>"
            Echo "</tr>"
          fi
          ;;
      esac
    done
    Echo "</table>"
  fi

  ProgressBar
  Echo "<br><h2>NUMA balancing</h2>"
  Echo "<font style='font-family:monospace;'>"

  NUMAB=$(cat /proc/sys/kernel/numa_balancing 2>/dev/null)
  Echo "Running configuration (/proc/sys/kernel/numa_balancing): "
  case "${NUMAB}"
  in
    0)
      Echo "<span class=textblue1>OFF</span>"
      ;;
    1)
      grep -e ^charon-par -e ^hpa\- -q ${TMPRPMFILE} 2>/dev/null
      if test $? -eq 0
      then
        #--- Charon-PAR: NUMA balancing must be OFF
        Incr_NBERR "NUMA balancing is ON (running configuration). Must be OFF for Charon-PAR"
        Echo "<span class=textred>ON</span>"
      else
        Echo "<span class=textblue1>ON</span>"
      fi
      ;;
    *)
      Echo "<span class=textorange>Unknown value '${NUMAB}'</span>"
      ;;
  esac
  Echo "<br>"

  NUMARES=$(grep kernel.numa_balancing /etc/sysctl.conf /etc/sysctl.d/*.conf 2>/dev/null | tail -1)
  NUMAB=$(echo ${NUMARES} | cut -f2 -d'=')
  NUMAF=$(echo ${NUMARES} | cut -f1 -d':')
  if test -z "${NUMAF}"
  then
    Echo "Permanent configuration: "
  else
    Echo "Permanent configuration (${NUMAF}): "
  fi
  case "${NUMAB}"
  in
    0)
      Echo "<span class=textblue1>OFF</span>"
      ;;
    1)
      grep -e ^charon-par -e ^hpa\- -q ${TMPRPMFILE} 2>/dev/null
      if test $? -eq 0
      then
        #--- Charon-PAR: NUMA balancing must be OFF
        Incr_NBERR "NUMA balancing is ON (permanent configuration). Must be OFF for Charon-PAR"
        Echo "<span class=textred>ON</span>"
      else
        Echo "<span class=textblue1>ON</span>"
      fi
      ;;
    "")
      Echo "<span class=textblue1>Not set</span> (not in /etc/sysctl.conf nor in /etc/sysctl.d/ folder)"
      ;;
    *)
      Echo "<span class=textorange>Unknown value '${NUMAB}'</span>"
      ;;
  esac
  Echo "<br>"

  NUMAG=$(grep -w numa /etc/default/grub 2>/dev/null)
  if test -n "${NUMAG}"
  then
    NUMAV1=$(echo ${NUMAG} | sed "s:\(^.numa=\)\(.*$\):\2:g" | awk '{print $1}')
    NUMAV2=$(echo ${NUMAG} | sed "s:\(^.numa_balancing=\)\(.*$\):\2:g" | awk '{print $1}')
  else
    NUMAV1="(not set)"
    NUMAV2="(not set)"
  fi
  Echo "Boot loader (/etc/default/grub): numa=<span class=textblue1>${NUMAV1}</span>&nbsp;numa_balancing=<span class=textblue1>${NUMAV2}</span>&nbsp;<br>"
  Echo "<br>"
  Echo "<span class=textgray><b>Note</b>: if 'grub' and 'sysctl' methods are used at the same time, the 'systctl' has higher priority on 'grub'.</span><br>"
  Echo "</font>"
  Insert_back_to_top

  Echo "<h2>Top 20 processes consuming memory</h2>"
  ProgressBar
  Echo "<font style='font-family:monospace;'>"
  if test ${SHORTVERSION} -eq 0
  then
    TRBG="bggray0"
    Echo "<table border=1 width=100%>"
    Echo "<tr><th>Pid</th><th>State</th><th>User</th><th>Started</th><th>%memory</th><th>%CPU</th><th>tty</th><th>unit</th><th>command</th></tr>"
    # ps -o pid,state,user:20,start_time,%mem,%cpu,tty,unit,command ahx | sort -b -k5 -n -r | head -20 | awk '{OFS=";";print $1,$2,$3,$4,$5,$6,$7,$8,$9}' | while read LINE
    ps -o pid,state,user:20,start_time,%mem,%cpu,tty,unit ahx | sort -b -k5 -n -r | head -20 | awk '{OFS=";";print $1,$2,$3,$4,$5,$6,$7,$8}' | while read LINE
    do
      if test -n "${TRBG}"
      then
        TRBG=""
        Echo "<tr>"
      else
        TRBG="bggray0"
        Echo "<tr class=bggray0>"
      fi
      for I in 1r 2c 3l 4l 5r 6r 7l 8l
      do
        ITM=$(echo $I | tr -dc [:digit:])
        case "$(echo $I | tr -d [:digit:])"
        in
          c)  ALI="center";;
          r)  ALI="right";;
          *)  ALI="left";;
        esac
        Echo "<td align=${ALI}>$(echo ${LINE} | cut -f${ITM} -d';')</td>"
      done
      ITMPID=$(echo ${LINE} | cut -f1 -d';')
      ITMCMD=$(ps -p ${ITMPID} -h -o command)
      Echo "<td align=left style='word-break:break-all;'>${ITMCMD}</td>"
      Echo "</tr>"
    done
    Echo "</table>"
  else
    Echo "<span class=textorange>Information not available (short version)</span><br>"
  fi
  Echo "</font>"
  Insert_back_to_top


  #------ Storage
  ProgressBar begin "Gathering storage details"

  Echo "<a name='Storage'></a><h1>Storage</h1>"
  Echo "<br><h2>Block devices</h2>"
  Echo "<font style='font-family:monospace;'>"
  Echo "<b>"
  Echo $(lsblk -ifp | head -1 | sed -e "s= =\&nbsp;=g")
  Echo "</b><br>"
  lsblk -ifnp | sed -e "s= =\&nbsp;=g" | sed \
    -e "s=|-=\&#9500;\&#9472;=g" \
    -e "s=\`-=\&#9492;\&#9472;=g" | sed "s=$=<br>=g" | while read LSB
  do
    ProgressBar
    if test -n "$(echo ${LSB} | grep /dev/loop)"
    then
      Echo "<span class=textgray>${LSB}</span>"
    else
      Echo "${LSB}"
    fi
  done
  Echo "</font>"

  Echo "<br><h2>SCSI devices (lsscsi)</h2>"
  Echo "<font style='font-family:monospace;'>"
  lsscsi -g -s -l | sed -e "s= =\&nbsp;=g" | while read LSB
  do
    ProgressBar
    if test -n "$(echo ${LSB} | grep ';state=')"
    then
      Echo "<span class=textgray>${LSB}</span><br>"
    else
      Echo "${LSB}<br>"
    fi
  done
  Echo "</font>"

  Echo "<br><h2>File systems</h2>"
  Echo "<font style='font-family:monospace;'>"
  typeset -i I=0
  df -hT | sed "s= =\&nbsp;=g" | while read LINE
  do
    ProgressBar
    I=I+1
    test ${I} -eq 1 && Echo "<b>"
    if test -n "$(echo ${LINE} | grep /dev/loop)"
    then
      Echo "<span class=textgray>${LINE}</span><br>"
    else
      Echo "${LINE}<br>"
    fi
    test ${I} -eq 1 && Echo "</b>"
  done
  Echo "</font>"
  Insert_back_to_top

  #------ Network
  ProgressBar begin "Gathering network details"

  Echo "<a name='Network'></a><h1>Network</h1>"

  Echo "<br><h2>ip</h2>"
  Echo "<font style='font-family:monospace;'>"
  if test ${SHORTVERSION} -eq 0
  then
    ip a | while read -r
    do
      LINE="${REPLY}"
      LINB=$(echo "${REPLY}" | sed "s= =\&nbsp;=g")
      echo ${LINE} | grep -q -E "^[0-9]{1,}:"
      if test $? = 0
      then
        Echo "${LINB}"
      else
        ProgressBar
        Echo "<span class=textblue1>${LINB}</span>"
      fi
      Echo "<br>"
    done
  else
    Echo "<span class=textorange>Information not available (short version)</span><br>"
  fi
  Echo "</font>"
  Insert_back_to_top

  systemctl -q is-active NetworkManager
  if test $? -eq 0
  then
    Echo "<h2>NetworkManager connection profiles (nmcli con)</h2>"
    Echo "<font style='font-family:monospace;'>"
    nmcli -c no con | sed "s= =\&nbsp;=g" | while read LINE
    do
      ProgressBar
      if test "$(echo ${LINE} | cut -c1-4)" = "NAME"
      then
        Echo "<b>${LINE}</b><br>"
      else
        if test -z "$(echo ${LINE} | grep '\-\-')"
        then
          Echo "<span class=textgreen2>${LINE}</span><br>"
        else
          Echo "${LINE}<br>"
        fi
      fi
    done
    Echo "</font>"

    Echo "<br><h2>Status of devices (nmcli dev)</h2>"
    Echo "<font style='font-family:monospace;'>"
    nmcli -c no dev | sed "s= =\&nbsp;=g" | while read LINE
    do
      ProgressBar
      if test "$(echo ${LINE} | cut -c1-6)" = "DEVICE"
      then
        Echo "<b>${LINE}</b><br>"
      else
        if test -n "$(echo ${LINE} | grep ';connected')"
        then
          Echo "<span class=textgreen2>${LINE}</span><br>"
        else
          if test -n "$(echo ${LINE} | grep ';disconnected')"
          then
            Echo "<span class=textred>${LINE}</span><br>"
          else
            Echo "${LINE}<br>"
          fi
        fi
      fi
    done
    Echo "</font>"
  else
    Echo "<br><h2>NetworkManager connection profiles (nmcli con)</h2>"
    Echo "<font style='font-family:monospace;'>"
    Echo "<span class=textorange>NetWorkManager service is not active.</span><br>"    
    Echo "</font>"
  fi
  Insert_back_to_top

  Echo "<br><h2>Network interfaces configuration file</h2>"
  if test ${SHORTVERSION} -eq 0
  then
    grep ':' /proc/net/dev | while read LINE
    do
      ProgressBar
      NETINT=$(echo ${LINE} | awk -F ':' '{print $1}' | tr -d ' ')
      IFCFGFILE=/etc/sysconfig/network-scripts/ifcfg-${NETINT}
      if test -e ${IFCFGFILE}
      then
        Echo "<table border='1'>"
        Echo "<tr><th>${IFCFGFILE}"
        Echo "</th></tr>"
        Echo "<tr><td>"
        cat ${IFCFGFILE} | sed -e "s= =\&nbsp;=g" | while read LC
        do
          if test ${INCLUDEIPADDR:-1} -eq 1
          then
            test "$(echo ${LC} | cut -c1)" = "#" && Echo "<span class=textgray>"
            Echo "<font style='font-family:monospace;'>${LC}</font>"
            test "$(echo ${LC} | cut -c1)" = "#" && Echo "</span>"
          else
            if test -n "$(echo ${LC} | grep -e 'IPADDR=' -e 'GATEWAY=' -e '^DNS.*=' | grep -v '127.0.0.1')"
            then
              LC="$(echo ${LC} | cut -f1 -d'=')="
              Echo "<font style='font-family:monospace;'>${LC}</font><span class=textorange>address not available as per user request</span><br>"
            else
              test "$(echo ${LC} | cut -c1)" = "#" && Echo "<span class=textgray>"
              Echo "<font style='font-family:monospace;'>${LC}</font>"
              test "$(echo ${LC} | cut -c1)" = "#" && Echo "</span>"
            fi
          fi
          Echo "<br>"
        done
        Echo "</td></tr>"
        Echo "</table><br>"
      fi
    done
  else
    Echo "<font style='font-family:monospace;'>"
    Echo "<span class=textorange>Information not available (short version)</span><br>"
    Echo "</font>"
  fi
  Insert_back_to_top

  Echo "<h2>netstat -r</h2>"
  Echo "<font style='font-family:monospace;'>"
  if test ${SHORTVERSION} -eq 0
  then
    which netstat >/dev/null 2>&1
    if test $? -eq 0
    then
      netstat -r | sed "s= =\&nbsp;=g" | while read N
      do
        ProgressBar
        Echo "${N}<br>"
      done
    else
      Echo "<span class=textorange>Information not available: 'netstat' is not installed</span><br>"
    fi
  else
    Echo "<span class=textorange>Information not available (short version)</span><br>"
  fi
  Echo "</font>"
  Insert_back_to_top

  #------ USB devices
  ProgressBar begin "Gathering USB devices details"

  Echo "<a name='USB'></a><h1>USB devices</h1>"
  Echo "<br><h2>lsusb</h2>"
  Echo "<font style='font-family:monospace;'>"
  if test -x /usr/bin/lsusb
  then
    /usr/bin/lsusb | while read LINE
    do
      ProgressBar
      if test -n "$(echo ${LINE} | grep 0529:)"
      then
        Echo "<span class=textblue2>${LINE}</span><br>"
      else
        Echo "${LINE}<br>"
      fi
    done
    test $(/usr/bin/lsusb 2>/dev/null | wc -l) -eq 0 && Echo "None.<br>"
    Echo "</font>"

    Echo "<br><h2>HASP USB devices details</h2>"
    Echo "<font style='font-family:monospace;'>"
    /usr/bin/lsusb -d 0529:0001 -v 2>/dev/null | grep -e ^Bus -e id*Product | sed "s= =\&nbsp;=g" | while read LINE
    do
      ProgressBar
      Echo "${LINE}<br>"
    done
    Echo "</font>"
    if test $(/usr/bin/lsusb -d 0529:0001 2>/dev/null | wc -l) -eq 0
    then
      Echo "<font style='font-family:monospace;'>None.</font><br>"
    fi
  else
    Echo "'lsusb' command not found.<br>"
    if test -n "$(rpm -q usbutils 2>/dev/null | grep 'not installed')"
    then
      Echo "Package 'usbutils' is not installed.<br>"
    fi
  fi
  Insert_back_to_top

  #-------------------------------------------------------------
  # SEH UTN information (if an SEH-Technology USB/network box is used
  #-------------------------------------------------------------
  if test -n "$(grep -w "${SEHUTNSERVICE}.service" ${TMPSVCLIST} | grep -vw 'not-found')"
  then
    Echo "<a name='SEHUTN'></a><h1>SEH UTN service information</h1>"
    Echo "<h2>Service details</h2>"
    Echo "<font style='font-family:monospace;'>"
    ISACT=$(systemctl is-active ${SEHUTNSERVICE} 2>/dev/null)
    if test -n "${ISACT}"
    then
      Echo "Service is in "
      if test "${ISACT}" = "active"
      then
        Echo "<span class=textgreen2>${ISACT}</span> state,"
      else
        Incr_NBERR "Service '${SEHUTNSERVICE}' is in '${ISACT}' state"
        Echo "<span class=msgerr>&nbsp;${ISACT}&nbsp;</span> state,"
      fi
      ISENA=$(systemctl is-enabled ${SEHUTNSERVICE} 2>/dev/null)
      if test -n "${ISENA}"
      then
        if test "${ISENA}" = "enabled"
        then
          Echo " <span class=textgreen2>${ISENA}</span>.<br>"
        else
          Echo " ${ISENA}.<br>"
        fi
      else
        Echo ".<br>"
      fi

      SEHVER="unknown"
      if test -x /usr/bin/utnm
      then
        SEHVER=$(/usr/bin/utnm -v | grep ^Version)
      else
        if test -x /usr/bin/yum
        then
          SEHVER=$(yum info seh-utn-driver | grep ^Version)
        else
          if test -x /usr/bin/dnf
          then
            SEHVER=$(yum info seh-utn-driver | grep ^Version)
          else
            if test -x /usr/bin/rpm
            then
              SEHVER=$(rpm -qi seh-utn-driver | grep ^Version)
            fi
          fi
        fi
      fi
      Echo "${SEHVER}<br>"

      SEHFIL="/usr/lib/systemd/system/seh_vhcd.service"
      SEHPER=$(find ${SEHFIL} -printf '%m' 2>/dev/null)
      if test -z "${SEHPER}"
      then
        Incr_NBWARN "Cannot check '${SEHFIL}' file permissions"
        Echo "<td class=msgwarn>Cannot check '${SEHFIL}' file permissions.</td>"
      else
        if test ${SEHPER} -eq 644
        then
          Echo "Permission check for ${SEHFIL} file: 644 (expected)<br>"
        else
          Incr_NBWARN "Permission check for '${SEHFIL}' file: ${SEHPER} (expected 644)"
          Echo "Permission check for ${SEHFIL} file: <span class=msgwarn>${SEHPER}</span> (expected 644)<br>"
        fi
      fi

      SEHRES=$(systemctl show -p Restart ${SEHUTNSERVICE} | cut -f2 -d'=')
      if test "${SEHRES}" = "no"
      then
        Incr_NBWARN "Automatic restart for '${SEHUTNSERVICE}' is disabled"
        Echo "Automatic restart: <span class=msgwarn>${SEHRES}</span><br>"
      else
        #--- on-success, on-failure, on-abnormal, on-watchdog, on-abort, or always
        Echo "Automatic restart: <span class=textgreen2>${SEHRES}</span><br>"
      fi
      Echo "</font>"

      Echo "<br><h2>Events related to ${SEHUTNSERVICE} since ${LOGSETDAT} (journalctl)</h2>"
      N=0
      Echo "<font style='font-family:monospace;'>"
      journalctl --since ${JDAT} | grep -w -e seh_vhcd -e "Logs begin" | grep -vw kernel | tail -32 | while read LINE
      do
        if test $N -eq 1
        then
          N=0
          Echo "<span class=bggray0>"
        else
          N=1
          Echo "<span>"
        fi
        Echo "${LINE}</span><br>"
      done
      Echo "</font>"
    else
      Echo "Service not found.<br>"
    fi
    Insert_back_to_top
  fi

  #-------------------------------------------------------------
  # Date time and NTP SETTINGS
  #-------------------------------------------------------------
  ProgressBar begin "Gathering time service settings"
  Echo "<a name='NTP'></a><h1>Time service settings</h1>"
  CHK=0

  Echo "<h2>System time and date</h2>"
  if test -x /usr/bin/timedatectl
  then
    Echo "<table class=noborder>"
    Echo "<font style='font-family:monospace;'>"
    timedatectl --no-pager | sed -e "s=\[1;39m==g" -e "s=\[0m==g" | while read LINE
    do
      if test -n "$(echo $LINE | grep "[[:alpha:]]:")"
      then
        LPAR=$(echo ${LINE} | cut -f1 -d':')
        LVAL=$(echo ${LINE} | sed "s=${LPAR}:==g")
        LVAL=$(echo ${LVAL})
        Echo "<tr class=noborder>"
        Echo "<td class=noborder>${LPAR}:</td><td class=noborder style='color:#0A71B4'>${LVAL}</td>"
      else
        LVAL=$(echo ${LINE})
        Echo "<tr class=noborder>"
        Echo "<td class=noborder></td><td class=noborder style='color:#0A71B4'>${LVAL}</td>"
      fi
      Echo "</tr>"
    done
    Echo "</font></table>"
  else
    Echo "<span class=textorange>Information not available ('timedatectl' command not found)</span>"
  fi
  Echo "<br>"

  Echo "<h2>chrony settings</h2>"
  if test -n "$(rpm -q chrony | grep 'is not installed')"
  then
    Echo "Package 'chrony' is not installed.<br>"
  else
    CHK=1
    RPMNAM="chronyd"
    Echo "<h3>${RPMNAM} service state</h3>"
    Echo "<font style='font-family:monospace;'>"
    if test -n "$(grep -w "${RPMNAM}.service" ${TMPSVCLIST} | grep -vw 'not-found')"
    then
      ISACT=$(systemctl is-active ${RPMNAM} 2>/dev/null)
      if test -n "${ISACT}"
      then
        Echo "Service is in "
        if test "${ISACT}" = "active"
        then
          Echo "<span class=textgreen2>${ISACT}</span> state,"
        else
          Echo "${ISACT} state,"
        fi
        ISENA=$(systemctl is-enabled ${RPMNAM} 2>/dev/null)
        if test -n "${ISENA}"
        then
          if test "${ISENA}" = "enabled"
          then
            Echo " <span class=textgreen2>${ISENA}</span>.<br>"
          else
            Echo " ${ISENA}.<br>"
          fi
        else
          Echo ".<br>"
        fi
        Echo "</font>"

        #--- Service exists, add 'chronyc tracking' output
        Echo "<br><h3>'chronyc tracking' output</h3>"
        Echo "<font style='font-family:monospace;'>"
        chronyc tracking 2>&1 | sed "s= =\&nbsp;=g" | while read LINE
        do
          Echo "${LINE}<br>"
        done
        Echo "</font>"

        #--- Service exists, add 'chronyc -n sources' output
        Echo "<br><h3>'chronyc -n sources' output</h3>"
        Echo "<font style='font-family:monospace;'>"
        if test ${SHORTVERSION} -eq 0
        then
          chronyc -n sources 2>&1 | sed "s= =\&nbsp;=g" | while read LINE
          do
            Echo "${LINE}<br>"
          done
        else
          Echo "<span class=textorange>Information not available (short version)</span><br>"
        fi
        Echo "</font>"
      else
        Echo "Service not found.<br>"
      fi
    else
      Echo "Service not found.<br>"
    fi
  fi
  Echo "<br><h2>ntp settings</h2>"
  Echo "<font style='font-family:monospace;'>"
  if test -n "$(rpm -q ntp | grep 'is not installed')"
  then
    Echo "Package 'ntp' is not installed.<br>"
  else
    CHK=1
    RPMNAM="ntpd"
    Echo "<h3>${RPMNAM} service state</h3>"
    if test -n "$(grep -w "${RPMNAM}.service" ${TMPSVCLIST} | grep -vw 'not-found')"
    then
      ISACT=$(systemctl is-active ${RPMNAM} 2>/dev/null)
      if test -n "${ISACT}"
      then
        Echo "Service is in "
        if test "${ISACT}" = "active"
        then
          Echo "<span class=textgreen2>${ISACT}</span> state,"
        else
          Echo "${ISACT} state,"
        fi
        ISENA=$(systemctl is-enabled ${RPMNAM} 2>/dev/null)
        if test -n "${ISENA}"
        then
          if test "${ISENA}" = "enabled"
          then
            Echo " <span class=textgreen2>${ISENA}</span>.<br>"
          else
            Echo " ${ISENA}.<br>"
          fi
        else
          Echo ".<br>"
        fi
        #--- Service exists, add 'ntpq -p' output
        Echo "<br><h3>'ntpq -pn' output</h3>"
        ntpq -pn 2>&1 | sed "s= =\&nbsp;=g" | while read LINE
        do
          Echo "${LINE}<br>"
        done
      else
        Echo "Service not found.<br>"
      fi
    else
      Echo "Service not found.<br>"
    fi
  fi
  Echo "</font>"

  #-------------------------------------------------------------
  # VMWARE SETTINGS
  #-------------------------------------------------------------
  if test -n "$(echo ${HWMANUF} | grep -w VMware)" && test "$(echo ${HWMODEL} | grep VMware)"
  then
    ProgressBar begin "Gathering VMware details"

    Echo "<br><a name='VMware'></a><h1>VMware settings</h1>"
    Echo "<font style='font-family:monospace;'>"
    if test -x ${VMWARETOOLBOXCMD}
    then
      VMTPRD=$(${VMWARETOOLBOXCMD} stat raw text session 2>/dev/null | grep ^version)
      if test $? -eq 0
      then
        VMTPRD=$(echo ${VMTPRD} | cut -f2 -d '=')
        VMTPRD=$(echo ${VMTPRD})
        Echo "VMware product: <span class=textblue1>${VMTPRD}</span><br>"
        VMTESX=1
      else
        Echo "VMware product: <span class=textblue1>Not ESX guest</span><br>"
        VMTESX=0
      fi

      VMTVER=$(${VMWARETOOLBOXCMD} -v 2>/dev/null)
      test -z "${VMTVER}" && VMTVER="<Unknown>"
      Echo "VMware tools version: <span class=textblue1>${VMTVER}</span><br><br>"
      Echo "</font>"

      Echo "<table border=1>"
      Echo "<tr><th>Parameter</th><th>Value</th></tr>"
      Echo "<font style='font-family:monospace;'>"

      #--- Sync with host time
      VMTVAL=$(${VMWARETOOLBOXCMD} timesync status 2>/dev/null)
      Echo "<tr><td>Time synchronization</td>"
      if test $? -eq 0
      then
        Echo "<td>${VMTVAL}</td>"
      else
        Echo "<td><span class=textorange>Cannot get value.</span></td>"
      fi
      Echo "</tr>"

      #--- Host time
      VMTVAL=$(${VMWARETOOLBOXCMD} stat hosttime 2>/dev/null)
      Echo "<tr><td>Host time</td>"
      if test $? -eq 0
      then
        Echo "<td>${VMTVAL}</td>"
      else
        Echo "<td><span class=textorange>Cannot get value.</span></td>"
      fi
      Echo "</tr>"

      #--- CPU speed
      VMTVAL=$(${VMWARETOOLBOXCMD} stat speed 2>/dev/null)
      Echo "<tr><td>CPU speed</td>"
      if test $? -eq 0
      then
        Echo "<td>${VMTVAL}</td>"
      else
        Echo "<td><span class=textorange>Cannot get value.</span></td>"
      fi
      Echo "</tr>"

      if test ${VMTESX} -eq 1
      then
        #--- CPU limit
        VMTVAL=$(${VMWARETOOLBOXCMD} stat raw text resources | grep vm.cpu.limit 2>/dev/null)
        Echo "<tr><td>CPU limit</td>"
        if test $? -eq 0
        then
          VMTVAL=$(echo ${VMTVAL} | cut -f2 -d '=')
          VMTVAL=$(echo ${VMTVAL})
          if test "${VMTVAL}" = "-1"
          then
            Echo "<td><span class=textgreen2>Not limited</span></td>"
          else
            Incr_NBWARN "VMware: CPU speed is limited to ${VMTVAL} Mhz"
            Echo "<td class=msgwarn>Limited to ${VMTVAL} Mhz</td>"
          fi
        else
          Echo "<td><span class=textorange>Cannot get value.</span></td>"
        fi
        Echo "</tr>"
      fi

      Echo "</table>"
    else
      Echo "<span class=textorange>VMware tools are not installed. Cannot retrieve information.</span><br>"
    fi
    Echo "</font>"
    Insert_back_to_top
  fi

  #-------------------------------------------------------------
  # PATH
  #-------------------------------------------------------------
  ProgressBar begin "Gathering PATH value"

  Echo "<a name='path'></a><h1>PATH</h1>"
  Echo "<font style='font-family:monospace;'>"
  DISPATH=$(echo ${PATH} | sed "s=:=<span class\=textblue3>:</span>=g")
  Echo "${DISPATH}<br>"
  Echo "</font>"
  
  #-------------------------------------------------------------
  # LINUX UPDATES
  #-------------------------------------------------------------
  ProgressBar begin "Linux updates settings"
  Echo "<br><a name='Linux_updates'></a><h1>Linux updates</h1>"
  YUMCRON=0
  DNFAUTO=0
  Echo "<h2>Automatic updates</h2>"

  #------ If yum-cron is installed
  RPMNAM="yum-cron"
  rpm -q ${RPMNAM} >/dev/null
  if test $? -eq 0
  then
    YUMCRON=1
    Echo "${RPMNAM} package is installed.<br>"

    Echo "<br><h3>Content of /etc/yum/yum-cron.conf</h3>"
    Echo "<font style='font-family:monospace;'>"
    if test -s /etc/yum/yum-cron.conf
    then 
      Echo "<table border='1'><tr><td>"
      grep -v -e ^# -e ^$ /etc/yum/yum-cron.conf | while read N
      do
        ProgressBar
        if test -n "$(echo ${N} | grep -w download_updates)"
        then
          Echo "<span class=textblue1>${N}</span><br>"
        else
          if test -n "$(echo ${N} | grep -w apply_updates)"
          then
            Echo "<span class=textorange>${N}</span><br>"
          else
            Echo "${N}<br>"
          fi
        fi
      done
      Echo "</tr></td></table>"
    else
      Incr_NBWARN "'/etc/yum/yum-cron.conf' file not found"
      Echo "<span class=msgwarn>&nbsp;File not found.&nbsp;</span><br>"
    fi
    Echo "</font><br>"

    ProgressBar
    Echo "<br><h2>${RPMNAM} service state</h2>"
    ISACT=$(systemctl is-active ${RPMNAM} 2>/dev/null)
    if test -n "$(grep -w "${RPMNAM}.service" ${TMPSVCLIST} | grep -vw 'not-found')"
    then
      if test -n "${ISACT}"
      then
        Echo "Service is in "
        if test "${ISACT}" = "active"
        then
          Echo "<span class=textgreen2>${ISACT}</span> state,"
        else
          Echo "${ISACT} state,"
        fi
        ISENA=$(systemctl is-enabled ${RPMNAM} 2>/dev/null)
        if test -n "${ISENA}"
        then
          if test "${ISENA}" = "enabled"
          then
            Echo " <span class=textgreen2>${ISENA}</span>.<br>"
          else
            Echo " ${ISENA}.<br>"
          fi
        else
          Echo ".<br>"
        fi
      else
        Incr_NBWARN "Service '${RPMNAM}' not found"
        Echo "<span class=msgwarn>&nbsp;Service not found.&nbsp;</span><br>"
      fi

      Echo "<br><h2>${RPMNAM} schedule information</h2>"
      if test -e /var/lock/subsys/${RPMNAM}
      then
        Echo "/var/lock/subsys/${RPMNAM} file exists.<br><br>"
        Echo "<b>'cron' files</b>:<br>"
        if test $(find /etc/cron* -name "*yum*" | wc -l) -gt 0
        then
          find /etc/cron* -name "*yum*" | while read LINE
          do
            ProgressBar
            Echo "${LINE}.<br>"
          done
        else
          Echo "None.<br>"
        fi
      else
        Echo "/var/lock/subsys/${RPMNAM} does not exist. Updates are disabled.<br>"
      fi
    else
      Incr_NBWARN "Service '${RPMNAM}' not found"
      Echo "<span class=msgwarn>&nbsp;Service not found.&nbsp;</span><br>"
    fi
  fi

  #------ If dnf-automatic is installed
  ProgressBar
  RPMNAM="dnf-automatic"
  rpm -q ${RPMNAM} >/dev/null
  if test $? -eq 0
  then
    DNFAUTO=1
    Echo "${RPMNAM} package is installed.<br>"

    Echo "<br><h2>Content of /etc/dnf/automatic.conf</h2>"
    Echo "<font style='font-family:monospace;'>"
    if test -s /etc/dnf/automatic.conf
    then 
      Echo "<table border='1'><tr><td>"
      grep -v -e "^#" -e "^$" /etc/dnf/automatic.conf | while read N
      do
        ProgressBar
        if test -n "$(echo ${N} | grep -w download_updates)"
        then
          Echo "<span class=textblue1>${N}</span><br>"
        else
          if test -n "$(echo ${N} | grep -w apply_updates)"
          then
            Echo "<span class=textorange>${N}</span><br>"
          else
            Echo "${N}<br>"
          fi
        fi
      done
      Echo "</tr></td></table>"
    else
      Incr_NBWARN "dnf-automatic package is installed but '/etc/dnf/automatic.conf' file not found"
      Echo "<span class=msgwarn>&nbsp;File not found.&nbsp;</span><br>"
    fi
    Echo "</font><br>"

    Echo "<br><h2>Service settings</h2>"
    Echo "<table border='1'><tr>"
    Echo "<th>Setting</th><th>Active</th><th>Enabled</th></tr>"

    for DNFSET in dnf-automatic.timer dnf-automatic-install.timer dnf-automatic-download.timer dnf-automatic-notifyonly.timer
    do
      ProgressBar
      Echo "<tr>"
      Echo "<td>${DNFSET}</td>"
      ISACT=$(systemctl is-active ${DNFSET} 2>/dev/null)
      if test -n "${ISACT}"
      then
        if test "${ISACT}" = "active"
        then
          Echo "<td class=textgreen2 align=center>${ISACT}</td>"
        else
          if test "${ISACT}" = "inactive"
          then
            Echo "<td class=textorange align=center>${ISACT}</td>"
          else
            Echo "<td align=center>${ISACT}</td>"
          fi
        fi
        ISENA=$(systemctl is-enabled ${DNFSET} 2>/dev/null)
        if test -n "${ISENA}"
        then
          if test "${ISENA}" = "enabled"
          then
            Echo "<td class=textgreen2 align=center>${ISENA}</td>"
          else
            if test "${ISENA}" = "disabled"
            then
              Echo "<td class=textorange align=center>${ISENA}</td>"
            else
              Echo "<td align=center>${ISENA}</td>"
            fi
          fi
        else
          Echo "<td>-</td>"
        fi
      else
        Echo "<td align=center>No service.</td><td align=center>-</td>"
      fi
      Echo "</tr>"
    done
    Echo "</table>"
  fi

  #------ If none is installed
  ProgressBar
  if test $YUMCRON -eq 0 -a $DNFAUTO -eq 0
  then
    Echo "<font style='font-family:monospace;'>"
    Echo "Automatic updates are not configured.<br>"
    Echo "</font>"
  fi

  #------ Check if reboot is required
  Echo "<br><h2>Reboot required checks</h2>"
  Echo "<h3>uname -a:</h3>"
  Echo "<font style='font-family:monospace;'>"
  Echo "$(uname -a)<br>"
  Echo "</font>"
  Echo "<br><h3>Kernels:</h3>"
  CURKRN="kernel-$(uname -r)"
  CHK=0
  Echo "<font style='font-family:monospace;'>"
  rpm -q kernel | while read RPMKRN
  do
    ProgressBar
    if test "${RPMKRN}" = "${CURKRN}"
    then
      #--- Current kernel
      Echo "<span class=textgreen2>${RPMKRN}</span> (current)<br>"
      CHK=1
    else
      if test ${CHK} -eq 0
      then
        #--- Previous kernels
        Echo "<span class=textgray>${RPMKRN}</span><br>"
      else
        #--- More recent kernels
        Echo "<span class=textorange>${RPMKRN}</span><br>"
      fi
    fi
  done
  Echo "</font>"

  Echo "<br><h3>Need restarting:</h3>"
  Echo "<font style='font-family:monospace;'>"
  if test -x /usr/bin/needs-restarting
  then
    /usr/bin/needs-restarting -r 2>/dev/null | while read NEEDRST
    do
      ProgressBar
      if test -n "$(echo ${NEEDRST} | grep 'Reboot is required')"
      then
        Incr_NBWARN "System update: ${NEEDRST}"
        Echo "<span class=msgwarn>${NEEDRST}</span><br>"
      else
        Echo "${NEEDRST}<br>"
      fi
    done
  else
    Echo "'needs-restarting' is not installed (provided by 'yum-utils' or 'dnf-utils' package)"
  fi
  Echo "</font>"
  Insert_back_to_top

  #-------------------------------------------------------------
  # LINUX SHUTDOWN AND REBOOT HISTORY
  #-------------------------------------------------------------
  ProgressBar begin "Gathering Linux shutdown and reboot history"
  Echo "<a name='Linux_RebootHistory'></a><h1>Linux shutdown and reboot history</h1>"
  Echo "<font style='font-family:monospace;'>"
  Echo "Booted: <span class=textblue1>${UPT2}</span><br>"
  Echo "<hr>"
  LOGDATSIN=$(date +'%Y%m%d' -d ${LOGSETDAT})
  typeset -i NBlast=0
  echo 0 >/tmp/CharonReport.lastx.tmp
  /usr/bin/last -x | grep -e ^reboot -e ^shutdown | sed "s= =\&nbsp;=g" | head -12 | while read LINE
  do
    NBlast=NBlast+1
    echo ${NBlast} >/tmp/CharonReport.lastx.tmp
    if test "$(echo ${LINE} | cut -c1-8)" = "shutdown"
    then
      Echo "<span class=textblue1>${LINE}</span><br>"
    else
      Echo "<span class=textblack>${LINE}</span><br>"
    fi
  done
  NBlast=$(cat /tmp/CharonReport.lastx.tmp)
  rm -f /tmp/CharonReport.lastx.tmp 2>/dev/null
  if test ${NBlast} -eq 0
  then
    if test -x /usr/bin/last
    then
      Echo "<span class=textorange>Cannot find last reboot and shutdown events using 'last -x'.</span><br>"
    else
      Echo "<span class=textred>Cannot find reboot and shutdown events, '/usr/bin/last' command not available.</span><br>"
    fi
  fi
  Echo "</font>"
  Insert_back_to_top

  #-------------------------------------------------------------
  # OOM SETTINGS
  #-------------------------------------------------------------
  ProgressBar begin "Gathering Out Of Memory settings"
  Echo "<a name='OOM'></a><h1>Out of Memory killer settings</h1>"
  grep -e ^charon-axp -e ^charon-vax -e ^charon-par -e ^hpa\- -q ${TMPRPMFILE}
  if test $? -eq 0
  then
    get_preferences 2>/dev/null
    if test $? -eq 0
    then
      Echo "<br><font style='font-family:monospace;'>"
      Echo "Charon VM process killing prevention settings (from preferences): "
      if test "${OOMPRVPIDKILL}" = "enabled"
      then
        Echo "<span class=textgreen2>"
      else
        Echo "<span class=textorange>"
      fi
      Echo "${OOMPRVPIDKILL}</font><br><br>"
    fi
  fi
  Echo "<font style='font-family:monospace;'>"
  Echo "vm.overcommit_memory value: <span class=textblue1>$(/sbin/sysctl -q vm.overcommit_memory | cut -f2 -d'=')</span><br>"
  Echo "<span class=textgray><u>Legend</u>: 0 = Heuristic overcommit handling, 1 = Always overcommit, 2 = Don't overcommit</span><br>"
  Echo "</font><br>"
  Echo "<font style='font-family:monospace;'>"
  Echo "vm.panic_on_oom value</b>: <span class=textblue1>$(/sbin/sysctl -q vm.panic_on_oom | cut -f2 -d'=')</span><br>"
  Echo "<span class=textgray><u>Legend</u>: 0 = Disabled, 1 = Enabled</span><br>"
  Echo "</font>"

  #--- Check if Charon processes have been killed by OOM
  declare -a CHARONPROGS
  #----- Add AXP/VAX executables
  CHARONPROGS=($(find /opt/charon/bin -type l -printf "%f\n" 2>/dev/null))
  #----- Add SSP executables
  CHARONPROGS+=("ssp4m")
  CHARONPROGS+=("ssp4u ssp4u-jit ssp4u-plus ssp4u-plus-jit")
  CHARONPROGS+=("ssp4v ssp4v-jit ssp4v-plus ssp4v-plus-jit")
  CHARONPROGS+=("ssp-agent ssp-manager ssp-director")
  #----- Add PAR executables
  CHARONPROGS+=("charon-par hppa")
  #----- Add license executables
  CHARONPROGS+=("aksusbd hasplmd license_server")

  ALLPROGS=$(echo ${CHARONPROGS[@]}|tr " " "|")

  MSGDATSIN=$(date +%s -d ${LOGSETDAT})
  for MF in $(ls /var/log/messages /var/log/messages-???????? 2>/dev/null)
  do
    MFD=$(date -r ${MF} +%s)
    if test ${MFD:-0} -ge ${MSGDATSIN}
    then
      if test -n "$(grep "Out of memory:" ${MF})"
      then
        ProgressBar
        Echo "<br><h2>Processes killed by OOM found in ${MF}</h2>"
        Echo "<font style='font-family:monospace;'><br>"
        grep -e "Killed process" -e "Out of memory:" ${MF}| while read MFL
        do
          test -n "$(echo ${MFL} | grep 'Killed process')" && Incr_NBERR "${MF}: ${MFL}"
          if test -n "$(echo ${MFL} | grep -Ew "${ALLPROGS}")"
          then
            MFL=$(echo ${MFL} | sed "s=\(^.*(\)\(.*\)\().*$\)=\1<span class\=msgerr>\2</span>\3=g")
          else
            MFL=$(echo ${MFL} | sed "s=\(^.*(\)\(.*\)\().*$\)=\1<span class\=textred>\2</span>\3=g")
          fi
          Echo "${MFL}<br>"
        done
        Echo "</font>"
        Insert_back_to_top
      fi
    fi
  done

  #-------------------------------------------------------------
  # CHARON SETTINGS
  #-------------------------------------------------------------
  ProgressBar begin "Gathering Charon configuration"
  Echo "<br><a name='Charon_configuration'></a><h1>Charon configuration</h1><br>"

  LISTINST=""
  grep -e ^charon\- -e ^hpa\- -q ${TMPRPMFILE}
  if test $? -eq 0
  then
    # Check if AXP, VAX, PAR, HPA or SSP is installed then display rpm installed and services settings
    Echo "<a name='Packages_Installed'></a><h2>Packages installed</h2>"
    Echo "<table border=1>"
    Echo "<tr><th>Name</th><th>Version</th><th>Release</th><th>Installation date</th><th>Release date</th><th>Description</th></tr>"
    Echo "<font style='font-family:monospace;'><br>"
    N=0
    grep -e ^charon\- -e ^hpa\- -e ^aksusbd -e ^license-server ${TMPRPMFILE} | sort | while read LINE
    do
      ProgressBar
      if test $N -eq 1
      then
        TRBG="bggray0"
        N=0
        Echo "<tr class=bggray0>"
      else
        TRBG=""
        N=1
        Echo "<tr>"
      fi
      TRWARN=${TRBG}
      PACKNVR=$(rpm -q --queryformat "<td>%{NAME}</td><td align=right>%{VERSION}</td><td align=right>%{RELEASE}</td>" ${LINE})
      PACKI=$(rpm -q --queryformat "%{INSTALLTIME:date}" ${LINE})
      PACKI=$(date +"%d-%b-%Y %H:%M:%S" -d "${PACKI}")
      PACKD=$(rpm -q --queryformat "%{DESCRIPTION}" ${LINE})
      RP=$(echo ${LINE} | cut -f2 -d'-')
      PACKR=""
      case "${LINE}"
      in
        charon-axp-*|charon-vax-*)
          RB=$(echo ${LINE} | cut -f4 -d'-' | cut -f1 -d'.')
          PACKR=${CharonProd["${RP}${RB}"]}
          if test -z "${PACKR}"
          then
            PACKR="Unknown release date"
          else
            if test -n "$(echo ${PACKR} | grep '\[W\]$')"
            then
              PACKR=$(echo ${PACKR} | sed "s=\[W\]$==g")
              TRWARN="msgwarn"
              Incr_NBWARN "Package '${LINE}' is not official: ${PACKR}"
            fi
          fi
          ;;
        charon-ssp-*)
          RB=$(echo ${LINE} | cut -f4 -d'-' | awk -F "." '{print $1"."$2"."$3}')
          PACKR=${CharonProd["${RP}${RB}"]}
          if test -z "${PACKR}"
          then
            PACKR="Unknown release date"
          else
            if test -n "$(echo ${PACKR} | grep '\[W\]$')"
            then
              PACKR=$(echo ${PACKR} | sed "s=\[W\]$==g")
              TRWARN="msgwarn"
              Incr_NBWARN "Package '${LINE}' is not official: ${PACKR}"
            fi
          fi
          ;;
        charon-par-*)
          RB=$(echo ${LINE} | cut -f3 -d'-')
          PACKR=${CharonProd["${RP}${RB}"]}
          if test -z "${PACKR}"
          then
            PACKR="Unknown release date"
          else
            if test -n "$(echo ${PACKR} | grep '\[W\]$')"
            then
              PACKR=$(echo ${PACKR} | sed "s=\[W\]$==g")
              TRWARN="msgwarn"
              Incr_NBWARN "Package '${LINE}' is not official: ${PACKR}"
            fi
          fi
          ;;
      esac
      if test -n "${TRWARN}"
      then
        Echo "${PACKNVR}<td align=right>${PACKI}</td><td class=${TRWARN} align=center>${PACKR}</td><td>${PACKD}</td>"
      else
        Echo "${PACKNVR}<td align=right>${PACKI}</td><td align=center>${PACKR}</td><td>${PACKD}</td>"
      fi
      Echo "</tr>"
    done
    Echo "</font></table>"
    Insert_back_to_top

    grep -e ^charon-axp -e ^charon-vax -q ${TMPRPMFILE}
    if test $? -eq 0
    then
      #------ Charon-AXP or Charon-VAX installed
      grep ^charon-axp -q ${TMPRPMFILE} && LISTINST="${LISTINST}/AXP"
      grep ^charon-vax -q ${TMPRPMFILE} && LISTINST="${LISTINST}/VAX"
      collect_charontoolkit
      collect_ncu
      collect_axpvax_agentd
    fi

    grep -e ^charon-par -e ^hpa\- -q ${TMPRPMFILE}
    if test $? -eq 0
    then
      #------ Charon-PAR or hppa installed
      LISTINST="${LISTINST}/PAR"
      collect_charontoolkit
    fi

    grep ^charon-ssp -q ${TMPRPMFILE}
    if test $? -eq 0
    then
      #------ Charon-SSP installed
      LISTINST="${LISTINST}/SSP"
      collect_charonssp
    fi

    LISTINST=$(echo ${LISTINST} | cut -c2-)

  else
    Echo "<span class=textorange>Charon is not installed.</span><br>"
  fi

  #-------------------------------------------------------------
  # HASP LICENSE SETTINGS
  #-------------------------------------------------------------
  ProgressBar begin "Gathering Charon license settings"
  Echo "<a name='HASP_licsettings'></a><h2>HASP license settings</h2>"

  SVCNAM="aksusbd"
  AKSEXE=/usr/sbin/aksusbd
  Echo "<a name='aksusbd_service'></a><h3>${SVCNAM} service</h3>"
  Echo "<span style='font-family:monospace'>"
  if test -n "$(grep -w "${SVCNAM}.service" ${TMPSVCLIST} | grep -vw 'not-found')"
  then
    ISACT=$(systemctl is-active ${SVCNAM} 2>/dev/null)
    if test -n "${ISACT}"
    then
      Echo "Service is in "
      if test "${ISACT}" = "active"
      then
        Echo "<span class=textgreen2>${ISACT}</span> state"
      else
        if test -x ${AKSEXE}
        then
          Incr_NBERR "Service '${SVCNAM}' state is '${ISACT}'"
          Echo "<span class=msgerr>&nbsp;${ISACT}&nbsp;</span> state"
        fi
      fi
      ISENA=$(systemctl is-enabled ${SVCNAM} 2>/dev/null)
      if test -n "${ISENA}"
      then
        if test "${ISENA}" = "enabled"
        then
          Echo " and is <span class=textgreen2>${ISENA}</span>."
        else
          if test -x ${AKSEXE}
          then
            Incr_NBERR "Service '${SVCNAM}' is not enabled"
            Echo " and is <span class=msgerr>&nbsp;${ISENA}&nbsp;</span>."
          fi
        fi
      else
        Echo "."
      fi
      Echo "<br><br>"
      SVCUFS=$(systemctl show -p UnitFileState ${SVCNAM} 2>/dev/null | cut -f2 -d '=')
      if test "${SVCUFS}" = "bad"
      then
        Echo "<span class=textorange><b>Note</b>: the service is not systemd native ('bad' status in the 'Loaded' line below)</span><br>"
        Echo "<br>"
      fi
      check_svcprot /etc/systemd/system/aksusbd.service
      systemctl -l --lines=20 status aksusbd.service 2>&1 | sed \
        -e "s=|-=\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&#9500;\&#9472;=g" \
        -e "s=\`-=\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&#9492;\&#9472;=g" \
        -e "s=* =\&diams;\&nbsp;=g" | while read LINE
      do
        Echo "${LINE}<br>"
      done
      Insert_back_to_top
      
      systemctl -q is-enabled hasplmd 2>/dev/null
      if test $? -eq 0
      then
        Echo "<a name='hasplmd_service'></a><h3>hasplmd service</h3>"
        check_svcprot /etc/systemd/system/hasplmd.service
        systemctl -l --lines=20 status hasplmd.service 2>&1 | sed \
          -e "s=|-=\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&#9500;\&#9472;=g" \
          -e "s=\`-=\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&#9492;\&#9472;=g" \
          -e "s=* =\&diams;\&nbsp;=g" | while read LINE
        do
          Echo "${LINE}<br>"
        done
        Insert_back_to_top
      fi

      ProgressBar
      Echo "<a name='HASP_runtime'></a><h3>Sentinel HASP Run-Time environment</h3>"
      Echo "<h4>${SVCNAM} version</h4>"

      if test -x ${AKSEXE}
      then
        ${AKSEXE} -v >/dev/null 2>&1
        if test $? -eq 0
        then
          Echo "$(${AKSEXE} -v)<br>"
        else
          ${AKSEXE}_x86_64 -v >/dev/null 2>&1
          if test $? -eq 0
          then
            Echo "$(${AKSEXE}_x86_64 -v 2>&1)<br>"
          fi
        fi
      else
        Incr_NBERR "Service '${SVCNAM}' exists but '${AKSEXE}' file does not exist or is not executable"
        Echo "<span class=msgerr>&nbsp;${AKSEXE} file does not exist or is not executable&nbsp;</span>"
      fi
      Echo "<br>"
      Echo "<h4>${SVCNAM} package</h4>"
      Echo "$(rpm -q ${SVCNAM})<br>"
      Echo "<br>"

      Echo "<a name='SACC'></a><h3>Sentinel Admin Control Center settings</h3>"
      Echo "<h4>hasplm version</h4>"
      if test -s /var/hasplm/hasplm.version
      then
        Echo "$(cat /var/hasplm/hasplm.version)<br>"
      else
        Echo "Cannot be determined<br>"
      fi
      Echo "<br>"
      Echo "<h4>Settings</h4>"

      ProgressBar
      declare -A HASPLMHASH
      HASPLMHASH=( ["name"]="Server name" \
                   ["accessfromremote"]="Allow Access from Remote Clients" \
                   ["accesstoremote"]="Allow Access to Remote Licenses" \
                   ["broadcastsearch"]="Broadcast Search for Remote Licenses" \
                   ["accremote"]="Allow Remote Access to ACC" \
                   ["bind_local_only"]="Network Visibility (0=all adapters, 1=localhost only)" )

      if test -e ${HASPLMINI}
      then
        Echo "<span class=textblue1>Important parameters</span>&nbsp;<span class=textgray>(hasplm.ini file is attached to the zip file)</span>:<br><br>"
        Echo "<table border=1>"
        Echo "<tr><th>Parameter</th><th>Value</th><th>Description</th></tr>"
        N=0
        for ITEM in name accessfromremote accesstoremote broadcastsearch accremote bind_local_only
        do
          ProgressBar
          if test $N -eq 1
          then
            N=0
            Echo "<tr class=bggray0>"
          else
            N=1
            Echo "<tr>"
          fi
          HASPVAL=$(grep -i "^${ITEM}.*=" ${HASPLMINI} | cut -f1 -d ";" | tr [:upper:] [:lower:])
          ITEMD=${HASPLMHASH[$ITEM]}
          if test -n "${HASPVAL}"
          then
            ITEMP=$(echo ${HASPVAL} | cut -f1 -d'=')
            ITEMV=$(echo ${HASPVAL} | cut -f2 -d'=')
          else
            ITEMP=${ITEM}
            ITEMV="Not defined"
          fi
          Echo "<td><span style='font-family:monospace'>${ITEMP}</span></td>"
          Echo "<td align=center><span style='font-family:monospace;text-align:center'>${ITEMV}</span></td>"
          Echo "<td><span class=textblue2>${ITEMD}</span></td>"
          Echo "</tr>"
        done
        Echo "</table>"

        Insert_back_to_top

        HASPACCREM=$(grep -i "^accremote.*=" ${HASPLMINI} | cut -f1 -d ";" | tr [:upper:] [:lower:])
        HASPBINDLO=$(grep -i "^bind_local_only.*=" ${HASPLMINI} | cut -f1 -d ";" | tr [:upper:] [:lower:])
        if test -n "${HASPACCREM}" -a -n "${HASPBINDLO}"
        then
          HASPACCV=$(echo ${HASPACCREM} | cut -f1 -d ";" | cut -f2 -d'=')
          HASPBINV=$(echo ${HASPBINDLO} | cut -f1 -d ";" | cut -f2 -d'=')
          if test ${HASPACCV:-1} -eq 1 -a ${HASPBINV:-0} -ne 0
          then
            Echo "<br>"
            Incr_NBERR "Sentinel Admin Control Center: remote access is enabled but bind_local_only is not set to 0"
            Echo "<span class=msgerr>&nbsp;Remote access is enabled but bind_local_only is not set to 0!&nbsp;</span><br>"
            Echo "Please set Network Visibility (on the Network tab) to All Network Adapters from the <a href='http://localhost:1947/_int_/config_network.html' target='_blank'>Sentinel Admin Control Center</a> page.<br>"
          fi
        fi

        #--- Display error log file content in the HTML file if enabled
        HASPERRORLOG=$(grep -i "^errorlog.*=" ${HASPLMINI} | cut -f2 -d "=" | cut -f1 -d ";" | tr [:upper:] [:lower:])
        HASPROTATLOG=$(grep -i "^rotatelogs.*=" ${HASPLMINI} | cut -f2 -d "=" | cut -f1 -d ";" | tr [:upper:] [:lower:])
        if test ${HASPERRORLOG:-0} -eq 1
        then
          DATMIN=$(date -d ${LOGSETDAT} +'%Y-%m-%d')
          DATMINX=$(echo ${DATMIN} | tr -d "-")
          if test ${HASPROTATLOG:-0} -eq 0
          then
            ls ${HASPLMDIR}/error*.log 2>/dev/null | while read HASPLOG
            do
              DATLOG=$(date -r ${HASPLOG} +'%Y-%m-%d')
              DATLOGX=$(echo ${DATLOG} | tr -d "-")
              if test ${DATLOGX} -ge ${DATMINX}
              then
                Echo "<br><span class=textblue1>Error log file:</span> ${HASPLOG} (since ${LOGSETDAT})<br><br>"
                LOGSIZ=$(find ${HASPLOG} -printf '%k')
                LOGSIZDSP=$(printf "%'.f\n" ${LOGSIZ})
                if test ${LOGSIZ} -le ${LOGMAXSIZ}
                then
                  hasplog_to_report "${HASPLOG}"
                else
                  Echo "Log file, size is ${LOGSIZ}Kb. Limit is ${LOGMAXDIS} <span class=bgorange>&nbsp;SKIPPED&nbsp;</span><br>"
                fi
              fi
            done
          else
            ls ${HASPLMDIR}/log/*_error*.log 2>/dev/null | while read HASPLOG
            do
              DATLOG=$(basename ${HASPLOG} | sed -e "s=\(^.*\)_error.*$=\1=g" -e "s=_=-=g")
              DATLOGX=$(echo ${DATLOG} | tr -d "-")
              if test ${DATLOGX} -ge ${DATMINX}
              then
                Echo "<br><span class=textblue1>Error log file:</span> ${HASPLOG} (since ${LOGSETDAT})<br><br>"
                LOGSIZ=$(find ${HASPLOG} -printf '%k')
                LOGSIZDSP=$(printf "%'.f\n" ${LOGSIZ})
                if test ${LOGSIZ} -le ${LOGMAXSIZ}
                then
                  hasplog_to_report "${HASPLOG}"
                else
                  Echo "Log file, size is ${LOGSIZ}Kb. Limit is ${LOGMAXDIS} <span class=bgorange>&nbsp;SKIPPED&nbsp;</span><br>"
                fi
              fi
            done
          fi
        fi
      else
        Echo "<span class=textorange>File '${HASPLMINI}' not found.</span><br>"
        Echo "<u>Note</u>: This means default options are used (no update done in the <a href='http://localhost:1947/_int_/config.html' target='_blank'>Sentinel Admin Control Center</a>)<br>"
      fi
    else
      Incr_NBWARN "Service '${SVCNAM}' not found"
      Echo "<span class=msgwarn>&nbsp;Service not found.&nbsp;</span><br>"
    fi
  else
    Echo "<span class=textorange>aksusbd is not installed (HASP license).</span><br>"
  fi
  Echo "</font>"
  Insert_back_to_top

  #-------------------------------------------------------------
  # VE license
  #-------------------------------------------------------------
  rpm -q license-server >/dev/null
  if test $? -eq 0
  then
    Echo "<a name='VE_licsettings'></a><h2>VE license settings</h2>"
    ProgressBar begin "Gathering Charon VE license settings"

    SVCNAM="licensed"
    Echo "<a name='licensed_service'></a><h3>${SVCNAM} service</h3>"
    Echo "<font style='font-family:monospace;'>"
    if test -n "$(grep -w "${SVCNAM}.service" ${TMPSVCLIST} | grep -vw 'not-found')"
    then
      ProgressBar
      ISACT=$(systemctl is-active ${SVCNAM} 2>/dev/null)
      if test -n "${ISACT}"
      then
        Echo "Service is in "
        if test "${ISACT}" = "active"
        then
          Echo "<span class=textgreen2>${ISACT}</span> state,"
        else
          Incr_NBERR "Service 'license-server' is in '${ISACT}' state"
          Echo "<span class=msgerr>&nbsp;${ISACT}&nbsp;</span> state,"
        fi
        ISENA=$(systemctl is-enabled ${SVCNAM} 2>/dev/null)
        if test -n "${ISENA}"
        then
          if test "${ISENA}" = "enabled"
          then
            Echo " <span class=textgreen2>${ISENA}</span>.<br>"
          else
            Incr_NBERR "Service 'license-server' is not enabled"
            Echo " <span class=msgerr>&nbsp;${ISENA}&nbsp;</span>.<br>"
          fi
        else
          Echo ".<br>"
        fi
        Echo "<br>"
        ProgressBar
        check_svcprot /etc/systemd/system/licensed.service
        SVCUFS=$(systemctl show -p UnitFileState ${SVCNAM} 2>/dev/null | cut -f2 -d '=')
        if test "${SVCUFS}" = "bad"
        then
          Echo "<span class=textorange><b>Note</b>: the service is not systemd native ('bad' status in the 'Loaded' line below)</span><br>"
          Echo "<br>"
        fi
        systemctl -l --lines=20 status ${SVCNAM}.service 2>&1 | sed \
          -e "s=|-=\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&#9500;\&#9472;=g" \
          -e "s=\`-=\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&nbsp;\&#9492;\&#9472;=g" \
          -e "s=* =\&diams;\&nbsp;=g" | while read LINE
        do
          Echo "${LINE}<br>"
        done
      fi
    else
      Incr_NBERR "VE license server package is installed but 'licensed' service is not found"
      Echo "<span class=msgerr>&nbsp;VE license server package is installed but 'licensed' service is not found&nbsp;</span>.<br>"
    fi
    Echo "</font>"

    for ITEM in "Actual status of license server;s;server" "Registered clients (AutoVE only);r;viewer" "Connected clients;c;viewer" "License utilisation;u;viewer"
    do
      ProgressBar
      VEwhat=$(echo $ITEM | cut -f1 -d';')
      VEparam=$(echo $ITEM | cut -f2 -d';')
      VEcmd=$(echo $ITEM | cut -f3 -d';')
      VEchap=$(echo $VEwhat | tr " " "_" | tr -d "()")
      Echo "<a name='${VEchap}'></a><h3>${VEwhat}</h3>"
      rm -f /tmp/CharonReport-VElicense.tmp 2>/dev/null
      Echo "<font style='font-family:monospace;'>"
      /opt/license-server/license_${VEcmd} -${VEparam} 2>&1 | sed -e "s= =\&nbsp;=g" | while read LINE
      do
        touch /tmp/CharonReport-VElicense.tmp
        Echo "${LINE}<br>"
      done
      if test ! -e /tmp/CharonReport-VElicense.tmp
      then
        Echo "'license_viewer -${VEparam}' output is empty.<br>"
      fi
      Echo "</font>"
      Insert_back_to_top
    done
    rm -f /tmp/CharonReport-VElicense.tmp 2>/dev/null

    Echo "<a name='VElicense_log'></a><h3>License server log file</h3>"
    Echo "<font style='font-family:monospace;'>"
    VELOG="/opt/license-server/log/license.log"
    VEDIR=$(dirname ${VELOG})
    if test -d ${VEDIR}
    then
      if test -e ${VELOG}
      then
        VENBL=$(wc -l ${VELOG} | awk '{print $1}')
        if test ${VENBL:-0} -eq 0
        then
          Echo "Log file '${VELOG}' is empty.<br>"
        else
          if test ${VENBL:-0} -gt 20
          then
            Echo "<span class=textblue1>Log file '${VELOG}' content (truncated to last 20 lines):</span><br>"
          else
            Echo "<span class=textblue1>Log file '${VELOG}' content:</span><br>"
          fi
          tail -20 ${VELOG} | sed "s= =\&nbsp;=g" | while read LINE
          do
            LINN=$(echo ${LINE} | sed "s=\&nbsp;= =g")
            if test -n "$(echo ${LINE} | grep ';WARN&')"
            then
              Incr_NBWARN "${VELOG}: ${LINN}"
              Echo "<span class=msgwarn>${LINE}</span><br>"
            elif test -n "$(echo ${LINE} | grep ';ERROR&')"
            then
              Incr_NBERR "${VELOG}: ${LINN}"
              Echo "<span class=msgerr>${LINE}</span><br>"
            elif test -n "$(echo ${LINE} | grep ';FATAL&')"
            then
              Incr_NBERR "${VELOG}: ${LINN}"
              Echo "<span class=msgfatal>${LINE}</span><br>"
            else
              Echo "<span>${LINE}</span><br>"
            fi
          done
        fi
      else
        Echo "Log file '${VELOG}' does not exist.<br>"
      fi
    else
      Echo "Log file folder '${VEDIR}' does not exist.<br>"
    fi
    Echo "</font>"
    Insert_back_to_top

    Echo "<a name='VElicense_cfg'></a><h3>License server configuration file</h3>"
    VECFG="/opt/license-server/config.ini"
    if test -e ${VECFG}
    then
      Echo "<font style='font-family:monospace;'>"
      cat ${VECFG} | while read LINE
      do
        case "$(echo ${LINE} | cut -c1)"
        in
          "#")
            Echo "<span class=textgray0>${LINE}</span><br>"
            ;;
          "[")
            Echo "<span class=textblue2>${LINE}</span><br>"
            ;;
          *)
            Echo "${LINE}<br>"
            ;;
        esac
      done
      Echo "</font>"
    else
      Echo "Configuration file '${VECFG}' does not exist.<br>"
    fi
    Insert_back_to_top
  fi

  #--- License content
  Echo "<a name='License'></a><h1>License</h1>"
  Echo "<a name='Charon_license'></a><h2>License content</h2>"
  Echo "<br>"
  ProgressBar

  OPTHASP=""
  HASPEXE=$(which hasp_srm_view 2>/dev/null)
  if test -z "${HASPEXE}"
  then
    if test -x /opt/charon/bin/hasp_srm_view
    then
      HASPEXE="/opt/charon/bin/hasp_srm_view"
    else
      if test -x /opt/charon-agent/ssp-agent/utils/license/hasp_srm_view
      then
        HASPEXE="/opt/charon-agent/ssp-agent/utils/license/hasp_srm_view"
      fi
    fi
  fi
  
  KEYID=""
  if test -z "${HASPEXE}"
  then
    Echo "<span class=msgerr>&nbsp;Cannot find 'hasp_srm_view' executable file.&nbsp;</span><br>"
    Echo "Please verify CHARON is installed and PATH is correctly set.<br>"
  else
    ProgressBar begin "Gathering Charon license content"

    if test -x /usr/bin/strings
    then
      #--- If 'strings' is installed, try to find the -all parameter in the executable file
      if test -n "$(strings ${HASPEXE} | grep ^-all)"
      then
        OPTHASP="-all"
      fi
    else
      #--- If 'strings' is not installed, let's assume '-all' parameter is available
      #    Note: for AXP/VAX, starting 4.7 and above
      OPTHASP="-all"
    fi

    OUTVIEW="/tmp/$(basename $0)_$(date +%Y%m%d_%H%M%S).view"
    touch ${OUTVIEW}

    if test ${OKAT:-0} -eq 1
    then
      #--- reading license using 'at' so that content can be read even from remote session
      echo "${HASPEXE} ${OPTHASP} >${OUTVIEW} 2>&1" | at now >${OUTVIEW}.tmp 2>&1
      ATNUM=$(grep ^job ${OUTVIEW}.tmp | awk '{print $2}')
      rm -f ${OUTVIEW}.tmp /tmp/CharonReport_licnums.tmp 2>/dev/null
      typeset -i I=0
      while test 1
      do
        ProgressBar
        I=I+1
        sleep 2
        test -z "$(at -l | grep -w ^${ATNUM})" && break
        if test $I -gt 30
        then
          >${OUTVIEW}
          break
        fi
      done
    else
      #--- 'at' conditions not met, reading license directly (will not work with remote session)
      Echo "<span class=textorange>Reading license directly without 'at' as 'atd' service is not running</span><br><br>"
      rm -f /tmp/CharonReport_licnums.tmp 2>/dev/null
      ${HASPEXE} ${OPTHASP} >${OUTVIEW} 2>&1
    fi

    Echo "<span style='font-family:monospace'>"
    typeset -i NLI=0
    echo ${NLI} >/tmp/CharonReport_liclines.tmp
    TODDAT=$(date +%Y%m%d)
    typeset -i DATDIF=0

    if test -e ${OUTVIEW}
    then
      cat ${OUTVIEW} >${ZIPFOLDER}/CharonReport.d/$(basename ${HASPEXE}).txt 2>&1
    fi

    cat ${OUTVIEW} | sed "s=\r==g" | while read LO
    do
      ProgressBar
      NLI=NLI+1
      echo ${NLI} >/tmp/CharonReport_liclines.tmp
      case "$(echo ${LO} | awk '{print $1,$2}')"
      in
        "License Manager")
          if test -n "$(echo ${LO} | grep '^License Manager running at host:')"
          then
            Echo "<span class=textgreen1>${LO}"
            RUNHOST=$(echo ${LO} | sed "s=^License Manager running at host: ==g")
            if test "${RUNHOST}" = "$(hostname -s)" || test "${RUNHOST}" = "$(hostname)"
            then
              Echo "&nbsp;(this host)"
            fi
            Echo "</span><br>"
          else
            Echo "${LO}<br>"
          fi
          ;;
        "License type:")
          Echo "<span class=bgblue3>${LO}</span><br>"
          ;;
        "License Manager")
          if test -n "$(echo ${LO} | grep '^License Manager running at host')"
          then
            Echo "<span class=textgreen1>${LO}</span><br>"
          else
            Echo "${LO}<br>"
          fi
          ;;
        "Product Name:")
          PRDNAM=$(echo ${LO} | sed "s=^Product Name: ==g")
          Echo "Product Name: <span class=textblue1><b>${PRDNAM}</b></span><br>"
          ;;
        "The License")
          if test -n "$(echo ${LO} | grep '^The License Number:')"
          then
            LICNUM=$(echo ${LO} | sed "s=\(^.*Number: \)\(.*\)=\2=g" | tr -d "\r\n")
            grep -q "^${LICNUM}$" /tmp/CharonReport_licnums.tmp 2>/dev/null
            if test $? -eq 0
            then
              Incr_NBERR "License '${LICNUM}', keyid '${KEYID}': duplicate license number"
            else
              echo "${LICNUM}" >>/tmp/CharonReport_licnums.tmp
            fi
            Echo "<br><span class=bggreen2>${LO}</span><br>"
          else
            Echo "${LO}<br>"
          fi
          ;;
        "Released product"|"License expiration"|"License time")
          case "$(echo ${LO} | awk '{print $3}')"
          in
            "expiration"|"date:")
              EXPDAT=$(echo ${LO} | cut -f2 -d: | cut -f1 -d '(')
              EXPDAT=$(echo ${EXPDAT} | sed "s= and = =g" | tr -d [:cntrl:])
              case "${EXPDAT}"
              in 
                "01-Jan-1970"|"Unlimited")
                  Echo "<span class=textgreen1>${LO}</span> (unlimited) <span class=textgreen2>&#10003;</span><br>"
                  ;;
                "SL license not started yet")
                  Incr_NBERR "License '${LICNUM}', keyid '${KEYID}': SL license not started yet"
                  Echo "<span class=msgerr>${LO}</span><br>"
                  ;;
                *)
                  XPRDAT=$(date +%Y%m%d -d "${EXPDAT}")
                  DATDIF=($(date +%s -d ${XPRDAT})-$(date +%s -d ${TODDAT}))/86400
                  if test ${DATDIF:-100} -gt 7
                  then
                    if test ${DATDIF:-100} -gt 14
                    then
                      Echo "<span class=textblue2>${LO}</span> (${DATDIF} days remaining)<br>"
                    else
                      Echo "<span class=textorange>${LO}</span> (${DATDIF} days remaining)<br>"
                    fi
                  else
                    if test ${DATDIF:-100} -gt 0
                    then
                      Incr_NBWARN "License '${LICNUM}', keyid '${KEYID}', product '${PRDNAM}': ${DATDIF} days remaining"
                      Echo "<span class=msgwarn>${LO}</span> (${DATDIF} days remaining)<br>"
                    else
                      Incr_NBERR "License '${LICNUM}', keyid '${KEYID}', product '${PRDNAM}': expired ${DATDIF#-} days ago"
                      Echo "<span class=msgerr>${LO}</span> (expired ${DATDIF#-} days ago)<br>"

                      if test $(ls -1 /var/hasplm/installed/68704/${KEYID}*.v2c 2>/dev/null | wc -l) -gt 0
                      then
                        Echo "&nbsp;&nbsp;<span class=textorange><i>Please remove expired software licenses. See chapter 'Removing a Software License' in the CHARON-${LISTINST} User's Guide.</i></span><br>"
                      fi
                    fi
                  fi
                  ;;
              esac
              ;;
            "time"|"remaining:")
              EXPTIM=$(echo ${LO} | cut -f2 -d: | cut -f1 -d'(' | cut -c2- | tr -d [:cntrl:])
              EXPHOUR=$(echo ${EXPTIM} | awk '{print $1}')
              EXPMINS=$(echo ${EXPTIM} | awk '{print $4}')
              if test ${EXPHOUR} -eq 0 -a ${EXPMINS} -eq 0
              then
                Incr_NBERR "Time limited license '${LICNUM}', keyid '${KEYID}', product '${PRDNAM}': expired"
                Echo "<span class=msgerr>${LO}</span> (expired)<br>"
              else
                if test ${EXPHOUR:-100} -gt 24
                then
                  if test ${EXPHOUR:-100} -gt 48
                  then
                    Echo "<span class=textblue2>${LO}</span><br>"
                  else
                    Echo "<span class=textorange>${LO}</span><br>"
                  fi
                else
                  if test ${EXPHOUR:-100} -gt 0
                  then
                    Incr_NBWARN "Time limited license '${LICNUM}', keyid '${KEYID}', product '${PRDNAM}': ${LO}"
                    Echo "<span class=msgwarn>${LO}</span><br>"
                  else
                    Incr_NBWARN "Time limited license '${LICNUM}', keyid '${KEYID}', product '${PRDNAM}': ${LO} (about to expire or expired)"
                    Echo "<span class=msgerr>${LO}</span> (about to expire or expired)<br>"
                  fi
                fi
              fi
              ;;
          esac
          ;;
        "Trying to")
          if test -n "$(echo ${LO} | grep '^Trying to connect to the key')"
          then
            KEYID=$(echo ${LO} | cut -f2 -d':' | tr -dc [:digit:])
            LICNUM=""
            NOTFOUND=0
          fi
          Echo "<b>${LO}</b><br>"
          ;;
        "No License")
          if test -n "$(echo ${LO} | grep '^No License information detected')"
          then
            Echo "<span class=bggray>${LO}</span><br>"
          else
            Echo "${LO}<br>"
          fi
          ;;
        *)
          if test -n "$(echo ${LO} | grep '^----------')"
          then
            if test -z "${LICNUM}"
            then
              if test ${NOTFOUND:-0} -eq 0
              then
                Incr_NBWARN "License keyid '${KEYID}': no license information detected (section is empty)"
                Echo "<span class=msgwarn>No license information detected (section is empty).</span><br>"
              fi
            fi
            Echo "<hr><br>"
          elif test -n "$(echo ${LO} | grep 'HASP key not found' | grep 'improper type')"
          then
            NOTFOUND=1
            if test -n "${KEYID}"
            then
              Incr_NBWARN "License keyid '${KEYID}': ${LO}"
              Echo "<span class=msgwarn>${LO}</span><br>"
              if test $(ls -1 /var/hasplm/installed/68704/${KEYID}*.v2c 2>/dev/null | wc -l) -gt 0
              then
                Incr_NBWARN "License keyid '${KEYID}': this Software License may be in cloned state"
                Echo "This Software License may be in cloned state.<br>"
                Echo "Click here to open the <a href='http://localhost:1947/_int_/devices.html' target='_blank'>Sentinel Admin Control Center</a> and verify.<br>"
                Echo "Software licenses are stored in the folder: <span class=textblue1>/var/hasplm/installed/68704</span><br>"
                Echo "If the license is in cloned state, please remove it (see chapter 'Removing a Software License' in the CHARON-${LISTINST} User's Guide).<br>"
              fi
            else
              Incr_NBWARN "${LO}"
              Echo "<span class=msgwarn>${LO}</span><br>"
            fi
          else
            Echo "${LO}<br>"
          fi
          ;;
      esac
    done
    NLI=$(cat /tmp/CharonReport_liclines.tmp 2>/dev/null)
    rm -f /tmp/CharonReport_liclines.tmp /tmp/CharonReport_licnums.tmp 2>/dev/nul
    if test ${NLI:-0} -eq 0
    then
      Echo "Cannot read license or license empty.<br>"
    fi
  fi
  Echo "</font>"
  Insert_back_to_top

  Echo "<a name='Software_license'></a><h2>Software license files list</h2>"
  Echo "<font style='font-family:monospace;'>"
  Echo "<span class=textblue1>Content of '/var/hasplm/installed/68704' folder:</span><br>"
  if test $(ls -1 /var/hasplm/installed/68704/ 2>/dev/null | wc -l) -eq 0
  then
    Echo "No file found.<br>"
  else
    ls -l /var/hasplm/installed/68704 2>&1 | sed "s= =\&nbsp;=g" | while read LINE
    do
      if test -n "$(echo ${LINE} | grep _base)"
      then
        Echo "<span class=textblue2>${LINE}</span><br>"
      else
        Echo "${LINE}<br>"
      fi
    done
  fi
  Echo "</font>"
  Insert_back_to_top

  #-------------------------------------------------------------
  # CHARON SERVICES
  #-------------------------------------------------------------
  CHARONSVCH1=0

  grep -e ^charon-axp -e ^charon-vax -q ${TMPRPMFILE}
  if test $? -eq 0
  then
    #------ Charon-AXP or Charon-VAX installed
    collect_charonservices axpvax
  fi

  grep -e ^charon-par -e ^hpa\- -q ${TMPRPMFILE}
  if test $? -eq 0
  then
    #------ Charon-PAR or hppa installed
    collect_charonservices par
  fi

  grep ^charon-ssp -q ${TMPRPMFILE}
  if test $? -eq 0
  then
    #------ Charon-SSP installed
    SSPEXELIST=$(find /opt/charon-ssp -name "ssp4[umv]" 2>/dev/null; \
                 find /opt/charon-ssp -name "ssp4[umv]-plus" 2>/dev/null; \
                 find /opt/charon-ssp -name "ssp4[umv]*jit")
    collect_charonservices ssp
  fi

  #-------------------------------------------------------------
  # END REPORT
  #-------------------------------------------------------------
  add_results
  Echo "<br><hr>"
  Echo "<b>&copy; Stromasys $(date +%Y)</b><br>"
  Echo "<span class=textgray>"
  Echo "<font style='font-family:monospace;'>"
  Echo "Script version ${RVERSION} - ${RVERDATE}<br>"
  if test -e ${CHECKFORUPDATE}
  then
    Echo "Charon Report automatic update check is disabled."
  fi 
  Echo "</font></span><br>"
  Insert_back_to_top
  Echo "</body></html>"
}

#-------------------------------------------------------------
# Check if CharonReport_cfgselected.txt exists then convert
# to new format name (was used before V1.47)
#-------------------------------------------------------------
if test -e ${ETCCHARON}/CharonReport_cfgselected.txt
then
  SOURCE="user"
  cat ${ETCCHARON}/CharonReport_cfgselected.txt | while read LINE
  do
    CFG=$(echo ${LINE} | cut -f2 -d';')
    if test -e ${CFG}
    then
      if test -n "$(grep -w set ${CFG} | grep -w session | grep -w hw_model)"
      then
        #--- Check if the file is a valid AXP/VAX .cfg file and not already in the list
        PRD="axpvax"
        SVCLIST="${ETCCHARON}/CharonReport_cfgselected_${PRD}.txt"
        touch ${SVCLIST}
        grep -q "^${CFG};" ${SVCLIST} 2>/dev/null
        if test $? -eq 1
        then
          ACFN=$(grep -w configuration_name ${CFG} | grep session | grep set | grep -v "^#" | awk -F'=' '{print $2}' | tr -d "'\"" | tr -d " ")
          test -z "${ACFN}" && ACFN="$(basename ${CFG} | sed "s=\.cfg$==g")"
          get_logfile_axpvax ${CFG}
          update_svclist "${CFG};${SOURCE};${LOGF};${SESSROTA};X;${ACFN}"
        fi
      elif test -n "$(grep -w model ${CFG} | grep -v '#')" -a -n "$(grep -w memory ${CFG} | grep -v '#')"
      then
        #--- Check if the file is a valid PAR .cfg file
        PRD="par"
        SVCLIST="${ETCCHARON}/CharonReport_cfgselected_${PRD}.txt"
        touch ${SVCLIST}
        grep -q "^${CFG};" ${SVCLIST} 2>/dev/null
        if test $? -eq 1
        then
          AMOD=$(grep -w model ${CFG} | grep -v '#' | sed "s=model==g" | tr -d "'" | tr -d '"')
          AMOD=$(echo ${AMOD})
          test -z "${AMOD}" && AMOD="charon-par"
          grep ^hpa\- -q ${TMPRPMFILE}
          if test $? -eq 0
          then
            AEXE="/opt/charon/bin/hppa"
          else
            AEXE="/opt/charon/bin/charon-par"
          fi
          get_logfile_par ${CFG}
          update_svclist "${CFG};${SOURCE};${LOGF};X;${AEXE};${AMOD}"
        fi
      elif test -n "$(grep '^\[system\]' ${CFG} | grep -v '#')" -a -n "$(grep '^\[ram\]' ${CFG} | grep -v '#')"
      then
        #--- Check if the file is a valid SSP .cfg file
        PRD="ssp"
        SVCLIST="${ETCCHARON}/CharonReport_cfgselected_${PRD}.txt"
        touch ${SVCLIST}
        grep -q "^${CFG};" ${SVCLIST} 2>/dev/null
        if test $? -eq 1
        then
          #--- Trying to get executable name (not 100% sure as no idea if jit or plus)
          AEXE=$(grep ^machine ${CFG} | cut -f2 -d'=')
          AEXE=$(echo ${AEXE} | sed "s=SUN-=ssp=g" | tr [:upper:] [:lower:])
          AEXE=$(find /opt/charon-ssp -name "${AEXE}")
          get_logfile_ssp ${CFG}
          update_svclist "${CFG};${SOURCE};${LOGF};X;${AEXE};X" donotreplace
        fi
      fi
    fi
  done
  rm -f ${ETCCHARON}/CharonReport_cfgselected.txt 2>/dev/null
fi

#-------------------------------------------------------------
# Clear stdin buffer
#-------------------------------------------------------------
while read -r -t 0; do read -r; done

#-------------------------------------------------------------
# Generate the report file
#-------------------------------------------------------------
echo
ProgressBar begin "Generating output to ${ZIPFOLDER}/${HTMLFILE}"
Generate_Report
ProgressBar end
echo "Report completed (${ZIPFOLDER}/${HTMLFILE})."

#-------------------------------------------------------------
# Generate the zip file
#-------------------------------------------------------------
tput sc
echo "Creating zip file ${ZIPFILE} ..."
mkdir ${ZIPFOLDER}/CharonReport.d/_etc
mkdir ${ZIPFOLDER}/CharonReport.d/_var
mkdir ${ZIPFOLDER}/CharonReport.d/_var/log
mkdir ${ZIPFOLDER}/CharonReport.d/_opt

#--- Create and add HTML file
zip -jq ${ZIPFILE} ${ZIPFOLDER}/${HTMLFILE}

#--- Add description
case "${REPORTTYPE}"
in
  "Ticket")      REPORTLINE="Ticket number: ${REPORTNUMB:-not specified}";;
  "Opportunity") REPORTLINE="Opportunity reference: ${REPORTNUMB:-not specified}";;
  "Project")     REPORTLINE="Project number: ${REPORTNUMB:-not specified}";;
  *)             REPORTLINE="Other: ${REPORTNUMB:-not specified}";;
esac
RSHORT=""
test ${SHORTVERSION} -eq 1 && RSHORT="(short version)"
echo "Charon Report Utility V${RVERSION} - ${RVERDATE} ${RSHORT}
${REPORTLINE}

" | zip -zq ${ZIPFILE}

#--- Add "ethtool -k <NIC>" output for all NIC in the zip file
ip a | while read LINE
do
  echo ${LINE} | grep -q -E "^[0-9]{1,}:"
  if test $? = 0
  then
    NIC=$(echo ${LINE} | cut -f2 -d ':' | tr -d [:space:])
    ethtool -k ${NIC} >${ZIPFOLDER}/CharonReport.d/ethtool-k-${NIC}.txt 2>&1
  fi
done

#--- Add all installed packages list to the zip file
if test ${SHORTVERSION} -eq 0
then
  sort ${TMPRPMFILE} >${TMPRPMFILE}.sorted
  mv -f ${TMPRPMFILE}.sorted ${ZIPFOLDER}/CharonReport.d/$(basename ${TMPRPMFILE})
fi

grep ^charon-ssp -q ${TMPRPMFILE}
if test $? -eq 0
then
  #------ Charon-SSP installed, add agent log files
  mkdir -p ${ZIPFOLDER}/CharonReport.d/_opt/charon-agent/ssp-agent/agent-log/
  cp -p /opt/charon-agent/ssp-agent/agent-log/agent.log* ${ZIPFOLDER}/CharonReport.d/_opt/charon-agent/ssp-agent/agent-log/ 2>/dev/null
fi

#--- Add the /etc/hasplm (.ini only) and /var/hasplm (.log only) folders to the zip file 
mkdir ${ZIPFOLDER}/CharonReport.d/_etc/hasplm
mkdir ${ZIPFOLDER}/CharonReport.d/_var/hasplm
cp -p /etc/hasplm/*.ini ${ZIPFOLDER}/CharonReport.d/_etc/hasplm/ 2>/dev/null
cp -p /var/hasplm/*.log ${ZIPFOLDER}/CharonReport.d/_var/hasplm/ 2>/dev/null
cp -p /var/hasplm/log/*.log ${ZIPFOLDER}/CharonReport.d/_var/hasplm/ 2>/dev/null

#--- Add the /etc/charon.d folder content (Toolkit)
if test -d /etc/charon.d
then
  mkdir ${ZIPFOLDER}/CharonReport.d/_etc/charon.d
  cp -p /etc/charon.d/* ${ZIPFOLDER}/CharonReport.d/_etc/charon.d/ 2>/dev/null
fi

#--- Add Charon Toolkit log file
mkdir -p ${ZIPFOLDER}/CharonReport.d/_opt/charon/log
cp -p /opt/charon/log/charon*.log* ${ZIPFOLDER}/CharonReport.d/_opt/charon/log/ 2>/dev/null

#--- Add Charon Toolkit script files
mkdir -p ${ZIPFOLDER}/CharonReport.d/_opt/charon/utils 2>/dev/null
cp -p /opt/charon/utils/charon_check.alertcmd ${ZIPFOLDER}/CharonReport.d/_opt/charon/utils/ 2>/dev/null
cp -p /opt/charon/utils/kit.* ${ZIPFOLDER}/CharonReport.d/_opt/charon/utils/ 2>/dev/null
cp -p /opt/charon/utils/charon_gstart.* ${ZIPFOLDER}/CharonReport.d/_opt/charon/utils/ 2>/dev/null
cp -p /opt/charon/utils/charon_logchk.list ${ZIPFOLDER}/CharonReport.d/_opt/charon/utils/ 2>/dev/null

#--- Add the /root/.charon* files for compatibility with older versions of the Linux Toolkit
ls /root/.charon* >/dev/null 2>&1
if test $? -eq 0
then
  mkdir ${ZIPFOLDER}/CharonReport.d/_root
  cp -p /root/.charon* ${ZIPFOLDER}/CharonReport.d/_root/
fi

#--- Add time service configuration files if exists
if test ${SHORTVERSION} -eq 0
then
  cp -p /etc/chrony.conf ${ZIPFOLDER}/CharonReport.d/_etc/ 2>/dev/null
  cp -p /etc/ntp.conf ${ZIPFOLDER}/CharonReport.d/_etc/ 2>/dev/null
fi

#--- Add journalctl data to the zip file
if test ${SHORTVERSION} -eq 0
then
  journalctl --since ${JDAT} >${ZIPFOLDER}/CharonReport.d/journalctl.txt
fi

#--- Add dmidecode output to the zip file
if test -x /usr/sbin/dmidecode
then
  dmidecode >${ZIPFOLDER}/CharonReport.d/dmidecode.txt 2>&1
else
  echo "'dmidecode' is not installed on this server" >${ZIPFOLDER}/CharonReport.d/dmidecode.txt
fi

#--- Add dmesg output to the zip file
dmesg >${ZIPFOLDER}/CharonReport.d/dmesg.txt 2>&1

#--- Add /var/log/messages files to the zip file
SDAT=$(date -d ${LOGSETDAT} +%s)
typeset -i N=0
if test ${SHORTVERSION} -eq 0
then
  for FILE in $(ls /var/log/messages*)
  do
    FDAT=$(date -r ${FILE} +%s)
    if test ${FDAT} -ge ${SDAT}
    then
      cp -p ${FILE} ${ZIPFOLDER}/CharonReport.d/_var/log 2>/dev/null
      N=N+1
    fi
  done
  if test $N -eq 0
  then
    touch ${ZIPFOLDER}/CharonReport.d/_var/log/No-messages-file-found
  fi
fi

#--- Add /var/log/audit files to the zip file if selinux is set to 'enforced'
if test "$(getenforce)" = "Enforcing"
then
  typeset -i N=0
  if test ${SHORTVERSION} -eq 0
  then
    for FILE in $(ls /var/log/audit/audit.log*)
    do
      FDAT=$(date -r ${FILE} +%s)
      if test ${FDAT} -ge ${SDAT}
      then
        cp -p ${FILE} ${ZIPFOLDER}/CharonReport.d/_var/log 2>/dev/null
        N=N+1
      fi
    done
    if test $N -eq 0
    then
      touch ${ZIPFOLDER}/CharonReport.d/_var/log/No-audit-logfile-found
    fi
  fi
fi

#--- Add 'netstat -an' and 'netstat -s'
if test ${SHORTVERSION} -eq 0
then
  which netstat >/dev/null 2>&1
  if test $? -eq 0
  then
    netstat -an >${ZIPFOLDER}/CharonReport.d/netstat-an.txt 2>&1
    netstat -s  >${ZIPFOLDER}/CharonReport.d/netstat-s.txt  2>&1
  else
    Echo "'netstat' is not installed" >${ZIPFOLDER}/CharonReport.d/netstat-an.txt 2>&1
    Echo "'netstat' is not installed" >${ZIPFOLDER}/CharonReport.d/netstat-s.txt  2>&1
  fi
fi

#--- Add VE license server log files
rpm -q license-server >/dev/null
if test $? -eq 0
then
  mkdir -p ${ZIPFOLDER}/CharonReport.d/_opt/license-server/log
  cp -p /opt/license-server/config.ini ${ZIPFOLDER}/CharonReport.d/_opt/license-server/ 2>/dev/null
  cp -p /opt/license-server/log/license.log* ${ZIPFOLDER}/CharonReport.d/_opt/license-server/log/ 2>/dev/null
  cp -p /opt/license-server/log/webserver.log ${ZIPFOLDER}/CharonReport.d/_opt/license-server/log/ 2>/dev/null
fi

#--- Add CharonReport_cfgselect*.txt files to the zip file
cp ${ETCCHARON}/CharonReport_cfgselected*.txt ${ZIPFOLDER}/CharonReport.d/

#--- Add CharonReport.d subfolder containing the cfg and log files and all other files created earlier
cd ${ZIPFOLDER}/CharonReport.d/

#------ Zip all remaining txt files
zip -uq ${ZIPFILE} *.txt

#------ Zip all system folders (/etc -> _etc)
zip -ruq ${ZIPFILE} _*

#------ Zip virtual machines cfg and log files
zip -ruq ${ZIPFILE} * -x _* -x *.txt

cd - >/dev/null

tput rc
tput cuu1
tput ed

#--- If the resulting zip file size is greater than 100Mb, a warning popup is displayed
typeset -i ZIPSIZ=$(find $ZIPFILE -printf '%k')
if test $ZIPSIZ -gt 100000
then
  echo -n "${ESCWARN}${ESC}[1mThe size of the resulting zip file is "
  printf "%'.0f" ${ZIPSIZ}
  echo "Kb!${ESC}[0m"
  echo "${ESCWARN}Please check its content before sending it to Stromasys support.${ESC}[0m"
fi

#--- CharonReport zip files purge (keep latest 7 days by default)
find ${ZIPFOLDER}/CharonReport-*.zip -mtime +7 -exec rm -f {} \;

echo "Created zip file ${ZIPFILE}"
echo "[38;5;27mPlease send the zip file (only) to Stromasys support team. Thank you.[0m"

#--- Check if VE license servers have been found and ask to run the CharonReport on these servers
if test -s ${TMPVESVRLIST}
then
  typeset -i I=0
  sort -u ${TMPVESVRLIST} | while read LINE
  do
    LTYP=$(echo ${LINE} | cut -f1 -d';' | cut -c2-)
    LSVR=$(echo ${LINE} | cut -f2 -d';')
    if test -z "$(ip a | grep -w inet | grep -w ${LSVR})" -a "${LSVR}" != "localhost" -a "${LSVR}" != "$(hostname)" -a "${LSVR}" != "$(hostname -s)"
    then
      I=I+1
      if test $I -eq 1
      then
        echo
        echo "[38;5;27mPlease run also the CharonReport script on the VE license server(s):[0m"
      fi
      if test "${LTYP}" = "SVR"
      then
        echo "- ${LSVR} (license server)"
      else
        echo "- ${LSVR} (backup license server)"
      fi
    fi
  done
fi

The_End
