#! /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/lib/ltsp/ltsp_config

boolean_is_true(){
    case "$(echo $1 | tr 'A-Z' 'a-z')" in
       true|y|yes) return 0 ;; 
       *) return 1 ;; 
    esac
}

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_localdev() {
    boolean_is_true "$LOCALDEV" && mkdir /var/run/drives
}

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

configure_swap() {
    if boolean_is_true "$USE_LOCAL_SWAP" ; then
        # Enable local swap partition if found on local disk
        for part in `sfdisk -l 2>/dev/null | awk '/ 82 / { print $1}'`; do
            swap_devices="$swap_devices $part"
        done
    fi

    if boolean_is_true "$NBD_SWAP" ; then
        SWAP_SERVER=${SWAP_SERVER:-"$SERVER"}
        NBD_PORT=${NBD_PORT:-"9210"}
        modprobe nbd
        nbd-client $SWAP_SERVER $NBD_PORT /dev/nbd0 && \
            swap_devices="$swap_devices /dev/nbd0"
    fi

    if boolean_is_true "$ENCRYPT_SWAP" ; then
        if [ -x /sbin/cryptsetup ]; then
            modprobe dm_crypt
        else
            echo "ERROR: ENCRYPT_SWAP=Y, but /sbin/cryptsetup not found. disabling swap."
            swap_devices=""
        fi
    fi

    num=0
    for device in $swap_devices ; do
        swap="$device"
        if boolean_is_true "$ENCRYPT_SWAP" ; then
            if [ -x /sbin/cryptsetup ]; then
                cryptsetup -d /dev/urandom create swap$num $swap && swap="/dev/mapper/swap$num"
                num=$(($num+1))
            fi
        fi
        mkswap $swap
        swapon $swap
    done
}

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_printer() {
    for I in 0 1 2; do
        eval DEVICE=\$\{PRINTER_${I}_DEVICE\}
        [ -n "${DEVICE}" ] && \
            eval PORT=\$\{PRINTER_${I}_PORT:="910${I}"\} && \
            /usr/sbin/jetpipe ${DEVICE} ${PORT}
    done
}

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

configure_fstab() {
    echo "/dev/root     /       unionfs defaults        0       0" > /etc/fstab
    echo "tmpfs         /tmp    tmpfs   defaults,nosuid,nodev 0 0" >> /etc/fstab
    mount /tmp
}

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

configure_x() {
    # If the user has specified an xorg.conf file, then copy it over.
    xserver_config="/etc/X11/xorg.conf"
    [ -n "$X_CONF" ] && [ -f "$X_CONF" ] && \
        cp "$X_CONF" "$xserver_config"
}

configure_serial_mouse() {
      if [ -n "$X_MOUSE_DEVICE" ] && \
          [ -n "$X_MOUSE_PROTOCOL" ] && \
          type inputattach >/dev/null 2>/dev/null && \
          [ -n "$(echo $X_MOUSE_DEVICE | awk '/\/dev\/ttyS[0-9]/')" ]; then
          inputattach --"$X_MOUSE_PROTOCOL" "$X_MOUSE_DEVICE" &
      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..."
	    type 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
        load_modules || true
        configure_console || true
        configure_resolver || true
        configure_swap || true
        configure_syslog || true
        configure_fstab || true
        run_rcfiles || true
        configure_x || 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
