diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f531ce5 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +**/pcmi/** diff --git a/posix/preload b/posix/preload new file mode 100755 index 0000000..e08451c --- /dev/null +++ b/posix/preload @@ -0,0 +1,19 @@ +#!/bin/sh -e + +# SUM + +# TODO: extract self without resolving to $0 because it doesn't resolve links +tail -c +"$(expr BYTES + 1)" $0 | lz4 -dc | tar -x +# TODO: remove hardcoded directory +# TODO: use a different extraction path +cd ID + +export ORIGIN="$(pwd)" +export LD_LIBRARY_PATH="$ORIGIN/lib" +export PATH="$ORIGIN/bin":$PATH + +export LD_DEBUG='libs' + +# TODO: use $0 instead +# FIXME: uses the system's basename +exec bin/"$(basename "$1")" diff --git a/posix/prepare b/posix/prepare new file mode 100755 index 0000000..d142f59 --- /dev/null +++ b/posix/prepare @@ -0,0 +1,128 @@ +#!/bin/sh -ex + +# 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 + + readelf -d "$1" | + grep NEEDED | + awk '{print $5}' | + sed s/\\[/\ / | sed s/\\]/\ / > $tmplist + + while test -s $tmplist; do + cat $LIBLIST $tmplist > $tmpfile + mv -f $tmpfile $LIBLIST + for f in $tmplist; do + readelf -d "$f" | + grep NEEDED | + awk '{print $5}' | + sed s/\\[/\ / | sed s/\\]/\ / > $tmplist + done + done + 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 +# FIXME: double sed should be avoided +DIRNAME="$WORKDIR"/"$(head -1 $WORKDIR/id | awk '{print $1}')" + +if test -s $LIBLIST; then + rm -f $LIBLIST +fi + +for b in $WORKDIR/bin/*; do + getlibs $b +done +sort -u $LIBLIST > $tmpfile +mv -f $tmpfile $LIBLIST +while read f; do + find -L $SYS_LIBDIR -maxdepth 2 -name "$f" -exec cp -n {} $WORKDIR/lib/ \; +done < $LIBLIST + +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 $DIRNAME.tar + +cat "$PRELOAD_SCRIPT" | +sed s/SUM/"$(cat $SUMFILE)"/ | +sed s/ID/"$(basename "$DIRNAME")"/ > 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".it + +rm -f tpr tpp +chmod +x "$DIRNAME".it + +rm -rf "$DIRNAME" +#"$DIRNAME".tar*