#!/bin/sh

# $Id$
numsec=1
id=$(id -u)
if [ $id -ne 0 ]; then
    echo "Run me as root"
    exit 0
fi

DRELEASE="FBSD72"
DARCH="amd64"

usage () {
printf "Usage:\n"
printf "\t$0 -r <release> [ -a <arch> ] [ -p <prefix> ]\n"
printf "\t$0 -h\n"
printf "\t$0 --help\n"
printf "default arch is ${DARCH}\n"
printf "example: $0 -r ${DRELEASE} -a ${DARCH}\n"
exit 0
}

if [ $# -eq 0 ]; then
  usage ${0}
fi

args=`getopt hr:a:p: $*`
set -- $args
for i; do
    case "$i"
    in
        -h|--help) usage ${0};;
        -r) RELEASE="$2";
            shift; shift;;
        -a) ARCH="$2";
            shift; shift;;
        -p) PREFIX="$2";
            shift; shift;;
        --) shift; break;;
    esac
done

if [ -z "${PREFIX}" ]; then
    PREFIX=""
fi

if [ -z "${RELEASE}" ]; then
    RELEASE=${DRELEASE}
fi
if  [ -z "${ARCH}" ]; then
    ARCH=${DARCH}
fi
excludes_root="etc/amd.map
etc/crontab
etc/exports
etc/fstab
etc/group
etc/hosts.equiv
etc/inetd.conf
etc/login.conf
etc/login.conf.db
etc/mail/aliases
etc/master.passwd
etc/passwd
etc/pwd.db
etc/spwd.db
etc/netgroup
etc/networks
etc/newsyslog.conf
etc/nscd.conf
etc/pam.d/rsh
etc/pam.d/sshd
etc/radius.conf
etc/rc.conf
etc/rc.d/place
etc/resolv.conf
etc/shells
etc/ssh/ssh_config
etc/ssh/ssh_known_hosts
etc/ssh/sshd_config
etc/sysctl.conf
etc/syslog.conf
etc/pam.d/sshd
root/.rhosts
root/.ssh/authorized_keys
root/.vimrc
named/etc/namedb/named.conf
named/etc/namedb/named.root
named/etc/namedb/rndc.conf
named/etc/namedb/ya_zone.conf
named/etc/namedb/localhost.rev
"
###############################################################################
############ some "library" stuff - wrappers, helpers, etc ####################
#####################################33########################################
color_yellow="\033[0m\033[0;33m"
color_green="\033[0m\033[0;32m"
color_red="\033[0m\033[0;31m"
color_blue="\033[0m\033[0;36m"
color_gray="\033[0m\033[0;28m"

LOGFILE=""
DMESG=""

cmdwrapper (){
        printf  "\t${color_gray}%s${color_blue}\n" "$cmd" > /dev/stderr
        #first arg - -rv or "" - return value to stdout (into variable, for example)
        #second arg - "fatal" or nothing - treat error as fatal or not
        ts="`date +%H:%M.%S`"
        if [ -n "${LOGFILE}" -a -f ${LOGFILE} ]; then
            printf "$ts | %s\n" "$cmd" >> ${LOGFILE}
        fi
        err=0
        fatal=$2
        retvarname=$1
        [ "$1" = "fatal" ] && fatal="fatal"
        if tmperr=`mktemp -t tmperr 2> /dev/null`; then
        else                                                                                                                        
           tmperr=/dev/null
        fi
        retvar=`eval $cmd 2> ${tmperr}`; err=$?
        if [ -n "${DMESG}" -a -f ${DMESG} ]; then
            dmesg > ${DMESG}
        fi
        if [ "$err" != 0 ]; then
            if [ -n "$fatal" ]; then
                printf "${color_red}\t\t`cat ${tmperr}`\n:Fatal error\nInterrupting setup...\n${color_gray}" 1>&2
                if [ -n "${LOGFILE}" -a -f ${LOGFILE} ]; then
                    cat ${tmperr} >> ${LOGFILE}
                fi
                fatal 1000 "Can't continue setup"
            else
                printf "${color_red}\t\t`cat ${tmperr}`\n\t\tNon-fatal error\n\t\tContinue...\n${color_gray}" 1>&2
                if [ -n "${LOGFILE}" -a -f ${LOGFILE} ]; then
                    cat ${tmperr} >> ${LOGFILE}
                fi
                return 1
            fi
        fi
        [ "${retvarname}" = "-rv" ] && printf "${retvar}"
        return 0
}

