2022-04-13 21:10:51 +00:00
|
|
|
#!/bin/sh
|
2022-04-15 18:05:20 +00:00
|
|
|
set -e # exit on failure
|
|
|
|
IFS=$(printf '\n\t') # smarter ifs
|
2022-06-24 15:57:13 +00:00
|
|
|
|
2022-07-13 04:39:09 +00:00
|
|
|
apprun() {
|
|
|
|
export PATH="$APPDIR"/bin:"$PATH"
|
|
|
|
export LD_LIBRARY_PATH="$APPDIR"/lib64:"$APPDIR"/lib:"$LD_LIBRARY_PATH"
|
|
|
|
exec "$APPDIR/$(basename "$ARGV0")" "$@"
|
|
|
|
}
|
|
|
|
|
2022-06-24 15:57:13 +00:00
|
|
|
header() {
|
2022-11-14 21:43:24 +00:00
|
|
|
set -e
|
2022-11-16 00:13:59 +00:00
|
|
|
APPDIR=$(mktemp -d) APPIMAGE="$(realpath "$0")"
|
2022-11-14 21:43:24 +00:00
|
|
|
export APPDIR APPIMAGE ARGV0="$0" OWD="$PWD"
|
2022-11-16 00:13:59 +00:00
|
|
|
dwarfs -o offset=auto -o tidy_strategy=swap -o workers="$(nproc)" "$0" "$APPDIR"
|
2022-11-14 21:43:24 +00:00
|
|
|
trap 'fusermount -quz $APPDIR; rmdir $APPDIR' 0 1 2 3 6 14 15 EXIT
|
2022-06-24 15:57:13 +00:00
|
|
|
"$APPDIR/AppRun" "$@"
|
2022-11-14 21:43:24 +00:00
|
|
|
exit $?
|
2022-06-24 15:57:13 +00:00
|
|
|
}
|
|
|
|
|
2022-07-13 04:39:09 +00:00
|
|
|
printfunc() {
|
|
|
|
echo '#!/bin/sh'
|
2022-09-09 18:54:24 +00:00
|
|
|
sed -n "s/^ *//;/^$1() {$/,/^}$/p" "$0" | tail -n+2 | head -n-1
|
2022-07-13 04:39:09 +00:00
|
|
|
}
|
|
|
|
|
2022-07-19 14:59:16 +00:00
|
|
|
unappimage() {
|
2022-09-09 18:54:24 +00:00
|
|
|
o=$(($(readelf -h "$1" | sed -e 's/[^0-9]//g;13p;18,19p;d' | sed -e 1a+ -e 2a*)))
|
|
|
|
unsquashfs -o "$o" "$@" # calculate offset via ELF header
|
2022-07-19 14:59:16 +00:00
|
|
|
}
|
|
|
|
|
2022-06-24 15:57:13 +00:00
|
|
|
zzexe() {
|
|
|
|
[ "$1" = "-p" ] && p="$2" && shift 2 # save prefix if present
|
2022-07-25 00:36:24 +00:00
|
|
|
tmp=$(mktemp) # make tmp file to avoid io operations
|
|
|
|
printfunc zzexe_header | sed -e "2s/);$/${1##*[./]})/" -e "7s/^/$p /" > "$tmp"
|
|
|
|
zstdmt -cq19 "$@" >> "$tmp"
|
|
|
|
mv "$tmp" "$1"
|
|
|
|
chmod +x "$1"
|
2022-06-24 15:57:13 +00:00
|
|
|
exit
|
|
|
|
}
|
|
|
|
|
|
|
|
zzexe_header() {
|
|
|
|
dir=$(dirname "$0") out=$(mktemp -t .zzXXXX.)
|
2022-12-22 02:48:57 +00:00
|
|
|
awk 'f;/^exit \$\?$/{f=1}' "$0" | head -c-1 | zstd -cd > "$out"
|
2022-06-24 15:57:13 +00:00
|
|
|
chmod +x "$out"
|
|
|
|
ln -s "$out" "$dir"
|
2022-10-10 23:31:29 +00:00
|
|
|
trap 'rm "$out" "$dir/$(basename "$out")"' 0 1 2 3 6 14 15 EXIT
|
2022-06-24 15:57:13 +00:00
|
|
|
"$dir/$(basename "$out")" "$@"
|
2022-11-16 00:13:59 +00:00
|
|
|
exit $?
|
2022-06-24 15:57:13 +00:00
|
|
|
}
|
2021-12-31 19:24:04 +00:00
|
|
|
|
2022-06-20 19:13:05 +00:00
|
|
|
case "$1" in
|
2022-07-13 04:39:09 +00:00
|
|
|
-a )
|
|
|
|
printfunc apprun > "$2"
|
|
|
|
chmod +x "$2"
|
|
|
|
exit ;;
|
|
|
|
-b )
|
|
|
|
printfunc apprun | sed '4s#/#/bin/#' > "$2"
|
|
|
|
chmod +x "$2"
|
|
|
|
exit ;;
|
2022-07-19 14:59:16 +00:00
|
|
|
-d )
|
2022-07-25 00:36:24 +00:00
|
|
|
d=dwarfs-root # just to keep line shorter, extract if file is dwarfs
|
|
|
|
dwarfsck -d0 -i"$2" && mkdir $d && dwarfsextract -o $d -i "$2" && exit
|
|
|
|
tmp=$(mktemp) # make tmp file to avoid io operations
|
2022-12-22 02:48:57 +00:00
|
|
|
awk 'f;/^exit \$\?$/{f=1}' "$2" | head -c-1 | zstd -cd > "$tmp"
|
2022-07-25 00:36:24 +00:00
|
|
|
mv "$tmp" "$2"
|
|
|
|
chmod +x "$2"
|
2022-07-19 14:59:16 +00:00
|
|
|
exit ;;
|
|
|
|
-p )
|
2022-06-24 15:57:13 +00:00
|
|
|
zzexe "$@" ;;
|
2022-07-13 04:39:09 +00:00
|
|
|
-z)
|
|
|
|
shift
|
|
|
|
zzexe "$@" ;;
|
2022-06-24 15:57:13 +00:00
|
|
|
--version | -v )
|
2023-01-09 16:14:33 +00:00
|
|
|
tput setaf 2; echo appdwarf 2023.01.09
|
2022-06-24 15:57:13 +00:00
|
|
|
tput setaf 6; echo Built by July 🏳️🌈; exit ;;
|
|
|
|
-* | '' )
|
2022-07-19 14:59:16 +00:00
|
|
|
echo "Usage: appdwarf [option] [APP/FILE/FOLDER/URL] [compression options]"
|
2022-07-13 04:39:09 +00:00
|
|
|
echo " -a [file] Write example AppRun to file and exit"
|
|
|
|
echo " -b [file] Write example AppRun with bin subdir to file and exit"
|
2022-07-19 14:59:16 +00:00
|
|
|
echo " -d [file] Decompress an appdwarf image or zzexe'd file"
|
2022-07-13 04:39:09 +00:00
|
|
|
echo
|
2022-07-19 14:59:16 +00:00
|
|
|
echo " -p [prefix] zzexe a file with prefix"
|
2022-07-13 04:39:09 +00:00
|
|
|
echo " -z zzexe a file"
|
|
|
|
echo
|
2022-06-24 15:57:13 +00:00
|
|
|
echo " -h, --help Print this help text"
|
|
|
|
echo " -v, --version Print the appdwarf version"; exit ;;
|
2022-06-20 19:13:05 +00:00
|
|
|
esac
|
2021-05-29 20:13:12 +00:00
|
|
|
|
2022-06-20 19:13:05 +00:00
|
|
|
if [ ! -d "$1" ]; then # directory doesn't exist, see if this is an appimage
|
|
|
|
if [ ! -f "$1" ]; then # file doesn't exist, see if this is a url
|
2022-07-25 00:36:24 +00:00
|
|
|
if ! echo "$1" | grep -q / ; then # AppImageHub
|
2022-06-26 01:13:25 +00:00
|
|
|
echo "Checking AppImageHub for this program..."
|
|
|
|
app=https://github.com/AppImage/appimage.github.io/raw/master/apps/$1.md
|
|
|
|
shift
|
|
|
|
set -- "$(curl -L "$app" | grep -o https.\*releases | sed 's|/releases$||')" "$@"
|
|
|
|
elif ! echo "$1" | grep https ; then # GitHub in Author/Repo format
|
|
|
|
app=$1
|
2022-07-19 14:59:16 +00:00
|
|
|
shift
|
|
|
|
set -- "https://github.com/$app" "$@"
|
2022-06-26 01:13:25 +00:00
|
|
|
fi
|
|
|
|
|
2022-07-25 00:36:24 +00:00
|
|
|
if echo "$1" | grep -q 'https://github.com/[^/]*/[^/]*/*$'; then # GitHub url
|
2022-06-26 01:13:25 +00:00
|
|
|
echo "Assuming this is a GitHub repo..."
|
|
|
|
app="$(echo "${1%/}"/releases | sed 's|github.com|api.github.com/repos|')"
|
|
|
|
shift
|
2023-01-09 16:14:33 +00:00
|
|
|
set -- "$(curl "$app" | grep -om1 "https.*$(uname -m)\.AppImage\|https.*[^-arm64]\.AppImage")" "$@"
|
2022-06-26 01:13:25 +00:00
|
|
|
fi
|
|
|
|
|
|
|
|
app=$(basename "$1") # actually try to get the appimage
|
2022-06-20 19:13:05 +00:00
|
|
|
if aria2c -x16 -s16 "$1" -o "$app" || wget "$1" -O "$app"; then
|
|
|
|
shift
|
|
|
|
set -- "$app" "$@"
|
|
|
|
else
|
2022-07-19 14:59:16 +00:00
|
|
|
tput setaf 1; echo "No valid remote or local input found. Exiting..." >&2
|
|
|
|
rm -f "$app"; exit 1
|
2022-06-20 19:13:05 +00:00
|
|
|
fi
|
|
|
|
fi
|
2022-05-13 00:32:37 +00:00
|
|
|
|
2022-07-19 04:54:08 +00:00
|
|
|
# this is a file, but it might be an existing dwarfs image
|
2022-07-19 14:59:16 +00:00
|
|
|
if dwarfsck -d0 -i"$1"; then
|
2022-07-19 04:54:08 +00:00
|
|
|
set -- "$@" --recompress=none
|
2022-08-05 13:55:58 +00:00
|
|
|
elif test "$(hexdump -n11 -e'"%x"' "$1")" = 464c457f1010224941; then
|
|
|
|
echo "AppImage found. Converting..." # appimage magic matched
|
2022-07-19 04:54:08 +00:00
|
|
|
app="$(basename "$1" .AppImage)"
|
2022-08-05 13:55:58 +00:00
|
|
|
unappimage "$1"
|
2022-07-19 04:54:08 +00:00
|
|
|
rm -rf "$1" "$app"
|
|
|
|
shift
|
|
|
|
set -- "$app" "$@"
|
|
|
|
mv squashfs-root "$1"
|
|
|
|
else
|
2022-06-20 19:13:05 +00:00
|
|
|
tput setaf 4; echo "$1 is not an AppImage, it will be zzexe'd"
|
2022-06-24 15:57:13 +00:00
|
|
|
zzexe "$@"
|
2022-06-20 19:13:05 +00:00
|
|
|
fi
|
2022-04-15 18:05:20 +00:00
|
|
|
fi
|
|
|
|
|
2022-06-24 15:57:13 +00:00
|
|
|
head="$(mktemp)"
|
2022-07-13 04:39:09 +00:00
|
|
|
printfunc header > "$head"
|
2022-06-24 15:57:13 +00:00
|
|
|
|
2022-07-13 04:39:09 +00:00
|
|
|
mkdwarfs -o "$(realpath "$1").sh" -B5 --header "$head" -i "$@"
|
2022-10-10 23:31:29 +00:00
|
|
|
rm -rf "$head" "$1"
|
2022-04-15 18:05:20 +00:00
|
|
|
chmod +x "$(realpath "$1").sh"
|