# Copyright (c) 2014 by David L. Craig, all rights reserved
# and licensed under version 2 of the GPL.
# http://dlc.casita.net/~dlc       mailto:dlc.usa@gmail.com
#
# This rc shell script was created by Plan 9 contributor maht
# in the contrib index, last updated Jan 6, 2010, by the name
# make_cpuauth.  In August 2014, David L. Craig modified it for
# the heart of the last section of his Virtual Plan 9 Cookbook
# to simplify the conversion of a freshly installed Bell Labs
# stand-alone terminal into a fully networked cpu/auth server.
#----------------------------------------------------------------
# Revisions:
# 2014-08-23 Alpha release with time zone and (virtual) rtc
#            timesync support
#----------------------------------------------------------------
# The following comments are from the opening echo commands
# of the original script:
#
# this script will ask some questions, see QUESTIONS HERE,
# answer the questions truthfully and it will become a cpu/auth
# server, you will probably have to make notes so you know what
# to do when it does a reboot at the end of the script
#
# These instructions were culled from the wiki and made to
# work on a fresh install on September 7th 2007
# 
# 20th July - Added testing for and if so starting venti on
# '/dev/$disk/arenas'.
#
# added aux/listen for doing cpu -h
#
# failed on 15th May because /386/bin/fossil has the wrong
# date and mk kernel tries to mk it
#----------------------------------------------------------------
# It seems here documents inside rc functions don't behave well.
# Thus the functions originally defined were converted into
# mainline commands (but the function names remain associated
# with the commands in the logging statements) and most of the
# echo command sequences have been converted to here documents.

if(! ~ $user glenda) {
   st='must be logged in as glenda'
   echo $st ; exit $st
}

# QUESTIONS HERE

