]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
If resolvconf is not present, try and emulate it's functionality just for dhcpcd...
authorRoy Marples <roy@marples.name>
Thu, 14 Aug 2008 10:38:15 +0000 (10:38 +0000)
committerRoy Marples <roy@marples.name>
Thu, 14 Aug 2008 10:38:15 +0000 (10:38 +0000)
dhcpcd-hooks/20-resolv.conf

index b86d5837a31cff2c67ce90d1871007f6d647acd8..5b02f62bf7ed4b7c989f013be0f4b3cbcc768611 100644 (file)
@@ -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