~pixelherodev/ANTS

bb32d750771e4e5a2c79639d0dda0bb209cad0af — Noam Preil 1 year, 1 day ago d253771
bootrc: replace with ANTS plan9rc
1 files changed, 713 insertions(+), 215 deletions(-)

M sys/src/9/boot/bootrc
M sys/src/9/boot/bootrc => sys/src/9/boot/bootrc +713 -215
@@ 4,26 4,6 @@ if(~ $#rootdir 0)
	rootdir=/root
objtype=`{cat /env/cputype}

# mount points
mntgen -s slashn /n && chmod 666 /srv/slashn
mntgen -s slashmnt /mnt && chmod 666 /srv/slashmnt
mntgen -s mntexport /mnt/exportfs && chmod 666 /srv/mntexport

bind /root /mnt/broot
unmount /root

bind -q '#σ' /shr
bind -q '#d' /fd
bind -q '#p' /proc
for(i in ¶ P S f æ t b m)
	bind -qa '#'^$i /dev

# bind in an ip interface
for(i in I l^(0 1 2 3))
	bind -qa '#'$i /net

# usually better than 1970
cat '#r/rtc' >/dev/time >[2]/dev/null

# reparse variables
for(i in `{ls -Qp /env}){


@@ 34,59 14,104 @@ for(i in `{ls -Qp /env}){
		$i=`{echo $$i}
	}
}
# utility functions

