pkgsrc/bootstrap/pkg.sh

569 lines
14 KiB
Bash
Executable file

#! /bin/sh
#
# $NetBSD: pkg.sh,v 1.1.1.1 2004/03/11 13:03:59 grant Exp $
#
#
# Copyright (c) 2002 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
# for the NetBSD project.
# 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
version=20020615
opsys=`uname -s`
case "$opsys" in
Darwin)
awkprog=/usr/bin/awk
catprog=/bin/cat
chmodprog=/bin/chmod
cpprog=/bin/cp
lnprog=/bin/ln
mkdirprog=/bin/mkdir
rmprog=/bin/rm
sedprog=/usr/bin/sed
;;
Linux)
awkprog=/usr/bin/awk
catprog=/bin/cat
chmodprog=/bin/chmod
cpprog=/bin/cp
lnprog=/bin/ln
mkdirprog=/bin/mkdir
rmprog=/bin/rm
sedprog=/bin/sed
;;
NetBSD)
awkprog=/usr/bin/awk
catprog=/bin/cat
chmodprog=/bin/chmod
cpprog=/bin/cp
lnprog=/bin/ln
mkdirprog=/bin/mkdir
rmprog=/bin/rm
sedprog=/usr/bin/sed
;;
SunOS)
awkprog=/usr/bin/nawk
catprog=/usr/bin/cat
chmodprog=/usr/bin/chmod
cpprog=/usr/bin/cp
lnprog=/usr/bin/ln
mkdirprog=/usr/bin/mkdir
rmprog=/usr/bin/rm
sedprog=/usr/xpg4/bin/sed
;;
*)
awkprog=awk
catprog=cat
chmodprog=chmod
cpprog=cp
lnprog=ln
mkdirprog=mkdir
rmprog=rm
sedprog=sed
;;
esac
getpkg()
{
if test -d $PKG_DBDIR/$1; then
d=$PKG_DBDIR/$1
else
d="`echo $PKG_DBDIR/${1}-*`"
fi
echo $d
}
case "$DIGESTPROG" in
"") DIGESTPROG=/usr/pkg/bin/digest ;;
esac
case "$PKG_DBDIR" in
"") PKG_DBDIR=/var/db/pkg ;;
esac
case "$PKG_DIGEST" in
"") PKG_DIGEST=sha1 ;;
esac
ALLDIGESTS="sha1 sha512"
case "$0" in
*pkg_create) cmd=create ;;
*pkg_delete) cmd=delete ;;
*pkg_info) cmd=info ;;
*pkg.sh|*pkg) cmd=$1; shift ;;
esac
case "$cmd" in
create)
if [ $# -lt 1 ]; then
echo "Usage: pkg create ..." > /dev/stderr
exit 1
fi
BUILDINFOFILE="" # done
BUILDVERSIONFILE="" # done
CONFLICTS="" # done
comment="" # done
DISPLAYFILE="" # done
DESCRFILE="" # done
plist="" # done
minush=no
realprefix=""
installfile="" # done
deinstallfile="" # done
srcdir=""
relsymlinks=no
mtreefile=""
plistonly=no
PREREQS=""
#prefix=""
reorder=no
requirements=""
allsizefile="" # done
thissizefile="" # done
updatefilecache=yes
excludefrom=""
while [ $# -gt 0 ]; do
case "$1" in
-B) BUILDINFOFILE="$2"; shift ;;
-C) CONFLICTS="$2"; shift ;;
-D) DISPLAYFILE="$2"; shift ;;
-I) realprefix="$2"; shift ;;
-L) srcdir="$2"; shift ;;
-O) plistonly=yes ;;
-P) PREREQS="$PREREQS $2"; shift ;;
-R) reorder=yes ;;
-S) allsizefile="$2"; shift ;;
-U) updatefilecache=no ;;
-V) echo $version; exit 0 ;;
-X) excludefrom="$excludefrom $2"; shift ;;
-b) BUILDVERSIONFILE="$2"; shift ;;
-c) case "$2" in
-*) comment="`echo $2 | $sedprog -e 's|^-||'`"; shift ;;
*) comment=`$catprog $2` ;;
esac
shift ;;
-d) DESCRFILE=$2; shift ;;
-f) plist="$2"; shift ;;
-h) minush=yes ;;
-i) installfile="$2"; shift ;;
-k) deinstallfile="$2"; shift ;;
-l) relsymlinks=yes ;;
-m) mtreefile="$2"; shift ;;
-p) PREFIX="$2"; shift ;;
-r) requirements="$2"; shift ;;
-s) thissizefile="$2"; shift ;;
-t) shift ;;
-v) set -x ;;
--) shift; break ;;
*) break ;;
esac
shift
done
PKGNAME=$1
if [ ! -d $PKG_DBDIR/$PKGNAME ]; then
$mkdirprog $PKG_DBDIR/$PKGNAME
fi
if [ -f "$BUILDINFOFILE" ]; then
$cpprog $BUILDINFOFILE $PKG_DBDIR/$PKGNAME/+BUILD_INFO
fi
if [ -f "$BUILDVERSIONFILE" ]; then
$cpprog $BUILDVERSIONFILE $PKG_DBDIR/$PKGNAME/+BUILD_VERSION
fi
echo $comment > $PKG_DBDIR/$PKGNAME/+COMMENT
$cpprog $DESCRFILE $PKG_DBDIR/$PKGNAME/+DESC
case "$installfile" in
"") ;;
*) $cpprog $installfile $PKG_DBDIR/$PKGNAME/+INSTALL ;;
esac
case "$deinstallfile" in
"") ;;
*) $cpprog $deinstallfile $PKG_DBDIR/$PKGNAME/+DEINSTALL ;;
esac
case "$DISPLAYFILE" in
"") ;;
*) $cpprog $DISPLAYFILE $PKG_DBDIR/$PKGNAME/+DISPLAY ;;
esac
case "$allsizefile" in
"") ;;
*) $cpprog $allsizefile $PKG_DBDIR/$PKGNAME/+SIZE_ALL ;;
esac
case "$thissizefile" in
"") ;;
*) $cpprog $thissizefile $PKG_DBDIR/$PKGNAME/+SIZE_PKG ;;
esac
export PREFIX PKGNAME CONFLICTS PREREQS DIGESTPROG PKG_DIGEST
$awkprog '
BEGIN {
if (ENVIRON["CONFLICTS"] != "") {
cflc = split(ENVIRON["CONFLICTS"], cflv);
for (i = 1 ; i <= cflc ; i++)
printf("@pkgcfl %s\n", cflv[i])
}
if (ENVIRON["PREREQS"] != "") {
prec = split(ENVIRON["PREREQS"], prev);
for (i = 1 ; i <= prec ; i++)
printf("@pkgdep %s\n", prev[i])
}
prefix = ENVIRON["PREFIX"];
printf("@name %s\n@cwd %s\n", ENVIRON["PKGNAME"], prefix) }
/^@(comment|dirrm|src)/ { print $0; next }
/^@(un)?exec/ { last = filename; gsub(".*/", "", last); gsub("%f", last);
fc = split(filename, fv, "/"); fn = prefix; for (i = 1 ; i < fc ; i++) fn = fn "/" fv[i]; gsub("%B", fn);
gsub("%F", filename);
gsub("%D", prefix); print $0; next }
{ filename = $0; printf("%s\n@comment MD5:", $0); cmd = sprintf("'$catprog' %s/%s | %s %s", prefix, $0, ENVIRON["DIGESTPROG"], ENVIRON["PKG_DIGEST"]); system(cmd) }
' < $plist > $PKG_DBDIR/$PKGNAME/+CONTENTS
# construct the digests of all the metafiles
echo "#! /bin/sh" > $PKG_DBDIR/$PKGNAME/+VERIFY
echo "" >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo 'case $# in' >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo '0) ;;' >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo '*) cd '$PKG_DBDIR/$PKGNAME ';;' >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo 'esac' >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo "" >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo "$awkprog '" >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo 'BEGIN { ex = 0 }' >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo 'END { exit(ex) }' >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo '/^@cwd/ { prefix = $2; next }' >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo '/^@/ { next }' >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo ' {' >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo ' for (done = 0 ; !done ; ) {' >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo ' filename = prefix "/" $0;' >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo ' getline;' >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo ' if ($0 ~ /^@comment (MD5|SHA1):/) {' >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo ' alg = dig = $2;' >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo ' gsub(":.*", "", alg);' >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo ' gsub("[A-Za-z0-9]*:", "", dig);' >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo ' cmd = sprintf("s=`'$catprog' %s | '$DIGESTPROG' %s`; if test \"%s\" != \"$s\"; then echo \"Checksum mismatch (%s): expected %s, got $s\"; fi", filename, alg, dig, filename, dig);' >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo ' if (system(cmd) != 0) ex = 1' >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo ' done = 1;' >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo ' }' >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo ' }' >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo "}' +CONTENTS" >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo "" >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo "$awkprog '" >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo "BEGIN { ex = 0 }" >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo "END { exit(ex) }" >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo " {" >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo 'cmd = sprintf("s=`'$catprog' %s | '$DIGESTPROG' %s`; if test \"%s\" != \"$s\"; then echo \"Checksum mismatch (%s): expected %s, got $s\"; fi", $1, $2, $3, $1, $3);' >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo "if (system(cmd) != 0) ex = 1" >> $PKG_DBDIR/$PKGNAME/+VERIFY
echo "}' << filesEOF" >> $PKG_DBDIR/$PKGNAME/+VERIFY
# construct the digests of all the metafiles
for f in +BUILD_INFO +BUILD_VERSION +COMMENT +CONTENTS +DEINSTALL +DESC +DISPLAY +INSTALL +SIZE_ALL +SIZE_PKG; do
if [ -f $PKG_DBDIR/$PKGNAME/$f ]; then
for dig in $ALLDIGESTS; do
echo "$f $dig `$catprog $PKG_DBDIR/$PKGNAME/$f | $DIGESTPROG $dig`" >> $PKG_DBDIR/$PKGNAME/+VERIFY
done
fi
done
echo "filesEOF" >> $PKG_DBDIR/$PKGNAME/+VERIFY
$chmodprog 0755 $PKG_DBDIR/$PKGNAME/+VERIFY
# change absolute symlinks to relative ones
case "$relsymlinks" in
yes) for f in `$awkprog '
$1 == "prefix" { prefix = $2; next }
$1 == "file" { printf("%s/%s\n", prefix, $0) }
' < $PKG_DBDIR/$PKGNAME/+INVENTORY`; do
if [ -h $f ]; then
target="`ls -al $1 | awk '{ print $11 }'`"
case "$target" in
/*) echo $prefix $target $f | /usr/bin/awk '
{
pc = split($1, pv, "/");
tc = split($2, tv, "/");
for (i = tc - pc + 2 ; i <= tc ; i++)
linkname = linkname "../";
for (i = pc + 1 ; i <= tc ; i++)
linkname = linkname "/" tv[i];
cmd = sprintf("'$rmprog' -f %s && '$lnprog' -s %s %s", $3, linkname, $3);
exit(system(cmd));
}'
;;
esac
fi
done
;;
esac
;;
delete)
deinstall=yes
force=no
doit=yes
justdb=no
prefix=""
needs=no
reqs=no
while [ $# -gt 0 ]; do
case "$1" in
-D) deinstall=no ;;
-O) justdb=yes ;;
-R) needs=yes ;;
-f) force=yes ;;
-n) doit=no ;;
-p) prefix=$2; shift ;;
-r) reqs=yes ;;
esac
shift
done
for pkg in $@; do
d=`getpkg $pkg`
hitme=yes
if [ -f $d/+REQUIRED_BY ]; then
hitme=no
case "$force" in
yes) hitme=yes ;;
esac
case "$needs" in
yes) hitme=yes ;;
esac
case "$hitme" in
no) echo "pkg_delete: package $pkg is required by other packages:"
$catprog $d/+REQUIRED_BY
echo "pkg_delete: 1 package deletion failed"
continue
;;
esac
fi
case "$hitme" in
yes) if [ -f $d/+VERIFY ]; then
$d/+VERIFY
fi
;;
esac
case "$reqs" in
yes) ;;
esac
done
;;
info)
allpackages=no
buildinfo=no
buildversion=no
comment=no
display=no
descr=no
exist=no
filedb=no
plist=no
index=no
install=no
deinstall=no
entries=no
needs=no
prefix=no
reqby=no
sizeall=no
sizepkg=no
version=no
if [ $# -eq 0 ]; then
set -- -I -a
fi
while [ $# -gt 0 ]; do
case "$1" in
-B) buildinfo=yes ;;
-D) display=yes ;;
-F) filedb=yes ;;
-I) index=yes ;;
-L) entries=yes ;;
-S) sizeall=yes ;;
-V) version=yes ;;
-a) allpackages=yes ;;
-b) buildversion=yes ;;
-c) comment=yes ;;
-d) descr=yes ;;
-e) exist=yes ;;
-f) plist=yes ;;
-i) install=yes ;;
-k) deinstall=yes ;;
-n) needs=yes ;;
-p) prefix=yes ;;
-r) reqby=yes ;;
-s) sizepkg=yes ;;
*) break ;;
esac
shift
done
case "$version" in
yes) echo $version; exit 0 ;;
esac
case "$filedb" in
yes) echo "-F is unimplemented" ;;
esac
case "$exist" in
yes) echo "-e is unimplemented" ;;
esac
case "$allpackages" in
yes) pkglist="`(cd $PKG_DBDIR; ls -d *-*)`" ;;
*) pkglist="$@" ;;
esac
for pkg in $pkglist; do
d=`getpkg $pkg`
case "$buildinfo" in
yes) $catprog $d/+BUILD_INFO ;;
esac
case "$display" in
yes) if [ -f $d/+DISPLAY ]; then
$catprog $d/+DISPLAY
fi ;;
esac
case "$index" in
yes) echo "`echo $d | $sedprog -e 's|.*/||'` `$catprog $d/+COMMENT`" ;;
esac
case "$entries" in
yes) $awkprog '
/^@cwd/ { prefix = $2 }
/^@/ { next }
{ printf("%s/%s\n", prefix, $0) }
' < $d/+CONTENTS ;;
esac
case "$buildversion" in
yes) $catprog $d/+BUILD_VERSION ;;
esac
case "$comment" in
yes) $catprog $d/+COMMENT ;;
esac
case "$descr" in
yes) $catprog $d/+DESC ;;
esac
case "$install" in
yes) if [ -f $d/+INSTALL ]; then
$catprog $d/+INSTALL
fi ;;
esac
case "$deinstall" in
yes) if [ -f $d/+DEINSTALL ]; then
$catprog $d/+DEINSTALL
fi ;;
esac
case "$needs" in
yes) $awkprog '/^@pkgdep/ { print $2 }' < $d/+CONTENTS ;;
esac
case "$prefix" in
yes) $awkprog '/^@cwd/ { print $2; exit }' < $d/+CONTENTS ;;
esac
case "$reqby" in
yes) if [ -f $d/+REQUIRED_BY ]; then
$catprog $d/+REQUIRED_BY
fi ;;
esac
case "$sizeall" in
yes) $catprog $d/+SIZE_ALL
esac
case "$sizepkg" in
yes) $catprog $d/+SIZE_PKG
esac
done
;;
show)
if [ $# -lt 1 ]; then
echo "Usage: pkg show type packages" > /dev/stderr
exit 1
fi
showtype=$1
shift
for pkg in $@; do
d=`getpkg $pkg`
case "$d" in
"") echo "No such package ($pkg)" ;;
*)
case "$showtype" in
allsizes)
$catprog $d/+SIZE_ALL ;;
blddep|blddeps)
$awkprog '/^@blddep/ { print $2 }' $d/+CONTENTS ;;
comment)
$catprog $d/+COMMENT ;;
description|desc|descr)
$catprog $d/+DESC ;;
deinstall)
if [ -f $d/+DEINSTALL ]; then
$catprog $d/+DEINSTALL
fi ;;
display)
if [ -f $d/+DISPLAY ]; then
$catprog $d/+DISPLAY
fi ;;
files)
$awkprog '
/^@cwd/ { prefix = $2 }
/^@/ { next }
{ printf("%s/%s\n", prefix, $0) }
' < $d/+CONTENTS ;;
index)
echo "`echo $d | $sedprog -e 's|.*/||'` `$catprog $d/+COMMENT`" ;;
info)
$catprog $d/+BUILD_INFO ;;
install)
if [ -f $d/+INSTALL ]; then
$catprog $d/+INSTALL
fi ;;
prefix)
$awkprog '/^@cwd/ { print $2 }' $d/+CONTENTS ;;
prereqs|pkgdep)
$awkprog '/^@pkgdep/ { print $2 }' $d/+CONTENTS ;;
size)
$catprog $d/+SIZE_PKG ;;
version)
$catprog $d/+BUILD_VERSION ;;
*)
echo "Unknown type \"$showtype\""
exit 1 ;;
esac
esac
done
;;
version)
echo $version
exit 0
;;
*) echo "$0: \"$cmd\" not found"
exit 1
;;
esac
exit 0