#!/bin/sh
#
# Update an single file (content via stdin) on the flash disk if the md5 does
# not match. This script tries to be on the safe side by checking md5 at
# various stages.
#
# TODO: Maybe rsync is also able to perform the mount and umount before and
# after, this will eliminate all the hacking with md5 checks.
#
# Rick van der Zwet <info@rickvanderzwet.nl>
#

if [ -z "$1" ]; then
  echo "Usage: $0 <filepath> [<md5sum> [<file mode bits> [<file ownership>]]]" 1>&2
  exit 128
fi

FILE=$1
NEW_MD5=${2:-""}
MODE_BITS=${3:-""}
OWNERSHIP=${4:-""}

if [ ! -f "$FILE" ]; then
  echo "# ERROR: File $FILE does not exists" 1>&2
  exit 1
fi

# First try to transfer file to local system
# this restricts the filesize to the maximum size of the /tmp system
TMPFILE=`mktemp -t $(basename $0)` || exit 1
cat > $TMPFILE || exit 1
TMP_MD5="`md5 -q $TMPFILE`" || exit 1

# Check which md5 to use, the given one or the calculated one
if [ -n "$NEW_MD5" ]; then
  TARGET_MD5="$NEW_MD5"
  if [ "$TMP_MD5" != "$TARGET_MD5" ]; then
    echo "# ERROR: File transfer failed" 1>&2
    exit 2
  fi
else
  TARGET_MD5="$TMP_MD5"
fi

# Actually check whether we need to copy the file 
CURRENT_MD5=`md5 -q $FILE` || exit 1
if [ "$CURRENT_MD5" != "$TARGET_MD5" ]; then
  echo "# INFO: Updating $FILE; old MD5 $CURRENT_MD5"
  mount -uwo noatime / || exit 1
  cp -f $TMPFILE $FILE
  [ -n "$MODE_BITS" ] && chmod $MODE_BITS $FILE
  [ -n "$OWNERSHIP" ] && chown $OWNERSHIP $FILE
  mount -ur /

  # Make sure to recheck the md5 alter write to make sure all went ok
  RECHECK_MD5=`md5 -q $FILE`
  echo "# INFO: Updated $FILE; new MD5 $RECHECK_MD5"
else
  echo "# INFO: File $FILE already has md5 $CURRENT_MD5"
fi
