#!/bin/sh

set -e

trap "message;\
      message \"Received signal.  Aborting.\";\
      message;\
      [ -n "$ROOT" ] && umount $ROOT > /dev/null 2>&1 || true;\
      [ -d "$TD" ] && rm -rf $TD;\
      exit 1" 1 2 3 15

message () {
  # pretty-print messages of arbitrary length
  MESSAGE_WIDTH_PENDING=$(echo -n "$*" | wc -c)
  MESSAGE_WIDTH_AVAIL=$(( ${COLUMNS:-80} - ${MESSAGE_WIDTH_USED:=0} ))
  if [ $(( $MESSAGE_WIDTH_USED + $MESSAGE_WIDTH_PENDING )) -gt \
      ${COLUMNS:-80} ] && [ $MESSAGE_WIDTH_USED -ne 0 ]
  then
      # time for a linebreak
      echo
      MESSAGE_WIDTH_AVAIL=${COLUMNS:-80}
  fi
  echo "$*" | fold -s -w $MESSAGE_WIDTH_AVAIL >&2
  MESSAGE_WIDTH_USED=0;
}

message_nonl () {
  # pretty-print messages of arbitrary length (no trailing newline)
  MESSAGE_WIDTH_PENDING=$(echo -n "$*" | wc -c)
  MESSAGE_WIDTH_AVAIL=$(( ${COLUMNS:-80} - ${MESSAGE_WIDTH_USED:=0} ))
  if [ $(( $MESSAGE_WIDTH_USED + $MESSAGE_WIDTH_PENDING )) -gt \
      ${COLUMNS:-80} ] && [ $MESSAGE_WIDTH_USED -ne 0 ]
  then
      # time for a linebreak
      echo
      MESSAGE_WIDTH_AVAIL=${COLUMNS:-80}
      MESSAGE_WIDTH_USED=0
  fi
  echo -n "$*" | fold -s -w $MESSAGE_WIDTH_AVAIL >&2
  MESSAGE_WIDTH_USED=$(( $MESSAGE_WIDTH_USED + $MESSAGE_WIDTH_PENDING ));
}

errormsg () {
  # exit script with error
  message "$*"
  exit 1;
}

if [ $# -ne 1 ]
then
    errormsg "Usage: $0 kernel_version"
fi

VERSION=$1

for FILE in /boot/vmlinuz-$VERSION /boot/System.map-$VERSION \
    /lib/modules/$VERSION/modules.dep
do
    if [ ! -f $FILE ]
    then
        errormsg "$0: could not open $FILE"
    fi
done

if [ "$(find /lib/modules/$VERSION -name \*.o)" = "" ]
then
    errormsg "$0: could not find any kernel modules in /lib/modules/$VERSION"
fi

KERNEL_VERSION=$(uname -r)
case "$KERNEL_VERSION" in
  2.2.*)
    BLOCKS=4096
    INODES=2048
  ;;
  2.4.* | 2.6.*)
    BLOCKS=8192
    INODES=4096
  ;;
  *)
    message "$0: Warning: Not updating initrd; don't know what to do with" \
            "kernel version $KERNEL_VERSION."
    exit 0
  ;;
esac

TD=${TMPDIR:-/tmp}/update-initrd.$$
mkdir $TD || errormsg "$0: unable to create temporary directory $TD; aborting."

INITRD=$TD/initrd
INITRD_GZ=/boot/initrd-$VERSION.gz

if [ ! -f $INITRD_GZ ]
then
    message_nonl "Creating $INITRD_GZ..."
else
    message_nonl "Updating $INITRD_GZ..."
    mv -f $INITRD_GZ $INITRD_GZ.old
fi

depmod -F /boot/System.map-$VERSION -a $VERSION

dd if=/dev/zero of=$INITRD bs=1k count=$BLOCKS 2> /dev/null

message_nonl "creating initrd filesystem..."
mke2fs -Fq -N $INODES $INITRD 2> /dev/null

ROOT=$TD/initrd-mnt
mkdir $ROOT
mount -o loop $INITRD $ROOT

message_nonl "copying files..."
message_nonl "/ "
cp /usr/share/discover/linuxrc $ROOT/linuxrc
message_nonl "/bin "
mkdir -m 755 $ROOT/bin
cp /bin/ash $ROOT/bin/sh
cp /bin/mount $ROOT/bin/mount
cp /bin/umount $ROOT/bin/umount
message_nonl "/dev "
mkdir -m 755 $ROOT/dev
( cd $ROOT/dev \
    && /sbin/MAKEDEV std console hda hdb hdc hdd sda sdb sdc sdd scd0 scd1 )
message_nonl "/etc "
mkdir -m 755 $ROOT/etc
touch $ROOT/etc/ld.so.conf
echo "alias block-major-8 sd_mod" > $ROOT/etc/modules.conf
message_nonl "/lib "
mkdir -m 755 $ROOT/lib
cp /lib/ld-linux.so.2 $ROOT/lib/ld-linux.so.2
cp /lib/libc.so.6 $ROOT/lib/libc.so.6
cp /lib/libm.so.6 $ROOT/lib/libm.so.6
cp /usr/lib/libdiscover.so.1 $ROOT/lib/libdiscover.so.1
rmdir $ROOT/lost+found
mkdir -m 755 $ROOT/proc
message_nonl "/sbin "
mkdir -m 755 $ROOT/sbin
cp /sbin/discover $ROOT/sbin/discover
cp /sbin/insmod $ROOT/sbin/insmod
cp /sbin/modprobe $ROOT/sbin/modprobe
message_nonl "/share "
mkdir -m 755 $ROOT/share
mkdir -m 755 $ROOT/share/discover
cp /usr/share/discover/*.lst $ROOT/share/discover
mkdir -m 1755 $ROOT/tmp
ln -s . $ROOT/usr

# Automatically copy in all of the first stage drivers and all drivers
# they depend on:

# Get a list of the SCSI drivers that discover might detect:
SCSI=`awk '{ if (match($2, "(scsi)") \
        && !match($3, "(ignore|unknown)")) \
        print $3 }' /usr/share/discover/pci.lst \
    | sort \
    | uniq`

# Copy in the SCSI disk and IDE-SCSI modules as well:
SCSI="$SCSI sd_mod ide-scsi"

for MODULE in $SCSI
do
    awk '! /\\$/ { print $0 } \
            /\\$/ { printf("%s", substr($0, 1, length($0) - 1)) }' \
            /lib/modules/$VERSION/modules.dep \
        | grep "^/lib/modules/$VERSION/.*/$MODULE.o" \
        | awk '{ print substr($1, 1, length($1) - 1) ; \
            for (i = 2; i <= NF; i++) print $i }' \
        | xargs tar cf - 2> /dev/null \
        | ( cd $ROOT && tar xf - )
done

cp /lib/modules/$VERSION/modules.dep $ROOT/lib/modules/$VERSION/modules.dep

umount $ROOT
rmdir $ROOT
gzip -9 < $INITRD > $INITRD_GZ
rm $INITRD
rm -r $TD
echo "done."

# vim:ai:et:sts=4:sw=4:tw=0:
