Initial commit from resolvconf-gentoo-1.4
[openresolv] / update.d / libc
1 #!/bin/sh
2 # Copyright 2006 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
4
5 # libc resolv.conf updater
6
7 # Written by Roy Marples (uberlord@gentoo.org)
8 # Heavily based on Debian resolvconf by Thomas Hood
9
10 [ "$(readlink /etc/resolv.conf 2>/dev/null)" \
11         != "resolvconf/run/resolv.conf" ] && exit 0
12
13 RESOLVCONF="$(resolvconf -l)"
14 BASE="/etc/resolvconf/resolv.conf.d/base"
15
16 uniqify() {
17     local result=
18     while [ -n "$1" ] ; do
19                 case " ${result} " in
20                         *" $1 "*) ;;
21                         *) result="${result} $1" ;;
22                 esac
23                 shift
24         done
25     echo "${result# *}"
26 }
27
28 OUR_NS=
29 if [ -e "${BASE}" ] ; then
30         OUR_NS="$(sed -n -e 's/^[[:space:]]*nameserver[[:space:]]*//p' "${BASE}")"
31 fi
32 OUR_NS="$(uniqify \
33         ${OUR_NS} \
34         $(echo "${RESOLVCONF}" \
35         | sed -n -e 's/^[[:space:]]*nameserver[[:space:]]*//p') \
36 )"
37
38 # libc only allows for 3 nameservers
39 # truncate after 127 as well
40 i=0
41 NS=
42 LOCALH=false
43 for N in ${OUR_NS} ; do
44         i=$((${i} + 1))
45         NS="${NS} ${N}"
46         [ "${i}" = "3" ] && break
47         case "${N}" in
48                 127.*) LOCALH=true; break ;;
49         esac
50 done
51
52 # This is nasty!
53 # If we have a local nameserver then assume they are intelligent enough
54 # to be forwarding domain requests to the correct nameserver and not search
55 # ones. This means we prefer search then domain, otherwise, we use them in
56 # the order given to us.
57 OUR_SEARCH=
58 if ${LOCALH} ; then
59         if [ -e "${BASE}" ] ; then
60                 OUR_SEARCH="$(sed -n -e 's/^[[:space:]]*search[[:space:]]*//p' "${BASE}")"
61         fi
62         OUR_SEARCH="${OUR_SEARCH} $(echo "${RESOLVCONF}" \
63                 | sed -n 's/^[[:space:]]*search[[:space:]]*//p')"
64         if [ -e "${BASE}" ] ; then
65                 OUR_SEARCH="${OUR_SEARCH} $(sed -n -e 's/^[[:space:]]*domain[[:space:]]*//p' "${BASE}")"
66         fi
67         OUR_SEARCH="${OUR_SEARCH} $( echo "${RESOLVCONF}" \
68                 | sed -n -e 's/^[[:space:]]*domain[[:space:]]*//p')"
69 else
70         if [ -e "${BASE}" ] ; then
71                 OUR_SEARCH="$(sed -n -e 's/^[[:space:]]*search[[:space:]]*//p' \
72                         -e 's/^[[:space:]]*domain[[:space:]]*//p' "${BASE}")"
73         fi
74         OUR_SEARCH="${OUR_SEARCH} $(echo "${RESOLVCONF}" \
75                 | sed -n -e 's/^[[:space:]]*search[[:space:]]*//p' \
76                         -e 's/^[[:space:]]*domain[[:space:]]*//p')"
77 fi
78
79 # libc only allows for 6 search domains 
80 i=0
81 SEARCH=
82 for S in $(uniqify ${OUR_SEARCH}) ; do
83         i=$((${i} + 1))
84         SEARCH="${SEARCH} ${S}"
85         [ "${i}" = "6" ] && break
86 done
87 [ -n "${SEARCH}" ] && SEARCH="search${SEARCH}"
88
89 # Hold our new resolv.conf in a variable to save on temporary files
90 NEWCONF="# Generated by resolvconf\n"
91 [ -e /etc/resolvconf/resolv.conf.d/head ] \
92         && NEWCONF="${NEWCONF}$(cat /etc/resolvconf/resolv.conf.d/head)\n"
93 [ -n "${SEARCH}" ] && NEWCONF="${NEWCONF}${SEARCH}\n"
94 for N in ${NS} ; do
95         NEWCONF="${NEWCONF}nameserver ${N}\n"
96 done
97
98 # Now dump everything else from our resolvs
99 if [ -e "${BASE}" ] ; then
100         NEWCONF="${NEWCONF}$(sed -e '/^[[:space:]]*$/d' \
101                 -e '/^[[:space:]]*nameserver[[:space:]]*.*/d' \
102                 -e '/^[[:space:]]*search[[:space:]]*.*/d' \
103                 -e '/^[[:space:]]*domain[[:space:]]*.*/d' \
104                 "${BASE}")" 
105 fi
106
107 # We don't know we're using GNU sed, so we do it like this
108 NEWCONF="${NEWCONF}$(echo "${RESOLVCONF}" | sed -e '/^[[:space:]]*$/d' \
109         -e '/^[[:space:]]*#/d' \
110         -e '/^[[:space:]]*nameserver[[:space:]]*.*/d' \
111         -e '/^[[:space:]]*search[[:space:]]*.*/d' \
112         -e '/^[[:space:]]*domain[[:space:]]*.*/d' \
113         )"
114 [ -e /etc/resolvconf/resolv.conf.d/tail ] \
115         && NEWCONF="${NEWCONF}$(cat /etc/resolvconf/resolv.conf.d/tail)"
116
117 # Check if the file has actually changed or not
118 if [ -e /etc/resolv.conf ] ; then
119         [ "$(cat /etc/resolv.conf)" = "$(printf "${NEWCONF}")" ] && exit 0
120 fi
121
122 # Create our resolv.conf now
123 printf "${NEWCONF}" > /etc/resolvconf/run/resolv.conf
124
125 # Restart nscd if it's running
126 if [ -x /etc/init.d/nscd ] ; then
127         /etc/init.d/nscd --nodeps --quiet conditionalrestart
128 fi
129
130 # Notify users of the resolver
131 for x in /etc/resolvconf/update-libc.d/* ; do
132         [ -e "${x}" ] && "${x}" "$@"
133 done
134
135 # vim: ts=4 :