#!/bin/bash
#< Wrapper around prtpicl to check temperature sensors on compatible Sun boxen

# Executables
AWK="/usr/local/bin/awk"
BASENAME="/usr/bin/basename"
CUT="/usr/bin/cut"
ECHO="/usr/bin/echo"
EGREP="/usr/bin/egrep"
GREP="/usr/bin/grep"
PRINTF="/usr/bin/printf"
PRTPICL="/usr/sbin/prtpicl -v -c temperature-sensor"
RM="/bin/rm"
SED="/bin/sed"
TEE="/usr/bin/tee"
TR="/usr/bin/tr"
WC="/usr/bin/wc"

# File Paths
TMP="/tmp"
TEMPTMP="${TMP}/check_temps-$$"
RAWFILE="${TEMPTMP}-raw"

# Information requested:
ALL=0
HIGH=0
LOW=0
# Modes:
DEBUG=0
VERBOSE=0

# Set a default threshold - 10 degrees
THRESHOLD=10

########
# set -x
########

function cleanup {
   ${RM} -f ${TEMPTMP}*
}

trap "cleanup; exit 1" 1 2 3 15

function print_usage {
   {
      ${ECHO} "Usage: $( ${BASENAME} $0 ) [ -v ] [ -d ] -a | [ -H | -L ] [ -t <threshold> ]"
      ${ECHO} "           -a    Check all (both High and Low) temperatures"
      ${ECHO} "           -H    Check High temperatures only"
      ${ECHO} "           -L    Check Low temperatures only"
      ${ECHO} "           -t    Alert when temperature +/- <threshold> degrees from boundary (default: 10)"
      ${ECHO} ""
      ${ECHO} "           -d    Enable some debugging output"
      ${ECHO} "           -h    Display this message"
      ${ECHO} "           -v    Verbose mode"
   } >&2
}

if [ "$#" -lt "1" ]; then
   ${ECHO} "Error: At least one type of temperature check must be requested"
   print_usage && exit 1
fi

# Argument and Option Processing ########################
while getopts ":adhHLt:v" OPTION; do
   case ${OPTION} in
      "a")      ALL="1"                         ;;
      "d")      DEBUG="1"                       ;;
      "h")      print_usage && exit 0           ;;
      "H")      HIGH="1"                        ;;
      "L")      LOW="1"                         ;;
      "t")      THRESHOLD="${OPTARG}"           ;;
      "v")      VERBOSE="1"                     ;;
       * )      print_usage && exit 1           ;;
   esac
done
shift $(( ${OPTIND} - 1 ))

(( DEBUG )) && {
   ${ECHO} "m[ v(${VERBOSE}) d(${DEBUG}) ] | i[ a(${ALL}) h(${HIGH}) l(${LOW}) ]"
}
#########################################################

function check_prtpicl {
   if [ ! -e $( ${ECHO} "${PRTPICL}" | ${CUT} -d' ' -f 1 ) ]; then
      ${ECHO} "Error: prtpicl command does not exist" >&2
      exit 1
   elif [ ! -x $( ${ECHO} "${PRTPICL}" | ${CUT} -d' ' -f 1 ) ]; then
      ${ECHO} "Error: prtpicl command is not executable" >&2
      exit 1
   fi
}

function check_threshold {
   ${ECHO} "${THRESHOLD}" | ${EGREP} '^[0-9]+$' >/dev/null 2>&1
   if [ "$?" -ne "0" ]; then
      ${ECHO} "Invalid threshold format! Use an integer value only"
      exit 1
   fi
}

function create_temp_file {
   ${PRTPICL} > ${RAWFILE}
}

function get_sensor_names {
   SENSOR_NAMES=$( ${GREP} '^[ ][ ]*[^:][^:]*temperature-sensor.*$' ${RAWFILE} |\
      ${SED} 's/^[ ][ ]*\(.*\) (.*$/\1/' | ${TR} '\n' ' ' )
   NO_OF_SENSORS=$( ${ECHO} "${SENSOR_NAMES}" | ${WC} -w )
   if [ "${NO_OF_SENSORS}" -eq "0" ]; then
      ${ECHO} "No sensors defined on this host - Aborting..."
      exit 0
   fi
}

function print_sensor_names {
   ${ECHO} "The following sensors have been detected on this system:"
   ${ECHO} "${SENSOR_NAMES}" | ${TR} ' ' '\n' | ${SED} -e 's/^/--> /' -e '$d'
}

