NetBSD/usr.sbin/pkg_install/view/pkg_view.sh

272 lines
7.8 KiB
Bash

#! /bin/sh
# $NetBSD: pkg_view.sh,v 1.4 2003/09/08 07:09:34 jlam Exp $
#
# Copyright (c) 2001 Alistair G. Crooks. 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.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by Alistair G. Crooks.
# 4. The name of the author may not be used to endorse or promote
# products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
# set -x
# set up program definitions
chmodprog=/bin/chmod
cmpprog=/usr/bin/cmp
cpprog=/bin/cp
envprog=/usr/bin/env
findprog=/usr/bin/find
grepprog=/usr/bin/grep
linkfarmprog=/usr/sbin/linkfarm
lnprog=/bin/ln
mkdirprog=/bin/mkdir
paxprog=/bin/pax
pkgadminprog=/usr/sbin/pkg_admin
pkginfoprog=/usr/sbin/pkg_info
rmprog=/bin/rm
rmdirprog=/bin/rmdir
sedprog=/usr/bin/sed
touchprog=/usr/bin/touch
usage() {
echo 'Usage: pkg_view [-n] [-v] [-i ignore] [-k pkg_dbdir_dflt] [-w viewname] [-d stowdir] [-W viewbase] add|check|delete pkgname...'
exit 1
}
version() {
$pkginfoprog -V
exit 0
}
checkpkg() {
if [ ! -d "$2/$1" ]; then
echo "pkg_view: \`$1' doesn't exist in \`$2'" 1>&2
exit 1
fi
}
#########################################
# Initialization and Options Processing #
#########################################
doit=""
stowdir=""
viewbase=${LOCALBASE:-/usr/pkg}
view=${PKG_VIEW:-""}
dflt_ignorefiles=${PLIST_IGNORE_FILES:-"info/dir *[~#] *.OLD *.orig *,v"}
dflt_pkg_dbdir=${PKG_DBDIR:-/var/db/pkg}
ignorefiles=""
verbose=0
while [ $# -gt 0 ]; do
case "$1" in
-d) stowdir=$2; shift ;;
-d*) stowdir=`echo $1 | $sedprog -e 's|^-d||'` ;;
-i) ignorefiles="$ignorefiles $2"; shift ;;
-i*) ignorefiles="$ignorefiles `echo $1 | $sedprog -e 's|^-i||'`" ;;
-k) dflt_pkg_dbdir="$2"; shift ;;
-k*) dflt_pkg_dbdir=`echo $1 | $sedprog -e 's|^-k||'` ;;
-n) doit=":" ;;
-V) version ;;
-v) verbose=`expr $verbose + 1` ;;
-W) viewbase=$2; shift ;;
-W*) viewbase=`echo $1 | $sedprog -e 's|^-p||'` ;;
-w) view=$2; shift ;;
--view=*) view=`echo $1 | $sedprog -e 's|--view=||'` ;;
--) shift; break ;;
*) break ;;
esac
shift
done
if [ $# -lt 1 ]; then
usage
fi
# echoN will actually give output if ${verbose} > N.
echo1=":"
echo2=":"
if [ ${verbose} -gt 0 ]; then echo1=echo; fi
if [ ${verbose} -gt 1 ]; then echo2=echo; fi
action=""
case "$1" in
add) action=add ;;
check) action=check ;;
delete|rm) action=delete ;;
*) usage ;;
esac
shift
# if standard view, put package info into ${dflt_pkg_dbdir}
# if not standard view, put package info into view's pkgdb
case "$view" in
"")
pkg_dbdir=${dflt_pkg_dbdir}
targetdir=${viewbase}
viewstr="the standard view"
;;
*)
pkg_dbdir=${viewbase}/${view}/.pkgdb
targetdir=${viewbase}/${view}
viewstr="view \"${view}\""
;;
esac
# Use stowdir if it's given, else fall back to ${DEPOTBASE} or else
# default to ${viewbase}/packages.
#
depot_pkg_dbdir=${stowdir:-${DEPOTBASE:-${viewbase}/packages}}
case "${depot_pkg_dbdir}" in
${pkg_dbdir})
echo "pkg_view: the depot and the view package database directories are the same" 1>&2
exit 1
;;
esac
##########################
# Shell helper functions #
##########################
# symlinks check|add|delete <pkg>
#
# Calls linkfarm(1) to check, add or delete the symlink farm in
# ${targetdir}. We also ignore the right set of files when doing the
# linkfarm operations.
#
symlinks() {
pkg=$2
case "$1" in
add) linkfarmflags="" ;;
check) linkfarmflags="-c" ;;
delete) linkfarmflags="-D" ;;
esac
if [ -f ${depot_pkg_dbdir}/$pkg/+BUILD_INFO ]; then
ignore=`$grepprog "^_PLIST_IGNORE_FILES=" ${depot_pkg_dbdir}/$pkg/+BUILD_INFO | $sedprog -e 's|^_PLIST_IGNORE_FILES=[ ]*||'`
fi
case "$ignore" in
"") ignore="${dflt_ignorefiles}" ;;
esac
dbs=`(cd ${depot_pkg_dbdir}/$pkg; echo +*)`
ignore="${ignore} ${ignorefiles} $dbs"
$doit $envprog PLIST_IGNORE_FILES="${ignore}" $linkfarmprog $linkfarmflags --target=${targetdir} --dir=${depot_pkg_dbdir} $pkg
}
#############
# Main Loop #
#############
while [ $# -gt 0 ]; do
case $action in
add)
checkpkg $1 ${depot_pkg_dbdir}
if [ -f ${pkg_dbdir}/$1/+DEPOT ]; then
echo "pkg_view: \`$1' already exists in $viewstr" 1>&2
exit 1
fi
$echo1 "Adding $1 to ${targetdir}."
symlinks add $1
$doit $mkdirprog -p ${depot_pkg_dbdir}/$1
temp=${depot_pkg_dbdir}/$1/+VIEWS.$$
$doit $touchprog ${depot_pkg_dbdir}/$1/+VIEWS
$doit $cpprog ${depot_pkg_dbdir}/$1/+VIEWS ${temp}
case "$doit" in
"") ($grepprog -v '^'${pkg_dbdir}'$' ${temp} || true; echo ${pkg_dbdir}) > ${depot_pkg_dbdir}/$1/+VIEWS ;;
esac
$doit $rmprog ${temp}
$doit $mkdirprog -p ${pkg_dbdir}/$1
#
# Copy all of the metadata files except for +VIEWS,
# which is only for the depoted package, and
# +REQUIRED_BY, which is irrelevant for a package in
# a view.
#
case "$doit" in
"") (cd ${depot_pkg_dbdir}/$1; $paxprog -rwpe '-s|\./\+VIEWS$||' '-s|\./\+REQUIRED_BY$||' ./+* ${pkg_dbdir}/$1)
$sedprog -e 's|'${depot_pkg_dbdir}/$1'|'${targetdir}'|g' < ${depot_pkg_dbdir}/$1/+CONTENTS > ${pkg_dbdir}/$1/+CONTENTS
echo "${depot_pkg_dbdir}/$1" > ${pkg_dbdir}/$1/+DEPOT
;;
esac
$doit $pkgadminprog -K ${pkg_dbdir} add $1
if [ -f ${pkg_dbdir}/$1/+INSTALL ]; then
$doit $chmodprog +x ${pkg_dbdir}/$1/+INSTALL
$doit $envprog -i PKG_PREFIX=${targetdir} ${pkg_dbdir}/$1/+INSTALL $1 VIEW-INSTALL
ec=$?
if [ $ec != 0 ]; then
echo "pkg_view: install script returned an error." 1>&2
exit $ec
fi
fi
;;
check)
checkpkg $1 ${depot_pkg_dbdir}
$echo1 "Checking $1 in ${targetdir}."
symlinks check $1
exit $?
;;
delete)
checkpkg $1 ${depot_pkg_dbdir}
if [ ! -f ${pkg_dbdir}/$1/+DEPOT ]; then
echo "pkg_view: \`$1' doesn't exist in $viewstr" 1>&2
exit 1
fi
$echo1 "Deleting $1 from ${targetdir}."
if [ -f ${pkg_dbdir}/$1/+REQUIRED_BY ]; then
if $cmpprog -s ${pkg_dbdir}/$1/+REQUIRED_BY /dev/null; then
: # not really required by another pkg
else
(echo "pkg_view: \`$1' is required by other packages:"
$sedprog -e 's|^| |' ${pkg_dbdir}/$1/+REQUIRED_BY) 1>&2
exit 1
fi
fi
if [ -f ${pkg_dbdir}/$1/+DEINSTALL ]; then
$doit $chmodprog +x ${pkg_dbdir}/$1/+DEINSTALL
$doit $envprog -i PKG_PREFIX=${targetdir} ${pkg_dbdir}/$1/+DEINSTALL $1 VIEW-DEINSTALL
ec=$?
if [ $ec != 0 ]; then
echo "pkg_view: de-install script returned an error." 1>&2
exit $ec
fi
fi
symlinks delete $1
temp=${depot_pkg_dbdir}/$1/+VIEWS.$$
$doit $cpprog ${depot_pkg_dbdir}/$1/+VIEWS ${temp}
case "$doit" in
"") ($grepprog -v '^'${pkg_dbdir}'$' ${temp} || true) > ${depot_pkg_dbdir}/$1/+VIEWS ;;
esac
$doit $rmprog ${temp}
$doit $rmprog -rf ${pkg_dbdir}/$1
$doit $pkgadminprog -K ${pkg_dbdir} delete $1
;;
esac
shift
done
exit 0