#!/bin/bash
# initrd-update-boottime: writes a given integer to a 'boottime' file
# in an initramfs.
# 
# Author: Will Woods <wwoods@redhat.com>
# 
# Note: Each run of this will add some tiny amount of data (~20b) to
# the initrd. You'll need to use '-u' when extracting the initrd to 
# be sure you get the most up-to-date copy of boottime.

defaultboottime="/etc/boottime"

append="false" # set to "true" to append to the cpio rather than rewriting

function usage() {
    echo "usage: $(basename $0) INITRD [BOOTTIME]"
    echo "Writes BOOTTIME (default: $defaultboottime) into INITRD"
}

# Check validity of our arguments
if [ $# -lt 1 ]; then
    usage
    exit $#
fi
ftype=$(file -b "$1")
if ! echo $ftype | egrep -q 'gzip|cpio'; then
    echo "$1 is not a readable initrd"
    exit 1
fi
initrd="$1"

boottime=${2:-$defaultboottime}
[ -r $boottime ] && timeval=$(< $boottime)
if ! [[ "$timeval" =~ ^[1-9][0-9]*\.[0-9]+$ ]]; then
    echo "$2 does not appear to be a valid boottime"
    exit 1
fi

# permission check
if [ $(id -u) -gt 0 ]; then
    echo "You need to be root to run this."
    exit 1
fi

# OK here we go.

# create tmpdir
tmpdir=$(mktemp -dt initrd-update-boottime-XXXXXXXXXX)

# extract given initrd to an uncompressed cpio in the tmpdir
if echo "$ftype" | grep -q 'gzip'; then
    gzip -dc < $initrd > $tmpdir/initrd.cpio
else
    cp $initrd $tmpdir/initrd.cpio
fi

# append the new boottime file to our temporary copy of the initrd
rboottime=${boottime##/} # relativize path
if [ "$append" == "true" ]; then
  ( cd $tmpdir; mkdir -p $(dirname $rboottime); cat $boottime > $rboottime; \
    echo $rboottime | cpio --quiet -o -H newc -A -F initrd.cpio )
  gzip -c9 $tmpdir/initrd.cpio > $initrd.update-boottime.tmp
else
  cd $tmpdir
  mkdir initrd
  cd initrd
  cpio --quiet -iud < ../initrd.cpio
  mkdir -p $(dirname $rboottime)
  cat $boottime > $rboottime;
  find . | cpio --quiet -o -H newc | gzip -c9 > $initrd.update-boottime.tmp
fi

# atomically overwrite the old initrd
mv $initrd.update-boottime.tmp $initrd

# clean up tmpdir
# FIXME fire this on interrupt
rm -rf $tmpdir
