#!/bin/bash
### BEGIN INIT INFO
# Provides:            fstab
# Required-Start:      cmdline
# Should-Start:
# Required-Stop:
# Should-Stop:
# Default-Start:       3 4 5
# Default-Stop:
# Short-Description:   Creates /etc/fstab.
# Description:         Creates /etc/fstab.
### END INIT INFO

[ "$1" = start ] || exit 0

. /.initrd/initenv
. /etc/init.d/functions

convert_dev()
{
	local retval dev value major minor
	retval="$1"
	dev="$2"

	case "$dev" in
		[0-9]*:[0-9]*)
			value="/dev/block/$dev"
			;;
		[0-9A-Fa-f]*)
			if (_=$(( 0x$dev ))) 2>/dev/null; then
				value=$(( 0x$dev ))
				major=$(( $value / 256 ))
				minor=$(( $value % 256 ))
				value="/dev/block/$major:$minor"
			else
				value="$dev"
			fi
			;;
		*)
			value="$dev"
			;;
	esac
	eval "$retval=\"\$value\""
}

in_list()
{
	local elem="$1"; shift
	while [ "$#" -gt 0 ]; do
		[ "$elem" != "$1" ] || return 0
		shift
	done
	return 1
}

gen_fstab()
{
	local i dev path str ndev ro fstab userdef_mounts

	userdef_mounts=()
	fstab=("")

	for conf in /etc/fstab /etc/fstab.d/*.conf; do
		[ -s "$conf" ] ||
			continue

		while read -r dev path str; do
			[ -n "${dev##\#*}" ] && [ -z "${path##/*}" ] ||
				continue

			i="${#fstab[@]}"

			case "$path" in
				/)
					i=0
					path="$rootmnt"
					;;
				/proc|/proc/*|/dev|/dev/*|/.initrd|/.initrd/*)
					continue
					;;
				/run|/sys)
					userdef_mounts+=("$path")
					;;
				/*)
					path="$rootmnt$path"
					;;
			esac

			convert_dev ndev "$dev"

			fstab[$i]="$ndev $path $str"
		done < "$conf"
	done

	if [ -n "${ROOT-}" ]; then
		convert_dev ndev "$ROOT"
		ROOTFLAGS="${ROOTFLAGS:-defaults}"

		ro=rw
		[ -z "$READONLY" ] || ro=ro

		fstab[0]="$ndev $rootmnt ${ROOTFSTYPE:-auto} $ro${ROOTFLAGS:+,$ROOTFLAGS} 1 1"
	fi

	[ -n "${fstab[0]-}" ] || [ -z "${DEBUG-}" ] ||
		echo "Root device unspecified." >&2

	if grep -qsw devtmpfs /proc/filesystems; then
		fstab+=("udevfs /dev devtmpfs mode=755,size=5m 0 0")
	elif grep -qsw tmpfs /proc/filesystems; then
		fstab+=("udevfs /dev tmpfs mode=755,size=5m 0 0")
	else
		echo "devtmpfs and tmpfs are not supported by the kernel." >&2
	fi

	in_list /run "${userdef_mounts[@]}" ||
		fstab+=("runfs /run tmpfs mode=755 0 0")

	in_list /sys "${userdef_mounts[@]}" ||
		fstab+=("sysfs /sys sysfs nodev,noexec,nosuid 0 0")

	modprobe -q fs-efivarfs >/dev/null 2>&1 ||:

	if grep -qsw efivarfs /proc/filesystems; then
		fstab+=("efivarfs /sys/firmware/efi/efivars efivarfs rw,nosuid,nodev,noexec,relatime 0 0")
	fi

	printf '%s\n' "${fstab[@]}" > /etc/fstab
}

action_shell 'Creating /etc/fstab:' gen_fstab
