December 6, 2014

Running the CTIX install process (stand-alone 68020 kernel needed)

How does one "extract" a stand-alone kernel from an existing full kernel?  


Working with a cadre of files found from an old MightyFrame CTIX 5.11 tape dump


The 2 versions of full CTIX that we have available are:

CTIX5.11onb

and

CTIX5.11vme

In reviewing the ctinstall program, we see that a comment in the program below indicates that it will put a stand-alone UNIX kernel on a tape.

The problem is, CTIX must already be running functionally in order to run this script. So we must start with an already-created CTIX stand-alone kernel for the MightyFrame.

All "required" files for this below program can be downloaded here.

/install/ctinstall

# Convergent Technologies - System V - Oct 1985
# /install/ctinstall

####################################
# ctinstall
#
# CTIX Installation script for product groups
#
####################################
#
# This Script uses ONLY the following commands, so we move them
# to a safe place (for restartability) (and to get around TXTBUSY)
# in case the installation fails:
#
# /bin/basename
# /bin/cat
# /bin/chmod  (doesn't need saving)
# /bin/cp, ln, mv
# /bin/cpio
# /bin/dd  (mega only)
# /bin/df
# /bin/dirname
# /bin/echo
# /bin/expr
# /bin/grep
# /bin/ls
# /bin/mkdir
# /bin/pwd  (cpio needs)
# /bin/rm
# /bin/sh
# /bin/sync
# /bin/uname
# /bin/who
# /etc/devnm
# /etc/fsck
# /etc/hinv  (miti* only)
# /etc/init  (CORE only)
# /etc/labelit  (CORE only)
# /etc/mount
# /etc/mountable or /etc/rc
# /etc/setmnt
# /etc/umount
# /install/Ins.Core1 (CORE only)
# /install/Ins.Core2 (CORE only)
# /install/Ins.Core4 (CORE only)
# /install/getfopts
# /install/getgrps
# /usr/bin/cut  (CORE only)
# /usr/local/bin/fsize
# /usr/local/bin/qinstall
# /usr/local/bin/qlist
# /usr/local/bin/tsioctl(mini, miti* only)
# /etc/ofcopy  (mega only)
#
# These are in the CORE, so it gets some special attention
#
# Usage ctinstall whence grpname 
#  whence is one of update, install, silent
#  where grpname is one or more of mstr.proto names
#

PATH=:/install:/bin:/usr/bin:/etc:/usr/local/bin; export PATH
REBOOT=false
# allow installation into alternate root
ROOT=${ROOT:-/}

# If we are being called by RawInstall, CTL and DRV are set.
# We default them to 0 and 0 here so Ins.Core4 will get them.
CTL=${CTL:-0}
DRV=${DRV:-0}
export CTL DRV

# following files must be present for successful installation
REQFILES="/bin/basename /bin/cat /bin/chmod /bin/cp /bin/cpio /bin/df /bin/dirname /bin/echo /bin/expr /bin/grep /bin/ln /bin/ls /bin/mkdir /bin/mv /bin/pwd /bin/rm /bin/sh /bin/sync /bin/uname /bin/who /etc/devnm /etc/fsck /etc/mount /etc/setmnt /etc/umount /install/getfopts /install/getgrps /usr/local/bin/fsize /usr/local/bin/qinstall /usr/local/bin/qlist"
MEGAFILES="/etc/ofcopy /bin/dd"
NOTMEGA="/usr/local/bin/tsioctl"
MITIFILES="/etc/hinv"
MINIFILES="/bin/ed /etc/iv"
COREFILES="/etc/init /etc/labelit /install/Ins.Core1 /install/Ins.Core2 /install/Ins.Core4 /usr/bin/cut"
# OK to quit at any time
trap "echo Installation Stopped. Must Start Over To Continue; exit 1;" 1 2 3

GROUPS=""
UGROUPS=""

umask 022
if [ "$1" = "update" -o "$1" = "install" -o "$1" = "silent" ]
then
 WHENCE=$1
 shift
fi
UGROUPS=$*

# assume existence of echo
echo "\n@(#)ctinstall.sh 1.34"

