#---------------------------------------------------------------------------- # /etc/boot.d/base-helper # # Creation: 2004-07-04 jw5 # Last Update: $Id$ #---------------------------------------------------------------------------- #---------------------------------------------------------------------------- # some useful functions # do_modprobe module params # do_insmod module params # do_insmod_once module params # do_insmod_if_exists module_path module params # module_path is relativ to /lib/modules/kernel_version # do_insmod_if_exists_once module_path module params # begin_script name # end_script name # get_rc_variable variable name file # mk_writable file # unique elements # returns a unique list in $list # set_error # sets an error flag and show an error message # is_error # checks and resets error flag set by set_error # clear_error # clears error flag set by set_error # log_error # show an error message and write it to /bootmsg.txt # translate_ip_net [ []] # translates a config value like IP_NET_1, calls set_error # if an error happens # translate_ip_dev () # translate a symbolic name the corresponding device name; # invokes set_error if an unknown symbolic name is passed # translate_ip_dev_reverse () # reverse lookup for device names, delivers the symbolic name # for a device #---------------------------------------------------------------------------- begin_push () { tos=`/usr/bin/expr $tos + 1` eval "stack_$tos=\"${1}\"" } begin_pop () { eval "ret=\"\$stack_${tos}\"" tos=`/usr/bin/expr $tos - 1` } begin_script () { # disable debugging set +x eval "tmp_debug=\"\$stack_${tos}\"" # push name and debug state of last script begin_push "$SCRIPT" begin_push "$SCRIPT_MSG" begin_push "$debug_active" SCRIPT="$1" SCRIPT_MSG="$2" if echo $1 | grep -q '[[:space:]]'; then log_error "script label contains spaces: '$1'" SCRIPT=$script fi case "x$SCRIPT_MSG" in x) SCRIPT_MSG="executing $SCRIPT ($script)" ;; *) SCRIPT_MSG="$SCRIPT_MSG ($script)" ;; esac /usr/local/bin/colecho "-> $SCRIPT_MSG" gn shell_dbg_opt= eval debug='$'$SCRIPT'_DO_DEBUG' case "$debug" in yes) debug_active='yes' shell_dbg_opt=-x set -x ;; *) case "$tmp_debug" in yes) debug_active=yes shell_dbg_opt=-x set -x ;; esac ;; esac } end_script () { # disable debugging set +x /usr/local/bin/colecho "-> finished $SCRIPT_MSG" gn begin_pop debug_state="$ret" begin_pop SCRIPT_MSG="$ret" begin_pop SCRIPT="$ret" case "$debug_active" in yes) case "$debug_state" in yes) set -x ;; *) debug_active='no' shell_dbg_opt= set +x ;; esac esac } do_log () { : ${base_log_file:=/bootmsg.txt} : ${base_colecho:=colecho} # kristov: disable colours when not called from a boot script (ticket #209) [ "$booting" = "yes" ] || log_col="" case $# in 0) while read line; do $base_colecho "$log_prefix $line" $log_col 1>&2 # kristov: don't log into file when not called from a boot script if [ "$booting" = "yes" ]; then case $log_boot$cons_boot in yesyes) echo "($script) $log_prefix $line" >> $base_log_file ;; esac fi done ;; *) $base_colecho "$log_prefix $*" $log_col 1>&2 # kristov: don't log into file when not called from a boot script if [ "$booting" = "yes" ]; then case $log_boot$cons_boot in yesyes) echo "($script) $log_prefix $*" >> $base_log_file ;; esac fi ;; esac } log_info() { log_boot= log_prefix=" " log_col=$2 : ${log_col:=gn} case "$1" in cy) log_col=$1 ; shift ;; esac case $# in 0) do_log ;; *) do_log "$@" ;; esac return 0 } log_warn() { log_boot=yes log_prefix="WARN:" log_col=rd do_log "$@" return 0 } log_error() { log_boot=yes log_prefix="ERR:" log_col="br x br" do_log "$@" return 1 } begin_probe () { probe='yes' } end_probe () { probe='' } do_insmod () { log_error "invoking insmod (directly or via one of the do_insmod variants), please try to eleminate it or replace it with do_modprobe" /sbin/insmod $* > /tmp/insmod.res 2>&1 res=$? if [ ! "$probe" -o "$debug_active" = 'yes' ] then case $res in 0) ;; *) log_error "insmod $module $* failed!" log_error < /tmp/insmod.res ;; esac cat /tmp/insmod.res fi return $res } do_modprobe () { /sbin/modprobe $* > /tmp/insmod.res 2>&1 res=$? case $res in 0) ;; *) log_error "modprobe $* failed!" log_error < /tmp/insmod.res ;; esac cat /tmp/insmod.res rm -f /tmp/insmod.res return $res } do_modprobe_if_exists () { [ -f /lib/modules/$kernel_version/$1/$2.$mod_ext ] || return 0 shift do_modprobe $* } do_insmod_once () { grep -q "^$1 " /proc/modules && return 0 do_insmod $* # returns the result of do_insmod } do_insmod_if_exists () { [ -f /lib/modules/$kernel_version/$1/$2.$mod_ext ] || return 0 shift do_insmod $* } do_insmod_if_exists_once () { grep -q "^$2 " /proc/modules && return 0 do_insmod_if_exists $* } mk_writable () { file=$1 case $file in /opt/*) log_error "mk_writable $file invoked, please remove /opt prefix" file=${file#/opt} ;; esac if [ -e $file ] then if [ -L $file ] then cp $file /tmp/mkwrt.$$ rm -f $file mv /tmp/mkwrt.$$ $file fi if [ ! -w $file ] then chmod +w $file fi fi } get_rc_variable() { local var=$1 local name=$2 local file=$3 # sed expression # s/^${name}='(.*)'/\1/p eval "$var='`sed -n \"s/^${name}='\(.*\)'/\1/p\" $file`'" } unique () { list='' for i in $* do case $list in *$i*) ;; *) list="$list $i" ;; esac done } set_error () { case "x$1" in x) ;; *) log_error "$1" ;; esac base_error='yes' return 1 } is_error () { case "x$base_error" in x) return 1 ;; *) base_error= ; return 0 ;; esac } clear_error () { base_error= } get_value () { local name=$1 eval res=\$$name case "x$res" in x) if ! set | grep -q "$name=" then set_error "unknown variable '$name'" fi ;; esac } # usage: lookup_name # parameter: either a FullQualifiedDomainName or an alias name # returns: nothing # errorcodes: 0 success - successfully resolved name to ip address # 1 error - no matching host record found # # description: Tries to resolve either an FQDN or an alias to an IP address. # Uses /etc/hosts and /etc/hosts.d/hosts* as source. # MAGIC done by this function: # The result will be stored in an global variable "res". lookup_name () { local name="$1" # sed expression description # - /[[:space:]]${name}\([[:space:]]\|$\)/ # a line containing the name we look for lead by a space and followed # by a space or a line end # - [0-9\.]\+ # an expression containing numbers and dots - may be an ip address # - s/^\([0-9\.]\+\).*/\1/p # an ip addresse at the beginning of the line - print it without # the remaining characters local ip=`sed -n -e "/[[:space:]]${name}\([[:space:]]\|$\)/s/^\([0-9\.]\+\).*/\1/p" /etc/hosts.d/hosts*` [ -z "$ip" ] && return 1 set $ip [ "$2" ] && log_error "lookup_name: multiple ip addresses for $name - $ip" res=$1 return 0 } lookup_name_orig () { # grep $1 /etc/hosts.d/hosts* > /tmp/hosts.all cat /etc/host.d/hosts* > /tmp/hosts.all param="$1" while read ip name aliases do case "$ip" in '#') ;; # skip comment *) case "$param" in $name) res=$ip rm /tmp/hosts.all return 0 ;; *) for name in $aliases do case "$param" in $name) res=$ip rm /tmp/hosts.all return 0 ;; esac done ;; esac ;; esac done < /tmp/hosts.all rm /tmp/hosts.all return 1 } translate_ip_net () { local tin_param="$1" local var_name=$2 local var=$3 case $tin_param in ip_net_* | ip_route_*) log_error "translate_ip_net: $tin_param ist not support anymore, use the real upper case names" tin_param=`echo $tin_param | tr a-z A-Z` ;; esac case $tin_param in *.*.*.* | none | default | pppoe | dynamic) res=$tin_param ;; any) res=0.0.0.0/0 ;; IP_NET_*_IPADDR) get_value ${tin_param%_IPADDR} res=${res%/*} ;; IP_NET_*) get_value $tin_param ;; IP_ROUTE_*) get_value $tin_param set $res res=$1 case $res in 0.0.0.0/0) set_error "you can't use a default route entry in a packet filter rule" ;; esac ;; @*) if ! lookup_name ${tin_param#@} then set_error "unable to lookup name $tin_param" fi ;; *) # # what is this case for? # if echo $tin_param | grep -q '^[0-9,]\+$' then res="$tin_param" else set_error fi ;; esac if is_error then if [ "$var_name" ]; then log_error "Unable to translate value '$tin_param' contained in $var_name." else set_error "invalid value '$tin_param' in translate_ip_net ()" fi clear_error return 1 else [ "$var" ] && eval $var="\"$res\"" return 0 fi } translate_ip_dev () { local tid_tif=$1 local tid_var=$2 local tid_real_if= if [ ! "$tid_var" ]; then log_error "translate_ip_dev: missing variable name" return fi net_alias_lookup_dev $tid_tif $tid_var TID_ && return case $tid_tif in IP_NET_*_DEV | ip_net_*_dev) translate_ip_net $tid_tif && tid_real_if=$res ;; circuit-*) if [ -f /var/run/$tid_tif ]; then read tid_real_if < /var/run/$tid_tif else set_error " Error: unknown circuit $tid_tif" fi ;; pppoe) if [ -f /var/run/pppoe-device ]; then read tid_real_if < /var/run/pppoe-device else set_error " Error: unknown circuit pppoe" fi ;; *) tid_real_if=$tid_tif ;; esac if [ "$tid_real_if" ]; then case $tid_real_if in *+) ;; # ignore wildcard names *) if grep -q $tid_real_if /proc/net/dev; then net_alias_add $tid_tif $tid_real_if TID_ else log_error "translate_ip_dev '$tid_tif': device '$tid_real_if' not present" fi ;; esac [ "$tid_var" ] && eval $tid_var=$tid_real_if fi } translate_ip_dev_reverse () { net_alias_lookup_name $1 $2 TID_ } wait_for_mdev () { while true; do read mdev_seq < /dev/mdev.seq read kernel_seq < /sys/kernel/uevent_seqnum [ 0$mdev_seq -gt 0$kernel_seq ] && break sleep 1 done } tos=0 SCRIPT='unknown' SCRIPT_MSG='none' base_helper='yes' case $kernel_version in 2.4*) mod_ext=o ;; *) mod_ext=ko ;; esac case "`ls -l /proc/$$/fd/1 2> /dev/null`" in */dev/console*) cons_boot=yes ;; esac : ${net_alias:=/etc/boot.d/network_aliases} . $net_alias net_alias_init net_alias_lookup_dev any any TID_ || net_alias_add any any TID_