#!/bin/bash
set -o errexit

# 
# CONFIG
###############
UML_PROFILE=
UML_WHICH=

while [[ $1 ]] ; do
	if [[ $1 == uml-[12] ]] ; then
		UML_WHICH=$1 ; shift
	else
		UML_PROFILE=$1 ; shift
	fi
done

[[ $UML_WHICH ]] || {
	echo "Usage: $0 [uml-config-file] uml-[12]"
	exit 1
}

if [[ -z $UML_PROFILE && -e uml_profile-$USER@$HOSTNAME ]] ; then
	UML_PROFILE=uml_profile-$USER@$HOSTNAME
fi

[[ $UML_PROFILE && -e $UML_PROFILE ]] || {
	echo "Usage: $0 [uml-config-file] uml-[12]"
	exit 1
} 

source $UML_PROFILE

######################
PATH=/sbin/:/usr/sbin:$PATH:/usr/lib/uml

# preconfigure persistent tap devices
if ! ifconfig | grep -q ^tap0 ; then
	sudo tunctl -u $USER -t tap0
	sudo ifconfig tap0 $TAP0 up
fi

if ! ifconfig | grep -q ^tap1 ; then
	sudo tunctl -u $USER -t tap1
	sudo ifconfig tap1 $TAP1 up
fi
# and let the uml_switch deamons run in the background forever...
# use -hub if you want to be able to tcpdump on the host.
# uml_switch -hub -tap tap0 -unix /tmp/uml0.ctl
# uml_switch -hub -tap tap1 -unix /tmp/uml1.ctl
if ! ps x | grep -v grep | grep -q "uml_switch.* /tmp/uml0.ctl" ; then
	uml_switch -tap tap0 -unix /tmp/uml0.ctl </dev/null &> /dev/null &
fi
if ! ps x | grep -v grep | grep -q "uml_switch.* /tmp/uml1.ctl" ; then
	uml_switch -tap tap1 -unix /tmp/uml1.ctl </dev/null &> /dev/null &
fi

#
# now, start both umls.
#

# this starts a SCREEN and an xterm attached to that screen.
start_uml() {
	local XPID SPID STY UMLPID LOGDIR COMMAND NAME=$1 EXTRA_ARG=$2
	local fg bg ubd0

	ubd0=UBDs_$i; ubd0=${!ubd0}; ubd0=${ubd0#*ubd0=}; ubd0=${ubd0%% *}

	fuser -v ${ubd0:-~/.uml/$NAME/mconsole} && {
		echo >&2 "$NAME seems to be still running, stop it first!"
		return 1
	}

	LOGDIR="/tmp/$(date +%Ft%H%M).$NAME"
	mkdir -p "$LOGDIR"
	cd "$LOGDIR"
	echo "LOGDIR=$LOGDIR"

	COMMAND="sleep 1; screen -t \"console ($NAME)\" $LINUX $CMDLINE umid=$NAME $EXTRA_ARG
		echo 'waiting for uml to come up, then attaching gdb and mconsole...'

		sleep 2
		screen -X caption always
		screen -X bindkey -k k1 select 4 # F1 -> vc/1
		screen -X bindkey -k k2 select 5 # F2 -> vc/2
		screen -X bindkey -k k3 select 1 # F3 -> console
		screen -X bindkey -k k4 select 0 # F4 -> gdb
		screen -X bindkey -k k5 select 2 # F5 -> mconsole
		screen -X bindkey -k k6 select 3 # F6 -> console log

		screen -t '$NAME mconsole' uml_mconsole $NAME
		screen -t 'less +F $NAME console' -- less +F screenlog.1
		screen -X title gdb; exec gdb $LINUX \$(<~/.uml/$NAME/pid)"
	echo "LINUX: $LINUX $CMDLINE umid=$NAME $EXTRA_ARG"
	screen -fn -e ^^^^ -S "$NAME" -L -m -D -t $NAME -- bash -c "$COMMAND" &
	SPID=$!
	
	export STY="$SPID.$NAME"

	(
		sleep 4
		if UMLPID=$(< ~/.uml/$NAME/pid); then
			screen -X register g "\
handle SIGSEGV pass nostop noprint
handle SIGUSR1 pass nostop noprint
continue
"
			screen -X -p gdb paste g
			#(
			#	# when this uml has died, there is no more mconsole.
			#	# reap gdb again.
			#	while test -e ~/.uml/$NAME/mconsole ; do sleep 5 ; done 
			#	screen -X register g $'quit\n'
			#       	screen -X -p 0 paste g  # quit gdb
			#	screen -X -p 2 paste g  # quit mconsole
			#) &
			screen -X "select" 1		# switch to console
			# wait for vc/2 to show up
			i=true
			while [[ -e ~/.uml/$NAME/pid ]] ; do
				[[ -e screenlog.5 ]] && break
				[[ -e screenlog.4 ]] && $i &&
					i=false && screen -X "select" 1
				[[ $SECONDS -ge 30 ]] && break
				sleep 1
			done
			screen -X "select" 1
			# screen -X detach
		else
			screen -X register g $'quit\n'
			screen -X -p 0 paste g  # quit gdb
			screen -X -p 2 paste g  # quit mconsole
		fi
	) &

	sleep 1
	screen -r "$SPID.$NAME" -p =

	#i=${NAME##*[^0-9]}
	#[[ $i == 1 ]] && fg=white  bg=black \
	#	      || fg=yellow bg=darkblue
	#xterm -fg $fg -bg $bg -geom 132x30 -T "$NAME" \
	#	-e screen -r "$SPID.$NAME" -p = \
	#	</dev/null >/dev/null 2>&1 &
}


# it could be fun to have one outer screen session,
# which has two windows with the inner (uml virtual console and gdb)
# screen sessions ... outer and inner screen escape should be different,
# of course, and some convenience key bindings to switch to the desired
# consoles should be done...
#
# for now, just start one screen for each uml, and detach.
# where you reattach, thats your business!
#

# in case this runs within konsole or xterm: set tab and window title
# konsole tab title:
echo -n $'\e]30;'$UML_WHICH$'\a'
# window title
echo -n $'\e]0;'$UML_WHICH$'\a'

i=${UML_WHICH##*[^0-9]}
uml_params=UMLPARAMs_$i
screen -r -D uml-$i || start_uml uml-$i "${!uml_params}" || screen -ls
