#! /bin/sh # $NetBSD: pkg_view.sh.in,v 1.3 2003/09/23 07:44:51 grant 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 prefix="/usr/pkg" exec_prefix="${prefix}" sbindir="${exec_prefix}/sbin" # set up program definitions chmodprog="/usr/bin/chmod" cmpprog="/usr/bin/cmp" cpprog="/usr/bin/cp" envprog="/usr/bin/env" findprog="/usr/bin/find" grepprog="/usr/bin/grep" linkfarmprog="${exec_prefix}/sbin/linkfarm" lnprog="/usr/bin/ln" mkdirprog="/usr/bin/mkdir" paxprog="/usr/pkg/bin/pax" pkgadminprog="${exec_prefix}/sbin/pkg_admin" pkginfoprog="${exec_prefix}/sbin/pkg_info" rmprog="/usr/bin/rm" rmdirprog="/usr/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 # # 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