#!	/bin/sh
# Please make sure this file can be executed by both "bash" and "ash".
# Most of this script is copied from the boot-floppies package, under
# /usr/src/boot-floppies*/scripts/rootdisk/prototype/Install/. If you
# fix something here, fix it there as well.

umask 022
readonly rm=rm
readonly ModuleHelp=$Target/usr/lib/module_help

readonly TempFile="/tmp/`echo $0|sed -e 's/^.*\///'`.$$"

readonly bold='[1m'
readonly clear='[H[J'
readonly norm='[0;10m'

count_words () {
	echo "$#"
}

# Pick the first word from a variable.
first () {
	echo "$1"
}

# Pick the second word from a variable.
second () {
	echo "$2"
}

# Pick the third word from a variable.
third () {
	echo "$3"
}

# Pick the fourth word from a variable.
fourth () {
	echo "$4"
}

last () {
	eval echo $"$#"
}

write_it_down () {
	local reply
	echo ""
	echo "$bold"\
"Something went wrong. You might want to write down the error messages
before you continue. Please press ENTER when you are ready.$norm"
	read reply
	return $?
}

# Shell interface to "dialog"
# Bruce Perens, November 1995
# This is free software under the GNU General Public License.

# Global options
#	The variable $BACKTITLE specifies the back title.
#	The variable $DIALOG_OPTIONS, initialized here to --clear, provides
#	options you want on the command line of each dialog invocation.
#	The variable $DIALOG_TEST can be set to "echo" to see the calls
#	to dialog without executing them.

DIALOG_OPTIONS=""

# Make any dialogue box, with default settings and backtitle from
# $BACKTITLE in the environment.
#
# dialog --type arg arg ...
#
dialogBox () {
	local type="$1"
	shift
	local title=""
	local backtitle=""

	local text="$1"
	shift

	if [ $# -ge 1 ]; then
		title="$1"
		shift
	fi

	if [ -n "$BACKTITLE" ]; then
		backtitle="$BACKTITLE"
	fi

	$DIALOG_TEST dialog $DIALOG_OPTIONS --title "$title" --backtitle \
	 "$backtitle" "$type" "$text" 0 0 "$@" 2>&1 1>/dev/tty
	local result=$?
	return $result
}

# Display a file.
#
# fileBox filename [title]
#
fileBox () {
	dialogBox --textbox "$1" "$2"
}

# textBox takes presents its standard input in a dialog box. This
# is useful for "here documents" and pipes.
#
# textBox [title]
#
textBox () {
	cat >$TempFile

	if [ $? -ne 0 ]; then
		echo "Can't make temporary file for dialog box." 1>&2
		return -1
	fi

	# Note that dialog needs stdin to be the terminal, so I redirect here.
	< /dev/tty dialogBox --textbox $TempFile "$1"
	local result=$?
	${rm} -f $TempFile
	return $result
}

msgBox () {
	dialogBox --msgbox "$1" "$2"
}

infoBox () {
	dialogBox --infobox "$1" "$2"
}

yesNoBox () {
	dialogBox --yesno "$1" "$2"
}

inputBox () {
	dialogBox --inputbox "$1" "$2" "$3"
}

# menu text title tag1 item1 ...
menu () {
	local text="$1"
	shift
	local title="$1"
	shift
	dialogBox --menu "$text" "$title" 0 "$@"
}

# menu text title tag1 item1 status1 ...
checklist () {
	local text="$1"
	shift
	local title="$1"
	shift
	dialogBox --checklist "$text" "$title" 0 "$@"
}

# menu text title tag1 item1 status1 ...
radiolist () {
	local text="$1"
	shift
	local title="$1"
	shift
	dialogBox --radiolist "$text" "$title" 0 "$@"
}

build_lists () {
	installed_module_list="`sed -e '/#.*$/d' -e 's/[ 	].*$//' \
	 < $Target/etc/modules`"
	module_help_list="`(cd $ModuleHelp/modules; echo *)`"
	argument_help_list="`(cd $ModuleHelp/arguments; echo *)`"
	return 0;
}

in_list ()
{
	for i in $1; do
		if [ $i = $2 ]; then
			return 0
		fi
	done
	return 1
}

module_is_installed () {
	in_list "$installed_module_list" $1
	local status=$?
	return $status
}

module_argument_help () {
	if in_list "$module_argument_help_list" $1; then
		sed -e '1d' < $ModuleHelp/arguments/$1
		echo ""
	fi
}

module_help () {
	if in_list "$module_help_list" $1; then
		help=`sed -e '1d' < $ModuleHelp/modules/$1`
	fi
}

module_summary () {
	local summary=""

	if in_list "$module_help_list" $1; then
		read summary < $ModuleHelp/modules/$1
	fi

	echo -n $summary
}

build_module_directory_menu () {
	local list

	list="$1/*.o"

	for i in $list; do
		local module="`echo $i | sed -e 's:^.*/::' -e 's/\.o$//'`"
		if [ "$module" != '*' ]; then
			local selected="-"

			if module_is_installed $module; then
				selected="+"
			fi

			echo -n \"$module\" \"$selected" "
			module_summary $module
			echo \" \\
		fi
	done
	echo ""
}

module_directory_menu () {
	local directory="$1"
	local text="$2"
	local title="$3"

	build_lists

	while true; do
		echo 'menu "$text" "$title" \' > $TempFile.1
		echo '"Exit" \
		 "  Finished with these modules. Return to the previous menu." \' \
		 >> $TempFile.1
		echo '" " " " \' >> $TempFile.1
		
		infoBox "Please wait while modules are detected." "Please wait"

		build_module_directory_menu $directory >> $TempFile.1

		while true; do
			local result
			result="$(. $TempFile.1)"
			if [ $? -ne 0 -o -z "$result" ]; then return 1; fi

			case "$result" in
			" ")
				;;
			Exit)
				return 0;;
			*)
				edit_module "$result"
				break
				;;
			esac
		done
		${rm} -f $TempFile.1
	done
}

