#!/bin/sh
#
#    Copyright (c) 2005-2006 Brocade Communications Systems, Inc.
#    All rights reserved.
#
#    File name:   date
#    Module name: fabos/src/utils/sys
#
#    This script is wrapper to the traditional /bin/date command
#    to be able to save the changed date into flash. It also
#    propagates date to the counterpart CP.
#
export PATH=/fabos/sbin:/fabos/bin:/bin:/usr/bin:/sbin

SWBD_SKYBOLT=SWBD148
SWBD_AMP=SWBD171
SWBD_AWING=SWBD178

# [ Applicable for both Amp, Skyb
SKYB_AMP_DP0_IP=127.2.10.20
SKYB_AMP_DP1_IP=127.2.10.21
# ]

#
# check_time_lic_present
#
# Checks whether the temporary licenses are 
# installed on the switch
#
# Return value:
#	0 if temporary licenses are installed
#	1 if temporary licenses are not installed
#
check_time_lic_present()
{
	/fabos/libexec/lutil -t 2>&1 
	if [ $? -eq 1 ]
	then
		return 0
	else
		return 1
	fi
}

#
# swbd
#
# Retrieve the current system platform name, of the form "SWBDn", where n
# is cardinal number, assuming a sin input stream.
#
swbd()
{
    sed -n -e 's/^.\+\(SWBD[[:digit:]]\{1,\}\).\+$/\1/gp'
}

#
# set_dp_time
# 
# If Skybolt or AMP platform, sync the CP time to each DP.
# As date command on DP is trimmed down binary with less
# switches, get the CP time/date and frame a custom date
# command runnable at each DP.
#
set_dp_time() 
{
	SWBD=`/sbin/sin | swbd 2> /dev/null`

	if [ $SWBD = $SWBD_SKYBOLT ] || \
	   [ $SWBD = $SWBD_AWING ] || \
	   [ $SWBD = $SWBD_AMP ]; then
		# DP0
		ping -c 1 $SKYB_AMP_DP0_IP >/dev/null
		if [ $? -eq 0 ]; then
			# pingable, attempt DP0 time sync
			local_cp_date_time=`/bin/date '+%Y.%m.%d-%H:%M:%S'`
			rsh -n $SKYB_AMP_DP0_IP date -s $local_cp_date_time >/dev/null
			if [ $? -ne 0 ]; then
				echo "date: DP0 date/time sync failed with $?"
			fi
		else
			echo "date: $SWBD: DP0 Unreachable, skipped timesync"
		fi

		# DP1

		if [ $SWBD != $SWBD_AWING ]; then
			ping -c 1 $SKYB_AMP_DP1_IP >/dev/null
			if [ $? -eq 0 ]; then
				# pingable, attempt DP1 time sync
				local_cp_date_time=`/bin/date '+%Y.%m.%d-%H:%M:%S'`
				rsh -n $SKYB_AMP_DP1_IP date -s $local_cp_date_time >/dev/null
				if [ $? -ne 0 ]; then
					echo "date: DP1 date/time sync failed with $?"
				fi
			else
				echo "date: $SWBD: DP1 Unreachable, skipped timesync"
			fi
		fi
	fi
}


# Skip checking Director Clock Alert Mode of FICON-CUP if first param is -nDCAM
# This parameter is used when setting date through MS-API.
chk_DCAM=1
if [ "$1" = "-nDCAM" ]; then
   chk_DCAM=0
   shift
fi

if [ $? -ne 0 ]; then
	exit 127
fi

