#!/bin/bash

unset LANG
unset LC_ALL

export PATH=/sbin:$PATH
q=--quiet

KERNELROOT=/tmp/updboot.kernel-$$
KERNELROOT=/tmp/updboot.kernel
MODLIST=$PWD/../anaconda/utils/modlist
PCITABLE=$PWD/../anaconda/kudzu/pcitable
TRIMPCITABLE=$PWD/../anaconda/utils/trimpcitable
GETMODDEPS=$PWD/../anaconda/utils/moddeps
FILTERMODDEPS=$PWD/../anaconda/utils/filtermoddeps
ARCHSIZE=""

MODLINKS="cdrom fs ipv4 misc net scsi"


usage () {
    echo "$0: <rpm-tree> <kernel-version>" 2>&1
    exit 1
}

resdeps () {
    list=`$GETMODDEPS -m $MODDEPS $*`
    items=$(for n in $* $list; do echo $n; done | sort -u)
    echo $items
}

findmodule () {
    find $KERNELROOT/lib/modules -name $1.o
}

copymodules () {
    for n in $1; do
	m=`findmodule $n`
	for dir in $2 ../../../RedHat/instimage/modules; do
	    if ! cp $m $dir/$ARCHSIZE ; then
		echo "Failed to copy $m to $dir/$ARCHSIZE (for module $n)"
	    fi
	done
    done
}

if [ -z "$1" -o -z "$2" ]; then
    usage
fi

wd=`pwd`

if [ x`basename $wd` != x"trees" ]; then
    usage
fi

rm -rf sparc/modules sparc64/modules local64/modules network64/modules \
    hdimage/modules ../../../RedHat/instimage/modules
mkdir -p sparc/modules/32 sparc64/modules/64 local64/modules/64 \
    network64/modules/64 hdimage/modules/64 \
    ../../../RedHat/instimage/modules/{32,64}
rm -rf tftp
mkdir tftp

for ARCH in sparc sparc64; do

    echo "Processing $ARCH architecture"

    case "$ARCH" in
	sparc) ARCHSIZE="32"; ARCHSH="sparc32" ;;
	sparc64) ARCHSIZE="64"; ARCHSH="" ;;
    esac

    rm -rf $KERNELROOT
    mkdir -p $KERNELROOT

    KVER=`rpm --qf '%{VERSION}-%{RELEASE}' -qp $1/kernel-$2.${ARCH}.rpm`
    rpm2cpio $1/kernel-$2.${ARCH}.rpm | (cd $KERNELROOT; cpio --quiet -id)

    if echo $2 | grep -e BOOT > /dev/null; then
	kversion=`echo $2 | sed 's/BOOT-//'`
	version=`echo ${kversion}BOOT`
    else
	version=$2
    fi

    if [ ! -d "$KERNELROOT/lib/modules/$version/scsi" ]; then
	echo "$1 is not a valid modules directory" 2>&1
	usage
    fi

    if [ ! -f "$KERNELROOT/boot/vmlinuz-$version" ]; then
	echo "$KERNELROOT/boot/vmlinuz-$version does not exist"
	usage
    fi