echo 'Enter sysname (the host name to use for the server):'
sysname=`{read}
echo 'Enter authdom (the domain of the Ethernet NIC):'
authdom=`{read}
echo 'Enter ipnet (the name to call the local net):'
ipnet=`{read}
echo 'Enter dns (the dot-quad IPv4 address of the dns server):'
dns=`{read}
echo 'Enter ip (the dot-quad IPv4 address of this host):'
p1=`{read}
echo 'Enter either cidr (1-31) or netmask (dot-quad):'
p2=`{read}
v=(`{awk -v 'd=n' -v 'a1='^$p1 -v 'a2='^$p2 -v 'mf=tmp/awk.mf.'^$pid \
     -f /usr/glenda/lib/get_ipv4conf </dev/null})
ip=$v(1)        ; cidr=$v(2)    ; netmask=$v(3) ; network=$v(4)
broadcast=$v(5) ; gateway=$v(6) ; host=$v(7) 
cat tmp/awk.mf.$pid ; rm tmp/awk.mf.$pid
if(! test -e /env/mouseport)
    mouseport=ps2intellimouse
if(! test -e /env/vgasize)
    vgasize=640x480x8
ether=`{cat /net/ether0/addr}
bootf='/386/9pc'
disk='sdC0'

for ( i in `{lc /adm/timezone | grep -v local | grep -v README} )
    cmp -s local $i && { timezone=($i) ; break }
cat <<'EOD'

Now you will be given the opportunity to revise the parameters
that will be used to reconfigure the stand-alone terminal into
a cpu/auth/fs server.  For each parameter, you will be shown
the current value enclosed by angle brackets.  If it is what
you want, just press to Enter key to move on to the next;
otherwise, type in the value you want used before pressing the
Enter key, and you will be asked to accept that new value again.

EOD
for (i in (authdom bootf broadcast disk dns ether gateway \
           ip ipnet mouseport netmask network sysname \
           timezone vgasize)) {
    j=1
    while ( ~ $#j 1 ) {
        eval 'w=($'^$i^')'
        echo $i^' is <'^$w^'>'
        j=`{read}
        if ( ~ $#j 1 ) eval $i^'=($j)'
    }
}
cat <<EOD

Here are the final parameters:

  authdom <$authdom^>
    bootf <$bootf^>
broadcast <$broadcast^>
     disk <$disk^>
      dns <$dns^>
    ether <$ether^>
  gateway <$gateway^>
       ip <$ip^>
    ipnet <$ipnet^>
mouseport <$mouseport^>
  netmask <$netmask^>
  network <$network^>
  sysname <$sysname^>
 timezone <$timezone^>
  vgasize <$vgasize^>
EOD
if(test -e /dev/$disk/arenas)
    echo 'venti on /dev/'^$disk^'/arenas'

echo 'Press Enter to begin reconfiguration or press Del to quit the script'
read

# ACTION STARTS HERE
9fat:
# ramfs # commented out because its need is enigmatic
#--------------------------------- fn backup_files {
    bkdir = /usr/glenda/backups/`{date -n}
    mkdir -p $bkdir && echo backups going in $bkdir
    cp /n/9fat/plan9.ini \
       /rc/bin/cpurc.local \
       /rc/bin/cpurc \
       /lib/ndb/local \
       /lib/ndb/auth \
       /dev/sdC0/nvram \
       $bkdir
    echo 'fn backup_files saved originals in '^$bkdir
#}
#--------------------------------- fn set_sysname {
    cat >>/n/9fat/plan9.ini <<EOD
sysname=$sysname
EOD
    echo 'fn set_sysname appended sysname='^$sysname
    echo '               to plan9.ini (but this will'
    echo '               replaced by fn write_bootmenu)'
#}
#--------------------------------- fn add_cfg {
    cd /cfg
    mkdir $sysname
    dircp example $sysname
    echo 'fn add_cfg copied /cfg/example tree to'
    echo '           /cfg/'^$sysname
#}
#--------------------------------- fn bind_devices {
    cat >/tmp/fn_bind_devices <<'EOD'
for (i in (m i S t))
    bind -a '#'^$i /dev >/dev/null >[2=1]
EOD
    cat /tmp/fn_bind_devices
    cat /tmp/fn_bind_devices >> /rc/bin/cpurc.local
    rm  /tmp/fn_bind_devices
    echo 'fn bind_devices appended for bind loop to'
    echo '                /rc/bin/cpurc.local'
#}
#--------------------------------- fn config_ip {
    cat >/tmp/fn_config_ip <<EOD
ip/ipconfig -g $gateway ether /net/ether0 $ip $netmask
EOD
    cat /tmp/fn_config_ip
    cat /tmp/fn_config_ip >>/cfg/$sysname/cpurc
    rm  /tmp/fn_config_ip
    echo 'fn config_ip appended ipconfig command to'
    echo '             /cfg/'^$sysname^'/cpurc'
#}
#--------------------------------- fn uncomment_cfg_cpurc {
    ed /cfg/$sysname/cpurc <<'EOD'
1+/# ip\/dhcpd/
s/# /# /
.
/# ip\/tftpd/
s/# /
.
/# ndb\/dns/
s/# /
s/$/ -r/
.
w
q
EOD
    echo 'fn uncomment_cfg_cpurc processed dhcpd, tftpd, and dns,'
    echo '                       and appended -r to dns line of'
    echo '                       /cfg/'^$sysname^'/cpurc'
#}
#--------------------------------- fn uncomment_cpurc {
    ed /rc/bin/cpurc <<'EOD'
1+/^# auth\/keyfs/
s/# /
.
/^# auth\/cron/
s/# /
.
1+/aux\/timesync/
s/-n pool.ntp.org/-ra1000000/
\.
w
q
EOD
# moved aux/listen to fn rioize to be added to /cfg/$sysname/cpustart
    echo 'fn uncomment_cpurc uncommented keyfs and cron and'
    echo '                   changed timesync source to rtc in'
    echo '                   /rc/bin/cpurc'
#}
#--------------------------------- fn enable_services {
    ls -l /rc/bin/service.auth/*tcp567*
    mv /rc/bin/service.auth/authsrv.tcp567 \
       /rc/bin/service.auth/tcp567
    mv /rc/bin/service/tcp567 \
       /rc/bin/service/!tcp567
    ls -l /rc/bin/service.auth/*tcp567*
    echo auth/secstored >>/cfg/$sysname/cpurc
    echo 'fn enable_services moved/renamed tcp567 within'
    echo '                   /rc/bin/service.auth tree and'
    echo '                   appended auth/secstored to'
    echo '                   /cfg/'^$sysname^'/cpurc'
#}
#--------------------------------- fn rioize {
    cat >/tmp/fn_rioize <<EOD
aux/listen -q -t /rc/bin/service.auth -d /rc/bin/service tcp
aux/mouse $mouseport
aux/vga -l $vgasize
exec rio
EOD
    cat /tmp/fn_rioize
    cat /tmp/fn_rioize >>/cfg/$sysname/cpustart
    rm  /tmp/fn_rioize
    echo 'fn rioize appended mouse, vga, and exec rio commands'
    echo '          to /cfg/'^$sysname^'/cpustart'
#}
#--------------------------------- fn create_bootes {
    cat >>/srv/fscons <<'EOD'
uname bootes bootes
uname adm +bootes
uname sys +bootes
fsys main
create /active/cron/bootes bootes bootes d775
create /active/sys/log/cron bootes bootes a664
EOD
    echo 'fn create_bootes commanded fscons to create user bootes'
    echo '                 with adm and sys membership and add'
    echo '                 cron and log entries in /active'
#}
#--------------------------------- (mainline)
echo 'When prompted, provide auth/keyfs with the password it is to set'
auth/keyfs
#--------------------------------- fn fill_ndb {
    cat >/tmp/fn_fill_ndb <<EOD
ipnet=$ipnet ip=$network ipmask=$netmask ether=$ether
    broadcast=$broadcast gateway=$gateway
    auth=$sysname
    cpu=$sysname
    fs=$sysname
    bootf=$bootf 
    dns=$dns

authdom=$authdom auth=$sysname

sys=$sysname dom=$sysname.$authdom ip=$ip 
EOD
    cat /tmp/fn_fill_ndb
    cat /tmp/fn_fill_ndb >>/lib/ndb/local
    rm  /tmp/fn_fill_ndb
    echo 'fn fill_ndb appended ipnet, authdom, and sys entries'
    echo '            to /lib/ndb/local'
#}
#--------------------------------- fn empower_bootes {
    cat >/tmp/empower_bootes <<'EOD'
hostid=bootes
    uid=!sys uid=!adm uid=*
EOD
    cat /tmp/empower_bootes
    cat /tmp/empower_bootes >>/lib/ndb/auth
    rm  /tmp/empower_bootes
    echo 'fn empower_bootes appended hostid=bootes entry to'
    echo '                  /lib/ndb/auth'
#}
#--------------------------------- fn install_kernel {
    if(! test -e /n/9fat/9pccpuf) {
	touch /386/bin/fossil # circumvent bad dates causing mk errors
	cd /sys/src/9/pc
	mk 'CONF=pccpuf' install
	mk clean
	cp /386/9pccpuf /n/9fat
    }
    echo 'fn install_kernel built the /386/9pccpuf kernel'
    echo '                  and copied it into the 9fat partition'
#}
#--------------------------------- fn write_bootmenu {
    cat >/tmp/plan9.ini <<EOD
[menu]
menuitem=pcf, Boot terminal - 9pcf
menuitem=pccpuf, Boot cpu/auth - 9pccpuf
menuitem=chooser, Choose kernel
menudefault=pccpuf, 10

[pcf]
bootfile=$disk!9fat!9pcf

[pccpuf]
bootfile=$disk!9fat!9pccpuf

[chooser]
bootfile=$disk!9fat!9pcf
bootfile=$disk!9fat!9pccpuf
 
[common]
EOD
    {
        grep -v '^bootfile=' /n/9fat/plan9.ini
    	if(test -e /dev/$disk/arenas)
    	    echo venti'='/dev/$disk/arenas
    } >>/tmp/plan9.ini
    cat /tmp/plan9.ini
    cat /tmp/plan9.ini >/n/9fat/plan9.ini
    rm  /tmp/plan9.ini
    echo 'fn write_bootmenu replaced plan9.ini in the 9fat partition'
#}
#--------------------------------- fn create_newfossil_sys_user {
#     cat >/sys/lib/newfsysuser <<'EOD'
# #!/bin/rc
# 
# auth/changeuser $1
# cat >>/srv/fscons <<'EOS'
# uname $1 $1
# uname sys +$1
# newuser $1
# newuser sys +$1
# EOS
# EOD
#     chmod 755 /sys/lib/newfsysuser
#     echo 'fn create_newfossil_sys_user added the newfsysuser rc script'
#     echo '                             to /sys/lib'
#} 
#--------------------------------- (mainline)
echo 'force_reinitialization_of_nvram_during_next_boot' >/dev/$disk/nvram
echo 'The content of /dev/'^$disk^'/nvram has been invalidated'
#--------------------------------- (mainline)
cat <<EOD
The reconfiguration prior to the reboot has completed.  After the
reboot you will be asked to provide the following variables (those
in uppercase indicate unknown values you will need to supply):
      authid : bootes
     authdom : $authdom
secstore key : YOUR_CHOICE
    password : BOOTES_PASSWORD

When you are ready to reboot, type "fshalt" and press Enter,
then follow the instructions in the "Virtual Plan 9 Cookbook"
to complete the conversion into a cpu/auth server.
EOD
cd /env ; rm authdom bootf broadcast cidr disk dns ether gateway \
             j ip ipnet mouseport netmask network p1 p2 sysname \
             timezone v vgasize w
