#!/bin/sh
# $Id: rc-boot,v 1.23 2002/07/13 22:44:04 misiek Exp $

umask 0177

#LOG_FILE=

# utils:

log () {
	if test "$LOG_FILE" ; then
		echo "$*" >> $LOG_FILE
	fi
}

msg () {
	echo 1>&2 "$*"
	log "$*"
}

debug () {
	if [ "$DEBUG" = "yes" ]; then
		msg "   $*"
	fi
}

die () {
	msg "$*"
	exit 1
}

is_yes () {
	case "$1" in
		[yY][eE][sS] | 1)
		return 0
		;;
	[nN][oO] | 0)
		return 1
		;;
	* )
		die "bad value for yes/no option: '$1'"
		;;
	esac
}

lower () {
	echo "$*" | tr 'A-Z' 'a-z'
}

get_dev () {
	grep -v '[ 	]*#' /etc/fstab | tr '\t' ' ' | tr -s ' ' | grep " $1 " | cut -f1 -d ' '
}


# Try to automaticaly determind the mbr. for explanation of word "automaticaly" see
# footnote 1 in doc/config 
Auto_Boot() {
	ROOT=$(get_dev /boot)
	if test -z "$ROOT" ; then
		ROOT=$(get_dev /)
	fi

	debug "mbr from ROOT = $ROOT"
  
	# support root on hardware raid... i wonder if any bootloader supports it :)
	if echo "$ROOT" | grep -q 'c[0-9]d[0-9]p[0-9][0-9]*$' ; then
		MBR=`echo $ROOT | sed -e 's/p[0-9]*$//'`
	else
		MBR=`echo $ROOT | sed -e 's/[0-9]*$//'`
	fi

	if [ "$MBR" = "" ]; then 
		die "Problems with \"automatical\" detection of your mbr, sorry."
	fi

	echo $MBR
	return 0
}

# Try to automaticaly determine your ROOT partition
# for explanation of word "automaticaly" see
# footnote 1 in doc/config 
Auto_Root() {
	AUTOROOT=$(get_dev /)

	debug "AUTOROOT = $AUTOROOT"
  
	if [ "$AUTOROOT" = "" ]; then 
		die "Problems with \"automatical\" detection of your /, sorry."
	fi
  
	echo $AUTOROOT
	return 0
}

Auto_Loader() {
	AUTO_LOADER=$(get_dev /boot)
	if test -z "$AUTO_LOADER" ; then
		debug "no /boot found, AUTO_LOADER = $AUTO_LOADER"
		AUTO_LOADER=$(get_dev /)
	else
		debug "/boot found, AUTO_LOADER = $AUTO_LOADER"
	fi
  
	if test -z "$AUTO_LOADER" ; then
		die "Problems with \"automatical\" detection of your /boot, sorry."
	fi
  
	echo $AUTO_LOADER
}

#Usualy it should be set to /etc/sysconfig/rc-boot
CONFIG_DIR=/etc/sysconfig/rc-boot

# load image from file given as argument
load_image () {
	TYPE=
	ROOT=
	KERNEL=
	INITRD=
	VGA=
	APPEND=
	LOCK=
	NAME=`basename ${IM_File}`
	ALIAS=

	case $NAME in
		*~ | *.bak | *.old | *.rpmnew | *.rpmsave )
			return 1
			;;
	esac

	. ${IM_File}

	TYPE=`lower $TYPE`

	if [ "$TYPE" = linux -a "$KERNEL" = "" ] ; then
		die "cannot have empty KERNEL= option for linux"
	fi

	if [ "$LOCK" = "" ] ; then
		LOCK=no
	fi

	if [ "$ROOT" = auto ] ; then
		ROOT=`Auto_Root`
		if [ $? != 0 ] ; then
			exit 1
		fi
	fi
 
	if test -z "$ROOT" ; then
		die "ROOT not specified in ${IM_File}"
	fi
  
	debug "loaded $NAME image [TYPE=$TYPE, ROOT=$ROOT, KERNEL=$KERNEL"
	debug "INITRD=$INITRD, VGA=$VGA, APPEND=$APPEND, ALIAS=$ALIAS]"
	return 0
}

### MAIN

