#!/bin/sh
# Copyright © 2005-2009  Roger Leigh <rleigh@debian.org>
# Copyright © 2009       Jan-Marek Glogowski <glogow@fbihome.de>
#
# schroot is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# schroot is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see
# <http://www.gnu.org/licenses/>.
#
#####################################################################

set -e

if [ -f "$CHROOT_SCRIPT_CONFIG" ]; then
    . "$CHROOT_SCRIPT_CONFIG"
elif [ "$2" = "ok" ]; then
    echo "script-config file '$CHROOT_SCRIPT_CONFIG' does not exist"
    exit 1
fi

# Mount a filesystem
# $1: mount options
# $2: mount device
# $3: mount location
do_mount()
{
    if [ "$AUTH_VERBOSITY" = "verbose" ]; then
	echo "Mounting $2 on $3"
    fi

    if [ ! -d "$3" ]; then
	mkdir -p "$3"
    fi
    if [ ! -d "$3" ]; then
	echo "$3 does not exist, and could not be created"
	exit 1
    fi

    mount $VERBOSE $1 "$2" "$3"
}

# Unmount all filesystems under specified location
# $1: mount base location
do_umount_all()
{
    if [ -d "$1" ]; then
	mounts="$("$LIBEXEC_DIR/schroot-listmounts" -m "$1")"
	if [ "x$mounts" != 'x' ]; then
            echo "$mounts" |
            while read mountloc; do
		if [ "$AUTH_VERBOSITY" = "verbose" ]; then
                    echo "Unmounting $mountloc"
		fi
		umount "$mountloc" || exit 1
            done || exit 1
	fi
    fi
}

# Mount a filesystem union
# $1: the mount location
do_mount_fs_union()
{
    # Prepare mount options (branch config) for union type
    if [ -z "$CHROOT_UNION_MOUNT_OPTIONS" ]; then
	case $CHROOT_UNION_TYPE in
	    unionfs)
		CHROOT_UNION_MOUNT_OPTIONS="dirs=${CHROOT_UNION_OVERLAY_DIRECTORY}=rw,${CHROOT_UNION_UNDERLAY_DIRECTORY}=ro"
		;;
	    aufs)
		CHROOT_UNION_MOUNT_OPTIONS="br:${CHROOT_UNION_OVERLAY_DIRECTORY}:${CHROOT_UNION_UNDERLAY_DIRECTORY}=ro"
		;;
	esac
    fi

    if [ "$AUTH_VERBOSITY" = "verbose" ]; then
	echo "Using '$CHROOT_UNION_TYPE' for filesystem union"
    fi

    # Try mounting fs
    mount -t "$CHROOT_UNION_TYPE" -o "$CHROOT_UNION_MOUNT_OPTIONS" "$CHROOT_NAME" "$1"
}

if [ "$AUTH_VERBOSITY" = "verbose" ]; then
    VERBOSE="-v"
#  FSCK_VERBOSE="-V"
fi

if [ "$CHROOT_TYPE" = "directory" ] || [ "$CHROOT_TYPE" = "file" ] || [ "$CHROOT_TYPE" = "file" ] || [ "$CHROOT_TYPE" = "loopback" ] || [ "$CHROOT_TYPE" = "block-device" ] || [ "$CHROOT_TYPE" = "lvm-snapshot" ]; then

    if [ "${CHROOT_UNION_TYPE:-none}" != "none" ]; then
	CREATE_UNION="yes"
    else
	CREATE_UNION="no"
    fi

    if [ "$CHROOT_TYPE" = "directory" ]; then
	CHROOT_MOUNT_OPTIONS="--bind"
	CHROOT_MOUNT_DEVICE="$CHROOT_DIRECTORY"
    elif [ "$CHROOT_TYPE" = "file" ]; then
	UNPACK_LOCATION="${UNPACK_DIR}/${SESSION_ID}"
	CHROOT_MOUNT_OPTIONS="--bind"
	CHROOT_MOUNT_DEVICE="${CHROOT_FILE_UNPACK_DIR}/${SESSION_ID}"

    elif [ "$CHROOT_TYPE" = "loopback" ]; then
	LOOP_DEVICE="$(/sbin/losetup -j "$CHROOT_FILE" | sed -e 's/:.*$//')"
	if [ -z "$LOOP_DEVICE" ]; then
	    CHROOT_MOUNT_DEVICE="$CHROOT_FILE"
	    CHROOT_MOUNT_OPTIONS="${CHROOT_MOUNT_OPTIONS},loop"
	else
	    CHROOT_MOUNT_DEVICE="$LOOP_DEVICE"
	    CHROOT_MOUNT_OPTIONS=""
	fi
    fi

    if [ $1 = "setup-start" ] || [ $1 = "setup-recover" ]; then

        # fsck doesn't like being run non-interactively
	#/sbin/fsck $FSCK_VERBOSE -n "$CHROOT_MOUNT_DEVICE"

        if [ ! -d "$CHROOT_MOUNT_LOCATION" ]; then
	    mkdir -p "$CHROOT_MOUNT_LOCATION"
        fi
	if [ ! -d "$CHROOT_MOUNT_LOCATION" ]; then
	    echo "$CHROOT_MOUNT_LOCATION does not exist, and could not be created"
	    exit 1
	fi

	# If recovering, we want to remount all filesystems to ensure
	# a sane state.
	if [ $1 = "setup-recover" ]; then
	    if [ "$CREATE_UNION" = "yes" ]; then
		do_umount_all "$CHROOT_UNION_UNDERLAY_DIRECTORY"
	    fi
	    do_umount_all "$CHROOT_MOUNT_LOCATION"
	fi

	if [ "$CREATE_UNION" = "yes" ]; then
	    do_mount "$CHROOT_MOUNT_OPTIONS" "$CHROOT_MOUNT_DEVICE" "$CHROOT_UNION_UNDERLAY_DIRECTORY"
	    do_mount_fs_union "$CHROOT_MOUNT_LOCATION"
	else
	    do_mount "$CHROOT_MOUNT_OPTIONS" "$CHROOT_MOUNT_DEVICE" "$CHROOT_MOUNT_LOCATION"
	fi

	if [ -n "$FSTAB" ]; then
	    if [ -f "$FSTAB" ]; then
		"$LIBEXEC_DIR/schroot-mount" $VERBOSE \
		    -f "$FSTAB" -m "$CHROOT_PATH"
	    else
		echo "fstab file '$FSTAB' does not exist"
		exit 1
	    fi
	fi

    elif [ $1 = "setup-stop" ]; then

	do_umount_all "$CHROOT_MOUNT_LOCATION"
	if [ "$CREATE_UNION" = "yes" ]; then
	    do_umount_all "$CHROOT_UNION_UNDERLAY_DIRECTORY"
	fi

	# Purge mount location.
	# The contents of file chroots are purged separately, because
	# we might want to repack the contents.
	if [ "$CHROOT_TYPE" != "file" ]; then
	    if echo "$CHROOT_MOUNT_LOCATION" | grep -q "^$MOUNT_DIR/"; then
		if [ -d "$CHROOT_MOUNT_LOCATION" ]; then
		    rmdir "$CHROOT_MOUNT_LOCATION"
		fi
	    fi
	fi

    fi

fi

