]> git.ipfire.org Git - ipfire-3.x.git/blame - src/mkinitramfs/functions
mkinitramfs: Remove dd from initramfs.
[ipfire-3.x.git] / src / mkinitramfs / functions
CommitLineData
17e7e3d5 1#!/bin/bash
fa424239
MT
2HEADER="\
3###############################################################################
4# #
5# IPFire.org - A linux based firewall #
6# Copyright (C) 2009 Michael Tremer & Christian Schmidt #
7# #
8# This program is free software: you can redistribute it and/or modify #
9# it under the terms of the GNU General Public License as published by #
10# the Free Software Foundation, either version 3 of the License, or #
11# (at your option) any later version. #
12# #
13# This program is distributed in the hope that it will be useful, #
14# but WITHOUT ANY WARRANTY; without even the implied warranty of #
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
16# GNU General Public License for more details. #
17# #
18# You should have received a copy of the GNU General Public License #
19# along with this program. If not, see <http://www.gnu.org/licenses/>. #
20# #
21###############################################################################
22"
23
24## GLOBAL VARIABLES ARE UPPERCASE
25## LOCAL VARIABLES ARE LOWERCASE
26
27VERBOSE=
28FORCE=
29TARGET=
30KERNEL=$(uname -r)
31MODULES=
32
33TMPDIR=$(mktemp -d)
34
35# Check if we are root
36if [ $UID != 0 ]; then
37 error "$0 must be run as root."
38 exit 1
39fi
40
41# Usage
42function usage() {
43 echo "$0 [--help] [-f] [-v] <out-initrd-image> <kernel-version>"
44 echo " [--with=<module>]"
45 echo
46 echo "example: $0 /boot/myinitramfs.img \`uname -r\`"
47}
48
49# Setting verbose mode
17e7e3d5 50function set_verbose() {
fa424239
MT
51 case "$1" in
52 yes|y|on|1)
53 VERBOSE=-v
54 ;;
55 no|n|off|0)
56 VERBOSE=
57 ;;
58 esac
17e7e3d5
MT
59}
60
fa424239 61# Returns if verbose is on or not
17e7e3d5 62function is_verbose() {
fa424239
MT
63 [ -n "$VERBOSE" ] && return 0
64 return 1
17e7e3d5
MT
65}
66
fa424239
MT
67# Like is_verbose but prints
68# the content of $VERBOSE
17e7e3d5 69function get_verbose() {
fa424239
MT
70 echo "$VERBOSE"
71 is_verbose
17e7e3d5
MT
72}
73
fa424239 74# Prints text if verbose is on
17e7e3d5 75function vecho() {
fa424239 76 is_verbose && echo "$@"
17e7e3d5
MT
77}
78
fa424239 79# Prints error if verbose is on
17e7e3d5 80function error() {
fa424239
MT
81 vecho "$@" >&2
82}
83
84function compress() {
85 cd - >/dev/null
86 IMAGE=$(mktemp)
87 vecho "[TASK] Compressing image $TARGET..."
88 (cd $TMPDIR && find . | cpio -H newc --quiet -o >| $IMAGE) || exit 1
89 gzip -c9 $IMAGE > $TARGET
90}
91
92function findone() {
93 find "$@" | awk '{ print $1; exit; }'
94}
95
96function findall() {
97 find "$@"
98}
99
100qpushd() {
101 pushd "$1" >/dev/null 2>&1
102}
103
104qpopd() {
105 popd >/dev/null 2>&1
106}
107
108function read_link() {
109 READLINK=$(readlink $1)
110 if grep -q "^/" <<< $READLINK; then
111 echo $READLINK
112 else
113 echo "$(dirname $1)/$READLINK"
114 fi
17e7e3d5
MT
115}
116
17e7e3d5 117function get_dso_deps() {
fa424239
MT
118 local bin="$1"
119 shift
120
121 declare -a FILES
122 declare -a NAMES
123
124 local LDSO="/lib/ld-linux.so.2"
125
126 declare -i n=0
127 while read NAME I0 FILE ADDR I1 ; do
128 [ "$FILE" == "not" ] && FILE="$FILE $ADDR"
129 [ "$NAME" == "not" ] && NAME="$NAME $I0"
130 NAMES[$n]="$NAME"
131 FILES[$n]="$FILE"
132 let n++
133 done << EOF
134 $(LD_TRACE_PRELINKING=1 LD_WARN= LD_TRACE_LOADED_OBJECTS=1 \
135 $LDSO $bin 2>/dev/null)
17e7e3d5
MT
136EOF
137
fa424239
MT
138 [ ${#FILES[*]} -eq 0 ] && return 1
139
140 # we don't want the name of the binary in the list
141 if [ "${FILES[0]}" == "$bin" ]; then
142 FILES[0]=""
143 NAMES[0]=""
144 [ ${#FILES[*]} -eq 1 ] && return 1
145 fi
146
147 declare -i n=0
148 while [ $n -lt ${#FILES[*]} ]; do
149 local FILE="${FILES[$n]}"
150 local NAME="${NAMES[$n]}"
151 if [ "$FILE" == "not found" -o "$NAME" == "not found" ]; then
152 cat 1>&2 <<EOF
17e7e3d5 153There are missing files on your system. The dynamic object $bin
fa424239 154requires ${NAMES[$n]} n order to properly function. mkinitramfs cannot continue.
17e7e3d5 155EOF
fa424239
MT
156 return 1
157 fi
158 case "$FILE" in
159 /lib*)
160 TLIBDIR=`echo "$FILE" | sed 's,\(/lib[^/]*\)/.*$,\1,'`
161 BASE=`basename "$FILE"`
162 if [ -f "$TLIBDIR/$BASE" ]; then
163 FILE="$TLIBDIR/$BASE"
164 fi
165 FILES[$n]="$FILE"
166 ;;
167 esac
168 let n++
169 done
170 echo "${FILES[@]}"
171}
172
173function install() {
174 local file dest
175 for file in $@; do
176 local msg="[FILE]"
177
178 ## Check if this is an absolute path
179 if [ "$(basename $file)" = "$file" ]; then
180 file=$(which $file)
181 fi
182
183 # Destination file
184 dest="$TMPDIR$file"
a86bcb1d 185 [ -e "$dest" ] && continue
fa424239
MT
186
187 mkdir -p "$(dirname $dest)" 2>/dev/null
188
189 local old_indent=$INDENT
190 INDENT=" $INDENT"
191
192 [ "${file%%.ko}" != "${file}" ] && msg="[KMOD]"
193 [ -L "$file" ] && msg="[SYML]"
194 #vecho "$msg$INDENT$file -> $dest"
195 vecho "$msg$INDENT$file"
196
197 # Check if $file is a symlink
198 if [ -L "$file" ]; then
199 install $(read_link $file)
200 fi
201
202 if [ "${file%%.ko}" != "${file}" ]; then
203 for i in $(moduledep $file); do
204 [ "$(locatemodule $i)" = "$file" ] && continue
205 installmodule $i
206 done
207 fi
208
209 cp -ld $file $dest
210
211 # Check if file is a script file
212 if [ "$(dd if=$file bs=2 count=1 2>/dev/null)" = "#!" ]; then
213 install $(head -n 1 $file | cut -c3-)
214 # Check if file is a kernel module
215 elif [ "${file%%.ko}" != "${file}" ]; then
216 local firmware
217 for firmware in $(modinfo -F firmware $file 2>/dev/null); do
218 firmware="/lib/firmware/$firmware"
219 [ -e "$firmware" ] && install $firmware
220 done
221 else
222 for dep in $(get_dso_deps "$file"); do
223 install $dep
224 done
225 fi
226
227 INDENT=$old_indent
228 done
229}
230
231# find module dependencies
232function moduledep() {
233 local deps mpargs
234 if [ "$1" == "--ignore-install" ]; then
235 mpargs="$mpargs --ignore-install"
236 shift
237 fi
238 local module=$(basename ${1%%.ko})
239 modprobe $mpargs --set-version $KERNEL --show-depends $module 2>/dev/null | \
240 awk '/^insmod / { print gensub(".*/","","g",$2) }' | \
241 while read foo; do \
242 [ "${foo%%.ko}" != "$1" ] && \
243 echo -n "${foo%%.ko} "; \
244 done
245}
246
247# XXX May be, we can drop this...
248# This loops to make sure it resolves dependencies of dependencies of...
249function resolvemoduledeps () {
250 local dep
251 local deps
252 local module
253 local newmodules
254 local modules=$@
255
256 before=0; after=1
257 while [ $before != $after ]; do
258 newmodules=
259 before=$(wc -c <<< $modules)
260 for module in $modules; do
261 deps=$(moduledep $module)
262 is_verbose && echo "Module $module depends on: $deps"
263 newmodules="$newmodules $module $deps"
264 done
265 modules=$(for i in $newmodules; do echo $i; done | sort -u)
266 after=$(wc -c <<< $modules)
267 done
268 echo $modules
269}
270
271function locatemodule() {
272 local mpargs=""
273 if [ "$1" == "--ignore-install" ]; then
274 mpargs="$mpargs --ignore-install"
275 shift
276 fi
277 local path=$(modprobe $mpargs --set-version $KERNEL --show-depends $1 2>/dev/null | \
278 awk '/^insmod / { print $2; }' | tail -n 1)
279 [ -n "$path" -a -f "$path" ] && echo $path
280}
281
282function installmodule() {
283 local module
9bf81f83 284 local load
fa424239 285 for module in $@; do
9bf81f83 286 [ "$module" = "--load" ] && load=1
fa424239
MT
287 module=$(locatemodule $module)
288 [ -z "$module" ] && continue
289
290 install $module
291 done
9bf81f83
MT
292 if [ "$load" = "1" ]; then
293 for module in $@; do
294 [ "$module" = "--load" ] && continue
295 cat >> $TMPDIR/sbin/real-init <<EOF
296vecho "Loading module $i..."
297modprobe $i
298EOF
299 done
300 fi
fa424239
MT
301}
302
303resolve_device_name() {
304 if [[ "$1" =~ ^/dev ]]; then
305 echo $1
306 else
307 findfs $1
308 fi
309}
310
311function finalize() {
312 qpopd
313
314 # Adding modules
315 installmodule $MODULES
316
317 # Build module deps file so we can use modprobe
318 vecho "[TASK] Running depmod..."
319 depmod -a -b "$TMPDIR" $KERNEL
320
321 # ldconfig
322 install /etc/ld.so.conf
323 [ -d "/etc/ld.so.conf.d" ] && \
324 for i in $(find /etc/ld.so.conf.d -type f); do
325 install $i
326 done
327 vecho "[TASK] Running ldconfig..."
328 ldconfig -r $TMPDIR
329
330 # Compressing
331 compress
332 rm -rf $TMPDIR 2>/dev/null
333}
334
335# resolve a device node to its major:minor numbers in decimal or hex
336function get_numeric_dev() {
337 ( fmt="%d:%d"
338 if [ "$1" == "hex" ]; then
339 fmt="%x:%x"
340 fi
341 ls -lH "$2" | awk '{ sub(/,/, "", $5); printf("'"$fmt"'", $5, $6); }'
342 ) 2>/dev/null
343}
344
345function resolve_device_name() {
346 if [[ "$1" =~ ^/dev ]]; then
347 echo $1
17e7e3d5 348 else
fa424239
MT
349 findfs $1
350 fi
351}
352
353function finddevnoinsys() {
354 majmin="$1"
355 if [ -n "$majmin" ]; then
356 dev=$(for x in /sys/block/* ; do find $x/ -name dev ; done | while read device ; do \
357 echo "$majmin" | cmp -s $device && echo $device ; done)
358 if [ -n "$dev" ]; then
359 dev=${dev%%/dev}
360 dev=${dev%%/}
361 echo "$dev"
362 return 0
363 fi
17e7e3d5 364 fi
fa424239 365 return 1
17e7e3d5
MT
366}
367
fa424239
MT
368findblockdevinsys() {
369 devname=$(resolve_device_name "$1")
370 if [[ "$devname" =~ ^/sys/block/ ]]; then
371 echo "$devname"
372 fi
373 majmin=$(get_numeric_dev dec $devname)
374 finddevnoinsys "$majmin"
375}
376
377findstoragedriverinsys () {
378 while [ ! -L device ]; do
379 for slave in $(ls -d slaves/* 2>/dev/null) ; do
380 slavename=${slave##*/}
381 case " $slavestried " in
382 *" $slavename "*)
383 continue
384 ;;
385 *)
386 slavestried="$slavestried $slavename"
387 qpushd $slave
388 findstoragedriverinsys
389 qpopd
390 ;;
391 esac
392 done
393 [ "$PWD" = "/sys" ] && return
394 cd ..
395 done
396 cd $(read_link ./device)
397 if echo $PWD | grep -q /virtio-pci/ ; then
9bf81f83 398 installmodule --load virtio_pci
fa424239
MT
399 fi
400 while [ "$PWD" != "/sys/devices" ]; do
401 deps=
402 if [ -f modalias ]; then
9bf81f83 403 installmodule --load $(cat modalias)
fa424239
MT
404 fi
405
406 [ -z "$deps" -a -L driver/module ] && \
407 deps=$(basename $(read_link driver/module))
9bf81f83 408 installmodule --load $deps
fa424239
MT
409 cd ..
410 done
411}
412
413function findstoragedriver() {
414 for device in $@; do
415 case " $handleddevices " in
416 *" $device "*)
417 continue ;;
418 *) handleddevices="$handleddevices $device" ;;
419 esac
420 vecho "[INFO] Looking for driver for device $device"
421 if [[ "$device" =~ ^/sys ]]; then
422 device=${device##*/}
423 fi
424 sysfs=""
425 device=$(echo "$device" | sed 's,/,!,g')
426 if [ -d /sys/block/$device/ ]; then
427 sysfs="/sys/block/$device"
428 else
429 sysfs=$(for x in /sys/block/*; do findone $x/ -type d -name $device; done)
430 fi
431 [ -z "$sysfs" ] && return
432 qpushd $sysfs
433 findstoragedriverinsys
434 qpopd
435 done
436}
437
438# Main
439while [ $# -gt 0 ] ; do
440 case $1 in
441 --help)
442 usage
443 exit 0
444 ;;
445 -f|--force)
446 FORCE=yes
447 ;;
448 -v|--verbose)
449 set_verbose on
450 ;;
451 --with=*)
452 MODULES="$MODULES ${1#--with=*}"
453 ;;
03ff757e
MT
454 --with-net)
455 WITH_NET=1
456 ;;
fa424239
MT
457 *)
458 if [ -z "$target" ] ; then
459 target=$1
460 elif [ -z "$kernel" ] ; then
461 kernel=$1
462 else
463 echo "Unknown option or parameter \"$1\""
464 usage
465 exit 1
466 fi
467 ;;
468 esac
469
470 shift
471done
472
473TARGET=${target-$TARGET}
474KERNEL=${kernel-$KERNEL}
475
476if [ -z "$TARGET" ]; then
477 usage
478 exit 1
479fi
480
481[[ "$TARGET" =~ "^/" ]] && TARGET="$PWD/$TARGET"
482
483if [ -z "$FORCE" ] && [ -e "$TARGET" ]; then
484 echo "Image $TARGET already exists. Use -f to overwrite"
485 exit 1
486fi
487
488# Changing to our dir, where we do our actions in
489qpushd $TMPDIR || exit 1
490
491# Make directory structure
492mkdir -p bin sbin dev sys proc sysroot \
493 etc/udev/rules.d lib/udev/rules.d
494
495# Install some essential binaries
b6d6f925 496install bash blkid chmod cat cut dmesg env find grep head ip kbd_mode \
e79e1f30 497 kill killall5 less ln \
16d10a88 498 ls lsmod mkdir mknod modprobe mount mountpoint openvt pidof ps rm sed \
fbfa5187 499 setfont sh sleep switch_root udevadm udevd umount \
d876bb14 500 /lib/udev/console_init
fa424239 501
fa424239
MT
502# Copy modprobe.conf and friends over
503[ -e /etc/modprobe.conf ] && install /etc/modprobe.conf
504for f in $(find /etc/modprobe.d -type f); do
505 install $f
506done
507
9bf81f83
MT
508# Install an empty fstab
509touch $TMPDIR/etc/fstab
510
fa424239
MT
511# terminfo bits make things work better if you fall into interactive mode
512[ -d "/usr/lib/terminfo" ] && \
513 for f in $(find /usr/lib/terminfo -type f); do
514 install $f
515 done
516
517# Add localization
eee16110
MT
518if [ -e "/etc/sysconfig/console" ]; then
519 install /etc/sysconfig/console
520 . /etc/sysconfig/console
521fi
3e1d8f2b 522[ -z "$FONT" ] && FONT="LatArCyrHeb-16"
fa424239
MT
523for i in /lib/kbd/consolefonts/$FONT.*; do
524 mkdir -p $TMPDIR/$(dirname $i) 2>/dev/null || true
525 cp -f $i $TMPDIR/$i
526 case "$i" in
527 *.gz)
528 gzip -fd $TMPDIR/$i
529 ;;
530 *.bz2)
531 bzip2 -fd $TMPDIR/$i
532 ;;
533 esac
534done
535
536cat > init <<'EOF'
537#!/bin/sh
538
539# Mounting directories
540mount -t proc proc /proc
541mount -t sysfs /sys /sys
542mount -t tmpfs -o mode=0755 udev /dev
543
544# Silencing kernel
545echo > /proc/sys/kernel/printk "1 4 1 7"
546
547# Adding important dev nodes
548mknod /dev/console c 5 1
549mknod /dev/null c 1 3
550mknod /dev/kmsg c 1 11
551mknod /dev/ptmx c 5 2
552mknod /dev/fb c 29 0
553mknod /dev/systty c 4 0
554
555# XXX really we need to openvt too, in case someting changes the
556# color palette and then changes vts on fbcon before gettys start.
557# (yay, fbcon bugs!)
558for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 ; do
559 mknod /dev/tty$i c 4 $i
560done
561
562for i in 0 1 2 3 ; do
563 mknod /dev/ttyS$i c 4 $(($i + 64))
564done
565
566mkdir -m 1777 /dev/shm
567ln -s /proc/self/fd /dev/fd
568ln -s fd/0 /dev/stdin
569ln -s fd/1 /dev/stdout
570ln -s fd/2 /dev/stderr
571
572mkdir /dev/pts
573mount -t devpts -o gid=5,mode=620 /dev/pts /dev/pts
574
575exec sbin/real-init
576EOF
577chmod 755 init
578
579# Write out real-init
580touch sbin/real-init; chmod 755 sbin/real-init
581cat > sbin/real-init <<'EOF'
582#!/bin/bash
583$HEADER
584
585export PATH=/sbin:/bin:/usr/sbin:/usr/bin
586export TERM=linux
587
c8b7be54 588init="/sbin/init"
fa424239
MT
589VERBOSE=-v
590
591READONLY=0
592SHELL=0
593ESHELL=0
594
595function emergency_shell()
17e7e3d5 596{
fa424239
MT
597 echo "Bug in initramfs /init detected. Dropping to a shell. Good luck!"
598 echo
599 bash
17e7e3d5 600}
fa424239 601trap "emergency_shell" 0 2
17e7e3d5 602
fa424239
MT
603# exit immediately if a command fails
604set -e
605
606# Setting verbose mode
607function set_verbose() {
608 case "$1" in
609 yes|y|on|1)
610 VERBOSE=-v
611 ;;
612 no|n|off|0)
613 VERBOSE=
614 ;;
615 esac
17e7e3d5
MT
616}
617
fa424239
MT
618# Returns if verbose is on or not
619function is_verbose() {
620 [ -n "$VERBOSE" ] && return 0
621 return 1
a2402ae4
MT
622}
623
fa424239
MT
624# Like is_verbose but prints
625# the content of $VERBOSE
626function get_verbose() {
627 echo "$VERBOSE"
628 is_verbose
629}
630
631# Prints text if verbose is on
632function vecho() {
633 if is_verbose; then echo "$@"; fi
a2402ae4 634}
17e7e3d5 635
fa424239
MT
636# Prints error if verbose is on
637function error() {
638 vecho "$@" >&2
639}
17e7e3d5 640
fa424239
MT
641/lib/udev/console_init tty0
642
643# Disable hotplugging
644echo "" > /proc/sys/kernel/hotplug
645
646# Parse kernel commandline options
647for o in $(cat /proc/cmdline) ; do
648 case $o in
649 init=*)
c8b7be54 650 init=${o#init=}
fa424239
MT
651 ;;
652 ro)
653 READONLY=1
654 ;;
655 rw)
656 READONLY=0
657 ;;
658 quiet)
659 set_verbose no
660 ;;
661 shell)
662 SHELL=1
663 ;;
664 eshell)
665 ESHELL=1
666 ;;
667 blacklist=*)
668 echo "blacklist ${o#blacklist=}" >> /etc/modprobe.conf
669 ;;
670 *)
671 m=$(echo $o |cut -s -d . -f 1)
672 opt=$(echo $o |cut -s -d . -f 2-)
673 if [ -z "$m" -o -z "$opt" ]; then
674 continue
675 fi
676 p=$(echo $opt |cut -s -d = -f 1)
677 v=$(echo $opt |cut -s -d = -f 2-)
678 if [ -z "$p" -o -z "$v" ]; then
679 continue
680 fi
681 echo "options $m $p=$v" >> /etc/modprobe.conf
682 ;;
683 esac
684done
685
686vecho "kernel commandline: $(cat /proc/cmdline)"
687EOF
77f077f3
MT
688
689if [ "${WITH_NET}" = "1" ]; then
690 MODULES="$MODULES af_packet"
691 for module in /lib/modules/$KERNEL/kernel/drivers/net/{,*/}*; do
692 MODULES="$MODULES $(basename ${module/.ko})"
693 done
694
695 install arping curl dhclient ip ping sha1sum /etc/nsswitch.conf \
696 /usr/lib/libnsl.so /usr/lib/libnss_{dns,files}.so
697 mkdir -p $TMPDIR/var/lib/dhclient 2>/dev/null
698
699 cat > sbin/dhclient-script <<'EOF'
700#!/bin/sh
701
702PATH=/usr/sbin:/sbin:/usr/bin:/bin
703
704function ip_encode() {
705 IFS=.
706
707 local int=0
708 for field in $1; do
709 int=$(( $(( $int << 8 )) | $field ))
710 done
711
712 echo $int
713 unset IFS
714}
715
716function mask_to_cidr() {
717 local mask
718 mask=$(ip_encode $1)
719 local cidr
720 cidr=0
721 local x
722 x=$(( 128 << 24 )) # 0x80000000
723
724 while [ $(( $x & $mask )) -ne 0 ]; do
725 [ $mask -eq $x ] && mask=0 || mask=$(( $mask << 1 ))
726 cidr=$(($cidr + 1))
727 done
728
729 if [ $(( $mask & 2147483647 )) -ne 0 ]; then # 2147483647 = 0x7fffffff
730 echo "Invalid net mask: $1" >&2
731 else
732 echo $cidr
733 fi
734}
735
736function ip_in_subnet() {
737 local netmask
738 netmask=$(_netmask $2)
739 [ $(( $(ip_encode $1) & $netmask)) = $(( $(ip_encode ${2%/*}) & $netmask )) ]
740}
741
742function _netmask() {
743 local vlsm
744 vlsm=${1#*/}
745 [ $vlsm -eq 0 ] && echo 0 || echo $(( -1 << $(( 32 - $vlsm )) ))
746}
747
748dhconfig() {
749 if [ -n "${old_ip_address}" ] &&
750 [ ! "${old_ip_address}" = "${new_ip_address}" ]; then
751 # IP address changed. Bringing down the interface will delete all
752 # routes, and clear the ARP cache.
753 ip -family inet addr flush dev ${interface} >/dev/null 2>&1
754 ip -family inet link set dev ${interface} down
755 fi
756
757 if [ "${reason}" = "BOUND" ] || [ "${reason}" = "REBOOT" ] ||
758 [ ! "${old_ip_address}" = "${new_ip_address}" ] ||
759 [ ! "${old_subnet_mask}" = "${new_subnet_mask}" ] ||
760 [ ! "${old_network_number}" = "${new_network_number}" ] ||
761 [ ! "${old_broadcast_address}" = "${new_broadcast_address}" ] ||
762 [ ! "${old_routers}" = "${new_routers}" ] ||
763 [ ! "${old_interface_mtu}" = "${new_interface_mtu}" ]; then
764 ip -family inet addr add ${new_ip_address}/${new_prefix} \
765 broadcast ${new_broadcast_address} dev ${interface}
766
767 if [ -n "${new_interface_mtu}" ]; then
768 ip link set ${interface} mtu ${new_interface_mtu}
769 fi
770
771 for router in ${new_routers}; do
772 if ! ip_in_subnet ${router} ${new_ip_address}/${new_prefix}; then
773 continue
774 fi
775 ip route replace default via ${router}
776 break
777 done
778 fi
779
780 if [ "${reason}" = "RENEW" ] && \
781 [ "${new_domain_name}" = "${old_domain_name}" ] && \
782 [ "${new_domain_name_servers}" = "${old_domain_name_servers}" ]; then
783 return
784 fi
785
786 if [ -n "${new_domain_name}" ] || [ -n "${new_domain_name_servers}" ] || \
787 [ -n "${new_domain_search}" ]; then
788
789 echo "; generated by $0" > /etc/resolv.conf
790
791 if [ -n "${new_domain_search}" ]; then
792 echo "search ${new_domain_search//\\032/ }" >> /etc/resolv.conf
793 elif [ -n "${new_domain_name}" ]; then
794 echo "search ${new_domain_name//\\032/ }" >> /etc/resolv.conf
795 fi
796
797 for nameserver in ${new_domain_name_servers} ; do
798 echo "nameserver ${nameserver}" >> /etc/resolv.conf
799 done
800 fi
801
802 if [ -n "${new_host_name}" ]; then
803 hostname ${new_host_name}
804 fi
805}
806
807new_prefix=$(mask_to_cidr ${new_subnet_mask})
808
809case "${reason}" in
810 MEDIUM)
811 exit 0
812 ;;
813
814 PREINIT)
815 ip -family inet addr flush dev ${interface} >/dev/null 2>&1
816 ip -family inet link set ${interface} up
817 exit 0
818 ;;
819
820 ARPCHECK|ARPSEND)
821 if [ -z "${new_ip_address}" ] || [ -z "${interface}" ] || \
822 arping -q -f -c 2 -w 3 -D -I ${interface} ${new_ip_address}; then
823 exit 0
824 else
825 exit 1
826 fi
827 ;;
828
829 BOUND|RENEW|REBIND|REBOOT)
830 dhconfig
831 exit 0
832 ;;
833
834 EXPIRE|FAIL|RELEASE|STOP)
835 if [ -n "${old_ip_address}" ]; then
836 # Shut down interface, which will delete routes and clear arp cache.
837 ip -family inet addr flush dev ${interface} >/dev/null 2>&1
838 ip -family inet link set ${interface} down
839 fi
840 exit 0
841 ;;
842
843 *)
844 echo "Unhandled state: ${reason}" >&2
845 exit 1
846 ;;
847esac
848
849EOF
850 chmod 755 sbin/dhclient-script
851fi