pkgsrc/pkgtools/pkg_chk/files/pkg_chk.sh

1052 lines
25 KiB
Bash
Executable file

#!@SH@ -e
#
# $Id: pkg_chk.sh,v 1.73 2014/04/23 00:01:01 abs Exp $
#
# TODO: Make -g check dependencies and tsort
# TODO: Make -g list user-installed packages first, followed by commented
# out automatically installed packages
# TODO: List user-installed packages that are not in config
# Copyright (c) 2001-2012 David Brownlee (Standard 2 clause BSD licence)
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
PATH=${PATH}:/usr/sbin:/usr/bin
SUMMARY_FILES="pkg_summary.bz2 pkg_summary.gz pkg_summary.txt"
bin_pkg_info2pkgdb()
{
# PKGDB is a newline separated list "pkgdir: pkgnamever[ pkgnamever ..] "
# For each PKGPATH return a set of valid package versions
${AWK} -F= '
$1=="PKGNAME"{pkgname=$2}
$1=="PKGPATH"{pkgpath=$2}
NF==0 {
if (pkgpath && pkgname)
pkgs[pkgpath]=pkgs[pkgpath]" "pkgname;
pkgpath="";
pkgname=""
}
END {
if (pkgpath && pkgname) pkgs[pkgpath]=pkgname;
for (pkg in pkgs) { print pkg ":" pkgs[pkg] " "; }
}
'
}
check_packages_installed()
{
MISSING_TODO=
MISMATCH_TODO=
for pkgdir in $* ; do
if [ -n "$opt_B" ];then
extract_pkg_vars $pkgdir PKGNAME FILESDIR PKGDIR DISTINFO_FILE PATCHDIR
elif [ -n "$opt_s" ] ; then
extract_pkg_vars $pkgdir PKGNAME
else
PKGNAME=
PKGNAMES="$(pkgdir2pkgnames $pkgdir)"
case "$PKGNAMES" in
# multiple packages - determine which (if any) is installed
*' '* )
# Sort so highest matching package picked first
PKGNAMES="$(echo $PKGNAMES | tr ' ' '\n' | ${SORT} -r)"
for pkgname in $PKGNAMES ; do
if [ -d $PKG_DBDIR/$pkgname ];then
PKGNAME=$pkgname
break;
fi
done
# In the absence of any better way to determine which
# should be picked, use the highest version
if [ -z "$PKGNAME" ] ; then
PKGNAME=$(echo $PKGNAMES | ${SED} 's/ .*//')
fi
;;
* ) PKGNAME=$PKGNAMES ;;
esac
fi
if [ -z "$PKGNAME" ]; then
MISSING_DONE=$MISSING_DONE" "$pkgdir
continue
fi
if [ -d "$PKG_DBDIR/$PKGNAME" ];then
if [ -n "$opt_B" ];then
# sort here temporarily to handle older +BUILD_VERSION
current_build_ver=$(get_build_ver | ${SED} 's|.*\$Net''BSD\: ||' | ${SORT} -u)
installed_build_ver=$(${SED} 's|.*\$Net''BSD\: ||' $PKG_DBDIR/$PKGNAME/+BUILD_VERSION | ${SORT} -u)
if [ x"$current_build_ver" != x"$installed_build_ver" ];then
msg "$pkgdir - $PKGNAME build_version mismatch"
verbose "--current--"
verbose "$current_build_ver"
verbose "--installed--"
verbose "$installed_build_ver"
verbose "----"
MISMATCH_TODO="$MISMATCH_TODO $PKGNAME"
else
verbose "$pkgdir - $PKGNAME OK"
fi
else
verbose "$pkgdir - $PKGNAME OK"
fi
else
# XXX need to handle multiple matching package case
msg_n "$pkgdir - "
pkg=$(echo $PKGNAME | ${SED} 's/-[0-9].*//')
pkginstalled=$(sh -c "${PKG_INFO} -e $pkg" || true)
if [ -z "$pkginstalled" ];then
msg_n "$PKGNAME missing"
MISSING_TODO="$MISSING_TODO $PKGNAME $pkgdir"
else
pkgmatch=$(echo $PKGNAME | ${SED} 's/-\([0-9].*\)/>=\1/')
if ! ${PKG_ADMIN} pmatch "$pkgmatch" "$pkginstalled" ; then
INSTALL=
if [ -n "$pkginstalled" ];then
msg_n "$pkginstalled < $PKGNAME"
MISMATCH_TODO="$MISMATCH_TODO $pkginstalled"
else
msg_n "missing $PKGNAME"
MISSING_TODO="$MISSING_TODO $PKGNAME $pkgdir"
fi
else
if [ -n "$opt_B" ];then
msg_n "$pkginstalled > $PKGNAME"
MISMATCH_TODO="$MISMATCH_TODO $pkginstalled"
else
msg_n "$pkginstalled > $PKGNAME - ignoring"
fi
fi
fi
if is_binary_available $PKGNAME ;then
msg_n " (has binary package)"
fi
msg
fi
done
}
cleanup_and_exit()
{
rm -f $MY_TMPFILE
rmdir $MY_TMPDIR
exit "$@"
}
delete_pkgs()
{
for pkg in $* ; do
if [ -d $PKG_DBDIR/$pkg ] ; then
run_cmd_su "${PKG_DELETE} -r $pkg" 1
fi
done
}
extract_make_vars()
{
MAKEFILE=$1
shift
MAKEDATA=".PHONY: x\nx:\n";
for var in $* ; do
MAKEDATA=$MAKEDATA"\t@echo $var=\${$var}\n"
done
eval $(printf "$MAKEDATA" | ${MAKE} -f - -f $MAKEFILE x | \
${SED} -e 's/[^=]*=/&"/' -e 's/$/"/')
for var in $* ; do
verbose_var $var
done
}
# $1 = name of variable
# $2 = default value
extract_mk_var()
{
if [ -z "`eval echo \\$$1`" ] ; then
eval $(printf "BSD_PKG_MK=1\n.PHONY: x\nx:\n\t@echo $1="'$'"{$1}\n" | ${MAKE} -f - -f $MAKECONF x)
if [ -z "`eval echo \\$$1`" ]; then
eval "$1=$2"
verbose_var $1 '(using default)'
else
verbose_var $1
fi
fi
}
extract_pkg_vars()
{
PKGDIR=$1
PKGNAME=
shift;
if [ ! -f $PKGSRCDIR/$pkgdir/Makefile ];then
msg "WARNING: No $pkgdir/Makefile - package moved or obsolete?"
return
fi
cd $PKGSRCDIR/$PKGDIR
extract_make_vars Makefile "$@"
if [ -z "$PKGNAME" ]; then
fatal "Unable to extract PKGNAME for $pkgdir"
fi
}
extract_variables()
{
extract_mk_var PKGSRCDIR ''
extract_mk_var LOCALBASE ''
if [ -z "$PKGSRCDIR" ] ; then
for dir in $LOCALBASE/pkgsrc /usr/pkgsrc . .. ../.. ; do
if [ -f "${dir}/mk/bsd.pkg.mk" ]; then
case "${dir}" in
/*) PKGSRCDIR="${dir}" ;;
*) PKGSRCDIR="$( cd "${dir}" >/dev/null 2>&1 && pwd )" ;;
esac
break
fi
done
fi
if [ -z "$opt_g" ]; then
# Now we have PKGSRCDIR, use it to determine PACKAGES, and PKGCHK_CONF
# as well as AWK, GREP, SED, PKGCHK_TAGS and PKGCHK_NOTAGS
#
if [ ! -d "$PKGSRCDIR" -a \( -z "$opt_b" -o -n "$opt_s" \) ] ; then
fatal "Unable to locate PKGSRCDIR (${PKGSRCDIR:-not set})"
fi
if [ -z "$opt_b" -o -n "$opt_s" -o -d $PKGSRCDIR/pkgtools/pkg_chk ] ;
then
cd $PKGSRCDIR/pkgtools/pkg_chk
extract_make_vars Makefile \
AWK GREP GZCAT GZIP_CMD ID PACKAGES PKGCHK_CONF PKGCHK_NOTAGS \
PKGCHK_TAGS PKGCHK_UPDATE_CONF PKG_ADD PKG_DBDIR \
PKG_DELETE PKG_ADMIN PKG_INFO PKG_SUFX SED SORT SU_CMD TSORT
if [ -z "$PACKAGES" ];then
PACKAGES=$PKGSRCDIR/packages
fi
elif [ $MAKECONF != /dev/null ] ; then
extract_make_vars $MAKECONF PACKAGES PKGCHK_CONF \
PKGCHK_UPDATE_CONF PKGCHK_TAGS PKGCHK_NOTAGS PKG_SUFX
if [ -z "$PACKAGES" ] ; then
PACKAGES="$(pwd)"
fi
fi
fi
# .tgz/.tbz to regexp
PKG_SUFX_RE="$(echo $PKG_SUFX | ${SED} 's/[.]/[.]/')"
if [ ! -d $PKG_DBDIR ] ; then
fatal "Unable to access PKG_DBDIR ($PKG_DBDIR)"
fi
if [ -z "$PKGCHK_CONF" ];then
# Check $PKG_SYSCONFDIR then fall back to $PKGSRCDIR
if [ -f $PKG_SYSCONFDIR/pkgchk.conf ] ; then
PKGCHK_CONF=$PKG_SYSCONFDIR/pkgchk.conf
else
PKGCHK_CONF=$PKGSRCDIR/pkgchk.conf
fi
fi
if [ -z "$PKGCHK_UPDATE_CONF" ];then
PKGCHK_UPDATE_CONF=$PKGSRCDIR/pkgchk_update-$(hostname).conf
fi
}
fatal()
{
msg "** $@" >&2
cleanup_and_exit 1
}
fatal_later()
{
msg "** $@" >&2
fatal_later=1
}
fatal_later_check()
{
if [ "$fatal_later" = 1 ] ; then
cleanup_and_exit 1
fi
}
fatal_maybe()
{
if [ -z "$opt_k" ];then
fatal "$@"
else
msg "$@"
fi
}
generate_conf_from_installed()
{
FILE=$1
if [ -r $FILE ]; then
mv $FILE ${FILE}.old
fi
echo "# Generated automatically at $(date)" > $FILE
echo $(pkgdirs_from_installed) | tr ' ' '\n' >> $FILE
}
get_bin_pkg_info()
{
for summary_file in $SUMMARY_FILES ; do
if [ -f $PACKAGES/$summary_file ] ; then
if [ -z "$(find $PACKAGES -type f -newer $PACKAGES/$summary_file -name '*.tgz')" ] ; then
verbose "Using summary file: $summary_file"
uncompress_filter $summary_file < $PACKAGES/$summary_file
return;
fi
msg "** Ignoring $summary_file as newer pkgs in $PACKAGES"
fi
done
msg_progress Scan $PACKAGES
list_bin_pkgs | ${XARGS} ${PKG_INFO} -X
}
get_build_ver()
{
if [ -n "$opt_b" -a -z "$opt_s" ] ; then
${PKG_INFO} -q -b $PACKAGES/$PKGNAME$PKG_SUFX | ${GREP} .
return
fi
# Unfortunately pkgsrc always outputs to a file, but it does
# helpfully allows us to specify the name
rm -f $MY_TMPFILE
${MAKE} _BUILD_VERSION_FILE=$MY_TMPFILE $MY_TMPFILE
cat $MY_TMPFILE
}
is_binary_available()
{
if [ -n "$PKGDB" ]; then
case "$PKGDB" in
*" $1 "*) return 0;;
esac
return 1
else
if [ -f "$PACKAGES/$1$PKG_SUFX" ]; then
return 0
else
return 1
fi
fi
}
list_bin_pkgs ()
{
# XXX ls -t is usually enough to get newer packages first, but it
# depends on how files appeared in the $PACKAGES - beware
ls -t $PACKAGES | grep "$PKG_SUFX_RE"'$' | ${SED} "s|^|$PACKAGES/|"
}
# Given a binary package filename as the first argumennt, return a list
# of exact package versions against which it was built and on which it
# depends
#
list_dependencies()
{
${PKG_INFO} -q -n $1 | ${GREP} .. || true
}
# Pass a list of pkgdirs, outputs a tsorted list including any dependencies
#
list_packages()
{
# Convert passed in list of pkgdirs to a list of binary package files
pkglist=''
for pkgdir in $* ; do
pkgname="$(pkgdir2pkgnames $pkgdir| ${SED} 's/ .*//')"
if [ -z "$pkgname" ]; then
fatal_later "$pkgdir - Unable to extract pkgname"
continue
fi
if is_binary_available "$pkgname" ; then
pkglist="$pkglist $pkgname$PKG_SUFX"
else
fatal_later "$pkgname - no binary package found"
fi
done
# Variables used in this loop:
# pkglist: Current list of binary package files to check for dependencies
# next_pkglist: List of binary package files to check after pkglist
# pairlist: completed list of package + dependency for use in tsort
while [ -n "$pkglist" ] ; do
verbose "pkglist: $pkglist"
for pkg in $pkglist ; do
set -o noglob
deplist="$(list_dependencies $PACKAGES/$pkg)"
verbose "$pkg: dependencies - `echo $deplist`"
if [ -n "$deplist" ] ; then
for depmatch in $deplist ; do
dep=`${PKG_ADMIN} -b -d $PACKAGES lsbest "$depmatch"`
if [ -z "$dep" ] ; then
fatal_later "$depmatch: dependency missing for $pkg"
else
pairlist="$pairlist$dep $pkg\n"
case $dep_cache in
*" $dep "*)
# depmatch_cache is a quick cache of already
verbose "$pkg: $deplist - cached"
;;
*)
next_pkglist="$next_pkglist $dep"
dep_cache="$dep_cache $dep "
;;
esac
fi
done
else
pairlist="$pairlist$pkg $pkg\n"
fi
set +o noglob
done
pkglist="$next_pkglist"
next_pkglist=
done
if [ -z "$opt_k" ] ; then
fatal_later_check
fi
printf "$pairlist" | ${TSORT}
}
pkgdir2pkgnames()
{
pkgdir=$1
if [ -z "$pkgdir" ] ; then
fatal "blank pkgdir in pkgdir2pkgnames()"
fi
oIFS="$IFS"
IFS="
"
# PKGDB is a newline separated list "pkgdir: pkgnamever[ pkgnamever ..] "
for pkgline in $PKGDB ; do
case "$pkgline" in
"$pkgdir:"*)
echo $pkgline | ${SED} -e 's/[^:]*: //' -e 's/ $//'
break;
;;
esac
done
IFS="$oIFS"
}
# Redefines opt_D and opt_U to full list of defined and unset tags
#
determine_tags()
{
# Determine list of tags
#
if [ "$PKGSRCDIR" = NONE ]; then
OPSYS=$(uname -s)
OS_VERSION=$(uname -r)
MACHINE_ARCH=$(uname -p)
else
extract_make_vars Makefile OPSYS OS_VERSION MACHINE_ARCH
fi
TAGS="$(hostname | ${SED} -e 's,\..*,,'),$(hostname),$OPSYS-$OS_VERSION-$MACHINE_ARCH,$OPSYS-$OS_VERSION,$OPSYS-$MACHINE_ARCH,$OPSYS,$OS_VERSION,$MACHINE_ARCH"
if [ -f /usr/X11R7/lib/libX11.a -o -f /usr/X11R6/lib/libX11.a ];then
TAGS="$TAGS,x11"
fi
if [ -n "$PKGCHK_TAGS" ];then
TAGS="$TAGS,$PKGCHK_TAGS"
fi
if [ -n "$PKGCHK_NOTAGS" ];then
if [ -n "$opt_U" ];then
opt_U="$opt_U,$PKGCHK_NOTAGS"
else
opt_U="$PKGCHK_NOTAGS"
fi
fi
# If '-U' contains a '*' then we need to unset TAGS and PKGCHK_TAGS, but
# still pick up -D, and even package specific -U options
verbose "unset TAGS=$opt_U"
case ",$opt_U," in
*,\*,*)
TAGS=''
;;
esac
if [ -n "$TAGS" ];then
if [ -n "$opt_D" ];then
opt_D="$opt_D,$TAGS"
else
opt_D="$TAGS"
fi
fi
verbose "set TAGS=$opt_D"
}
pkgdirs_from_conf()
{
CONF=$1; shift
LIST="$*"
if [ ! -r $CONF ];then
fatal "Unable to read PKGCHK_CONF '$CONF'"
fi
determine_tags
# Extract list of valid pkgdirs (skip any 'alreadyset' in $LIST)
#
verbose ${AWK} -v alreadyset="$LIST" -v set_tags="$opt_D" -v unset_tags="$opt_U"
LIST="$LIST "$(${AWK} -v alreadyset="$LIST" -v set_tags="$opt_D" -v unset_tags="$opt_U" '
BEGIN {
split(alreadyset, tmp, " ");
for (itag in tmp) {
skip[tmp[itag]] = 1;
}
split(set_tags, tmp, ",");
for (itag in tmp) {
if (tmp[itag] == "*") {
match_all_packages = 1;
}
taglist[tmp[itag]] = 1;
}
split(unset_tags, tmp, ",");
for (itag in tmp) {
skip[tmp[itag]] = 1;
nofile[tmp[itag]] = 1;
delete taglist[tmp[itag]];
}
taglist["*"] = "*"
}
function and_expr_with_dict(expr, dict, ary, i, r, d) {
split(expr,ary,/\+/);
r = 1;
for (i in ary) {
if (ary[i] ~ /^\// && ! nofile[ary[i]]) {
if (getline d < ary[i] == -1)
{ r = 0; break ;}
}
else if (! (ary[i] in dict))
{ r = 0; break ;}
}
return r;
}
{
sub("#.*", "");
if (skip[$1])
next;
need = 0;
if ($0 ~ /\=/) {
split($0, tmp, "[ \t]*=");
taggroup = tmp[1];
sub("[ \t]*=", "=");
}
else
{
taggroup = ""
if (match_all_packages || NF == 1) # If only one arg, we want pkg
{
print $1;
next;
}
}
for (f = 2 ; f<=NF ; ++f) { # For each word on the line
if (sub("^-", "", $f)) { # If it begins with a '-'
if (f == 2) # If first entry '-', assume '*'
{ need = 1; }
if (and_expr_with_dict($f, taglist))
next; # If it is true, discard
} else {
if (and_expr_with_dict($f, taglist))
need = 1; # If it is true, note needed
}
}
if (need)
if (taggroup)
taglist[taggroup] = 1
else
print $1;
}
' < $CONF
)
echo $LIST
}
pkgdirs_from_installed()
{
${PKG_INFO} -Bqa | ${AWK} -F= '/^PKGPATH=/{print $2}' | ${SORT}
}
msg()
{
if [ -n "$opt_L" ] ; then
echo "$@" >> "$opt_L"
fi
if [ -n "$opt_l" ] ; then
echo "$@" >&2
else
echo "$@"
fi
}
msg_progress()
{
if [ -z "$opt_q" ] ; then
msg "[ $@ ]"
fi
}
msg_n()
{
msg $ac_n "$*"$ac_c
}
pkg_fetch()
{
PKGNAME=$1
PKGDIR=$2
run_cmd "cd $PKGSRCDIR/$PKGDIR && ${MAKE} fetch-list | sh"
if [ -n "$FAIL" ]; then
FAILED_DONE=$FAILED_DONE" "$PKGNAME
else
FETCH_DONE=$FETCH_DONE" "$PKGNAME
fi
}
pkg_fetchlist()
{
PKGLIST=$@
msg_progress Fetch
while [ $# != 0 ]; do
pkg_fetch $1 $2
shift ; shift;
done
}
pkg_install()
{
PKGNAME=$1
PKGDIR=$2
INSTALL=$3
FAIL=
if [ -d $PKG_DBDIR/$PKGNAME ];then
msg "$PKGNAME installed in previous stage"
run_cmd_su "${PKG_ADMIN} unset automatic $PKGNAME"
elif [ -n "$opt_b" ] && is_binary_available $PKGNAME; then
if [ -n "$saved_PKG_PATH" ] ; then
export PKG_PATH=$saved_PKG_PATH
fi
run_cmd_su "${PKG_ADD} $PACKAGES/$PKGNAME$PKG_SUFX"
if [ -n "$saved_PKG_PATH" ] ; then
unset PKG_PATH
fi
elif [ -n "$opt_s" ]; then
run_cmd "cd $PKGSRCDIR/$PKGDIR && ${MAKE} update CLEANDEPENDS=yes"
fi
if [ -z "$opt_n" -a -z "$opt_q" -a ! -d $PKG_DBDIR/$PKGNAME ];then
FAIL=1
fi
if [ -n "$FAIL" ]; then
FAILED_DONE=$FAILED_DONE" "$PKGNAME
else
INSTALL_DONE=$INSTALL_DONE" "$PKGNAME
fi
}
pkg_installlist()
{
INSTALL=$1 ; shift
msg_progress $INSTALL
while [ $# != 0 ]; do
pkg_install $1 $2 $INSTALL
shift ; shift;
done
}
run_cmd()
{
FAIL=
if [ -n "$2" ]; then
FAILOK=$2
else
FAILOK=$opt_k
fi
if [ -z "$opt_q" ];then
msg $(date +%R) $1
fi
if [ -z "$opt_n" -a -z "$opt_q" ];then
if [ -n "$opt_L" ] ; then
sh -c "$1" >> "$opt_L" 2>&1 || FAIL=1
else
sh -c "$1" || FAIL=1
fi
if [ -n "$FAIL" ] ; then
msg "** '$1' failed"
if [ -n "$opt_L" ] ; then
tail -100 "$opt_L" | egrep -v '^(\*\*\* Error code 1|Stop\.)' |\
tail -40
fi
if [ "$FAILOK" != 1 ]; then
fatal "** '$1' failed"
fi
fi
fi
}
run_cmd_su()
{
if [ -n "$SU_CMD" ]; then
run_cmd "${SU_CMD} '$1'" "$2"
else
run_cmd "$1" "$2"
fi
}
uncompress_filter()
{
case "$1" in
*.gz) ${GZCAT} ;;
*.bz2) ${BZCAT} ;;
*) cat ;;
esac
}
set_path()
{
arg=$1
case $arg in
http://* | ftp://* | /*) echo $arg ;;
*) echo $basedir/$arg ;;
esac
}
usage()
{
if [ -n "$1" ] ; then
echo "$@"
echo
fi
echo 'Usage: pkg_chk [opts]
-a Add all missing packages
-B Force exact pkg match - check "Build version" & even downgrade
-b Use binary packages
-C conf Use pkgchk.conf file 'conf'
-D tags Comma separated list of additional pkgchk.conf tags to set
-f Perform a 'make fetch' for all required packages
-g Generate an initial pkgchk.conf file
-h This help
-k Continue with further packages if errors are encountered
-L file Redirect output from commands run into file (should be fullpath)
-l List binary packages including dependencies
-N List installed packages for which a newer version is in TODO
-n Display actions that would be taken, but do not perform them
-p Display the list of pkgdirs that match the current tags
-P dir Set PACKAGES dir (overrides any other setting)
-q Do not display actions or take any action; only list packages
-r Recursively remove mismatches (use with care)
-s Use source for building packages
-U tags Comma separated list of pkgchk.conf tags to unset ('*' for all)
-u Update all mismatched packages
-v Verbose
pkg_chk verifies installed packages against pkgsrc.
The most common usage is 'pkg_chk -u -q' to check all installed packages or
'pkg_chk -u' to update all out of date packages.
For more advanced usage, including defining a set of desired packages based
on hostname and type, see pkg_chk(8).
If neither -b nor -s is given, both are assumed with -b preferred.
'
exit 1
}
verbose()
{
if [ -n "$opt_v" ] ; then
msg "$@" >&2
fi
}
verbose_var()
{
if [ -n "$opt_v" ] ; then
var=$1
shift
verbose Variable: $var = $(eval echo \$$var) $@
fi
}
original_argv="$@" # just used for verbose output
while getopts BC:D:L:P:U:abcfghiklNnpqrsuv ch; do
case "$ch" in
a ) opt_a=1 ;;
B ) opt_B=1 ;;
b ) opt_b=1 ;;
C ) opt_C="$OPTARG" ;;
c ) opt_a=1 ; opt_q=1 ; echo "-c is deprecated - use -a -q" ;;
D ) opt_D="$OPTARG" ;;
f ) opt_f=1 ;;
g ) opt_g=1 ;;
h ) opt_h=1 ;;
i ) opt_u=1 ; opt_q=1 ; echo "-i is deprecated - use -u -q" ;;
k ) opt_k=1 ;;
L ) opt_L="$OPTARG" ;;
l ) opt_l=1 ;;
N ) opt_N=1 ;;
n ) opt_n=1 ;;
p ) opt_p=1 ;;
P ) opt_P="$OPTARG" ;;
q ) opt_q=1 ;;
r ) opt_r=1 ;;
s ) opt_s=1 ;;
U ) opt_U="$OPTARG" ;;
u ) opt_u=1 ;;
v ) opt_v=1 ;;
esac
done
shift $(($OPTIND - 1))
if [ -z "$opt_b" -a -z "$opt_s" ];then
opt_b=1; opt_s=1;
fi
if [ -z "$opt_a$opt_g$opt_l$opt_p$opt_r$opt_u$opt_N" ];then
usage "Must specify at least one of -a, -g, -l, -p, -r, -u or -N";
fi
if [ -n "$opt_h" ];then
usage
fi
if [ $# != 0 ];then
usage "Additional argument ($*) given"
fi
verbose "ARGV: $original_argv"
# Hide PKG_PATH to avoid breakage in 'make' calls
saved_PKG_PATH=$PKG_PATH
unset PKG_PATH || true
test -n "$AWK" || AWK="@AWK@"
test -n "$BZCAT" || BZCAT="@BZCAT@"
test -n "$GREP" || GREP="@GREP@"
test -n "$GZCAT" || GZCAT="@GZCAT@"
test -n "$GZIP_CMD" || GZIP_CMD="@GZIP_CMD@"
export GZIP_CMD
test -n "$ID" || ID="@ID@"
test -n "$MAKE" || MAKE="@MAKE@"
test -n "$MAKECONF" || MAKECONF="@MAKECONF@"
test -n "$MKTEMP" || MKTEMP="@MKTEMP@"
test -n "$PKG_ADD" || PKG_ADD="@PKG_ADD@"
test -n "$PKG_ADMIN" || PKG_ADMIN="@PKG_ADMIN@"
test -n "$PKG_DBDIR" || PKG_DBDIR="@PKG_DBDIR@"
test -n "$PKG_DELETE" || PKG_DELETE="@PKG_DELETE@"
test -n "$PKG_INFO" || PKG_INFO="@PKG_INFO@"
test -n "$SED" || SED="@SED@"
test -n "$SORT" || SORT="@SORT@"
test -n "$TSORT" || TSORT="@TSORT@"
test -n "$XARGS" || XARGS="@XARGS@"
test -n "$PKG_SYSCONFDIR" || PKG_SYSCONFDIR="@PKG_SYSCONFDIR@"
MY_TMPDIR=`${MKTEMP} -d ${TMPDIR-/tmp}/${0##*/}.XXXXXX`
test -n "$MY_TMPDIR" || fatal "Couldn't create temporary directory."
MY_TMPFILE=$MY_TMPDIR/tmp
if [ -z "$MAKECONF" ] ; then
for mkconf in "@MAKECONF@" "@PREFIX@/etc/mk.conf" /etc/mk.conf ; do
if [ -f "$mkconf" ] ; then
MAKECONF="$mkconf"
break
fi
done
fi
if [ -z "$MAKECONF" -o ! -f "$MAKECONF" ] ; then
MAKECONF=/dev/null
fi
verbose_var MAKECONF
# grabbed from GNU configure
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
# Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
if (echo -n testing; echo 1,2,3) | ${SED} s/-n/xn/ | grep xn >/dev/null; then
ac_n= ac_c='
' ac_t=' '
else
ac_n=-n ac_c= ac_t=
fi
else
ac_n= ac_c='\c' ac_t=
fi
if [ -n "$opt_L" ] ; then
printf '' > $opt_L
fi
basedir=$(pwd)
extract_variables
if [ -n "$opt_C" ] ; then
PKGCHK_CONF="$(set_path $opt_C)"
fi
if [ -n "$opt_P" ] ; then
PACKAGES="$(set_path $opt_P)"
fi
if [ -d $PACKAGES/All ] ; then
PACKAGES="$PACKAGES/All"
fi
if [ "`${ID} -u`" = 0 ] ; then
SU_CMD=
fi
if [ -n "$opt_N" ]; then
${PKG_INFO} | \
${SED} -e "s/[ ].*//" -e "s/-[^-]*$//" \
-e "s/py[0-9][0-9]pth-/py-/" \
-e "s/py[0-9][0-9]-/py-/" | \
while read a
do
b=$(grep "o $a-[0-9]" $PKGSRCDIR/doc/TODO | \
${SED} -e "s/[ ]*o //")
if [ "$b" ]
then
echo $a: $b
fi
done
fi
if [ -n "$opt_b" -a -z "$opt_s" ] ; then
case $PACKAGES in
http://*|ftp://*)
for summary_file in $SUMMARY_FILES ; do
verbose "parse pkg_summary $PACKAGES/$summary_file"
PKGDB="$(ftp -o - $PACKAGES/$summary_file \
| uncompress_filter $summary_file | bin_pkg_info2pkgdb)"
if [ -n "$PKGDB" ]; then
break
fi
done
;;
*)
if [ -d "$PACKAGES" ] ; then
PKGDB="$(get_bin_pkg_info | bin_pkg_info2pkgdb)"
PKGSRCDIR=NONE
fi
;;
esac
verbose "PKGDB entries: $(echo "$PKGDB"|wc -l)"
fi
if [ -n "$opt_g" ]; then
verbose "Write $PKGCHK_CONF based on installed packages"
generate_conf_from_installed $PKGCHK_CONF
cleanup_and_exit
fi
if [ -n "$opt_r" -o -n "$opt_u" ];then
verbose "Enumerate PKGDIRLIST from installed packages"
PKGDIRLIST=$(pkgdirs_from_installed)
fi
if [ -n "$opt_p" ] ; then
pkgdirs_from_conf $PKGCHK_CONF $PKGDIRLIST | tr ' ' '\n'
cleanup_and_exit
fi
if [ -n "$opt_a" -o -n "$opt_l" ];then # Append to PKGDIRLIST based on conf
verbose "Append to PKGDIRLIST based on config $PKGCHK_CONF"
PKGDIRLIST="$(pkgdirs_from_conf $PKGCHK_CONF $PKGDIRLIST)"
fi
if [ -n "$opt_l" ] ; then
list_packages $PKGDIRLIST
else
check_packages_installed $PKGDIRLIST
fi
if [ -n "$MISMATCH_TODO" ]; then
delete_and_recheck=1
elif [ -n "$opt_u" -a -f $PKGCHK_UPDATE_CONF ] ; then
delete_and_recheck=1
fi
if [ -n "$delete_and_recheck" ]; then
if [ -n "$opt_u" ] ; then # Save current installed list
if [ -f $PKGCHK_UPDATE_CONF ] ; then
msg "Merging in previous $PKGCHK_UPDATE_CONF"
if [ -z "$opt_n" -a -z "$opt_q" ] ; then
tmp=$(cat $PKGCHK_UPDATE_CONF)
echo $tmp $(pkgdirs_from_installed) | tr ' ' '\n' | ${SORT} -u \
> $PKGCHK_UPDATE_CONF
tmp=
fi
else
if [ -z "$opt_n" -a -z "$opt_q" ] ; then
echo $(pkgdirs_from_installed) | tr ' ' '\n' \
> $PKGCHK_UPDATE_CONF
fi
fi
fi
if [ -n "$opt_r" -o -n "$opt_u" ] ; then
if [ -n "$MISMATCH_TODO" ]; then
delete_pkgs $MISMATCH_TODO
msg_progress Rechecking packages after deletions
fi
if [ -n "$opt_u" ]; then
PKGDIRLIST="$(pkgdirs_from_conf $PKGCHK_UPDATE_CONF $PKGDIRLIST)"
fi
if [ -n "$opt_a" -o -n "$opt_u" ]; then
check_packages_installed $PKGDIRLIST # May need to add more
fi
fi
fi
if [ -n "$opt_f" ] ; then
pkg_fetchlist $MISSING_TODO
fi
if [ -n "$MISSING_TODO" ] ; then
if [ -n "$opt_a" -o -n "$opt_u" ] ; then
pkg_installlist Install $MISSING_TODO
fi
fi
if [ -n "$opt_u" -a -z "$FAILED_DONE" -a -f $PKGCHK_UPDATE_CONF ] ; then
run_cmd "rm -f $PKGCHK_UPDATE_CONF"
fi
[ -z "$MISSING_DONE" ] || msg "Missing:$MISSING_DONE"
[ -z "$INSTALL_DONE" ] || msg "Installed:$INSTALL_DONE"
if [ -n "$FAILED_DONE" ] ; then
msg "Failed:$FAILED_DONE"
cleanup_and_exit 1
fi
cleanup_and_exit