source: freewrt/package/fwifupdown/files/main.sh@ 44d850e

Last change on this file since 44d850e was 44d850e, checked in by Christian Fischer <spaetzle@…>, 19 years ago

fixed failure handling bug

git-svn-id: svn://www.freewrt.org/trunk/freewrt@2443 afb5a338-a214-0410-bd46-81f09a774fd1

  • Property mode set to 100755
File size: 8.0 KB
Line 
1#!/bin/sh
2#
3# This file is part of the FreeWRT project. FreeWRT is copyrighted
4# material, please see the LICENCE file in the top-level directory
5# or at http://www.freewrt.org/licence for details.
6#
7# Christian Fischer <spaetzle@freewrt.org>
8#
9
10set -u
11
12builtin() {
13 local builtin=$1
14 local alias=$(alias $builtin)
15 unalias $builtin
16 alias $(echo $alias|sed 's/'\''//g')
17 shift
18 $builtin $@
19}
20
21config() {
22 [ "$1" != "0" ]
23}
24__ifupdown() {
25 local environ=$(cat $ENVFILE)
26
27 IFUPDOWN_ENV=$(echo -n $IFUPDOWN_ENV|sed 's/\(MDENT=\)[^ ]*[[:space:]]*//g';\
28 echo " PARENT_IFACE_TYPE=$IFACE_TYPE"; \
29 echo " PARENT_IFACE=$IFACE"; \
30 echo " MDENT=$MDENT") \
31 busybox $@
32
33 retval=$?
34 echo $environ > $ENVFILE
35 return $retval
36}
37
38__exit() {
39 [ "$1" != "0" ] && echo "H_ERR=1" >> $ENVFILE
40 exit $1
41}
42
43iface_exists() {
44 grep -q "${1:-$IFACE}:" /proc/net/dev
45}
46
47is_up() {
48 local iface=${1:-$IFACE}
49
50 if iface_exists $iface
51 then
52 ip a|grep ${iface}:[[:space:]]|grep -q UP && return
53
54 ### ifupdown netlink bug workaround ###
55 # suppress "ip: RTNETLINK answers: File exists" message in the case of
56 # iface is down but an ip address is assigned
57 ip a|grep ${iface}$|grep -q inet && ip addr flush dev $iface >/dev/null 2>&1
58 ### end workaround ###
59 fi
60 return 1
61}
62
63main_env_update() {
64 local t_mdent lastmatch=""
65
66 # get submode from calling hook script
67 SUBMODE=$(dirname $0|sed '{ s/\(.*\/\)*//; s/\.d$//}')
68
69 # create env file
70 if ! [ -f "$ENVFILE" ]
71 then
72 [ -d $(dirname $ENVFILE) ] || mkdir -p $(dirname $ENVFILE)
73 echo "MDENT=0" >> $ENVFILE
74 echo "LASTLOG=0" >> $ENVFILE
75
76 if is_up
77 then
78 IFACE_STATE="up"
79 else
80 IFACE_STATE="down"
81 fi
82 echo "IFACE_STATE=$IFACE_STATE" >> $ENVFILE
83
84 if [ "$IFACE" != "lo" ]
85 then
86 # search for existing lib files end evaluate iface type by using the appropriate
87 # function from lib file
88 for lib in ${LIBDIR}/* ${LIBDIR_OVERLAY}/*
89 do
90 if [ -f $lib ]
91 then
92 if (. $lib; iface_type 2>&-)
93 then
94 if [ "$lastmatch" != "" ]
95 then
96 if [ "$(basename $lib)" = "$(basename $lastmatch)" ]
97 then
98 mprint -s "Warning: $lib overlays $lastmatch"
99 else
100 mprint -s "Error: iface type $lib overlays $lastmatch"
101 fi
102 fi
103 lastmatch=$lib
104 fi
105 fi
106 done
107 fi
108
109 if [ "$lastmatch" != "" ]
110 then
111 IFACE_TYPE=$(basename $lastmatch)
112 else
113 # if iface type isn't evaluated type "iface" is default
114 IFACE_TYPE="iface"
115 fi
116
117 # update env
118 echo "IFACE_TYPE=${IFACE_TYPE}" >> $ENVFILE
119 fi
120
121 . $ENVFILE
122 t_mdent=$MDENT
123
124 # expand $IFUPDOWN_ENV
125 for var in $IFUPDOWN_ENV; do
126 eval $var
127 done
128
129 [ $t_mdent -gt $MDENT ] && MDENT=$t_mdent
130 main_pos_update
131}
132
133main_pos_update() {
134 if [ "${MDENT:-0}" = "0" ]
135 then
136 STARTCOL=""
137 else
138 STARTCOL="\x1B[$(expr ${MDENT:-0} \* ${TAB})C"
139 fi
140 sed 's/MDENT=[0-9]*/'MDENT=$MDENT'/' -i $ENVFILE
141}
142
143main_preup() {
144 config $RT_PREUP_PRINTING_OFF || mstart
145
146 if ! config $RT_PREUP_IFUP_CHECK_OFF && is_up
147 then
148 if ! config $RT_PREUP_PRINTING_OFF
149 then
150 mup
151 mstate 1
152 minfo "Interface already up"
153 fi
154 exit 1
155 fi
156
157 if_preup 2>&-
158 retval=$?
159
160 if [ $retval != 0 ]
161 then
162 if [ $retval != 127 ]
163 then
164 fail_preup 2>&- || exit 1
165 fi
166 fi
167
168 config $RT_PREUP_PRINTING_OFF || mup
169}
170
171main_up() {
172 if ! config $RT_UP_IFUP_CHECK_OFF
173 then
174 is_up
175 retval=$?
176
177 if [ $retval != 0 ]
178 then
179
180 if ! config $RT_UP_PRINTING_OFF
181 then
182 mstate $retval
183 [ "$METHOD" = "manual" ] && minfo "Method manual is set"
184 fi
185 exit 1
186 else
187 config $RT_UP_PRINTING_OFF || mstate $retval
188 fi
189 fi
190
191 if_up 2>&-
192 retval=$?
193
194 if [ $retval != 0 ]
195 then
196 if [ $retval != 127 ]
197 then
198 fail_up 2>&- || exit 1
199 fi
200 fi
201
202 if [ -d /tmp/ifupdown/pcode/${IFACE} ]
203 then
204 for dir in /tmp/ifupdown/pcode/${IFACE}/*
205 do
206 if [ -f ${dir}/postup ]
207 then
208 . ${dir}/postup
209 fi
210 done
211 fi
212}
213
214main_down() {
215 config $RT_DOWN_PRINTING_OFF || mstop
216
217 if [ -d /tmp/ifupdown/pcode/${IFACE} ]
218 then
219 for dir in /tmp/ifupdown/pcode/${IFACE}/*
220 do
221 if [ -f ${dir}/predown ]
222 then
223 . ${dir}/predown
224 fi
225 done
226 fi
227
228 if_down 2>&-
229 retval=$?
230
231 if [ $retval != 0 ]
232 then
233 if [ $retval != 127 ]
234 then
235 fail_down 2>&- || exit 1
236 fi
237 fi
238
239 config $RT_DOWN_PRINTING_OFF || mdown
240}
241
242main_postdown() {
243 if ! config $RT_POSTDOWN_IFDOWN_CHECK_OFF
244 then
245 if [ $IFACE_STATE = "down" ]
246 then
247 if ! config $RT_POSTDOWN_PRINTING_OFF
248 then
249 mdown
250 mstate 1
251 minfo "Interface already down"
252 fi
253 else
254 if is_up
255 then
256 if ! config $RT_POSTDOWN_PRINTING_OFF
257 then
258 mstate 1
259 [ "$METHOD" = "manual" ] && minfo "Method manual is set"
260 fi
261 return 1
262 else
263 config $RT_POSTDOWN_PRINTING_OFF || mstate 0
264 fi
265 fi
266 fi
267
268 if_postdown 2>&-
269 retval=$?
270
271 if [ $retval != 0 ]
272 then
273 if [ $retval != 127 ]
274 then
275 fail_postdown 2>&- || exit 1
276 fi
277 fi
278
279 # pcode cleanup
280 rm -rf /tmp/ifupdown/pcode/*/$IFACE 2>&- 1>&-
281}
282
283main_ifup() {
284 case $METHOD in
285 dhcp)
286 main_dhcp_up || exit 1
287
288 # don't handle any failures, it's really not my problem if that goes wrong
289 main_exec_inlinehooks
290
291 main_up || exit 1
292 RT_BB_NOEXEC=1
293 ;;
294 esac
295}
296
297main_ifdown() {
298 case $METHOD in
299 dhcp)
300 main_dhcp_down
301
302 # don't handle any failures, it's really not my problem if that goes wrong
303 main_exec_inlinehooks
304
305 main_postdown || exit 1
306 RT_BB_NOEXEC=1
307 ;;
308 esac
309}
310
311main_exec_inlinehooks() {
312 case $SUBMODE in
313 if-pre-up)
314 [ "${IF_PRE_UP:-""}" != "" ] && eval $IF_PRE_UP
315 ;;
316 if-up)
317 [ "${IF_UP:-""}" != "" ] && eval $IF_UP
318 ;;
319 if-down)
320 [ "${IF_DOWN:-""}" != "" ] && eval $IF_DOWN
321 ;;
322 if-post-down)
323 [ "${IF_POST_DOWN:-""}" != "" ] && eval $IF_POST_DOWN
324 ;;
325 esac
326}
327
328main_dhcp_up() {
329 local err
330
331 if ! err=$(ip link set $IFACE up 2>&1 1>&-)
332 then
333 mprint -s "main_dhcp_up: $err"
334 return 1
335 fi
336
337 if [ "${IF_DHCPCLIENT:-""}" != "" -a "${IF_DHCPCLIENT_OPTS:-""}" != "udhcpc" ]
338 then
339 if [ -x "$(which $IF_DHCPCLIENT)" ]
340 then
341 err=$(eval $IF_DHCPCLIENT ${IF_DHCPCLIENT_OPTS:-""} 2>&1 1>&-) || mprint -s "main_dhcp_up: $err" &
342 return 0
343 fi
344 mprint -s "$IF_DHCPCCLIENT not found, using builtin udhcpcd"
345 fi
346
347 if ! err=$(udhcpc -b -t 0 -p /var/run/udhcpc.${IFACE}.pid -i $IFACE ${IF_HOSTNAME:+"-H $IF_HOSTNAME"} ${IF_CLIENTID:+"-c $IF_CLIENTID"} \
348 ${IF_SCRIPT:+"-s $IF_SCRIPT"} 2>&1 1>&-)
349 then
350 mprint -s "main_dhcp_up: $err"
351 return 1
352 fi
353
354 return 0
355}
356
357main_dhcp_down() {
358 local err
359
360 if [ -f /var/run/udhcpc.${IFACE}.pid ]
361 then
362 err=$(kill -TERM "$(cat /var/run/udhcpc.${IFACE}.pid)" 2>&1 1>&-) || mprint -s "main_dhcp_down: $err"
363 fi
364
365 if is_up
366 then
367 err=$(ip addr flush dev $IFACE 2>&1 1>&-) || mprint -s "main_dhcp_down: $err"
368 err=$(ip link set $IFACE down 2>&1 1>&-) || mprint -s "main_dhcp_down: $err"
369 fi
370}
371
372### main entry point ###
373
374CFG_PRINTING_OFF=0
375CFG_SYSLOG_OFF=0
376CFG_BUSYBOX_COMPAT=0
377
378if ! [ -f /etc/conf.d/ifupdown ]
379then
380 logger -t ifupdown "/etc/conf.d/ifupdown not found"
381 exit 1
382fi
383. /etc/conf.d/ifupdown
384
385RT_PREUP_PRINTING_OFF=0
386RT_UP_PRINTING_OFF=0
387RT_DOWN_PRINTING_OFF=0
388RT_POSTDOWN_PRINTING_OFF=0
389RT_PREUP_IFUP_CHECK_OFF=0
390RT_UP_IFUP_CHECK_OFF=0
391RT_POSTDOWN_IFDOWN_CHECK_OFF=0
392RT_BB_NOEXEC=0
393readonly ENVFILE="/tmp/ifupdown/env"
394readonly LIBDIR="/opt/ifupdown/lib"
395readonly LIBDIR_OVERLAY="/etc/network/lib"
396IFACE_TYPE="none"
397H_ERR=0
398
399alias exit="__exit"
400alias ifup="__ifupdown ifup"
401alias ifdown="__ifupdown ifdown"
402
403if ! [ -f /opt/ifupdown/bin/mfunctions.sh ]
404then
405 logger -t ifupdown "/opt/ifupdown/bin/mfunctions.sh not found"
406 exit 1
407fi
408. /opt/ifupdown/bin/mfunctions.sh
409
410main_env_update
411
412config $H_ERR && builtin exit 1
413
414if [ "$IFACE_TYPE" != "iface" ]
415then
416 if [ -f "${LIBDIR_OVERLAY}/$IFACE_TYPE" ]
417 then
418 . ${LIBDIR_OVERLAY}/$IFACE_TYPE
419 elif [ -f "${LIBDIR}/$IFACE_TYPE" ]
420 then
421 . ${LIBDIR}/$IFACE_TYPE
422 else
423 mprint -s "Error: libfile not found"
424 fi
425fi
426
427case $SUBMODE in
428 if-pre-up)
429 main_preup
430 main_ifup
431 # bypass execution of further busybox ifupdown.c code
432 config $RT_BB_NOEXEC && builtin exit 1
433 ;;
434 if-up)
435 main_up
436 ;;
437 if-down)
438 main_down
439 main_ifdown
440 # bypass execution of further busybox ifupdown.c code
441 config $RT_BB_NOEXEC && builtin exit 1
442 ;;
443 if-post-down)
444 main_postdown
445 ;;
446esac
447
448exit 0
449
450# vim:ts=4
Note: See TracBrowser for help on using the repository browser.