redhat-rpm-config/brp-mangle-shebangs
DistroBaker f6a0df9797 Merged update from upstream sources
This is an automated DistroBaker update from upstream sources.
If you do not know what this is about or would like to opt out,
contact the OSCI team.

Source: https://src.fedoraproject.org/rpms/redhat-rpm-config.git#27a8c7a7c29c8ee850279d607d35793cbb91c983
2021-03-23 11:10:32 +00:00

166 lines
4.3 KiB
Bash
Executable File

#!/bin/bash -eu
# If using normal root, avoid changing anything.
if [ -z "$RPM_BUILD_ROOT" -o "$RPM_BUILD_ROOT" = "/" ]; then
exit 0
fi
exclude_files=""
exclude_files_from=""
exclude_shebangs=""
exclude_shebangs_from=""
usage() {
local verbose=$1 && shift
local outfile=$1 && shift
local status=$1 && shift
(
echo 'usage: brp-mangle-shebangs [--files <regexp>] [--files-from <file>] [--shebangs <regexp>] [--shebangs-from <file>]'
if [ "${verbose}" == "yes" ]; then
echo ' --files: extended regexp of files to ignore'
echo ' --files-from: file containing a list of extended regexps of files to ignore'
echo ' --shebangs: extended regexp of shebangs to ignore'
echo ' --shebangs-from: file containing a list of extended regexps of shebangs to ignore'
fi
) >>${outfile}
exit ${status}
}
while [ $# -gt 0 ] ; do
case "$1" in
--files)
exclude_files="${2}"
shift
;;
--files=*)
exclude_files="${1##--files=}"
;;
--files-from)
exclude_files_from="${2}"
shift
;;
--files-from=*)
exclude_files_from="${1##--files-from=}"
;;
--shebangs)
exclude_shebangs="${2}"
shift
;;
--shebangs=*)
exclude_shebangs="${1##--shebangs=}"
;;
--shebangs-from)
exclude_shebangs_from="${2}"
shift
;;
--shebangs-from=*)
exclude_shebangs_from="${1##--shebangs-from=}"
;;
--help|--usage|"-?"|-h)
usage yes /dev/stdout 0
;;
*)
echo "Unknown option \"${1}\"" 1>&2
usage no /dev/stderr 1
;;
esac
shift
done
cd "$RPM_BUILD_ROOT"
# Large packages such as kernel can have thousands of executable files.
# We take care to not fork/exec thousands of "file"s and "grep"s,
# but run just two of them.
# (Take care to exclude filenames which would mangle "file" output).
find -executable -type f ! -path '*:*' ! -path $'*\n*' \
| file -N --mime-type -f - \
| grep -P ".+(?=: text/)" \
| {
fail=0
while IFS= read -r line; do
f=${line%%:*}
# Remove the dot
path="${f#.}"
if [ -n "$exclude_files" ]; then
echo "$path" | grep -q -E "$exclude_files" && continue
fi
if [ -n "$exclude_files_from" ]; then
echo "$path" | grep -q -E -f "$exclude_files_from" && continue
fi
if ! read shebang_line < "$f"; then
echo >&2 "*** WARNING: Cannot read the first line from $f, removing executable bit"
ts=$(stat -c %y "$f")
chmod -x "$f"
touch -d "$ts" "$f"
continue
fi
orig_shebang="${shebang_line#\#!}"
if [ "$orig_shebang" = "$shebang_line" ]; then
echo >&2 "*** WARNING: $f is executable but has no shebang, removing executable bit"
ts=$(stat -c %y "$f")
chmod -x "$f"
touch -d "$ts" "$f"
continue
fi
# Trim spaces
while shebang="${orig_shebang// / }"; [ "$shebang" != "$orig_shebang" ]; do
orig_shebang="$shebang"
done
# Treat "#! /path/to " as "#!/path/to"
orig_shebang="${orig_shebang# }"
shebang="$orig_shebang"
if [ -z "$shebang" ]; then
echo >&2 "*** WARNING: $f is executable but has empty shebang, removing executable bit"
ts=$(stat -c %y "$f")
chmod -x "$f"
touch -d "$ts" "$f"
continue
fi
if [ -n "${shebang##/*}" ]; then
echo >&2 "*** ERROR: $f has shebang which doesn't start with '/' ($shebang)"
fail=1
continue
fi
if ! { echo "$shebang" | grep -q -P "^/(?:usr/)?(?:bin|sbin)/"; }; then
continue
fi
# Replace "special" env shebang:
# /whatsoever/env /whatever/foo → /whatever/foo
shebang=$(echo "$shebang" | sed -r -e 's@^(.+)/env /(.+)$@/\2@')
# /whatsoever/env foo → /whatsoever/foo
shebang=$(echo "$shebang" | sed -r -e 's@^(.+/)env (.+)$@\1\2@')
# If the shebang now starts with /bin, change it to /usr/bin
# https://bugzilla.redhat.com/show_bug.cgi?id=1581757
shebang=$(echo "$shebang" | sed -r -e 's@^/bin/@/usr/bin/@')
# Replace ambiguous python with python2
py_shebang=$(echo "$shebang" | sed -r -e 's@/usr/bin/python(\s|$)@/usr/bin/python2\1@')
if [ "$shebang" != "$py_shebang" ]; then
echo >&2 "*** ERROR: ambiguous python shebang in $path: #!$orig_shebang. Change it to python3 (or python2) explicitly."
fail=1
elif [ "#!$shebang" != "#!$orig_shebang" ]; then
echo "mangling shebang in $path from $orig_shebang to #!$shebang"
ts=$(stat -c %y "$f")
sed -i -e "1c #!$shebang" "$f"
touch -d "$ts" "$f"
fi
done
exit $fail
}