#!/bin/bash
###########

do_usage() {
	echo "Usage: $0 [NAME]"
	echo
	echo "Where NAME is the name of the Linux-VServer"
	echo " More info on the directory layout can be found at the 'flower page'"
	echo " http://www.nongnu.org/util-vserver/doc/conf/configuration.html"
}




do_parsecfg() {
	echo -n "Parsing old configfile"
	# Obtain all settings from the Linux-VServer using old configfile
	source /etc/vservers/${VSNAME}.conf
	echo " [DONE]"
	echo
}


do_parsesh() {
	echo -n "Parsing old shellscript: "
	TYPE=0
	SKIP=0

	if [ -f ${VSBDIR}/scripts/generic.sh ]; then
		rm ${VSBDIR}/scripts/generic.sh
	fi

	echo "#!/bin/bash" > ${VSBDIR}/scripts/pre-start
	echo "source ${VSBDIR}/scripts/generic.sh" >> ${VSBDIR}/scripts/pre-start
	echo >> ${VSBDIR}/scripts/pre-start
       
	echo "#!/bin/bash" > ${VSBDIR}/scripts/post-start
	echo "source ${VSBDIR}/scripts/generic.sh" >> ${VSBDIR}/scripts/post-start
	echo >> ${VSBDIR}/scripts/post-start
	
	echo "#!/bin/bash" > ${VSBDIR}/scripts/pre-stop
	echo "source ${VSBDIR}/scripts/generic.sh" >> ${VSBDIR}/scripts/pre-stop
	echo >> ${VSBDIR}/scripts/pre-stop

	echo "#!/bin/bash" > ${VSBDIR}/scripts/post-stop
	echo "source ${VSBDIR}/scripts/generic.sh" >> ${VSBDIR}/scripts/post-stop
	echo >> ${VSBDIR}/scripts/post-stop

	while read SHELLSCRIPT ; do
		case $SHELLSCRIPT in
			pre-sta*)
				echo -n " pre-start"
				TYPE=1
				SKIP=1
				;;
			post-sta*)
				echo -n " post-start"
				TYPE=2
				SKIP=1
				;;
			pre-sto*)
				echo -n " pre-stop"
				TYPE=3
				SKIP=1
				;;
			post-sto*)
				echo -n " post-stop"
				TYPE=4
				SKIP=1
				;;
			"case $1 in")
				SKIP=1
				;;
			"esac")
				SKIP=1
				;;
			";;")
				SKIP=1
				;;
		esac

		if [ "${SKIP}" != "1" ]; then
			case $TYPE in
				0)
					echo $SHELLSCRIPT >> ${VSBDIR}/scripts/generic.sh
					;;
				1)
					echo $SHELLSCRIPT >> ${VSBDIR}/scripts/pre-start
					;;
				2)
					echo $SHELLSCRIPT >> ${VSBDIR}/scripts/post-start
					;;
				3)
					echo $SHELLSCRIPT >> ${VSBDIR}/scripts/pre-stop
					;;
				4)
					echo $SHELLSCRIPT >> ${VSBDIR}/scripts/post-stop
					;;
			esac
		else
			SKIP=0
		fi
	done < /etc/vservers/$VSNAME.sh
	echo " [DONE]"
	echo
}


