# Sample dhcpcd hook script for ntp
# Like our resolv.conf hook script, we store a database of ntp.conf files
# and merge into /etc/ntp.conf

# You can set the env var NTP_CONF to another file like this
#   dhcpcd -e NTP_CONF=/usr/pkg/etc/ntpd.conf
# or by adding this to /etc/dhcpcd.enter-hook
#   NTP_CONF=/usr/pkg/etc/ntpd.conf
# to use OpenNTPD instead of the default NTP.

if type invoke-rc.d >/dev/null 2>&1; then
	# Debian has a seperate file for DHCP config to avoid stamping on
	# the master.
	[ -e /var/lib/ntp ] || mkdir /var/lib/ntp
	: ${ntp_service:=ntp}
	: ${NTP_DHCP_CONF:=/var/lib/ntp/ntp.conf.dhcp}
fi

: ${ntp_service:=ntpd}
: ${ntp_restart_cmd:=service_condcommand $ntp_service restart}
ntp_conf_dir="$state_dir/ntp.conf"

# If we have installed OpenNTPD but not NTP then prefer it
# XXX If both exist then update both?
if [ -z "$NTP_CONF" -a -e /etc/ntpd.conf -a ! -e /etc/ntp.conf ]; then
	: ${NTP_CONF:=/etc/ntpd.conf}
else
	: ${NTP_CONF:=/etc/ntp.conf}
fi

ntp_conf=${NTP_CONF}
NL="
"

build_ntp_conf()
{
	local cf="$state_dir/ntp.conf.$ifname"
	local interfaces= header= srvs= servers= x=

	# Build a list of interfaces
	interfaces=$(list_interfaces "$ntp_conf_dir")

	if [ -n "$interfaces" ]; then
		# Build the header
		for x in ${interfaces}; do
			header="$header${header:+, }$x"
		done

		# Build a server list
		srvs=$(cd "$ntp_conf_dir";
			key_get_value "server " $interfaces)
		if [ -n "$srvs" ]; then
			for x in $(uniqify $srvs); do
				servers="${servers}server $x$NL"
			done
		fi
	fi

	# Merge our config into ntp.conf
	[ -e "$cf" ] && rm -f "$cf"
	[ -d "$ntp_conf_dir" ] || mkdir -p "$ntp_conf_dir"

	if [ -n "$NTP_DHCP_CONF" ]; then
		[ -e "$ntp_conf" ] && cp "$ntp_conf" "$cf"
		ntp_conf="$NTP_DHCP_CONF"
	elif [ -e "$ntp_conf" ]; then
		remove_markers "$signature_base" "$signature_base_end" \
			"$ntp_conf" > "$cf"
	fi

	if [ -n "$servers" ]; then
		echo "$signature_base${header:+ $from }$header" >> "$cf"
		printf %s "$servers" >> "$cf"
		echo "$signature_base_end${header:+ $from }$header" >> "$cf"
	else
		[ -e "$ntp_conf" -a -e "$cf" ] || return
	fi

	# If we changed anything, restart ntpd
	if change_file "$ntp_conf" "$cf"; then
		[ -n "$ntp_restart_cmd" ] && eval $ntp_restart_cmd
	fi
}

add_ntp_conf()
{
	local cf="$ntp_conf_dir/$ifname" x=

	[ -e "$cf" ] && rm "$cf"
	[ -d "$ntp_conf_dir" ] || mkdir -p "$ntp_conf_dir"
	if [ -n "$new_ntp_servers" ]; then
		for x in $new_ntp_servers; do
			echo "server $x" >> "$cf"
		done
	fi
	build_ntp_conf
}

remove_ntp_conf()
{
	if [ -e "$ntp_conf_dir/$ifname" ]; then
		rm "$ntp_conf_dir/$ifname"
	fi
	build_ntp_conf
}

# For ease of use, map DHCP6 names onto our DHCP4 names
case "$reason" in
BOUND6|RENEW6|REBIND6|REBOOT6|INFORM6)
	new_ntp_servers="$new_dhcp6_sntp_servers"
;;
esac

if $if_up; then
	add_ntp_conf
elif $if_down; then
	remove_ntp_conf
fi