setOp=0
if [ $# -gt 1 ]; then
	args=$(echo $* | tr ' ' '\n')
	for arg in $args
	do
		if [ `echo $arg |cut -c -2` = "-s" -o `echo $arg |cut -c -3` = "--s" ]; then
			setOp=1
		fi
	done
fi

if [ $# -eq 0 ]; then
   /bin/date
elif [ $# -eq 1 ] || \
     [ "$1" = "-u" ] || \
     [ "$1" = "--utc" ] || \
     [ "$1" = "--universal" ] || \
     [ $setOp -eq 1 ] || \
     [ `echo $1|cut -d' ' -f1|  wc --bytes 2> /dev/null` -gt 2  -a \
       `echo $1 |cut -c -2 2> /dev/null` = "-s"	] || \
     [ `echo $1|cut -d' ' -f1|  wc --bytes 2> /dev/null` -gt 2  -a \
       `echo $1 |cut -c -3 2> /dev/null` = "--s" ]; then

        #user=`/usr/bin/whoami`
	user=`echo $SWLOGNAME`
#Find whether it is read or write command.


        if [ `echo $1|cut -d' ' -f1|  wc --bytes 2> /dev/null` -gt 2 ] && [ `echo $1 |cut -c -2` = "-s" \
              -o `echo $1 |cut -c -3` = "--s" ]; then
               setOp=2
        elif [ $# -eq 1 ]; then
	       arg=`echo $1 |cut -c -1`
               if [ "$arg" != "-" \
                    -a "$arg" != "+" ]; then
	            setOp=2
	       fi
	elif [ $# -gt 1 ]; then
               if [ "$1" = "-u" \
         	    -o "$1" = "--utc" \
                    -o "$1" = "--universal" ]; then
		  setOp=3
               fi
	fi

	#Check for Time based licenses.
	if [ $setOp -eq 1 -o $setOp -eq 2 -o $setOp -eq 3 ]; then
		# Check whether the temporary licenses are 
		# installed on the switch
		check_time_lic_present
		ret_val=$?
		if [ $ret_val -eq 0 ]; then
			# Temporary licenses are installed
			# Exit without changing the date
			echo "Cannot change the date since temporary licenses are installed on the switch"
			exit
		fi

		/fabos/sbin/eos_check
		if [ $? -eq 1 ];then
			# EOS time reached
			# Exit without changing the date
			exit
		fi
	fi

#Check for active CP or non Ulys switch. 
	chassis_info=`getchassisconfig`
	ischassis=`echo $chassis_info | \
		sed -n -e 's/.*Chassis based system: //gp' | \
		sed -n -e 's/ .*//gp'`
	num_switches=`echo $chassis_info | \
		sed -n -e 's/Number of switches: //gp' | \
		sed -n -e 's/ .*//gp'`
	if [ "$ischassis" = "Yes" ]; then
		cp=`/fabos/bin/hashow | /bin/grep Local | \
	    /bin/sed -e "s/[ ]*//g" | /usr/bin/cut -d: -f2 | \
	    /usr/bin/cut -d, -f1 2> /dev/null`
	fi

	if [ $setOp -eq 0 ]; then
	        /bin/date "$*"
#It is a write command so check if it is Active CP.
        elif [ "$cp" = "Active" -o "$ischassis" != "Yes" ]; then

#Check with Time Service if date can be changed
             /fabos/cliexec/tsIsUpdatable

# ERROR is non-zero; OK is zero
             ts_ret=$?

             if [ $ts_ret -ne 0 ]; then
                 exit
             fi

#
# Warn the user if the Director Clock Alert Mode of FICON-CUP is ON.
# This check is not performed for Access Gateway
#
	     AG_FILENAME=/etc/fabos/ag_platform.$FABOS_SWITCHNO
	     if [ -f $AG_FILENAME ]; then
	             SWITCH_AGMODE=1
	     else
	             SWITCH_AGMODE=0
	     fi
	     if [ $SWITCH_AGMODE -eq 0 -a $chk_DCAM -eq 1 ]; then
                 ficoncupshow modereg DCAM |grep 1  > /dev/null 2>&1
                 if [ $? -eq 0 ]; then
                    echo "date: Warning! Director time stamp is about to be modified."
                    echo "      Do you want to continue? [y/n] :"
                    read response
                    if [ "$response" != "y" -a "$response" != "Y" ]; then
                        echo "date: Aborting date modification..."
                        exit
                    fi
                 fi
             fi
		# setOp as 1 and 2 are same except for arguments passed to /bin/date,
		#option +%T won't work with "".
		if [ $setOp -eq 1 ]; then
		    olddate=$(/bin/date +"%D-%T");
	            /bin/date $* 2> /dev/null
         	    if [ $? -eq 1 ]; then
			echo "Failed: Invalid argument passed"
			exit 1
		     fi
		     newdate=$(/bin/date +"%D-%T");
		   # date change notify to raslogd quiet time 
		   /fabos/cliexec/quietdatechange
		elif [ $setOp -eq 2 ]; then
                    olddate=$(/bin/date +"%D-%T");
                    /bin/date "$*" 2> /dev/null
                    if [ $? -eq 1 ]; then
	                    echo "Failed: Invalid argument passed"
        	            exit 1
                    fi
                     newdate=$(/bin/date +"%D-%T");
                   # date change notify to raslogd quiet time
                   /fabos/cliexec/quietdatechange
		else
		   olddate=$(/bin/date +"%D-%T");
	           /bin/date $*	2> /dev/null
		   newdate=$(/bin/date +"%D-%T");
		fi

                if [ $? -eq 0 ]; then

                   /sbin/hwclock -w --utc
				   set_dp_time
#Find if counterpart CP exists and then proceed.
                   output=`/sbin/sin|grep "Processor No"  2> /dev/null`
	           if [ $? -eq 0 ]; then	
                      IDX=`sin |grep "Processor No"| cut -d: -f2 2> /dev/null`
                      if [ $IDX -eq 0 ]; then
                         RIDX=6
                      else
                         RIDX=5
                      fi
		   fi

	           output=`/fabos/bin/hashow 2>/dev/null`	
                   if [ $? -eq 0 -a "$cp" = "Active" ]; then
                      redundant=`/fabos/bin/hashow |grep "Remote" |cut -d' ' -f6 2> /dev/null`
		      if [ "$redundant" = "Standby" -a $setOp -eq 1 ] || \
			 [ "$redundant" = "Standby" -a $setOp -eq 2 ]; then
                         /usr/bin/rsh 10.0.0.$RIDX rdate -s 10.0.0.`expr $IDX + 5`
	              elif [ "$redundant" = "Standby" -a $setOp -eq 3 ]; then
                         /usr/bin/rsh 10.0.0.$RIDX /bin/date $*
	              fi		
		
                      if [ "$redundant" = "Standby" -a $? -eq 0 ]; then
                         /usr/bin/rsh 10.0.0.$RIDX /sbin/hwclock -w --utc
                      fi
                   fi
                fi
# Propagate date change to fabric
                /fabos/rbin/tsDateChange $olddate $newdate
		
        else # if [ $? -eq 0 ] date write command successful
           echo "date: cannot set date: operation not permitted"
        fi
else
	check_time_lic_present
	ret_val=$?
	if [ $ret_val -eq 0 ]; then
		# Temporary licenses are installed
		# Exit without changing the date
		echo "Cannot change the date since temporary licenses are installed on the switch"
		exit
	fi

	/fabos/sbin/eos_check
	if [ $? -eq 1 ];then
		# EOS time reached
		# Exit without changing the date
		exit
	fi

	/bin/date $* 2> /dev/null 
fi

