2018-02-15 09:02:44 +00:00
|
|
|
#!/bin/bash -eu
|
2018-01-10 12:38:28 +00:00
|
|
|
|
|
|
|
# If using normal root, avoid changing anything.
|
|
|
|
if [ -z "$RPM_BUILD_ROOT" -o "$RPM_BUILD_ROOT" = "/" ]; then
|
|
|
|
exit 0
|
|
|
|
fi
|
|
|
|
|
2018-05-02 18:28:58 +00:00
|
|
|
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
|
2018-02-14 19:09:03 +00:00
|
|
|
|
2018-01-10 12:38:28 +00:00
|
|
|
cd "$RPM_BUILD_ROOT"
|
|
|
|
|
|
|
|
trim() {
|
|
|
|
printf '%s' "$*"
|
|
|
|
}
|
|
|
|
|
2019-11-21 14:48:07 +00:00
|
|
|
# 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/)" \
|
|
|
|
| {
|
2018-01-10 12:38:28 +00:00
|
|
|
fail=0
|
2019-11-21 14:48:07 +00:00
|
|
|
while IFS= read -r line; do
|
|
|
|
f=${line%%:*}
|
2018-01-10 12:38:28 +00:00
|
|
|
|
2018-02-14 19:09:03 +00:00
|
|
|
# Remove the dot
|
|
|
|
path="${f#.}"
|
|
|
|
|
|
|
|
if [ -n "$exclude_files" ]; then
|
|
|
|
echo "$path" | grep -q -E "$exclude_files" && continue
|
|
|
|
fi
|
2018-05-02 18:28:58 +00:00
|
|
|
if [ -n "$exclude_files_from" ]; then
|
|
|
|
echo "$path" | grep -q -E -f "$exclude_files_from" && continue
|
|
|
|
fi
|
2018-02-14 19:09:03 +00:00
|
|
|
|
2018-01-10 12:38:28 +00:00
|
|
|
ts=$(stat -c %y "$f")
|
|
|
|
|
2018-02-20 10:34:07 +00:00
|
|
|
read shebang_line < "$f" || :
|
|
|
|
orig_shebang=$(trim $(echo "$shebang_line" | grep -Po "#!\K.*" || echo))
|
|
|
|
shebang="$orig_shebang"
|
2018-02-14 19:09:03 +00:00
|
|
|
if [ -n "$exclude_shebangs" ]; then
|
|
|
|
echo "$shebang" | grep -q -E "$exclude_shebangs" && continue
|
|
|
|
fi
|
2018-05-02 18:28:58 +00:00
|
|
|
if [ -n "$exclude_shebangs_from" ]; then
|
|
|
|
echo "$shebang" | grep -q -E -f "$exclude_shebangs_from" && continue
|
|
|
|
fi
|
2018-02-14 19:09:03 +00:00
|
|
|
|
2018-01-10 12:38:28 +00:00
|
|
|
if [ -z "$shebang" ]; then
|
|
|
|
echo >&2 "*** WARNING: $f is executable but has empty or no shebang, removing executable bit"
|
|
|
|
chmod -x "$f"
|
|
|
|
touch -d "$ts" "$f"
|
|
|
|
continue
|
2018-02-08 09:38:40 +00:00
|
|
|
elif [ -n "${shebang##/*}" ]; then
|
2018-01-10 12:38:28 +00:00
|
|
|
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:
|
2018-02-07 17:11:42 +00:00
|
|
|
# /whatsoever/env /whatever/foo → /whatever/foo
|
|
|
|
shebang=$(echo "$shebang" | sed -r -e 's@^(.+)/env /(.+)$@/\2@')
|
2018-01-10 12:38:28 +00:00
|
|
|
# /whatsoever/env foo → /whatsoever/foo
|
|
|
|
shebang=$(echo "$shebang" | sed -r -e 's@^(.+/)env (.+)$@\1\2@')
|
|
|
|
|
2018-07-16 08:48:54 +00:00
|
|
|
# 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/@')
|
|
|
|
|
2018-01-10 12:38:28 +00:00
|
|
|
# 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
|
2018-09-09 20:46:34 +00:00
|
|
|
echo >&2 "*** ERROR: ambiguous python shebang in $path: #!$orig_shebang. Change it to python3 (or python2) explicitly."
|
|
|
|
fail=1
|
2018-02-20 10:34:07 +00:00
|
|
|
elif [ "#!$shebang" != "#!$orig_shebang" ]; then
|
2018-01-10 12:38:28 +00:00
|
|
|
sed -i -e "1c #!$shebang" "$f"
|
2018-02-14 19:09:03 +00:00
|
|
|
echo "mangling shebang in $path from $orig_shebang to #!$shebang"
|
2018-01-10 12:38:28 +00:00
|
|
|
fi
|
|
|
|
|
|
|
|
touch -d "$ts" "$f"
|
2019-11-21 14:48:07 +00:00
|
|
|
done
|
2018-01-10 12:38:28 +00:00
|
|
|
|
|
|
|
exit $fail
|
2019-11-21 14:48:07 +00:00
|
|
|
}
|