etc/protocols - sync with NetBSD-8
[minix.git] / external / bsd / dhcpcd / dist / dhcpcd-run-hooks.in
blob8fe9a5007c132bb2e93bad65da600fbf8b2bb172
1 #!/bin/sh
2 # $NetBSD: dhcpcd-run-hooks.in,v 1.11 2015/08/21 10:39:00 roy Exp $
4 # dhcpcd client configuration script
6 # Handy variables and functions for our hooks to use
7 case "$reason" in
8 ROUTERADVERT)
9 ifsuffix=".ra";;
10 INFORM6|BOUND6|RENEW6|REBIND6|REBOOT6|EXPIRE6|RELEASE6|STOP6)
11 ifsuffix=".dhcp6";;
12 IPV4LL)
13 ifsuffix=".ipv4ll";;
15 ifsuffix=".dhcp";;
16 esac
17 ifname="$interface$ifsuffix"
19 from=from
20 signature_base="# Generated by dhcpcd"
21 signature="$signature_base $from $ifname"
22 signature_base_end="# End of dhcpcd"
23 signature_end="$signature_base_end $from $ifname"
24 state_dir=@RUNDIR@/dhcpcd
25 _detected_init=false
27 : ${if_up:=false}
28 : ${if_down:=false}
29 : ${syslog_debug:=false}
31 # Ensure that all arguments are unique
32 uniqify()
34 local result= i=
35 for i do
36 case " $result " in
37 *" $i "*);;
38 *) result="$result $i";;
39 esac
40 done
41 echo "${result# *}"
44 # List interface config files in a directory.
45 # If dhcpcd is running as a single instance then it will have a list of
46 # interfaces in the preferred order.
47 # Otherwise we just use what we have.
48 list_interfaces()
50 local i= x= ifaces=
51 for i in $interface_order; do
52 for x in "$1"/$i.*; do
53 [ -f "$x" ] && ifaces="$ifaces${ifaces:+ }${x##*/}"
54 done
55 done
56 for x in "$1"/*; do
57 [ -f "$x" ] && ifaces="$ifaces${ifaces:+ }${x##*/}"
58 done
59 uniqify $ifaces
62 # Trim function
63 trim()
65 local var="$*"
67 var=${var#"${var%%[![:space:]]*}"}
68 var=${var%"${var##*[![:space:]]}"}
69 if [ -z "$var" ]; then
70 # So it seems our shell doesn't support wctype(3) patterns
71 # Fall back to sed
72 var=$(echo "$*" | sed -e 's/^[[:space:]]*//;s/[[:space:]]*$//')
74 printf %s "$var"
77 # We normally use sed to extract values using a key from a list of files
78 # but sed may not always be available at the time.
79 key_get_value()
81 local key="$1" value= x= line=
83 shift
84 if type sed >/dev/null 2>&1; then
85 sed -n "s/^$key//p" $@
86 else
87 for x do
88 while read line; do
89 case "$line" in
90 "$key"*) echo "${line##$key}";;
91 esac
92 done < "$x"
93 done
97 # We normally use sed to remove markers from a configuration file
98 # but sed may not always be available at the time.
99 remove_markers()
101 local m1="$1" m2="$2" x= line= in_marker=0
103 shift; shift
104 if type sed >/dev/null 2>&1; then
105 sed "/^$m1/,/^$m2/d" $@
106 else
107 for x do
108 while read line; do
109 case "$line" in
110 "$m1"*) in_marker=1;;
111 "$m2"*) in_marker=0;;
112 *) [ $in_marker = 0 ] && echo "$line";;
113 esac
114 done < "$x"
115 done
119 # Compare two files.
120 comp_file()
123 [ -e "$1" -a -e "$2" ] || return 1
125 if type cmp >/dev/null 2>&1; then
126 cmp -s "$1" "$2"
127 elif type diff >/dev/null 2>&1; then
128 diff -q "$1" "$2" >/dev/null
129 else
130 # Hopefully we're only working on small text files ...
131 [ "$(cat "$1")" = "$(cat "$2")" ]
135 # Compare two files.
136 # If different, replace first with second otherwise remove second.
137 change_file()
140 if [ -e "$1" ]; then
141 if comp_file "$1" "$2"; then
142 rm -f "$2"
143 return 1
146 cat "$2" > "$1"
147 rm -f "$2"
148 return 0
151 # Compare two files.
152 # If different, copy or link depending on target type
153 copy_file()
156 if [ -h "$2" ]; then
157 [ "$(readlink "$2")" = "$1" ] && return 1
158 ln -sf "$1" "$2"
159 else
160 comp_file "$1" "$2" && return 1
161 cat "$1" >"$2"
165 # Save a config file
166 save_conf()
169 if [ -f "$1" ]; then
170 rm -f "$1-pre.$interface"
171 cat "$1" > "$1-pre.$interface"
175 # Restore a config file
176 restore_conf()
179 [ -f "$1-pre.$interface" ] || return 1
180 cat "$1-pre.$interface" > "$1"
181 rm -f "$1-pre.$interface"
184 # Write a syslog entry
185 syslog()
187 local lvl="$1"
189 if [ "$lvl" = debug ]; then
190 ${syslog_debug} || return 0
192 [ -n "$lvl" ] && shift
193 [ -n "$*" ] || return 0
194 case "$lvl" in
195 err|error) echo "$interface: $*" >&2;;
196 *) echo "$interface: $*";;
197 esac
198 if type logger >/dev/null 2>&1; then
199 logger -i -p daemon."$lvl" -t dhcpcd-run-hooks "$interface: $*"
203 # Check for a valid domain name as per RFC1123 with the exception of
204 # allowing - and _ as they seem to be widely used.
205 valid_domainname()
207 local name="$1" label
209 [ -z "$name" -o ${#name} -gt 255 ] && return 1
211 while [ -n "$name" ]; do
212 label="${name%%.*}"
213 [ -z "$label" -o ${#label} -gt 63 ] && return 1
214 case "$label" in
215 -*|_*|*-|*_) return 1;;
216 # some sh require - as the first or last character in the class
217 # when matching it
218 *[![:alnum:]_-]*) return 1;;
219 esac
220 [ "$name" = "${name#*.}" ] && break
221 name="${name#*.}"
222 done
223 return 0
226 valid_domainname_list()
228 local name
230 for name do
231 valid_domainname "$name" || return $?
232 done
233 return 0
236 # Check for a valid path
237 valid_path()
240 case "$@" in
241 *[![:alnum:]#%+-_:\.,@~\\/\[\]=\ ]*) return 1;;
242 esac
243 return 0
246 # With the advent of alternative init systems, it's possible to have
247 # more than one installed. So we need to try and guess what one we're
248 # using unless overriden by configure.
249 detect_init()
251 _service_exists="@SERVICEEXISTS@"
252 _service_cmd="@SERVICECMD@"
253 _service_status="@SERVICESTATUS@"
255 [ -n "$_service_cmd" ] && return 0
257 if ${_detected_init}; then
258 [ -n "$_service_cmd" ]
259 return $?
262 # Detect the running init system.
263 # As systemd and OpenRC can be installed on top of legacy init
264 # systems we try to detect them first.
265 _service_status=
266 if [ -x /bin/systemctl -a -S /run/systemd/private ]; then
267 _service_exists="/bin/systemctl --quiet is-enabled \$1.service"
268 _service_status="/bin/systemctl --quiet is-active \$1.service"
269 _service_cmd="/bin/systemctl \$2 \$1.service"
270 elif [ -x /usr/bin/systemctl -a -S /run/systemd/private ]; then
271 _service_exists="/usr/bin/systemctl --quiet is-enabled \$1.service"
272 _service_status="/usr/bin/systemctl --quiet is-active \$1.service"
273 _service_cmd="/usr/bin/systemctl \$2 \$1.service"
274 elif [ -x /sbin/rc-service -a \
275 -s /libexec/rc/init.d/softlevel -o -s /run/openrc/softlevel ]
276 then
277 _service_exists="/sbin/rc-service -e \$1"
278 _service_cmd="/sbin/rc-service \$1 -- -D \$2"
279 elif [ -x /usr/sbin/invoke-rc.d ]; then
280 _service_exists="/usr/sbin/invoke-rc.d --query --quiet \$1 start >/dev/null 2>&1 || [ \$? = 104 ]"
281 _service_cmd="/usr/sbin/invoke-rc.d \$1 \$2"
282 elif [ -x /sbin/service ]; then
283 _service_exists="/sbin/service \$1 >/dev/null 2>&1"
284 _service_cmd="/sbin/service \$1 \$2"
285 elif [ -x /bin/sv ]; then
286 _service_exists="/bin/sv status \1 >/dev/null 2>&1"
287 _service_cmd="/bin/sv \$1 \$2"
288 elif [ -x /usr/bin/sv ]; then
289 _service_exists="/usr/bin/sv status \1 >/dev/null 2>&1"
290 _service_cmd="/usr/bin/sv \$1 \$2"
291 elif [ -e /etc/slackware-version -a -d /etc/rc.d ]; then
292 _service_exists="[ -x /etc/rc.d/rc.\$1 ]"
293 _service_cmd="/etc/rc.d/rc.\$1 \$2"
294 _service_status="/etc/rc.d/rc.\$1 status 1>/dev/null 2>&1"
295 else
296 for x in /etc/init.d/rc.d /etc/rc.d /etc/init.d; do
297 if [ -d $x ]; then
298 _service_exists="[ -x $x/\$1 ]"
299 _service_cmd="$x/\$1 \$2"
300 break
302 done
303 if [ -e /etc/arch-release ]; then
304 _service_status="[ -e /var/run/daemons/\$1 ]"
305 elif [ "$x" = "/etc/rc.d" -a -e /etc/rc.d/rc.subr ]; then
306 _service_status="$x/\$1 check 1>/dev/null 2>&1"
310 _detected_init=true
311 if [ -z "$_service_cmd" ]; then
312 syslog err "could not detect a useable init system"
313 return 1
315 return 0
318 # Check a system service exists
319 service_exists()
322 if [ -z "$_service_exists" ]; then
323 detect_init || return 1
325 eval $_service_exists
328 # Send a command to a system service
329 service_cmd()
332 if [ -z "$_service_cmd" ]; then
333 detect_init || return 1
335 eval $_service_cmd
338 # Send a command to a system service if it is running
339 service_status()
342 if [ -z "$_service_cmd" ]; then
343 detect_init || return 1
345 if [ -n "$_service_status" ]; then
346 eval $_service_status
347 else
348 service_command $1 status >/dev/null 2>&1
352 # Handy macros for our hooks
353 service_command()
356 service_exists $1 && service_cmd $1 $2
358 service_condcommand()
361 service_exists $1 && service_status $1 && service_cmd $1 $2
364 # We source each script into this one so that scripts run earlier can
365 # remove variables from the environment so later scripts don't see them.
366 # Thus, the user can create their dhcpcd.enter/exit-hook script to configure
367 # /etc/resolv.conf how they want and stop the system scripts ever updating it.
368 for hook in \
369 @SYSCONFDIR@/dhcpcd.enter-hook \
370 @HOOKDIR@/* \
371 @SYSCONFDIR@/dhcpcd.exit-hook
373 for skip in $skip_hooks; do
374 case "$hook" in
375 */*~) continue 2;;
376 */"$skip") continue 2;;
377 */[0-9][0-9]"-$skip") continue 2;;
378 */[0-9][0-9]"-$skip.sh") continue 2;;
379 esac
380 done
381 if [ -f "$hook" ]; then
382 . "$hook"
384 done