#! /bin/sh

# $Id: make-fai-bootfloppy,v 1.27 2002/04/15 14:31:20 lange Exp $
#*********************************************************************
#
# make-fai-bootfloppy -- create a boot floppy for FAI
#
# This script is part of FAI (Fully Automatic Installation)
# (c) 2000-2002 by Thomas Lange, lange@informatik.uni-koeln.de
# Universitaet zu Koeln
#
#*********************************************************************
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
# 
# A copy of the GNU General Public License is available as
# `/usr/share/common-licences/GPL' in the Debian GNU/Linux distribution
# or on the World Wide Web at http://www.gnu.org/copyleft/gpl.html.  You
# can also obtain it by writing to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#*********************************************************************

version="version 1.7.3, 15 Apr 2002"
set -e
MKIMAGE=0
floppydev=/dev/fd0
MOUNTPOINT=/floppy
mountopts=""
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
umount_dirs() {
    cd /
    umount "$MOUNTPOINT" || true
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
die() {

    echo -e "$@"
    exit 99
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
determine_kernel_version() {

    local num all
    all=$(ls $NFSROOT/boot/System.map-*)
    if [ `echo $all | wc -l ` = 1 ]; then
	KERNELVERSION=$(echo "kernel version $all" | sed -e 's#.*/System.map-##')
    else
	die "Can't determine kernel version for $all"
    fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
usage() {

    cat <<EOF
make-fai-bootfloppy, create a boot floppy for FAI. $version

   Copyright (C) 2000-2002 by Thomas Lange

   Usage: make-fai-bootfloppy [parameter]

   -h       print this message.
   -s host  use a static ip for host (try to get from DNS)
   -f file  make a 1440k floppy image
   -m dir   use dir as mountpoint [/floppy]

DESCRIPTION
   Creates a boot floppy for booting a FAI install client.
   No arguments are needed but you must be root.
   All parameters are passed to the kernel via append in lilo.conf.

EXAMPLE
    To make a boot floppy for my old SMC EtherCard Plus Elite 16T, I use

    # make-fai-bootfloppy "reserve=0x300,32 ether=10,0x300,eth0"

EOF
    exit 0
}

# - - - - - - - - - - - - - - - - - - - - - - - - - -
# main part
while getopts "f:s:m:h" opt ; do
        case "$opt" in
        h) usage ;;
	f) MKIMAGE=1; floppydev="$OPTARG" ;;
	m) MOUNTPOINT="$OPTARG" ;;
	s) TARGETHOST="$OPTARG" ;;
        ?) echo "Error parsing arguments"; exit 1;;
esac
done
shift `expr $OPTIND - 1`

if [ "$UID" -ne 0 ]; then
 echo "You must be root!"
 exit 9
fi

trap "umount_dirs" EXIT
# additional kernel parameter
params="$@"

. /etc/fai/fai.conf

determine_kernel_version
grep -q ic_bootp $NFSROOT/boot/System.map-$KERNELVERSION && TYPE=BOOTP
grep -q ic_dhcp $NFSROOT/boot/System.map-$KERNELVERSION && TYPE=DHCP

[ "$TYPE" ] || die "Can't determine kernel boot protocol.\nMaybe there's no $NFSROOT/boot/System.map-$KERNELVERSION"

ndevices=0
devices=`egrep -v "lo:|^Inter-|^ face" /proc/net/dev | awk -F: '{print $1}'`
for dev in $devices; do
    ndevices=$(($ndevices+1))
done
[ $ndevices = 0 ] && die "No network interface found. Can't determine IP address."
if [ $ndevices = 1 ]; then
    SERVERINTERFACE=$dev
else
    while [ -z "$SERVERINTERFACE" ]; do
	echo "Your machine has multiple network interfaces: $devices"
	echo -n "Specify which one will be used for FAI (eg. eth1): "
	read SERVERINTERFACE
    done
fi
SERVERIP=`LC_ALL=C ifconfig $SERVERINTERFACE | perl -ne '/inet addr:([0-9\.]+)/ && print $1'`
echo "Using interface $SERVERINTERFACE with IP address: $SERVERIP"

if [ -n "${TARGETHOST}" ] ; then
    BROADCAST=`LC_ALL=C ifconfig $SERVERINTERFACE | perl -ne '/Bcast:([0-9\.]+)/ && print $1'`
    NETMASK=`LC_ALL=C ifconfig $SERVERINTERFACE | perl -ne '/Mask:([0-9\.]+)/ && print $1'`
    GATEWAY=`LC_ALL=C route -n | grep '^0\.0\.0\.0' | awk '{ print $2 }'`
    TARGETIP=`host -t a ${TARGETHOST} 2> /dev/null | awk '{print $3}'`
    params="ip=${TARGETIP}:${SERVERIP}:${GATEWAY}:${NETMASK}:${TARGETHOST}::off $params" 
fi

if [ $MKIMAGE -eq 1 ]; then 
    dd if=/dev/zero of=$floppydev bs=1024 count=1440
    mountopts="$mountopts -o loop"
    mkfsopt=-F
fi

mke2fs $mkfsopt -q -i 8192 -m 0 $floppydev || die "Can't create ext2 file system on $floppydev"
mount $mountopts $floppydev $MOUNTPOINT || die "Can't mount floppy $floppydev"
mkdir $MOUNTPOINT/boot $MOUNTPOINT/etc

# do not copy System.map*
cp -dp $NFSROOT/boot/map $NFSROOT/boot/chain* $NFSROOT/boot/boot* $NFSROOT/boot/vmlinuz-$KERNELVERSION $MOUNTPOINT/boot 2>/dev/null || true
ln -s boot/vmlinuz-$KERNELVERSION $MOUNTPOINT/vmlinuz
# since lilo 21.5, boot.b is a link
[ -e $MOUNTPOINT/boot/boot.b ] || ln -fs $MOUNTPOINT/boot/boot-compat.b $MOUNTPOINT/boot/boot.b

[ $MKIMAGE -eq 1 ] && cat > $MOUNTPOINT/etc/lilo.conf <<-EOF
   disk=$(mount | grep $MOUNTPOINT | sed -e 's/.*loop=\([^)]*\))/\1/')
   bios=0x00
   cylinders=80
   heads=2
   sectors=18
EOF

cat >> $MOUNTPOINT/etc/lilo.conf <<-EOF
    boot=$floppydev
    root=$NFSROOT/dev/boot255
    install=$MOUNTPOINT/boot/boot.b
    map=$MOUNTPOINT/boot/map
    append="nfsroot=$SERVERIP:$NFSROOT $params"
    delay=10
    compact
    image=$MOUNTPOINT/vmlinuz
    label=FAI-$TYPE
    read-only
EOF

$NFSROOT/sbin/lilo -C $MOUNTPOINT/etc/lilo.conf

cat <<EOF
Writing boot data to floppy.
   boot protocol : $TYPE
   nfsroot       : $SERVERIP:$NFSROOT
   parameters    : $params
The kernel configuration is $NFSROOT/boot/config-$KERNELVERSION-$TYPE.
EOF
