#!/bin/sh -e

# NEEDED: lz4 readelf tar cat awk cut sed sh sort

WORKDIR="$(basename "$1")"
SYS_LIBDIR='/lib'
PRELOAD_SCRIPT='preload'
LIBLIST=$WORKDIR/liblist
SUMFILE=$WORKDIR/checksum
tmpfile=$WORKDIR/tt

die ()
{
	echo "$1"
	exit
}

getlibs ()
{
	tmplist=$WORKDIR/tmplist

	touch $LIBLIST

	# Take the executable and get the first level dependencies
	readelf -d "$1" |
	grep NEEDED |
	awk '{print $5}' |
	sed s/\\[/\ / | sed s/\\]/\ / > $tmplist

	# While there are more dependencies
	while [ "$(cat $tmplist)" ]; do
		# Add them to the master file
		cat $LIBLIST $tmplist > $tmpfile
		mv -f $tmpfile $LIBLIST

		# Copy them to lib/
		while read l; do
			find -L $SYS_LIBDIR -maxdepth 2 -name "$l" -exec cp -n {} $WORKDIR/lib/ \;
		done < $tmplist

		# Extract their dependencies
		touch $tmpfile
		for f in $WORKDIR/lib/*; do
			if [ "$(grep -F "$(basename "$f")" "$tmplist")" ]; then
				readelf -d "$f" |
				grep NEEDED |
				awk '{print $5}' |
				sed s/\\[/\ / | sed s/\\]/\ / >> $tmpfile
			fi
		done
		sort -u $tmpfile > $tmplist
	done
	sort -u $LIBLIST > $tmpfile
	mv -f $tmpfile $LIBLIST
	rm -f $tmplist
}

if ! [ $WORKDIR ]; then
	die 'Not enough arguments'
fi

if ! test -d $WORKDIR ; then
	die 'Argument is not a directory'
fi

if test -e $WORKDIR/bin; then 
	if ! test -d $WORKDIR/bin; then
		die 'bin/ is not a directory'
	fi
else
	die 'Directory does not contain bin/'
fi

if ! test -e $WORKDIR/id; then
	die 'id file not present'
fi

if ls -1 $WORKDIR/bin; then
	for f in $WORKDIR/bin/*; do
		if ! test -x $f; then
			die "$f is not executable"
		fi
	done
else
	die 'bin/ is empty, there has to be at least one executable'
fi

# Create necessary directories and files
mkdir -p $WORKDIR/lib
mkdir -p $WORKDIR/man
mkdir -p $WORKDIR/ext
touch $WORKDIR/env

# TODO: add usage and error checking
DIRNAME="$WORKDIR"/"$(head -1 $WORKDIR/id | awk '{print $1}')"

if test -s $LIBLIST; then
	rm -f $LIBLIST
fi

echo "Fetching dependencies and stripping binaries..."
# TODO: get al binary dependencies from deps file
# Get all dependencies and strip them
for b in $WORKDIR/bin/*; do
	getlibs $b
	strip $b
done
echo "Stripping libraries..."
for l in $WORKDIR/lib/*; do
	strip $l
done

echo "Compressing destination directory..."
if test -d $DIRNAME; then
	rm -rf $DIRNAME
fi
mkdir -p $DIRNAME

cp -r $WORKDIR/bin $DIRNAME/
cp -r $WORKDIR/lib $DIRNAME/
cp -r $WORKDIR/man $DIRNAME/
cp -r $WORKDIR/ext $DIRNAME/
cp $WORKDIR/env $DIRNAME/
cp $WORKDIR/id $DIRNAME/

tar -c -f $DIRNAME.tar -C $WORKDIR "$(basename $DIRNAME)"
md5sum -b $DIRNAME.tar | cut -d " " -f1 > $SUMFILE
lz4 --rm -9 -c $DIRNAME.tar > "$DIRNAME".tar.lz4

echo "Injecting payload..."
cat "$PRELOAD_SCRIPT" |
sed s/SUM/"$(cat $SUMFILE)"/ |
sed s/ID/"$(basename "$DIRNAME")"/ |
awk '!/^ *#/ && NF' > tpp

size="$(wc -c tpp | cut -d " " -f1)"
strsize="$(echo "BYTES" | wc -c)"
numsize="$(echo "$size" | wc -c)"
normsize="$(expr "$size" - "$(expr "$strsize" - "$numsize")")"

cat tpp |
sed s/BYTES/"$normsize"/ > tpr
cat tpr "$DIRNAME".tar.lz4 > "$DIRNAME".ti

echo "Cleaning up..."
rm -f tpr tpp
chmod +x "$DIRNAME".ti

rm -rf "$DIRNAME" "$DIRNAME".tar*