#!/bin/sh
# Set up device nodes and /servers translators.
#
# Use cases:
#   - from d-i's /libexec/runsystem, to create a minimal set of device nodes
#     and translators for the installer environment;
#   - from debootstrap on initial installation, to create device and server
#     nodes before /dev and /servers are firmlinked to the host system.
#   - from hurd.postinst, on upgrade, where only non-existant nodes should be
#     created, and the other ones should be left alone.


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

usage () {
cat >&2 <<EOU
Usage: $0 [OPTIONS]
Set up device nodes and /servers translators.

  -k, --keep-active      Keep active translators running
  -K, --keep-all         Don't even set passive translators on existing files
  -m, --minimal          Create a minimal subset of nodes only
  -p, --parted           Prefer parted stores for partition devices

At least one of -k or -K must be given.
EOU
}

# Parse command-line arguments
REPLACE=
MDFLAGS=
MINIMAL=
while [ $# -gt 0 ]; do
	case "$1" in
	    -k|--keep-active)
		MDFLAGS="$MDFLAGS -k"
		REPLACE=y
		shift;;
	    -K|--keep-all)
		MDFLAGS="$MDFLAGS -K"
		REPLACE=n
		shift;;
	    -m|--minimal)
		MINIMAL=y
		shift;;
	    -p|--parted)
		MDFLAGS="$MDFLAGS -p"
		shift;;
	    *) 
		usage
		exit 1;;
	esac
done

if [ -z "$REPLACE" ]; then
	usage
	exit 1
fi

# Usage: foldsubst <pat> xxxx yyyy zzzz ...
# <pat> is substituted for every character of xxxx with sed, the character in
# question being accessible as a '\0' in <pat>, and the result is used as the
# new pattern to handle the remaining arguments.
foldsubst () {
	[ "$2" ] || { echo $1; return; }
	expanded=$(echo "$2" | sed "s/./ $1/g"); shift 2
	foldsubst "$expanded" $@;
}

# Verbosely attach a translator.
st () {
	node=$1
	cmdl=$2
	name=${3:-$cmdl}

	echo -n " $name"
	if [ "$REPLACE" = y ] || ! showtrans $1 > /dev/null 2>&1 ; then
		# Work around a bug in ext2fs, which crashes if a non-empty
		# file is turned into a symlink through settrans, by clearing
		# the passive translator first.
		settrans -ck $node
		settrans -ck $node $cmdl
	fi
}

# Verbosely create device nodes, with some help from foldsubst.
md () {
	pattern=$1; shift
	sedrepl=$(echo $pattern | sed -e 's/X/\\0/' -e 's/Y/\\\\0/')
	devs=$(foldsubst "$sedrepl" $@)

	echo -n " $pattern"
	/sbin/MAKEDEV $MDFLAGS $devs
}


echo -n "Setting up translators:"
cd /servers
mkdir -p socket
mkdir -p bus/pci

st exec /hurd/exec
touch default-pager 2> /dev/null
chmod 755 default-pager
st default-pager /hurd/proxy-defpager
st socket/1 /hurd/pflocal
st socket/local '/hurd/symlink 1' '(+link)'
st socket/2 '/hurd/pfinet -6 /servers/socket/26' inet
st socket/inet  '/hurd/symlink 2'  '(+link)'
st socket/26 '/hurd/pfinet -4 /servers/socket/2' inet6
st socket/inet6 '/hurd/symlink 26' '(+link)'
st bus/pci /hurd/pci-arbiter
st acpi /hurd/acpi
st shutdown /hurd/shutdown
touch startup 2> /dev/null

if [ -z "$MINIMAL" ]; then
	st password /hurd/password
	st crash-kill '/hurd/crash --kill' crash-kill
	st crash-suspend '/hurd/crash --suspend' crash-suspend
	st crash-dump-core '/hurd/crash --dump-core' crash-dump-core
	if [ "$(uname -m)" = x86_64 ]; then
		st crash '/hurd/symlink crash-kill' crash
	else
		st crash '/hurd/symlink crash-dump-core' crash
	fi
fi

echo .


echo -n "Creating device nodes:"
cd /dev

md fd
md fdX 01
md std
md vcs
md hdX 012345
md hdXsY 012345 123456789
md hdXs1Y 012345 0123456
md sdX 012345
md sdXsY 012345 123456789
md sdXs1Y 012345 0123456
md rumpdisk
md wdX 012345
md wdXsY 012345 123456789
md wdXs1Y 012345 0123456
md rumpusbdisk
md udX 012345
md udXsY 012345 123456789
md udXs1Y 012345 0123456
md cdX 01
md ucdX 01
md netdde
md ethX 0123
md pseudo-root
md rtc

[ -r /var/lib/random-seed ] || date ${SOURCE_DATE_EPOCH:+--date=@${SOURCE_DATE_EPOCH}} > /var/lib/random-seed 2> /dev/null
chmod 600 /var/lib/random-seed

if [ "$MINIMAL" ]; then
	md loopX 0123
	md ttyX 1234
	md ptypX 0123456789
	md comX 0123
else
	md loopX 01234567
	md ttyX 123456
	md ptyp
	md ptyq
	md lprX 012
	md comX 0123
fi

st random "/hurd/random --seed-file /var/lib/random-seed" random
st urandom "/hurd/random --seed-file /var/lib/random-seed --fast" urandom

st kbd '/hurd/symlink cons/kbd' kbd
st mouse '/hurd/symlink cons/mouse' mouse
! [ -L shm ] || rm -f shm
! [ -d shm ] || rmdir shm

# TODO let initscript make it a tmpfs when tmpfs open/mmap/close/unlink/dereference crash is fixed, see #923078 and /lib/init/tmpfs.sh
st shm '/hurd/symlink /tmp' shm

echo .

