| #!/bin/sh /etc/rc.common | 
 | # Copyright (C) 2011 OpenWrt.org | 
 |  | 
 | #START=98 | 
 |  | 
 | USE_PROCD=1 | 
 | PROG=/usr/sbin/ntpd | 
 | HOTPLUG_SCRIPT=/usr/sbin/ntpd-hotplug | 
 |  | 
 | get_dhcp_ntp_servers() { | 
 | 	local interfaces="$1" | 
 | 	local filter="*" | 
 | 	local interface ntpservers ntpserver | 
 |  | 
 | 	for interface in $interfaces; do | 
 | 		[ "$filter" = "*" ] && filter="@.interface='$interface'" || filter="$filter,@.interface='$interface'" | 
 | 	done | 
 |  | 
 | 	ntpservers=$(ubus call network.interface dump | jsonfilter -e "@.interface[$filter]['data']['ntpserver']") | 
 |  | 
 | 	for ntpserver in $ntpservers; do | 
 | 		local duplicate=0 | 
 | 		local entry | 
 | 		for entry in $server; do | 
 | 			[ "$ntpserver" = "$entry" ] && duplicate=1 | 
 | 		done | 
 | 		[ "$duplicate" = 0 ] && server="$server $ntpserver" | 
 | 	done | 
 | } | 
 |  | 
 | validate_ntp_section() { | 
 | 	uci_load_validate system timeserver "$1" "$2" \ | 
 | 		'dhcp_interface:list(string)' \ | 
 | 		'enable_server:bool:0' \ | 
 | 		'enabled:bool:1' \ | 
 | 		'interface:string' \ | 
 | 		'server:list(host)' \ | 
 | 		'use_dhcp:bool:1' | 
 | } | 
 |  | 
 | start_ntpd_instance() { | 
 | 	local peer | 
 |  | 
 | 	[ "$2" = 0 ] || { | 
 | 		echo "validation failed" | 
 | 		return 1 | 
 | 	} | 
 |  | 
 | 	[ $enabled = 0 ] && return | 
 |  | 
 | 	[ $use_dhcp = 1 ] && get_dhcp_ntp_servers "$dhcp_interface" | 
 |  | 
 | 	[ -z "$server" -a "$enable_server" = "0" ] && return | 
 |  | 
 | 	procd_open_instance | 
 | 	procd_set_param command "$PROG" -n -N | 
 | 	if [ "$enable_server" = "1" ]; then | 
 | 		procd_append_param command -l | 
 | 		[ -n "$interface" ] && { | 
 | 			local ifname | 
 |  | 
 | 			network_get_device ifname "$interface" || \ | 
 | 				ifname="$interface" | 
 | 			procd_append_param command -I "$ifname" | 
 | 			procd_append_param netdev "$ifname" | 
 | 		} | 
 | 	fi | 
 | 	[ -x "$HOTPLUG_SCRIPT" ] && procd_append_param command -S "$HOTPLUG_SCRIPT" | 
 | 	for peer in $server; do | 
 | 		procd_append_param command -p $peer | 
 | 	done | 
 | #	procd_set_param respawn | 
 | 	[ -x /sbin/ujail -a -e /etc/capabilities/ntpd.json ] && { | 
 | 		procd_add_jail ntpd ubus | 
 | 		procd_add_jail_mount "$HOTPLUG_SCRIPT" | 
 | 		procd_add_jail_mount "/usr/share/libubox/jshn.sh" | 
 | 		procd_add_jail_mount "/usr/bin/env" | 
 | 		procd_add_jail_mount "/usr/bin/jshn" | 
 | 		procd_add_jail_mount "/bin/ubus" | 
 | 		procd_set_param capabilities /etc/capabilities/ntpd.json | 
 | 		procd_set_param user ntp | 
 | 		procd_set_param group ntp | 
 | 		procd_set_param no_new_privs 1 | 
 | 	} | 
 | 	procd_close_instance | 
 | } | 
 |  | 
 | start_service() { | 
 | 	. /lib/functions/network.sh | 
 | 	validate_ntp_section ntp start_ntpd_instance | 
 | } | 
 |  | 
 | service_triggers() { | 
 | 	local script name use_dhcp enable_server interface | 
 |  | 
 | 	script=$(readlink -f "$initscript") | 
 | 	name=$(basename ${script:-$initscript}) | 
 |  | 
 | 	procd_add_config_trigger "config.change" "system" /etc/init.d/$name reload | 
 |  | 
 | 	config_load system | 
 | 	config_get use_dhcp ntp use_dhcp 1 | 
 |  | 
 | 	[ $use_dhcp = 1 ] && { | 
 | 		local dhcp_interface | 
 | 		config_get dhcp_interface ntp dhcp_interface | 
 |  | 
 | 		if [ -n "$dhcp_interface" ]; then | 
 | 			for n in $dhcp_interface; do | 
 | 				procd_add_interface_trigger "interface.*" $n /etc/init.d/$name reload | 
 | 			done | 
 | 		else | 
 | 			procd_add_raw_trigger "interface.*" 1000 /etc/init.d/$name reload | 
 | 		fi | 
 | 	} | 
 |  | 
 | 	config_get_bool enable_server ntp enable_server 0 | 
 | 	config_get interface ntp interface | 
 |  | 
 | 	[ $enable_server -eq 1 ] && [ -n "$interface" ] && { | 
 | 		local ifname | 
 |  | 
 | 		network_get_device ifname "$interface" || \ | 
 | 			ifname="$interface" | 
 | 		procd_add_interface_trigger "interface.*" "$ifname" \ | 
 | 			/etc/init.d/"$name" reload | 
 | 	} | 
 |  | 
 | 	procd_add_validation validate_ntp_section | 
 | } |