#! /bin/sh

# /etc/rc for MacMach BSD 4.3

# See /etc/rc.network for network startup.
# See /etc/rc.afs and /etc/rc.nfs for fileserver startup.
# See /etc/rc.local for local daemons.
# Look in /etc/newconfig for saved configuration files.

# This script conditions the system before it enters multi-user mode.
# If /install exists, the installation procedure is run instead.
#   1) check file systems (if "/fastboot" does not exist)
#   2) recover passwd file if needed
#   2) start up network (/etc/rc.network)
#   3) mount local and remote file systems
#   4) check quotas
#   5) save log files (copy * to *.old)
#   6) clear out temporary directories
#   7) reset modes for pty devices
#   8) start up daemons (syslogd, update, cron, /etc/rc.local)
# The output from stdout and stderr is sent to the console.  The AUTOBOOT flag
# is set by the argument "autoboot".  This is a signal from /etc/init that an
# operator is not present during the boot.   During AUTOBOOT, if an error is
# encountered, /etc/rc will exit with a value of 1 to signal /etc/init to
# restart.  Otherwise, the operator is given the chance to ignore the error
# and continue.  The operator also has the option of entering a shell to fix
# the problem.  When AUTOBOOT is not set, the operator is given the option of
# skipping the initial file system check.  The network access is started by
# the /etc/rc.network script.  When all tasks have completed, /etc/rc exits
# with a value of 0 to signal /etc/init to enter multi-user mode.  When the
# AUTOBOOT flag is not set, the file "/etc/nologin" is created to prevent
# user logins.

# NOTE: all servers and daemons are given /dev/null for their stdin

# initial environment, /etc/init provides none
# assume that /bin and /etc exist in the root partition
HOME="/"; export HOME
PATH="/bin:/etc"; export PATH

# /etc/init will call /etc/rc with or without the argument "autoboot"
# other arguments are ignored
# if not AUTOBOOT, assume manual boot from single-user state
AUTOBOOT="$1"; [ "$AUTOBOOT" = "autoboot" ] || AUTOBOOT=""
export AUTOBOOT

# if no console, quietly give up
[ -f /dev/console ] reboot -h

# /etc/init sets up stdin, stdout and stderr as "/", read-only
# make stdin, stdout and stderr be /dev/console
exec </dev/console >/dev/console 2>&1

# this message is displayed when impossible errors happen
WIZARD="This should not happen, call a Wizard!"
export WIZARD

# this "function" is used for boot-time errors
# if not AUTOBOOT, solicit shell command
# if exit non-zero, /etc/init will restart
RESTART='
  test "$AUTOBOOT" && { echo "autoboot: failed"; exit 1; };
  echo "enter a shell command, exit 0 to continue, exit 1 to restart";
  echo -n "# ";
  sh -t </dev/console || { echo "restarting..."; sleep 10; exit 1; };
  echo "";
  echo "continuing..."
'

# if /install exists, do installation procedure then reboot
[ -f /install ] && {
  newsys ramdisk "" "" "" "" /mnt || halt
  reboot
}

# announce /etc/rc entry
echo ""
[ "$AUTOBOOT" ] && echo "/etc/rc: $AUTOBOOT"

# if AUTOBOOT, do "fsck -p"
CHECK="$AUTOBOOT"
FASTBOOT="/fastboot"
WARNING="WARNING: Non-fsck'ed file systems can cause kernel panic's."
if [ "$CHECK" -a -f $FASTBOOT ]; then
  echo -n "fastboot: "
  CHECK=""
elif [ ! "$CHECK" ]; then
  echo "$WARNING"
  echo -n "check file systems? (y/n) "
  read X; if [ "$X" = "Y" -o "$X" = "y" ]; then CHECK="$X"; fi
fi
rm -f $FASTBOOT
if [ "$CHECK" ]; then
  echo "checking file systems:"
  cat /etc/fstab | while read X; do echo "  $X"; done
  fsck -p
  case $? in
    0) echo "file systems ok"
      ;;
    2) sleep 10
      exit 1
      ;;
    4) echo "NOTE: root fixed, rebooting (no sync)"
      sleep 10
      /etc/reboot -q -n
      ;;
    8) echo "ERROR: \"fsck -p\" failed"
      echo "$WIZARD"
      eval "$RESTART"
      ;;
    12) echo "ERROR: \"fsck -p\" interrupted"
      echo "$WARNING"
      echo "You should reboot and start over."
      eval "$RESTART"
      ;;
    *) echo "ERROR: \"fsck -p\" returned \"$?\""
      echo "$WIZARD"
      eval "$RESTART"
      ;;
  esac
