#!/bin/bash
# vim: cindent:shiftwidth=4:tabstop=4:smarttab:textwidth=100

set -o posix
set -o errexit
set -o pipefail
set -o nounset
#set -o xtrace

#$title$ Intelligent Platform Management Interface (IPMI)
#$check$ clock synchronization for System Event Log (SEL)
#$ref$ ipmitool(1), /var/log/ipmi
#$author$ Rafal Rzeczkowski
#$version$ 0.6.1

level_check long

#CHANGELOG
#0.5.0	initial
#0.5.1	downgrade failure report level to caution
#0.6.0	recognize new date format from ipmitool 1.8.19
#0.6.1	explicitly set locale for ipmitool

declare -r -a PROBLEMS=(TIME_OFFSET)
test -n ${#PROBLEMS[@]}

declare -r DATE_DIFF_MAX=10

# explicitly set locale for ipmitool so that it outputs time in a consistent format
# select 'en_CA' since it uses ISO 8601 format for date (d_fmt in /usr/share/i18n/locales)
date_ipmi_raw=$(LANG='en_CA.UTF-8' ipmitool sel time get)

if [[ "${date_ipmi_raw#*/}" != "${date_ipmi_raw}" ]]; then
	# ipmitool version 1.8.18
	# {04/22/2013 20:57:10}
	D=$date_ipmi_raw
	date_ipmi_rfc="${D:6:4}-${D:0:2}-${D:3:2} ${D:11:8}"
	#RFC-3339: 2006-08-07 12:34:56-06:00
	date_ipmi_epoch=$(date --utc --date="$date_ipmi_rfc" +%s)
	time_format_version=18
elif [[ "${date_ipmi_raw#*-}" != "${date_ipmi_raw}" ]]; then
	# ipmitool version 1.8.19
	# {2023-06-15 04:45:06 PM EDT}
	date_ipmi_epoch=$(date --utc --date="$date_ipmi_raw" +%s)
	time_format_version=19
else
	exit 1
fi
echodebug "date_ipmi_epoch: $date_ipmi_epoch"

date_sys_epoch=$(date --utc +%s)
echodebug "date_sys_epoch: $date_sys_epoch"

date_diff=$(( date_ipmi_epoch - date_sys_epoch ))
if [[ $date_diff -lt 0 ]]; then
	date_diff=$((-date_diff))
fi
seconds_plural=$(plural_text $date_diff 'second')

if [[ $date_diff -gt $DATE_DIFF_MAX ]]; then
	fail caution "LOM time inaccuracy of $date_diff $seconds_plural exceeds $DATE_DIFF_MAX second limit"
	helpmsg 'ensure that the IPMI controller is using NTP servers'
	problem TIME_OFFSET $time_format_version
else
	echodebug "IPMI time ($date_ipmi_raw) is synchronized to within $date_diff $seconds_plural of system time"
	ok
fi
