#!/bin/sh

# copyright 2009 Vagrant Cascadian <vagrant@freegeek.org>,
# 2010 Alkis Georgopoulos <alkisg@gmail.com>,
# 2011 Wim Muskee <wimmuskee@gmail.com>, distributed under the
# terms of the GNU General Public License version 2 or any later version.

# generic functions

usage() {
cat <<EOF
$0 [OPTION] command
  -a, --arch                Architecture of the chroot.  Default is arch of the host.
  -b, --base                Base of ltsp chroot.  Default is /opt/ltsp if unspecified.
  -c, --mount-package-cache Mount package cache dir from server.
  -d, --mount-dev           Mount /dev from server.
  -h, --help                This message.
  -m, --mount-all           Mount all server dirs mentioned in this message.
  -p, --mount-proc          Mount /proc from server.
  -r, --copy-resolv-conf    Copy /etc/resolv.conf from server.
EOF
}

analyze_command_line() {
    local done_opts

    while [ -z "$done_opts" ] ; do
        case "$1" in
            -a|--arch) ARCH=$(echo $2 | sed -e "s,',,g") ; shift 2 ;;
            -b|--base) BASE=$(echo $2 | sed -e "s,',,g") ; shift 2 ;;
            -c|--mount-package-cache) MOUNT_PACKAGE_CACHE=true ; shift 1 ;;
            -d|--mount-dev) MOUNT_DEV=true; shift 1 ;;
            -h|--help) usage ; exit 0 ;;
            -m|--mount-all) MOUNT_ALL=true; shift 1 ;;
            -p|--mount-proc) MOUNT_PROC=true; shift 1 ;;
            -r|--copy-resolv-conf) COPY_RESOLV_CONF=true; shift 1 ;;
            --) shift ; done_opts=true ;;
            *) die "$0: Internal error!" ;;
        esac
    done
    COMMAND="$@"
}

default_options() {
    if [ -n "$ROOT" ]; then
        # If $ROOT contains a terminating /, remove it
        ROOT=${ROOT%/}
        # Extract $BASE and $ARCH from $ROOT in case they're needed afterwards
        BASE=${ROOT%/*}
        ARCH=${ROOT##*/}
    else
        BASE=${BASE:-/opt/ltsp}
        # If $BASE contains a terminating /, remove it
        BASE=${BASE%/}
        if [ -z "$ARCH" ]; then
            # Prefer the chroot that corresponds to the server arch,
            # but if that doesn't exist, use the first one available.
            ARCH=$(detect_arch)

            if [ ! -d "$BASE/$ARCH" ]; then
                for dir in "$BASE"/*/; do
                    # If it's not "images" and it's not "*" because of no subdirs
                    if [ -n "${dir##*/images/}" ] && [ -d "$dir" ]; then
                        # Keep only the subdir name
                        ARCH=${dir%/}
                        ARCH=${ARCH##*/}
                        break
                    fi
                done
            fi
        fi
        ROOT="$BASE/$ARCH"
    fi
}

pre_chroot() {
    test -d "$ROOT" || die "ERROR: ltsp chroot not found: $ROOT"

    if boolean_is_true "$MOUNT_ALL"; then
        MOUNT_PACKAGE_CACHE=true
        MOUNT_DEV=true
        MOUNT_PROC=true
    fi
    if boolean_is_true "$MOUNT_PACKAGE_CACHE"; then
        mount_package_cache
    fi
    if boolean_is_true "$MOUNT_DEV"; then
        mark_mount --bind "/dev" "$ROOT/dev"
        mark_mount -t devpts -o rw,noexec,nosuid,gid=5,mode=620 devpts "$ROOT/dev/pts"
    fi
    if boolean_is_true "$MOUNT_PROC"; then
        mark_mount -t proc proc "$ROOT/proc"
    fi
    if boolean_is_true "$COPY_RESOLV_CONF"; then
        cp /etc/resolv.conf "$ROOT/etc/"
    fi
}

post_chroot() {
    # Stop trapping
    trap - 0 HUP INT QUIT KILL SEGV PIPE TERM
    umount_marked
}

# distro specific functions
mount_package_cache() {
    echo "Mounting the package cache is not available for your distribution."
}

# Main

# Parse command line arguments
if ! ARGS=$(getopt -n "$0" -o +a:b:cdhmpr -l \
    'arch:,base:,mount-package-cache,mount-dev,help,mount-all,mount-proc,copy-resolv-conf' -- "$@"); then
    exit 1
fi

# Source the ltsp server functions
. /usr/share/ltsp/ltsp-server-functions

# First, include the configuration file, if it exists
if [ -f /etc/ltsp/ltsp-chroot.conf ]; then
    . /etc/ltsp/ltsp-chroot.conf
fi

# The command line parameters override the configuration file settings
analyze_command_line $ARGS

# Finally, fall back to using default values for any unset options
default_options

require_root

trap "post_chroot" 0 HUP INT QUIT KILL SEGV PIPE TERM
pre_chroot
eval LTSP_HANDLE_DAEMONS=false chroot "$ROOT" $COMMAND
