#!/bin/sh
#----------------------------------------------------------------------------
# /etc/rc - boot script
#
# Creation:     29.03.2000  fm
# Last Update:  $Id: rc,v 1.45 2004/05/06 19:09:03 harri Exp $
#  
# Copyright (c) 2000-2002 Frank Meyer
#----------------------------------------------------------------------------

#----------------------------------------------------------------------------
# stop-function to be used instead of 'exit' to keep error-messages readable 
#----------------------------------------------------------------------------
stop ()
{
    while true
    do
        if [ "$fli4l_debug" = "yes" ]
        then
	    exec > /dev/console 2>&1
            /bin/sh
        else
            sleep 10000
        fi
    done
}

#----------------------------------------------------------------------------
# extract boot param
#----------------------------------------------------------------------------
get_boot_param () {
    grep " $1" /proc/cmdline > /dev/null 2>&1
    if [ $? -ne 0 ]
    then
        if [ "$2" = "stop" ]
        then
            echo "ERROR: Missing parameter $1= in syslinux.cfg, stopping boot process" 2>&1
            stop
        fi
    else
        sed "s/.* $1=\([^[:space:]]*\).*/\1/" /proc/cmdline
    fi
}

#-----------------------------------------------------------------------------
# get_tar_from_boot - fetch opt.tar from floppy, hd or cd mounted on /boot
#-----------------------------------------------------------------------------
get_tar_from_boot() {
    if [ ! -f /boot/$1 ]
    then
        echo "ERROR: missing $1, stopping boot process" 2>&1
        stop
    fi
    bunzip2 -c /boot/$1
}

#-----------------------------------------------------------------------------
# get_tar_from_network - fetch opt.tar from network
#-----------------------------------------------------------------------------
get_tar_from_network() {
    tftp -g -r $b_dir/$1 -l - $b_sv | bunzip2 -c 
}


PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin:.; export PATH
trap "" 1

#----------------------------------------------------------------------------
# mount devices, e.g. /proc
#----------------------------------------------------------------------------
cd /        # be in root directory
mount -av   # mount /proc
mount
chmod 755 / # tmpfs has some strange default modes...

#----------------------------------------------------------------------------
# initialize some variables
#----------------------------------------------------------------------------
fli4l_debug=`get_boot_param fli4ldebug`
if [ "$fli4l_debug" = "yes" ]
then
    set -x
    fli4l_deb_log=`get_boot_param fli4ldeblog`
    if [ "$fli4l_deb_log" ]
    then
	exec > /tmp/boot.log 2>&1
    fi
    stack_0='yes'
fi
boot_dev=`get_boot_param boot stop`
recover=`get_boot_param recover`
rcfile=rc.cfg
optfile=opt_tar.bz2
optbackup=opt2_tar.bz2
boot_fs=vfat

#----------------------------------------------------------------------------
# check if kernel supports e2compr
#----------------------------------------------------------------------------
E2COMPR_KERNEL=`grep ext2_register /proc/ksyms | cut -f2 -d" "`

if [ "$E2COMPR_KERNEL" = "ext2_register_compression_module" ]
then
   E2COMPR_KERNEL="yes"
   echo 'E2COMPR_KERNEL="yes"' >> /var/run/e2compr.cfg
   echo "e2compr: Using a linux kernel with e2compr-support."
fi

#----------------------------------------------------------------------------
# load drivers if needed
#----------------------------------------------------------------------------
if [ -f /etc/modules.sh ]
then
    dtou /etc/modules.sh
    . /etc/modules.sh
fi

#----------------------------------------------------------------------------
# get rc.cfg
#----------------------------------------------------------------------------
case "$boot_dev" in
    network)      # booting from network
