#!/etc/sys_sh
# `node_data/etc/rc

# Suitable for DOMAIN/OS versions SR10.0, 10.1, 10.2, 10.3 or 10.4
# Modified by Paul Szabo, 5 Apr 94

# Includes rc.local and rc.user, do not run separately.
# Use in conjunction with `node_data/etc/daemons/README.
#
# Generally, there is no need to edit this file (except for
# the yearly change of TZ).
# To start a daemon, create a file of the same name
# in /etc/daemons, as directed by /etc/daemons/README.
#
# This script is run by /etc/init during node startup,
# with identity root.wheel.none.
# Any daemons that should NOT run as root.wheel.none
# should be setuid,setgid to the appropriate person.group.
#
# Will write log file /usr/adm/rc.log.
#
# The setting of the SYSTYPE variable for this script
# is determined by the contents of /etc/environ.

# echo commands are parenthesized so that they will be run
# in a subprocess since echo is builtin to the shell. Otherwise
# the shell running this script and all the programs started
# from it would acquire /dev/console as their controlling tty.

# Note on exported variables:
# Only PATH, TZ, TZNAME and NODEID are exported from this script.
# These may be useful for commands started.
# Luckily, sub-shells (those in parentheses) either inherit
# non-exported variables, or parameter references are expanded
# as the commands are scanned by this shell.
# (Hopefully SYSTYPE, ISP, USER, LOGNAME, PROJECT, ORGANIZATION,
# TERM and NODETYPE are already in the environment.)


# May be used to (re-)start single daemons.
# Use the name of a daemon (as used in /etc/daemons) as first
# (and only) argument to re-start that one daemon, e.g.
#   /etc/rc  spm
# (assuming that the appropriate files are in /etc/daemons).
# Unwanted environment variables will be unset.


#---------------------------------------------------------------


# Set RESTART to 'boot', or the name of the daemon to restart.
# Normally $1 is 'autoboot', but could it be 'reboot' or 'system boot'?
# Is /etc/rc ever invoked (from /etc/init) without any arguments?
case "$1" in
  *boot* | *system* )
    RESTART=boot
  ;;
  * )
    if [ $# -eq 1 ]; then
      RESTART="$1"
    else
      echo "No daemon to restart? Arguments are <$*>"
      exit 1
    fi
    # Unset unwanted (environment) variables
    OLDIFS="$IFS"
    IFS='
'
    for v in `set`; do
      IFS="$OLDIFS="
      set -- $v
      case "$1" in
        RESTART | OLDIFS | v ) dummy=keep;;
        IFS | MAILCHECK | PATH | PS1 | PS2 ) dummy=cannot;;
        SYSTYPE | ISP | USER | LOGNAME | PROJECT | ORGANIZATION | TERM | NODEID | NODETYPE ) dummy=want;;
        * ) unset $1;;
      esac
    done
    IFS="$OLDIFS"
  ;;
esac


#---------------------------------------------------------------


# Copyright notice
# if [ -f /etc/copyright ]; then
#   if [ -f /bin/cat ]; then
#     (/bin/cat  /etc/copyright >/dev/console)
#   elif [ -f /com/catf ]; then
#     (/com/catf /etc/copyright >/dev/console)
#   fi
# fi
if [ "$RESTART" = boot ]; then
  (echo "\n... Copyright ...\n" >/dev/console)
fi


#---------------------------------------------------------------


# Set proper environment.


HOME=/
PATH=/bin
export PATH
cd /


# Set suitable umask
umask 0027


# Timezone
# We could read this from somewhere (/etc/timezone ?) instead
# of hard-coding it here. How many files do you want to maintain?
# TZ=EST-10; export TZ
# TZNAME=AEST; export TZNAME
# GMT-10 is standard (winter), GMT-11 for daylight saving (summer).
# GMT is safer, but EST (EDT) is for SYS5.3.
# AEST standard (winter), AEDT daylight saving (summer) for BSD4.3.
# Aegis (including lcnode) is as set by CALENDAR (or /com/tz).
# The fancy TZ below works. (Look in 'ver sys5 man timezone', i.e. file
# /sys5.3/usr/catman/p_man/man4/timezone.4 . Why does it work for BSD?)
# From SR10.3 (and maybe later versions of 10.2) we should be able to
# use Mmonth.week.dayofweek arguments instead of Julian dates, e.g.
# AEDT-11:00:00AEST-10:00:00;M3.1.0/2:00:00,M10.5.0/2:00:00 (standard
# POSIX notation, look in a POSIX or maybe an X/Open manual: sunday=0,
# week 5 means last dayofweek in that month).
# 1990: TZ='AEDT-11:00:00AEST-10:00:00;63/2:00:00,301/2:00:00'
# 1991: TZ='AEDT-11:00:00AEST-10:00:00;62/2:00:00,300/2:00:00'
# 1992: TZ='AEDT-11:00:00AEST-10:00:00;61/2:00:00,299/2:00:00'
# 1993: TZ='AEDT-11:00:00AEST-10:00:00;66/2:00:00,304/2:00:00'
TZ='AEDT-11:00:00AEST-10:00:00;66/2:00:00,304/2:00:00'
export TZ
TZNAME=
if [ -f /sys5.3/bin/date ]; then
  TZNAME=`(/sys5.3/bin/date +%ZT)`
fi
if [ -z "$TZNAME" ]; then
  TZNAME=AEXT
fi
export TZNAME

if [ -f /usr/apollo/bin/tz ]; then
  if [ "$TZNAME" = AEDT ]; then
    /usr/apollo/bin/tz 11:00 AEDT
  else
    /usr/apollo/bin/tz 10:00 AEST
  fi
fi


# Set up name and ID of node and name of disk