if [ -f ${CONFIG_DIR}/config ]; then 
	debug "Reading config file. \"${CONFIG_DIR}/config\""
	. ${CONFIG_DIR}/config
else
	die "There is no config file. \"${CONFIG_DIR}/config\". :(("
fi

if is_yes $DOIT ; then
	:
else
	msg "If you want to use it for something first read the" \
	"docs and then set the DOIT variable to yes."
	exit 0
fi

if [ "$TIMEOUT" = "" ] ; then
	TIMEOUT=30
fi

if [ "$BOOT" = "mbr" ]; then 
	BOOT=`Auto_Boot`
	if [ $? != 0 ] ; then
		exit 1
	fi
	debug "detected BOOT = $BOOT"
fi

if [ "$STAGE2" = auto ] ; then
	STAGE2=`Auto_Loader`
	if [ $? != 0 ] ; then
		exit 1
	fi
	debug "detected STAGE2 = $STAGE2"
fi

if [ "$BOOT" = "" ] ; then
	die "You must specify where should I install your loader."
fi

LOADER=$(lower $LOADER)

if [ "$LOADER" == "" ]; then 
	func=
	for f in $CONFIG_DIR/*_functions.sh ; do
		if test "$func" ; then
			die "more then one _functions.sh file found, and" \
			"LOADER= not specified in config"
		fi
		func=$f
	done
else
	func=$CONFIG_DIR/${LOADER}_functions.sh
fi

if test ! -r $func ; then
	die "cannot read '$func' file"
fi

# to be set in X_functions.sh
LOADER_CONFIG=

. $func

if test -z "$LOADER_CONFIG" ; then
	die "buggy functions file, no loader_config"
fi

first=
def=nok

if [ "`echo ${CONFIG_DIR}/images/*`" = "${CONFIG_DIR}/images/*" ] ; then
	die "No valid images in ${CONFIG_DIR}/images/. Exit"
fi

debug "first round, looking for default"

# ok, we first look for an defult entry
for IM_File in ${CONFIG_DIR}/images/* ; do
	load_image $IM_File || continue
	if test -z "$first" ; then
		first=$NAME
	fi
	if [ "$NAME" = "$DEFAULT" ] ; then
		def=ok
	fi
done

if [ "$DEFAULT" = "" ] ; then
	IM_File=${CONFIG_DIR}/images/PLD
	if [ -f ${IM_File} ] && load_image ${IM_File}; then
		DEFAULT=$NAME
		msg "$NAME taken as default image"
	else
		DEFAULT=$first
		msg "$first taken as default image"
	fi
elif [ "$def" = nok ] ; then
	die "cannot found default image ($DEFAULT) in $CONFIG_DIR/images"
fi

# ok, starting up!
TMP_CONFIG=`mktemp /tmp/rc-boot.conf.XXXXXX`

debug "second round, prep"

for IM_File in ${CONFIG_DIR}/images/* ; do
	load_image $IM_File || continue
	rc_boot_prep_image
done

rc_boot_init > $TMP_CONFIG

debug "third round, here we go"

for IM_File in ${CONFIG_DIR}/images/* ; do
	load_image $IM_File || continue
	msg "image: $NAME$([ "$NAME" = "$DEFAULT" ] && echo " *") is $TYPE on $ROOT"
	rc_boot_image >> $TMP_CONFIG
done

rc_boot_fini >> $TMP_CONFIG

cp -f $LOADER_CONFIG ${LOADER_CONFIG}.bak
cat $TMP_CONFIG > $LOADER_CONFIG
rm $TMP_CONFIG

# Lets check if you trust us.
if is_yes "$DONT_TOUCH_LOADER" ; then
	# ok. You should feel guilty.
	msg "Don't you know that the trust is very important in the live :))." \
		"I'm hope you know what you are doing."
else
	# Well, we will do our best.
	# Here we realy go. It installs loader in the place
	# specified in the /etc/sysconfig/rc-boot/config
	debug "running bootloader"

	if rc_boot_run ; then
		debug "Ok. Loader installed."
	else
		die "SOMETHING WENT VERY WRONG! CHECK THE LOADER CONFIG BY HAND!"
	fi
fi

# Thats all folk.

exit 0
