# -*- shell-script -*-

_log_msg()
{
	if [ "$quiet" = "y" ]; then return; fi
	echo "$@"
}

log_success_msg()
{
	_log_msg "Success: $@"
}

log_failure_msg()
{
	_log_msg "Failure: $@"
}

log_warning_msg()
{
	_log_msg "Warning: $@"
}

log_begin_msg()
{
	if [ -x /sbin/usplash_write ]; then
		/sbin/usplash_write "TEXT $@"
	fi
	_log_msg "Begin: $@ ..."
}

log_end_msg()
{
	if [ -x /sbin/usplash_write ]; then
		/sbin/usplash_write "SUCCESS ok"
	fi
	_log_msg "Done."
}

panic()
{
	if [ -x /sbin/usplash_write ]; then
		/sbin/usplash_write "QUIT"
	fi
	# Disallow console access
	if [ "${panic}" = 0 ]; then
		reboot
	fi

	# Call mountroot failure hooks if requested.
	if [ "${1}" = "-r" ]; then
		shift 1

		if [ -r "/tmp/mountroot-fail.hooks" ]; then
			mountroot_fail_hooks=$(cat /tmp/mountroot-fail.hooks)
			for mr_fh in ${mountroot_fail_hooks}; do
				${mr_fh} mountfail
			done
		fi
	fi

	modprobe -Qb i8042
	modprobe -Qb atkbd
	echo $@
	PS1='(initramfs) ' /bin/sh -i </dev/console >/dev/console 2>&1
}

maybe_break()
{
	if [ x$1 = x${break} ]; then
		panic "Spawning shell within the initramfs"
	fi
}

render()
{
	eval "echo -n \${$@}"
}

set_initlist()
{
	unset initlist
	for si_x in ${initdir}/*; do
		if [ ! -x ${si_x} ]; then
			continue
		fi
		initlist="${initlist} ${si_x#${initdir}/}"
	done
}

reduce_satisfied()
{
	deplist="$(render array_${1})"
	unset tmpdeplist
	for rs_y in ${deplist}; do
		case $rs_y in
		*\|*)
			OLD_IFS="$IFS"
			IFS='|'
			for rs_z in $rs_y; do
				IFS="$OLD_IFS"
				if [ ! -f ${initdir}/${rs_z} ]; then
					IFS='|'
					continue
				fi
				tmpdeplist="${tmpdeplist} ${rs_z}"
				break
			done
			IFS="$OLD_IFS"
			;;
		*)
			if [ ! -f ${initdir}/${rs_y} ]; then
				continue
			fi
			tmpdeplist="${tmpdeplist} ${rs_y}"
			;;
		esac
	done
	deplist=${tmpdeplist}
	for rs_x in ${runlist}; do
		pop_list_item ${rs_x} ${deplist}
		deplist=${tmppop}
	done
	eval array_${1}=\"${deplist}\"
}

get_prereqs()
{
	set_initlist
	for gp_x in ${initlist}; do
		tmp=$(${initdir}/${gp_x} prereqs)
		eval array_${gp_x}=\"${tmp}\"
	done
}

count_unsatisfied()
{
	set -- ${@}
	return ${#}
}

# Removes $1 from initlist
pop_list_item()
{
	item=${1}
	shift
	set -- ${@}
	unset tmppop
	# Iterate
	for pop in ${@}; do
		if [ ${pop} = ${item} ]; then
			continue
		fi
		tmppop="${tmppop} ${pop}"
	done

}

# This function generates the runlist, so we clear it first.
reduce_prereqs()
{
	unset runlist
	set_initlist
	set -- ${initlist}
	i=$#
	# Loop until there's no more in the queue to loop through
	while [ ${i} -ne 0 ]; do
		oldi=${i}
		for rp_x in ${initlist}; do
			reduce_satisfied ${rp_x}
			count_unsatisfied $(render array_${rp_x})
			cnt=${?}
			if [ ${cnt} -eq 0 ]; then
				runlist="${runlist} ${rp_x}"
				pop_list_item ${rp_x} ${initlist}
				initlist=${tmppop}
				i=$((${i} - 1))
			fi
		done
		if [ ${i} -eq ${oldi} ]; then
			panic "PANIC: Circular dependancy.  Exiting."
		fi
	done
}

call_scripts()
{
	for cs_x in ${runlist}; do
		# mkinitramfs verbose output
		if [ "${verbose}" = "y" ]; then
			echo "Calling hook ${cs_x}"
		fi
		${initdir}/${cs_x}
		# allow boot scripts to modify exported boot paramaters
		if [ -e /conf/param.conf ]; then
			. /conf/param.conf
		fi
	done
}

run_scripts()
{
	initdir=${1}
	get_prereqs
	reduce_prereqs
	call_scripts
}

# Load custom modules first
load_modules()
{
	if [ -e /conf/modules ]; then
		cat /conf/modules | while read m; do
			# Skip empty lines
			if [ -z "$m" ];  then
				continue
			fi
			# Skip comments - d?ash removes whitespace prefix
			com=$(printf "%.1s" "${m}")
			if [ "$com" = "#" ]; then
				continue
			fi
			modprobe -Qb $m
		done
	fi
}

# lilo compatibility
parse_numeric() {
	case $1 in
	"")
		return
		;;
	/*)
		return
		;;
	*:*)
		minor=${1#*:}
		major=${1%:*}
		;;
	*)
		value=$(( 0x${1} ))
		minor=$(( ${value} % 256 ))
		major=$(( ${value} / 256 ))
		;;
	esac

	mknod /dev/root b ${major} ${minor}
	ROOT=/dev/root
}

add_mountroot_fail_hook()
{
	echo "$0" >> /tmp/mountroot-fail.hooks
}
