aboutsummaryrefslogtreecommitdiffstats
path: root/dhcpcd-hooks/20-resolv.conf
diff options
context:
space:
mode:
Diffstat (limited to 'dhcpcd-hooks/20-resolv.conf')
-rw-r--r--dhcpcd-hooks/20-resolv.conf87
1 files changed, 77 insertions, 10 deletions
diff --git a/dhcpcd-hooks/20-resolv.conf b/dhcpcd-hooks/20-resolv.conf
index 437c116..e757ddf 100644
--- a/dhcpcd-hooks/20-resolv.conf
+++ b/dhcpcd-hooks/20-resolv.conf
@@ -1,14 +1,71 @@
# Generate /etc/resolv.conf
# Support resolvconf(8) if available
+# We can merge other dhcpcd resolv.conf files into one like resolvconf,
+# but resolvconf is preferred as other applications like VPN clients
+# can readily hook into it.
+# Also, resolvconf can configure local nameservers such as bind
+# or dnsmasq. This is important as the libc resolver isn't that powerful.
-make_resolv_conf()
+resolv_conf_dir="${state_dir}/resolv.conf"
+
+build_resolv_conf()
+{
+ local cf="/etc/resolv.conf.${interface}"
+ local interfaces= header= search= srvs= servers= x=
+
+ # Build a list of interfaces
+ interfaces=$(list_interfaces "${resolv_conf_dir}")
+
+ # Build the resolv.conf
+ if [ -n "${interfaces}" ]; then
+ # Build the header
+ for x in ${interfaces}; do
+ header="${header}${header:+, }${x}"
+ done
+
+ # Build the search list
+ search=$(cd "${resolv_conf_dir}"; \
+ key_get_value "search " ${interfaces})
+ [ -n "${search}" ] && search="search $(uniqify ${search})\n"
+
+ # Build the nameserver list
+ srvs=$(cd "${resolv_conf_dir}"; \
+ key_get_value "nameserver " ${interfaces})
+ for x in $(uniqify ${srvs}); do
+ servers="${servers}nameserver ${x}\n"
+ done
+ fi
+ header="${signature_base}${header:+ ${from} }${header}"
+
+ # Assemble resolv.conf using our head and tail files
+ [ -f "${cf}" ] && rm -f "${cf}"
+ echo "${header}" > "${cf}"
+ if [ -f /etc/resolv.conf.head ]; then
+ cat /etc/resolv.conf.head >> "${cf}"
+ else
+ echo "# /etc/resolv.conf.head can replace this line" >> "${cf}"
+ fi
+ printf "${search}${servers}" >> "${cf}"
+ if [ -f /etc/resolv.conf.tail ]; then
+ cat /etc/resolv.conf.tail >> "${cf}"
+ else
+ echo "# /etc/resolv.conf.tail can replace this line" >> "${cf}"
+ fi
+ mv -f "${cf}" /etc/resolv.conf
+}
+
+add_resolv_conf()
{
+ local x= conf="${signature}\n"
+
+ # If we don't have any configuration, remove it
if [ -z "${new_domain_name_servers}" -a \
-z "${new_domain_name}" -a \
-z "${new_domain_search}" ]; then
- return 0
+ remove_resolv_conf
+ return $?
fi
- local x= conf="${signature}\n"
+
if [ -n "${new_domain_search}" ]; then
conf="${conf}search ${new_domain_search}\n"
elif [ -n "${new_domain_name}" ]; then
@@ -19,22 +76,32 @@ make_resolv_conf()
done
if type resolvconf >/dev/null 2>&1; then
printf "${conf}" | resolvconf -a "${interface}"
- else
- save_conf /etc/resolv.conf
- printf "${conf}" > /etc/resolv.conf
+ return $?
+ fi
+
+ if [ -e "${resolv_conf_dir}/${interface}" ]; then
+ rm -f "${resolv_conf_dir}/${interface}"
+ fi
+ if [ ! -d "${resolv_conf_dir}" ]; then
+ mkdir -p "${resolv_conf_dir}"
fi
+ printf "${conf}" > "${resolv_conf_dir}/${interface}"
+ build_resolv_conf
}
-restore_resolv_conf()
+remove_resolv_conf()
{
if type resolvconf >/dev/null 2>&1; then
resolvconf -d "${interface}" -f
else
- restore_conf /etc/resolv.conf || return 0
+ if [ -e "${resolv_conf_dir}/${interface}" ]; then
+ rm -f "${resolv_conf_dir}/${interface}"
+ fi
+ build_resolv_conf
fi
}
case "${reason}" in
-BOUND|INFORM|REBIND|REBOOT|RENEW|TIMEOUT) make_resolv_conf;;
-EXPIRE|FAIL|IPV4LL|RELEASE|STOP) restore_resolv_conf;;
+BOUND|INFORM|REBIND|REBOOT|RENEW|TIMEOUT) add_resolv_conf;;
+PREINIT|EXPIRE|FAIL|IPV4LL|RELEASE|STOP) remove_resolv_conf;;
esac