File: functions.sh

package info (click to toggle)
aranym 1.1.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 25,488 kB
  • sloc: cpp: 178,117; ansic: 170,405; perl: 5,637; sh: 5,547; asm: 2,282; makefile: 1,324; objc: 218
file content (320 lines) | stat: -rw-r--r-- 12,663 bytes parent folder | download | duplicates (2)
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
# This file is supposed to be sourced by each Recipe
# that wants to use the functions contained herein
# like so:
# wget -q https://github.com/AppImage/AppImages/raw/master/functions.sh -O ./functions.sh
# . ./functions.sh

# RECIPE=$(realpath "$0")

# Options for apt-get to use local files rather than the system ones
OPTIONS="-o Debug::NoLocking=1
-o APT::Cache-Limit=125829120
-o Dir::Etc::sourcelist=./sources.list
-o Dir::State=./tmp
-o Dir::Cache=./tmp
-o Dir::State::status=./status
-o Dir::Etc::sourceparts=-
-o APT::Get::List-Cleanup=0
-o APT::Get::AllowUnauthenticated=1
-o Debug::pkgProblemResolver=true
-o Debug::pkgDepCache::AutoInstall=true
-o APT::Install-Recommends=0
-o APT::Install-Suggests=0
"

# Detect system architecture to know which binaries of AppImage tools
# should be downloaded and used.
case "$(uname -i)" in
  x86_64|amd64)
#    echo "x86-64 system architecture"
    SYSTEM_ARCH="x86_64";;
  i?86)
#    echo "x86 system architecture"
    SYSTEM_ARCH="i686";;
#  arm*)
#    echo "ARM system architecture"
#    SYSTEM_ARCH="";;
  unknown)
#         uname -i not answer on debian, then:
    case "$(uname -m)" in
      x86_64|amd64)
#        echo "x86-64 system architecture"
        SYSTEM_ARCH="x86_64";;
      i?86)
#        echo "x86 system architecture"
        SYSTEM_ARCH="i686";;
    esac ;;
  *)
    echo "Unsupported system architecture"
    exit 1;;
esac

# Either get the file from remote or from a static place.
# critical for builds without network access like in Open Build Service
cat_file_from_url()
{
  cat_excludelist="wget -q $1 -O -"
  [ -e "$STATIC_FILES/${1##*/}" ] && cat_excludelist="cat $STATIC_FILES/${1##*/}"
  $cat_excludelist
}

git_pull_rebase_helper()
{
  git reset --hard HEAD
  git pull
}

# Patch /usr to ././ in ./usr
# to make the contents of usr/ relocateable
# (this requires us to cd ./usr before running the application; AppRun does that)
patch_usr()
{
  find usr/ -type f -executable -exec sed -i -e "s|/usr|././|g" {} \;
}

# Download AppRun and make it executable
get_apprun()
{
  TARGET_ARCH=${ARCH:-$SYSTEM_ARCH}
  if test -f "$STATIC_FILES/AppRun-${TARGET_ARCH}"; then
    cp -a $STATIC_FILES/AppRun-${TARGET_ARCH} AppRun
  else
	wget -c https://github.com/AppImage/AppImageKit/releases/download/continuous/AppRun-${TARGET_ARCH} -O AppRun
  fi
  chmod a+x AppRun
}

# Copy the library dependencies of all exectuable files in the current directory
# (it can be beneficial to run this multiple times)
copy_deps()
{
  PWD=$(readlink -f .)
  FILES=$(find . -type f -executable -or -name *.so.* -or -name *.so | sort | uniq )
  for FILE in $FILES ; do
    ldd "${FILE}" | grep "=>" | awk '{print $3}' | xargs -I '{}' echo '{}' >> DEPSFILE
  done
  DEPS=$(cat DEPSFILE | sort | uniq)
  for FILE in $DEPS ; do
    if [ -e $FILE ] && [[ $(readlink -f $FILE)/ != $PWD/* ]] ; then
      cp -v --parents -rfL $FILE ./ || true
    fi
  done
  rm -f DEPSFILE
}

# Move ./lib/ tree to ./usr/lib/
move_lib()
{
  mkdir -p ./usr/lib ./lib && find ./lib/ -exec cp -v --parents -rfL {} ./usr/ \; && rm -rf ./lib
  mkdir -p ./usr/lib ./lib64 && find ./lib64/ -exec cp -v --parents -rfL {} ./usr/ \; && rm -rf ./lib64
  find ./usr/lib -name "*.so*" | xargs --no-run-if-empty chmod a+x
  find ./usr/lib64 -name "*.so*" | xargs --no-run-if-empty chmod a+x
}

# Delete blacklisted files
delete_blacklisted()
{
  BLACKLISTED_FILES=$(cat_file_from_url https://github.com/AppImage/AppImages/raw/master/excludelist | sed 's|#.*||g')
  echo $BLACKLISTED_FILES
  for FILE in $BLACKLISTED_FILES ; do
    FILES="$(find . -name "${FILE}" -not -path "./usr/optional/*")"
    for FOUND in $FILES ; do
      rm -vf "$FOUND" "$(readlink -f "$FOUND")"
    done
  done

  # Do not bundle developer stuff
  rm -rf usr/include || true
  rm -rf usr/lib/cmake || true
  rm -rf usr/lib/pkgconfig || true
  find . -name '*.la' | xargs -i rm {}
}

# Echo highest glibc version needed by the executable files in the current directory
glibc_needed()
{
  find . -name *.so -or -name *.so.* -or -type f -executable  -exec readelf -s '{}' 2>/dev/null \; | sed -n 's/.*@GLIBC_//p'| awk '{print $1}' | sort --version-sort | tail -n 1
}
# Add desktop integration
# Usage: get_desktopintegration name_of_desktop_file_and_exectuable
get_desktopintegration()
{
  REALBIN=$(grep -o "^Exec=.*" "$1.desktop" | sed -e 's|Exec=||g' | cut -d " " -f 1 | head -n 1)
  cat_file_from_url https://raw.githubusercontent.com/AppImage/AppImageKit/master/desktopintegration > "./usr/bin/$REALBIN.wrapper"
  chmod a+x "./usr/bin/$REALBIN.wrapper"

  sed -i -e "s|^Exec=$REALBIN|Exec=$REALBIN.wrapper|g" "$1.desktop"
}

# Generate AppImage; this expects $ARCH, $APP and $VERSION to be set
generate_appimage()
{
  # Download AppImageAssistant
  URL="https://github.com/AppImage/AppImageKit/releases/download/6/AppImageAssistant_6-${SYSTEM_ARCH}.AppImage"
  wget -c "$URL" -O AppImageAssistant
  chmod a+x ./AppImageAssistant

  # if [[ "$RECIPE" == *ecipe ]] ; then
  #   echo "#!/bin/bash -ex" > "./${APP}.AppDir/Recipe"
  #   echo "# This recipe was used to generate this AppImage." >> "./${APP}.AppDir/Recipe"
  #   echo "# See http://appimage.org for more information." >> "./${APP}.AppDir/Recipe"
  #   echo "" >> "./${APP}.AppDir/Recipe"
  #   cat $RECIPE >> "./${APP}.AppDir/Recipe"
  # fi
  #
  # Detect the architecture of what we are packaging.
  # The main binary could be a script, so let's use a .so library
  BIN=$(find . -name *.so* -type f | head -n 1)
  INFO=$(file "$BIN")
  if [ -z $ARCH ] ; then
    if [[ $INFO == *"x86-64"* ]] ; then
      ARCH=x86_64
    elif [[ $INFO == *"i686"* ]] ; then
      ARCH=i686
    elif [[ $INFO == *"armv6l"* ]] ; then
      ARCH=armhf
    else
      echo "Could not automatically detect the architecture."
      echo "Please set the \$ARCH environment variable."
     exit 1
    fi
  fi

  mkdir -p ../out || true
  GLIBC_NEEDED=${GLIBC_NEEDED:=$(glibc_needed)}
  rm "../out/${APP}-${VERSION}.glibc${GLIBC_NEEDED}-${ARCH}.AppImage" 2>/dev/null || true
  ./AppImageAssistant "./${APP}.AppDir/" "../out/${APP}-${VERSION}.glibc${GLIBC_NEEDED}-${ARCH}.AppImage"
}

# Generate AppImage type 2
generate_type2_appimage()
{
  # Get the ID of the last successful build on Travis CI
  # ID=$(wget -q https://api.travis-ci.org/repos/AppImage/appimagetool/builds -O - | head -n 1 | sed -e 's|}|\n|g' | grep '"result":0' | head -n 1 | sed -e 's|,|\n|g' | grep '"id"' | cut -d ":" -f 2)
  # Get the transfer.sh URL from the logfile of the last successful build on Travis CI
  # Only Travis knows why build ID and job ID don't match and why the above doesn't give both...
  # URL=$(wget -q "https://s3.amazonaws.com/archive.travis-ci.org/jobs/$((ID+1))/log.txt" -O - | grep "https://transfer.sh/.*/appimagetool" | tail -n 1 | sed -e 's|\r||g')
  # if [ -z "$URL" ] ; then
  #   URL=$(wget -q "https://s3.amazonaws.com/archive.travis-ci.org/jobs/$((ID+2))/log.txt" -O - | grep "https://transfer.sh/.*/appimagetool" | tail -n 1 | sed -e 's|\r||g')
  # fi
  URL="https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-${SYSTEM_ARCH}.AppImage"
  wget -c "$URL" -O appimagetool
  chmod a+x ./appimagetool
  test -f appimagetool || exit 1
  set +x
  GLIBC_NEEDED=${GLIBC_NEEDED:=$(glibc_needed)}
  TARGET_ARCH=${ARCH:-$SYSTEM_ARCH}
  if test -z "$APPIMAGE"; then
  	APPIMAGE=`echo $APP | tr ' ' '_'`${VERSION}.glibc$GLIBC_NEEDED-${TARGET_ARCH}.AppImage
  fi
  if ( [ ! -z "$KEY" ] ) && ( ! -z "$TRAVIS" ) ; then
    wget https://github.com/AppImage/AppImageKit/files/584665/data.zip -O data.tar.gz.gpg
    ( set +x ; echo $KEY | gpg2 --batch --passphrase-fd 0 --no-tty --skip-verify --output data.tar.gz --decrypt data.tar.gz.gpg )
    tar xf data.tar.gz
    sudo chown -R $USER .gnu*
    mv $HOME/.gnu* $HOME/.gnu_old ; mv .gnu* $HOME/
    ./appimagetool -n -s --bintray-user $BINTRAY_REPO_OWNER --bintray-repo $BINTRAY_REPO -v "./${APP}.AppDir/" "$APPIMAGE" || exit 1
  else
    ./appimagetool -n --bintray-user $BINTRAY_REPO_OWNER --bintray-repo $BINTRAY_REPO -v "./${APP}.AppDir/" "$APPIMAGE" || exit 1
  fi
  set -x
  OUT=${OUT:-../out}
  mkdir -p "${OUT}" || true
  mv *.AppImage* "${OUT}"
  set +x
}

# Generate status file for use by apt-get; assuming that the recipe uses no newer
# ingredients than what would require more recent dependencies than what we assume
# to be part of the base system
generate_status()
{
  mkdir -p ./tmp/archives/
  mkdir -p ./tmp/lists/partial
  touch tmp/pkgcache.bin tmp/srcpkgcache.bin
  wget -q -c "https://github.com/AppImage/AppImages/raw/master/excludedeblist"
  rm status 2>/dev/null || true
  for PACKAGE in $(cat excludedeblist | cut -d "#" -f 1) ; do
    printf "Package: $PACKAGE\nStatus: install ok installed\nArchitecture: all\nVersion: 9:999.999.999\n\n" >> status
  done
}

# Find the desktop file and copy it to the AppDir
get_desktop()
{
   find usr/share/applications -name "${LOWERAPP}.desktop" -exec cp {} . \; || true
}

fix_desktop() {
    # fix trailing semicolons
    for key in Actions Categories Implements Keywords MimeType NotShowIn OnlyShowIn; do
      sed -i '/'"$key"'.*[^;]$/s/$/;/' $1
    done
}

# Find the icon file and copy it to the AppDir
get_icon()
{
  find ./usr/share/pixmaps/$LOWERAPP.png -exec cp {} . \; 2>/dev/null || true
  find ./usr/share/icons -path *32* -name $LOWERAPP.png -exec cp {} . \; 2>/dev/null || true
  find ./usr/share/icons -path *48* -name $LOWERAPP.png -exec cp {} . \; 2>/dev/null || true
  find ./usr/share/icons -path *64* -name $LOWERAPP.png -exec cp {} . \; 2>/dev/null || true
  find ./usr/share/icons -path *128* -name $LOWERAPP.png -exec cp {} . \; 2>/dev/null || true
  find ./usr/share/icons -path *256* -name $LOWERAPP.png -exec cp {} . \; 2>/dev/null || true
  find ./usr/share/icons -path *512* -name $LOWERAPP.png -exec cp {} . \; 2>/dev/null || true
  ls -lh $LOWERAPP.png || true
}

# Find out the version
get_version()
{
  THEDEB=$(find ../*.deb -name $LOWERAPP"_*" | head -n 1)
  if [ -z "$THEDEB" ] ; then
    echo "Version could not be determined from the .deb; you need to determine it manually"
  fi
  VERSION=$(echo $THEDEB | cut -d "~" -f 1 | cut -d "_" -f 2 | cut -d "-" -f 1 | sed -e 's|1%3a||g' | sed -e 's|+dfsg||g' )
  echo ${VERSION}
}

# transfer.sh
transfer() { if [ $# -eq 0 ]; then echo "No arguments specified. Usage:\necho transfer /tmp/test.md\ncat /tmp/test.md | transfer test.md"; return 1; fi
tmpfile=$( mktemp -t transferXXX ); if tty -s; then basefile=$(basename "$1" | sed -e 's/[^a-zA-Z0-9._-]/-/g'); curl --progress-bar --upload-file "$1" "https://transfer.sh/$basefile" >> $tmpfile; else curl --progress-bar --upload-file "-" "https://transfer.sh/$1" >> $tmpfile ; fi; cat $tmpfile; rm -f $tmpfile; }

# Patch binary files; fill with padding if replacement is shorter than original
# http://everydaywithlinux.blogspot.de/2012/11/patch-strings-in-binary-files-with-sed.html
# Example: patch_strings_in_file foo "/usr/local/lib/foo" "/usr/lib/foo"
patch_strings_in_file() {
    local FILE="$1"
    local PATTERN="$2"
    local REPLACEMENT="$3"
    # Find all unique strings in FILE that contain the pattern
    STRINGS=$(strings ${FILE} | grep ${PATTERN} | sort -u -r)
    if [ "${STRINGS}" != "" ] ; then
        echo "File '${FILE}' contain strings with '${PATTERN}' in them:"
        for OLD_STRING in ${STRINGS} ; do
            # Create the new string with a simple bash-replacement
            NEW_STRING=${OLD_STRING//${PATTERN}/${REPLACEMENT}}
            # Create null terminated ASCII HEX representations of the strings
            OLD_STRING_HEX="$(echo -n ${OLD_STRING} | xxd -g 0 -u -ps -c 256)00"
            NEW_STRING_HEX="$(echo -n ${NEW_STRING} | xxd -g 0 -u -ps -c 256)00"
            if [ ${#NEW_STRING_HEX} -le ${#OLD_STRING_HEX} ] ; then
                # Pad the replacement string with null terminations so the
                # length matches the original string
                while [ ${#NEW_STRING_HEX} -lt ${#OLD_STRING_HEX} ] ; do
                    NEW_STRING_HEX="${NEW_STRING_HEX}00"
                done
                # Now, replace every occurrence of OLD_STRING with NEW_STRING
                echo -n "Replacing ${OLD_STRING} with ${NEW_STRING}... "
                hexdump -ve '1/1 "%.2X"' ${FILE} | \
                sed "s/${OLD_STRING_HEX}/${NEW_STRING_HEX}/g" | \
                xxd -r -p > ${FILE}.tmp
                chmod --reference ${FILE} ${FILE}.tmp
                mv ${FILE}.tmp ${FILE}
                echo "Done!"
            else
                echo "New string '${NEW_STRING}' is longer than old" \
                     "string '${OLD_STRING}'. Skipping."
            fi
        done
    fi
}