edit_module () {
	local module="$1"
	local help="`module_help $module`"
	local selected="-"
	local text="$help
The $module module is not currently installed."

	if module_is_installed $module; then
		selected="+"
		text="$help""The $module module is currently installed."
	fi

	cat > $TempFile.2 << EOF
	menu "$text" "Module $module $selected" \\
	"Exit" "Finished with this module. Return to the previous menu" \\
EOF
	
	if [ "$selected" = "+" ]; then
		echo '"Remove" "Remove the module from the kernel." \' >> $TempFile.2
	else
		echo '"Install" "Install the module in the kernel." \' >> $TempFile.2
	fi

	echo "" >> $TempFile.2

	local result
	result="$(. $TempFile.2)"
	local status=$?
	${rm} -f $TempFile.2

	if [ $status -ne 0 -o -z "$result" ]; then return 1; fi

	case "$result" in
	Exit)
		return 0
		;;
	Install)
		install_module $module
		return 0
		;;
	Remove)
		remove_module $module
		return 0
		;;
	esac
	return 1
}

edit_arguments ()
{
	local module="$1"
	local commands="`module_argument_help $module`"
	local old_arguments="`sed -n -e '/options[ 	]*'$module'[ 	]*/p' \
	 < $Target/etc/conf.modules \
	 | sed -e 's/options[ 	]*'$module'[ 	]*//'`"
	local arguments
	arguments="`inputBox \
"$commands
Please enter any command-line arguments for the $module module." \
	 "Enter Command-Line Arguments" $old_arguments`"
	if [ $? -ne 0 ]; then return 1; fi

	if [ "$old_arguments" != "$arguments" ]; then
		${rm} -f $Target/etc/conf.modules.new
		sed '/options[ 	]*'$module'[ 	]/d' < $Target/etc/conf.modules \
		 > $Target/etc/conf.modules.new
		chown root.root $Target/etc/conf.modules.new
		chmod 644 $Target/etc/conf.modules.new
		if [ -n "$arguments" ]; then
			echo "options $module $arguments" >> $Target/etc/conf.modules.new
		fi
		sync
		${rm} -f $Target/etc/conf.modules.old
		ln $Target/etc/conf.modules $Target/etc/conf.modules.old
		mv -f $Target/etc/conf.modules.new $Target/etc/conf.modules
		sync
	fi
}

