#!/usr/bin/bash
# What busybox init starts on each console.
#
# This is a wrapper around "give the user a shell" rather than the shell
# itself, and the indirection is the whole point.
#
# The obvious inittab entry is `-/usr/bin/bash --login`, and on a system with
# no accounts it appears to work perfectly. It also skips PAM -- and PAM is
# what registers a login session. pam_elogind, in the session stack, is the
# only thing that creates /run/user/<uid>: not the shell, not the kernel, not
# elogind on its own. Without that directory there is nowhere for a Wayland
# socket, a session D-Bus or any per-user runtime state to live, and the
# failure does not appear until something graphical is started, at which point
# it looks like a compositor bug.
#
# So: go through login(1) whenever there is one, and fall back to a bare shell
# only when there is not. Today there is not -- shadow is not in the live
# manifest and util-linux is built --disable-login -- so this takes the
# fallback and the result is what it always was. The moment shadow and
# linux-pam are added to ISO_EXTRA_PACKAGES, the same ISO starts registering
# proper sessions with no change to this package.

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

# Stand aside on tty1 when a greeter is going to take it.
#
# The collision is invisible until it happens and then it is the worst kind of
# visible. /dev/console follows the LAST console= on the kernel command line;
# with a serial port that is ttyS0 and this entry is nowhere near tty1, but on
# a machine with no serial port it is tty0, which is tty1 -- the terminal the
# inittab's graphical entry starts a greeter on. Two processes on one terminal
# fight over every keystroke, and on an ISO being demonstrated that is the
# failure everybody sees.
#
# The decision belongs to whoever knows whether a session will start, so it is
# asked rather than duplicated: graphical-session --would-start prints nothing
# and answers with its exit status, which means the two scripts cannot come to
# different conclusions from the same medium.
#
# Deliberately not a hold on tty2 and tty3: they are ordinary shells and no
# greeter touches them. Only the /dev/console entry can land on tty1.
console_active=$(sed -n 's/.* //p' /sys/class/tty/console/active 2>/dev/null)
case $(tty 2>/dev/null):$console_active in
	/dev/console:tty[0-9]*)
		if /usr/libexec/duct-live/graphical-session --would-start 2>/dev/null; then
			echo
			echo "duct-live: tty1 belongs to the graphical session on this medium."
			echo "duct-live: shells are on tty2 and tty3 (alt+F2, alt+F3)."
			echo
			while :; do
				sleep 3600
			done
		fi
		;;
esac

# -f root: skip authentication rather than prompt for a password nobody set.
# A live system with no accounts has no password to ask for, and a login prompt
# that cannot be satisfied is worse than none.
#
# login is not exec'd through a shell, so it inherits this process's controlling
# terminal -- which is the one busybox init opened for this inittab entry.
for login in /usr/bin/login /usr/sbin/login; do
	[ -x "$login" ] || continue
	# Announced, and not only for the log.
	#
	# BOTH branches print, so a boot test can assert a positive fact about
	# WHICH one was taken. Without this the only marker available on a system
	# that has login(1) would be one printed before console-session runs at
	# all -- and a marker that cannot distinguish "this worked" from "this was
	# never installed" is the exact weakness that let an earlier ISO ship a
	# duct-live with no console-session and still pass its boot test.
	#
	# Say what it provides rather than what it did, so the line is useful to
	# someone reading a console as well as to a grep.
	echo "duct-live: starting a PAM session via $login; pam_elogind creates /run/user/<uid>"
	exec "$login" -f root
done

# No login(1). Announce it, because a session that is not registered is a real
# difference in behaviour and not something to discover later from a puzzled
# compositor.
echo
echo "duct-live: no login(1) available -- starting a shell without a PAM session."
echo "duct-live: /run/user/\$UID will not exist; graphical sessions need shadow"
echo "duct-live: and linux-pam in the ISO manifest."
echo

exec /usr/bin/bash --login
