#!/bin/bash
LANG=C

set -x

PATH=$PATH:/sbin:/usr/sbin
IMAGEUUID=$(date +%Y%m%d%H%M).$(uname -i)

usage () {
	echo "usage: mk-images <pkgsrc> <toplevel> <template> <imgdir> <buildarch> <productname> <version> [<productpath>]"
    exit 0
}

DEBUG=""
if [ "$1" == "--debug" ]; then
    DEBUG="--debug"
    shift
fi

NEEDGR=yes
if [ "$1" == "--nogr" ]; then
    NEEDGR=""
    shift
fi

if [ -z "$1" -o -z "$2" -o -z "$3" -o -z "$4" -o -z "$5" -o -z "$6" -o -z "$7" -o -z "$8" ]; then usage; fi

PRODUCT=$6
VERSION=$7
PRODUCTPATH=$8
if [ -n "$9" ]; then
    BUGURL=$9
fi

TOPDIR=$(echo $0 | sed "s,/[^/]*$,,")
if [ $TOPDIR = $0 ]; then
    $TOPDIR="."
fi
TOPDIR=$(cd $TOPDIR; pwd)

# modules that are needed.  this is the generic "needed for every arch" stuff
COMMONMODS="fat vfat nfs sunrpc lockd floppy cramfs loop edd pcspkr squashfs ipv6 virtio_pci"
USBMODS="ohci-hcd uhci-hcd ehci-hcd hid mousedev usb-storage sd_mod sr_mod ub"
FIREWIREMODS="ieee1394 ohci1394 sbp2"
IDEMODS="ide-cd ide-cs"
SCSIMODS="sr_mod sg st sd_mod scsi_mod iscsi_tcp iscsi_ibft"
FSMODS="fat msdos vfat ext3 ext4 reiserfs jfs xfs gfs2 lock_nolock"
LVMMODS="dm-mod dm-zero dm-snapshot dm-mirror dm-multipath dm-round-robin dm-emc dm-crypt"
RAIDMODS="md raid0 raid1 raid10 raid5 raid6 raid456 dm-raid45 dm-mem-cache dm-region_hash dm-message"
SECSTAGE="$RAIDMODS $LVMMODS $FSMODS $IDEMODS $SCSIMODS"
BTERMMODS="vga16fb"
CRYPTOMODS="aead aes_generic ansi_cprng anubis arc4 authenc blowfish cast5 cast6 cbc ccm chainiv crypto_algapi crypto_api crypto_blkcipher crypto_hash crypto_null cryptomgr ctr deflate des ecb eseqiv gf128mul hmac khazad krng md4 md5 michael_mic rng seqiv serpent sha256 sha512 tcrypt tea tgr192 twofish wp512 xcbc xts"
PCMCIASOCKMODS="yenta_socket i82365 tcic pcmcia"
INFINIBANDMODS="ib_ipoib"
INITRDMODS="$USBMODS $FIREWIREMODS $IDEMODS $SCSIMODS $FSMODS $LVMMODS $RAIDMODS $CRYPTOMODS $BTERMMODS $COMMONMODS $PCMCIASOCKMODS $INFINIBANDMODS =scsi =net"

# Set, verify, and create paths
    KERNELPATH=$1
    TOPDESTPATH=$2
    IMAGEPATH=$TOPDESTPATH/images
    FULLMODPATH=/tmp/instimagemods.$$
    FINALFULLMODPATH=$4/modules
    INSTIMGPATH=$TOPDESTPATH/images
    INSTIMGTEMPLATE=$3
    IMGPATH=$4
    KERNELBASE=/tmp/updboot.kernel.$$
    MODDEPS=$KERNELBASE/moddeps
    MODALIAS=$KERNELBASE/modules.alias
    BUILDARCH=$5

    KERNELNAME=vmlinuz

    if [ "$BUILDARCH" = "ia64" ]; then
	KERNELDIR="/boot/efi/EFI/redhat"
    else
	KERNELDIR="/boot"
    fi
    
    if [ "$BUILDARCH" = "sparc64" ]; then
	BASEARCH=sparc
    else
	BASEARCH=$BUILDARCH
    fi

    # explicit block size setting for some arches (FIXME: we compose 
    # ppc64-ish trees as ppc, so we have to set the "wrong" block size)
    if [ "$BUILDARCH" = "sparc64" ]; then
	CRAMBS="--blocksize 8192"
    elif [ "$BUILDARCH" = "sparc" ]; then
	CRAMBS="--blocksize 4096"
    else
	CRAMBS=""
    fi

    if [ $BUILDARCH = x86_64 -o $BUILDARCH = s390x ]; then
	LIBDIR=lib64
    else
	LIBDIR=lib
    fi

    rm -rf $IMAGEPATH
    rm -rf $FULLMODPATH
    rm -rf $FINALFULLMODPATH
    rm -rf $KERNELBASE
    mkdir -p $IMAGEPATH
    mkdir -p $FULLMODPATH
    mkdir -p $FINALFULLMODPATH
    mkdir -p $KERNELBASE
    mkdir -p $INSTIMGPATH

# Stuff that we need
    TRIMMODALIAS=$IMGPATH/usr/lib/anaconda-runtime/trimmodalias
    TRIMPCIIDS=$IMGPATH/usr/lib/anaconda-runtime/trimpciids
    GETKEYMAPS=$IMGPATH/usr/lib/anaconda-runtime/getkeymaps
    GENINITRDSZ=$IMGPATH/usr/lib/anaconda-runtime/geninitrdsz
    MKS390CDBOOT=$IMGPATH/usr/lib/anaconda-runtime/mk-s390-cdboot
    KEYMAPS=/tmp/keymaps-$BUILDARCH.$$
    SCREENFONT=$IMGPATH/usr/lib/anaconda-runtime/screenfont-${BASEARCH}.gz
    GETMODDEPS=$IMGPATH/usr/lib/anaconda-runtime/moddeps
    MODLIST=$IMGPATH/usr/lib/anaconda-runtime/modlist
    MODINFO=$IMGPATH/usr/lib/anaconda-runtime/loader/module-info
    FILTERMODDEPS=$IMGPATH/usr/lib/anaconda-runtime/filtermoddeps
#    LOADERBINDIR=/mnt/src/scientific/5rolling/$BUILDARCH/build/loader-sl-209
#CJS rhel5.6 loader fails on slf5.6 so this is the loader from SLF.5.5
    LOADERBINDIR=$IMGPATH/usr/lib/anaconda-runtime/loader
    BOOTDISKDIR=$IMGPATH/usr/lib/anaconda-runtime/boot
    LANGTABLE=$IMGPATH/usr/lib/anaconda/lang-table
    PCIIDS=$IMGPATH/usr/share/hwdata/pci.ids
    XDRIVERS=$IMGPATH/usr/share/hwdata/videoaliases
    XDRIVERDESCS=$IMGPATH/usr/share/hwdata/videodrivers
    CACHE=$KERNELBASE/.cache
    MODULESUSED=$KERNELBASE/modules-used

    touch $MODULESUSED

    REQUIREMENTS="$TRIMMODALIAS $TRIMPCIIDS $PCIIDS $XDRIVERDESCS $GETMODDEPS $MODINFO
		  $FILTERMODDEPS $LANGTABLE $GETKEYMAPS"

    dieLater=
    for n in $REQUIREMENTS; do
	if [ ! -f $n ]; then
	    echo "$n doesn't exist"
	    dieLater=1
	fi
    done

    for n in $BOOTDISKDIR; do
	if [ ! -d $n ]; then
	    echo "$n doesn't exist"
	    dieLater=1
	fi
    done

    if [ -n "$dieLater" ]; then exit 1; fi

    if [ "$BUILDARCH" != "s390" -a "$BUILDARCH" != "s390x" ]; then
       # go ahead and create the keymaps so we only have to do it once
       if [ -f $IMGPATH/usr/lib/anaconda-runtime/keymaps-override-$BUILDARCH ]; then
	   echo "Found keymap override, using it"
	   cp $IMGPATH/usr/lib/anaconda-runtime/keymaps-override-$BUILDARCH $KEYMAPS
       else
	   echo "Running: $GETKEYMAPS $BUILDARCH $KEYMAPS $IMGPATH"
	   $GETKEYMAPS $BUILDARCH $KEYMAPS $IMGPATH
	   if [ $? != 0 ]; then
	       echo "Unable to create keymaps and thus can't create initrd."
	       exit 1
	   fi
       fi
    fi
 
findPackage() {
    dir=$1
    name=$2
    
    for n in $dir/$name*{$KERNELARCH,noarch}.rpm; do
	thisName=$(rpm --nodigest --nosignature --qf '%{NAME}' -qp $n)
	if [ -z "$thisName" ]; then
	    continue
	fi
	if [ $thisName = $name ]; then
	    echo $n
	    return
	fi
    done

    echo "cannot find package $name in path $dir" >&2
}

findmodule () {
    if [ ! -f $CACHE ]; then
        find $KERNELROOT/lib/modules/ > $CACHE
    fi
    
    grep "/$1\.ko" $CACHE
}

rundepmod () {
    what=$1
    final=$2

    $FAKEARCH /sbin/depmod -a -F $KERNELROOT/boot/System.map-$version \
            -b $KERNELROOT $version
    mv $KERNELROOT/lib/modules/$version/modules.alias $MODALIAS

    cat $KERNELROOT/lib/modules/$version/modules.dep | $FILTERMODDEPS > $final 
}

getmoddeps () {
    what=$1
    final=$2

    for mod in $what ; do
	mod=$(echo $mod | sed 's/\.ko  */|^/g;s/\.ko$//;s/.*\///')
	egrep $mod $MODDEPS >> $final.foo
    done
    mv $final.foo $final
}

intcopymodules () {
    dir=$2

    for n in $1; do
	m=$(findmodule $n)
	if [ -z "$m" ]; then
            [ -n "$DEBUG" ] && echo "Module $n not found in kernel rpm" >&2
        else 
	    echo $n >> $MODULESUSED
	    for o in $m ; do 
		echo $n
		ver=$(echo $o |cut -d / -f 7)
		myarch=$(echo $o |cut -d / -f 4)
		if ! [ -d $dir/$ver/$myarch ] ; then mkdir -p $dir/$ver/$myarch ; fi
		if ! cp $o $dir/$ver/$myarch; then
		    echo "Failed to copy $o to $dir/$ver/$myarch (for module $n)" >&2
		fi
	    done
        fi
    done
}

# This loops to make sure it resolves dependencies of dependencies of...
resdeps () {
    items="$*"

    before=1
    after=2

    while [ $before != $after ]; do
	before=`echo $items | wc -c`

	if [ $? != "0" ] ; then
	    kill -9 $$
	fi	
	list=`$GETMODDEPS -m $MODDEPS $items`
	items=$(for n in $items $list; do echo $n; done | sort -u)
	after=`echo $items | wc -c`
    done

    echo $items
}

expandModuleSet() {
    SET=""
    for name in $1; do
	char=$(echo $name | cut -c1)
        if [ $char = '=' ]; then
	    NAME=$(echo $name | cut -c2-)
	    SET="$SET $($MODLIST --modinfo-file $MODINFO $NAME)"
	elif [ $char = '+' ]; then
	    NAME=$(echo $name | cut -c2-)

	    # all of the modules of this type
	    $MODLIST --modinfo-file $MODINFO $NAME > /tmp/emsAll.$$
	    # the modules used that are of this type
	    sort -u $MODULESUSED | cat - /tmp/emsAll.$$ | sort | 
		    uniq -d > /tmp/emsUsed.$$
	    # the modules that are of this type, but not used
	    SET="$SET $(cat /tmp/emsAll.$$ /tmp/emsUsed.$$ | sort | uniq -u)"

	    rm -f /tmp/emsAll.$$ /tmp/emsUsed.$$
	else
	    SET="$SET $name"
	fi
    done

    echo $SET
}

makemoduleball() {
    unset MMB_DD
    MMB_MODINFO="module-info"
    MMB_NAME="modules.cgz"

    while [ x$(echo $1 | cut -c1-2) = x"--" ]; do
	if [ "$1" = "--dd" ]; then
	    MMB_DD="$2"
	    shift; shift
	    MMB_MODINFO="modinfo"
	    continue
	elif [ "$1" = "--name" ]; then
	    MMB_NAME="$2"
	    shift; shift
	    continue
	fi
	echo "unknown option passed to $0"
	exit 1
    done

    MMB_DIR=$1
    MMB_MODULESET=$(resdeps $2)

    rm -rf $MMB_DIR/modules $MMB_DIR/$MMB_NAME $MMB_DIR/modules.dep $MMB_DIR/modules.alias \
	   $MMB_DIR/modules.pcimap $MMB_DIR/pcitable $MMB_DIR/$MMB_MODINFO \
	   $MMB_DIR/pci.ids
    mkdir -p $MMB_DIR/modules

    MMB_MODULESET=$(intcopymodules "$MMB_MODULESET" $MMB_DIR/modules)

    pushd $MMB_DIR/modules > /dev/null

    $MODLIST --modinfo-file $MODINFO --ignore-missing --modinfo \
	$MMB_MODULESET > ../$MMB_MODINFO

    getmoddeps "$(find . -name *.ko)" ../modules.dep

    # create the modules.alias file
    $TRIMMODALIAS $(find . -name *.ko -exec basename {} \;) < $MODALIAS > ../modules.alias
    
    # create the pci.ids, from modules.alias and the X driver aliases
    awk '!/^(\t\t|#)/ { print ;if ($0 == "ffff  Illegal Vendor ID") nextfile; }' < $PCIIDS | \
      $TRIMPCIIDS ../modules.alias $XDRIVERS/* > ../pci.ids

    if [ -n "$MMB_DD" ]; then
	echo $MMB_DD > $MMB_DIR/rhdd
    fi

    find . -type f | cpio --quiet -H crc -o | gzip -9 > ../$MMB_NAME
    cd ..
    rm -rf modules
    chmod 644 *
    popd  > /dev/null
}

makeproductfile() {
    root=$1

    rm -f $root/.buildstamp
    echo $IMAGEUUID > $root/.buildstamp
    echo $PRODUCT >> $root/.buildstamp
    echo $VERSION >> $root/.buildstamp
    echo $PRODUCTPATH >> $root/.buildstamp
    if [ -n "$BUGURL" ]; then
	echo $BUGURL >> $root/.buildstamp
    fi
}

setupShellEnvironment() {
    # setup password/group entries
    cat > $MBD_DIR/etc/passwd << EOF
root::0:0::/:/sbin/loader
debug::0:0:debug shell:/:/bin/bash
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
EOF
    cat > $MBD_DIR/etc/group << EOF
root:x:0:root
tty:x:5:
EOF
    echo "sshd:x:74:" >> $MBD_DIR/etc/group
    echo "telnet          23/tcp" > $MBD_DIR/etc/services 
    echo "tcp     6       TCP" > $MBD_DIR/etc/protocols

    # PAM configuration
    for i in pam_limits.so pam_env.so pam_unix.so pam_deny.so; do
       cp -f $IMGPATH/$LIBDIR/security/$i $MBD_DIR/$LIBDIR/security
    done
    
    cp -f $IMGPATH/etc/pam.d/other $MBD_DIR/etc/pam.d
    cat > $MBD_DIR/etc/pam.d/login << EOF
#%PAM-1.0
auth        required      pam_env.so
auth        sufficient    pam_unix.so likeauth nullok
auth        required      pam_deny.so
account     required      pam_unix.so
password    sufficient    pam_unix.so nullok use_authtok md5 shadow
password    required      pam_deny.so
session     required      pam_limits.so
session     required      pam_unix.so
EOF
    cp -f $MBD_DIR/etc/pam.d/login $MBD_DIR/etc/pam.d/sshd
    cp -f $MBD_DIR/etc/pam.d/login $MBD_DIR/etc/pam.d/remote

    cp -f $IMGPATH/etc/security/{limits.conf,pam_env.conf} $MBD_DIR/etc/security/

    # setup xinetd for telnet
    cp -f $IMGPATH/etc/xinetd.conf $MBD_DIR/etc/xinetd.conf
    mkdir -p $MBD_DIR/etc/xinetd.d
    cat > $MBD_DIR/etc/xinetd.d/telnet <<EOF
service telnet
{
        flags           = REUSE
        socket_type     = stream
        wait            = no
        user            = root
        server          = /sbin/in.telnetd
        log_on_failure  += USERID
        disable         = no
}
EOF

    # key generation takes ages on s390, you really don't want this for every
    # installation attempt. These are NOT the keys of the installed system!
    mkdir -m 0700 -p $MBD_DIR/etc/ssh
    echo -n "Generating SSH1 RSA host key: "
    /usr/bin/ssh-keygen -q -t rsa1 -f $MBD_DIR/etc/ssh/ssh_host_key \
                        -C '' -N '' >&/dev/null
    echo
    echo -n "Generating SSH2 RSA host key: "
    /usr/bin/ssh-keygen -q -t rsa -f $MBD_DIR/etc/ssh/ssh_host_rsa_key \
                        -C '' -N '' >&/dev/null
    echo
    echo -n "Generating SSH2 DSA host key: "
    /usr/bin/ssh-keygen -q -t dsa -f $MBD_DIR/etc/ssh/ssh_host_dsa_key \
                        -C '' -N '' >&/dev/null
    echo
    (cd $MBD_DIR/etc/ssh; \
        chmod 600 ssh_host_key ssh_host_rsa_key ssh_host_dsa_key; \
        chmod 644 ssh_host_key.pub ssh_host_rsa_key.pub ssh_host_dsa_key.pub; )


    cat > $MBD_DIR/etc/ssh/sshd_config <<EOF
Port 22
HostKey /etc/ssh/ssh_host_key
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
PermitRootLogin yes
IgnoreRhosts yes
StrictModes yes
X11Forwarding yes
X11DisplayOffset 10
PrintMotd yes
XAuthLocation /sbin/xauth
KeepAlive yes
SyslogFacility AUTHPRIV
RSAAuthentication yes
PasswordAuthentication yes
PermitEmptyPasswords yes
PermitUserEnvironment yes
EOF
    chmod 600 $MBD_DIR/etc/ssh/sshd_config

    # copy in the binaries
    cp -f $IMGPATH/usr/bin/login $MBD_DIR/sbin/login
    cp -f $IMGPATH/usr/sbin/sshd $MBD_DIR/sbin/sshd
    cp -f $IMGPATH/usr/sbin/xinetd $MBD_DIR/sbin/xinetd
    cp -f $IMGPATH/usr/sbin/in.telnetd $MBD_DIR/sbin/in.telnetd
    cp -f $IMGPATH/usr/bin/ipcalc $MBD_DIR/sbin/ipcalc

    # and copy libraries too
    mkdir -p $MBD_DIR/$LIBDIR $MBD_DIR/lib
    for lib in $IMGPATH/$LIBDIR/libc.so* \
	       $IMGPATH/$LIBDIR/libc-*.so* \
       	       $IMGPATH/$LIBDIR/ld-*.so* \
       	       $IMGPATH/$LIBDIR/ld.so* \
       	       $IMGPATH/$LIBDIR/ld64.so* \
	       $IMGPATH/$LIBDIR/libaudit.so* \
	       $IMGPATH/$LIBDIR/libtermcap.so* \
               $IMGPATH/$LIBDIR/libpam.so* \
    	       $IMGPATH/$LIBDIR/libdl.so* \
    	       $IMGPATH/$LIBDIR/libdl-*.so* \
	       $IMGPATH/$LIBDIR/libnss_files* \
	       $IMGPATH/$LIBDIR/libnsl* \
	       $IMGPATH/usr/$LIBDIR/libnss3.so \
               $IMGPATH/usr/$LIBDIR/libnssutil3.so \
	       $IMGPATH/$LIBDIR/libkeyutils* \
	       $IMGPATH/$LIBDIR/libpthread* \
	       $IMGPATH/usr/$LIBDIR/libplc4.so \
	       $IMGPATH/usr/$LIBDIR/libplds4.so \
	       $IMGPATH/usr/$LIBDIR/libnspr4.so \
	       $IMGPATH/$LIBDIR/libutil.so* \
	       $IMGPATH/$LIBDIR/libutil-*.so* \
	       $IMGPATH/$LIBDIR/libcrypt*so* \
	       $IMGPATH/$LIBDIR/libselinux*so* \
	       $IMGPATH/$LIBDIR/libsepol*so* \
	       $IMGPATH/$LIBDIR/libattr*so* \
	       $IMGPATH/$LIBDIR/libresolv.so* \
	       $IMGPATH/$LIBDIR/libresolv-*.so* \
	       $IMGPATH/$LIBDIR/libm.so* \
	       $IMGPATH/$LIBDIR/libm-*.so* \
	       $IMGPATH/$LIBDIR/libz.so* \
	       $IMGPATH/$LIBDIR/libssl* \
	       $IMGPATH/$LIBDIR/libcom_err* \
	       $IMGPATH/$LIBDIR/libe2p* \
	       $IMGPATH/$LIBDIR/libuuid* \
               $IMGPATH/usr/$LIBDIR/libfipscheck* \
	       $IMGPATH/usr/$LIBDIR/libwrap*.so* \
	       $IMGPATH/$LIBDIR/libwrap*.so* \
               $IMGPATH/usr/$LIBDIR/libX11.so* \
               $IMGPATH/usr/$LIBDIR/libXau.so* \
               $IMGPATH/usr/$LIBDIR/libXdmcp.so* \
	       $IMGPATH/usr/$LIBDIR/libXmuu.so* \
	       $IMGPATH/usr/$LIBDIR/libXext.so* \
	       $IMGPATH/usr/$LIBDIR/libXt.so* \
	       $IMGPATH/usr/$LIBDIR/libSM.so* \
	       $IMGPATH/usr/$LIBDIR/libICE.so* ; do
	if [ -e $lib ]; then cp -df $lib $MBD_DIR/$LIBDIR/ ; fi
    done 

    if [ -e $IMGPATH/lib/ld64.so* ]; then cp -df $IMGPATH/lib/ld64.so* $MBD_DIR/lib/ ; fi 
    if [ -e $IMGPATH/lib/ld-*.so ]; then cp -df $IMGPATH/lib/ld-*.so $MBD_DIR/lib/ ; fi 
    if [ -e $IMGPATH/lib64/ld64.so* ]; then cp -df $IMGPATH/lib64/ld64.so* $MBD_DIR/lib64/ ; fi 

    mkdir -p $MBD_DIR/usr/$LIBDIR
    for lib in $IMGPATH/usr/$LIBDIR/libkrb5.so* \
	       $IMGPATH/usr/$LIBDIR/libkrb5support.so* \
	       $IMGPATH/usr/$LIBDIR/libgssapi_krb5.so* \
	       $IMGPATH/usr/$LIBDIR/libk5crypto.so* \
	       $IMGPATH/usr/$LIBDIR/libcom_err.so* ; do
	if [ -e $lib ]; then cp -df $lib $MBD_DIR/usr/$LIBDIR/ ; fi
    done 
}

addBusyBox() {
    cp -f $IMGPATH/usr/bin/bash $MBD_DIR/sbin/bash
    cp -f $IMGPATH/usr/bin/busybox $MBD_DIR/sbin/busybox

    # make some symlinks
    ln -sf bash $MBD_DIR/sbin/sh
    (cd $MBD_DIR/sbin;
      set $(./busybox 2>&1 | awk '/^\t([[:alnum:]_\.\[]+,)+/' | sed 's/,//g' | sed 's/ +//');
      while [ -n "$1" ]; do
        if [ $1 != "busybox" -a $1 != "sh" ]; then
          if [ ! -f "$1" ]; then
            ln -sf ./busybox $1
          else
            [ -n "$DEBUG" ] && echo "Overriding busybox version of $1"
          fi
        fi
        shift
      done)
}

makeinitrd() {
    EXTRAINITRDPATH=""
    INITRDSIZE=""
    KEEP=""
    PADSIZE=""
    LOADERBIN=""
    INITRDMODULES=""
    MODULEBALLNAME="modules.cgz"
    MYLANGTABLE=$LANGTABLE
    MYLOADERTR=loader.tr
    while [ x$(echo $1 | cut -c1-2) = x"--" ]; do
	if [ $1 = "--initrdto" ]; then
	    EXTRAINITRDPATH=$2
	    shift; shift
	    continue
	elif [ $1 = "--keep" ]; then
	    KEEP=yes
	    shift
	    continue
	elif [ $1 = "--initrdsize" ]; then
	    INITRDSIZE=$2
	    shift; shift
	    continue
	elif [ $1 = "--loaderbin" ]; then
	    LOADERBIN=$2
	    shift; shift
	    continue
	elif [ $1 = "--modules" ]; then
	    INITRDMODULES=$2
	    shift; shift
	    continue
	elif [ $1 = "--moduleballname" ]; then
	    MODULEBALLNAME=$2
	    shift; shift
	    continue
	fi
	echo "Unknown option passed to makeinitrd"
	exit 1
    done
    if [ -z "$LOADERBIN" ]; then
	echo "no loader binary specified!" >&2
	exit 1
    fi
    if [ -z "$INITRDMODULES" ]; then
	echo "warning: no loader modules specified!" >&2
    fi
    if [ -z "$INITRDSIZE" ]; then
	echo "I don't know how big to make the initrd image!" >&2
	exit 1
    fi

    MBD_DIR=/tmp/makebootdisk.dir.$$
    MBD_FSIMAGE=/tmp/makebootdisk.initrdimage.$$
    MBD_BOOTTREE=/tmp/makebootdisk.tree.$$

    rm -rf $MBD_DIR MBD_FSIMAGE
    mkdir -p $MBD_DIR/modules
    mkdir -p $MBD_DIR/sbin
    mkdir -p $MBD_DIR/dev
    mkdir -p $MBD_DIR/etc
    mkdir -p $MBD_DIR/proc
    mkdir -p $MBD_DIR/selinux
    mkdir -p $MBD_DIR/sys
    mkdir -p $MBD_DIR/tmp
    mkdir -p $MBD_DIR/etc/terminfo/{a,b,d,l,s,v,x}
    mkdir -p $MBD_DIR/var/state
    mkdir -p $MBD_DIR/var/run
    mkdir -p $MBD_DIR/var/lock/rpm

    if [ "$BUILDARCH" = "ppc" -o "$BUILDARCH" = "ppc64" ]; then
	mkdir -p $MBD_DIR/dev/iseries
    fi

    if [ "$BUILDARCH" = "s390" -o "$BUILDARCH" = "s390x" ]; then
	mkdir -m 111 -p $MBD_DIR/var/empty/sshd
	mkdir -p $MBD_DIR/etc/{pam.d,security}
	mkdir -p $MBD_DIR/$LIBDIR/security
	cp $IMGPATH/$LIBDIR/libpam_misc.so.0.* $MBD_DIR/$LIBDIR/libpam_misc.so.0
	ln -s /tmp $MBD_DIR/var/state/xkb
	cp $IMGPATH/usr/bin/xauth $MBD_DIR/sbin/xauth
        cp $IMGPATH/usr/sbin/cmsfs* $MBD_DIR/sbin/
    fi

    if [ -n "$INITRDMODULES" ]; then
	MODSET=`expandModuleSet "$INITRDMODULES"`
        makemoduleball --name $MODULEBALLNAME $MBD_DIR/modules "$MODSET"
    fi

    cat > $MBD_DIR/etc/passwd << EOF
    root::0:0:root:/:/bin/bash
EOF

    # set up the arch bits
    echo $arch > $MBD_DIR/etc/arch

    install -s -m 755 $LOADERBINDIR/$LOADERBIN $MBD_DIR/sbin/loader
    strip $MBD_DIR/sbin/loader
    if [ "$BUILDARCH" != "s390" -a "$BUILDARCH" != "s390x" ]; then
	install -s -m 755 $LOADERBINDIR/init $MBD_DIR/sbin
	strip $MBD_DIR/sbin/init
	ln -s ./init $MBD_DIR/sbin/reboot
	ln -s ./init $MBD_DIR/sbin/halt
	ln -s ./init $MBD_DIR/sbin/poweroff
    else
	install -s -m 755 $LOADERBINDIR/shutdown $MBD_DIR/sbin/shutdown
	install -m 755 $IMGPATH/usr/lib/anaconda-runtime/loader/linuxrc.s390 $MBD_DIR/sbin/init
	install -m 755 $IMGPATH/usr/lib/anaconda-runtime/loader/lsznet.raw $MBD_DIR/sbin/lsznet
	install -m 755 $IMGPATH/usr/sbin/dasdfmt $MBD_DIR/sbin/dasdfmt
	install -m 755 $IMGPATH/usr/sbin/udevsettle $MBD_DIR/sbin/udevsettle
	install -m 755 $IMGPATH/usr/sbin/udevd $MBD_DIR/sbin/udevd
	mkdir -p $MBD_DIR/etc/udev
	echo "# udev.conf" > $MBD_DIR/etc/udev/udev.conf
    fi

    if [ "$BUILDARCH" != "s390" -a "$BUILDARCH" != "s390x" ]; then
       install -m 644 $KEYMAPS $MBD_DIR/etc/keymaps.gz
       install -m 644 $SCREENFONT $MBD_DIR/etc/screenfont.gz
    fi
    install -m 644 $MYLANGTABLE $MBD_DIR/etc/lang-table
    
    install -m 644 $LOADERBINDIR/$MYLOADERTR $MBD_DIR/etc/loader.tr
    for i in a/ansi d/dumb l/linux s/screen v/vt100 v/vt100-nav v/vt102 x/xterm x/xterm-color b/bterm g/gnome ; do
	[ -f $IMGPATH/usr/share/terminfo/$i ] && \
	  install -m 644 $IMGPATH/usr/share/terminfo/$i $MBD_DIR/etc/terminfo/$i
    done

    makeproductfile $MBD_DIR

    for n in insmod rmmod modprobe; do
	ln -s loader $MBD_DIR/sbin/$n
    done

    ln -s /usr/bin/sh $MBD_DIR/sbin/sh
    ln -s /sbin/init $MBD_DIR/init
    ln -s /proc/mounts $MBD_DIR/etc/mtab
    ln -s sbin $MBD_DIR/bin
    mkdir -p $MBD_DIR/var/lib
    ln -s ../../tmp $MBD_DIR/var/lib/xkb

    # s390/s390x need sshd/telnet setup
    if [ "$BUILDARCH" = "s390" -o "$BUILDARCH" = "s390x" ]; then
	setupShellEnvironment
    fi

    addBusyBox

cat > $MBD_DIR/.profile <<EOF
PATH=/bin:/usr/bin:/usr/sbin:/mnt/sysimage/sbin:/mnt/sysimage/usr/sbin:/mnt/sysimage/bin:/mnt/sysimage/usr/bin
export PATH
EOF

    rm -f $MBD_FSIMAGE
    (cd $MBD_DIR; find . |cpio --quiet -c -o) |gzip -9 > $MBD_FSIMAGE

    size=$(du $MBD_FSIMAGE | awk '{ print $1 }')

    echo "Wrote $MBD_FSIMAGE (${size}k compressed)"

    if [ -n "$EXTRAINITRDPATH" ]; then
	mkdir -p `dirname $EXTRAINITRDPATH`
	cp -a $MBD_FSIMAGE $EXTRAINITRDPATH
    fi

    if [ -z "$KEEP" ]; then
	rm -rf $MBD_FSIMAGE $MBD_BOOTTREE
    fi
}

makeinstimage () {
    imagename=$1
    type=$2
    tmpdir=/tmp/instimage.dir.$$

    rm -rf $tmpimage $tmpdir
    mkdir -p $mntpoint $tmpdir

    mkdir -p $tmpdir
    (cd $INSTIMGTEMPLATE; find . | cpio --quiet -p $tmpdir)
    makeproductfile $tmpdir

    if [ -z "$type" -o "$type" = "cramfs" ]; then 
        echo "Running mkcramfs $CRAMBS $tmpdir $INSTIMGPATH/${imagename}2.img"
        mkfs.cramfs $CRAMBS $tmpdir /tmp/${imagename}2.img.$$
    elif [ "$type" = "squashfs" ]; then
        echo "Running mksquashfs $tmpdir /tmp/${imagename}2.img -all-root -no-fragments"
        mksquashfs $tmpdir /tmp/${imagename}2.img.$$ -all-root -no-fragments
        chmod 0644 /tmp/${imagename}2.img.$$
    fi
    cp /tmp/${imagename}2.img.$$ $INSTIMGPATH/${imagename}2.img
    size=$(ls -l $INSTIMGPATH/${imagename}2.img | awk '{print $5}')
    size=$(expr $size / 1024)
    echo "Wrote $INSTIMGPATH/${imagename}2.img (${size}k)..."
    relpath=${INSTIMGPATH#$TOPDESTPATH/}
    echo "instimage = ${relpath}/${imagename}2.img" >> $TOPDESTPATH/.treeinfo
    rm -rf $tmpdir
}

makemainimage () {
    imagename=$1
    type=$2
    mmi_tmpimage=/tmp/instimage.img.$$
    mmi_mntpoint=/tmp/instimage.mnt.$$
    
    rm -rf $mmi_tmpimage $mmi_mntpoint
    mkdir $mmi_mntpoint

    if [ $type = "ext2" ]; then
        SIZE=$(du -sk $IMGPATH | awk '{ print int($1 * 1.1) }')
        if [ -d $IMGPATH/usr/lib/anaconda-runtime ]; then
	    ERROR=$(du -sk $IMGPATH/usr/lib/anaconda-runtime | awk '{ print $1 }')
	    SIZE=$(expr $SIZE - $ERROR)
        fi
        dd if=/dev/zero bs=1k count=${SIZE} of=$mmi_tmpimage 2>/dev/null
        mke2fs -q -F $mmi_tmpimage > /dev/null 
	tune2fs -c0 -i0 $mmi_tmpimage >/dev/null
        mount -o loop $mmi_tmpimage $mmi_mntpoint
        rc=$?
        [ $rc = 0 ] || return $rc

        (cd $IMGPATH; find . | fgrep -v "./usr/lib/anaconda-runtime" |
	        cpio -H crc -o) | (cd $mmi_mntpoint; cpio -iumd)
        makeproductfile $mmi_mntpoint
        umount $mmi_mntpoint
        rmdir $mmi_mntpoint
    elif [ $type = "squashfs" ]; then
        makeproductfile $IMGPATH
        echo "Running mksquashfs $IMGPATH $mmi_tmpimage -all-root -no-fragments"
        mksquashfs $IMGPATH $mmi_tmpimage -all-root -no-fragments
        chmod 0644 $mmi_tmpimage
        SIZE=$(expr `cat $mmi_tmpimage | wc -c` / 1024)
    elif [ $type = "cramfs" ]; then
        makeproductfile $IMGPATH
        echo "Running mkcramfs $CRAMBS $IMGPATH $mmi_tmpimage"
        mkfs.cramfs $CRAMBS $IMGPATH $mmi_tmpimage
        SIZE=$(expr `cat $mmi_tmpimage | wc -c` / 1024)
    fi
    
    cp $mmi_tmpimage $INSTIMGPATH/${imagename}.img
    chmod 644 $INSTIMGPATH/${imagename}.img

    echo "Wrote $INSTIMGPATH/${imagename}.img (${SIZE}k)"
    relpath=${INSTIMGPATH#$TOPDESTPATH/}
    echo "mainimage = ${relpath}/${imagename}.img" >> $TOPDESTPATH/.treeinfo
    
    rm $mmi_tmpimage
}

makeSecondStage() {
    echo "[stage2]" >> $TOPDESTPATH/.treeinfo
    echo "Building minstg.img"
    makeinstimage "minstg" "squashfs"
    [ $? = 0 ] || exit 1
    echo "Building stage2.img"
    makemainimage "stage2" "squashfs"
    rc=$?
    [ $rc = 0 ] || exit $rc
}

doPostImages() {
   /bin/true
}

# source the architecture specific mk-images file so we can call functions
# in it
if [ ${BUILDARCH} = s390x ]; then
    # FIXME: this is a bad hack for s390, but better than copying for now
    source $TOPDIR/mk-images.s390
elif [ ${BUILDARCH} = ppc64 ]; then
    # ... and similar for ppc64
    source $TOPDIR/mk-images.ppc 
elif [ ${BUILDARCH} = "x86_64" -o ${BUILDARCH} = "i386" ]; then
    source $TOPDIR/mk-images.x86
else
    source $TOPDIR/mk-images.${BUILDARCH}
fi

# Find the kernel, unpack it, and verify it
kerneltags="kernel"
arches="$BUILDARCH"
if [ "$BUILDARCH" = "ppc" ]; then
    arches="ppc64 ppc64iseries ppc"
elif [ "$BUILDARCH" = "i386" ]; then
    arches="i586"
    kerneltags="kernel kernel-xen"
elif [ "$BUILDARCH" = "x86_64" ]; then
    kerneltags="kernel kernel-xen"
elif [ "$BUILDARCH" = "ia64" ]; then
    kerneltags="kernel kernel-xen"
fi

foundakernel=""
for KERNELARCH in $arches; do
  for kernelvers in $kerneltags; do
    kpackage=$(findPackage $KERNELPATH $kernelvers)
    if [ "$KERNELARCH" = "i586" -a ! -f "$kpackage" ]; then
	echo "No i586 kernel, trying i686..."
	KERNELARCH="i686"
	kpackage=$(findPackage $KERNELPATH $kernelvers)
    fi

    if [ ! -f "$kpackage" ]; then
	echo "kernel ($kernelvers) doesn't exist for $KERNELARCH.  skipping"
	continue
    fi

    KERNELROOT=$KERNELBASE/$KERNELARCH
    mkdir -p $KERNELROOT/lib/modules/misc

    foundakernel="yes"

    if [ "${kernelvers}" = "kernel-xen" ]; then kerneltag="xen" ; fi

    version=$(rpm --nodigest --nosignature --qf '%{VERSION}-%{RELEASE}' -qp $kpackage)${kerneltag}
    arch=$(rpm --nodigest --nosignature --qf '%{ARCH}\n' -qp $kpackage)
    echo "unpacking $kpackage.$arch"

    rpm2cpio $kpackage | (cd $KERNELROOT; cpio --quiet -iumd)

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

    if [ ! -f "$KERNELROOT/$KERNELDIR/${KERNELNAME}-$version" ]; then
	echo "$KERNELROOT/$KERNELDIR/${KERNELNAME}-$version does not exist"
	exit 1
    fi

    allmods=$(find $KERNELROOT/lib/modules/$version -name *.ko)

    rundepmod "$allmods" $MODDEPS
    find $KERNELROOT/lib/modules/$version > $CACHE

    # make the boot images
    makeBootImages
  done
done

doPostImages

# do some clean up before making the cramfs of the second stage
rm -rf $INSTIMGTEMPLATE/usr/lib/anaconda-runtime $INSTIMGTEMPLATE/usr/lib/syslinux $IMGPATH/usr/lib/syslinux

if [ -n "$foundakernel" ]; then
  # make the second stage
  find $KERNELBASE/*/lib/modules/ > $CACHE
  makeSecondStage
  rm -rf $KERNELBASE
fi

cd $TOPDIR