#!/bin/sh -eu
. /usr/libexec/init/lib.sh

fstab_file=/etc/fstab

handle_fsck_error()
{
	case $1 in
	0)	# OK
		return
		;;
	2)	# Needs re-run, still fs errors
		echo "File system still has errors; re-run fsck manually!"
		;;
	4)	# Root modified
		echo "Root file system was modified, will reboot ..."
		request_reboot
		;;
	8)	# Check failed
		echo "Automatic file system check failed; help!"
		;;
	12)	# Got signal
		echo "Boot interrupted."
		;;
	*)
		echo "Unknown error $1; help!"
		;;
	esac
	request_shell
}

do_fsck_all()
{
	if [ -e /fastboot ]; then
		echo "Fast boot: skipping filesystem checks."
		return
	fi
	trap : 2 		# Ignore SIGINT, SIGQUIT, so we
	trap : 3		# enter single-user mode on failure.

	echo "Starting file system checks:"
	fsck -x / $fsck_flags
	handle_fsck_error "$?"
}

do_fsck_root()
{
	if [ -e /fastboot ]; then
		echo "Fast boot: skipping filesystem checks."
		return
	fi
	trap : 2 		# Ignore SIGINT, SIGQUIT, so we
	trap : 3		# enter single-user mode on failure.

	# Do nothing if root file system has fs_passno=0 in /etc/fstab,
	# or if root file system is not mentioned in /etc/fstab, or if
	# root file system seems to be a network mount.
	root_in_fstab=false
	while read fs_spec fs_file fs_vfstype fs_mntops fs_freq fs_passno
	do
		# skip comment or blank line
		case "${fs_spec}" in
		\#*|'') continue ;;
		esac

		# fs_freq and fs_passno default to 0 if not specified
		: ${fs_freq:=0} ${fs_passno:=0}

		case "${fs_file},${fs_passno}" in
		/,0)
			echo "Not checking /: fs_passno = 0 in ${fstab_file}"
			return
			;;
		/,*)
			root_in_fstab=true
			case "${fs_spec}" in
			*:*)
				echo "Not checking /: network mount"
				return
				;;
			esac
			;;
		esac
	done < "${fstab_file}"

	if $root_in_fstab; then
		echo "Starting root file system check:"
		fsck $fsck_flags /
		handle_fsck_error "$?"
		return
	else
		echo "Not checking /: not listed in ${fstab_file}"
	fi
}

case "$1" in
	root)
		do_fsck_root
		;;
	all)
		do_fsck_all
		;;
	*)
		echo "fsck $1: unsupported mode"
		exit 1
		;;
esac
