find-package (findByName): replaced /usr/bin/which with custom shell code
This is to address a few problems: 1) When checking RPM_BUILD_ROOT, st_mode test performed by /usr/bin/which is not quite reliable. Files can be packaged with different %attr mode. 2) When checking RPM_BUILD_ROOT, there could be symbolic links there which are (not-so-) broken. 3) When checking host system, files like /sbin/init (which is 0700) are effectively bypassed by /usr/bin/which. 4) There's an ongoing practice of placing shell function libraries under /usr/bin, e.g. /usr/bin/git-sh-setup. These files are sourced from within shell scripts and need not be executable at all. This leads me to the point that permission check, which is performed by /usr/bin/which, is not needed at all. Note that things are getting more like contents_index_bin search. And for RPM_BUILD_ROOT, we do not even require strong stat-wise file existence. I like this new term: "strong stat-wise file existence". It's awesome.
This commit is contained in:
parent
3925c4c392
commit
d74f8d9a69
@ -175,10 +175,17 @@ FindByName()
|
||||
|
||||
# Check buildroot first.
|
||||
if [ -n "${RPM_BUILD_ROOT-}" ]; then
|
||||
local RPATH
|
||||
RPATH="$(printf %s "$findpackage_path" |sed -e "s|[^:]\+|$RPM_BUILD_ROOT&|g")"
|
||||
if rep="$(PATH="$RPATH" /usr/bin/which -- "$r" 2>/dev/null)"; then
|
||||
$Verbose "$f: $r -> \$RPM_BUILD_ROOT${rep#$RPM_BUILD_ROOT} (skip)"
|
||||
rep=$(IFS="$IFS:"; set -f
|
||||
for dir in $findpackage_path; do
|
||||
rep="$dir/$r"
|
||||
BR_rep="$RPM_BUILD_ROOT/$rep"
|
||||
if [ -f "$BR_rep" -o -L "$BR_rep" ]; then
|
||||
printf '%s\n' "$rep"
|
||||
break
|
||||
fi
|
||||
done)
|
||||
if [ -n "$rep" ]; then
|
||||
$Verbose "$f: $r -> \$RPM_BUILD_ROOT$rep (skip)"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
@ -262,29 +269,35 @@ FindByName()
|
||||
# In this case, we perfer to put aside the conflict for a while, and query
|
||||
# the host system first. There's a good chance that the right package, either
|
||||
# arpsend or vzctl, IS installed, and other unrelated packages are NOT installed.
|
||||
# However, if /usr/bin/which cannot find any candidate, we have to produce the
|
||||
# dependency on /usr/bin/arpsend -> arpsend.
|
||||
# However, if the host system does not provide any candidate, we have to produce
|
||||
# the dependency on /usr/bin/arpsend -> arpsend.
|
||||
save_rep="$rep" save_package="$package"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Lookup in the host system.
|
||||
if rep="$(PATH="$findpackage_path" /usr/bin/which --all -- "$r" 2>/dev/null)"; then
|
||||
rep=$(IFS="$IFS:"; set -f
|
||||
for dir in $findpackage_path; do
|
||||
rep="$dir/$r"
|
||||
if [ -f "$rep" ]; then
|
||||
printf '%s\n' "$rep"
|
||||
fi
|
||||
done)
|
||||
if [ -n "$rep" ]; then
|
||||
local n="$(IFS=$'\n'; set -- $rep; echo $#)"
|
||||
if [ "$n" -gt 1 ]; then
|
||||
# If '/usr/bin/which --all' yields a few paths,
|
||||
# e.g. '/usr/bin/which --all awk' -> {/bin/awk,/usr/bin/awk},
|
||||
# We've got a few paths, e.g. awk -> {/bin/awk,/usr/bin/awk};
|
||||
# we check if all paths really point to the same file.
|
||||
n="$(IFS=$'\n'; for f in $rep; do readlink -vm "$f"; done |sort -u |wc -l)"
|
||||
if [ "$n" -gt 1 ]; then
|
||||
local Verbose=Info
|
||||
Info "$f: which $r:$(echo '' $rep)"
|
||||
Info "$f: host_env $r:$(echo '' $rep)"
|
||||
fi
|
||||
# But we select the first path, which is the best, anyway.
|
||||
rep="$(IFS=$'\n'; set -- $rep; printf %s "$1")"
|
||||
fi
|
||||
if [ -n "$rep" ]; then
|
||||
$Verbose "$f: $r -> $rep -> ... (via which)"
|
||||
$Verbose "$f: $r -> $rep -> ... (via host_env)"
|
||||
FindByPath "$f" "$rep"
|
||||
return
|
||||
fi
|
||||
|
Loading…
x
Reference in New Issue
Block a user