#! /bin/sh
#
# System-V init script for the NTP daemon
#

. /usr/local/bin/telem/gps_functions

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC="network time protocol daemon"
NAME=ntpd
DAEMON=/usr/sbin/$NAME
#NTPDATE_BIN=/usr/bin/ntpdate
CONFIGFILE=/etc/ntp.conf

# Gracefully exit if the package has been removed.
test -x $DAEMON || exit 0

# Read config file if it is present.
if [ -r /etc/default/$NAME ]
then
	. /etc/default/$NAME
fi

NTPDATE_PROBLEM_FILE=/var/local/telem/errors/ntpdate

getInitialTime() {
	# parse ntpdate options
	vTimeout=15
	while : ; do
		case "$1" in
		-t)	# set timeout
			case "$#" in 1) logger -s -p "user.info" -t "$0" "Missing timeout value" ;; esac; shift
			[ -n "$1" ] && vTimeout=$1
			;;
		--)	# end of options, must use to exit loop
			shift
			break
			;;
		*)	# ignore other options
			shift
			;;
		esac
		shift
	done
	# Give more time for GPS
	[ -z "$NTPSERVERS" ] && [ "$vTimeout" -lt "20" ] && vTimeout=20
	# 5 seconds should be minimum, because it may take 5 samples to get time, depending on the server
	# on ntpdate -t 1 meant response timeout from server, but we can not check it with ntpd.
	[ "$vTimeout" -lt "15" ] && vTimeout=15
	tmpfile_ntpd_init="/tmp/ntpd_get_initial_time"
	# ntpd -q is equivalent to ntpdate, but is missing timeout option
	# -q	Set the time and quit.
	# -g	Allow the first adjustment to be Big.
	# -c	configuration file name.
	# -d	debug
	# -n	Do not fork
	# ntpd will get time from whatever source is good: GPS or configured ntp servers
	touch "$tmpfile_ntpd_init"
	(
		# There should be no other ntpd running
		logger -s -p "user.info" -t "$0" "Getting initial time"
		if ntpd -q -n -g -d -c "$CONFIGFILE" &> "/var/log/telem/ntpd_initial_time.log"; then
			logger -s -p "user.info" -t "$0" "Done getting initial time"
		else
			logger -s -p "user.info" -t "$0" "Failed getting initial time"
		fi
		rm "$tmpfile_ntpd_init"
		
	) &
	sleep 1
	i="0"
	# Here we simulate ntpdate timeout
	while [ -f "$tmpfile_ntpd_init" ] && [ "$i" -lt "$vTimeout" ]; do
		i=$((i+1))
		sleep 1
	done
	[ -f "$tmpfile_ntpd_init" ] && {
		logger -s -p "user.info" -t "$0" "Getting initial time timed out after $vTimeout seconds"
		killall -9 ntpd
		echo "killtime $(date)" >> "/var/log/telem/ntpd_initial_time.log"
		return 1
	}
	return 0
}

telemapp3224() {
	# Hack for telem-app #3224
	mkdir -p '/tmp/telem'
	touch    '/tmp/telem/ntp_init_ok'
}

setup() {
	if isGPSttyEnabled; then
		CONFIGFILE=/etc/ntp-run.conf
		TIME1_CORRECTION=0.0
		[ -e /usr/local/etc/telem/gps_time1_correction ] && TIME1_CORRECTION=$(cat /usr/local/etc/telem/gps_time1_correction)
		
		echo "# THIS FILE IS AUTOMATICALLY GENERATED, ALL CHANGES TO THIS FILE WILL BE LOST!" > $CONFIGFILE
		
		cat /etc/ntp.conf >> $CONFIGFILE
		
		echo "
# GPS sync with NMEA and PPS kernel discipline

# GPS synchronization with NMEA data and kernel PPS
server 127.127.20.0 mode 17 minpoll 4 maxpoll 4 prefer
fudge 127.127.20.0 time1 $TIME1_CORRECTION time2 0.133 flag1 1 flag3 1
" >> $CONFIGFILE
	fi
}

start() {
	stop
	setup

	logger -s -p "user.info" -t "$0" "Starting NTP service"
	doGetInitialTime=false
	isGPSttyEnabled && doGetInitialTime=true
	[ "$NTPDATE" = "yes" ] && [ ! -z "$NTPSERVERS" ] && doGetInitialTime=true
	if $doGetInitialTime; then
		if getInitialTime $NTPDATE_OPTS -- ; then 
			# getting time went well, update clock
			hwclock -w -u
			telemapp3224
			rm -f "$NTPDATE_PROBLEM_FILE" 2>/dev/null
		else
			touch "$NTPDATE_PROBLEM_FILE"
		fi
	fi

	if [ "$NTPD" = "yes" ]; then
		logger -s -p "user.info" -t "$0" "Starting $DESC: $NAME"
		/usr/local/bin/ntp/StartNTP &> /dev/null &
		echo "."
	fi
}

stop() {
	logger "Killing NTP service"
	busybox kill -9 $(pidof -x $(basename $0) -o %PPID) 2>/dev/null # S49ntp might still be starting things up
	busybox killall -9 StartNTP
	busybox killall -9 ntpd
	busybox killall -9 ntpdate 2>/dev/null # may not be running
	killall check_ntp_status 2>/dev/null # may not be running
}

restart() {
	safeRestart
}

ntp_reset_lockFile="/tmp/ntpd_reset_lock"
safeRestart() {
	# restart only if there are servers
	if [ -n "$NTPSERVERS" ]; then
		if [ ! -e "$ntp_reset_lockFile" ]; then
			touch "$ntp_reset_lockFile"
			(
				# restart after 6 seconds, because there may be many request in short time from multiple processes.
				while [ "$(find "$ntp_reset_lockFile" -mmin -0.1 -mmin +0 2>/dev/null)" == "$ntp_reset_lockFile" ]; do
					sleep 2
				done
				start # stop is inside start
				rm "$ntp_reset_lockFile"
			) &
		else
			# just update time to postpone restart
			touch "$ntp_reset_lockFile"
		fi
	fi
}

forceRestart() {
	start # stop is inside start
}

case "$1" in
	start)
		start
		;;
	stop)
		stop
		;;
	restart|reload)
		restart
		;;
	force-restart)
		forceRestart
		;;
	safe-restart)
		safeRestart
		;;
	*)
		echo "Usage: $0 {start|stop|restart|force-restart|safe-restart}"
		exit 1
esac

exit $?