do_gencfgdir() {
	echo "Creating new configdirectory"
	# Create new vserver configuration directories
	# and create some sane defaults
	# - like `vserver [NAME] build -m skeleton` would do
	mkdir -p ${VSBDIR}/apps/init
	mkdir -p ${VSBDIR}/interfaces/0/
	mkdir -p ${VSBDIR}/uts
	mkdir -p ${VSBDIR}/scripts
	
	ln -s /var/run/vservers/${VSNAME} ${VSBDIR}/run
	ln -s /etc/vservers/.defaults/run.rev ${VSBDIR}/run.rev
	ln -s /etc/vservers/.defaults/vdirbase/${VSNAME} ${VSBDIR}/vdir

	#
	# Create the new configuration based on the [NAME].conf file
	# 

	# Fill the System capabilities file (2.6 kernel)
	echo -n " * Setting Bcapabilities:"
	if [ -f ${VSBDIR}/bcapabilities ]; then
		rm -f ${VSBDIR}/bcapabilities
	fi
	for CAPA in ${S_CAPS}; do
		echo -n " ${CAPA}"
		echo "${CAPA}" >> ${VSBDIR}/bcapabilities
	done
	echo " [OK]"
	
	# Fill the System capabilities file (2.4 kernel)
#	echo -n " * Setting capabilities:"
#	if [ -f ${VSBDIR}/capabilities ]; then
#		rm -f ${VSBDIR}/capabilities
#	fi
#	for CAPA in ${S_CAPS}; do
#		echo -n " ${CAPA}"
#		echo "${CAPA}" >> ${VSBDIR}/capabilities
#	done
#	echo " [OK]"

	# Fill the Context capabilities file
#	echo -n " * Setting Ccapabilities:"
#	if [ -f ${VSBDIR}/ccapabilities ]; then
#		rm -f ${VSBDIR}/ccapabilities
#	fi
#	for CAPA in ${S_CAPS}; do
#		echo -n " ${CAPA}"
#		echo "${CAPA}" >> ${VSBDIR}/ccapabilities
#	done
#	echo " [OK]"

	# Set the flags for this Linux-VServer
	echo -n " * Setting flags:"
	if [ -f ${VSBDIR}/flags ]; then
		rm -f ${VSBDIR}/flags
	fi
	if [ "${S_FLAGS}" == "" ]; then
		S_FLAGS="lock nproc"
	fi
	
	for FLAG in ${S_FLAGS}; do
		echo -n " ${FLAG}"
		echo "${FLAG}" >> ${VSBDIR}/flags
	done
	echo " [OK]"

	# Setup the fstab file (Using sane defaults)
	# - There was no way to specify this in the
	#   old style config file
	echo -n " * Setting the fstab(s):"
	echo "none	/proc		proc	defaults		0 0" > ${VSBDIR}/fstab
	echo "none	/dev/pts	devpts	gid=5,mode=620		0 0" >> ${VSBDIR}/fstab
	echo "#none	/tmp		tmpfs	size=16m,mode=1777	0 0" >> ${VSBDIR}/fstab

	# Define, but don't use, a local fstab entry
#	echo "# The fstab file for the vserver." > ${VSBDIR}/fstab.local
#	echo "#" >> ${VSBDIR}/fstab.local
#	echo "# In opposite to the normal 'fstab' file, the mounting happens in the local network context." >> ${VSBDIR}/fstab.local
#	echo "# Currently there is no way to mix entries of both files; 'fstab' will be always processed" >> ${VSBDIR}/fstab.local
#	echo "# before 'fstab.local'." >> ${VSBDIR}/fstab.local
#	echo " [OK]"

	# Init based configuration
#	echo -n " * Setting the INIT configuration:"
#	if [ "${S_START}" != "" ]; then
#		echo "${S_START}" > ${VSBDIR}/apps/init/cmd.start
#	fi
#	if [ "${S_STOP}" != "" ]; then
#		echo "${S_STOP}" > ${VSBDIR}/apps/init/cmd.stop
#	fi
	if [ "`echo ${S_START} | grep default`" != "" ]; then
		echo "gentoo" > ${VSBDIR}/apps/init/style
	else
		echo "default" > ${VSBDIR}/apps/init/style
	fi
	echo " [OK]"
	
	# Set the vserver name / context
	echo -n " * Setting Linux VServer specifics (contextid, etc):"
	echo "${VSNAME}" > ${VSBDIR}/name
	echo "${S_CONTEXT}" > ${VSBDIR}/context

	# Change the `uname` output for the Linux-VServer
	echo "${S_HOSTNAME}" > ${VSBDIR}/uts/nodename
	echo "`uname -r | cut -d - -f 1`" > ${VSBDIR}/uts/release
	echo " [OK]"

	# IP Configuration
	echo " * Setting up network configuration..."
	NETID=0
	for VSNET in ${IPROOT}; do
		echo "  - Interface ${NETID} -"
		VSNETDEV="`echo ${IPROOT} | cut -d : -f 1`"
		VSNETADDR="`echo ${IPROOT} | cut -d : -f 2 | cut -d / -f 1`"
		VSNETMASK="`echo ${IPROOT} | cut -d : -f 2 | cut -d / -f 2`"
		mkdir -p ${VSBDIR}/interfaces/${NETID}/

		if [ "${VSNETBCAST}" != "" ]; then
			echo "   Broadcast: ${VSNETBCAST}"
			echo "${VSNETBCAST}" > ${VSBDIR}/interfaces/${NETID}/bcast
		fi
		if [ "${VSNETDEV}" != "" ]; then
			echo "   Device: ${VSNETDEV}"
			echo "${VSNETDEV}" > ${VSBDIR}/interfaces/${NETID}/dev
		fi
#		touch ${VSBDIR}/interfaces/${NETID}/disabled
		if [ "${VSNETADDR}" != "" ]; then
			echo "   Address: ${VSNETADDR}"
			echo "${VSNETADDR}" > ${VSBDIR}/interfaces/${NETID}/ip
		fi
		if [ "${VSNETMASK}" != "" ]; then
			echo "   Netmask: ${VSNETMASK}"
			echo "${VSNETMASK}" > ${VSBDIR}/interfaces/${NETID}/mask
		fi
		echo "   Alias name: ${NETID}${VSNAME}"
		echo "${NETID}${VSNAME}" > ${VSBDIR}/interfaces/${NETID}/name
#		touch ${VSBDIR}/interfaces/${NETID}/nodev
#		echo "${IPROOTBCAST}" > ${VSBDIR}/interfaces/${NETID}/prefix
#		echo "${IPROOTBCAST}" > ${VSBDIR}/interfaces/${NETID}/scope
		let NETID++
	done
	echo 
}

