summaryrefslogtreecommitdiffstats
path: root/dhcpcd/dhcpcd-hooks/30-hostname
diff options
context:
space:
mode:
Diffstat (limited to 'dhcpcd/dhcpcd-hooks/30-hostname')
-rw-r--r--dhcpcd/dhcpcd-hooks/30-hostname154
1 files changed, 154 insertions, 0 deletions
diff --git a/dhcpcd/dhcpcd-hooks/30-hostname b/dhcpcd/dhcpcd-hooks/30-hostname
new file mode 100644
index 00000000..616fb82a
--- /dev/null
+++ b/dhcpcd/dhcpcd-hooks/30-hostname
@@ -0,0 +1,154 @@
+# Set the hostname from DHCP data if required
+
+# A hostname can either be a short hostname or a FQDN.
+# hostname_fqdn=true
+# hostname_fqdn=false
+# hostname_fqdn=server
+
+# A value of server means just what the server says, don't manipulate it.
+# This could lead to an inconsistent hostname on a DHCPv4 and DHCPv6 network
+# where the DHCPv4 hostname is short and the DHCPv6 has an FQDN.
+# DHCPv6 has no hostname option.
+# RFC4702 section 3.1 says FQDN should be prefered over hostname.
+#
+# As such, the default is hostname_fqdn=true so that a consistent hostname
+# is always assigned.
+: ${hostname_fqdn:=true}
+
+# Some systems don't have hostname(1)
+_hostname()
+{
+ local name=
+
+ if [ -z "$1" ]; then
+ if type hostname >/dev/null 2>&1; then
+ hostname
+ elif [ -r /proc/sys/kernel/hostname ]; then
+ read name </proc/sys/kernel/hostname && echo "$name"
+ elif sysctl kern.hostname >/dev/null 2>&1; then
+ sysctl -n kern.hostname
+ elif sysctl kernel.hostname >/dev/null 2>&1; then
+ sysctl -n kernel.hostname
+ else
+ return 1
+ fi
+ return $?
+ fi
+
+ # Always prefer hostname(1) if we have it
+ if type hostname >/dev/null 2>&1; then
+ hostname "$1"
+ elif [ -w /proc/sys/kernel/hostname ]; then
+ echo "$1" >/proc/sys/kernel/hostname
+ elif sysctl kern.hostname >/dev/null 2>&1; then
+ sysctl -w "kern.hostname=$1"
+ elif sysctl kernel.hostname >/dev/null 2>&1; then
+ sysctl -w "kernel.hostname=$1"
+ else
+ # We know this will fail, but it will now fail
+ # with an error to stdout
+ hostname "$1"
+ fi
+}
+
+need_hostname()
+{
+ local hostname hfqdn=false hshort=false
+
+ case "$force_hostname" in
+ [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|1) return 0;;
+ esac
+
+ hostname="$(_hostname)"
+ case "$hostname" in
+ ""|"(none)"|localhost|localhost.localdomain) return 0;;
+ esac
+
+ case "$hostname_fqdn" in
+ [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|1) hfqdn=true;;
+ [Ss][Ee][Rr][Vv][Ee][Rr]) ;;
+ *) hshort=true;;
+ esac
+
+ if [ -n "$old_fqdn" ]; then
+ if ${hfqdn} || ! ${hsort}; then
+ [ "$hostname" = "$old_fqdn" ]
+ else
+ [ "$hostname" = "${old_fqdn%%.*}" ]
+ fi
+ elif [ -n "$old_host_name" ]; then
+ if ${hfqdn}; then
+ if [ -n "$old_domain_name" -a \
+ "$old_host_name" = "${old_host_name#*.}" ]
+ then
+ [ "$hostname" = \
+ "$old_host_name.$old_domain_name" ]
+ else
+ [ "$hostname" = "$old_host_name" ]
+ fi
+ elif ${hshort}; then
+ [ "$hostname" = "${old_host_name%%.*}" ]
+ else
+ [ "$hostname" = "$old_host_name" ]
+ fi
+ else
+ # No old hostname
+ false
+ fi
+}
+
+try_hostname()
+{
+
+ if valid_domainname "$1"; then
+ _hostname "$1"
+ else
+ syslog err "Invalid hostname: $1"
+ fi
+}
+
+set_hostname()
+{
+ local hfqdn=false hshort=false
+
+ need_hostname || return
+
+ case "$hostname_fqdn" in
+ [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|1) hfqdn=true;;
+ "") ;;
+ *) hshort=true;;
+ esac
+
+ if [ -n "$new_fqdn" ]; then
+ if ${hfqdn} || ! ${hshort}; then
+ try_hostname "$new_fqdn"
+ else
+ try_hostname "${new_fqdn%%.*}"
+ fi
+ elif [ -n "$new_host_name" ]; then
+ if ${hfqdn}; then
+ if [ -n "$new_domain_name" -a \
+ "$new_host_name" = "${new_host_name#*.}" ]
+ then
+ try_hostname "$new_host_name.$new_domain_name"
+ else
+ try_hostname "$new_host_name"
+ fi
+ elif ${hshort}; then
+ try_hostname "${new_host_name%%.*}"
+ else
+ try_hostname "$new_host_name"
+ fi
+ fi
+}
+
+# For ease of use, map DHCP6 names onto our DHCP4 names
+case "$reason" in
+BOUND6|RENEW6|REBIND6|REBOOT6|INFORM6)
+ new_fqdn="$new_dhcp6_fqdn"
+ ;;
+esac
+
+if $if_up; then
+ set_hostname
+fi