#----------------------------------------------------------------------------
# /etc/boot.d/base-helper
#
# Creation:     2004-07-04 jw5 
# Last Update:  $Id: base-helper 10512 2005-12-04 13:50:13Z hh $
#----------------------------------------------------------------------------

#----------------------------------------------------------------------------
# some useful functions
#      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
#      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
#      translate_ip_net
#         translates a config value like IP_NET_1, calls set_error
#         if an error happens
#----------------------------------------------------------------------------
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

    eval debug='$'$SCRIPT'_DO_DEBUG'
    case "$debug" in
    yes)
        debug_active='yes'
        set -x
        ;;
    *)
        case "$tmp_debug" in
        yes) 
             debug_active=yes
             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'
            set +x
            ;;
        esac
    esac
}

log_error () {
    case $# in
    0)
        while read line
        do
        colecho "$SCRIPT: $line" br x br 1>&2
        echo "$SCRIPT: $line" >> /bootmsg.txt
        done
        ;;
    *)
        colecho "$SCRIPT: $*" br x br 1>&2
        echo "$SCRIPT: $*" >> /bootmsg.txt
        ;;
    esac
}

begin_probe () {
    probe='yes'
}

end_probe () {
    probe=''
}

do_insmod () {
    /sbin/insmod $* > /tmp/insmod.res 2>&1 
    res=$?
    if [ ! "$probe" -o "$debug_active" = 'yes' ]
    then
    if [ $res != 0 ]
    then
        log_error "insmod $module $* failed!"
        log_error < /tmp/insmod.res
    fi
    cat /tmp/insmod.res
    fi
}

do_insmod_once () {
    if ! grep -q "^$1 " /proc/modules
    then
        do_insmod $*
    fi
}

do_insmod_if_exists () {
    if [ -f /lib/modules/$kversion/$1/$2.o ]
    then
        shift
        do_insmod $*
    fi
}

do_insmod_if_exists_once () {
    if ! grep -q "^$2 " /proc/modules
    then
        do_insmod_if_exists $*
    fi
}

mk_writable ()
{
    file=$1
    case $file in 
    /opt/*)
        log_error "mk_writable $file invoked, please remove /opt prefix"
        file=`echo $file | sed -e 's#^/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
}

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'
}

is_error ()
{
    case "x$base_error" in
        x) return 1 ;;
        *) base_error= ; return 0 ;;
    esac
}

lookup_name ()
{
    param="$1"
    while read ip name aliases
    do
    case "$ip" in 
        '#') ;; # skip comment
        *)
        case "$param" in
            $name)
            res=$ip
            return 0
            ;;
            *)
            for name in $aliases
            do
                case "$param" in
                $name)
                    res=$ip
                    return 0
                    ;;
                esac
            done
            ;;
        esac
        ;;
    esac
    done < /etc/hosts
    return 1
}

get_value ()
{
    name=`echo $1 | tr '[a-z]' '[A-Z]'`
    eval "res=\$$name"
    case "x$res" in
    x) 
        if ! set | grep -q "$name=" 
        then
            set_error "unknown variable '$name'"
        fi
        ;;
    esac
}

translate_ip_net ()
{
    tin_param="$1"
    case $tin_param in
    *.*.*.* | none | default | pppoe | dynamic)
        res=$tin_param
    ;;
    any)
        res=0.0.0.0/0
    ;;
    IP_NET_*_IPADDR | ip_net_*_ipaddr)
        tmp=`echo $tin_param | sed -e 's/_IPADDR//I'`
        get_value $tmp
        res=`echo $res | sed -e 's#/.*##'`
    ;;
    IP_NET_* | ip_net_*)
        get_value $tin_param
    ;;
    IP_ROUTE_* | 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 `echo $tin_param | sed -e 's/^@//'`
        then
            return
        fi
        set_error "unable to lookup name $tin_param"
    ;;
    *)
        if echo $tin_param | grep '^[0-9,]\+$' 
        then
            res="$tin_param"
            return
        fi
        set_error
    ;;
    esac
    if is_error
    then
        set_error "invalid value '$tin_param' in translate_ip_net ()"
    fi
}

tos=0
SCRIPT='unknown'
SCRIPT_MSG='none'
base_helper='yes'