if [ ! -s /etc/mountable  -a  ! -s /etc/rc ]
then
 echo Neither /etc/mountable nor /etc/rc exist.
 echo Need one or the other to determine mountability of /usr.
 echo "Have you mounted /usr if it's a mountable file system?"
 echo "Type yes if it's OK to continue: \c"
 read ans
 if [ "$ans" = "y" ]
 then ans=yes
 fi
 if [ "$ans" != "yes" ]
 then
  echo "\nTerminating Installation."
  exit 98
 fi
fi
# assume existence of mount, grep, rm here
usrflag=1
# determine whether /usr is a mountable file system
# /etc/mountable a convention on Mini's, Mighty's, but not necessarily on Mega's
# (/dev/fp003, /dev/dsk/c0d0s3 or /dev/dpXXX)
# if it is mountable, but it's not mounted, mount it for user
# (because /usr/bin and /usr/local/bin commands are used in this script)
# note: if /usr is mountable but not mounted, devnm will return root device
# don't do all this jazz if installing into alternate ROOT
if [ "$ROOT" = "/" ]
then
if [ -s /etc/mountable ]
then
 # look for "/usr" at end of line -- assume no space after "/usr"
 usr=`grep "/usr$" /etc/mountable`
else
 # assume /usr entry comes before entries like /usr/src
 usr=`grep "mount /dev/.p... /usr" /etc/rc`
fi
usrflag=$?
if [ "$usrflag" = "0" ]
then
 # /usr is a mountable file system
 set - $usr
 # make sure line is not commented out
 if [ "$1" = "mount"  -o  "$1" = "/etc/mount" ]
 then
  USRDEV=$2
  USR=$3
  # is /usr mounted?
  mount > /tmp/mnt$$
  mnt=`grep "^/usr" /tmp/mnt$$`
  if [ $? != 0 ]
  then
   echo "\nMounting /usr."
   mount $USRDEV $USR > /dev/null 2>&1 || { echo "\nCannot mount $USRDEV $USR" ; exit 4; }
  fi
  rm -f /tmp/mnt$$
 fi
 # otherwise line in /etc/rc must be commented out
 # and we'll assume /usr is not mountable
fi
fi

# check for existence of required files
for i in $REQFILES
do
 if [ ! -s $i ]
 then
  echo $i is required for Installation.
  echo Terminating Installation.
  exit 99
 fi
done

if [ ! -d ${ROOT}/install ]
then
 mkdir ${ROOT}/install || { echo "\nCannot mkdir $ROOT/install" ; exit 88; }
fi

# assume existence of uname
machine=`uname -m`
if  [ $machine = mega ]
then
# determine QIC drive # on MegaFrame
 ofcopy '[sys]<sys>configufs.sys' config.ufs
 qic=`grep -i QIC config.ufs`
 err=$?
 if [ $err != 0 ]
 then
  echo "\nQIC device not found in [sys]<sys>configufs.sys."
  echo "Unable to install software from tape without QIC drive configured."
  exit 2
 fi
 set - $qic
 case $3 in
  000) drive=0
  ;;
  001) drive=1
  ;;
  002) drive=2
  ;;
  003) drive=3
  ;;
  *)   echo "\nInvalid QIC drive number in [sys]<sys>configufs.sys."
       echo "Drive number must be in range 000 - 003."
       exit 3
  ;;
 esac
 rm -f config.ufs
 ndrive=/dev/nrmt$drive
 rdrive=/dev/rmt$drive
 BS=512
else
# machine is a MiniFrame or a MightyFrame; QIC is drive 0 by convention
 ndrive=/dev/rmt4
 rdrive=/dev/rmt0
 BS=64k
fi

# now that we know what machine this is, check for existence of other files
case "$machine" in
miti* )
 for i in $MITIFILES
 do
  if [ ! -s $i ]
  then
   echo $i is required for Installation.
   echo Terminating Installation.
   exit 97
  fi
 done
 ;;
mini )
 for i in $MINIFILES
 do
  if [ ! -s $i ]
  then
   echo $i is required for Installation.
   echo Terminating Installation.
   exit 97
  fi
 done
 ;;
mega )
 for i in $MEGAFILES
 do
  if [ ! -s $i ]
  then
   echo $i is required for Installation.
   echo Terminating Installation.
   exit 96
  fi
 done
 ;;
