#!/bin/sh
: ${resource_lock_timeout:=30}
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 ()
{
set +x
eval "tmp_debug=\"\$stack_${tos}\""
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 ()
{
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}
[ "$booting" = "yes" ] || log_col=""
case $# in
0)
while read line; do
$base_colecho "$log_prefix $line" $log_col 1>&2
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
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
rm -f /tmp/insmod.res.$$
return $res
}
do_modprobe () {
quiet=
if [ "$1" = "-q" ]
then
quiet=-q
shift
fi
/sbin/modprobe $* > /tmp/insmod.res.$$ 2>&1
res=$?
case $res in
0) ;;
*)
if [ -z "$quiet" ]
then
log_error "modprobe $* failed!"
log_error < /tmp/insmod.res.$$
fi
;;
esac
[ -z "$quiet" ] && cat /tmp/insmod.res.$$
rm -f /tmp/insmod.res.$$
return $res
}
do_modprobe_if_exists () {
quiet=
if [ "$1" = "-q" ]
then
quiet=-q
shift
fi
local kernel_version=$(uname -r)
if ! grep -q "^alias $2 " /lib/modules/$kernel_version/modules.alias
then
[ -f /lib/modules/$kernel_version/$1/$2.$mod_ext ] || return 0
fi
shift
do_modprobe $quiet $*
}
do_insmod_once () {
grep -q "^$1 " /proc/modules && return 0
do_insmod $*
}
do_insmod_if_exists () {
local kernel_version=$(uname -r)
if ! grep -q "^alias $2 " /lib/modules/$kernel_version/modules.alias
then
[ -f /lib/modules/$kernel_version/$1/$2.$mod_ext ] || return 0
fi
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
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
}
lookup_name ()
{
local name="$1"
if [ -f /etc/dnsmasq.d/cname.conf ]
then
local real=`grep "=${name}," /etc/dnsmasq.d/cname.conf | cut -d "=" -f2 | cut -d "," -f2`
[ -z "$real" ] || name="$real"
fi
local ip=`sed -n -e "/[[:space:]]${name}\([[:space:]]\|$\)/s/^\([0-9\.]\+\)[[:space:]].*/\1/p" /etc/hosts.d/hosts*`
[ -z "$ip" ] && return 1
set $ip
[ "$2" ] && log_error "lookup_name: multiple IPv4 addresses for $name - $ip"
res=$1
return 0
}
do_translate_ip_net()
{
get_value $1
is_error && return 1
local net="$res"
if [ "$net" = "dhcp" ]
then
potentially_dynamic=1
get_value $1_DEV
is_error && return 1
if [ -f /var/run/dhcpv4.nets ]
then
res=$(sed -n "/^$res=/s/^$res=//p" /var/run/dhcpv4.nets)
else
res=
fi
if [ ! -n "$res" ]
then
set_error
return 1
else
return 0
fi
else
return 0
fi
}
can_translate_ip_net()
{
tin_param="$1"
case $tin_param in
*.*.*.* | none | default | pppoe | any | IP_NET_*_DEV | IP_ROUTE_*)
return 0
;;
dynamic)
[ -f /var/run/dynamic.ip ]
;;
IP_NET_*_IPADDR)
can_translate_ip_net ${tin_param%_IPADDR}
;;
IP_NET_*)
do_translate_ip_net $tin_param
res=$?
clear_error
return $res
;;
@*)
lookup_name ${tin_param#@}
;;
*)
return 1
;;
esac
}
translate_ip_net ()
{
local tin_param="$1"
local var_name=$2
local var=$3
potentially_dynamic=
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)
res=$tin_param
;;
dynamic)
potentially_dynamic=1
if [ -f /var/run/dynamic.ip ]
then
res=$(cat /var/run/dynamic.ip)
else
set_error "no dynamic IPv4 address available"
fi
;;
any)
res=0.0.0.0/0
;;
IP_NET_*_IPADDR)
do_translate_ip_net ${tin_param%_IPADDR}
res=${res%/*}
;;
IP_NET_*)
do_translate_ip_net $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
;;
*)
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_ignore=$3
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)
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
*+)
;;
*)
if grep -q "^[[:space:]]*\<$tid_real_if\>" /proc/net/dev
then
net_alias_add $tid_tif $tid_real_if TID_
elif [ -z "$tid_ignore" ]
then
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 ()
{
sleep 1
}
get_local_ipv4_addresses()
{
local i res
for i in $(seq 1 ${IP_NET_N:-0})
do
if do_translate_ip_net IP_NET_${i}
then
echo $res
else
clear_error
fi
done
return 0
}
get_local_ipv4_subnets()
{
local addr
for addr in $(get_local_ipv4_addresses)
do
echo $(netcalc network $addr)/${addr#*/}
done
return 0
}
lock_resource()
{
local pidfile="/var/lock/fli4l-$1.$$"
local lockfile="/var/lock/fli4l-$1.lock"
local i=0
while ! ln -s "$pidfile" "$lockfile" 2>/dev/null
do
sleep 1
i=$((i + 1))
if [ $i -eq $resource_lock_timeout ]
then
pid=$(readlink "$lockfile" | sed 's/.*\.\([0-9]\+\)$/\1/')
owner=$(cat /proc/$pid/comm)
log_error "$2: failed to lock resource $1 within $resource_lock_timeout seconds: already locked by $owner[$pid]"
return 1
fi
done
return 0
}
unlock_resource()
{
local lockfile="/var/lock/fli4l-$1.lock"
rm -f "$lockfile"
return 0
}
. /etc/boot.d/volume.inc
tos=0
SCRIPT='unknown'
SCRIPT_MSG='none'
base_helper='yes'
mod_ext=ko
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_
