aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2017-03-31 08:28:10 +0200
committerMarc André Tanner <mat@brain-dump.org>2017-03-31 09:32:42 +0200
commitda4e2efb9249cb8cd1e382a7653da0140bb1c95d (patch)
treee1a3af0838317dca1de73d2d069d8d6e4bbac5fe
parent12f50c8b515642d2510364115778ef90a26ebcb7 (diff)
downloadvis-da4e2efb9249cb8cd1e382a7653da0140bb1c95d.tar.gz
vis-da4e2efb9249cb8cd1e382a7653da0140bb1c95d.tar.xz
Use a minimal POSIX shar implementation for self extracting executable
This only requires POSIX shell utilies for extraction. The resulting archive is bigger (it is not gzip compressed) and startup will be slower due to many spawned processes.
-rw-r--r--GNUmakefile3
-rwxr-xr-xshar.sh120
-rwxr-xr-xvis-single.sh14
3 files changed, 121 insertions, 16 deletions
diff --git a/GNUmakefile b/GNUmakefile
index c19a64c..16635c0 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -256,10 +256,9 @@ standalone: clean
PATH=$(DEPS_BIN):$$PATH $(MAKE)
single: standalone
- cp vis-single.sh vis-single
for e in $(ELF); do \
${STRIP} "$$e"; \
done
- tar c $(EXECUTABLES) lua/ | gzip -9 >> vis-single
+ ./shar.sh vis-single $(EXECUTABLES) $$(find lua -name '*.lua')
.PHONY: standalone local dependencies-common dependencies-local dependencies-clean
diff --git a/shar.sh b/shar.sh
new file mode 100755
index 0000000..c7a532c
--- /dev/null
+++ b/shar.sh
@@ -0,0 +1,120 @@
+#!/bin/sh
+# Modified version of https://shiz.me/junk/code/fun/shar.sh
+# The generated shell archive is automatically extracted to a
+# temporary directory and the first archive member is executed.
+set -e
+
+if test $# -lt 2 ; then
+ echo "usage: $0 <output> <files>"
+ exit 1
+fi
+
+save() {
+ for i ; do
+ printf "%s\n" "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/"
+ done
+ echo " "
+}
+
+octal_mode() {
+ local mode
+
+ mode="$(ls -ld "$1" | awk '{ print $1 }' | tr '[A-Z]' '-' | cut -c2-)"
+ for i in 1 2 3 ; do
+ i=0
+ case "$mode" in r??*) i=$((i + 4)) ;; esac
+ case "$mode" in ?w?*) i=$((i + 2)) ;; esac
+ case "$mode" in ??-*) ;; ???*) i=$((i + 1)) ;; esac
+ printf "%d" "$i"
+ mode=$(echo "$mode" | cut -c4-)
+ done
+}
+
+out=$1
+tmpout=$1.tmp
+exe=$2
+shift
+
+rm -f "$tmpout"
+for f ; do
+ if test -f "$f" ; then
+ cat "$f" >> "$tmpout"
+ fi
+done
+trap 'rm "$tmpout"' EXIT
+
+clear=
+
+for f ; do
+ if test -z "$clear" ; then
+ set --
+ clear=1
+ fi
+
+ mode=$(octal_mode "$f")
+ if test -f "$f" ; then
+ size=$(wc -c "$f" | awk '{ print $1 }')
+ echo "adding: $f (mode $mode, $size bytes)"
+ set -- "$@" "f+$mode+$size:$f"
+ elif test -d "$f" ; then
+ echo "adding directory: $f (mode $mode)"
+ set -- "$@" "d+$mode:$f"
+ else
+ echo "can't add unknown file type $f" >&2
+ fi
+done
+
+cat >"$out"<<HEADER
+#!/bin/sh
+set -e
+
+outdir="\$(mktemp -d -p "\${TMPDIR:-/tmp}" .unshar-XXXXXX)"
+if test \$? -ne 0 -o ! -d "\$outdir" ; then
+ echo "failed to create temporary directory"
+ exit 1
+fi
+trap 'rm -rf "\$outdir"' EXIT INT QUIT TERM HUP
+argc=\$#
+
+self="\$0"
+set -- $(save "$@") "\$@"
+
+exec 3<"\$self"
+while read -r l ; do
+ test "\$l" = "exit 0;" && break
+done <&3
+
+while test \$# -gt \$argc ; do
+ file="\$1"
+ shift
+ meta="\${file%%:*}"
+ fn="\${file#*:}"
+ type="\${meta%%+*}"
+ meta="\${meta#*+}"
+ mode="\${meta%%+*}"
+ size="\${meta#*+}"
+ base="\${fn%/*}"
+
+ case "\$type" in
+ f)
+ echo "unpacking: \$fn (mode \$mode, \$size bytes)"
+ test "\$base" != "\$fn" && mkdir -p "\$outdir/\$base"
+ dd of="\$outdir/\$fn" bs="\$size" count=1 >/dev/null <&3
+ ;;
+ d)
+ echo "creating: \$fn (mode \$mode)"
+ mkdir -p "\$outdir/\$fn"
+ ;;
+ esac
+ chmod "\$mode" "\$outdir/\$fn" || :
+done >/dev/null 2>&1
+
+PATH="\$outdir:\$PATH" "\$outdir/$exe" "\$@"
+exit \$?
+
+exit 0;
+HEADER
+
+cat "$tmpout" >> "$out"
+chmod +x "$out"
+
diff --git a/vis-single.sh b/vis-single.sh
deleted file mode 100755
index e779b67..0000000
--- a/vis-single.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-
-set -e
-
-VISTMP="$(mktemp -d -p "${TMPDIR:-/tmp}" .vis-XXXXXX)"
-trap 'rm -rf "$VISTMP"' EXIT INT QUIT TERM HUP
-
-sed '1,/^__TAR_GZ_ARCHIVE_BELOW__$/d' "$0" | gzip -d | tar xC "$VISTMP"
-
-PATH="$VISTMP:$PATH" "$VISTMP/vis" "$@"
-
-exit $?
-
-__TAR_GZ_ARCHIVE_BELOW__