esac
case "$machine" in
mega )
 ;;
* )
 for i in $NOTMEGA
 do
  if [ ! -s $i ]
  then
   echo $i is required for Installation.
   echo Terminating Installation.
   exit 95
  fi
 done
 ;;
esac
set - `devnm ${ROOT}`
ROOTDEV=$1

# get processor type and hardware configuration
# mini and mega are 1sw
PROC=1sw
case "$machine" in
miti* )
 FP=`hinv 68881`
 if [ $? = 0 ]
 then
  PROC=2fp
 else
  PROC=2sw
 fi
 ;;
esac

#############################
# Tape Format
# 0 VHB and Loader
# 1 stand-alone UNIX kernel
# 2 sa file system  (reserved area 1)
# 3 maintenance fs  (reserved area 2)
# 4 for future expansion (reserved area 3)
# 5 install tools cpio archive
# 6 start of Group 0 files
#############################

echo "\nPositioning the Tape for Product Installation."
if [ $machine != mega ]
then
 tsioctl -c rewind $rdrive
 # tsioctl won't tell us if tape not present
 # skip first 5 files on tape
 tsioctl -c skip $ndrive 5
 # now we're at the install tools cpio archive
else
 dd if=$rdrive of=/dev/null bs=$BS count=1 > /dev/null 2>&1
 if [ $? != 0 ]
 then
  echo "Tape not inserted.  Please insert tape and start over."
  exit 38
 fi
 dd if=$ndrive of=/dev/null bs=$BS > /dev/null 2>&1
 dd if=$ndrive of=/dev/null bs=$BS > /dev/null 2>&1
 dd if=$ndrive of=/dev/null bs=$BS > /dev/null 2>&1
 dd if=$ndrive of=/dev/null bs=$BS > /dev/null 2>&1
 dd if=$ndrive of=/dev/null bs=$BS > /dev/null 2>&1
fi

rm -f ${ROOT}/install/DESC ${ROOT}/install/SpecInstall
cd $ROOT || { echo "\nCannot cd to $ROOT" ; exit 5; }
# get product description file off tape
if [ $machine = mega ]
then
 cpio -icdum install/DESC install/SpecInstall < $ndrive > /dev/null 2>&1
else
 cpio -iQcdum install/DESC install/SpecInstall < $ndrive > /dev/null 2>&1
fi
if [ $? != 0 ]
then
 echo "Tape not inserted.  Please insert tape and start over."
 exit 39
fi
cd $ROOT/install || { echo "\nCannot cd to $ROOT/install" ; exit 6; }
l=`ls DESC`
if [ $? != 0 ]
then
 echo "\nNo product description file."
 exit 7
fi
PROD=`grep PRODUCT DESC`
if [ $? = 0 ]
then
 set - $PROD
 shift
 PROD=$*
fi
RELEASESUBR=`grep RELEASE DESC`
if [ $? = 0 ]
then
 set - $RELEASESUBR
 RELEASESUBR=$2
else
 echo Release not available in DESC file.
 # (need below for labelit)
 exit 41
fi

rm -f ${ROOT}/install/restart
prompt="\nUpdate, silent update or new installation of $PROD $RELEASESUBR\n('update', 'silent' or 'install')?: \c"
while [ "$WHENCE" != "update" -a "$WHENCE" != "install" -a "$WHENCE" != "silent" ]
do
 # update or install
 echo $prompt
 read WHENCE
 prompt="Please enter either 'update', 'silent' or 'install':? \c"
done
# We must be in single user state, but don't worry about it
# if we're installing to alternate root
if [ "$ROOT" = "/" ]
then
 if [ -s /etc/utmp ]
 then
  set - `who -r`
  if [ "$3" != "S" ]
  then
   echo "\nYou must be in single user state to run this script."
   echo Type: halt RETURN
   echo Then wait for message: Ok To Stop Or Reset Processor
   echo Then re-mount the disk and re-execute this script.
   exit 8
  fi
  if [ "$LOGNAME" != "root" ]
  then
   echo "\nYou must be root to execute this script."
   exit 9
  fi
 fi
fi

###################################