do_updatevserver() {
	rm -rf /vservers/${VSNAME}/dev \
		/vservers/${VSNAME}/proc

	mkdir -p /vservers/${VSNAME}/proc
	mkdir -p /vservers/${VSNAME}/dev/pts

	mknod -m 666 /vservers/${VSNAME}/dev/full c 1 7
	mknod -m 666 /vservers/${VSNAME}/dev/null c 1 3
	mknod -m 666 /vservers/${VSNAME}/dev/ptmx c 5 2
	mknod -m 644 /vservers/${VSNAME}/dev/random c 1 8
	mknod -m 666 /vservers/${VSNAME}/dev/tty c 5 0
	mknod -m 644 /vservers/${VSNAME}/dev/urandom c 1 9
	mknod -m 666 /vservers/${VSNAME}/dev/zero c 1 5
}


### Main
if [ "$1" == "" ]; then
  do_usage
  exit 1
fi

### Settings
VSNAME=$1
VSBDIR=/etc/vservers/${VSNAME}

### Clean up if wanted
if [ "$2" == "-f" -a -d ${VSBDIR} ]; then
	echo -n "Forcing removal of previous configuration directory: ${VSBDIR}"
	rm -rf ${VSBDIR}
	echo " [DONE]"
	echo
fi

if [ -f /etc/vservers/${VSNAME}.conf -a -d /vservers/${VSNAME} ]; then
	do_parsecfg	;# Read the [NAME].conf file
	do_gencfgdir	;# Convert the [NAME].conf file
	do_parsesh	;# Convert the [NAME].sh file
	do_updatevserver;# Convert proc/dev tree
else
	echo "VServer configuration not found!"
	exit 1
fi