install_module () {
	local module="$1"
	sync

	edit_arguments $module

	echo $clear$bold\
"Installing module $module. If the device isn't there, or isn't configured
correctly, this could cause your system to pause for up to a minute."$norm
	echo ""
	sync
	modprobe $module
	local status=$?

	echo ""
	if [ $status -eq 0 ]; then
		echo "Installation succeeded."
		echo "$module" >> $Target/etc/modules
	else
		echo "Installation failed."
	fi

	echo ""
	echo "$bold""Please press ENTER when you are ready to continue.$norm"
	local reply
	read reply

}

remove_module () {
	sync
	local module="$1"

	echo $clear$bold\
"Removing module $module..."$norm
	echo ""
	sync
	modprobe -r $module
	if [ $? -ne 0 ]; then
		write_it_down
		msgBox "$module was not removed." "Problem"
		return 1
	fi
	${rm} -f $Target/etc/modules.tmp
	sed -e /^$module\$/d < $Target/etc/modules >$Target/etc/modules.tmp
	if [ $? -ne 0 ]; then return 1; fi
	chmod 644 $Target/etc/modules.tmp
	chown root.root $Target/etc/modules.tmp
	sync
	${rm} -f $Target/etc/modules.old
	ln $Target/etc/modules $Target/etc/modules.old
	mv $Target/etc/modules.tmp $Target/etc/modules
	sync

	return 0
}

modules () {
	KernelVersion=$(third `cat /proc/version`)
	if [ $? -ne 0 -o -z "$KernelVersion" ]; then
		msgBox \
"I couldn't find the kernel version.
Please make sure /proc is mounted." "Problem"
		return 1
	fi

	local text=\
"Modules are loadable device drivers. Please go through the menus
for each category and look for devices, network protocols, filesystems,
etc. that you would like to have supported by your system. You should
not install modules for devices that aren't installed in your system,
as they will sometimes cause the system to pause for a long time while
it is searching for the device. Also, drivers for devices that you
don't have use memory that you could put to better use.

Please select the category of modules."

	echo 'menu "$text" "Select Category" \' > $TempFile

	echo '"Exit" \
	 " Finished with modules. Return to the previous menu." \' \
	 >> $TempFile
	echo '" " " " \' >> $TempFile
	
	for i in $Target/lib/modules/$KernelVersion/*; do
		if [ ! -d $i ]; then continue; fi
		local directory=`echo $i | sed -e 's:^.*/::'`
		local help=""
		local summary=" "

		if [ -f $ModuleHelp/$KernelVersion/directories/$directory ]
		then
			help="$ModuleHelp/$KernelVersion/directories/$directory"
		elif [ -f $ModuleHelp/directories/$directory ]; then
			help="$ModuleHelp/directories/$directory"
		fi

		if [ -n "$help" ]; then
			read summary < $help
		fi

		echo "\"$directory\"" \\ >> $TempFile
		echo "\"$summary"\" \\ >> $TempFile
	done
	echo "" >> $TempFile

	while true; do
		local result status
		result="`. $TempFile`"
		if [ $? -ne 0 -o -z "$result" ]; then return 1; fi

		case "$result" in
		" ")
			;;
		Exit)
			return 0;;
		*)
			module_directory_menu \
			 "$Target/lib/modules/$KernelVersion/$result" \
"The modules that are currently installed on your system have
a \"+\" character to the right of their name. Modules that aren't
installed have a \"-\" to the right of their name. You can read a
page about the purpose of any module and then you can enable
or disable it. To do so, use the up and down arrow keys to move
the cursor to the line for the module, and then press ENTER." \
"Select $d modules"
			;;
		esac
	done
	${rm} -f $TempFile
}

modules "$1"
${rm}  -f $TempFile $TempFile.1 $TempFile.2
exit 0
