# 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.
+
+# We store our resolvconfs in /var/run so they are cleaned at boot.
+resolvconf_dir=/var/run/dhcpcd/resolv.conf
+
+uniqify()
+{
+ local result=
+
+ while [ -n "$1" ]; do
+ case " ${result} " in
+ *" $1 "*);;
+ *) result="${result}${result:+ }$1";;
+ esac
+ shift
+ done
+ echo "${result}"
+}
+
+build_resolv_conf()
+{
+ local cf="/etc/resolv.conf.${interface}"
+ local header="${signature_base}"
+ local interfaces= search= srvs= servers= x=
+
+ # Build a list of interfaces
+ for x in "${resolvconf_dir}"/*; do
+ [ -n "${interfaces}" ] && header="${header}, "
+ header="${header}${x##*/}"
+ interfaces="${interfaces}${interfaces:+ }${x##*/}"
+ done
+
+ # Build a search list
+ for x in ${interfaces}; do
+ x="${resolvconf_dir}/${x}"
+ search="${search}${search:+ }$(sed -n 's/^search //p' "${x}")"
+ done
+ [ -n "${search}" ] && search="search $(uniqify "${search}")\n"
+
+ # Build a nameserver list
+ for x in ${interfaces}; do
+ x="${resolvconf_dir}/${x}"
+ srvs="${srvs}${srvs:+ }$(sed -n 's/^nameserver //p' "${x}")"
+ done
+ if [ -n "${srvs}" ]; then
+ for x in $(uniqify "${srvs}"); do
+ servers="${servers}nameserver ${x}\n"
+ done
+ fi
+
+ # Build our final resolv.conf
+ [ -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
+}
make_resolv_conf()
{
-z "${new_domain_search}" ]; then
return 0
fi
- local x= conf="${signature}\n" cf="/etc/resolv.conf.${interface}"
+ local x= conf="${signature}\n"
if [ -n "${new_domain_search}" ]; then
conf="${conf}search ${new_domain_search}\n"
elif [ -n "${new_domain_name}" ]; then
done
if type resolvconf >/dev/null 2>&1; then
printf "${conf}" | resolvconf -a "${interface}"
- else
- rm -f "${cf}"
- if [ -f /etc/resolv.conf.head ]; then
- cat /etc/resolv.conf.head > "${cf}"
- fi
- printf "${conf}" >> "${cf}"
- if [ -f /etc/resolv.conf.tail ]; then
- cat /etc/resolv.conf.tail >> "${cf}"
- fi
- save_conf /etc/resolv.conf
- mv -f "${cf}" /etc/resolv.conf
+ return $?
fi
+
+ if [ ! -d "${resolvconf_dir}" ]; then
+ mkdir -p "${resolvconf_dir}"
+ fi
+ if [ -e "${resolvconf_dir}/${interface}" ]; then
+ rm -f "${resolvconf_dir}/${interface}"
+ fi
+ printf "${conf}" > "${resolvconf_dir}/${interface}"
+ build_resolv_conf
}
restore_resolv_conf()
if type resolvconf >/dev/null 2>&1; then
resolvconf -d "${interface}" -f
else
- restore_conf /etc/resolv.conf || return 0
+ if [ -e "${resolvconf_dir}/${interface}" ]; then
+ rm -f "${resolvconf_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;;
+PREINIT|EXPIRE|FAIL|IPV4LL|RELEASE|STOP) restore_resolv_conf;;
esac