#!/bin/sh

PREFIX=/usr
: ${LIBDIR=$PREFIX/lib}
. "$LIBDIR/libalpine.sh"

usage() {
	cat <<-__EOF__
		usage: genfstab [-h] [-U] ROOT

		Generate fstab entries from mounted filesystems below ROOT.

		options:
		 -h  Show this help
		 -U  Use UUIDs for device identifiers
	__EOF__
	exit $1
}

die() {
	echo "$@" >&2
	exit 1
}

blkid_uuid() {
	local dev="$1"
	blkid 2>/dev/null | sed -n "s|^$dev:.* UUID=\"\\([^\"]*\\)\".*|\\1|p"
}

source_spec() {
	local dev="$1" value= i=
	case "$dev" in
		"${ROOT}"/dev/*) dev="/dev/${dev#"${ROOT}"/dev/}";;
	esac
	if [ "$uuid" -eq 1 ]; then
		for i in $NO_DISK_UUID; do
			if [ "$i" = "$dev" ]; then
				printf "%s" "$dev"
				return
			fi
		done
		case "$dev" in
			/dev/md*) printf "%s" "$dev"; return;;
		esac
		value=$(blkid_uuid "$dev")
		if [ -n "$value" ]; then
			printf "UUID=%s" "$value"
			return
		fi
	fi
	printf "%s" "$dev"
}

is_pseudofs() {
	case "$1" in
		autofs|binfmt_misc|bpf|cgroup|cgroup2|configfs|debugfs|devpts|devtmpfs|efivarfs|fusectl|hugetlbfs|mqueue|proc|pstore|securityfs|sysfs|tracefs)
			return 0
			;;
	esac
	return 1
}

print_mounts() {
	local root="$1"
	local fs_spec= fs_file= fs_vfstype= fs_mntops= fs_freq= fs_passno=
	local mountpoint= passno=

	awk -v root="${root%/}/" 'substr($2 "/", 1, length(root)) == root' \
		"${ROOT}proc/mounts" | \
		while read -r fs_spec fs_file fs_vfstype fs_mntops fs_freq fs_passno; do
			if is_pseudofs "$fs_vfstype"; then
				continue
			fi

			mountpoint=${fs_file#"$root"}
			[ -n "$mountpoint" ] || mountpoint=/
			case "$mountpoint" in
				/*) ;;
				*) mountpoint="/$mountpoint";;
			esac
			mountpoint=$(echo "$mountpoint" | sed -E 's:/+:/:g')

			if [ "$mountpoint" = / ]; then
				passno=1
			else
				passno=2
			fi

			printf "%s\t%s\t%s\t%s\t0 %s\n" \
				"$(source_spec "$fs_spec")" \
				"$mountpoint" \
				"$fs_vfstype" \
				"$fs_mntops" \
				"$passno"
		done
}

uuid=0
while getopts "hU" opt; do
	case "$opt" in
		h) usage 0;;
		U) uuid=1;;
		'?') usage 1 >&2;;
	esac
done
shift $((OPTIND - 1))

[ $# -eq 1 ] || usage 1 >&2

root=$(cd "$1" 2>/dev/null && pwd -P) || die "genfstab: $1 is not a directory"

print_mounts "$root"
