#!/bin/rc # mount pointsmntgen -s slashn /n && chmod 666 /srv/slashnmntgen -s slashmnt /mnt && chmod 666 /srv/slashmntmntgen -s mntexport /mnt/exportfs && chmod 666 /srv/mntexport bind /root /mnt/brootunmount /root bind -q '#d' /fdbind -q '#p' /procfor(i in S f k æ t b m) bind -qa '#'^$i /dev # bind in an ip interfacefor(i in I l^(0 1 2 3)) bind -qa '#'$i /net # usualy better than 1970cat '#r/rtc' >/dev/time >[2]/dev/null # reparse variablesfor(i in `{ls -Qp /env}){ switch($i){ case '*'* 'fn#'* e820 apm0 apid ifs path pid prompt status ? # ignore these case * $i=`{echo $$i} }} fn sigint { status=interrupted} fn fatal { echo $* exit $"*} 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'){ rc -i $1=() } if(~ $#$1 0) ask $*} mt=() fn main{ mp=() echo '9netboot kernel' echo 'netbootfile='^$netbootfile echo 'bootfs='^$fs echo 'bootuser='^$user while(~ $#mp 0){ bootargs=tcp nobootprompt=() mn=`{echo $bootargs | sed 's,!, ,'} ma=$mn(2-) mn=$mn(1) switch(m$"mn){ case $mt mp=m$mn mp=$$mp } if(~ $"mn 'local'){ echo 'error: 9netboot does not support local booting' mp=() } } # authentication agent if(! test -f /srv/factotum){ x=(/boot/factotum -n -sfactotum) if(~ $service cpu){ x=($x -S) if(~ -k $ff) x=($x -k) } if not x=($x -u) if(! ~ $#debugfactotum 0) x=($x -p) must $x } # 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 } # connect method $mp(2) $ma # mount and change root in new enviroment and namespace rfork ne # mount root filesystem if(~ $#rootdir 0) rootdir=/root must mount -c /srv/boot $rootdir if(~ $#netbootfile 0){ netbootfile=/386/9pcf } netboot $rootdir $netbootfile} # keyboard and serial consoleif(test -x /bin/aux/kbdfs){ a=$console(1) if(! ~ $#a 0) a=/dev/eia^$a aux/kbdfs -q -s cons $a} # usb devicesif(test -x /bin/nusbrc && ! test -e /env/nousbrc) nusbrc # load boot methodsfn showlocaldevs {}fn configlocal {}for(i in /rc/lib/*.rc){ . $i} # boot(8) command line argumentsff=()aa=()while(! ~ $#* 0){ if(~ $1 -*){ if(~ $1 -u*){ if(~ $1 -u){ user=$2 shift } if not { user=`{echo $1 | sed 's,^-u,,g'} } } if not { if(~ $1 -*f*) ff=($ff -f) if(~ $1 -*k*) ff=($ff -k) if(~ $1 -*m*) ff=($ff -m) } shift } if not { while(! ~ $#* 0){ aa=($aa $1) shift } }}if(! ~ $#aa 0 && ~ $#bootargs 0 && ~ $#nobootprompt 0){ bootargs=$aa nobootprompt=$aa} while(){ @{main} # subshell doesnt wait on interrupts while(~ $status interrupted){wait} # cleanup so it can be restarted nobootprompt=() rm -f /srv/^(cfs boot cs dns)} </dev/cons
#!/bin/rc
# 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 '#d' /fd
bind -q '#p' /proc
for(i in S f k æ 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
# usualy better than 1970
cat '#r/rtc' >/dev/time >[2]/dev/null
# 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}
}
}
fn sigint {
status=interrupted
}
fn fatal {
echo $*
exit $"*
}
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'){
rc -i
$1=()
}
if(~ $#$1 0)
ask $*
}
mt=()
fn main{
mp=()
echo '9netboot kernel'
echo 'netbootfile='^$netbootfile
echo 'bootfs='^$fs
echo 'bootuser='^$user
while(~ $#mp 0){
bootargs=tcp
nobootprompt=()
mn=`{echo $bootargs | sed 's,!, ,'}
ma=$mn(2-)
mn=$mn(1)
switch(m$"mn){
case $mt
mp=m$mn
mp=$$mp
}
if(~ $"mn 'local'){
echo 'error: 9netboot does not support local booting'
mp=()
}
}
# authentication agent
if(! test -f /srv/factotum){
x=(/boot/factotum -n -sfactotum)
if(~ $service cpu){
x=($x -S)
if(~ -k $ff)
x=($x -k)
}
if not
x=($x -u)
if(! ~ $#debugfactotum 0)
x=($x -p)
must $x
}
# 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
}
# connect method
$mp(2) $ma
# mount and change root in new enviroment and namespace
rfork ne
# mount root filesystem
if(~ $#rootdir 0)
rootdir=/root
must mount -c /srv/boot $rootdir
if(~ $#netbootfile 0){
netbootfile=/386/9pcf
}
netboot $rootdir $netbootfile
}
# keyboard and serial console
if(test -x /bin/aux/kbdfs){
a=$console(1)
if(! ~ $#a 0)
a=/dev/eia^$a
aux/kbdfs -q -s cons $a
}
# usb devices
if(test -x /bin/nusbrc && ! test -e /env/nousbrc)
nusbrc
# load boot methods
fn showlocaldevs {}
fn configlocal {}
for(i in /rc/lib/*.rc){
. $i
}
# boot(8) command line arguments
ff=()
aa=()
while(! ~ $#* 0){
if(~ $1 -*){
if(~ $1 -u*){
if(~ $1 -u){
user=$2
shift
}
if not {
user=`{echo $1 | sed 's,^-u,,g'}
}
}
if not {
if(~ $1 -*f*)
ff=($ff -f)
if(~ $1 -*k*)
ff=($ff -k)
if(~ $1 -*m*)
ff=($ff -m)
}
shift
}
if not {
while(! ~ $#* 0){
aa=($aa $1)
shift
}
}
}
if(! ~ $#aa 0 && ~ $#bootargs 0 && ~ $#nobootprompt 0){
bootargs=$aa
nobootprompt=$aa
}
while(){
@{main}
# subshell doesnt wait on interrupts
while(~ $status interrupted){wait}
# cleanup so it can be restarted
nobootprompt=()
rm -f /srv/^(cfs boot cs dns)
} </dev/cons