#!/bin/bash
#
# Execute Date, Time, and/or Timezone changes o the HMC with commands
#  requiring root privilege 
#
# Description: Issue to run privileged Date/Time commands 
#
# Change Activity:
#   09/08/2006 ferrants    569860 - initial version
#   09/15/2006 ferrants    570565 - update usage comments
#   10/23/2006 ferrants    484296 - add NTP support
#   02/12/2007 ferrants    590209 - check for existence of timezone file prior to creating link
#
#STARTUSAGE
#
# Usage:
#   dateTimeUtil -c queryTimezone
#   dateTimeUtil -c queryDateTime
#   dateTimeUtil -c removeLocaltime
#   dateTimeUtil -c copyClock -f <clock file>
#   dateTimeUtil -c linkZone -f <timezone file>
#   dateTimeUtil -c setDateTime -d <date> -t <time> -k <clock value>
#   dateTimeUtil -c modifyBuildFile
#   dateTimeUtil -c queryNtpService
#   dateTimeUtil -c enableNtp -s <state>
#
# Where:
#   -c   The operation to be performed.  Must be one of:
#        . queryTimezone - determines either the file or symbolically linked
#                          /etc/localtime file and returns stdOut of 'find'
#                          command
#        . queryDateTime - issues the Linux 'date' command with special
#                          formatting options
#        . removeLocaltime - deletes the current /etc/localtime file
#        . copyClock - copies a new version of the /etc/sysconfig/clock file to
#                      the system
#        . linkZone - symbolically links the selected timezone to the
#                     /etc/localtime file
#        . setDateTime - issues the Linux 'date' and 'hwclock' commands with
#                        appropriate args
#        . modifyBuildFile - invokes the 'modHscBuildDatFile' script (which
#                            'touch's the backup trgiiger file, if appropriate)
#        . queryNtpService - queries whether or not the xntpd service is running
#        . enableNtp - force starts/stops the xntp service
#
#   -d   The date string argument for setting the current date.  Used for the 
#        setDateTime operation, in the format day/month/year, example: 4/14/2006
#   -f   The updated version of the /etc/sysconfig/clock file to be written or
#        the new timezone file, depending on usage
#   -k   The new value of the BIOS clock setting, either "--utc" or "--localtime"
#   -s   The value to set xntpd service in, either "start" or "stop"
#   -t   The time string argument for setting the current time.  Used for the
#        setDateTime operation, in the format hh:mm:ss, example: 10:45:32
#
# Return Codes:
# 6 - error when issuing the 'date --set="xxx xxx"' command
# 7 - error when issuing the 'hwclock --systohc xxx' command
# 8 - error if input timezone file cannot be found on the system
# * - other system command return codes
#
#ENDUSAGE
#****************************************************************************

function showUsage() {
   # Print out the prologue comments as usage info
   sed -e '/STARTUSAGE/,/ENDUSAGE/ s/^#//' -e '1,/STARTUSAGE/ d' -e '/ENDUSAGE/,$ d' "$0"
}


#-------------------------------------------------------------------------------
# common exit point for setDateTime processing
#-------------------------------------------------------------------------------
exit_cleanup() {
    
    if [ $1 -eq 0 ]; then
	echo "Setting the date/time and hardware clock was successful. Date/time is now `date`." >> $log
    else
	echo "Setting the date/time or hardware clock failed and exited with rc=$1." >> $log
    fi
    
    exit $1
}  

#-------------------------------------------------------------------------------
# Just in case we have NLS troubles reading system information...
#-------------------------------------------------------------------------------
LANG=en_US
export LANG

# Initialize some constants
log='/var/hsc/log/datetime.log'
modScriptFile='/opt/hsc/bin/modHscBuildDat'

# Initialize variables that hold option values 
giveUsage=0
cmd=
dateval=
file=
clockval=
state=
timeval=

# Parse the options
while getopts 'c:d:f:k:s:t:?' optname; do
   case "$optname" in
      c) cmd="$OPTARG";;
      d) dateval="$OPTARG";;
      f) file="$OPTARG";;
      k) clockval="$OPTARG";;
      s) state="$OPTARG";;
      t) timeval="$OPTARG";;
      \?) giveUsage=1; break;;
   esac
   noopt=0
done

