2007-03-05 01:15:05 +03:00
#!/bin/sh -efu
2002-03-25 23:37:46 +03:00
#
2003-04-22 19:11:52 +04:00
# Copyright (C) 2002-2003 Dmitry V. Levin <ldv@altlinux.org>
2007-03-08 16:49:21 +03:00
# Copyright (C) 2007 Alexey Tourbin <at@altlinux.org>
2002-03-25 23:37:46 +03:00
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
2003-11-09 19:47:45 +03:00
. @RPMCONFIGDIR@/functions
2002-03-25 23:37:46 +03:00
2007-03-08 21:54:08 +03:00
RPM_FINDPACKAGE_PATH="${RPM_FINDPACKAGE_PATH-}:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin"
RPM_FINDPACKAGE_PATH="$(IFS="$IFS:"; set -f; echo '' $RPM_FINDPACKAGE_PATH |sed -e 's/ */:/g; s/^://')"
Debug "RPM_FINDPACKAGE_PATH=$RPM_FINDPACKAGE_PATH"
2007-08-07 21:04:23 +04:00
# Below we use 'local Verbose=Info' to increase per-case verbosity.
Verbose=Verbose
2007-03-08 15:20:02 +03:00
FindByPath()
2002-03-25 23:37:46 +03:00
{
2007-03-08 15:20:02 +03:00
# Dependence name starts with `/'.
local f="$1" rep="$2" package; shift 2 || return
2002-03-25 23:37:46 +03:00
2007-03-08 15:20:02 +03:00
# Does it start with buildroot?
if [ -n "${RPM_BUILD_ROOT-}" ] && [ -z "${rep##$RPM_BUILD_ROOT*}" ]; then
Info "$f: invalid dependence: $rep"
return 1
fi
2003-04-22 19:11:52 +04:00
2007-03-08 15:20:02 +03:00
# Does it belong to buildroot?
if [ -n "${RPM_BUILD_ROOT-}" ] && [ -e "$RPM_BUILD_ROOT$rep" ]; then
2007-08-07 21:04:23 +04:00
$Verbose "$f: $rep -> \$RPM_BUILD_ROOT$rep (skip)"
2007-03-08 15:20:02 +03:00
return
fi
2003-04-22 19:11:52 +04:00
2007-03-08 15:20:02 +03:00
# Is it an alternative?
if readlink "$rep" |grep -qs '^/etc/alternatives/'; then
2007-08-07 21:04:23 +04:00
$Verbose "$f: $rep -> $rep (alternative)"
2007-03-08 15:20:02 +03:00
printf %s\\n "$rep"
return
fi
2003-04-22 19:11:52 +04:00
find-package (FindByPath): enhanced contents_index search
In FindByPath, we should always check contents_index_bin first.
It is not quite expensive, and we make no assumptions which path
entries it may contain (our contents_index_bin, in addition
to standard *bin/ paths, also has /etc entries).
However, if contents_index_bin lookup fails, we may or may
not want to proceed with very expensive contents_index_all
search. We assume that, if contents_index_bin lookup actually
has take place for some standard *bin/ path, then there is simply
no need to proceed with contents_index_all.
Now we also assume that contents_index_all file can be possibly
gzipped (I use "gzip -cdfq" for "zcat or cat", found in zgrep).
Also increased verbosity (Verbose to Info) for contents_index_all
messages, since it is expensive and it is a means of "last resort"
to finding something strange before giving up, which is quite worth
to note about.
Also increased verbosity for "raw, not found" dependencies,
since they are likely to become unmet.
2007-08-07 17:32:46 +04:00
# Always try package binary index.
local idx_bin="${RPM_PKG_CONTENTS_INDEX_BIN-}" try_idx_bin=1
[ -n "$idx_bin" ] && [ -s "$idx_bin" ] && [ -r "$idx_bin" ] || try_idx_bin=
if [ -n "$try_idx_bin" ]; then
package="$(awk -v "f=$rep" '($1 == f) {print $2}' "$idx_bin" |sort -u)"
2007-03-08 16:49:21 +03:00
local n="$(IFS=$'\n'; set -- $package; echo $#)"
if [ "$n" = 1 ]; then
2007-08-07 21:04:23 +04:00
$Verbose "$f: $rep -> $package (via contents_index_bin)"
2007-03-08 15:20:02 +03:00
printf %s\\n "$package"
return
2007-03-08 16:49:21 +03:00
elif [ "$n" -gt 1 ]; then
Info "$f: $rep indexed by:$(echo '' $package)"
2007-08-07 21:04:23 +04:00
Info "$f: $rep -> $rep (raw, ambiguous, via contents_index_bin)"
2007-03-08 16:49:21 +03:00
printf %s\\n "$rep"
2007-03-08 15:20:02 +03:00
return
fi
find-package (FindByPath): enhanced contents_index search
In FindByPath, we should always check contents_index_bin first.
It is not quite expensive, and we make no assumptions which path
entries it may contain (our contents_index_bin, in addition
to standard *bin/ paths, also has /etc entries).
However, if contents_index_bin lookup fails, we may or may
not want to proceed with very expensive contents_index_all
search. We assume that, if contents_index_bin lookup actually
has take place for some standard *bin/ path, then there is simply
no need to proceed with contents_index_all.
Now we also assume that contents_index_all file can be possibly
gzipped (I use "gzip -cdfq" for "zcat or cat", found in zgrep).
Also increased verbosity (Verbose to Info) for contents_index_all
messages, since it is expensive and it is a means of "last resort"
to finding something strange before giving up, which is quite worth
to note about.
Also increased verbosity for "raw, not found" dependencies,
since they are likely to become unmet.
2007-08-07 17:32:46 +04:00
fi
# Maybe try pkg complete index.
local idx_all="${RPM_PKG_CONTENTS_INDEX_ALL-}" try_idx_all=1
[ -n "$idx_all" ] && [ -s "$idx_all" ] && [ -r "$idx_all" ] || try_idx_all=
case "$try_idx_bin$rep" in
1/bin/* | 1/sbin/* | 1/usr/bin/* | 1/usr/sbin/* )
# Binary index already checked for standard *bin/* entries.
# No need to check complete index.
try_idx_all=
esac
if [ -n "$try_idx_all" ]; then
# Checking complete index is expensive.
2007-08-07 21:04:23 +04:00
local Verbose=Info
find-package (FindByPath): enhanced contents_index search
In FindByPath, we should always check contents_index_bin first.
It is not quite expensive, and we make no assumptions which path
entries it may contain (our contents_index_bin, in addition
to standard *bin/ paths, also has /etc entries).
However, if contents_index_bin lookup fails, we may or may
not want to proceed with very expensive contents_index_all
search. We assume that, if contents_index_bin lookup actually
has take place for some standard *bin/ path, then there is simply
no need to proceed with contents_index_all.
Now we also assume that contents_index_all file can be possibly
gzipped (I use "gzip -cdfq" for "zcat or cat", found in zgrep).
Also increased verbosity (Verbose to Info) for contents_index_all
messages, since it is expensive and it is a means of "last resort"
to finding something strange before giving up, which is quite worth
to note about.
Also increased verbosity for "raw, not found" dependencies,
since they are likely to become unmet.
2007-08-07 17:32:46 +04:00
Info "$f: checking contents_index_all for $rep"
# Complete package index is possibly gzipped.
package="$(gzip -cdfq "$idx_all" |awk -v "f=$rep" '($1 == f) {print $2}' |sort -u)"
local n="$(IFS=$'\n'; set -- $package; echo $#)"
if [ "$n" = 1 ]; then
Info "$f: $rep -> $package (via contents_index_all)"
printf %s\\n "$package"
return
elif [ "$n" -gt 1 ]; then
Info "$f: $rep indexed by:$(echo '' $package)"
Info "$f: $rep -> $rep (raw, ambiguous, via contents_index_all)"
printf %s\\n "$rep"
return
fi
fi
2003-04-22 19:11:52 +04:00
2007-03-08 15:20:02 +03:00
# Check package database.
if package="$(rpmquery --whatprovides --queryformat='%{NAME}\n' -- "$rep")"; then
package="$(printf %s "$package" |LC_COLLATE=C sort -u)"
local n="$(IFS=$'\n'; set -- $package; echo $#)"
if [ "$n" = 1 ]; then
2007-08-07 21:04:23 +04:00
$Verbose "$f: $rep -> $package (via rpmdb)"
2007-03-08 15:20:02 +03:00
printf %s\\n "$package"
return
elif [ "$n" -gt 1 ]; then
Info "$f: $rep provided by:$(echo '' $package)"
2007-08-07 21:04:23 +04:00
Info "$f: $rep -> $rep (raw, ambiguous, via rpmdb)"
2007-03-08 16:49:21 +03:00
printf %s\\n "$rep"
return
2007-03-08 15:20:02 +03:00
fi
fi
2003-04-22 19:11:52 +04:00
2007-03-08 15:20:02 +03:00
# Not found; output raw dependence.
find-package (FindByPath): enhanced contents_index search
In FindByPath, we should always check contents_index_bin first.
It is not quite expensive, and we make no assumptions which path
entries it may contain (our contents_index_bin, in addition
to standard *bin/ paths, also has /etc entries).
However, if contents_index_bin lookup fails, we may or may
not want to proceed with very expensive contents_index_all
search. We assume that, if contents_index_bin lookup actually
has take place for some standard *bin/ path, then there is simply
no need to proceed with contents_index_all.
Now we also assume that contents_index_all file can be possibly
gzipped (I use "gzip -cdfq" for "zcat or cat", found in zgrep).
Also increased verbosity (Verbose to Info) for contents_index_all
messages, since it is expensive and it is a means of "last resort"
to finding something strange before giving up, which is quite worth
to note about.
Also increased verbosity for "raw, not found" dependencies,
since they are likely to become unmet.
2007-08-07 17:32:46 +04:00
Info "$f: $rep -> $rep (raw, not found)"
2007-03-08 15:20:02 +03:00
printf %s\\n "$rep"
}
2003-04-22 19:11:52 +04:00
2007-03-08 15:20:02 +03:00
FindByName()
{
local f="$1" r="$2" rep package; shift 2 || return
2003-04-22 19:11:52 +04:00
2007-03-08 15:20:02 +03:00
# Check buildroot first.
if [ -n "${RPM_BUILD_ROOT-}" ]; then
local RPATH
2007-03-08 21:54:08 +03:00
RPATH="$(printf %s "$RPM_FINDPACKAGE_PATH" |sed -e "s|[^:]\+|$RPM_BUILD_ROOT&|g")"
2007-03-08 15:20:02 +03:00
if rep="$(PATH="$RPATH" /usr/bin/which -- "$r" 2>/dev/null)"; then
2007-08-07 21:04:23 +04:00
$Verbose "$f: $r -> \$RPM_BUILD_ROOT${rep#$RPM_BUILD_ROOT} (skip)"
2007-03-08 15:20:02 +03:00
return
fi
fi
2003-04-22 19:11:52 +04:00
2007-03-08 15:20:02 +03:00
# Check for pkg contents binary index.
2007-03-08 23:31:55 +03:00
rep= package=
2007-03-08 15:20:02 +03:00
if [ -n "${RPM_PKG_CONTENTS_INDEX_BIN-}" ] && [ -s "$RPM_PKG_CONTENTS_INDEX_BIN" ] && [ -r "$RPM_PKG_CONTENTS_INDEX_BIN" ]; then
2007-03-08 21:54:08 +03:00
local out="$(awk -v r="$r" -v RPM_FINDPACKAGE_PATH="$RPM_FINDPACKAGE_PATH" '
BEGIN {
n = split(RPM_FINDPACKAGE_PATH, ary, ":")
for (i = 1; i <= n; i++) {
dir = ary[i]
sub("/+$", "", dir)
2007-03-11 23:40:37 +03:00
file = dir "/" r
if (dir && !(file in FILES))
FILES[file] = i
2007-03-08 21:54:08 +03:00
}
}
2007-03-11 23:40:37 +03:00
NF==2 && ($1 in FILES) {
print FILES[$1] "\t" $1 "\t" $2
2007-03-08 21:54:08 +03:00
}
' "$RPM_PKG_CONTENTS_INDEX_BIN" |
sort -n |sort -u -k3 |sort -n |cut -f2-)"
2007-03-08 18:26:28 +03:00
local n="$(IFS=$'\n'; set -- $out; echo $#)"
if [ "$n" = 1 ]; then
rep="$(IFS=$'\t\n'; set -- $out; printf %s "$1")"
package="$(IFS=$'\t\n'; set -- $out; printf %s "$2")"
2007-08-07 21:04:23 +04:00
$Verbose "$r -> $rep -> $package (via contents_index_bin)"
2007-03-08 18:26:28 +03:00
printf %s\\n "$package"
return
elif [ "$n" -gt 1 ]; then
2007-08-07 21:04:23 +04:00
local Verbose=Info
2007-03-08 18:26:28 +03:00
Info "$f: $r indexed by:$(printf %s "$out" |sed -e 's/\t/ -> /; s/$/,/; $s/,$//' |xargs echo '')"
rep="$(IFS=$'\t\n'; set -- $out; printf %s "$1")"
package="$(IFS=$'\t\n'; set -- $out; printf %s "$2")"
local rep2="$(IFS=$'\t\n'; set -- $out; printf %s "$3")"
if [ "$rep" = "$rep2" ]; then
2007-08-07 21:04:23 +04:00
Info "$f: $r -> $rep -> $rep (raw, ambiguous, via contents_index_bin)"
2007-03-08 18:26:28 +03:00
printf %s\\n "$rep"
return
2002-03-25 23:37:46 +03:00
fi
2007-03-08 18:26:28 +03:00
fi
2007-03-08 15:20:02 +03:00
fi
2007-03-08 16:18:41 +03:00
# Lookup in the host system.
2007-03-08 23:31:55 +03:00
local irep="$rep"
2007-03-08 21:54:08 +03:00
if rep="$(PATH="$RPM_FINDPACKAGE_PATH" /usr/bin/which --all -- "$r" 2>/dev/null)"; then
2007-03-08 16:18:41 +03:00
local n="$(IFS=$'\n'; set -- $rep; echo $#)"
if [ "$n" -gt 1 ]; then
n="$(IFS=$'\n'; for f in $rep; do readlink -vm "$f"; done |sort -u |wc -l)"
2007-08-07 21:04:23 +04:00
if [ "$n" -gt 1 ]; then
local Verbose=Info
Info "$f: which $r:$(echo '' $rep)"
fi
2007-03-08 16:18:41 +03:00
rep="$(IFS=$'\n'; set -- $rep; printf %s "$1")"
fi
if [ -n "$rep" ]; then
2007-08-07 21:04:23 +04:00
$Verbose "$f: $r -> $rep -> ... (via which)"
2007-03-08 16:18:41 +03:00
FindByPath "$f" "$rep"
2007-03-08 15:20:02 +03:00
return
fi
fi
2007-03-08 23:31:55 +03:00
# Reconsult pkg contents binary index.
if [ -n "$irep" ] && [ -n "$package" ]; then
rep="$irep"
2007-08-07 21:04:23 +04:00
$Verbose "$f: $r -> $rep -> $package (via contents_index_bin)"
2007-03-08 23:31:55 +03:00
printf %s\\n "$package"
return
fi
2007-03-08 15:20:02 +03:00
# Not found.
2007-08-07 21:04:23 +04:00
Info "$f: $r not found (skip)"
2007-03-08 15:20:02 +03:00
}
2007-03-06 21:08:06 +03:00
2007-03-08 15:20:02 +03:00
FindPackage()
{
local f="$1" r; shift || return
for r; do
2007-08-07 21:04:23 +04:00
local Verbose=Verbose
2007-08-07 20:41:04 +04:00
case "$r" in
/*)
FindByPath "$f" "$r" ;;
*/*)
Info "$f: invalid pathname $r" ;;
-*)
Info "$f: invalid command $r" ;;
'')
;;
*)
FindByName "$f" "$r" ;;
esac
2002-03-25 23:37:46 +03:00
done
}