# Append-Line must have the following parameters:
# boot=network              # set boot-flag
# b_ip=192.169.6.1/24       # set ip-address to get opt.tar.bz2
# b_gw=192.168.6.10         # not needed if tftp-server is in the same subnet
# b_sv=192.168.6.2          # ip of the tftp-server (not dns-name)
# b_dir=/export/fli4l-boot  # directory where opt.tar.bz2 is stored on the tftp-server
        b_ip=`get_boot_param address stop`  # ip-address and netmask
        b_gw=`get_boot_param b_gw`          # optional default-router  
        b_sv=`get_boot_param b_sv stop`     # tftp-server
        b_dir=`get_boot_param b_dir stop`   # tftp-directory

        # calculate the other values
        address=`echo $b_ip | cut -d / -f 0`
        netmask=`netcalc netmask $b_ip`
        broadcast=`netcalc broadcast $b_ip`

        # configure interfaces
        ifconfig eth0 $address netmask $netmask broadcast $broadcast

        # set gateway if needed
        if [ "$b_gw" ]
        then
            route add default gw $b_gw
        fi

        # fetch rc.cfg from server
        colecho "fetching $b_dir/rc.cfg from $b_sv - please wait ..." gn
        tftp -g -r "$b_dir"/rc.cfg -l /tmp/rc.$$ "$b_sv"
        if [ $? != 0 ]
        then
            colecho "ERROR: unable to fetch rc.cfg from server" br x br
            stop   
        fi
        get_opt_tar=get_tar_from_network
    ;;
    integrated)     # opt_tar.bz2 and rc.cfg are already in rootfs
# Append-Line must have the following parameters:
# boot=integrated                                   # set boot-flag
    cp /boot/rc.cfg /tmp/rc.$$
    get_opt_tar=get_tar_from_boot
    ;;
    *)              # opt.tar.bz2 is on fdd/hd/cd
# Append-Line must have the following parameters:
# boot=<device where opt.tar.bz2 ist stored>        # set boot-flag
        mount -r "$boot_dev" /boot -t "$boot_fs"
        if [ "$?" != "0" ]
        then
            colecho "ERROR: can't mount boot-partition, check drivers" br x br
            stop
        fi

        if [ -f /boot/rc999.recover -a -f /boot/$optbackup -a -f /boot/rc2.cfg ]
        then
            cp /boot/rc999.recover /etc/rc.d
            dtou /etc/rc.d/rc999.recover
            . /etc/rc.d/rc999.recover
        fi

        colecho "getting configuration from bootdisk ..." gn
        cp /boot/"$rcfile" /tmp/rc.$$
        if [ "$?" != "0" ]
        then
            colecho "ERROR: $rcfile not found on boot-partition" br x br
            stop   
        fi

        get_opt_tar=get_tar_from_boot
    ;;
esac

#----------------------------------------------------------------------------
# load configuration from rc.cfg
#----------------------------------------------------------------------------
dtou /tmp/rc.$$
. /tmp/rc.$$			# get fli4l config
rm /tmp/rc.$$			# clean up

if [ -f /boot/hd.cfg ]  # get hdinstall config if present
then
    cp /boot/hd.cfg /tmp/hd.$$
    dtou /tmp/hd.$$
    . /tmp/hd.$$
    rm /tmp/hd.$$		# clean up
fi

#----------------------------------------------------------------------------
# create ramdisk or mount partition for optional files
#----------------------------------------------------------------------------
if [ "$E2COMPR_OPT" = "yes" -a "$E2COMPR_KERNEL" = "yes" -a "$recover" != "fastreset" ]
then

    echo "e2compr: Using ext2fs for this ramdisk."
    inodes=`/usr/bin/expr "$E2COMPR_OPT_SIZE" / 4 + 1024`
    mkfs.ext2 -qm0 -N $inodes /dev/ram1 "$E2COMPR_OPT_SIZE" 2> /dev/null

    echo "/dev/ram1 /opt ext2 ro 0 0" >>/etc/fstab
    opt_on_hd=no

elif [ "$hd_opt" = "" -o "$recover" = "fastreset" ]
then
    echo "tmpfs /opt tmpfs ro,mode=755 0 0" >>/etc/fstab
    opt_on_hd=no