if [ "$giveUsage" -eq 1 ]; then
   showUsage
   exit 99
fi
      
if [ -z "$cmd" ]; then
   echo "Missing required argument command argument"
   showUsage
   exit 99
fi

#
# Handle the various requests
#

if [ "$cmd" == "queryTimezone" ]; then
   # look for timezone file/link, expect stdOut to contain path/file information
#   find /etc/localtime -type l -printf \"%l:\"
   if [ -L /etc/localtime ]; then
      # symlink'd file
      find /etc/localtime -type l -printf \"%l:\"
      findRC=$?
      if [ $findRC -eq 0 ]; then
         # (arbitrary, unique) success code
         exit 50
      else
         exit $findRC
      fi
   elif [ -f /etc/localtime ]; then
      # non-link'd file (copied from /usr/share/zoneinfo/*)
      sum /etc/localtime
      sumRC=$?
      if [ $sumRC -eq 0 ]; then
         # (arbitrary, unique) success code
         exit 51
      else
         exit $sumRC
      fi
   else
      # (non-zero) error code
      exit 1
   fi

elif [ "$cmd" == "queryDateTime" ]; then
   # read the HMC system date in expected format
   date +%Y:%m:%d:%H:%M:%S
   exit $?

elif [ "$cmd" == "removeLocaltime" ]; then
   rm -f /etc/localtime
   exit $?

elif [ "$cmd" == "copyClock" ]; then
   if [ -z "$file" ]; then
      echo "Missing required -f argument"
      showUsage
      exit 99
   fi
   cp -f $file /etc/sysconfig/clock
   exit $?

elif [ "$cmd" == "linkZone" ]; then
   if [ -z "$file" ]; then
      echo "Missing required -f argument"
      showUsage
      exit 99
   fi
   if [ ! -f $file ]; then
      # timezone file does not exist - do not allow broken link to be created
      exit 8
   else
      ln -sf $file /etc/localtime
   fi
   exit $?

elif [ "$cmd" == "modifyBuildFile" ]; then
   # simply execute the aux script
   eval $modScriptFile
   exit $?

elif [ "$cmd" == "queryNtpService" ]; then
   # issue NTP service status query
   /etc/rc.d/hmcxntpd status 2>&1 >/dev/null
   exit $?

elif [ "$cmd" == "enableNtp" ]; then
   # command to either start or stop the xntpd service
   if [ -z "$state" ]; then
      echo "Missing required -s argument"
      showUsage
      exit 99
   fi

   # issue the command
   if [ "$state" == "start" ]; then
      /etc/rc.d/hmcxntpd force_start 2>&1 >/dev/null
   else
      /etc/rc.d/hmcxntpd force_stop 2>&1 >/dev/null
   fi
   exit $?

elif [ "$cmd" == "setDateTime" ]; then
   # This request will write the description file to stdout
   if [ -z "$dateval" ]; then
      echo "Missing required -d argument"
      showUsage
      exit 99
   fi
   if [ -z "$timeval" ]; then
      echo "Missing required -t argument"
      showUsage
      exit 99
   fi
   if [ -z "$clockval" ]; then
      echo "Missing required -k argument"
      showUsage
      exit 99
   fi
   
   # Clean and start log to date/time settings
   if [ -f $log ]; then
      rm -f $log
   fi
   echo -e "Date/Time and hardware clock setting log for `date`.\n" > $log
   
   # set the system time and log it
   dateCmd="/bin/date --set=\"$dateval $timeval\""
   hwclockCmd="/sbin/hwclock --systohc $clockval"

   echo "'date' command to be issued is: $dateCmd" >> $log
   eval $dateCmd >> $log 2>&1
   dateRC=$?

   if [ $dateRC -eq 0 ]; then
      echo "'hwclock' command to be issued is: $hwclockCmd" >> $log
      eval $hwclockCmd >> $log 2>&1
      hwclockRC=$?
      if [ $hwclockRC -eq 0 ]; then
         exit_cleanup 0
      else
         echo "The 'hwclock' command failed with rc=$hwclockRC." >> $log
         exit_cleanup 7
      fi
   else
      echo "The 'date' command failed with rc=$dateRC." >> $log
      exit_cleanup 6
   fi
   exit_cleanup $?

else
   echo "Unknown command verb: $cmd"
   showUsage
   rc=99
fi
