#!/bin/sh
<<@

LILO QUICK INSTALLATION
-----------------------

This installation script installs LILO and generates the configuration file
/etc/lilo/config. It uses safe defaults for most configuration options.
Please read the documentation (preferably the more complete LaTeX version,
doc.tex) before making changes to the configuration generated by QuickInst.

To run QuickInst, simply type

./QuickInst

If the normally used root partition is mounted below root (e.g. during
system installation), set the environment variable ROOT to the name of the
directory on which the root partition is mounted and run QuickInst, e.g.

ROOT=/root ./QuickInst

A subshell can be spawned at each prompt. Type  !  to get an interactive
shell that has to be left with  exit . Type  !command args ...  to execute
a command and immediately return to QuickInst.

QuickInst can only be used to install LILO on IDE (AT-BUS) or SCSI hard
disks. The LILO version must be 0.9 or later, the kernel should be 0.99 or
later if using a SCSI disk. Owners of ST01/ST02 and Ultrastor SCSI adapters
have to create a file /etc/lilo/disktab to describe the disk geometry.

WARNING: QuickInst may get confused if you're running it in a directory
	 that contains a mixture of old and new LILO distributions. To be
	 safe, always extract new LILO distributions in their own, new
	 directory.

------------- End of description. What follows is program code. -------------
@

locate()
{
    var=$1
    while shift && [ ! -z "$1" ]; do
	for p in `echo $PATH | sed 's/:/ /g'`; do
	    if [ -x $p/$1 ]; then
		eval $var=$p/$1
		return 0
	    fi
	done
    done
    return 1
}

probe()
{
    [ ! -z "`dd if=$1 bs=1 count=1 2>/dev/null | tr '\0' x`" ]
    return
}

bootflag()
{
    [ "XY" = "`(dd of=/dev/null bs=510 count=1; dd bs=2 count=1 |
      tr -c '\125\252' . | tr '\125\252' XY) <$1 2>/dev/null`" ]
    return
}

krnltype()
{
    if [ "YX" = "`(dd bs=2 count=1 | tr -c '\001\013' . | tr '\001\013' XY) \
      <$1 2>/dev/null`" ]; then
	echo compound
    else
	echo image
    fi
}

get()
{
    while true; do
	echo -n "$1 "
	if [ -z "$3" ]; then
	    echo -n "(no default) "
	else
	    echo -n "[$3] "
	fi
	read line
	line="`echo "$line" | sed 's/^ *\([^ ]\(\|.*[^ ]\)\) *$/\1/'`"
	if [ -z "$line" ]; then
	    if [ -z "$3" ]; then
		echo "No default, please specify a value."
		continue
	    fi
	    line=$3
	fi
	if [ "x$line" = "x!" ]; then
	    echo
	    echo "Starting a sub-shell. Type  exit  to return."
	    echo
	    ${SHELL:-sh}
	    echo
	    continue
	fi
	if echo "$line" | grep -s '^!'; then
	    sh -c "`echo \"$line\" | sed 's/^!//'`"
	else
	    eval $2="$line"
	    break
	fi
    done
}

yesno()
{
    while true; do
	get "$1" line $2
	if echo "$line" | egrep -si '^y(|e(|s))$'; then
	    return 0
	fi
	if echo "$line" | egrep -si '^no?$'; then
	    return 1
	fi
	echo "YES or NO, please."
    done
}

echo
if [ $ROOT/etc/lilo = `pwd` ]; then
    echo "You can't run QuickInst in /etc/lilo ! Please cd to the directory"
    echo "that contains your LILO source files and try again."
    echo
    exit 1
fi

if id | grep -s 'uid=0('; then : ; else
    echo "You probably have to be root to install LILO."
    echo
    if yesno "Try to install LILO anyway ?" no; then : ; else
	echo
	exit 1
    fi
    echo
fi

badlib=""
if [ "`echo 'X(Y)' | sed 's/\(X\)(Y)/\1/'`" != "X" ]; then
    echo "Your sed doesn't behave like sed."
    badlib=y
fi
if [ "`echo 'X(Y)' | grep '^X(Y)'`" != "X(Y)" ]; then
    echo "Your grep doesn't behave like grep."
    badlib=y
fi
if [ "`echo 'X(Y)' | egrep '^(X)\(Y\)'`" != "X(Y)" ]; then
    echo "Your egrep doesn't behave like egrep."
    badlib=y
fi
if [ ! -z "$badlib" ]; then
    echo "Your libraries might be broken."
    echo
    exit 1
fi

echo "QuickInst configures LILO and installs it on your hard disk. It should"
echo "only be used for first-time installations, NOT to update or modify an"
echo "existing installation of LILO."
echo
echo "The installation procedure can be interrupted by pressing ^C at any"
echo "time. When at a prompt, a sub-shell can be invoked with the exclamation"
echo "mark."
echo
if yesno "Continue ?" yes; then : ; else
    echo
    exit 0
fi
echo

replace=""
if [ -d $ROOT/etc/lilo ]; then
    echo "A directory /etc/lilo already exists. If you're installing a new"
    echo "version of LILO now, QuickInst has to replace the old files with the"
    echo "new ones."
    echo
    if yesno "Replace old files ?" yes; then
	replace=y
    fi
    echo
fi

if [ -f $ROOT/etc/lilo/install -a -f $ROOT/etc/lilo/install.new -a \
  "$replace" != "y" ]; then
    echo "Found /etc/lilo/install and /etc/lilo/install.new. Please verify"
    echo "whether /etc/lilo/install is obsolete."
    echo
    if yesno "Replace install by install.new ?" yes; then
	mv -f $ROOT/etc/lilo/install.new $ROOT/etc/lilo/install
    fi
    echo
fi

echo
if [ ! -f $ROOT/etc/lilo/boot.b -o ! -z "$replace" ]; then
    if [ ! -f boot.b ]; then
	if [ ! -f first.S ]; then
	    echo "LILO is not installed and I don't know how to make it."
	    echo "Please cd to the directory where your LILO source lives and"
	    echo "try again."
	    echo
	    exit 1
	fi
	if [ ! -f /usr/include/linux/config.h ]; then
	    echo "The kernel header files appear to be missing. Please install"
	    echo "them, they try QuickInst again ."
	    echo
	    exit 1
	fi
	if [ ! -f /usr/include/linux/autoconf.h ]; then
	    echo "(Creating dummy /usr/include/linux/autoconf.h)"
	    echo
	    touch /usr/include/linux/autoconf.h
	fi
	echo "Making LILO ..."
	echo
	if make; then : ; else exit; fi
	echo
    fi
    echo "Installing LILO ..."
    echo
    if make install; then : ; else exit; fi
    echo
fi

if [ ! -x ./activate ]; then
    echo "activate  is not in the current directory. Please cd to your LILO"
    echo "source directory and run QuickInst again."
fi

if [ ! -f $ROOT/etc/lilo/install ]; then
    if [ -f install.new ]; then
	cp install.new $ROOT/etc/lilo/install
    else
	echo "Generating default $ROOT/etc/lilo/install ..."
	echo '$ROOT/etc/lilo/lilo -C /etc/lilo/config $*' \
	  >$ROOT/etc/lilo/install
	echo
    fi
fi

echo "Generating /etc/lilo/config ..."

first="/dev/[hs]da"
if probe /dev/hda; then
    first=/dev/hda
else
    if probe /dev/sda; then
	first=/dev/sda
    fi
fi
root=""
if locate path rootdev rdev setroot; then
    root=`$path | awk '{ print $1 }'`
    echo
    echo "(/ is mounted on $root)"
fi
boot=""
if echo $root | grep -s "^${first}[1-4]*\$"; then
    boot=$root
fi

echo
echo "Please specify the name of the device where the LILO boot sector should"
echo "be stored. (Suggested locations are the Linux root partition or the MBR"
echo "of your first drive)."
echo
while true; do
    get "Device name" inp $boot
    if echo "$inp" | egrep -s "^${first}\$|^${first}[1-4]\$"; then
	if probe "$inp"; then
	    boot=$inp
	    break
	else
	    echo "No such device exists. Type  !ls $first[1-4]  for a list of"
	    echo "possible names."
	fi
    else
	echo "This is not a valid device name. Try names like $first or"
	echo "${first}1"
    fi
done

disk=`echo $boot | sed 's/[1-4]$//'`
oldboot=`./activate $disk 2>/dev/null`
newboot=""
if [ $boot != "$oldboot" ]; then
    echo
    echo "Currently active partition of $disk is $oldboot"
    if yesno "Change it to $boot ?"; then
	newboot=`echo $boot | sed 's,/dev/[sh]da,,'`
	echo
	echo "Partition $newboot of $disk will be made active as soon as"
	echo "the LILO installation is complete."
    else
	echo
	echo "Please don't forget to configure the boot manager you are using"
	echo "to boot LILO from $boot."
    fi
fi

kernel=""
for n in /vmlinux /linux /Image /etc/Image; do
    if [ -f $ROOT/$n ]; then
	kernel=$n
	break
    fi
done

echo
echo "Please specify the name of the kernel image file you want to boot by"
echo "default."
echo
while true; do
    get "Default kernel" inp $kernel
    if [ -f "$ROOT$inp" ]; then
	if echo "$inp" | grep -s '^/'; then
	    kernel=$inp
	    break
	else
	    echo "Use only absolute path names, e.g. /linux"
	fi
    else
	echo "No such file."
    fi
