1becca085Sroy# Set the hostname from DHCP data if required
2becca085Sroy
3becca085Sroy# A hostname can either be a short hostname or a FQDN.
4becca085Sroy# hostname_fqdn=true
5becca085Sroy# hostname_fqdn=false
6becca085Sroy# hostname_fqdn=server
7becca085Sroy
8becca085Sroy# A value of server means just what the server says, don't manipulate it.
9becca085Sroy# This could lead to an inconsistent hostname on a DHCPv4 and DHCPv6 network
10becca085Sroy# where the DHCPv4 hostname is short and the DHCPv6 has an FQDN.
11becca085Sroy# DHCPv6 has no hostname option.
12becca085Sroy# RFC4702 section 3.1 says FQDN should be prefered over hostname.
13becca085Sroy#
14becca085Sroy# As such, the default is hostname_fqdn=true so that a consistent hostname
15becca085Sroy# is always assigned.
16becca085Sroy: ${hostname_fqdn:=true}
17becca085Sroy
18becca085Sroy# If we used to set the hostname, but relinquish control of it, we should
19becca085Sroy# reset to the default value.
20becca085Sroy: ${hostname_default=}
21becca085Sroy
22becca085Sroy# Some systems don't have hostname(1)
23becca085Sroy_hostname()
24becca085Sroy{
25becca085Sroy	if [ -z "${1+x}" ]; then
26becca085Sroy		if [ -r /proc/sys/kernel/hostname ]; then
27becca085Sroy			read name </proc/sys/kernel/hostname && echo "$name"
28*3de1d4c3Sroy		elif command -v hostname >/dev/null 2>/dev/null; then
29becca085Sroy			hostname
30becca085Sroy		elif sysctl kern.hostname >/dev/null 2>&1; then
31becca085Sroy			sysctl -n kern.hostname
32becca085Sroy		elif sysctl kernel.hostname >/dev/null 2>&1; then
33becca085Sroy			sysctl -n kernel.hostname
34becca085Sroy		else
35becca085Sroy			return 1
36becca085Sroy		fi
37becca085Sroy		return $?
38becca085Sroy	fi
39becca085Sroy
40becca085Sroy	if [ -w /proc/sys/kernel/hostname ]; then
41becca085Sroy		echo "$1" >/proc/sys/kernel/hostname
42*3de1d4c3Sroy	elif [ -n "$1" ] && command -v hostname >/dev/null 2>&1; then
43becca085Sroy		hostname "$1"
44becca085Sroy	elif sysctl kern.hostname >/dev/null 2>&1; then
45becca085Sroy		sysctl -w "kern.hostname=$1" >/dev/null
46becca085Sroy	elif sysctl kernel.hostname >/dev/null 2>&1; then
47becca085Sroy		sysctl -w "kernel.hostname=$1" >/dev/null
48becca085Sroy	else
49becca085Sroy		# May fail to set a blank hostname
50becca085Sroy		hostname "$1"
51becca085Sroy	fi
52becca085Sroy}
53becca085Sroy
54becca085Sroyis_default_hostname()
55becca085Sroy{
56becca085Sroy	case "$1" in
57becca085Sroy	""|"$hostname_default"|localhost|localhost.localdomain)
58becca085Sroy		return 0;;
59becca085Sroy	esac
60becca085Sroy	return 1
61becca085Sroy}
62becca085Sroy
63becca085Sroyneed_hostname()
64becca085Sroy{
65becca085Sroy	# Always load the hostname variable for future use
66becca085Sroy	hostname="$(_hostname)"
67becca085Sroy	is_default_hostname "$hostname" && return 0
68becca085Sroy
69becca085Sroy	case "$force_hostname" in
70becca085Sroy	[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|1) return 0;;
71becca085Sroy	esac
72becca085Sroy
73becca085Sroy	if [ -n "$old_fqdn" ]; then
74becca085Sroy		if ${hfqdn} || ! ${hshort}; then
75becca085Sroy			[ "$hostname" = "$old_fqdn" ]
76becca085Sroy		else
77becca085Sroy			[ "$hostname" = "${old_fqdn%%.*}" ]
78becca085Sroy		fi
79becca085Sroy	elif [ -n "$old_host_name" ]; then
80becca085Sroy		if ${hfqdn}; then
81becca085Sroy			if [ -n "$old_domain_name" ] &&
82becca085Sroy			   [ "$old_host_name" = "${old_host_name#*.}" ]
83becca085Sroy			then
84becca085Sroy				[ "$hostname" = \
85becca085Sroy				    "$old_host_name.$old_domain_name" ]
86becca085Sroy			else
87becca085Sroy				[ "$hostname" = "$old_host_name" ]
88becca085Sroy			fi
89becca085Sroy		elif ${hshort}; then
90becca085Sroy			[ "$hostname" = "${old_host_name%%.*}" ]
91becca085Sroy		else
92becca085Sroy			[ "$hostname" = "$old_host_name" ]
93becca085Sroy		fi
94becca085Sroy	else
95becca085Sroy		# No old hostname
96becca085Sroy		false
97becca085Sroy	fi
98becca085Sroy}
99becca085Sroy
100becca085Sroytry_hostname()
101becca085Sroy{
102becca085Sroy	[ "$hostname" = "$1" ] && return 0
103becca085Sroy	if valid_domainname "$1"; then
104becca085Sroy		syslog info "Setting hostname: $1"
105becca085Sroy		_hostname "$1"
106becca085Sroy	else
107becca085Sroy		syslog err "Invalid hostname: $1"
108becca085Sroy	fi
109becca085Sroy}
110becca085Sroy
111becca085Sroyset_hostname()
112becca085Sroy{
113becca085Sroy	hfqdn=false
114becca085Sroy	hshort=false
115becca085Sroy	case "$hostname_fqdn" in
116becca085Sroy	[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|1)	hfqdn=true;;
117becca085Sroy	""|[Ss][Ee][Rr][Vv][Ee][Rr])		;;
118becca085Sroy	*)					hshort=true;;
119becca085Sroy	esac
120becca085Sroy
121becca085Sroy	need_hostname || return
122becca085Sroy
123becca085Sroy	if [ -n "$new_fqdn" ]; then
124becca085Sroy		if ${hfqdn} || ! ${hshort}; then
125becca085Sroy			try_hostname "$new_fqdn"
126becca085Sroy		else
127becca085Sroy			try_hostname "${new_fqdn%%.*}"
128becca085Sroy		fi
129becca085Sroy	elif [ -n "$new_host_name" ]; then
130becca085Sroy		if ${hfqdn}; then
131becca085Sroy			if [ -n "$new_domain_name" ] &&
132becca085Sroy			   [ "$new_host_name" = "${new_host_name#*.}" ]
133becca085Sroy			then
134becca085Sroy				try_hostname "$new_host_name.$new_domain_name"
135becca085Sroy			else
136becca085Sroy				try_hostname "$new_host_name"
137becca085Sroy			fi
138becca085Sroy		elif ${hshort}; then
139becca085Sroy			try_hostname "${new_host_name%%.*}"
140becca085Sroy		else
141becca085Sroy			try_hostname "$new_host_name"
142becca085Sroy		fi
143becca085Sroy	elif ! is_default_hostname "$hostname"; then
144becca085Sroy		try_hostname "$hostname_default"
145becca085Sroy	fi
146becca085Sroy}
147becca085Sroy
148becca085Sroy# For ease of use, map DHCP6 names onto our DHCP4 names
149becca085Sroycase "$reason" in
150becca085SroyBOUND6|RENEW6|REBIND6|REBOOT6|INFORM6)
151becca085Sroy	new_fqdn="$new_dhcp6_fqdn"
152becca085Sroy	old_fqdn="$old_dhcp6_fqdn"
153becca085Sroy	;;
154becca085Sroyesac
155becca085Sroy
156becca085Sroyif $if_configured && $if_up && [ "$reason" != ROUTERADVERT ]; then
157becca085Sroy	set_hostname
158becca085Sroyfi
159