#!/bin/bash
# mychroot - Copyright 2006 JeR

# Usage: mychroot [PATH]
# Chroots into PATH or else into the current working directory
# Files: ${HOME}/.mychroot, containing a list of names of directories
# under / that you want to bind in the chroot target.
# If any of these is already bound under the chroot target, it is not
# mounted again and the script remembers to leave it mounted when it quits.

# = Program Configuration =

progname="$(basename ${0})"
configfile="${HOME}/.${progname}"


# = Functions =

einfo() {
	echo "${progname}: ${*}"
}

ismounted() {
	mount | grep -q ${1}
}

domount() {
	einfo "  Mounting ${chroot}/${1}:"
	mount -v --bind /${1} ${chroot}/${1}
}

doumount() {
	einfo "  Unmounting ${chroot}/${1}"
	umount -vlf ${chroot}/${1}
}


# = Chroot Configuration =

if test -f "${configfile}"; then
	chrootdirs="$(cat "${configfile}")"
	einfo "Using ${configfile} to bind: ${chrootdirs}"
fi
if test -z "${chrootdirs}"; then
	chrootdirs="proc dev sys"
	einfo "${configfile} not found"
	einfo "Defaulting to binding: ${chrootdirs}"
fi

oldpath="${PWD}"
chroot="$(readlink -f "${1}")"
test -n "${chroot}" || chroot="${oldpath}"
imounted=""


# = Main =

if test -d ${chroot}; then
	cd ${chroot} && chroot="${PWD}" 

	for i in ${chrootdirs}; do
		if ismounted ${chroot}/${i}; then
			einfo "  /${i} already mounted"
		else
			domount ${i}
			imounted="${imounted} ${i}"
		fi
	done

	einfo "Chrooting to ${chroot}"
	chroot ${chroot} /bin/bash

	if test -z "${imounted}"; then
		einfo "Not unmounting filesystems"
	else
		einfo "Unmounting filesystems: ${imounted}"
		for i in ${imounted}; do
			doumount ${i}
		done
	fi

	cd "${oldpath}"
fi


# = Closing time =

unset chroot oldpath imounted chrootdirs progname configfile