function create_sensor_files {
   for SENSOR in ${SENSOR_NAMES}; do
      # Formulate a temp file name
      SENSOR_TMP="${TEMPTMP}-${SENSOR}.s"
      (( DEBUG )) && {
         ${ECHO} "--> ${SENSOR_TMP} will contain"
         ${PRTPICL} |\
            ${SED} -ne 's/^[ ][ ]*//' -e "/^${SENSOR}/,/^:name[         ]*${SENSOR}/ p" |\
            ${TR} '\t' ' ' | ${TR} -s ' ' | ${SED} -e 's/://' -e 's/ /|/' | ${TEE} ${SENSOR_TMP}
      } || {
         ${PRTPICL} |\
            ${SED} -ne 's/^[ ][ ]*//' -e "/^${SENSOR}/,/^:name[         ]*${SENSOR}/ p" |\
            ${TR} '\t' ' ' | ${TR} -s ' ' | ${SED} -e 's/://' -e 's/ /|/' > ${SENSOR_TMP}
      }
   done
}

function parse_sensor_files {
   TOTAL_WARNINGS=0
   for SENSOR_FILE in ${TEMPTMP}-*.s; do
      (( VERBOSE )) && {
         ${ECHO} "--> Parsing sensor file ${SENSOR_FILE}"
      }
      while read LINE; do
         VARIABLE=$( ${ECHO} "${LINE}" | ${CUT} -d'|' -f1 )
         VALUE=$( ${ECHO} "${LINE}" | ${CUT} -d'|' -f2 )
         if ${ECHO} "${VALUE}" | "${GREP}" '(temperature-sensor, ' >/dev/null 2>&1; then
            THIS_SENSOR="${VARIABLE}"
            (( VERBOSE )) && {
               ${PRINTF} "%25s -- %5s\n" "CurrentSensor" "${THIS_SENSOR}"
            }
         fi
         # Now, we can act upon the specified invocation options
         if [ "${ALL}" -eq "1" ]; then
            # If we are testing ALL, we don't need individual tests
            LOW=1
            HIGH=1
         fi
         if [ "${VARIABLE}" = "Temperature" ]; then
            CURRENTTEMP="${VALUE}"
            (( VERBOSE )) && {
               ${PRINTF} "%25s == %5s\n" "${VARIABLE}" "${VALUE}"
            }
         fi
         if [ "${HIGH}" -eq "1" ]; then
            case ${VARIABLE} in
               "HighPowerOffThreshold" )
                  HIGHPOWEROFF="${VALUE}"
                  (( OURHIGHPOWEROFF = HIGHPOWEROFF - THRESHOLD ))
                  (( VERBOSE )) && {
                     ${PRINTF} "%25s -- %5s\n" "${VARIABLE}" "${VALUE}"
                     ${PRINTF} "%25s -- %5s\n" "OurHighPowerOffThreshold" "${OURHIGHPOWEROFF}"
                  } ;;
                "HighShutdownThreshold" )
                   HIGHSHUTDOWN="${VALUE}"
                   (( OURHIGHSHUTDOWN = HIGHSHUTDOWN - THRESHOLD ))
                   (( VERBOSE )) && {
                      ${PRINTF} "%25s -- %5s\n" "${VARIABLE}" "${VALUE}"
                      ${PRINTF} "%25s -- %5s\n" "OurHighShutdownThreshold" "${OURHIGHSHUTDOWN}"
                   } ;;
                "HighWarningThreshold" )
                   HIGHWARNING="${VALUE}"
                   (( OURHIGHWARNING = HIGHWARNING - THRESHOLD ))
                   (( VERBOSE )) && {
                      ${PRINTF} "%25s -- %5s\n" "${VARIABLE}" "${VALUE}"
                      ${PRINTF} "%25s -- %5s\n" "OurHighWarningThreshold" "${OURHIGHWARNING}"
                   } ;;
            esac 
         fi 
         if [ "${LOW}" -eq "1" ]; then
            case ${VARIABLE} in
               "LowPowerOffThreshold" )
                  LOWPOWEROFF="${VALUE}"
                  (( OURLOWPOWEROFF = LOWPOWEROFF + THRESHOLD )) 
                  (( VERBOSE )) && {
                     ${PRINTF} "%25s -- %5s\n" "${VARIABLE}" "${VALUE}"
                     ${PRINTF} "%25s -- %5s\n" "OurLowPowerOffThreshold" "${OURLOWPOWEROFF}"
                  } ;;
               "LowShutdownThreshold" )
                  LOWSHUTDOWN="${VALUE}"
                  (( OURLOWSHUTDOWN = LOWSHUTDOWN + THRESHOLD )) 
                  (( VERBOSE )) && {
                     ${PRINTF} "%25s -- %5s\n" "${VARIABLE}" "${VALUE}"
                     ${PRINTF} "%25s -- %5s\n" "OurLowShutdownThreshold" "${OURLOWSHUTDOWN}"
                  } ;;
               "LowWarningThreshold" )
                  LOWWARNING="${VALUE}"
                  (( OURLOWWARNING = LOWWARNING + THRESHOLD )) 
                  (( VERBOSE )) && {
                     ${PRINTF} "%25s -- %5s\n" "${VARIABLE}" "${VALUE}"
                     ${PRINTF} "%25s -- %5s\n" "OurLowWarningThreshold" "${OURLOWWARNING}"
                  } ;;
            esac 
         fi 
      done < ${SENSOR_FILE}
   (( VERBOSE )) && {
      ${ECHO} "--> Warnings (if any) for this sensor:"
   }
   WARNING_COUNT=0
   if [ "${HIGH}" -eq "1" ]; then
      if [ "${CURRENTTEMP}" -ge "${OURHIGHPOWEROFF}" ]; then
         ${PRINTF} "[ %15s ]--> %5s >= %5s ( %s )\n" "${THIS_SENSOR}" "${CURRENTTEMP}" "${OURHIGHPOWEROFF}" "OurHighPowerOffThreshold"
         (( WARNING_COUNT = WARNING_COUNT + 1 ))
      fi
      if [ "${CURRENTTEMP}" -ge "${OURHIGHSHUTDOWN}" ]; then
         ${PRINTF} "[ %15s ]--> %5s >= %5s ( %s )\n" "${THIS_SENSOR}" "${CURRENTTEMP}" "${OURHIGHSHUTDOWN}" "OurHighShutdownThreshold"
         (( WARNING_COUNT = WARNING_COUNT + 1 ))
      fi
      if [ "${CURRENTTEMP}" -ge "${OURHIGHWARNING}" ]; then
         ${PRINTF} "[ %15s ]--> %5s >= %5s ( %s )\n" "${THIS_SENSOR}" "${CURRENTTEMP}" "${OURHIGHWARNING}" "OurHighWarningThreshold"
         (( WARNING_COUNT = WARNING_COUNT + 1 ))
      fi
   fi
   if [ "${LOW}" -eq "1" ]; then
      if [ "${CURRENTTEMP}" -le "${OURLOWPOWEROFF}" ]; then
         ${PRINTF} "[ %15s ]--> %5s <= %5s ( %s )\n" "${THIS_SENSOR}" "${CURRENTTEMP}" "${OURLOWPOWEROFF}" "OurLowPowerOffThreshold"
         (( WARNING_COUNT = WARNING_COUNT + 1 ))
      fi
      if [ "${CURRENTTEMP}" -le "${OURLOWSHUTDOWN}" ]; then
         ${PRINTF} "[ %15s ]--> %5s <= %5s ( %s )\n" "${THIS_SENSOR}" "${CURRENTTEMP}" "${OURLOWSHUTDOWN}" "OurLowShutdownThreshold"
         (( WARNING_COUNT = WARNING_COUNT + 1 ))
      fi
      if [ "${CURRENTTEMP}" -le "${OURLOWWARNING}" ]; then
         ${PRINTF} "[ %15s ]--> %5s <= %5s ( %s )\n" "${THIS_SENSOR}" "${CURRENTTEMP}" "${OURLOWWARNING}" "OurLowWarningThreshold"
         (( WARNING_COUNT = WARNING_COUNT + 1 ))
      fi
   fi
   (( VERBOSE )) && {
      if [ "${WARNING_COUNT}" -eq "0" ]; then
         ${ECHO} "No warnings for this sensor"
      elif [ "${WARNING_COUNT}" -eq "1" ]; then
         ${ECHO} "--[ ${WARNING_COUNT} WARNING FOR THIS SENSOR ]--"
      else 
         ${ECHO} "--[ ${WARNING_COUNT} WARNINGS FOR THIS SENSOR ]--"
      fi
   }
   (( TOTAL_WARNINGS = TOTAL_WARNINGS + WARNING_COUNT ))
   done
   (( VERBOSE )) && {
      ${ECHO} "--> Total number warnings (if any) for this host:"
      if [ "${TOTAL_WARNINGS}" -eq "0" ]; then
         ${ECHO} "No warnings for this host"
      elif [ "${TOTAL_WARNINGS}" -eq "1" ]; then
         ${ECHO} "--[ ${TOTAL_WARNINGS} WARNING FOR THIS HOST ]--"
      else 
         ${ECHO} "--[ ${TOTAL_WARNINGS} WARNINGS FOR THIS HOST ]--"
      fi
   }
}

check_prtpicl
check_threshold
create_temp_file
get_sensor_names
(( VERBOSE )) && {
   print_sensor_names
}
create_sensor_files
parse_sensor_files
cleanup

if [ "${TOTAL_WARNINGS}" -gt "0" ]; then
   exit 69
fi

exit 0