#!/bin/sh
#-----------------------------------------------------------
# 1/2008 by Th. Trepl (aka Moody)
# thomas@equinox.homelinux.org
#-----------------------------------------------------------
#
# Make a binary package.
#
# ./makepkg.sh -d /path/to/destdir pkgname
#
# This results in pkgname.bin (an executable)
#
#-----------------------------------------------------------

function show_help() {
    cat <<EOF
$0 [option] <pkgname>

Options:
-d,--directory <dirname>    Directory which will be tarred
                        into the package. This is the directory
                        which was specified in DESTDIR while
                        compilation. Default is currect directory.
--postcmd <filename>    File which contains the commands which
                        should be executed AFTER the package
                        has been installed.
                        "-" as filename will use stdin.
--precmd <filename>     File which contains the commands which
                        should be executed BEFORE the package
                        will be installed.
                        "-" as filename will use stdin.

<pkgname> is the name used for the resulting install package.
".bin" will be appended to that name.

EOF
}

ACTDIR=$(dirname $0)
BASEDIR=$(pwd)
PKGNAME="makepkg"
POSTCMD=""
PRECMD=""

while [ $# -gt 0 ]; do
    case "$1" in
        -d|--directory)	shift; BASEDIR=$1
                        ;;
        --postcmd) shift; POSTCMD=$1
                        ;;
        --precmd) shift; PRECMD=$1
                        ;;
        -h|--help) show_help
                   exit 0
                        ;;
        -*)     echo "Invalid option. Try --help"
                exit 1
                ;;
        *)      PKGNAME=$1
                break
                ;;
    esac
    shift
done

#--------------------------------------
# Creating the package script
#--------------------------------------
WORKFILE=$(mktemp -p /tmp)
echo "#!/bin/sh" > $WORKFILE
echo "PKGNAME=$(basename $PKGNAME)" >> $WORKFILE
cat >> $WORKFILE <<"EOF"
BINOFFS=%SIZE%

ACTDIR=$(dirname $0)
[ "${ACTDIR:0:1}" != "/" ] && ACTDIR=$(pwd)/$ACTDIR
SELF=$ACTDIR/$(basename $0)

function test_arch() {
    dd if=$SELF bs=1 skip=$BINOFFS 2>/dev/null | tar -tzf -
}
function extract_arch() {
    dd if=$SELF bs=1 skip=$BINOFFS 2>/dev/null | tar -xspzvf -
}
EOF

echo "function pre_install() {" >>$WORKFILE
echo "  echo \"pre_install\"" >>$WORKFILE
if [ -n "$PRECMD" ]; then
    cat $PRECMD >> $WORKFILE
fi
echo "} # pre_install" >>$WORKFILE

echo "function post_install() { :" >>$WORKFILE
echo "  echo \"post_install\"" >>$WORKFILE
if [ -n "$POSTCMD" ]; then
    cat $POSTCMD >> $WORKFILE
fi
echo "} # post_install" >>$WORKFILE

cat >>$WORKFILE <<"EOF"
#-----------------------------------------
#- Main program starts here
#-----------------------------------------
ACTION="i"
while [ $# -gt 0 ]; do
    case "$1" in
        -d|--directory) INSTALLDIR=$1; shift
                   ;;
        -t|--test) ACTION="t"
                   ;;
        -x|--extract) ACTION="x"
                   ;;
        -i|--install) ACTION="i"
                   ;;
        *)    echo "Invalid option $1"
              exit 1
              ;;
    esac
    shift
done

if [ "$ACTION" == "x" \
  -o "$ACTION" == "i" ]; then
    if [ $(id -u) -ne 0 ]; then
        echo "Must be root to run install"
        exit 1
    fi
fi
case "$ACTION" in
    t) test_arch ;;
    x) cd $INSTALLDIR/ && extract_arch ;;
    i) cd $INSTALLDIR/ && pre_install && extract_arch && post_install ;;
esac

exit $?
EOF

#--------------------------------------
# Calculate the script size
#--------------------------------------
sync
SIZE=$(stat -c %s $WORKFILE)
SIZE=$(($SIZE / 1024 + 1))
SIZE=$(($SIZE * 1024))

sed -i -e "s/%SIZE%/$SIZE/g" $WORKFILE

ASIZE=$(stat -c %s $WORKFILE)
DELTA=$(($SIZE - $ASIZE))
dd if=/dev/zero bs=1 count=$DELTA >> $WORKFILE
pushd $BASEDIR 2>&1 >/dev/null
tar -czspvf - * >> $WORKFILE
popd 2>&1 >/dev/null

mv $WORKFILE ${PKGNAME}.bin
chmod 755 ${PKGNAME}.bin
