#!/bin/sh
# -*- shell-script -*-

# Copyright (c) 2006 BBN Technologies Corp.  All rights reserved.
# Copyright (c) 2012--2014 Raytheon BBN Technologies.  All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. Neither the name of BBN Technologies nor the names of its contributors
#    may be used to endorse or promote products derived from this software
#    without specific prior written permission.

# THIS SOFTWARE IS PROVIDED BY BBN TECHNOLOGIES AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL BBN TECHNOLOGIES OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.

# This software was developed under funding from DARPA's ACERT program
# under contract number NBCH050166.

## This script supports automatic installing of NetBSD from a release
## (specifically, the contents of releasedir from build.sh, such as
## might be on a CDROM).  It intends to support the netbsd-2 branch
## and later.

## The script is invoked as root, and assumes that $cwd is a release
## directory.

## Install the version of NetBSD in the current directory, including X11:
##   INSTALL-NetBSD install
## Install the version of NetBSD in the current directory, not including X11:
##   INSTALL-NetBSD -nox install
## Install just the kernel (in a system with X11):
##   INSTALL-NetBSD installkernel
## Install just userland (in a system with X11):
##   INSTALL-NetBSD installuser

## TODO: the branch is not checked

log() { printf %s\\n "$*"; }
logn() { printf %s "$*"; }
error() { log "ERROR: $@" >&2; }
fatal() { error "$@"; exit 1; }
try() { "$@" || fatal "'$@' failed"; }

logn "INSTALL-NetBSD OVERALL start "; date

# Only root can install
uid=$(try id -u) || exit 1
if [ 0 != "${uid}" ]; then
    fatal "INSTALL-NetBSD: MUST BE ROOT"
fi

## The following files store information about the kernel config that
## should be installed on the current machine, and the branch of
## NetBSD that the machine is currently running.
kernel_file=/.BUILD-NetBSD.kernel
branch_file=/.BUILD-NetBSD.branch

# X requested?
if [ "$1" = "-nox" ]; then
    xsets=no
    shift
else
    xsets=yes
fi

case "$1" in
    installkernel)
	installkernel=t
	;;
    installuser)
	installuser=t
	;;
    install)
	installkernel=t
	installuser=t
	;;
    *) fatal "argument _$1_ invalid";;
esac

# determine arch
arch=$(try uname -m) || exit 1

## Read name of kernel from config file.  The wrong kernel may fail to
## work (e.g., GENERIC_LAPTOP vs. GENERIC), so fail if not found.
if [ -f "$kernel_file" ]; then
    read kern < $kernel_file
else
    fatal "$kernel_file must contain name of kernel"
fi

# check for a release
for d in "$arch" "$arch"/binary "$arch"/binary/sets "$arch"/binary/kernel; do
    if [ ! -d "$d" ]; then
	fatal "directory $d missing"
    fi
done

# check for our kernel
kern_file=$arch/binary/kernel/netbsd-$kern.gz
if [ ! -f "$kern_file" ]; then
    fatal "$kern_file missing"
fi

# Put base last, so that if we're going to lose because of a new libc
# for which we *should* have rebooted first with a new kernel, there's
# some chance that the last pax will be running and a hard reset will
# result in an ok system.
SETS="comp games man modules misc tests text base"
XSETS="xbase xcomp xfont xserver"
ETCSETS="etc"
XETCSETS="xetc"

# check for X11 - must match release
if [ "$xsets" = yes ]; then
    # X11 requested - look for them
    SETS="$XSETS $SETS"
    ETCSETS="$XETCSETS $ETCSETS"
else
    # X11 not requested
    for s in $XSETS $XETCSETS; do
	if [ -f "$arch"/binary/sets/"$s".tgz ]; then
	    fatal "-nox but $s present"
	fi
    done
fi

# check for sets
for set in $SETS $ETCSETS; do
    if [ ! -f "$arch"/binary/sets/"${set}".tgz ]; then
	log "INFO: $arch/binary/sets/${set} missing"
    fi
done

# install kernel
if [ "$installkernel" = t ]; then
    # ".ok" is reserved for human judgement that a kernel is ok.
    try cp -pf /netbsd /netbsd.old
    try zcat "$kern_file" > /netbsd.new
    try mv -f /netbsd.new /netbsd

    # uncomment when we're sure this is safe
    # try cp -p /usr/mdec/boot /boot

    # find root device, and type, and ensure this is safe
    # (try cd /usr/mdec; try installboot -v "$DISK" bootxx_ffsv1) || exit 1
fi

# install userland
if [ "$installuser" = t ]; then
    # This file is in base, not etc, so ensure it is not managed.
    try etcmanage --remove /etc/release

    logn "Unpacking sets:"
    for set in $SETS; do
	setfile=$arch/binary/sets/${set}.tgz
	logn " [$set"
	if [ -f "$setfile" ]; then
	    (try cd /; try pax -rz -pe) <$setfile || exit 1
	else
	    logn " missing"
	fi
	logn "]"
	# try to avoid filling up memory with softupdates
	try sync; try sync; try sync
    done
    log "."

    NETBSDETC=/usr/netbsd-etc
    try rm -rf "${NETBSDETC}"
    try mkdir -p "${NETBSDETC}"
    for set in $ETCSETS; do
	(try cd "${NETBSDETC}"; try pax -rz -pe) \
	    <$arch/binary/sets/${set}.tgz || exit 1
    done
    log "ETCMANAGE"
    try etcmanage --update "$NETBSDETC"

    (try cd /dev; try ./MAKEDEV all) || exit 1
fi

logn "INSTALL-NetBSD OVERALL finish "; date