else
  echo "skipping file system check"
  echo "$WARNING"
fi

# recover passwd file if needed
if [ -s /etc/ptmp ]; then
  if [ -s /etc/passwd ]; then
    ls -l /etc/passwd /etc/ptmp
    rm -f /etc/ptmp # should really remove the shorter
  else
    echo "passwd file recovered from ptmp"
    mv /etc/ptmp /etc/passwd
  fi
elif [ -r /etc/ptmp ]; then
  echo "removing passwd lock file"
  rm -f /etc/ptmp
fi

# startup local and external network
. /etc/rc.network

# mount local and remote file systems
echo "mounting file systems"
umount -a >/dev/null 2>&1
mount -a || {
  echo "ERROR: \"mount -a\" failed";
  echo "$WIZARD";
  eval "$RESTART";
}
df

# set swapping preferences
# "/etc/swapon" specified because of bug in mach-swapon *sigh*
/etc/swapon /usr/pagingfile

# if external network, start up NFS
[ "$NETNAME" -a -r /etc/rc.nfs ] && . /etc/rc.nfs

# if external network, start up AFS
[ "$NETNAME" -a -r /etc/rc.afs ] && . /etc/rc.afs

# full PATH now that all file systems are mounted
PATH=/bin:/etc:/usr/ucb:/usr/bin ; export PATH

# check quotas
echo -n "checking quotas:"
quotacheck -a -p
echo " done."
quotaon -a

# save old log files
echo "saving /usr/adm/syslog.log"
mv /usr/adm/syslog.log /usr/adm/syslog.log.old
cp /dev/null /usr/adm/syslog.log
echo "saving /usr/adm/messages"
mv /usr/adm/messages /usr/adm/messages.old
cp /dev/null /usr/adm/messages

# preserve editory files
echo "preserving editor files"
(cd /tmp; /usr/lib/ex3.7preserve -a)

# clear temporary directories
echo "clearing /tmp"
(cd /tmp; find . ! -name . ! -name lost+found ! -name quotas -exec rm -rf {} \; )
echo "clearing /usr/tmp"
(cd /usr/tmp; rm -rf *)
echo "clearing /usr/spool/at/past"
(cd /usr/spool/at/past; rm -f *)
echo "clearing /usr/spool/uucp/LCK.* /usr/spool/uucp/STST/*"
(cd /usr/spool/uucp; rm -f LCK.* STST/*)

# reset modes for pty devices
echo "resetting modes for pty devices"
chmod 666 /dev/tty[pqrs]*

# start up daemons, stdin is /dev/null, stdout and stderr are console
echo -n "standard daemons:"
rm -f /dev/log; syslogd </dev/null & echo -n " syslogd"
update </dev/null & echo -n " update"
cron </dev/null & echo -n " cron"
echo ""

# Start up the mach daemons.
if [ -f /etc/mach_init ]; then
  echo "mach daemons: netmsgserver envmgr ipcexecd netmemoryserver"
  /etc/netmsgserver </dev/null >/dev/null 2>&1 &
  /etc/envmgr </dev/null >/dev/null 2>&1 &
  /etc/ipcexecd </dev/null >/dev/null 2>&1 &
  /etc/netmemoryserver </dev/null >/dev/null 2>&1 &
fi

# startup local daemons -- ignore any failures here
[ -r /etc/rc.local ] && sh /etc/rc.local </dev/null

# allow logins only if AUTOBOOT
NOLOGIN="/etc/nologin"
if [ "$AUTOBOOT" ]; then
  echo "allowing user logins..."
  rm -f $NOLOGIN
else
  echo "WARNING: allowing root logins only"
  echo "Remove $NOLOGIN to allow user logins."
  echo "SYSTEM IS SINGLE USER" > $NOLOGIN
  date >> $NOLOGIN
fi

# normal exit
# /etc/init will now enter multi-user mode
exit 0
