#! /bin/sh
#
# Author:   Matt Zimmerman <mdz@ubuntu.com>
#
### BEGIN INIT INFO
# Provides:          ltsp-client-setup
# Required-Start:    mountvirtfs $local_fs
# Required-Stop:     mountvirtfs $local_fs
# Default-Start:     S 1 2 3 4 5
# Default-Stop:      0 6
# Short-Description: Script for LTSP client initialization
# Description:
### END INIT INFO

set -e

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC="LTSP client setup"
NAME=ltsp-client-setup
SCRIPTNAME=/etc/init.d/$NAME

# Gracefully exit if ltsp_chroot file is not present
test -f /etc/ltsp_chroot || exit 0

. /lib/lsb/init-functions
. /usr/share/ltsp/ltsp-init-common

test -f /etc/default/ltsp-client-setup && . /etc/default/ltsp-client-setup

load_modules() {
    for module in $(env|grep ^MODULE_|sed -e s/^MODULE_[0-9]*\=//|sed -e s/\ /*/);do
        modprobe $(echo $module|tr "*" " ")
    done
}

configure_nbd() {
    # Restart nbd so -persist will work
    nbdcmd=`pgrep -l -f "/dev/nbd0 -persist" | cut -d " " -f "2-"`
    if [ -n "$nbdcmd" ]; then
        nbd-client -d /dev/nbd0
        nbd-client -c /dev/nbd0
        while [ "$?" != "1" ]; do
            nbd-client -c /dev/nbd0
        done
        $nbdcmd
    fi
}

configure_localdev() {
    boolean_is_true "$LOCALDEV" && mkdir -p /var/run/drives
}

configure_console() {
    if [ -n "$CONSOLE_KEYMAP" ]; then
        ckbcomp -model pc105 "$CONSOLE_KEYMAP" | loadkeys
    fi
}

configure_resolver() {
    hostname=$(hostname)
    if [ "(none)" = "$hostname" ] ; then
        /etc/init.d/hostname.sh start
        hostname="$(hostname)"
    else
        echo $hostname > /etc/hostname
    fi
    cat <<EOF > /etc/hosts
127.0.0.1 localhost
127.0.0.2 $hostname
$SERVER server
EOF
    if [ -f /etc/hosts.ltsp ]; then
        cat /etc/hosts.ltsp >> /etc/hosts
    fi

    if [ -n "$DNS_SERVER" ] && [ -n "$SEARCH_DOMAIN" ]; then
        cat <<EOF > /etc/resolv.conf
search $SEARCH_DOMAIN
nameserver $DNS_SERVER
EOF
    fi
}

configure_syslog() {
    if [ -z "$SYSLOG" ] || [ "$SYSLOG" = "remote" ]; then
        syslog_conf=/etc/syslog.conf
        if [ -d /etc/rsyslog.d ]; then
            syslog_conf=/etc/rsyslog.d/ltsp.conf   
            touch $syslog_conf
        fi
        if [ -f "$syslog_conf" ]; then
            cat <<EOF > "$syslog_conf"
*.* @${SYSLOG_HOST:-$SERVER}
EOF
        fi
    fi
}

configure_fstab() {
    if [ -z "$CONFIGURE_FSTAB" ] || boolean_is_true "$CONFIGURE_FSTAB" ; then
        echo "/dev/root     /       unionfs defaults        0       0" > /etc/fstab
        echo "tmpfs         /tmp    tmpfs   defaults,nosuid,nodev 0 0" >> /etc/fstab
        mount /tmp
    fi

}

# muzso: preseed() has been modified to only collect commands in a variable
#        and does not pipe them instantly to debconf-communicate
#        We do this at the end in one batch.
preseed() {
    question="$1"
    value="$2"

    if [ -n "$value" ]; then
        [ -n "$debconf_commands" ] && debconf_commands="${debconf_commands}\n"
        debconf_commands="${debconf_commands}set $question $value"
        debconf_commands="${debconf_commands}\nfset $question seen true"
    fi
}

bind_mounts () {
    # set defaults
    test -z "$tmpfs_dir" && tmpfs_dir=/var/lib/ltsp-client-setup
    test -z "$rw_dirs" && rw_dirs="/var/cache/man /var/lib/xkb /var/lock /var/run /var/log /var/spool /var/tmp /tmp /var/lib/discover"
    test -z "$copy_dirs" && copy_dirs=""
    test -z "$temp_copy_dirs" && temp_copy_dirs="/var/cache/debconf"
    test -z "$bindfiles" && bindfiles="/etc/X11/xorg.conf /etc/X11/XF86Config-4"
    mount -t tmpfs -o mode=0755 tmpfs $tmpfs_dir
    # preserve directory structure
    for d in $rw_dirs ; do
        if [ -d "$d" ]; then
            cd $tmpfs_dir
            tar --no-recursion -cpf - $(find $d -type d 2> /dev/null) 2> /dev/null | tar xpf -
            mount --bind $tmpfs_dir/$d $d
        else
            echo "WARNING: $d does not exist"
        fi
    done
    # copy contents into tmpfs
    for d in $copy_dirs $temp_copy_dirs; do
        if [ -d "$d" ]; then
            cd $tmpfs_dir
            tar -cpf - $d 2> /dev/null | tar xpf -
            mount --bind $tmpfs_dir/$d $d
        else
            echo "WARNING: $d does not exist"
        fi
    done
    # mount one file on top of another
    for f in $bindfiles ; do
        if [ -e "$f" ]; then
            mkdir -p "$(dirname $tmpfs_dir/$f)"
            cp $f $tmpfs_dir/$f
            mount --bind $tmpfs_dir/$f $f
        else
            echo "WARNING: $f does not exist"
        fi
    done
}

bind_unmounts() {
    for dir in $temp_copy_dirs; do
        umount $dir
        rm -rf $tmpfs_dir/${dir#/}
    done
}

run_rcfiles() {
    for rcfile in $(env | sort | awk -F= '$1 ~ /^RCFILE_/ { print $2 }'); do
        [ -x "$rcfile" ] && "$rcfile" $@
    done
}

case "$1" in
    start)
        log_begin_msg "Setting up LTSP client..."
        which usplash_write >/dev/null 2>/dev/null && \
            usplash_write "TIMEOUT 120" || true
        if [ -z "$root_write_method" ]; then
            touch / 2> /dev/null || root_write_method="bind_mounts"
        fi
        [ "$root_write_method" = "bind_mounts" ] && bind_mounts
        if [ -f "/etc/ltsp/getltscfg-cluster.conf" ]; then
            # Tell the control center that we are booting and get lts.conf
            eval $(getltscfg-cluster -a -l refresh) || true
        fi
        load_modules || true
        configure_nbd || true
        set_time || true
        configure_console || true
        configure_resolver || true
        configure_swap || true
        configure_syslog || true
        configure_fstab || true
        run_rcfiles || true
        configure_serial_mouse || true
        configure_localdev || true
        configure_printer || true
        [ "$root_write_method" = "bind_mounts" ] && bind_unmounts
        log_end_msg 0
        ;;
    stop)
        #   echo -n "Stopping $DESC: $NAME"
        #   d_stop
        #   echo "."
        ;;
    restart|force-reload)
        #
        #   If the "reload" option is implemented, move the "force-reload"
        #   option to the "reload" entry above. If not, "force-reload" is
        #   just the same as "restart".
        #
        echo -n "Restarting $DESC: $NAME"
        d_stop
        sleep 1
        d_start
        echo "."
        ;;
    *)
        echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
        exit 1
        ;;
esac

exit 0