# make sure file system is sane
echo "\nRunning fsck on root file system."
case "$machine" in
mini )
 echo If there are any problems the system will re-boot.
 echo After the system is back up re-execute /install/ctinstall in single user mode.
 if [ "$WHENCE" = "install" ]
 then
  fsck -b /dev/r$ROOTDEV
 else
  if [ "$ROOTDEV" = "fp001" ]
  then
   fsck /dev/$ROOTDEV
  else
   fsck -b /dev/r$ROOTDEV
  fi
 fi
 ;;
miti* )
 fsck -b /dev/r$ROOTDEV
 ;;
* )
 fsck /dev/$ROOTDEV
 ;;
esac
 
# if /usr is mountable and it's mounted, umount it; fsck it; re-mount it before install
# don't do all this jazz if ROOT is an alternate
if [ "$ROOT" = "/" ]
 then
 if [ "$usrflag" = "0" ]
 then
  # is /usr mounted?
  mount > /tmp/mnt$$
  mnt=`grep "/usr" /tmp/mnt$$`
  if [ $? = 0 ]
  then
   # first turn off accting
   if [ -x /usr/lib/acct/accton ]
   then
    /usr/lib/acct/accton
   fi
   echo "\nUnmounting /usr."
   umount $USRDEV || { echo "\nCannot umount $USRDEV" ; exit 10; }
  fi
  rm -f /tmp/mnt$$
  echo "\nRunning fsck on /usr file system."
  fsck $USRDEV
  # make sure / mounted wrt mnttab
  > /etc/mnttab
  echo "$ROOTDEV /" | setmnt 
  echo "\nRe-mounting /usr."
  mount $USRDEV $USR > /dev/null 2>&1 || { echo "\nCannot mount $USRDEV $USR" ; exit 11; }
 else
  # make sure / mounted wrt mnttab
  > /etc/mnttab
  echo "$ROOTDEV /" | setmnt 
 fi
fi

#############################
# Each product is made up of up to N groups:
# 0         install controlling files for group 0
# 1         (optional) customizable files for group 0
# 2   (optional) optional files for group 0
# 3         actual files of group 0
# 4         install controlling files for group 1
# 5         (optional) customizable files for group 1
# 6   (optional) optional files for group 1
# 7         actual files of group 1
# .
# .
# .
# (N-1)*4+0 install controlling files for group N-1
# (N-1)*4+1 (optional) customizable files for group N-1
# (N-1)*4+2 (optional) optional files for group N-1
# (N-1)*4+3 actual files of group N-1
#
#############################
# install control files <optional> :
# GRPproto proto file for group GRP
# GRP  filelist of required files
# GRP.size size of root-installable files in blocks
# GRP.usize size of /usr-installable files in blocks
# <GRP.cust> filelist of customizable files
# <GRP.noup> filelist of zero-length files
# <GRP.noqu> filelist of potential text busy files
# <GRP.fopt> filelist of optional files
# <GRPid0.lst> filelist of id0 optional files
# <GRPid0.opt> options filter for id0 optional files
# <GRPid0.ins> install script for id0 optional files
# <GRPid1.lst> filelist of id1 optional files
# <GRPid1.opt> options filter for id1 optional files
# <GRPid1.ins> install script for id1 optional files
#      .
#      .
#      .
# <GRPidN.lst> filelist of idN optional files
# <GRPidN.opt> options filter for idN optional files
# <GRPidN.ins> install script for idN optional files

# get user's group choices
if [ "$UGROUPS" = "" ]
then
 . ${ROOT}/install/getgrps
fi

if [ "$UGROUPS" = "" ]
then
 echo "\nNo groups chosen."
 exit 12
fi

# Say basic dangerous things
if [ "$WHENCE" != "install" ]
then
 echo "\nThis procedure will update your filesystem with $PROD $RELEASESUBR group(s)\n\n\t$UGROUPS."
 if [ "$WHENCE" != "silent" ]
 then
 echo "\nBE SURE YOU BACK UP ANYTHING YOU HAVE CHANGED BEFORE PROCEEDING."
 echo "\nType 'yes' to continue: \c"
 read ans
 if [ "$ans" = "y" ]
 then ans=yes
 fi

 if [ "$ans" != "yes" ]
 then
  echo "\nTerminating Installation."
  exit 13
 fi
 fi
