From: Roy Marples Date: Thu, 14 Aug 2008 10:38:15 +0000 (+0000) Subject: If resolvconf is not present, try and emulate it's functionality just for dhcpcd... X-Git-Tag: v4.0.2~37 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b78ebc2f4c93e0a0b93a839e65d70c331d8134b7;p=thirdparty%2Fdhcpcd.git If resolvconf is not present, try and emulate it's functionality just for dhcpcd so we can sanely handle >1 instance running. --- diff --git a/dhcpcd-hooks/20-resolv.conf b/dhcpcd-hooks/20-resolv.conf index b86d5837..5b02f62b 100644 --- a/dhcpcd-hooks/20-resolv.conf +++ b/dhcpcd-hooks/20-resolv.conf @@ -1,5 +1,75 @@ # 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() { @@ -8,7 +78,7 @@ 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 @@ -19,18 +89,17 @@ make_resolv_conf() 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() @@ -38,11 +107,14 @@ 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