#!/bin/sh

# live-tools(7) - System Support Scripts
# Copyright (C) 2016-2020 The Debian Live team
# Copyright (C) 2006-2015 Daniel Baumann <mail@daniel-baumann.ch>
#
# This program comes with ABSOLUTELY NO WARRANTY; for details see COPYING.
# This is free software, and you are welcome to redistribute it
# under certain conditions; see COPYING for details.

set -e

# Exit if system is not a live system
if ! grep -qs "boot=live" /proc/cmdline || \
# Exit if system is netboot
   grep -qs "netboot" /proc/cmdline || \
   grep -qs "root=/dev/nfs" /proc/cmdline || \
   grep -qs "root=/dev/cifs" /proc/cmdline || \
# Exit if system is findiso
   grep -qs "findiso" /proc/cmdline || \
# Exit if system is toram
   grep -qs "toram" /proc/cmdline || \
# Exit if user disabled medium eject
   grep -qs "cdrom-detect/eject=false" /proc/cmdline || \
   grep -qs "noeject" /proc/cmdline
then
	exit 0
fi

# Reading configuration files from filesystem and live-medium
for _FILE in /etc/live/tools.conf /etc/live/tools/* \
	     /run/live/medium/live/tools.conf /run/live/medium/live/tools/*
do
	if [ -e "${_FILE}" ]
	then
		. "${_FILE}"
	fi
done

# Setting defaults
LIVE_MEDIUM_EJECT_VERBOSE="${LIVE_MEDIUM_EJECT_VERBOSE:-true}"
# Seconds to wait for ENTER / plymouth keystroke before continuing shutdown.
# Graphical sessions never see /dev/console; an infinite read hung runit/s6 stage 3.
LIVE_MEDIUM_EJECT_TIMEOUT="${LIVE_MEDIUM_EJECT_TIMEOUT:-8}"

# Ejecting live-medium
_DEVICE="$(findmnt -Un -o source /run/live/medium 2>/dev/null | sed -e 's|^/dev/||')" || true

# Systemd version >=253, the mount point for live medium is remounted dynamically when rebooting/halting.
# Mount point is like /run/shutdown/mounts/4fefd9f5c22cea7e
if [ -z "${_DEVICE}" ]
then
	live_media_mnt="$(df --output=target 2>/dev/null | grep -Ew "^/run/shutdown/mounts" || true)"
	if [ -n "${live_media_mnt}" ]
	then
		_DEVICE="$(findmnt -Un -o source ${live_media_mnt} 2>/dev/null | sed -e 's|^/dev/||')" || true
	fi
fi

if [ ! -b "/dev/${_DEVICE}" ]
then
	exit 0
fi

case "${_DEVICE}" in
	sd*)
		_DEVICE=$(echo $_DEVICE | sed -e 's/[0-9]*$//')
		if readlink "/sys/block/${_DEVICE}" | grep -q usb
		then
			# ignoring usb mass storage devices
			# (they need coldreboot to recover)
			exit 0
		fi
		;;
esac

EJECT_PID=
if command -v eject >/dev/null 2>&1
then
	# Delay eject briefly so the prompt (if any) can show first.
	# Do not wait forever afterwards — virtual CD eject can hang (e.g. QEMU).
	(sleep 1; eject -p -m /dev/${_DEVICE}) >/dev/null 2>&1 &
	EJECT_PID=$!
fi

prompt_with_timeout() {
	_timeout="${LIVE_MEDIUM_EJECT_TIMEOUT}"
	case "${_timeout}" in
		""|0|*[!0-9]*) _timeout=8 ;;
	esac
	if command -v timeout >/dev/null 2>&1
	then
		timeout "${_timeout}" "$@" || true
	else
		# No timeout(1): skip blocking wait so shutdown can finish.
		:
	fi
}

case "${LIVE_MEDIUM_EJECT_VERBOSE}" in
	true)
		if [ -x /bin/plymouth ] && plymouth --ping
		then
			plymouth message --text="Please remove the live-medium, close the tray (if any) and press ENTER to continue:"
			prompt_with_timeout plymouth watch-keystroke > /dev/null
		else
			stty sane < /dev/console 2>/dev/null || true

			printf "\n\nPlease remove the live-medium, close the tray (if any) and press ENTER to continue (timeout %ss):\n" \
				"${LIVE_MEDIUM_EJECT_TIMEOUT}" > /dev/console

			prompt_with_timeout sh -c 'read x < /dev/console'
		fi
		;;
esac

if [ -n "${EJECT_PID}" ]; then
	# Give background eject a short window; never block stage 3 indefinitely.
	if command -v timeout >/dev/null 2>&1
	then
		timeout 5 sh -c "while kill -0 ${EJECT_PID} 2>/dev/null; do sleep 0.2; done" || true
		kill "${EJECT_PID}" 2>/dev/null || true
	fi
	wait "${EJECT_PID}" 2>/dev/null || true
fi