done

(
    echo -n "# LILO configuration created by QuickInst  "
    date | tr -s x ' '
    echo
    echo "boot = $boot"
    echo "install = /etc/lilo/boot.b"
    echo "compact"
    echo "delay = 5       # optional, for systems that boot very quickly"
    echo "vga = normal    # force sane state"
    echo "ramdisk = 0     # paranoia setting"
    echo "root = current  # use \"current\" root"
    echo "`krnltype $kernel` = $kernel"
    if [ "`echo $kernel | sed 's,/\([^/]*\)$,\1,'`" != "linux" ]; then
	echo "  label = linux"
    fi
) >$ROOT/etc/lilo/config.tmp

echo
if yesno "Define additional kernels ?"; then
    default=""
    for n in $kernel.old /vmlinux.old /linux.old /Image.old /etc/Image.old; do
	if [ -f $ROOT/$n ]; then
	    default=$n
	    break
	fi
    done
    echo
    echo "Specify the names of additional kernels now. Use \"done\" (without"
    echo "the quotes) to stop adding kernels."
    echo
    while true; do
	get "Kernel" inp $default
	if [ done = "$inp" ]; then
	    break
	fi
	if echo "$inp" | grep -s '^/'; then
	    echo "`krnltype $inp` = $inp" >>$ROOT/etc/lilo/config.tmp
	    if [ ! -f $ROOT$inp ]; then
		echo "File doesn't exist now. - Making entry optional."
		echo "  optional" >>$ROOT/etc/lilo/config.tmp
	    fi
	else
	    echo "Use only absolute path names, e.g. /linux"
	fi
	default="done"
    done
fi

echo
if yesno "Define additional operating systems ?"; then
    echo
    echo "Specify the names of devices that contain boot sectors of additional"
    echo "operating systems now. You might want to run  fdisk  or  efdisk  to"
    echo "list the partition table(s) of your hard disk(s) in order to obtain"
    echo "the device names. Use \"done\" (without the quotes) to stop adding"
    echo "operating systems."
    echo
    default=""
    default_lbl=dos
    while true; do
	get "Device name" inp $default
	if [ done = "$inp" ]; then
	    break
	fi
	if echo "$inp" | grep -s '^/dev/[hs]d[ab][1-4]$'; then
	    if probe "$inp"; then
		if bootflag $inp; then
		    boot=$inp
		    (
			echo "other = $inp"
			echo -n "  table = "
			echo $inp | sed 's/[1-4]$//'
		    ) >>$ROOT/etc/lilo/config.tmp
		    get "Label" inp $default_lbl
		    default_lbl=""
		    default="done"
		    echo "  label = $inp" >>$ROOT/etc/lilo/config.tmp
		else
		    echo "$inp does not have a valid boot signature."
		fi
	    else
		echo "No such device exists. Type  !ls /dev/[hs]d[ab][1-4]  for"
		echo "a list of possible names."
	    fi
	else
	    echo "Expecting names like /dev/hda1, /dev/sda3, etc."
	fi
    done
fi

if [ -f $ROOT/etc/lilo/config ]; then
    mv /etc/lilo/config /etc/lilo/config.old
fi
mv /etc/lilo/config.tmp /etc/lilo/config

echo
echo "Ready to install LILO's boot sector on your hard disk."
echo "Type  !cat $ROOT/etc/lilo/config  if you want to check the configuration"
echo "file."
echo
if yesno "Install LILO now ?" yes; then
    echo
    outfile=${TMPDIR:-/tmp}/out$$
    errflag=${TMPDIR:-/tmp}/err$$
    if [ -f $errflag ]; then
	rm $errflag
    fi
    (
	if
	    $ROOT/etc/lilo/install 2>&1
	then : ; else
	    touch $errflag
	fi
    ) | tee $outfile
    if [ -f $errflag ]; then
	rm $errflag
	if egrep -s 'geo_query_dev HDIO_|: Got bad geometry' <$outfile; then
	    echo
	    echo "LILO is unable to obtain geometry information for your SCSI"
	    echo "disk. Please create an /etc/lilo/disktab file in which the"
	    echo "necessary parameters are described. See also section \"Disk"
	    echo "parameter table\" in the documentation."
	    echo
	    exit
	fi
	echo
	echo "Something went wrong. Verify your input and try to minimize the"
	echo "complexity of the settings, e.g. by omitting additional kernels"
	echo "and operating systems."
	echo
	exit
    fi
    rm $outfile
    if [ ! -z "$newboot" ]; then
	./activate $disk $newboot
    fi
fi
echo
echo "Done."
echo
