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