db5d2a13243e74f8b8508429d7ef2d63cc782857
[openresolv] / libc.in
1 #!/bin/sh
2 # Copyright 2007-2009 Roy Marples
3 # All rights reserved
4
5 # libc subscriber for resolvconf
6
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
9 # are met:
10 #     * Redistributions of source code must retain the above copyright
11 #       notice, this list of conditions and the following disclaimer.
12 #     * Redistributions in binary form must reproduce the above
13 #       copyright notice, this list of conditions and the following
14 #       disclaimer in the documentation and/or other materials provided
15 #       with the distribution.
16 #
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 RESOLVCONF="${RESOLVCONF:-resolvconf}"
30 SYSCONFDIR=@SYSCONFDIR@
31 LIBEXECDIR=@LIBEXECDIR@
32 VARBASE=@VARBASE@
33 IFACEDIR="${VARBASE}/run/resolvconf/interfaces"
34
35 # sed may not be available, and this is faster on small files
36 key_get_value()
37 {
38         local key="$1" value= x= line=
39
40         shift
41         if [ $# -eq 0 ]; then
42                 while read line; do
43                         case "${line}" in
44                         "${key}"*) echo "${line##${key}}";;
45                         esac
46                 done
47         else
48                 for x; do
49                         while read line; do
50                                 case "${line}" in
51                                 "${key}"*) echo "${line##${key}}";;
52                                 esac
53                         done < "${x}"
54                 done
55         fi
56 }
57
58 # Support original resolvconf configuration layout
59 # as well as the openresolv config file
60 if [ -f "${SYSCONFDIR}"/resolvconf.conf ]; then
61         . "${SYSCONFDIR}"/resolvconf.conf
62 elif [ -d "${SYSCONFDIR}/resolvconf" ]; then
63         SYSCONFDIR="${SYSCONFDIR}/resolvconf/resolv.conf.d"
64         base="${SYSCONFDIR}/resolv.conf.d/base"
65         if [ -f "${BASE}" ]; then
66                 name_servers="$(key_get_value "nameserver " "${base}")"
67                 search_domains="$(key_get_value "search " "${base}")"
68                 if [ -z "${search_domains}" ]; then
69                         search_domains="$(key_get_value "domain " "${base}")"
70                 fi
71                 resolv_conf_options="$(key_get_value "options " "${base}")"
72         fi
73         if [ -f "${SYSCONFDIR}"/resolv.conf.d/head ]; then
74                 resolv_conf_head="$(cat "${SYSCONFDIR}"/resolv.conf.d/head)"
75         fi
76         if [ -f "${SYSCONFDIR}"/resolv.conf.d/tail ]; then
77                 resolv_conf_tail="$(cat "${SYSCONFDIR}"/resolv.conf.d/tail)"
78         fi
79 fi
80 resolv_conf="${resolv_conf:-/etc/resolv.conf}"
81
82 uniqify()
83 {
84         local result=
85         while [ -n "$1" ]; do
86                 case " ${result} " in
87                 *" $1 "*);;
88                 *) result="${result} $1";;
89 esac
90 shift
91 done
92 echo "${result# *}"
93 }
94
95 case "${resolv_conf_passthrough:-NO}" in
96 [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
97         newest=
98         for conf in "${IFACEDIR}"/*; do
99                 if [ -z "${newest}" -o "${conf}" -nt "${newest}" ]; then
100                         newest="${conf}"
101                 fi
102         done
103         [ -z "${newest}" ] && exit 0
104         newconf="$(cat "${newest}")\n"
105         ;;
106 *)
107         eval "$(${RESOLVCONF} -v)"
108         newsearch="$(uniqify ${search_domains} ${SEARCH})"
109         newns="$(uniqify ${name_servers} ${NAMESERVERS})"
110
111         # Hold our new resolv.conf in a variable to save on temporary files
112         newconf="# Generated by resolvconf\n"
113         if [ -n "${resolv_conf_head}" ]; then
114                 newconf="${newconf}${resolv_conf_head}\n"
115         fi
116         [ -n "${newsearch}" ] && newconf="${newconf}search ${newsearch}\n"
117         for n in ${newns}; do
118                 newconf="${newconf}nameserver ${n}\n"
119         done
120
121         # Now get any configured options
122         opts="${resolv_conf_options}${resolv_conf_options:+ }"
123         opts="${opts}$(${RESOLVCONF} -l | key_get_value "options ")"
124         if [ -n "${opts}" ]; then
125                 newconf="${newconf}options"
126                 for opt in $(uniqify ${opts}); do
127                         newconf="${newconf} ${opt}"
128                 done
129                 newconf="${newconf}\n"
130         fi
131
132         if [ -n "{resolv_conf_tail}" ]; then
133                 newconf="${newconf}${resolv_conf_tail}\n"
134         fi
135         ;;
136 esac
137
138 # Check if the file has actually changed or not
139 if [ -e "${resolv_conf}" ]; then
140         [ "$(cat "${resolv_conf}")" = "$(printf "${newconf}")" ] && exit 0
141 fi
142
143 # Create our resolv.conf now
144 (umask 022; printf "${newconf}" > "${resolv_conf}")
145
146 ${RESOLVCONF} -s nscd restart
147 retval=$?
148
149 # Notify users of the resolver
150 for script in "${LIBEXECDIR}"/libc.d/*; do
151         if [ -f "${script}" -a -x "${script}" ]; then
152                 RESOLVCONF="${RESOLVCONF}" "${script}" "$@"
153                 retval=$((${retval} + $?))
154         fi
155 done
156 exit ${retval}