else
    echo "/dev/$hd_opt /opt minix ro,noatime 0 0" >>/etc/fstab
    opt_on_hd=yes
    fsck.minix -a /dev/"$hd_opt"
fi
    
#----------------------------------------------------------------------------
# mount optional files location
#----------------------------------------------------------------------------
colecho "mount optional files location ..." gn
mount /opt
if [ "$?" != "0" ]
then
    colecho "ERROR: can't mount /opt" br x br
    stop
fi

#----------------------------------------------------------------------------
# unzip all files from bootdevice to optfiles-location
#----------------------------------------------------------------------------
unpack ()       # declare unpack-function first
{
    cd /opt
    eval "$get_opt_tar $optfile" | pipe_progress | tar -xf - 2>/tmp/tar-error-$$
    if [ -s /tmp/tar-error-$$ ]
    then
        colecho "ERROR: tar failed with:" br x br
        cat /tmp/tar-error-$$
        if [ $opt_on_hd = 'yes' ]
        then
            colecho "ERROR: not enough space on hd, check size of /dev/$hd_opt" br x br
        else
            colecho "ERROR: you seem to be out of RAM" br x br
        fi
        stop
    fi
    rm /tmp/tar-error-$$
    cd /

    dtou /opt/etc/prep/rc*.*
    for j in /opt/etc/prep/rc*.*
    do
        if [ -f $j ]
        then
            . $j
        fi
    done
}

#----------------------------------------------------------------------------
# update files on opt-Partition if new opt_tar.bz2 found 
#----------------------------------------------------------------------------
if [ "$opt_on_hd" = "yes" -a -f /boot/$optfile ]
then
    mount -w /opt -o remount
    mount -w $boot_dev /boot -t "$boot_fs" -o remount
    rm -rf /opt/etc /opt/files /opt/var
    colecho "updating optional files on harddisk ..." gn
    unpack
    rm /boot/opt.old 2>/dev/null
    mv /boot/$optfile /boot/opt.old
elif [ "$opt_on_hd" = "no" ]
then
    colecho "extracting files from $optfile ..." gn
    mount -w /opt -o remount

    # e2compr: enable compression if activated
    if [ "$E2COMPR_OPT" = "yes" -a "$E2COMPR_KERNEL" = "yes" ]
    then
         echo "e2compr: enabling \"/opt\"-compression using $E2COMPR_OPT_ALGO."
         /bin/chattr +c -m "$E2COMPR_OPT_ALGO" /opt && \
         echo 'E2COMPR_OPT_OK="yes"' >> /var/run/e2compr.cfg
    fi

    unpack
fi

if [ "$boot_dev" = "network" ]      # remove lan-drivers after getting opt_tar.bz2
then
    ifconfig eth0 down
    . /etc/stop-modules.sh
elif [ "$boot_dev" != "integrated" ]
then
    umount /boot
fi

#----------------------------------------------------------------------------
# create symlinks to optfiles
#----------------------------------------------------------------------------
colecho "creating symlinks from rootfs to optional files ..." gn
mount -r /opt -o remount
/bin/sh /etc/mklinks.sh /opt/files /

#----------------------------------------------------------------------------
# copy config and var-files
#----------------------------------------------------------------------------
cp -R /opt/etc/* /etc 2>/dev/null
cp -R /opt/var/* /var 2>/dev/null

#----------------------------------------------------------------------------
# initialize counter for ttyI devices
#----------------------------------------------------------------------------
echo 0 >/var/run/next_ttyI

#----------------------------------------------------------------------------
# run rc-script, normal bootsequence from here. scripts are already dtou'ed !
#----------------------------------------------------------------------------
for j in /etc/rc.d/rc*.*
do
    if [ -f $j ]
    then
        . $j
    fi
done

if [ "$fli4l_deb_log" ]
then
    exec > /dev/console 2>&1
    cp /tmp/boot.log $fli4l_deb_log
    sync
fi
# prevent dying deamons
sleep 10