else
 echo "\nThis procedure will install the following $PROD $RELEASESUBR group(s) on your system:"
 echo "\n\t$UGROUPS"
fi

echo "\nStarting to Install Group(s) $UGROUPS."
# main loop for groups
while [ 1 = 1 ]
do

cd $ROOT/install || { echo "\nCannot cd to $ROOT/install" ; exit 66; }
for f in $UGROUPS
do
 # remove file lists
 rm -f $f
done
# remove any other old, extraneous installation control files
rm -f *.cust *.fopt *.opt *.ins *.lst *.flst *proto *.size *.usize *.noqu *.noup
# don't let user stop
trap "" 2

# get proto file and file lists
if [ $machine = mega ]
then
 cpio -icum < $ndrive > /dev/null 2>&1 || { echo Cannot extract group control files; exit 14; }
else
 cpio -iQcum < $ndrive > /dev/null 2>&1 || { echo Cannot extract group control files; exit 14; }
fi

# get current group and reconstruct groups list without current group
GRP=""
NGROUPS=""
for f in $UGROUPS
do
 if [ -s $f ]
 then
  GRP=$f
 else
  NGROUPS="$f $NGROUPS"
 fi
done
UGROUPS=$NGROUPS

if [ "$GRP" = "" ]
then
 GRP=`basename *proto proto`
 if [ "$GRP" = "" ]
 then
  echo "No group proto file extracted"
  exit 15
 fi
 # skip over whatever group came off the tape
 if [ -r "$GRP.cust" ]
 then
  echo "Skipping group $GRP customizable files."
  if [ "$machine" = "mega" ]
  then
   dd if=$ndrive of=/dev/null bs=$BS > /dev/null 2>&1
  else
   tsioctl -c skip $ndrive
  fi
 fi
 if [ -r "$GRP.fopt" ]
 then
  echo "Skipping group $GRP optional files."
  if [ "$machine" = "mega" ]
  then
   dd if=$ndrive of=/dev/null bs=$BS > /dev/null 2>&1
  else
   tsioctl -c skip $ndrive
  fi
 fi
 echo "Skipping group $GRP required files."
 if [ "$machine" != "mega" ]
 then
  tsioctl -c skip $ndrive
 else
  dd if=$ndrive of=/dev/null bs=$BS > /dev/null 2>&1
 fi
 # remove install control files for skipped group
 rm -f $GRP $GRP.cust $GRP.fopt $GRP.opt $GRP.ins $GRP.lst $GRP.flst ${GRP}proto $GRP.size $GRP.usize $GRP.noqu $GRP.noup
 continue
fi

