#!/bin/sh

VSYSROOT=/OS


function create_vsys()
{
	sys="$1"

	# Create the virtual system directory and mount point
	mkdir -p "$VSYSROOT/$sys/..." > /dev/null 2>&1

	# Move to the virtual system directory
	cd "$VSYSROOT/$sys"

	# Mount the remote filesystem tree.
	showmount --no-headers -e "$sys" | while read fs
	do
		set -- $fs
		mount "$sys:$1" "...$1"
	done

	# Map names from the mount point to the virtual system directory.
	for i in .../*
	do
		# Don't map ..., tmp, dev or usr
		if [ "$i" = ".../..." -o "$i" = ".../tmp" -o "$i" = ".../dev" -o "$i" = ".../usr" ]; then
			continue
		else
			rm -f `basename "$i"`
			ln -s "$i" `basename "$i"`
		fi
	done

	# Map /usr too. We have to do this since /usr/tmp needs to be local.
	rm -f usr > /dev/null 2>&1
	mkdir usr > /dev/null 2>&1
	cd usr
	for i in ../.../usr/*
	do
		# Don't map tmp
		if [ "$i" = "../.../usr/tmp" ]; then
			continue
		else
			rm -f `basename "$i"`
			ln -s "$i" `basename "$i"`
		fi
	done
	cd ..

	# Make the local directories
	rm -f dev > /dev/null 2>&1
	mkdir tmp usr/tmp dev > /dev/null 2>&1
	chmod a=rwx,+t tmp usr/tmp
	cp -dpR /dev . > /dev/null 2>&1

	# And connect the access program for the virtual system
	cd $VSYSROOT/bin
	ln -sf bin "$sys"
}


function destroy_vsys()
{
	vsys="$1"

	# If it's a symlink just get rid of it and the associated program.
	if [ -L "$VSYSROOT/$vsys" ]; then
		rm -f $VSYSROOT/$vsys
		rm -f $VSYSROOT/bin/$vsys
	fi

	# If it isn't a directory or it hasn't got a ... subdirectory
	# it isn't a virtual system.
	if [ ! -d "$VSYSROOT/$vsys" -o ! -d "$VSYSROOT/$vsys/..." ]; then
		echo "$vsys is not a virtual system"
		exit 1
	fi

	# Unmount anything mounted for this virtual system.
	awk '{ print $2 }' /etc/mtab | grep "^$VSYSROOT/$vsys/..." | sort -r | while read fs
	do
		umount "$fs"
	done

	# Remove the virtual system tree. Avoid removing anything below
	# anything starting with . (specifically ... in case anything
	# has failed to unmount - we don't symlink dor files in the
	# root directory anyway).
	rm -rf $VSYSROOT/$vsys/*
	rmdir $VSYSROOT/$vsys/...
	rmdir $VSYSROOT/$vsys

	# Remove the associated program.
	rm -f $VSYSROOT/bin/$vsys
}


function alias_vsys()
{
	alias="$1"
	vsys="$2"

	cd $VSYSROOT

	# If the alias already exists as a link get rid of it.
	if [ -L "$alias" ]; then
		rm -f "$alias"
	fi

	# If the alias already exists or the virtual system doesn't
	# exist we can't do this.
	if [ -e "$alias" ]; then
		echo "$alias already exists"
	elif [ ! -d "$vsys" -a ! -L "$vsys" ]; then
		echo "Virtual system $vsys does not exist"
	else
		ln -s "$vsys" "$alias"
		cd bin
		rm -f "$alias"
		ln bin "$alias"
	fi
}


function usage()
{
	echo "usage: mkvsys [ -r vsysroot ]      Set the vsys root (default /OS)"
	echo "              [ -a alias real ]    Add an alias for the given system"
	echo "              [ -c system ]        Create the specified virtual system"
	echo "              [ -d system ]        Destroy the specified virtual system or alias"
}


if [ $# -eq 0 ]; then
	usage
	exit 1
fi

while [ $# -gt 0 ]
do
	case "$1" in
		-r)
			if [ $# -eq 1 ]; then
				usage
				exit 1
			fi
			VSYSROOT="$2"
			shift ; shift
			;;

		-c)
			if [ $# -eq 1 ]; then
				usage
				exit 1
			fi
			create_vsys "$2"
			shift ; shift
			;;

		-d)
			if [ $# -eq 1 ]; then
				usage
				exit 1
			fi
			destroy_vsys "$2"
			shift ; shift
			;;

		-a)
			if [ $# -eq 1 ]; then
				usage
				exit 1
			fi
			alias_vsys "$2" "$3"
			shift ; shift ; shift
			;;

		*)
			usage
			exit 1
			;;
	esac
done