# Domain/OS name, with slashes and maybe trailing blanks.
# (We cannot use /etc/hostname, in case we restart lpd)
NODENAME=
if [ -f /etc/lcnode ]; then
  if [ -f /com/chpat ]; then
    NODENAME=`(/etc/lcnode -brief -name -maxnodes 1 | /com/chpat '[/ ]')`
  elif [ -f /usr/bin/tr ]; then
    NODENAME=`(/etc/lcnode -brief -name -maxnodes 1 | /usr/bin/tr -d '/ ')`
  elif [ -f /bin/tr ]; then
    NODENAME=`(/etc/lcnode -brief -name -maxnodes 1 | /bin/tr -d '/ ')`
  else
    NODENAME=`(/etc/lcnode -brief -name -maxnodes 1)`
  fi
fi
if [ -z "$NODENAME" ]; then
  NODENAME=Unknown
fi

if [ -z "$NODEID" ]; then
# Already set up at SR10.2
  if [ -f /etc/lcnode ]; then
    NODEID=`(/etc/lcnode -me -brief)`
  fi
  if [ -z "$NODEID" ]; then
    NODEID=Unknown
  fi
fi
export NODEID

DISKNAME=`pwd`
if [ -z "$DISKNAME" ]; then
  DISKNAME=//
fi


# Figure out date
DATE=
if [ -f /bin/date ]; then
  DATE=`(/bin/date)`
elif [ -f /com/date ]; then
  DATE=`(/com/date)`
fi
if [ -z "$DATE" ]; then
  DATE="(date unknown)"
fi
DATE="Started on $DATE"


#zzz Could set up all sorts of things by something like
# ( /usr/apollo/bin/bldt | { read lin; read st1 nod NET_NODE st2 NAM lin; read dos ker rev VER lin; echo "Net.node_ID: $NET"; echo "Name: $NAM"; echo "Version: $VER"; } )
# In particular, we could have
# VERSION=`( /usr/apollo/bin/bldt | { read lin; read lin; read dos ker rev VER lin; echo "$VER"; } )`



# Set up names of `node_data trees
TREES=OK

ND_=`(cd \\\`node_data 2>/dev/null; pwd)`
if [ -z "$ND_" -o "$ND_" = "$DISKNAME" ]; then
  if [ "$RESTART" = boot ]; then
    (echo "Directory \`node_data does not exist ???" >/dev/console)
  else
    echo "Directory \`node_data does not exist ???"
  fi
  ND_=/
  TREES=wrong
fi

ND_E=`(cd $ND_/etc 2>/dev/null; pwd)`
if [ -z "$ND_E" -o "$ND_E" = "$DISKNAME" ]; then
  if [ "$RESTART" = boot ]; then
    (echo "Directory \`node_data/etc does not exist ???" >/dev/console)
  else
    echo "Directory \`node_data/etc does not exist ???"
  fi
  ND_E=/
  TREES=wrong
fi

ND_ED=`(cd $ND_E/daemons 2>/dev/null; pwd)`
if [ -z "$ND_ED" -o "$ND_ED" = "$DISKNAME" ]; then
  if [ "$RESTART" = boot ]; then
    (echo "Directory \`node_data/etc/daemons does not exist ???" >/dev/console)
  else
    echo "Directory \`node_data/etc/daemons does not exist ???"
  fi
  ND_ED=/
  TREES=wrong
fi

ND_S=`(cd $ND_/system_logs 2>/dev/null; pwd)`
if [ -z "$ND_S" -o "$ND_S" = "$DISKNAME" ]; then
  if [ "$RESTART" = boot ]; then
    (echo "Directory \`node_data/system_logs does not exist ???" >/dev/console)
  else
    echo "Directory \`node_data/system_logs does not exist ???"
  fi
  ND_S=/
  TREES=wrong
fi


#---------------------------------------------------------------


# Utility functions.

# Does /etc/sys_sh really accept FUNCTIONs?
# /bsd4.3/bin/sh does not, but /sys5.3/bin/sh does.

set -h


# Write string $1 to console,
# to log file rc.log, and also to log file $2 if set.
if [ "$RESTART" = boot ]; then
  WRITE ()
  {
  (echo "$1" >/dev/console)
  (echo "$1" >>$ND_S/rc.log)
  if [ -n "$2" ]; then
    (echo "$1" >>$2)
  fi
  }
else
  WRITE ()
  {
  echo "$1"
  (echo "$1" >>$ND_S/rc.log)
  if [ -n "$2" ]; then
    (echo "$1" >>$2)
  fi
  }
fi


# Delete file or link or directory $1
# If $2 is "wild" then use $1*
if [ -f /com/dll -a -f /com/dlt ]; then
  DLT ()
  {
  wild=
  if [ "$2" = wild ]; then
    wild="?*"
  fi
  # /com/dlt does not delete links, but object pointed to! Do dll first.
  WRITE "Removing $1$wild"
  /com/dll "$1$wild" -nq
  /com/dlt "$1$wild" -nq
  }
elif [ -f /bin/rm ]; then
  # Just a * does not match initial dots, e.g. in /tmp/*;
  # but /tmp/.* would remove /tmp/.. !!
  DLT ()
  {
  wild=
  if [ "$2" = wild ]; then
    wild="*"
  fi
  WRITE "Removing $1$wild"
  /bin/rm -r -f - $1$wild
  }
else
  DLT ()
  {
  wild=
  if [ "$2" = wild ]; then
    wild="*"
  fi
  WRITE "Cannot remove $1$wild:"
  WRITE "  neither /bin/rm nor /com/dll, dlt are available."
  }
fi


