#!/bin/bash -efu

. shell-error

FILES=()
DIRS=()

append_uniq()
{
	local arr i sz v
	eval "sz=\${#$1[*]}"
	for (( i=0; $i < $sz; i++ )); do
		eval "v=\"\${$1[$i]}\""
		[ "$v" != "$2" ] ||
			return 0
	done
	eval "$1+=(\"\$2\")"
}

append_progs()
{
	local n f PATH="$BUSYBOX_PATH:$SYSTEM_PATH"
	for n; do
		f=$(type -P "$n") ||
			fatal "Not found utility: $n"
		[ -n "${f##$RUNTIMEDIR/*}" ] ||
			continue
		append_uniq FILES "$f"
	done
}

for n in \
	"$RUNTIMEDIR" "$BASEDATADIR" \
	${LOCALBUILDDIR:+"${LOCALBUILDDIR-}$RUNTIMEDIR"} \
	${PUT_FEATURE_DIRS-} $PUT_DIRS;
do
	append_uniq DIRS "$n"
done

FILES+=(
	"$UDEVD"
	"$UDEVADM"
	/lib/udev/ata_id
	/lib/udev/cdrom_id
	/lib/udev/scsi_id
)

for n in \
	/lib/udev/{edd_id,vol_id,path_id,usb_id,firmware} \
	/usr/share/terminfo/l \
	/var/resolv \
	"$KERNEL_MODULES_DIR"/modules.{builtin,order,builtin.modinfo} \
	/etc/modprobe.conf;
do
	[ ! -e "$n" ] ||
		append_uniq FILES "$n"
done

append_progs \
	blkid cat chmod chroot cp depmod dmesg findmnt grep kill killall5 ln \
	logger ls lsmod mkdir mknod mktemp modprobe mount mountpoint mv \
	readlink rm rmdir setsid sh sleep start-stop-daemon switch_root \
	touch umount which ${PUT_FEATURE_PROGS-} ${PUT_PROGS-}

while read -d: -r n; do
	[ -n "$n" ] ||
		continue
	(set +f; shopt -s nullglob dotglob; printf '%s\n' "$n"/*) > "$TEMPDIR/list"
	while read -r bin; do
		[ -n "$bin" ] ||
			continue
		for pattern in '*/shell-*' ${PUT_FEATURE_PROGS_WILDCARD-}; do
			[ -z "${bin##$pattern}" ] ||
				continue
			[ -n "${bin##$RUNTIMEDIR/*}" ] ||
				continue
			append_uniq FILES "$bin"
		done
	done < "$TEMPDIR/list"
done <<<"$BUSYBOX_PATH:$SYSTEM_PATH"
rm -f -- "$TEMPDIR/list"

for n in ${PUT_FEATURE_FILES-} $PUT_FILES; do
	append_uniq FILES "$n"
done

cd "$ROOTDIR"

mkdir $verbose -p -- \
	./.initrd/{killall,uevent/events,uevent/queues/udev/.tmp} \
	./etc/{{initrd,modprobe.d,sysconfig},udev/rules.d} \
	./lib/{udev,initrd/{all,kmodules,post,pre}} \
	./var/{lock/subsys,log,run} \
	./{home/root,dev,mnt,root,run,proc,sys,tmp,bin,sbin} \
	./"$KERNEL_MODULES_DIR" \
	#

initrd-release

mkfifo ./.initrd/telinit
mkfifo ./.initrd/rdshell

printf '%s\n' "${DIRS[@]}"  |xargs -r put-tree .
printf '%s\n' "${FILES[@]}" |xargs -r put-file .

if [ ".$UDEVD" != ./sbin/udevd ]; then
	mkdir -p -- ./sbin
	mv $verbose -f -- ".$UDEVD" ./sbin/udevd
	ln $verbose -s -- /sbin/udevd ".$UDEVD"
fi

if [ ".$UDEVADM" != ./sbin/udevadm ]; then
	mkdir -p -- ./sbin
	mv $verbose -f -- ".$UDEVADM" ./sbin/udevadm
	ln $verbose -s -- /sbin/udevadm ".$UDEVADM"
fi

for i in rc0 rc1 rc2 rc3 rc4 rc5 rc6 init; do
	mkdir -p "./etc/rc.d/$i.d"
	ln -s -f "rc.d/$i.d" "./etc/$i.d"
done

for n in group gshadow passwd shadow fstab; do
	touch "./etc/$n"
done

# No shell access inside initramfs by default.
[ -s ./etc/sysconfig/rdshell ] ||
	printf 'RDSHELL_MODE=disable\n' >./etc/sysconfig/rdshell

if [ ! -x ./bin/sh ]; then
	for n in bash dash mksh ash; do
		[ -x "./bin/$n" ] || continue
		verbose "Setting $n as /bin/sh ..."
		ln -s "$n" ./bin/sh
		break
	done
fi

for d in lib etc; do
	if [ -d "/$d/modprobe.d" ]; then
		verbose "Copying files from $d/modprobe.d ..."
		find -L "/$d/modprobe.d" \
				-name '*.conf' \
			-exec cp -aLt ./etc/modprobe.d -- '{}' '+'
	fi

	if [ -d "/$d/udev/initramfs-rules.d" ]; then
		verbose "Copying files from /$d/udev/initramfs-rules.d ..."
		find -L "/$d/udev/initramfs-rules.d" \
				-name '*.rules' \
			-exec cp -aLt ./etc/udev/rules.d -- '{}' '+'
	fi
done