mprintf (){
    ts="`date +%H:%M.%S`"
    if [ "$1" = "Done" ]; then
        printf "${color_green}Done${color_gray}\n\n\n"
    else
        printf "${color_yellow}$1${color_gray} \n"
    fi
    
    if [ -n "${LOGFILE}" -a -f ${LOGFILE} ]; then
        if [ "$1" = "Done" ]; then
            printf "$ts\t--> Done\n\n\n" >> ${LOGFILE}
        else
            printf "$ts\t--> %s \n" "$1" >> ${LOGFILE}
        fi
    fi
}

countdown () {
    c=$1
    nr="$2"
    while [ $c -gt 0 ]; do
        c=$(($c-1))
        cl=$((`echo $c | wc -m`-1))
        printf "$c" 1>&2
        if [ -z "$nr" ];then
            read -t 1 REBOOT
            if [ $? -eq 0 ]; then                                                                                                   
                mprintf "\nExiting...."
                exit 0
            fi
        else
            read -t 1 REBOOT
            if [ $? -eq 0 ]; then
                c=0
                return 0;
            fi
        fi
        while [ $cl -gt 0 ]; do
            cl=$(($cl-1))
            printf '\b' 1>&2
        done
    done
}
#fatal trap handler
fatal () {
    mprintf "$2" 1>&2
    countdown $numsec
    mprintf "\nExiting...."
    exit 1
}
###############################################################################
############ end of "library" stuff - wrappers, helpers, etc ##################
#####################################33########################################


chat (){
    # imitate restore interactive session
    echo 'add *'
    for file in `eval echo $"excludes"_$1` ;do
        echo "delete $file"
    done
    echo "extract"
    sleep 1
    echo "1"
}

mprintf "Mounting remote filesystems"
nfs_flags="-T -3 -r 32768 -w 32768 -o noatime,async,nosuid,ro -i -t 600 -R 10 -x 10"
nfs_parent="ysbackup2.yandex.ru"
nfs_basepath="/opt/tftpboot/${RELEASE}.${ARCH}"
cmd="find \
/sbin/ \
/usr/bin/ \
/usr/sbin/ \
/bin/ \
/lib/ \
/rescue/ \
/stand/ \
/var/empty/ \
/libexec/ \
/usr/libexec/ \
/usr/share/ \
/usr/include/ \
/usr/lib/ \
/usr/lib32/ \
-fstype ufs -flags schg | xargs chflags noschg"; cmdwrapper fatal
cmd="mkdir /mnt/dump"; cmdwrapper
cmd="mount_nfs $nfs_flags $nfs_parent:$nfs_basepath/dumps.${RELEASE}.${ARCH}/common /mnt/dump";cmdwrapper fatal
cmd="mkdir /mnt/kern"; cmdwrapper
cmd="mount_nfs $nfs_flags $nfs_parent:$nfs_basepath/kernels.${RELEASE}.${ARCH}/common /mnt/kern"; cmdwrapper fatal
mprintf "Done"

mprintf "Installing kernel"
cmd="ls /mnt/kern/*sh"
KERNSCRIPT="`cmdwrapper -rv`"
if [ -z "${PREFIX}" ]; then
    cmd="/bin/sh ${KERNSCRIPT}"; cmdwrapper
else
    cmd="/bin/sh ${KERNSCRIPT} -p ${PREFIX}"; cmdwrapper
fi
mprintf "Done"

#mprintf "Restoring var"
#cd ${PREFIX}/var
#cmd="chat var | restore -u -i -f /mnt/dump/var.dump > /dev/null 2>&1"; cmdwrapper fatal
#mprintf "Done"

mprintf "Restoring root"
cd ${PREFIX}/
cmd="chat root | restore -u -i -f /mnt/dump/root.dump > /dev/null 2>&1"; cmdwrapper fatal
if [ -z "${PREFIX}" ]; then
    mount -t devfs dev /dev
fi
mprintf "Done"


mprintf "Housekeeping"
cmd="umount /mnt/dump"; cmdwrapper
cmd="umount /mnt/kern"; cmdwrapper
cmd="rm -R /mnt/dump /mnt/kern"; cmdwrapper
mprintf "Done"
exit 0