fn sigint {
	status=interrupted
fn sigint{
	echo interrupt received
}

fn fatal {
	echo $* >[1=2]
	exit $"*
fn shifter{
	shift
	echo $*
}

fn must {
	$* || fatal $"*^': '^$status
}

fn ask {
	echo -n $1
	echo -n $2
	if(! ~ $#3 0){
		echo -n '['
		echo -n $3
		echo -n '] '
	}
	$1=`{dd -bs 64 -count 1 >[2]/dev/null}
	if(~ $#$1 0)
		$1=$3
	if(~ $"$1 '!rc'){
fn getans{
	query=$1
	value=`{shifter $*}
	echo '* '$"query' = '$"value' : accept, new value, '''clear'''', or '''rc'''
	answer=`{dd -bs 128 -count 1 >[2]/dev/null}
	switch($answer){
	case rc
		rc -i
		$1=()
		getans $query $value
	case clear
		$query = ''
	case ?*
		$query = $answer
	case ''
		$query = $value
	}
	if(~ $#$1 0)
		ask $*
}

fn cleanenv {
	rm /env/bootargs
	rm /env/bootcmd
	rm /env/bootparse
	rm /env/bootpartition
	rm /env/cpuport
	rm /env/factotum
	rm /env/factotumopts
	rm '/env/fn#doafterfact'
	rm '/env/fn#doafterroot'
	rm '/env/fn#dochecksys'
	rm '/env/fn#dofactotum'
	rm '/env/fn#dogetrootfs'
	rm '/env/fn#doinitscript'
	rm '/env/fn#doramsetup'
	rm '/env/fn#dostartventi'
	rm '/env/fn#dotryusb'
	rm '/env/fn#findpart'
	rm '/env/fn#getans'
	rm '/env/fn#hostcheck'
	rm '/env/fn#ipsetup'
	rm '/env/fn#shifter'
	rm /env/getrootfs
	rm /env/hostdir
	rm /env/hosttest
	rm /env/initscript
	rm /env/interactive
	rm /env/ipdone
	rm /env/ramsetup
	rm /env/startventi
	rm /env/systest
	rm /env/tgzfs
	rm /env/usercheck
	rm /env/localventi
	rm /env/venticonf
	rm /env/ventilisten
	rm /env/ventiparse
	rm /env/vhttplisten
	rm /env/cleanenv
}

# environment checking functions

fn findpart{
	if(~ $bootparse(1) *dev*)
		echo $bootparse(1) |sed 's/^local!//'
	if not
		echo $bootparse(1) |sed 's/^local!#./\/dev/'
}

fn hostcheck{
	hosttest=`{cat /dev/hostowner}
	if(~ $hosttest ''){
		if(~ $user ''){
	if(~ $#hosttest 0){
		if(~ $#user 0){
			user=glenda
		}
		echo 'no hostowner found: setting to '$user
		echo -n $user >'/dev/hostowner'
	}
	if(~ $user ''){
	if(~ $#user 0)
		user=`{cat /dev/hostowner}
	}
}

fn dochecksys{
	systest=`{cat /dev/sysname}
	switch($sysname){
	case ?*
		if(~ $systest ''){
			echo setting /dev/sysname to $sysname
		if(~ $#systest 0){
#			echo setting /dev/sysname to $sysname
			echo -n $sysname >/dev/sysname
			systest=`{cat /dev/sysname}
		}


@@ 94,16 119,13 @@ fn dochecksys{
			echo warning sysname mismatch between dev and env
		}
	case ''
		if(~ $systest ''){
			if(~ $service cpu){
		if(~ $#systest 0){
			if(~ $service cpu)
				sysname=helix
			} 
			if(~ $service terminal){
				sysname=front
			}
			if(~ $sysname ''){
			if(~ $service terminal)
				sysname=gnot
			if(~ $#sysname 0)
				sysname=mutant
			}
			echo no sysname found in dev or env setting to $sysname
			echo -n $sysname >/dev/sysname
		}


@@ 114,70 136,127 @@ fn dochecksys{
	}
}

fn ants{
	paqfs -s -S frontpaq -c 128 /boot/bootfs.paq
	bind -a /boot /bin
	hostcheck
	dochecksys
	ipparams=`{echo $ipparams}

##	set up ramfs as a rootlike fs
	
	hostdir=`{cat '#c/hostowner'}
	cd /
	echo -n 'ramfs -S ramboot...'
	ramfs -S ramboot
	mount -c /srv/ramboot /root
	bind -ac /root /
	echo -n 'tar xf /lib/skel.tar...'
	tar xf /lib/skel.tar
	if (test -d /root/mnt)
		bind -ac /root/mnt /mnt
	mount -b /srv/factotum /mnt
	bind -ac /root/bin /bin

##	get tgzfs if chosen and load into the ramdisk

	if(~ $tgzfs '')
		tgzfs=tools.tgz
	if(~ $tgzfs no)
		tgzfs=''

	if(~ $tgzfs *.tgz){
		dossrv
		if(~ $fatpath '')
			fatpath=`{ls /dev/sd*/9fat}
		if(! test -d /x)
			mkdir /root/x
		mount /srv/dos /x $fatpath
		if(test -e /x/$tgzfs){
			echo -n tar xzf $tgzfs^...
			tar xzf /x/$tgzfs
fn showlocaldev {
	echo $1'	' $2
	if(~ $#bootargs 0){
		if(! ~ $#cdboot 0){
			if(~ $2 9660)
				bootargs=local!$1
		}
		if not {
			if(! ~ $2 '' dos)
				bootargs=local!$1
		}
		if not
			echo 'tgz not found continuing with only /boot'
	}
}

	timezone=`{cat /adm/timezone/local}
fn showlocaldevs{
	for(d in /dev/sd*) if(test -r $d/ctl){
		q=`{sed 's,(inquiry|geometry),\
\1,g' $d/ctl | grep inquiry}
		echo $d':' $q(2-)
		for(i in `{ls -p $d}){
			p=$d/$i
			switch($i){
			case ctl raw log led
				;
			case plan9 nvram swap
				echo $p
			case *
				showlocaldev $p `{fstype $p}
			}
		}
	}
	for(d in /shr/sd*) if(test -d $d) {
		echo $d':'
		for(p in $d/*.^(iso paq)) if(test -f $p){
			t=`{fstype $p}
			~ $#t 0 || showlocaldev $p $t
		}
	}
}

##	if we aren't bootes we need to have a $home
# startup action functions

	if(! ~ $user bootes){
		echo 'copying bootes skeleton to '$user
		mkdir /root/usr/$user
		mkdir /root/usr/$user/lib
		mkdir /root/usr/$user/tmp
		mkdir /root/usr/$user/bin
		mkdir /root/usr/$user/bin/rc
		mkdir /root/usr/$user/bin/$cputype
		cp /usr/bootes/lib/profile /root/usr/$user/lib/profile
fn doramsetup{
	switch($ramsetup){
	case ''
		echo no ramsetup
	case ?*
		hostcheck
#		echo 'ramsetup '^$ramsetup^'...'
		rc -c $ramsetup
		if (test -e /srv/ramboot) {
			mount -c /srv/ramboot /mnt/rboot
			bind -ac /mnt/rboot/lib /lib
		}
#		echo 'timezone...'
#		timezone=`{cat /adm/timezone/local}
	}
}

fn dofactotum{
	if(~ $interactive yes)
		spc=()
	switch($factotum){
	case ''
		echo no factotum
	case cpu
#		echo $spc cpu factotum...
		/boot/factotum $factotumopts -S -s factotum
	case terminal
#		echo $spc terminal factotum...
		/boot/factotum $factotumopts -u -s factotum
	case debug
		hostcheck
		echo $spc debug factotum...
		/boot/factotum $factotumopts -d -s factotum
	}
}

fn dotryusb{
	if(! ~ $tryusb no){
		if (test -e /dev/usb/ctl) {
#			usbd /srv/usb
#			sleep 3
			if(test -e /dev/sdU0.0){
				if(! ~ $sdB0part ''){
					echo usb disk partfs -p $sdB0part -s partfs.sdXX /dev/sdU0.0
					partfs -p $sdB0part -s partfs.sdXX /dev/sdU0.0
					chmod 666 /srv/partfs.sdXX
				}
				if not
					echo /dev/sdU0.0 exists but no bootpartition information found
			}
		}
	}
}

fn ipsetup{
	if(! test -e /net/ipifc/0/ctl){
		ip/ipconfig -6 ether /net/ether0
		if(! ~ $#gateway 0){
			ipparams=( -g $gateway ether /net/ether0 $ipaddress $ipmask )
			echo ipconfig $ipparams
			ip/ipconfig $ipparams
		}
		if not{
			echo 'ipconfig...'
			test -e /env/nora6 || ip/ipconfig ether /net/ether0 ra6 recvra 1
			ip/ipconfig -h $sysname ether /net/ether0
		}
		ip/ipconfig loopback /dev/null 127.1
	}
	ipdone=yes
}

	bind -c /usr/$user/tmp /tmp
	echo 'partial root built starting services'
	auth/newns -n /lib/namespace initskel
	if(! ~ $privpassword ''){
		echo adding key to factotum
fn doafterfact{
	if (! ~ $#afterfact 0){
		echo after factotum command $afterfact
		rc -c $afterfact
	}
	if(! ~ $#privpassword 0){
		echo 'privpassword found - setting factotum key'
		if(~ $passdom '')
			passdom=9front
		if(~ $keyowner '')


@@ 190,109 269,303 @@ fn ants{
	}
}

mt=()

fn main{
	mp=()
	while(~ $#mp 0){
		if(~ $#nobootprompt 0){
			echo
			showlocaldevs
			ask bootargs ' is (tcp, tls, il, local!device)' $"bootargs
		}
		if not bootargs=$nobootprompt
		nobootprompt=()
		mn=`{echo $bootargs | sed 's,!, ,'}
		ma=$mn(2-)
		mn=$mn(1)
		switch(m$"mn){
		case $mt
			mp=m$mn
			mp=$$mp
fn dostartventi{
	switch($startventi){
	case yes
#		echo starting venti
		if(~ $venticonf '#'*)
			localventi=yes
		if(~ $venticonf '/dev'*)
			localventi=yes
		if(! ~ $ipdone yes){
			if(~ $localventi yes){
				echo Only starting loopback networking for local venti, ipconfig later if you need to...
				ip/ipconfig loopback /dev/null 127.1
			}
			if not
				ipsetup
		}
		if(~ $#ventilisten 0)
			venti/venti -c $venticonf
		if not
			venti/venti -c $venticonf -a $ventilisten -h $vhttplisten
		if(~ $#ventilisten 0){
			ventilisten=`{venticonf $venticonf |grep '^addr'}
			if(~ $#ventilisten 0)
				venti=tcp!127.1!17034
			if not
				venti=`{echo $ventilisten(2) | sed 's/!.*!/!127.1!/'}
		}
		if not
			venti=`{echo $ventilisten | sed 's/!.*!/!127.1!/'}
	case later
		echo ok you can start venti later that is fine
	}
}

	# authentication agent
	if(! test -f /srv/factotum){
		# we remount ip inteface after hostowner is set
		unmount '#I' /net >[2]/dev/null

		x=(/boot/factotum -n -sfactotum)
		if(~ $service cpu)
			x=($x -S)
fn dogetrootfs{
	switch($getrootfs){
	case 9660
		if(~ $interactive yes){
			echo 'parsed cd bootpartition as ' $bootpartition ' enter new value if this is incorrect'
			getans bootpartition $bootpartition
		}
		if not if(~ $#bootpartition 0){
			echo 'no bootpartition found, trying /dev/sdD0/data as default'
			bootpartition=/dev/sdD0/data
		}
		if (! test -e $bootpartition)
			bootpartition=`{ls /dev/sd*/data}
		if (~ $#bootpartition 0)
			bootpartition=FAIL
		cdpart=$bootpartition
		{9660srv -s -f $bootpartition $bootparse(2-) &} <[0=1] | echo 0 >/srv/boot
		bootsrv=/srv/boot		
	case hjfs
#		bootpartition=`{findpart fs}
		if(~ $interactive yes){
			echo 'parsed hjfs bootpartition as ' $bootpartition ' enter new value if this is incorrect'
			getans bootpartition $bootpartition
		}
		if not if(~ $#bootpartition 0){
			echo 'no bootpartition found, trying /dev/sdC0/fs as default'
			bootpartition=/dev/sdC0/fs
		}
		if (! test -e $bootpartition)
			bootpartition=`{ls /dev/sd*/fs}
		if (~ $#bootpartition 0)
			bootpartition=FAIL
		hjfs=$bootpartition
		{hjfs -s -f $bootpartition $bootparse(2-) &} <[0=1] | echo 0 >/srv/boot
		bootsrv=/srv/boot
	case cwfs*
#		bootpartition=`{findpart fscache}
		if(~ $interactive yes){
			echo 'parsed cwfs bootpartition as ' $bootpartition ' enter new value if this is incorrect'
			getans bootpartition $bootpartition
		}
		if not if(~ $#bootpartition 0){
			echo 'no bootpartition found, trying /dev/sdC0/fscache as default'
			bootpartition=/dev/sdC0/fscache
		}
		if (! test -e $bootpartition)
			bootpartition=`{ls /dev/sd*/fscache}
		if (~ $#bootpartition 0)
			bootpartition=FAIL
		cwfs=$bootpartition
		{cwfs64x -s -f $bootpartition $bootparse(2-) &} <[0=1] | echo 0 >/srv/boot
		bootsrv=/srv/boot
	case fossil
		if(! ~ $fossil ?*){
#			bootpartition=`{findpart fossil}
			if(~ $interactive yes){
				echo 'parsed fossil bootpartition as ' $bootpartition ' enter new value if this is incorrect'
				getans bootpartition $bootpartition
			}
			if not if(~ $#bootpartition 0){
				echo 'no bootpartition found, trying /dev/sdC0/fossil as default'
				bootpartition=/dev/sdC0/fossil
			}
			if (! test -e $bootpartition)
				bootpartition=`{ls /dev/sd*/fossil}
			if (~ $#bootpartition 0)
				bootpartition=FAIL
			fossil=$bootpartition
		}
		if(! ~ $#venti 0){
			if(~ $venti *tcp*){
				if(! ~ $ipdone yes)
					ipsetup
			}
			if not
				venti=tcp!^$venti^!17034
		}
#		echo starting fossil from $fossil...
		fossil/fossil -f $fossil -c 'srv -p fscons'
		echo 'srv -A boot' >>/srv/fscons
		bootsrv=/srv/boot
		bootpartition=$fossil
	case tcp
		if(! ~ $ipdone yes){
			ipsetup
		}
		if(~ $#fs 0){
			echo 'fs is [ ' $fs ' ]?'
			getans fs $fs
		}
		if(~ $#auth 0)
			auth=$fs
## HACK: on terminals start new factotum that knows where to dial
		if(~ $factotum terminal)
			/boot/factotum -a $auth
		echo srv $fs to /srv/boot...
		if(~ $fs *tcp*)
			srv $fs boot
		if not
			x=($x -u)
		if(! ~ $#debugfactotum 0)
			x=($x -p)
		must $x

		bind -qa '#I' /net
			srv tcp!$fs!564 boot
		bootsrv=/srv/boot
	case tls
		if(! ~ $ipdone yes)
			ipsetup
		if(~ $#fs 0){
			echo 'fs is [ ' $fs ' ]?'
			getans fs $fs
		}
		if(~ $auth '')
			auth=$fs
## HACK: on terminals start new factotum that knows where to dial
		if(~ $factotum terminal)
			/boot/factotum -a $auth
		echo srv $fs to /srv/boot...
		if(~ $fs *tcp*)
			srvtls $fs boot
		if not
			srvtls tcp!$fs!17020 boot
		bootsrv=/srv/boot
	case aan
		if(! ~ $ipdone yes)
			ipsetup
		if(~ $#fs 0){
			echo 'fs is [ ' $fs ' ]?'
			getans fs $fs
		}
		if(~ $#auth 0)
			auth=$fs
## HACK: on terminals start new factotum that knows where to dial
		if(~ $factotum terminal)
			/boot/factotum -a $auth
		echo srv $fs to /srv/boot...
		if(~ $fs *tcp*)
			rimport -p -s boot $fs / /n/bootimp
		if not
			rimport -p -s boot tcp!$fs!17019 / /n/bootimp
		bootsrv=/srv/boot
	case srv
		if(~ $interactive yes){
			echo 'enter full path to target srv'
			getans bootsrv $bootsrv
		}
	case ''
		echo no standard root fs attached
	}
# add cfs if requested
	if(~ $#cfs 1 && test -x /bin/cfs && test -f $cfs){
		{/bin/cfs -s -S -f $cfs </srv/boot &} | echo 0 >/srv/cfs
		mv /srv/boot /srv/boot.nocfs
		mv /srv/cfs /srv/boot
	}
}

	# setup low level namespace
	ants

	# config method
	$mp(1) $ma

	# load keys from secstore if $auth or $secstore is not empty
	x=secstore
	if(~ $#$x 0) x=auth
	if(! ~ $#$x 0 && test -x /bin/auth/secstore && test -f /mnt/factotum/ctl){
		x=(auth/secstore -G factotum -s^$$x)
		if(~ $service cpu)
			$x -n >/mnt/factotum/ctl
		if(~ $status *readnvram* || ! ~ $service cpu)
			$x >/mnt/factotum/ctl
fn doafterroot{
	switch($afterroot){
	case ?*
		echo afterroot command $afterroot
		rc -c $afterroot
	case ''
		echo -n ''
	}
}

	# connect method
	$mp(2) $ma
fn doinitscript{
	switch($initscript){
	case ?*
		auth/newns -n /lib/$namespace $initscript
	case easteregg
		echo guess i should make an easter egg here
	}
}

	# insert cfs in the pipeline
	if(test -x /bin/cfs){
		if(~ $#bootdisk 1 && ~ $#cfs 0)
			cfs=$bootdisk/cache
		if(~ $#cfs 1 && ! ~ $cfs off && test -f $cfs){
			{/bin/cfs -s -f $cfs </srv/boot &} | echo 0 >/srv/cfs
			rm /srv/boot
			mv /srv/cfs /srv/boot
fn dorootstart{
	switch($rootstart){
	case grid
		service=cpu
		echo grid service started mounting $bootsrv and starting hubrc
		mount $bootsrv /root
		cat /root/adm/timezone/local >/env/timezone
		if(test -e /root/rc/bin/hubrc)
			auth/newns -n /root/lib/namespace /root/rc/bin/hubrc
		if not{
			echo no hubrc found trying defaults
			cs
			import -c $hubserver / /n/$hubserver
			mount -c /n/$hubserver/srv/gridhub /n/gridhub
			echo 'attaching to '$hubserver' gridhub'
			if(test -e /n/gridhub/^$sysname^0){
				echo 'attaching rc to existing clonecpu hubs'
				rc -i </n/gridhub/^$sysname^0 >>/n/gridhub/^$sysname^1 >>[2]/n/gridhub/^$sysname^2 &
			}
			hub gridhub $sysname
		}
	case cpu
		service=cpu
#		echo mounting $bootsrv to /root and starting cpurc
		mount $bootsrv /root
		cat /root/adm/timezone/local >/env/timezone
		if(test -e /root/rc/bin/cpurc)
			auth/newns -n /root/lib/namespace /root/rc/bin/cpurc
		if not
			echo ERROR no cpurc found
	case terminal
		service=terminal
#		echo mounting $bootsrv to /root and starting termrc
		mount $bootsrv /root
		cat /root/adm/timezone/local >/env/timezone
		if(~ $#user 0){
			user=`{cat /dev/hostowner}
		}
		home=/usr/$user
		if(test -e /root/rc/bin/termrc){
			rm /env/'fn#sigint'
			auth/newns -n /root/lib/namespace /root/rc/bin/termrc
			auth/newns -n /root/lib/namespace rc -c 'cd; . $home/lib/profile'
		}
		if not
			echo ERROR no termrc found
	case ''
		echo not starting externally rooted startup scripts
	}
}

	# mount and change root in new enviroment and namespace
	rfork ne

	# mount root filesystem
	if(~ $#rootdir 0)
		rootdir=/root
	must mount -c '#s/boot' /root $rootspec
############# Begin script execution ###############
echo 'Advanced Namespace Tools 6.00 Starting...'

	# compile init command
	if(~ $#init 0){
		init=/$cputype/init
		if(~ $service cpu)
			init=($init -c)
		if not
			init=($init -t)
	}
# mount points
if (test -e /bin/mntgen){
	mntgen -s slashn /n
	mntgen -s slashmnt /mnt
	mntgen -s mntexport /mnt/exportfs
}
if (test -e /bin/chmod){
	chmod 666 /srv/slashn
	chmod 666 /srv/slashmnt
	chmod 666 /srv/mntexport
}

	# remove enviroment variables
	rm -f '#e/'^$mt '#e/'? '#e/'?? '#e/fn#'* 
bind /root /mnt/broot
unmount /root

	# remove part of our temporary root
	/mnt/broot/$cputype/bin/unmount /$cputype/bin /bin
	/mnt/broot/$cputype/bin/unmount /rc/bin /bin
	/mnt/broot/$cputype/bin/unmount /
# bind devices
bind -q '#σ' /shr
bind -q '#d' /fd
bind -q '#p' /proc
for(i in ¶ P S f k æ t b m)
	bind -qa '#'^$i /dev

	# create the name space, mount the root fs
	/mnt/broot/$cputype/bin/bind / /
	/mnt/broot/$cputype/bin/bind -ac $rootdir /
# bind in an ip interface
for(i in I l^(0 1 2 3))
	bind -qa '#'$i /net

	# remove the remaining temporary root
	/mnt/broot/$cputype/bin/unmount /mnt/broot
# usually better than 1970
cat '#r/rtc' >/dev/time >[2]/dev/null

	exec $init
# reparse variables
for(i in `{ls -Qp /env}){
	switch($i){
	case '*'* 'fn#'* e820 apm0 apid ifs path pid prompt status ?
		# ignore these
	case *
		$i=`{echo $$i}
	}
}

# keyboard and serial console


@@ 301,7 574,6 @@ if(test -x /bin/aux/kbdfs){
	if(! ~ $#a 0)
		a=/dev/eia^$a
	aux/kbdfs -q -s cons $a

	if(! ~$#kbmap 0){
		if(test -f /sys/lib/kbmap/$kbmap){
			echo 'setting kbmap to' $kbmap


@@ 314,23 586,249 @@ if(test -x /bin/aux/kbdfs){
if(test -x /bin/nusbrc && ! test -e /env/nousbrc)
	nusbrc

# load boot methods
fn showlocaldevs {}
fn configlocal {}
for(i in /rc/lib/*.rc){
	. $i
diskparts

# set up srv of 9front paqfs
#echo -n paqfs...
paqfs -q -s -S frontpaq -c 128 /boot/bootfs.paq
bind -a /boot /bin

# Parse plan9.ini options and trying to set sane defaults
if(! ~ $#1 0)
	. $1
if(~ $cdboot yes)
	showlocaldevs
if(! ~ $#nobootprompt 0)
	bootargs=$nobootprompt
if(~ $#bootargs 0)
	showlocaldevs
factotumopts=`{echo $factotumopts}
bootparse=`{echo $bootargs}
ipparams=`{echo $ipparams}
switch($bootparse(1)){
case tcp*
	getrootfs=tcp
	if(! ~ $bootparse(2) '')
		ipparams=`{shifter $bootparse}
case tls*
	getrootfs=tls
	if(! ~ $bootparse(2) '')
		ipparams=`{shifter $bootparse}
case aan*
	getrootfs=aan
	if(! ~ $bootparse(2) '')
		ipparams=`{shifter $bootparse}
case srv*
	getrootfs=srv
case *
	getrootfs=`{echo $bootparse | sed 's,!, ,'}
	bootpartition=$getrootfs(2)
	getrootfs=`{fstype $bootpartition}
}
if(~ $#ramsetup 0)
	ramsetup=ramskel
if(~ $#initscript 0)
	initscript=initskel
if(~ $#tgzfs 0)
	tgzfs=tools.tgz
if(~ $tgzfs no)
	tgzfs=''
if(~ $#namespace 0)
	namespace=namespace
if(~ $#factotum 0)
	factotum=`{cat '/env/service'}
if(~ $#rootstart 0)
	rootstart=`{cat '/env/service'}
ventiparse=`{echo $venti}
venticonf=$ventiparse(1)
ventilisten=$ventiparse(2)
vhttplisten=$ventiparse(3)
if(~ $venticonf '#'*)
	startventi=yes
if(~ $venticonf '/dev'*)
	startventi=yes
if(~ $#venticonf 0)
	venticonf=/dev/sdC0/arenas
if(~ $#ventilisten 1)
	if(~ $#vhttplisten 0)
		vhttplisten=tcp!127.1!8000
if(~ $#interactive 0)
	interactive=traditional

# interactive startup prompts and actions
fn startinter{
	echo Interactive Startup - enter to continue to options or type rc for a shell
	answer=`{read}
	if(~ $answer rc){
		echo dropping to rc shell with limited commands
		rc -i
	}
	echo 'Internet config DHCP by default. Enter ipconfig parameters if needed'
	getans ipparams $ipparams
	echo 'Choose factotum mode - cpu terminal or debug.'
	getans factotum $factotum
	dofactotum
	dotryusb
	echo 'Enter sysname'
	getans sysname $sysname
	echo 'Skeleton fs required for mountpoints. Default ramskel recommended.'
	getans ramsetup $ramsetup
	echo 'Load optional tools from 9fat? Enter tools.tgz or other if desired'
	getans tgzfs $tgzfs
	doramsetup
	hostcheck
	dochecksys
	echo 'Start local Venti? Enter yes if so.'
	getans startventi $startventi
	if(~ $startventi yes){
		echo 'enter venti listen string'
		getans ventilisten $ventilisten
		echo 'enter venti httplisten string'
		getans vhttplisten $vhttplisten
	}
	dostartventi
	echo 'Root file server? cwfs, hjfs, fossil, tcp, tls, aan or leave blank.'
	getans getrootfs $getrootfs
	if(~ $getrootfs tcp || ~ $getrootfs tls || ~ $getrootfs aan){
		echo 'fileserver is [ ' $fs ' ]?'
		getans fs $fs
		if (~ $#auth 0)
			auth=$fs
		echo 'auth is [ ' $auth ' ]?'
		getans auth $auth
		echo 'cfs is [ ' $cfs ' ]?'
		getans cfs $cfs
	}
	if(~ $getrootfs fossil){
		echo 'Dial a venti server? Enter a dialstring or ip if so.'
		getans venti $venti
		if(! ~ $#venti 0){
			if(! ~ $venti *tcp*)
				venti=tcp!^$venti^!17034
			ipsetup
		}
	}
	dogetrootfs
	echo 'Create cpu server namespace on a port of your choice? Initskel if so.'
	getans initscript $initscript
	doinitscript
	echo 'Start cpurc termrc from the file server? Enter cpu or terminal if so.'
	getans rootstart $rootstart
	echo 'storing startup configuration to ramdisk in /usr/'$user'/tmp/p9cfg'
	save9cfg
	cleanenv >[2] /dev/null
	dorootstart
	echo 'Keep console in ramboot namespace? yes if so.'
	getans staylocal $staylocal
	if(! ~ $staylocal no){
		echo starting shell in current namespace
		home=/usr/$user
		rc -i
	}
}

# traditional startup prompts and actions
fn starttrad{
	dofactotum
	dotryusb
	doramsetup
	hostcheck
	dochecksys
	doafterfact
	showlocaldevs
	if(~ $#nobootprompt 0){
		echo -n 'root is from (tcp,tls,aan,local)['$bootargs']: '
		bootanswer=`{read}
		if(~ $bootanswer rc)
			rc -i
		if not if(! ~ $#bootanswer 0)
			bootparse=`{echo $bootanswer}
	}
	switch($bootparse(1)){
	case tcp*
		getrootfs=tcp
		if(! ~ $bootparse(2) '')
			ipparams=`{shifter $bootparse}
	case tls*
		getrootfs=tls
		if(! ~ $bootparse(2) '')
			ipparams=`{shifter $bootparse}
	case aan*
		getrootfs=aan
		if(! ~ $bootparse(2) '')
			ipparams=`{shifter $bootparse}
	case srv*
		getrootfs=srv
	case *
		getrootfs=`{echo $bootparse | sed 's,!, ,'}
		bootpartition=$getrootfs(2)
		getrootfs=`{fstype $bootpartition}
	}
	if(~ $getrootfs tcp || ~ $getrootfs tls || ~ $getrootfs aan){
		if (~ $#fs 0){
			echo 'fileserver is [ ' $fs ' ]?'
			getans fs $fs
		}
		if (~ $#auth 0){
			auth=$fs
			echo 'auth is [ ' $auth ' ]?'
			getans auth $auth
		}
	}
	dostartventi
#	interactive=yes
	dogetrootfs
#	interactive=traditional
	doafterroot
	doinitscript
#	echo 'storing startup configuration to ramdisk in /usr/'$user'/tmp/p9cfg'
	save9cfg
	cleanenv >[2] /dev/null
	dorootstart
	if(! ~ $staylocal no){
		echo starting shell in current namespace
		home=/usr/$user
		rc -i
	}
}

# non-interactive startup actions
fn startnonint{
	dofactotum
	dotryusb
	doramsetup
	hostcheck
	dochecksys
	doafterfact
	dostartventi
	dogetrootfs
	doafterroot
	doinitscript
	echo 'storing startup configuration to ramdisk in /usr/'$user'/tmp/p9cfg'
	save9cfg
	cleanenv >[2] /dev/null
	dorootstart
	if(! ~ $staylocal no){
		echo starting shell in current namespace
		home=/usr/$user
		rc -i
	}
}

# add partitions and binds
configlocal
if(~ $interactive yes){
	@{startinter}
} </dev/cons
if not if(~ $interactive traditional){
	@{starttrad}
} </dev/cons
if not {
	@{startnonint}
} </dev/cons

echo 'startup scripts exited!! starting recovery rc'
while(){
	@{main}
	@{rc}
} </dev/cons

	# subshell doesnt wait on interrupts
	while(~ $status interrupted){wait}
exit ''

	# cleanup so it can be restarted
	nobootprompt=()
	rm -f /srv/^(cfs boot cs dns)
} </dev/cons