# Delete file(s).
DLF ()
  {
  while [ $# -gt 0 ]; do
    FILE="$1"
    shift
    if [ -z "$FILE" ]; then continue; fi
    if [ -f "$FILE" ]; then
      DLT "$FILE"
    elif [ -d "$FILE" ]; then
      WRITE "Object $FILE is a directory (not deleted)"
    fi
  done
  }


# Delete directory(ies).
DLD ()
  {
  while [ $# -gt 0 ]; do
    FILE="$1"
    shift
    if [ -z "$FILE" ]; then continue; fi
    if [ -d "$FILE" ]; then
      DLT "$FILE"
    elif [ -f "$FILE" ]; then
      WRITE "Object $FILE is a file (not deleted)"
    fi
  done
  }


# Sub-function used by CRF.
if [ -f /com/crf ]; then
  CRFW ()
  {
  WRITE "Creating file $1"
  /com/crf "$1"
  }
elif [ -f /usr/bin/touch ]; then
  CRFW ()
  {
  WRITE "Creating file $1"
  /usr/bin/touch "$1"
  }
elif [ -f /bin/touch ]; then
  CRFW ()
  {
  WRITE "Creating file $1"
  /bin/touch "$1"
  }
else
  CRFW ()
  {
  WRITE "Cannot create file $1:"
  WRITE "  neither /usr/bin/touch, /bin/touch nor /com/crf are available."
  }
fi


# Create file(s) $1, $2, ... (if do not already exist).
CRF ()
  {
  while [ $# -gt 0 ]; do
    FILE="$1"
    shift
    if [ -z "$FILE" ]; then continue; fi
    if [ -f "$FILE" ]; then continue; fi
    if [ -d "$FILE" ]; then
      WRITE "Object $FILE is a directory, not a file"
      continue
    fi
    CRFW "$FILE"
  done
  }


# Sub-function used by CRD.
if [ -f /com/crd ]; then
  CRDW ()
  {
  WRITE "Creating directory $1"
  /com/crd "$1"
  }
elif [ -f /bin/mkdir ]; then
  CRDW ()
  {
  WRITE "Creating directory $1"
  /bin/mkdir "$1"
  }
else
  CRDW ()
  {
  WRITE "Cannot create directory $1:"
  WRITE "  neither /bin/mkdir nor /com/crd are available."
  }
fi


# Create directory(ies) $1, $2, ... (if do not already exist).
CRD ()
  {
  while [ $# -gt 0 ]; do
    FILE="$1"
    shift
    if [ -z "$FILE" ]; then continue; fi
    if [ -d "$FILE" ]; then continue; fi
    if [ -f "$FILE" ]; then
      WRITE "Object $FILE is a file, not a directory"
      continue
    fi
    CRDW "$FILE"
  done
  }


# Sub-function used by START.
if [ -f /etc/server -a -f /etc/sys_sh ]; then
  STARTW ()
  {
  logf=
  cmd="$1"
  if [ -n "$6" ]; then cmd="$cmd $6"; fi
  if [ "$5" = log ]; then
    logf="$ND_S/$3.log"
    (echo "\n$DATE" >>$logf)
    cmd="$cmd >>$logf 2>&1"
  fi
  if [ "$4" = trail ]; then cmd="$cmd &"; fi
  WRITE "  $2 ($cmd)" $logf
  if /etc/server -p /etc/sys_sh -c "$cmd"; then
    (echo "$DATE" >$ND_ED/enable_$3)
  else
    WRITE "Daemon $2 ($cmd) failed" $logf
  fi
  }
else
  STARTW ()
  {
  WRITE "Cannot start $2 ($1): /etc/server or /etc/sys_sh do not exist."
  }
fi


# Start executable daemon $1 if control file $2 exists,
# and create enable_$3 if daemon is started.
# (Normally $2 and $3 are both the same as the leafname in $1, but...)
# In more detail: execute command $1,
#   only if $ND_ED/$2 exists.
#   only if $ND_ED/enable_$4 exists, i.e. if daemon $4 has been started; $4="ok" is OK.
#   only if $5="true"; to be used mainly as $DISKED.
#   only if file or directory $6 exists; $6="ok" is OK.
#   use trailing & if $7 is "trail".
#   put output into log file $ND_S/$3 if $8 is "log".
#   parameter $9 is passed to $1, enclose in quotes if needed.
#   if $9="line_single", "line_optional" or "line_repeat", then option line is read
#     from file $ND_ED/$2 instead. Comment and empty lines are ignored.
#     If no option line is found in file then, if $9="line_optional" then default
#     option $10 is passed to $1, otherwise an error message is written.
#     If $9="line_repeat" then file is scanned for multiple option lines.
# Create file $ND_ED/enable_$3 if daemon started
START ()
  {
  if [ $# -lt 8 -o $# -gt 10 ]; then
    WRITE "Wrong number ($#) of parameters to START:"
    WRITE "    <$1> <$2> <$3> <$4> <$5> <$6> <$7> <$8> <$9>"
    return
  fi
  if [ "$RESTART" != boot -a "$2" != "$RESTART" ]; then return; fi
  if [ ! -f "$ND_ED/$2" ]; then return; fi
  CMND="$1"
  STUB="$2"
  ENAB="$3"
  DEPD="$4"
  DSKD="$5"
  EXST="$6"
  TRAI="$7"
  LOGG="$8"
  OPTS="$9"
  if [ ! -f "$CMND" ]; then
    WRITE "Cannot start $STUB: $CMND does not exist."
    return
  fi
  if [ "$DEPD" != ok ]; then
    if [ ! -f "$ND_ED/enable_$DEPD" ]; then
      WRITE "Cannot start $STUB ($CMND): $DEPD has not been enabled."
      return
    fi
  fi
  if [ "$DSKD" != true ]; then
    WRITE "Cannot start $STUB ($CMND): not a disked node."
    return
  fi
  if [ "$EXST" != ok ]; then
    if [ ! -f "$EXST" -a ! -d "$EXST" ]; then
      WRITE "Cannot start $STUB ($CMND): $EXST does not exist."
      return
    fi
  fi

  if [ "$OPTS" = line_single -o "$OPTS" = line_repeat -o "$OPTS" = line_optional ]; then
    STARTED=false
    OLDIFS="$IFS"
    IFS='
'
    for LINE in `( IFS="$OLDIFS"; while read line; do
                     case "$line" in '' | '#'* ) continue;; esac
                     echo "$line"
                   done <"$ND_ED/$STUB" )`; do
      IFS="$OLDIFS"
      STARTW "$CMND" "$STUB" "$ENAB" "$TRAI" "$LOGG" "$LINE"
      STARTED=true
      if [ "$OPTS" != line_repeat ]; then break; fi
    done
    IFS="$OLDIFS"
    if [ "$STARTED" != true ]; then
      if [ "$OPTS" = line_optional ]; then
        shift
        OPTS="$9"
        # No other way of referencing $10 (no ${10} in this shell)
        STARTW "$CMND" "$STUB" "$ENAB" "$TRAI" "$LOGG" "$OPTS"
      else
        WRITE "Cannot start $STUB ($CMND): no options specified."
      fi
    fi
  else
    STARTW "$CMND" "$STUB" "$ENAB" "$TRAI" "$LOGG" "$OPTS"
  fi
  }


# # Check that link $1 points to directory `node_data/$2
# # In fact only checks that directory $1 is the same as `node_data/$2.
# CHK_LINK ()
#   {
#   if [ -d "$1" ]; then
#     dummy=`(cd $1 2>/dev/null; pwd)`
#     if [ "$dummy" != "$ND_/$2" ]; then
#       WRITE "ERROR: Directory $1 does not resolve to node_data/$2"
#     fi
#   else
#     WRITE "ERROR: Directory $1 does not exist"
#   fi
#   }


#---------------------------------------------------------------


# Start working on the messy bits.


WRITE "\n*****  $DATE  *****\n"
if [ "$RESTART" != boot ]; then
  WRITE "Re-starting daemon $RESTART (with SYSTYPE = $SYSTYPE)"
fi


# Figure out if this node is disked or diskless
# by comparing `node_data and /sys/node_data.
# This is important for some software like rgyd.
# You would be mad to run rgyd on a diskless node. In any case, only
# one node among the disked one and its diskless partners may run it,
# since there is only one /sys/registry.
if [ "$ND_" = `(cd /sys/node_data; pwd)` ]; then
  DISKED=true
  if [ "$RESTART" = boot ]; then
    if [ "//$NODENAME" = "$DISKNAME" ]; then
        WRITE "Booting $NODENAME ($NODEID) from own disk (with SYSTYPE = $SYSTYPE)\n"
    else
        WRITE "Booting $NODENAME ($NODEID) from own disk $DISKNAME (with SYSTYPE = $SYSTYPE)\n"
    fi
  fi
else
  DISKED=false
  if [ "$RESTART" = boot ]; then
    WRITE "Booting $NODENAME ($NODEID) from partner disk $DISKNAME (with SYSTYPE = $SYSTYPE)\n"
  fi
fi


# if [ "$TREES" = OK ]; then
#   CHK_LINK  /bsd4.3/usr/preserve      preserve
#   CHK_LINK  /dev                      dev
#   CHK_LINK  /etc/daemons              etc/daemons
#   CHK_LINK  /etc/ncs/lbcm_cache_dir   etc/ncs/lbcm_cache_dir
#   CHK_LINK  /tmp                      tmp
#   CHK_LINK  /usr/X11/lib/xdm          etc/xdm
#   CHK_LINK  /usr/X11/lib/xinit        etc/xinit
#   CHK_LINK  /usr/adm                  system_logs
#   CHK_LINK  /usr/preserve             preserve
#   CHK_LINK  /usr/spool/at             cron/at
#   CHK_LINK  /usr/spool/cron           cron
#   CHK_LINK  /usr/spool/locks          locks
#   CHK_LINK  /usr/tmp                  usrtmp
# fi


if [ "$RESTART" = boot ]; then
  # Allow logins?
  DLF /etc/nologin

  # Make MOTD world writable? No!
  #if [ -f /bin/chmod ]; then
  #  /bin/chmod 666 /etc/motd
  #fi

  if [ -f /etc/find_orphans ]; then
    WRITE "Looking for orphaned files"
    (/etc/find_orphans >/dev/console)
  else
    WRITE "Cannot look for orphaned files:"
    WRITE "  /etc/find_orphans is not available."
  fi

  if [ -f "$ND_ED/preserve" ]; then
    #zzz Any other names we need to know about?
    #zzz Is it right to run both SYSTYPE preserve commands?
    if [ -f /bsd4.3/usr/lib/ex3.7preserve ]; then
      WRITE "Preserving bsd4.3 editor files"
      (cd /tmp; /bsd4.3/usr/lib/ex3.7preserve -a)
    else
      WRITE "No /bsd4.3/usr/lib/*preserve file, cannot preserve"
    fi
    if [ -f /sys5.3/usr/lib/expreserve ]; then
      WRITE "Preserving sys5.3 editor files"
      (cd /tmp; /sys5.3/usr/lib/expreserve -a)
    elif [ -f /sys5.3/usr/lib/ex5.3apreserve ]; then
    # Name at SR10.0
      WRITE "Preserving sys5.3 editor files"
      (cd /tmp; /sys5.3/usr/lib/ex5.3apreserve -a)
    else
      WRITE "No /sys5.3/usr/lib/*preserve file, cannot preserve"
    fi
    (echo "$DATE" >$ND_ED/enable_preserve)
  else
    WRITE "We do not preserve editor files"
  fi

  DLT /tmp/ wild

  if [ "$SYSTYPE" = "bsd4.3" ]; then
    if [ -f /etc/umount -a -f /etc/mount -a -f /etc/mother ]; then
      WRITE "Initializing /etc/mtab"
      #zzz Is the option to umount really -A, or should that be -a?
      (/etc/umount -A; /etc/mount -f `/etc/mother`)
    else
      WRITE "Cannot initialize /etc/mtab: /etc/umount, mount or mother missing"
    fi
  elif [ "$SYSTYPE" = "sys5.3" ]; then
    if [ -f /etc/mother -a -f /etc/setmnt ]; then
      WRITE "Initializing /etc/mnttab"
      (/etc/mother | /etc/setmnt)
    else
      WRITE "Cannot initialize /etc/mnttab: /etc/mother or setmnt missing"
    fi
  else
    WRITE "Wrong SYSTYPE ($SYSTYPE), no mounting done at all"
  fi

  # Remove enable_indicator files
  DLT $ND_ED/enable_ wild

  # Make sure some files exist
  CRF $ND_E/.rgyloc $ND_E/utmp $ND_S/dm_error_log $ND_S/wtmp

  # This directory is needed for X stuff: Xapollo, vue and xdm which are
  # started here, as well as for Xdomain which may be started by any user.
  CRD /tmp/.X11-unix

  # Re-ACL some files, directory
  if [ -f /usr/apollo/bin/chacl ]; then
    /usr/apollo/bin/chacl -u root -g wheel -z none $ND_E/.rgyloc $ND_E/utmp $ND_S/dde_error_log $ND_S/dm_error_log $ND_S/net_log $ND_S/proc_dump $ND_S/wtmp
    /usr/apollo/bin/chacl u=prwx,g=rwx,z=I,o=rwx   $ND_E/.rgyloc
    /usr/apollo/bin/chacl u=prwx,g=r,z=I,o=r,spm.spm.none=rw  $ND_E/utmp
    /usr/apollo/bin/chacl u=prwx,g=rwk,z=I,o=rwk   $ND_S/dde_error_log $ND_S/dm_error_log $ND_S/net_log $ND_S/proc_dump
    /usr/apollo/bin/chacl u=prwx,g=k,z=I,o=k,spm.spm.none=rwk $ND_S/wtmp
    /usr/apollo/bin/chacl -D root.wheel.none       $ND_S/dde_error_log $ND_S/dm_error_log $ND_S/net_log $ND_S/proc_dump $ND_S/wtmp

    /usr/apollo/bin/chacl -odf -u root -g wheel -z none /tmp/.X11-unix
    /usr/apollo/bin/chacl u=prwx,g=rxk,z=rwxk,o=rxk /tmp/.X11-unix
    /usr/apollo/bin/chacl -d u=Pk,g=pk,z=I,o=k   /tmp/.X11-unix
    /usr/apollo/bin/chacl -f u=Prw,g=prwk,z=I,o=rwk /tmp/.X11-unix
    # /usr/apollo/bin/chacl -f -D user.server.none /tmp/.X11-unix
    # /usr/apollo/bin/chacl -f -D spm.spm.none /tmp/.X11-unix
  elif [ -f /com/edacl ]; then
    /com/edacl -p root prwx -g wheel rwx -o none -ignore -w rwx $ND_E/.rgyloc
    /com/edacl -p root prwx -g wheel r   -o none -ignore -w r -af spm.spm.none rw  $ND_E/utmp
    /com/edacl -p root prwx -g wheel rwk -o none -ignore -w rwk -df root.wheel.none $ND_S/dde_error_log $ND_S/dm_error_log $ND_S/net_log $ND_S/proc_dump
    /com/edacl -p root prwx -g wheel k   -o none -ignore -w k   -af spm.spm.none rwk -df root.wheel.none $ND_S/wtmp

    /com/edacl -p root prwx -g wheel rxk -o none rwxk -w rxk /tmp/.X11-unix
    /com/edacl -id -p root ik -g wheel pk -o none -ignore -w k /tmp/.X11-unix
    /com/edacl -if -p root irw -g wheel prwk -o none -ignore -w rwk /tmp/.X11-unix
    # /com/edacl -if -p root irwk -g wheel prwk -o none -ignore -w rwk -df user.server.none -df spm.spm.none /tmp/.X11-unix
  else
    WRITE "Neither /usr/apollo/bin/chacl nor /com/edacl exist"
    WRITE "  Cannot re-ACL (in $ND_E):"
    WRITE "    .rgyloc  utmp"
    WRITE "  Cannot re-ACL (in $ND_S):"
    WRITE "    dde_error_log  dm_error_log  net_log  proc_dump  wtmp"
    WRITE "  Cannot re-ACL /tmp/.X11-unix"
  fi
fi


#---------------------------------------------------------------


if [ "$RESTART" = boot ]; then
  WRITE "\nStarting standard (root.wheel.none) daemons:"
fi


# Local protection.
START /etc/lprotect lprotect lprotect ok true ok notrail nolog line_single


# Domain networking

# Increase/decrease network availability.
START /etc/netsvc netsvc netsvc ok true ok notrail log line_single

# Domain internet routing. Must start before TCP and NCS.
START /etc/rtsvc rtsvc rtsvc ok true ok notrail log line_repeat

# IBM token ring 802.5 source routing (turn off)
START /etc/ritr ritr ritr ok true ok notrail log line_repeat


# Streams

# Enable System V STREAMS.
START /sys/vstreams/streamd streamd streamd ok true ok trail nolog

# Enable System V STREAMS error logging.
START /etc/strerr strerr strerr streamd true ok trail nolog

# Build System V STREAMS stacks.
START /etc/stackd stackd stackd streamd true ok trail nolog


# Start TECHnet services if installed, before TCP services.
# See /etc/rc.technet for instructions.
if [ "$RESTART" = boot -o "$RESTART" = technet ]; then
  if [ -f /etc/rc.technet ]; then
    WRITE "Starting TECHnet services."
    WRITE "Why not incorporate rc.technet into rc?"
    /etc/sys_sh /etc/rc.technet
  fi
fi


# Disk updating daemon to run sync() every 30 seconds.
START /etc/update update update ok true ok notrail nolog


# syslogd and TCP services

# Name manager configuration (SR10.2 or later).
START /etc/nmconfig nmconfig nmconfig ok true ok notrail nolog line_repeat

# SNMP network management daemon.
START /etc/snmpd snmpd snmpd ok true ok notrail nolog

# IP host name. We recommend that you allow the IP host name to default to
# the node's DOMAIN name, set by ctnode.
START /etc/hostname hostname hostname ok true ok notrail nolog line_single

# Set up TCP/IP name of node
if [ -f $ND_ED/enable_hostname ]; then
  TCPNAME=`(/etc/hostname)`
  if [ -z "$TCPNAME" ]; then
    TCPNAME=Unknown
  fi
else
  TCPNAME="$NODENAME"
fi

##zzz Do we need this only at SR10.2?
# Host ID. This may (?) be needed by TCP/IP.
if [ -f $ND_ED/hostid ]; then
  START /etc/hostid hostid hostid ok true ok notrail nolog line_single
else
  START /etc/hostid tcpd hostid ok true ok notrail nolog "$TCPNAME"
fi

# Enable the socket() interface.
# Tcpd must fork and exit before ifconfig is run; do not use a trailing &.
# At SR10.3, you may need the '-c' option, to run in
# 'compatibility' mode with (buggy) pre_SR10.3 systems.
START /etc/tcpd tcpd tcpd hostid true ok notrail nolog line_optional

# Enable network interfaces for TCP.
# Ifconfig must complete before routed starts up; do not use a trailing &.
if [ -f $ND_ED/ifconfig ]; then
  START /etc/ifconfig ifconfig ifconfig tcpd true ok notrail nolog line_repeat
else
  START /etc/ifconfig tcpd ifconfig tcpd true ok notrail nolog "net0 $TCPNAME netmask defaultmask"
  START /etc/ifconfig tcpd ifconfig tcpd true ok notrail nolog "lo0 127.0.0.1"
fi

# Error logging.
START /etc/syslogd syslogd syslogd ok true ok notrail nolog line_optional

# Dynamic routing.
START /etc/routed routed routed tcpd true ok notrail nolog line_single

# Additional static routes.
START /etc/route route route tcpd true ok notrail nolog line_repeat

# Public-domain routing daemon gated, instead of routed (and route).
#zzz Sometimes gated does not fork, so use trailing & to ensure we do not get stuck.
START /etc/gated gated gated tcpd true /etc/gated.conf trail nolog line_optional

# IP-to-MAC address mappings for remote hosts.
START /etc/arp arp arp tcpd true ok notrail nolog line_repeat

# Internet super-daemon.
START /etc/inetd inetd inetd tcpd true ok notrail nolog

# Enable the Berkeley Internet name server.
START /etc/named named named tcpd true ok notrail nolog line_optional

# Enable rwho and ruptime information.
START /etc/rwhod rwhod rwhod tcpd true ok notrail nolog line_optional

# Berkeley time server daemon (SR10.2 or later).
START /etc/timed timed timed ok true ok notrail nolog line_optional


# NFS and related stuff

###zzzzz How could we run nmconfig, possibly with 'hostent_bind',
###      before starting named?
###zzzzz How could we run nmconfig, possibly with 'hostent_yp',
###      before starting nfs?

if [ -f $ND_ED/nfs ]; then
  DEFAULTDOMAIN=`(/bin/cat /etc/defaultdomain)`
  if [ -z "$DEFAULTDOMAIN" ]; then
    DEFAULTDOMAIN=Unknown
  fi

  START /bin/domainname      nfs nfs_domain tcpd       true notrail nolog "$DEFAULTDOMAIN"
  START /sys/nfs/reboot      nfs nfs_reboot nfs_domain true notrail nolog
  START /sys/nfs/clntConfig  nfs nfs_config nfs_reboot true notrail nolog 'flushInterval=86400,tempLifetime=86400,fhCacheLifetime=30'
  START /usr/etc/exportfs    nfs nfs_export nfs_config true notrail nolog '-a'

  START /usr/etc/portmap     nfs nfs_portmp nfs_export true notrail nolog
  START /usr/etc/keyserv     nfs nfs_keysrv nfs_export true notrail nolog

  if [ -f $ND_ED/ypserv ]; then
    START /usr/etc/ypserv           nfs nfs_ypserv nfs_export true notrail nolog
    START /usr/etc/ypbind           nfs nfs_ypbind nfs_ypserv true notrail nolog '-ypsetme'
    START /usr/etc/yp/ypset         nfs nfs_ypset  nfs_ypbind true notrail nolog "$TCPNAME"
    START /usr/etc/yp/ypxfrd        nfs nfs_ypxfrd nfs_ypset  true trail nolog
    START /usr/etc/yp/ypupdated     nfs nfs_update nfs_ypset  true trail nolog
    START /usr/etc/yp/rpc.yppasswdd nfs nfs_passwd nfs_ypset  true trail nolog '/etc/passwd -m passwd'
  else
    START /usr/etc/ypbind           nfs nfs_ypbind nfs_export true notrail nolog
  fi

  START /usr/etc/rpc.statd   nfs nfs_statd  nfs_ypbind true trail nolog
  START /usr/etc/rpc.lockd   nfs nfs_lockd  nfs_ypbind true trail nolog
  START /usr/etc/rpc.mountd  nfs nfs_mountd nfs_ypbind true trail nolog
  START /usr/etc/automount   nfs nfs_amount nfs_ypbind true trail nolog '-m -anet /net -hosts'
  START /usr/etc/nfsd        nfs nfs        nfs_ypbind true trail nolog '-anet 4'
  START /etc/damd            nfs nfs_damd   nfs_ypbind true trail nolog '-e'
  START /etc/pcnfsd          nfs nfs_pcnfsd nfs_ypbind true trail nolog
fi


if [ "$RESTART" = boot ]; then
  if [ "$SYSTYPE" = "bsd4.3" ]; then
    # Mount file systems in /etc/fstab (now that tcpd is running)
    if [ -f /etc/umount -a -f /etc/mount -a -f /etc/mother ]; then
      (/etc/mount -a)
    fi
  fi
fi


# NCS services

# In NCS 1.5.1, local location services were provided by the local location
# broker daemon (llbd). In NCS 2.0, local location services are provided by
# the remote procedure call daemon (rpcd). For easier transition from 1.5.1
# to 2.0 on Domain/OS, there is a link "/etc/ncs/llbd" -> "rpcd". Both llbd
# and rpcd must fork and the parent exit before other NCS servers may be
# run: do not use trailing &.
#zzz However, rpcd often (but not always) returns a failed exit status, and
# then we think that rpcd has not started, while in fact the child goes on
# merrily (it was the parent which returned failure). A way around this is
# to start rpcd with a trailing &, thus ignoring its status; we hope that
# other NCS daemons will re-try if they cannot connect to rpcd.
if [ -f $ND_ED/rpcd ]; then
  START /etc/ncs/rpcd rpcd llbd ok true ok trail nolog line_optional
else
  START /etc/ncs/llbd llbd llbd ok true ok notrail nolog line_optional
fi

# Global Location Broker.
START /etc/ncs/glbd glbd glbd llbd true ok trail nolog line_optional

# Registry daemon.
# rgyd must fork and its parent exit before
# it can service registry queries: do not use trailing &.
#
# If you want immediate fault information from the registry server rather
# than monitoring entries in the rgyd_error_log, change the startup line
# to redirect output to the console device:
#    (/etc/rgyd >/dev/console 2>&1)
# This will cause faults to be displayed in a scrolling fashion at the
# bottom of the screen, NOT in a window. The interactive user will have
# to use the DM refresh screen command, "rs", to clean up the display after a
# message is generated. Sometimes node shutdown will cause extra shutdown signals
# to be delivered to the registry server - this will cause an error condition to
# be reported, but will NOT cause any problems with the server database. In all
# cases errors are also reported in /sys/node_data/system_logs/rgyd_error_log.
START /etc/rgyd rgyd rgyd llbd $DISKED /sys/registry/rgy_data trail nolog

# Network License Server: Controls license usage for
# applications using NetLS.
START /etc/netls/netlsd netlsd netlsd llbd true ok trail nolog


# Miscellaneous UNIX daemons

# /etc/cron is in fact a link to /etc/$SYSTYPE/cron.
if [ "$RESTART" = boot -o "$RESTART" = cron ]; then
  if [ -f $ND_ED/cron ]; then
    DLF /sys5.3/usr/lib/cron/FIFO
    START /etc/cron cron cron ok true ok notrail nolog
  fi
fi

# What's this? No daemon to start?
if [ "$RESTART" = boot -o "$RESTART" = uucico ]; then
  if [ -f $ND_ED/uucico ]; then
    DLT /usr/spool/uucp/LCK. wild
    DLT /usr/spool/locks/LCK. wild
  fi
fi

# bsd4.3 lpr printer server.
# Why the messing around with servername? Could start lpd with trailing &,
# but must ensure that it forks before creating the servername file.
if [ "$RESTART" = boot -o "$RESTART" = lpd ]; then
  if [ -f $ND_ED/lpd -a "$SYSTYPE" = "bsd4.3" ]; then
    DLF /usr/spool/lpd/servername
    START /usr/lib/lpd lpd lpd llbd $DISKED /usr/spool/lpd notrail nolog
    (echo "$NODENAME" > /usr/spool/lpd/servername)
  fi
fi

# sys5.3 lp printer server.
# Does not need LLBD ??!!
if [ "$RESTART" = boot -o "$RESTART" = lpsched ]; then
  if [ -f $ND_ED/lpsched -a "$SYSTYPE" = "sys5.3" ]; then
    DLF /usr/spool/lp/FIFO
    DLF /usr/spool/lp/SCHEDLOCK
    START /usr/lib/lpsched lpsched lpsched ok $DISKED /usr/spool/lp notrail nolog
  fi
fi

# System accounting
START /etc/accton accounting accounting ok true /usr/adm/acct notrail nolog /usr/adm/acct

# Sendmail daemon
if [ "$RESTART" = boot -o "$RESTART" = sendmail ]; then
  if [ -f $ND_ED/sendmail ]; then
    DLT /usr/spool/mqueue/lf wild
    START /usr/lib/sendmail sendmail sendmail ok true ok trail nolog line_single
  fi
fi

# portmap to locate SUN-RPC services.
# Portmap must fork and the parent exit before mountd starts:
# do not use trailing &.
START /etc/portmap portmap portmap ok true ok notrail nolog

# Run mountd to receive remote mount requests.
START /etc/mountd mountd mountd portmap true ok trail nolog

# Run nfsd to receive remote file system requests.
START /etc/nfsd nfsd nfsd mountd true ok trail nolog


# Miscellaneous Domain daemons

# audit_daemon to support auditing.
START /etc/audit/audit_daemon audit audit ok true ok trail nolog

# External paging daemon (needed for cdfsd only, only from SR10.4)
START /etc/xpager xpager xpager ok true ok trail nolog line_optional

# CDROM file system daemon to allow a CDROM file system 
# to be mounted on this machine. From SR10.4, also needs xpager.
START /etc/cdfsd cdfsd cdfsd llbd true ok trail nolog

# Diskless node boot server.
START /sys/net/netman netman netman ok $DISKED ok trail nolog


#---------------------------------------------------------------


# This section is a copy of rc.user, originally run through
# /etc/server /etc/sys_sh /etc/rc.user
# thus used to run as user.server.none .
# Make sure that all daemons mentioned are setuid AND setgid
# to something convenient, or they would run as root.wheel.none .


if [ "$RESTART" = boot ]; then
  WRITE "\nStarting other (setuid, setgid) daemons:"
fi


# Server process manager.
START /sys/spm/spm spm spm ok true ok trail nolog

# D3M
START /sys/d3m/d3m_server d3m_server d3m_server ok true ok trail nolog

# Naming server
START /sys/ns/ns_helper ns_helper ns_helper ok $DISKED ok trail nolog

# Store and forward
START /sys/sf/sf_helper sf_helper sf_helper ok $DISKED ok trail nolog

# Domain print manager
START /sys/hardcopy/prmgr prmgr prmgr llbd true ok trail log "-cfg $ND_ED/prmgr"

# Domain print server: possibly one for each serial and parallel line;
# and a 'plain' one for backwards compatibility
START /sys/hardcopy/prsvr prsvr  prsvr  llbd true ok trail log "$ND_ED/prsvr"
START /sys/hardcopy/prsvr prsvr1 prsvr1 llbd true ok trail log "$ND_ED/prsvr1"
START /sys/hardcopy/prsvr prsvr2 prsvr2 llbd true ok trail log "$ND_ED/prsvr2"
START /sys/hardcopy/prsvr prsvr3 prsvr3 llbd true ok trail log "$ND_ED/prsvr3"
START /sys/hardcopy/prsvr prsvrp prsvrp llbd true ok trail log "$ND_ED/prsvrp"

# pre10q daemon for mixed sr10-sr9 environments.
START /sys/hardcopy/pre10q pre10q pre10q ok true ok trail nolog line_single

# Summagraphic bitpad support.
START /sys/dm/sbp1 bitpad bitpad ok true ok trail nolog line_single

# dial server for the dial_server_request command.
START /sys/dial_server dial_server dial_server ok true ok trail nolog

# Network maintenance server. Collects network statistics.
START /sys/net/netmain_srvr netmain_srvr netmain_srvr ok true ok trail nolog

# writed for the write(1) program (both bsd4.3 and sys5.3)
START /etc/writed writed writed ok true ok trail nolog

# DPCI server for ring and/or tty-line
if [ "$RESTART" = boot -o "$RESTART" = dpci ]; then
  if [ -f $ND_ED/dpci ]; then
    # Make sure this file exists
    CRF /tmp/dpci_prf_log
    # Re-ACL it
    if [ -f /usr/apollo/bin/chacl ]; then
      /usr/apollo/bin/chacl -u root -g wheel -z none /tmp/dpci_prf_log
      /usr/apollo/bin/chacl u=prwx,g=rwk,z=I,o=rwk /tmp/dpci_prf_log
      # /usr/apollo/bin/chacl -D user.server.none /tmp/dpci_prf_log
      # /usr/apollo/bin/chacl -D spm.spm.none /tmp/dpci_prf_log
    elif [ -f /com/edacl ]; then
      /com/edacl -p root prwx -g wheel rwk -o none -ignore -w rwk /tmp/dpci_prf_log
      # /com/edacl -p root prwx -g wheel rwk -o none -ignore -w rwk -df user.server.none -df spm.spm.none /tmp/dpci_prf_log
    else
      WRITE "Neither /usr/apollo/bin/chacl nor /com/edacl exist"
      WRITE "  Cannot re-ACL /tmp/dpci_prf_log"
    fi
    START /sys/dpci/dpci dpci dpci ok true ok trail nolog line_repeat
  fi
fi

# DPCIring, PC-on-TR server
START /sys/dpciring/session dpciring dpciring ok true ok trail nolog

# DPCI1, PC-on-tty-line server
START /sys/dpci1/session dpci1 dpci1 ok true ok trail nolog line_repeat

# MHSnet. Note that this needs quite a lot of setting up,
# which cannot be checked here. Needs TCP/IP.
START /usr/spool/MHSnet/_lib/start MHSnet MHSnet tcpd true /usr/lib/MHSnetparams trail log

# ingres database. Needs quite a lot of setting up which cannot be checked
# here; it is also started with a shell script. Needs (at least minimal) TCP/IP.
START /sys5.3/bin/su ingres ingres tcpd true /master/sfw/ask trail nolog "ingres -c iiboot"

# WorldWideWeb/Gopher server. Needs quite a lot of setting up which cannot
# be checked here; it uses perl scripts. Needs TCP/IP.
START /bsd4.3/bin/su httpd httpd tcpd true /z/x/httpd/httpd trail nolog "httpd -c /z/x/httpd/httpd -d /z/x/httpd"

# MATLAB licence manager. Luckily we can start lmgrd daemon directly (without
# need for shell script). Needs TCP/IP (on all clients too).
START /y/sfw/matlab/etc/apollo/lmgrd lm_matlab lm_matlab tcpd true /y/sfw/matlab/etc/apollo/lm_matlab trail log "-c /y/sfw/matlab/etc/license.dat"


#---------------------------------------------------------------


# Start Window system(s).
# Currently only the X Server is started here. The DM is started from
# init as a tty. See /etc/ttys.
#
# The nice command should be used to set scheduling priority on Xapollo
# to --5 (example: /bin/nice --5 /etc/Xapollo .....).
# It is not recommended to use priorities higher than -5.
#zzz How to do this through START?
#
# You may select vuelogin by touching /etc/daemons/vue. In the absence
# of a /usr/X11/lib/vue/vuelogin/Xconfig file vuelogin will use the
# /usr/lib/X11/xdm/xdm-config file. Vuelogin will recognize xdm
# resources for backward compatibility.
#
# Do not attempt to specify more than one of Xapollo, xdm or vue.

if [ "$RESTART" = boot -o "$RESTART" = Xapollo -o "$RESTART" = xdm -o "$RESTART" = vue ]; then
  if [ -f $ND_ED/Xapollo -o -f $ND_ED/xdm -o -f $ND_ED/vue ]; then
    WRITE "\nStarting window system:"
    START /etc/vuerc vue vue ok true /usr/X11/lib/vue/etc/vuelogin trail nolog
    START /etc/xdm xdm xdm ok true /usr/X11/lib/xdm/Xservers trail nolog
    START /etc/Xapollo Xapollo Xapollo ok true ok trail nolog line_single
  fi
fi


#---------------------------------------------------------------


# Start X.25 services if installed.
# See /etc/rc.x25 for instructions.
if [ "$RESTART" = boot -o "$RESTART" = x25 ]; then
  if [ -f /etc/rc.x25 ]; then
    WRITE "Starting X.25 services."
    WRITE "Why not incorporate rc.x25 into rc?"
    /etc/sys_sh /etc/rc.x25
  fi
fi


#---------------------------------------------------------------


if [ "$RESTART" = boot ]; then
  WRITE "\nNode startup completed."
fi

exit 0

