Fix typo
[openresolv] / libc.in
1 #!/bin/sh
2 # Copyright 2006 Gentoo Foundation
3 # Copyright 2007 Roy Marples
4 # All rights reserved
5
6 # libc subscriber for resolvconf 
7
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions
10 # are met:
11 #     * Redistributions of source code must retain the above copyright
12 #       notice, this list of conditions and the following disclaimer.
13 #     * Redistributions in binary form must reproduce the above
14 #       copyright notice, this list of conditions and the following
15 #       disclaimer in the documentation and/or other materials provided
16 #       with the distribution.
17 #
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 PREFIX=
31 RESOLVCONF="${PREFIX}"/etc/resolvconf
32 RESOLVCONFS="$(resolvconf -l)"
33 BASE="${RESOLVCONF}/resolv.conf.d/base"
34
35 uniqify() {
36     local result=
37     while [ -n "$1" ]; do
38                 case " ${result} " in
39                         *" $1 "*) ;;
40                         *) result="${result} $1" ;;
41                 esac
42                 shift
43         done
44     echo "${result# *}"
45 }
46
47 OUR_NS=
48 if [ -e "${BASE}" ]; then
49         OUR_NS="$(sed -n -e 's/^[[:space:]]*nameserver[[:space:]]*//p' "${BASE}")"
50 fi
51 OUR_NS="$(uniqify \
52         ${OUR_NS} \
53         $(echo "${RESOLVCONFS}" \
54         | sed -n -e 's/^[[:space:]]*nameserver[[:space:]]*//p') \
55 )"
56
57 # libc only allows for 3 nameservers
58 # truncate after 127 as well
59 i=0
60 NS=
61 LOCALH=false
62 for N in ${OUR_NS}; do
63         i=$((${i} + 1))
64         NS="${NS} ${N}"
65         [ "${i}" = "3" ] && break
66         case "${N}" in
67                 127.*) LOCALH=true; break ;;
68         esac
69 done
70
71 # This is nasty!
72 # If we have a local nameserver then assume they are intelligent enough
73 # to be forwarding domain requests to the correct nameserver and not search
74 # ones. This means we prefer search then domain, otherwise, we use them in
75 # the order given to us.
76 OUR_SEARCH=
77 if ${LOCALH} ; then
78         if [ -e "${BASE}" ]; then
79                 OUR_SEARCH="$(sed -n -e 's/^[[:space:]]*search[[:space:]]*//p' "${BASE}")"
80         fi
81         OUR_SEARCH="${OUR_SEARCH} $(echo "${RESOLVCONFS}" \
82                 | sed -n 's/^[[:space:]]*search[[:space:]]*//p')"
83         if [ -e "${BASE}" ]; then
84                 OUR_SEARCH="${OUR_SEARCH} $(sed -n -e 's/^[[:space:]]*domain[[:space:]]*//p' "${BASE}")"
85         fi
86         OUR_SEARCH="${OUR_SEARCH} $( echo "${RESOLVCONFS}" \
87                 | sed -n -e 's/^[[:space:]]*domain[[:space:]]*//p')"
88 else
89         if [ -e "${BASE}" ]; then
90                 OUR_SEARCH="$(sed -n -e 's/^[[:space:]]*search[[:space:]]*//p' \
91                         -e 's/^[[:space:]]*domain[[:space:]]*//p' "${BASE}")"
92         fi
93         OUR_SEARCH="${OUR_SEARCH} $(echo "${RESOLVCONFS}" \
94                 | sed -n -e 's/^[[:space:]]*search[[:space:]]*//p' \
95                         -e 's/^[[:space:]]*domain[[:space:]]*//p')"
96 fi
97
98 # libc only allows for 6 search domains 
99 i=0
100 SEARCH=
101 for S in $(uniqify ${OUR_SEARCH}); do
102         i=$((${i} + 1))
103         SEARCH="${SEARCH} ${S}"
104         [ "${i}" = "6" ] && break
105 done
106 [ -n "${SEARCH}" ] && SEARCH="search${SEARCH}"
107
108 # Hold our new resolv.conf in a variable to save on temporary files
109 NEWCONF="# Generated by resolvconf\n"
110 [ -e "${RESOLVCONF}"/resolv.conf.d/head ] \
111         && NEWCONF="${NEWCONF}$(cat "${RESOLVCONF}"/resolv.conf.d/head)\n"
112 [ -n "${SEARCH}" ] && NEWCONF="${NEWCONF}${SEARCH}\n"
113 for N in ${NS}; do
114         NEWCONF="${NEWCONF}nameserver ${N}\n"
115 done
116
117 # Now dump everything else from our resolvs
118 if [ -e "${BASE}" ]; then
119         NEWCONF="${NEWCONF}$(sed -e '/^[[:space:]]*$/d' \
120                 -e '/^[[:space:]]*nameserver[[:space:]]*.*/d' \
121                 -e '/^[[:space:]]*search[[:space:]]*.*/d' \
122                 -e '/^[[:space:]]*domain[[:space:]]*.*/d' \
123                 "${BASE}")" 
124 fi
125
126 # We don't know we're using GNU sed, so we do it like this
127 NEWCONF="${NEWCONF}$(echo "${RESOLVCONFS}" | sed -e '/^[[:space:]]*$/d' \
128         -e '/^[[:space:]]*#/d' \
129         -e '/^[[:space:]]*nameserver[[:space:]]*.*/d' \
130         -e '/^[[:space:]]*search[[:space:]]*.*/d' \
131         -e '/^[[:space:]]*domain[[:space:]]*.*/d' \
132         )"
133 [ -e "${RESOLVCONF}"/resolv.conf.d/tail ] \
134         && NEWCONF="${NEWCONF}$(cat "${RESOLVCONF}"/resolv.conf.d/tail)"
135
136 # Check if the file has actually changed or not
137 if [ -e "${RESOLVCONF}"/run/resolv.conf ]; then
138         [ "$(cat "${RESOLVCONF}"/run/resolv.conf)" = "$(printf "${NEWCONF}")" ] && exit 0
139 fi
140
141 # Create our resolv.conf now
142 printf "${NEWCONF}" > "${RESOLVCONF}"/run/resolv.conf
143
144 resolvconf -s nscd restart
145
146 # Notify users of the resolver
147 for x in "${REVOLVCONF}"/update-libc.d/*; do
148         [ -e "${x}" ] && "${x}" "$@"
149 done
150
151 # vim: ts=4 :