echo "Installing Group $GRP."
# $GRP.size -- total installation size; $GRP.usize -- /usr files size only
if [ -s $GRP.size ]
then
 echo "\nCalculating size required for group $GRP."
 # see if enough room for the files in this archive
 # set how much current files take
 CSZ=0
 cd $ROOT || { echo "\nCannot cd to $ROOT" ; exit 16; }
 rm -f /tmp/usr.$$
 for i in ${ROOT}/install/$GRP ${ROOT}/install/$GRP.cust ${ROOT}/install/$GRP.noqu
 do
  if [ -s $i ]
  then
   CTMP=`cat $i | fsize`
   CSZ=`expr $CSZ + $CTMP`
   grep "^\./usr" $i >> /tmp/usr.$$
  fi
 done
 
 if [ "$GRP" = "CORE" ]
 then
  for i in $COREFILES
  do
   if [ ! -s $i ]
   then
    echo $i is required for Installation.
    echo Terminating Installation.
    exit 94
   fi
  done
  # remove unused files
  . ${ROOT}/install/Ins.Core1
 fi

 # set current blks free on root
 set - `df /dev/$ROOTDEV`
 RFREE=$4
 # V vs V.2 botch
 if [ "$RFREE" = "blocks" ]
 then
  # system V
  RFREE=$3
 fi
 # set current blks free on usr if a mountable file system
 if [ "$usrflag" = "0" ]
 then
  USZ=`cat /tmp/usr.$$ | fsize`
  rm -f /tmp/usr.$$
  set - `df /usr`
  UFREE=$4
  if [ "$UFREE" = "blocks" ]
  then
   # system V
   UFREE=$3
  fi
  # root blks in use = total blks - usr blks
  CSZ=`expr $CSZ \- $USZ`
 fi
 RNEED=`cat ${ROOT}/install/$GRP.size`
 UNEED=`cat ${ROOT}/install/$GRP.usize`
 if [ "$RNEED" != "" ]
 then
  if [ "$usrflag" = "0" ]
  then
   RNEED=`expr $RNEED \- $UNEED`
  fi
  # leave some fudge
  CSZ=`expr $RFREE \- $RNEED \+ $CSZ`
  if [ "$CSZ" -lt "300" ]
  then
   echo "Not enough room on root '/' for this group."
   echo "Of $RFREE 512 Byte Blocks, only $CSZ would remain."
   echo "Proceed at your own risk."
   echo "Do you wish to proceed? \c"
   read line
   if [ "$line" = "y" ]
   then line=yes
   fi
   if [ "$line" != "yes" ]
   then
   echo Aborting Installation.
   echo "Type /install/restart to restart after more space is available."
   echo "exec /install/ctinstall $WHENCE $GRP $UGROUPS" >/install/restart
   chmod +x /install/restart
   # remove install stuff
   cd $ROOT/install || { echo "\nCannot cd to $ROOT/install" ; exit 18; }
   rm -f $GRP $GRP.cust $GRP.fopt $GRP.opt $GRP.ins $GRP.lst $GRP.flst ${GRP}proto $GRP.size $GRP.usize $GRP.noqu $GRP.noup
   rm -rf custom
   rm -f DESC SpecInstall qlist qinstall
   if [ "$REBOOT" = "true" ]
   then
    cd $ROOT || { echo "\nCannot cd to $ROOT" ; exit 37; }
    sync;sync
    echo "Remove the Tape and press return: \c"
    read ans
    sync;sync;reboot
   fi
   exit 19
   fi
  else
   if [ "$CSZ" -gt "$RFREE" ]
   then
       RNEED="free up `expr $CSZ - $RFREE`"
   else
       RNEED="require an additional `expr $RFREE - $CSZ`" 
   fi
   echo "Installation will $RNEED root Blocks (512 Byte Blocks)."
   echo "(Currently $RFREE 512 Byte blocks are available on root.)"
  fi
 fi
if [ "$usrflag" = "0" ]
then
 if [ "$UNEED" != "" ]
 then
  # leave some fudge
  USZ=`expr $UFREE \- $UNEED \+ $USZ`
  if [ "$USZ" -lt "300" ]
  then
   echo "Not enough room on /usr for this group."
   echo "Of $UFREE 512 Byte Blocks, only $USZ would remain."
   echo Aborting Installation.
   echo "Type /install/restart to restart after more space is available."
   echo "exec /install/ctinstall $WHENCE $GRP $UGROUPS" >/install/restart
   chmod +x /install/restart
   # remove install stuff
   cd $ROOT/install || { echo "\nCannot cd to $ROOT/install" ; exit 20; }
   rm -f $GRP $GRP.cust $GRP.fopt $GRP.opt $GRP.ins $GRP.lst $GRP.flst ${GRP}proto $GRP.size $GRP.usize $GRP.noqu $GRP.noup
   rm -rf custom
   rm -f DESC SpecInstall qlist qinstall
   if [ "$REBOOT" = "true" ]
   then
    cd $ROOT || { echo "\nCannot cd to $ROOT" ; exit 37; }
    sync;sync
    echo "Remove the Tape and press return: \c"
    read ans
    sync;sync;reboot
   fi
   exit 21
  else
   if [ "$USZ" -gt "$UFREE" ]
   then
       UNEED="free up `expr $USZ - $UFREE`"
   else
       UNEED="require an additional `expr $UFREE - $USZ`" 
   fi
   echo "Installation will $UNEED /usr Blocks (512 Byte Blocks)."
   echo "(Currently $UFREE 512 Byte blocks are available on /usr.)"
  fi
 fi
