summary refs log tree commit diff
path: root/pkgs/build-support/appimage/appimage-exec.sh
blob: b209ce983e58517da8ebde11787d0466ad4edade (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!@shell@
if [ -n "$DEBUG" ] ; then
  set -x
fi

#export PATH=@path@
PATH="@path@:$PATH"
#DEBUG=0

# src : AppImage
# dest : let's unpack() create the directory
unpack() {
  local src=$1
  local out=$2
  local appimageSignature=""
  local appimageType=0

  # https://github.com/AppImage/libappimage/blob/ca8d4b53bed5cbc0f3d0398e30806e0d3adeaaab/src/libappimage/utils/MagicBytesChecker.cpp#L45-L63
  eval "$(r2 "$src" -nn -Nqc "p8j 3 @ 8" |
    jq -r '{appimageSignature: (.[:-1]|implode), appimageType: .[-1]}|
      @sh "appimageSignature=\(.appimageSignature) appimageType=\(.appimageType)"')"

  # check AppImage signature
  if [[ "$appimageSignature" != "AI" ]]; then
    echo "Not an appimage."
    exit
  fi

  case "$appimageType" in
    1 ) echo "Uncompress $(basename "$src") of type $appimageType."
        mkdir "$out"
        pv "$src" | bsdtar -x -C "$out" -f -
        ;;
    2)
        # This method avoid issues with non executable appimages,
        # non-native packer, packer patching and squashfs-root destination prefix.

        # multiarch offset one-liner using same method as AppImage
        # see https://gist.github.com/probonopd/a490ba3401b5ef7b881d5e603fa20c93
        offset=$(r2 "$src" -nn -Nqc "pfj.elf_header @ 0" |\
          jq 'map({(.name): .value}) | add | .shoff + (.shnum * .shentsize)')

        echo "Uncompress $(basename "$src") of type $appimageType @ offset $offset."
        unsquashfs -q -d "$out" -o "$offset" "$src"
        chmod go-w "$out"
        ;;

    # 3) get ready, https://github.com/TheAssassin/type3-runtime
    *)  echo Unsupported AppImage Type: "$appimageType"
        exit
        ;;
  esac
  echo "$(basename "$src") is now installed in $out"
}

apprun() {

  eval "$(rahash2 "$APPIMAGE" -j | jq -r '.[] | @sh "SHA256=\(.hash)"')"
  echo sha256 = \""$SHA256"\"\;
  export APPDIR="${XDG_CACHE_HOME:-$HOME/.cache}/appimage-run/$SHA256"

  #compatibility
  if [ -x "$APPDIR/squashfs-root" ]; then APPDIR="$APPDIR/squashfs-root"; fi

  if [ ! -x "$APPDIR" ]; then
    mkdir -p "$(dirname "$APPDIR")"
    unpack "$APPIMAGE" "$APPDIR"
  else echo "$(basename "$APPIMAGE")" installed in "$APPDIR"
  fi

  export PATH="$PATH:$PWD/usr/bin"
  wrap "$@"
}

wrap() {

  cd "$APPDIR" || exit
  # quite same in appimageTools
  export APPIMAGE_SILENT_INSTALL=1

  if [ -n "$APPIMAGE_DEBUG_EXEC" ]; then
    exec "$APPIMAGE_DEBUG_EXEC"
  fi

  exec ./AppRun "$@"
}

usage() {
  echo "Usage: appimage-run [appimage-run options] <AppImage> [AppImage options]";
  echo
  echo 'Options are passed on to the appimage.'
  echo "If you want to execute a custom command in the appimage's environment, set the APPIMAGE_DEBUG_EXEC environment variable."
  exit 1
}

while getopts ":a:d:xrw" option; do
    case "${option}" in
        a)  #AppImage file
            # why realpath?
            APPIMAGE="$(realpath "${OPTARG}")"
            ;;
        d)  #appimage Directory
            export APPDIR=${OPTARG}
            ;;
        x)  # eXtract
            unpack_opt=true
            ;;
        r)  # appimage-Run
            apprun_opt=true
            ;;
        w)  # WrapAppImage
            wrap_opt=true
            ;;
        *)
            usage
            ;;
    esac
done
shift $((OPTIND-1))

if [[ $unpack_opt = true ]] && [[ -f "$APPIMAGE" ]]; then
  unpack "$APPIMAGE" "$APPDIR"
  exit
fi

if [[ $apprun_opt = true ]] && [[ -f "$APPIMAGE" ]]; then
  apprun "$@"
  exit
fi

if [[ $wrap_opt = true ]] && [[ -d "$APPDIR" ]]; then
  wrap "$@"
  exit
fi