#!/bin/sh
#
#	setup 1.0 - setup a Minix-vmd skeleton system	Author: Kees J. Bot
#								29 Sep 1996

umask 022
PATH=/sbin:/usr/sbin:/bin:/usr/bin
export PATH

[]()
{
	# Index into a list, i.e. f='x y z'; $([] 1 $f) = y
	shift $1
	shift
	echo "$1"
}

@()
{
	# Dereference, i.e. y=z; x=y; $(@ $x) = z
	eval "echo \$$1"
}

case "$DEBUG" in			# $DEBUG gives floppy device names.
/dev/*/dev/*)
	x() echo : "$@" >&2		# 'x' only prints dangerous commands.
	;;
'')
	x() "$@"			# 'x' does dangerous command.
	;;
*)	echo "Strange value for \$DEBUG: $DEBUG" >&2
	exit 1
esac

# We don't take any options, we can only install a Minix-vmd skeleton.
case $# in
0)	# Fine.
	;;
*)
	echo >&2 "\
Usage: setup	# Install a Minix-vmd skeleton system.
		# See usage(8) on how to install floppy sets."
	exit 1
esac

# Installing Minix-vmd on the hard disk.
if [ ! "$DEBUG" ]
then
	# Must be in / or we can't mount or umount.
	case "`pwd`" in
	/?*)	echo "Please type 'cd /', you are locking up `pwd`" >&2	
		exit 1
	esac
	case "$0" in
	/tmp/*)
		rm -f "$0"
		;;
	*)	cp -p "$0" /tmp/setup
		exec /tmp/setup
	esac
fi

# Find out what we are running from from the mounted file table.
{
	read thisroot rest		# Current root (/dev/ram or /dev/fd?)
	read fdusr rest			# USR (/dev/fd? or /dev/fd?c)
} </etc/mtab

if [ "$DEBUG" ]				# $DEBUG tells devices?
then
	thisroot=$([] 0 $DEBUG)
	fdusr=$([] 1 $DEBUG)
fi

# What do we know about ROOT?
case $thisroot:$fdusr in
/dev/ram:/dev/fd0c)	fdroot=/dev/fd0		# Combined ROOT+USR in drive 0
			;;
/dev/ram:/dev/fd1c)	fdroot=/dev/fd1		# Combined ROOT+USR in drive 1
			;;
/dev/ram:/dev/fd*)	fdroot=unknown		# ROOT is some other floppy
			;;
/dev/fd*:/dev/fd*)	fdroot=$thisroot	# ROOT is mounted directly
			;;
*)			fdroot=$thisroot	# ?
	echo -n "\
It looks like Minix-vmd has been installed on disk already.  Are you sure you
know what you are doing? [y] "
	read yn
	case "$yn" in
	''|[yY]*|sure)	;;
	*)	exit
	esac
esac

echo -n "\
This is the Minix-vmd installation script.

Note 1: If the screen blanks suddenly then hit F3 to select \"software
        scrolling\".  Later read boot(8) on how to set this permanently.

Note 2: If things go wrong then hit DEL and start over.

Note 3: The installation procedure is described in the manual page usage(8).
	It will be hard without it.  (This is Minix-vmd, about twice the
	complexity of standard Minix, so you'd better know what you are doing.)

Note 4: Some questions have default answers, like this: [y]
	Simply hit RETURN (or ENTER) if you want to choose that answer.
	Some have examples, like this: [q,p,/usr]  You must type something.

Note 5: If you see a colon (:) then you should hit RETURN to continue.
:"
read ret

echo "
What type of keyboard do you have?  You can choose one of:
"
ls -C /usr/lib/keymaps | sed -e 's/\.kbd//g' -e 's/^/    /'
echo -n "
Keyboard type? [us-std] "; read keymap
case "$keymap" in
?*)	x keymap -l "/usr/lib/keymaps/$keymap.kbd"
esac

echo -n "
Minix-vmd requires the filesystems /, /tmp, /usr, /var, /opt and /home.  You
will now be put in the editor \"part\" to make any (sub)partitions necessary
for these file systems.  Please note the names of the devices you make.
:"
read ret

showdev()
{
	local fs="$1"
	local dev="$2"
	local size="$3"

	echo -n "	$fs	"
	case "$dev" in
	/)	echo "(not mounted, part of /)"
		;;
	/*)	echo "$dev/.lo$fs  (part of $dev)"
		;;
	*)	echo "$dev${size:+"		$size kb, rest for swapspace"}"
	esac
}

askdev()
{
	local fs="$1"
	local varfs="$2"
	local dev=$([] 0 $(@ $varfs))
	local size=$([] 1 $(@ $varfs))
	local lfs newdev newsize primary

	echo -n "
Type the name of the device or file system to place $fs onto.  You can use
names like 'hd2a', 'sd9c', for device names"
	if [ $fs != / ]
	then
		echo -n ", and '/usr', '/var', for names
of file systems to loopback mount $fs from, and '/' to make $fs part of the
root file system"
	fi
	echo -n ".  Device? [$dev] "
	read newdev

	case "$newdev" in
	'')
		# Keep current value.
		;;
	/ | /usr | /var | /opt | /home)
		if [ $fs = / ]
		then
			echo;echo "The root file system must be a device"
			return 1
		fi
		dev=$newdev
		size=
		;;
	/dev/*)
		if [ ! -b "$newdev" ]
		then
			echo;echo "There is no block device $newdev"
			return 1
		fi
		dev=$(expr "$newdev" : '/dev/\(.*\)')
		;;
	*)
		if [ ! -b "/dev/$newdev" ]
		then
			echo;echo "There is no block device /dev/$newdev"
			return 1
		fi
		dev="$newdev"
	esac

	if [ ! $dev : / ]
	then
		echo -n "
A device can be part file system and part swap space.  You can make this split
by setting a size for the file system that is smaller than the device.  Note
that devices with swap space should not have bad blocks.  If the file system
should occupy the entire device then type 'all'.

How many kilobytes large should $fs be? [${size:-all}] "
		read newsize
		test x"$newsize" = '' && newsize=$size
		test x"$newsize" = xall && newsize=
		if [ ! x"$newsize" : x'[0-9]*' ]
		then
			echo "'$newsize' is not a decimal number"
			return 1
		fi
		size=$newsize
	fi
	setvar $varfs "$dev $size"

	# Try to guess better defaults from the new device input.
	if [ ! "$guessed" -a "$dev" : '.*[0-9][0-9]*[a-d]' ]
	then
		primary=$(expr "$dev" : '\(.*\).')

		test $fs = /    || root="${primary}a $([] 1 $root)"
		test $fs = /tmp || tmp="${primary}b $([] 1 $tmp)"
		test $fs = /usr || usr="${primary}c $([] 1 $usr)"
	fi
	guessed=t	# Only guess once.

	# All devices that are loopbacked on a loopbacked device shouldn't.
	if [ $dev : / ]
	then
		for lfs in tmp usr var opt home
		do
			if [ $([] 0 $(@ $lfs)) = $fs ]
			then
				setvar $lfs /
			fi
		done
	fi
	return 0
}

root=hd2a tmp='hd2b 4096' usr=hd2c var=/usr opt=/usr home=/usr
correct= guessed= partitioned=
while [ ! "$correct" ]
do
	test "$partitioned" || part || exit
	partitioned=t

	echo "
This is the current assumption on what the Minix-vmd file systems will become:
"
	showdev / $root
	showdev /tmp $tmp
	showdev /usr $usr
	showdev /var $var
	showdev /opt $opt
	showdev /home $home
	echo -n "
Please type 'q' if this is correct, 's' for a subshell, 'p' if you want to
rerun 'part', or the name of the filesystem you want to change:
				[q,s,p,/,/tmp,/usr,/var,/opt,/home] "
	read fs
	case "$fs" in
	q)	correct=t
		;;
	s)	sh
		;;
	p)	partitioned=
		;;
	/)	askdev / root
		;;
	/tmp | /usr | /var | /opt | /home)
		askdev $fs $(expr $fs : '/\(.*\)')
		;;
	*)	echo;echo "Please type 'q', 'p', or a file system name."
	esac
done

echo -n "
Hit return if everything is fine, or hit DEL to bail out if you want to
think it over.  The next step will scribble on disk.
:"
read ret

echo "
Making file systems...
"

for varfs in root tmp usr var opt home
do
	dev=$([] 0 $(@ $varfs))
	size=$([] 1 $(@ $varfs))
	test ! $dev : '/' || continue

	bpi=
	test $varfs = root && bpi='-b 1440'

	x mkfs -t 2f $bpi /dev/$dev $size || exit
	if [ "$size" ]
	then
		x mkfs -t +swap /dev/$dev
	elif [ $varfs != root -a $varfs != tmp ]
	then
		echo "\
Scanning /dev/$dev for bad blocks.  (Hit DEL to stop the scan if are absolutely
sure that there can not be any bad blocks.  Otherwise just wait.)"
		trap ': nothing' 2
		x readall -b /dev/$dev | sh
		echo "Scan done"
		sleep 2
		trap 2
	fi
	x mount -q /dev/$dev /mnt || exit
	mode=755
	test $varfs = tmp && mode=1777
	test $varfs = opt && mode=775
	x chmod $mode /mnt || exit
	x umount -q /mnt || exit
done

for fs in tmp usr var opt home
do
	lfs=$([] 0 $(@ $fs))
	test $lfs : '/.' || continue

	dev=$([] 0 $(@ $(expr $lfs : '/\(.*\)')))
	x mount -q /dev/$dev /mnt || exit
	test -d /mnt/.lo || x mkdir /mnt/.lo || exit
	mode=755
	test $fs = tmp && mode=1777
	test $fs = opt && mode=775
	x mkdir -m $mode /mnt/.lo/$fs || exit
	x umount -q /mnt || exit
done

echo "
Migrating from floppy to disk...
"

Mount()
# Mount a filesystem that may be loopbacked or part of the root file system.
{
	local fs="$1"
	local dir="$2"
	local dev

	dev=$([] 0 $(@ $fs))
	case "$dev" in
	/)	x mount /dev/$([] 0 $root) $dir || return 1
		test -d $dir/$fs || x mkdir $dir/$fs
		x mount -t lo $dir/$fs $dir || return 1
		;;
	/*)	dev=$([] 0 $(@ $(expr $dev : '/\(.*\)')))
		x mount /dev/$dev $dir || return 1
		x mount -t lo $dir/.lo/$fs $dir || return 1
		;;
	*)	x mount /dev/$dev $dir || return 1
	esac
}

Umount()
{
	local fs="$1"
	local dir="$2"
	local dev

	dev=$([] 0 $(@ $fs))
	case "$dev" in
	/*)	x umount $dir || return 1
	esac
	x umount $dir || return 1
}

Mount usr /mnt || exit			# Mount the intended /usr.

x cpdir -v /usr /mnt || exit		# Copy the usr floppy.

Umount usr /mnt || exit			# Unmount the intended /usr.

Mount var /var || exit			# Mount the intended /var.

x mkdir -m 775 /var/adm			# Create /var skeleton.
if [ "$DEBUG" ]
then
	echo ": >/var/adm/lastlog >/var/adm/log >/var/adm/wtmp"
else
	>/var/adm/lastlog >/var/adm/log >/var/adm/wtmp
fi
x mkdir -m 755 /var/lib
x mkdir -m 775 /var/local /var/local/adm /var/opt
x chown bin /var/lib /var/local/adm
x mkdir -m 700 /var/preserve
x mkdir -m 755 /var/run /var/spool
x mkdir -m 1711 /var/spool/at /var/spool/at/past
x mkdir -m 775 /var/spool/locks
x chgrp uucp /var/spool/locks
x mkdir -m 700 /var/spool/lpd
x chown daemon:daemon /var/spool/lpd
x mkdir -m 770 /var/spool/uucp
x mkdir -m 775 /var/spool/uucppublic
x chown uucp:uucp /var/spool/uucp /var/spool/uucppublic
x mkdir -m 1777 /var/tmp

Umount var /var || exit			# Unmount the intended /var.

usr_on_root=
if [ $fdroot = unknown ]
then
	x umount /usr || exit		# Unmount the /usr floppy.

	if [ $([] 0 $usr) = / ]
	then
		x mount /dev/$([] 0 $root) /mnt || exit	# A new root
		x mount -t lo /mnt/usr /usr		# A new /usr
		usr_on_root=t
	else
		Mount usr /usr || exit			# A new /usr
	fi

	echo "
By now the floppy USR has been copied to $([] 0 $usr), and it is now in use as
/usr.  Please insert the installation ROOT floppy in a floppy drive."

	drive=
	while [ -z "$drive" ]
	do
		echo -n "What floppy drive is it in? [0] "; read drive

		case $drive in
		'')	drive=0
			;;
		[01])
			;;
		*)	echo "It must be 0 or 1, not \"$drive\"."
			drive=
		esac
	done
	fdroot=/dev/fd$drive
fi

echo "
Copying $fdroot to /dev/$([] 0 $root)
"

test "$usr_on_root" || x mount /dev/$([] 0 $root) /mnt || exit

if [ $thisroot = /dev/ram ]
then
	# Running from the RAM disk, root image is on a floppy.
	x mount $fdroot /root || exit
	if [ "$usr_on_root" ]
	then
		x rmdir /root/usr	# /usr already there
	fi
	x cpdir -v /root /mnt || exit
	if [ "$usr_on_root" ]
	then
		x mkdir -m 555 /root/usr
	fi
	x umount /root || exit
	x cpdir -f /dev /mnt/dev	# Copy any extra MAKEDEV'd devices
	test -f /etc/vdisk.conf && x cp -p /etc/vdisk.conf /mnt/etc/vdisk.conf
else
	# Running from the floppy itself.
	x cpdir -vx / /mnt || exit
	test $([] 0 $usr) = / || x chmod 555 /mnt/usr
	x chmod 555 /mnt/mnt
	test -h /mnt/usr && x chmod 755 /usr
fi

# Fix up any directories on the new root that are not mountpoints.
for fs in tmp usr var opt home
do
	lfs=$([] 0 $(@ $fs))
	test $lfs = '/' || continue

	mode=755
	test $fs = tmp && mode=1777
	test $fs = opt && mode=775
	x chmod $mode /mnt/$fs || exit
done

# Create file system table of the new system.
fstab=/mnt/etc/fstab
test "$DEBUG" && fstab=/dev/tty

echo -n "\
# fstab - File System Table
#
# Device	Dir	Type	Options		Freq	Pass	Time
" >$fstab

devnr=1
for fs in root tmp usr var opt home
do
	dev=$([] 0 $(@ $fs))
	size=$([] 1 $(@ $fs))

	test ! $dev : / || continue	# Real devices first.

	dev=/dev/$dev dir=/$fs type=2f options=rw freq=7 pass=$devnr
	test $fs = root && dir=/
	test "$size" && options=rw,swap
	test $fs = tmp && freq=0
	devnr=$(expr $devnr + 1)

	echo -n "\
$dev	$dir	$type	$options		$freq	$pass	0
" >>$fstab
done

for fs in root tmp usr var opt home
do
	dev=$([] 0 $(@ $fs))
	size=$([] 1 $(@ $fs))

	test $dev : /. || continue	# Loopback?

	echo -n "\
$dev/.lo/$fs	/$fs	lo	rw		0	0	0
" >>$fstab
done

echo -n "
/dev/fd0	/fd0	dev	rw,noauto,user	0	0	0
/dev/fd1	/fd1	dev	rw,noauto,user	0	0	0
" >>$fstab

					# National keyboard map.
case "$keymap" in
?*)	x cp -p "/usr/lib/keymaps/$keymap.kbd" /mnt/etc/keymap
esac

test -h /mnt/usr || x umount /mnt || exit

					# Make bootable.
if [ $([] 0 $root) : '.*[0-9][0-9]*[a-d]' ]
then
	primary=$(expr $([] 0 $root) : '\(.*\).')
	x installboot -m /dev/$primary /usr/mdec/masterboot >/dev/null
fi
x installboot -d /dev/$([] 0 $root) /usr/mdec/bootblock /boot >/dev/null || exit
x edparams /dev/$([] 0 $root) \
	"rootdev=$([] 0 $root); ramimagedev=$([] 0 $root); save" || exit

echo "
Please insert the installation ROOT floppy and type 'halt' to exit Minix-vmd.
You can type 'boot $([] 0 $root)' to try the newly installed Minix-vmd system.  See
\"Testing\" in the usage manual."