fi
else
 echo "\nCannot determine whether enough room on root file system."
 echo "Proceed at your own risk."
 echo "Do you wish to proceed? \c"
 read line
 if [ "$line" = "y" ]
 then line=yes
 fi
 if [ "$line" != "yes" ]
 then
  # remove install stuff
  cd $ROOT/install || { echo "\nCannot cd to $ROOT/install" ; exit 22; }
  rm -f $GRP $GRP.cust $GRP.fopt $GRP.opt $GRP.ins $GRP.lst $GRP.flst ${GRP}proto $GRP.size $GRP.usize $GRP.noqu $GRP.noup
  rm -rf custom
  rm -f DESC SpecInstall qlist qinstall
  echo "Installation Aborted."
  if [ "$REBOOT" = "true" ]
  then
   cd $ROOT || { echo "\nCannot cd to $ROOT" ; exit 37; }
   sync;sync
   echo "Remove the Tape and press return: \c"
   read ans
   sync;sync;reboot
  fi
  exit 23
 fi
fi
cd $ROOT/install || { echo "\nCannot cd to $ROOT/install" ; exit 24; }

if [ "$GRP" = "CORE" ]
then
 . ${ROOT}/install/Ins.Core2
fi

# pull off the customizable files first
cd $ROOT/install || { echo "\nCannot cd to $ROOT/install" ; exit 25; }
if [ -s $GRP.cust ]
then
 if [ ! -d ${ROOT}/install/custom ]
 then
  mkdir ${ROOT}/install/custom 
 fi
 echo "\nReading Customizable $GRP files."
 # place customizable files in flat space under ${ROOT}/install/custom
 cd $ROOT/install/custom || { echo "\nCannot cd to $ROOT/install/custom" ; exit 26; }
 if [ $machine = mega ]
 then
  cpio -ivcum < $ndrive > /dev/null 2>&1
 else
  cpio -ivQcum < $ndrive > /dev/null 2>&1
 fi
 cd $ROOT/install || { echo "\nCannot cd to $ROOT/install" ; exit 27; }
 NQ=""
 for i in `cat $GRP.cust`
 do
  NQ="$NQ ${ROOT}/install/custom/`basename $i` $i"
 done
 echo "Installing Customizable $GRP files."
 if [ "$WHENCE" = "update" ]
 then
  # query
  qinstall -rVq ${ROOT}/install/${GRP}proto ${ROOT} $NQ || { echo "qinstall failed"; exit 28; }
 else
  # save and replace, no query on silent and raw installs
  qinstall -rV ${ROOT}/install/${GRP}proto ${ROOT} $NQ || { echo "qinstall failed"; exit 40; }
 fi
 rm -rf ${ROOT}/install/custom/*
 sync
 echo "\n$GRP Customizable files installed."
fi

# second, pull off the optional files
cd $ROOT/install || { echo "\nCannot cd to $ROOT/install" ; exit 29; }
if [ -s $GRP.fopt ]
then
 # getfopts uses $PROC
 . getfopts
 sync
fi


# start cpio of required group files - Remember disk is gone after cpio is done
# let user retry
cd $ROOT || { echo "\nCannot cd to $ROOT" ; exit 30; }
ERR=0
RV=1
trap "ERR=1" 2
while [ $RV != 0 ]
do
 # NOTE: cpio needs pwd
 echo "\nInstalling required $GRP files."
 if [ $machine = mega ]
 then
  cpio -ivcdum < $ndrive 2> /dev/null
 else
  cpio -ivQcdum < $ndrive 2> /dev/null
 fi
 RV=$?

 if [ $ERR = 1 -o $RV != 0 ]
 then
  echo "Cpio Stopped: Type 'yes' to continue with next: \c"
  read line
  if [ "$line" = "y" ]
  then line=yes
  fi
  if [ "$line" != "yes" ]
  then
   echo Aborting Installation.
   echo "Type /install/restart to restart after more space is available."
   echo "exec /install/ctinstall $WHENCE $GRP $UGROUPS" >/install/restart
   chmod +x /install/restart
   # remove install stuff
   cd $ROOT/install || { echo "\nCannot cd to $ROOT/install" ; exit 31; }
   rm -f $GRP $GRP.cust $GRP.fopt $GRP.opt $GRP.ins $GRP.lst $GRP.flst ${GRP}proto $GRP.size $GRP.usize $GRP.noqu $GRP.noup
   rm -rf custom
   rm -f DESC SpecInstall qlist qinstall
   if [ "$GRP" = "CORE" ]
   then
    echo "Restoring previous commands."
    eval $RESTORE
   fi
   exit 32
  fi
 fi
done

sync

# don't let user interfere
trap "" 1 2 3

# if install, make zero length files
if [ $WHENCE = install -a -f ${ROOT}/install/$GRP.noup ]
then
 echo "Creating 0 length files."
 for i in `cat ${ROOT}/install/$GRP.noup`
 do
  # create list of directory components
  ndir=$i
  dirlist=""
  while [ 1 = 1 ]
  do
   ndir=`dirname $ndir`
#   echo $ndir
   if [ "$ndir" = "."  -o  "$ndir" = "/"  -o  "$ndir" = "./" ]
   then
    break
   fi
   bdir=`basename $ndir`
   dirlist="$bdir $dirlist"
  done
#  echo $dirlist
  for d in $dirlist
  do
   ndir=$ndir/$d
   if [ ! -d $ndir ]
   then
    mkdir $ndir || { echo "\nCannot mkdir $ndir" ; }
   fi
  done
  >/$i
 done
 sync
fi

# Check permissions
echo "\nChecking permissions, modes and omissions on new $GRP commands."
qlist -s ${ROOT}/install/${GRP}proto / 1>/dev/null 2>&1
if [ "$usrflag" = "0" ]
then
 # check mounted file systems, too
 qinstall -csm ${ROOT}/install/${GRP}proto /
else
 # don't check mounted file systems
 qinstall -cs ${ROOT}/install/${GRP}proto /
fi

# remove saved files
if [ "$machine" != mini ]
then
 PATH=:/bin:/usr/bin:/etc:/usr/local/bin ; export PATH
fi

# OK to stop
trap 1 2 3

# Done!!
cd ${ROOT}/install || { echo "\nCannot cd to $ROOT/install" ; exit 55; }
rm -f $GRP $GRP.cust $GRP.fopt $GRP.opt $GRP.ins $GRP.lst $GRP.flst ${GRP}proto $GRP.size $GRP.usize $GRP.noqu $GRP.noup
cd $ROOT || { echo "\nCannot cd to $ROOT" ; exit 77; }
echo "Completed Installation of Group $GRP."

# iv stuff
if [ "$GRP" = "CORE" ]
then
 . ${ROOT}/install/Ins.Core4
fi

if [ "$UGROUPS" = "" ]
then
 break
else
 echo "\nContinuing with $UGROUPS ..."
fi

# end group loop
done

# finish up

if [ -s ${ROOT}/install/SpecInstall ]
then
 ${ROOT}/install/SpecInstall
 rm -f ${ROOT}/install/SpecInstall
fi
sync
echo "Rewinding tape."
if [ $machine != mega ]
then
 tsioctl -c rewind $rdrive
else
 dd if=$rdrive of=/dev/null bs=$BS count=1 > /dev/null 2>&1
fi
# clean up files common to all groups
rm -f $ROOT/install/DESC $ROOT/install/SpecInstall $ROOT/install/qlist $ROOT/install/qinstall
rm -rf $ROOT/install/custom
echo "\nInstallation Complete."
if [ "$REBOOT" = "true" ]
then
 if [ "$machine" = mini ]
 then
  cd $ROOT || { echo "\nCannot cd to $ROOT" ; exit 37; }
  cp $ROOT/install/bin/sync $ROOT/install
  cp $ROOT/install/bin/rm $ROOT/install
  $ROOT/install/rm -rf $ROOT/install/bin
  $ROOT/install/sync;
  $ROOT/install/sync
  echo " Remove the Tape and press RESET."
  $ROOT/install/rm  -f $ROOT/install/sync $ROOT/install/Ins* 
  $ROOT/install/rm -f $ROOT/install/cpio
  $ROOT/install/sync;
  $ROOT/install/sync
  while : ; do : ; done
 else
  sync; sync
  echo "Remove the tape and press return (the system will reboot): \c"
  read line
  reboot
 fi
fi
exit 0


----------------------------------------------------------------

Here is a 1988 publication about hacking the 68020 unix kernel
http://bit.ly/1u89hBK

----------------------------------------------------------------

Jobs posted twice on oDesk