#   if [ ! -f "$KERNELROOT/boot/module-info-$version" ]; then
#	echo "$KERNELROOT/boot/module-info-$version does not exist"
#	usage
#   fi

    MODINFO=$KERNELROOT/boot/module-info-$version
    # we really ought to use the above modinfo file :-(
    MODINFO=$PWD/../anaconda/loader/module-info
    MODDEPS=$KERNELROOT/moddeps

    $ARCHSH depmod -e -i -m $KERNELROOT/boot/System.map-$version \
	$KERNELROOT/lib/modules/$version/*/*.o | $FILTERMODDEPS > $MODDEPS

    NETMODULES="sunhme sunqe sunbmac myri_sbus"
    SCSIMODULES="qlogicpti sg st"
    FCMODULES="pluto fcal soc socal fc4"
#    FSMODULES=$(resdeps "nfs vfat ufs")
    FSMODULES=$(resdeps "vfat ufs")
    BLOCKMODULES="linear raid0 raid1 raid5"

    case "$ARCH" in
	sparc) MISCMODULES=
		ADDNET=; ADDSCSI=; ADDMISC=; ADDFC= ;;
	sparc64) MISCMODULES="lp parport parport_ax"
		NETMODULES="$NETMODULES 3c59x de4x5"
		SCSIMODULES="$SCSIMODULES aic7xxx sym53c8xx qlogicisp"
		ADDNET="./network64/modules ./hdimage/modules"
		ADDSCSI="./local64/modules ./hdimage/modules"
		ADDMISC="./local64/modules ./network64/modules"
		ADDFC="./hdimage/modules" ;;
    esac
    copymodules "$NETMODULES" "./$ARCH/modules $ADDNET"
    copymodules "$FSMODULES" "./$ARCH/modules $ADDMISC"
    copymodules "$SCSIMODULES" "./$ARCH/modules $ADDSCSI"
    copymodules "$FCMODULES" "./$ARCH/modules $ADDFC"
    copymodules "$MISCMODULES" "./$ARCH/modules $ADDMISC"
    copymodules "$BLOCKMODULES" "./$ARCH/modules"

    for I in sparc/modules sparc64/modules local64/modules network64/modules \
	hdimage/modules ../../../RedHat/instimage/modules; do
	if [ ! -d $I/$ARCHSIZE ]; then continue; fi

	echo -n "Computing $I dependencies... "

	cd $I/$ARCHSIZE;

	SPACE2=`du -s . | awk '{print $1}'`

	$ARCHSH /sbin/depmod -m $KERNELROOT/boot/System.map-$version -i -e *.o | \
	    grep ':.*o' | \
	    sed -e 's/\.o//g' \
	    -e 's/lp: parport/lp: parport_ax/g' \
            -e 's/plip: parport/plip: parport_ax/g' > modules.dep
	if grep "unresolved symbol" modules.dep; then
	    echo "ERROR - Unresolved symbols in $I/$ARCHSIZE"
	else
	    echo "done. "
	fi

	# create the module-info file
	cat $MODINFO | sed 's|ncr53c8xx|sym53c8xx|g' > module-info.tmp
	$MODLIST --modinfo-file module-info.tmp --ignore-missing --modinfo \
	    $(ls *.o | sed 's/\.o$//') > module-info
	rm -f module-info.tmp

	# create the pcitable
	cat $PCITABLE | sed 's|ncr53c8xx|sym53c8xx|g' | $TRIMPCITABLE *.o > pcitable

	echo -n "Balling $I modules... "

	for m in `ls *.o`; do
	    if objdump -h $m | grep '\.modinfo' >/dev/null; then
		# s2=`du -s $m | awk '{print $1}'`
		( nm -u $m
		  $ARCHSH modinfo -p $m | sed 's/ .*$//'
		  objdump -r $m | grep -v 'file format' | grep '^[0-9a-fA-F]' | awk '{print $3}'
		  echo init_module
		  echo cleanup_module
		  echo kernel_version
		) | sort -u > $m.tmp1
		nm -f posix $m | sed 's/ .*$//' | sort > $m.tmp2
		strip `comm -13 $m.tmp1 $m.tmp2 | sed 's/^/-N /'` $m
		rm -f $m.tmp1 $m.tmp2
		# s1=`du -s $m | awk '{print $1}'`
		# echo "$m: done (saved `expr $s2 - $s1`k)"
	    fi
	done

	mkdir $version
	mv *.o $version
	find $version -type f | cpio $q -H crc -o | gzip -9 > modules.cgz
	rm -rf $version

	SPACE1=`du -s . | awk '{print $1}'`

	# At the moment sparc32 has no modules which sparc64
	# does not have as well, so we can cheat
	case "$ARCH" in
	    sparc) mv -f modules.cgz .. ;;
	    sparc64) mv -f modules.cgz ../modules64.cgz ;;
	esac

	mv -f module-info modules.dep pcitable ..

	cd -

	rm -rf $I/$ARCHSIZE

	DIFF=`expr $SPACE2 - $SPACE1`
	echo "done (saved ${DIFF}k)"
    done

    elftoaout -o boot$ARCHSIZE/vmlinux$ARCHSIZE.aout $KERNELROOT/boot/vmlinux-$version
    gzip -9 < boot$ARCHSIZE/vmlinux$ARCHSIZE.aout > boot$ARCHSIZE/vmlinux$ARCHSIZE.gz
    rm -f boot$ARCHSIZE/vmlinux$ARCHSIZE.aout
    cp -f "$KERNELROOT/boot/vmlinux-$version" tftp/vmlinux$ARCHSIZE
done

ln -f boot32/vmlinux32.gz ../../../boot/vmlinux32.gz
ln -f boot64/vmlinux64.gz ../../../boot/vmlinux64.gz

rm -rf $KERNELROOT

rm -f hdimage/modules/{module-info,modules.dep,pcitable}
cp -a ../../../RedHat/instimage/modules/{module-info,modules.dep,pcitable} \
    hdimage/modules
