regpkg revision 1.9
11.1Sagc#! /bin/sh 21.1Sagc# 31.9Sapb# $NetBSD: regpkg,v 1.9 2006/01/04 14:14:35 apb Exp $ 41.1Sagc# 51.1Sagc# Copyright (c) 2003 Alistair G. Crooks. All rights reserved. 61.1Sagc# 71.1Sagc# Redistribution and use in source and binary forms, with or without 81.1Sagc# modification, are permitted provided that the following conditions 91.1Sagc# are met: 101.1Sagc# 1. Redistributions of source code must retain the above copyright 111.1Sagc# notice, this list of conditions and the following disclaimer. 121.1Sagc# 2. Redistributions in binary form must reproduce the above copyright 131.1Sagc# notice, this list of conditions and the following disclaimer in the 141.1Sagc# documentation and/or other materials provided with the distribution. 151.1Sagc# 3. All advertising materials mentioning features or use of this software 161.1Sagc# must display the following acknowledgement: 171.1Sagc# This product includes software developed by Alistair G. Crooks. 181.1Sagc# for the NetBSD project. 191.1Sagc# 4. The name of the author may not be used to endorse or promote 201.1Sagc# products derived from this software without specific prior written 211.1Sagc# permission. 221.1Sagc# 231.1Sagc# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 241.1Sagc# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 251.1Sagc# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 261.1Sagc# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 271.1Sagc# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 281.1Sagc# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 291.1Sagc# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 301.1Sagc# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 311.1Sagc# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 321.1Sagc# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 331.1Sagc# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 341.1Sagc# 351.1Sagc 361.9Sapb# Usage: regpkg [options] set pkgname 371.9Sapb# 381.9Sapb# Registers a syspkg in the database directory, 391.9Sapb# and optionally creates a binary package. 401.9Sapb# 411.9Sapb# Options: 421.9Sapb# -q Quiet. 431.9Sapb# -v Verbose. 441.9Sapb# -f Force. 451.9Sapb# -m Ignore errors from missing files. 461.9Sapb# -u Update. 471.9Sapb# -c Use cached information from ${BUILD_INFO_CACHE}. 481.9Sapb# -d destdir Sets DESTDIR. 491.9Sapb# -t binpkgdir Create a binary package (in *.tgz format) in the 501.9Sapb# specified directory. Without this option, a binary 511.9Sapb# package is not created. 521.9Sapb# -M metalog Use the specified metalog file to override file 531.9Sapb# or directory attributes when creating a binary package. 541.9Sapb# -N etcdir Use the specified directory for passwd and group files. 551.9Sapb# 561.9Sapb# When -f is set: If the desired syspkg already exists, it is overwritten. 571.9Sapb# When -u is set: If the desired syspkg already exists, it might be 581.9Sapb# overwritten or left alone, depending on whether it's older 591.9Sapb# or newer than the files that belong to the syspkg. 601.9Sapb# When neither -u nor -f are set: It's an error for the desired syspkg 611.9Sapb# to already exist. 621.1Sagc 631.9Sapbprog="${0##*/}" 641.9Sapbtoppid=$$ 651.8Sapbrundir="$(dirname "$0")" # ${0%/*} isn't good enough when there's no "/" 661.9Sapb. "${rundir}/sets.subr" 671.9Sapb 681.9Sapbbomb() 691.9Sapb{ 701.9Sapb #echo "${prog}: bomb: start, toppid=${toppid} \$\$=$$" 711.9Sapb kill ${toppid} # in case we were invoked from a subshell 721.9Sapb #echo "${prog}: bomb: killed ${toppid}" 731.9Sapb exit 1 741.9Sapb} 751.6Serh 761.9Sapb# A literal newline 771.9Sapbnl=' 781.9Sapb' 791.9Sapb# A literal tab 801.9Sapbtab=' ' 811.9Sapb 821.9Sapb# Prefixes for error messages, warnings, and important informational 831.9Sapb# messages. 841.9SapbERROR="${prog}: ERROR: " 851.9SapbWARNING="${prog}: WARNING: " 861.9SapbNOTE="${prog}: NOTE: " 871.9SapbERRWARN="${ERROR}" # may be changed by "-f" (force) command line flag 881.9SapbERRWARNNOTE="${ERROR}" # may be changed by "-u" (update) command line flag 891.1Sagc 901.9Sapb# 911.9Sapb# All temporary files will go in ${SCRATCH}, which will be deleted on 921.9Sapb# exit. 931.9Sapb# 941.9SapbSCRATCH="$( ${MKTEMP} -d "/var/tmp/${0##*/}.XXXXXX" )" 951.9Sapbif [ $? -ne 0 -o \! -d "${SCRATCH}" ]; then 961.9Sapb echo >&2 "Could not create scratch directory." 971.9Sapb bomb 981.1Sagcfi 991.1Sagc 1001.9Sapb# 1011.9Sapb# cleanup() always deletes the SCRATCH directory, and might also 1021.9Sapb# delete other files or directories. 1031.9Sapb# 1041.9Sapbes=0 1051.9Sapbcleanup_must_delete_binpkgfile=false 1061.9Sapbcleanup_must_delete_dbsubdir=false 1071.9Sapbcleanup () 1081.9Sapb{ 1091.9Sapb trap - 0 1101.9Sapb #echo "${prog}: cleanup start" 1111.9Sapb if ${cleanup_must_delete_binpkgfile:-false} && [ -e "${binpkgfile}" ] 1121.9Sapb then 1131.9Sapb echo >&2 "${prog}: deleting partially-created ${binpkgfile}" 1141.9Sapb rm -f "${binpkgfile}" 1151.9Sapb fi 1161.9Sapb if ${cleanup_must_delete_dbsubdir:-false} \ 1171.9Sapb && [ -e "${SYSPKG_DB_SUBDIR}" ] 1181.9Sapb then 1191.9Sapb echo >&2 "${prog}: deleting partially-created ${SYSPKG_DB_SUBDIR}" 1201.9Sapb rm -rf "${SYSPKG_DB_SUBDIR}" 1211.9Sapb fi 1221.9Sapb rm -rf "${SCRATCH}" 1231.9Sapb #echo "${prog}: cleanup done, exit ${es}" 1241.9Sapb exit ${es} 1251.9Sapb} 1261.9Sapbtrap 'es=128; cleanup' 1 2 3 13 15 # HUP INT QUIT PIPE TERM 1271.9Sapbtrap 'es=$?; cleanup' 0 # EXIT 1281.9Sapb 1291.9Sapb# 1301.9Sapb# Parse command line args. 1311.9Sapb# 1321.9Sapbverbose=false 1331.9Sapbverbosity=0 1341.9Sapbquiet=false 1351.9Sapbforce=false 1361.9Sapbupdate=false 1371.9Sapballowmissing=false 1381.9SapbDESTDIR="${DESTDIR}" 1391.9Sapbbinpkgdir="" 1401.9Sapbmetalog="" 1411.9Sapbetcdir="" 1421.9SapbSYSPKG_DB_TOPDIR="" 1431.9Sapbpkgset="" 1441.9Sapbpkg="" 1451.9Sapbparse_args () 1461.9Sapb{ 1471.9Sapb while [ $# -gt 2 ]; do 1481.9Sapb case "$1" in 1491.9Sapb -q) quiet=true ; verbose=false ;; 1501.9Sapb -v) verbose=true ; quiet=false 1511.9Sapb verbosity=$(( ${verbosity} + 1 )) 1521.9Sapb ;; 1531.9Sapb -f) force=true ;; 1541.9Sapb -u) update=true ;; 1551.9Sapb -m) allowmissing=true ;; 1561.9Sapb -c) # The -c option is ignored. The BUILD_INFO_CACHE 1571.9Sapb # environment variable is used instead. 1581.9Sapb ;; 1591.9Sapb -d) DESTDIR="$2" ; shift ;; 1601.9Sapb -d*) DESTDIR="${1#-?}" ;; 1611.9Sapb -t) binpkgdir="$2" ; shift ;; 1621.9Sapb -t*) binpkgdir="${1#-?}" ;; 1631.9Sapb -M) metalog="$2" ; shift ;; 1641.9Sapb -M*) metalog="${1#-?}" ;; 1651.9Sapb -N) etcdir="$2" ; shift ;; 1661.9Sapb -N*) etcdir="${1#-?}" ;; 1671.9Sapb *) break ;; 1681.9Sapb esac 1691.9Sapb shift 1701.9Sapb done 1711.9Sapb if ${force}; then 1721.9Sapb ERRWARN="${WARNING}" 1731.9Sapb else 1741.9Sapb ERRWARN="${ERROR}" 1751.9Sapb fi 1761.9Sapb if ${update}; then 1771.9Sapb ERRWARNNOTE="${NOTE}" 1781.9Sapb else 1791.9Sapb ERRWARNNOTE="${ERRWARN}" 1801.9Sapb fi 1811.9Sapb DESTDIR="${DESTDIR%/}" # delete trailing "/" if any 1821.9Sapb if [ \! -n "${etcdir}" ]; then 1831.9Sapb etcdir="${DESTDIR}/etc" 1841.9Sapb fi 1851.9Sapb if [ -n "${binpkgdir}" -a \! -d "${binpkgdir}" ]; then 1861.9Sapb echo >&2 "${ERROR}binary pkg directory ${binpkgdir} does not exist" 1871.9Sapb bomb 1881.9Sapb fi 1891.9Sapb # 1901.9Sapb # SYSPKG_DB_TOPDIR is the top level directory for registering 1911.9Sapb # syspkgs. It defaults to ${DESTDIR}/var/db/syspkg, but can be 1921.9Sapb # overridden by environment variables SYSPKG_DBDIR or PKG_DBDIR. 1931.9Sapb # 1941.9Sapb # Note that this corresponds to the default value of PKG_DBDIR 1951.9Sapb # set in .../distrib/syspkg/mk/bsd.syspkg.mk. 1961.9Sapb # 1971.9Sapb SYSPKG_DB_TOPDIR="${SYSPKG_DBDIR:-${PKG_DBDIR:-${DESTDIR}/var/db/syspkg}}" 1981.9Sapb 1991.9Sapb if [ $# -ne 2 ]; then 2001.9Sapb echo "Usage: regpkg [options] set pkgname" 2011.9Sapb bomb 2021.9Sapb fi 2031.9Sapb 2041.9Sapb pkgset="$1" 2051.9Sapb pkg="$2" 2061.9Sapb} 2071.1Sagc 2081.9Sapb# 2091.9Sapb# make_PLIST() creates a skeleton PLIST from the pkgset description. 2101.9Sapb# 2111.9Sapb# The result is stored in the file ${PLIST}. 2121.9Sapb# 2131.9SapbPLIST="${SCRATCH}/PLIST" 2141.9Sapbmake_PLIST () 2151.9Sapb{ 2161.9Sapb if ${verbose} ; then 2171.9Sapb echo "Making PLIST for \"${pkg}\" package (part of ${pkgset} set)" 2181.9Sapb fi 2191.9Sapb prefix="${DESTDIR:-/}" 2201.9Sapb realprefix=/ 2211.9Sapb ${HOST_SH} "${rundir}/makeplist" -p "${prefix}" -I "${realprefix}" \ 2221.9Sapb "${pkgset}" "${pkg}" \ 2231.9Sapb >"${PLIST}" 2>"${SCRATCH}/makeplist-errors" 2241.9Sapb if ${EGREP} -v '^DEBUG:' "${SCRATCH}/makeplist-errors" ; then 2251.9Sapb # "find" invoked from makeplist sometimes reports 2261.9Sapb # errors about missing files or directories, and 2271.9Sapb # makeplist ignores the errors. Catch them here. 2281.9Sapb echo >&2 "${ERROR}makeplist reported errors for ${pkg}:" 2291.9Sapb cat >&2 "${SCRATCH}/makeplist-errors" 2301.9Sapb echo >&2 "${ERROR}see above for errors from makeplist" 2311.9Sapb if ${allowmissing}; then 2321.9Sapb echo >&2 "${prog}: ${NOTE}: ignoring above errors, due to '-m' option." 2331.9Sapb else 2341.9Sapb ${force} || bomb 2351.9Sapb fi 2361.9Sapb fi 2371.9Sapb} 2381.1Sagc 2391.9Sapb# 2401.9Sapb# init_allfiles() converts the PLIST (which contains relative filenames) 2411.9Sapb# into a list of absolute filenames. Directories are excluded from the 2421.9Sapb# result. 2431.9Sapb# 2441.9Sapb# The result is stored in the variable ${allfiles}. 2451.9Sapb# 2461.9Sapballfiles='' 2471.9Sapbinit_allfiles () 2481.9Sapb{ 2491.9Sapb [ -f "${PLIST}" ] || make_PLIST 2501.9Sapb allfiles="$( ${AWK} ' 2511.9Sapb BEGIN { destdir = "'"${DESTDIR%/}"'" } 2521.9Sapb /^@cwd/ { prefix = $2; next } 2531.9Sapb /^@dirrm/ { next } 2541.9Sapb { printf("%s%s%s\n", destdir, prefix, $0) }' "${PLIST}" )" 2551.9Sapb} 2561.1Sagc 2571.9Sapb# 2581.9Sapb# init_newestfile() finds the newest file (most recent mtime). 2591.9Sapb# 2601.9Sapb# The result is stored in the variable ${newestfile}. 2611.9Sapb# 2621.9Sapbnewestfile='' 2631.9Sapbinit_newestfile () 2641.9Sapb{ 2651.9Sapb [ -s "${allfiles}" ] || init_allfiles 2661.9Sapb # We assume no shell special characters in ${allfiles}, 2671.9Sapb # and spaces only between file names, not inside file names. 2681.9Sapb # This should be safe, because it has no no user-specified parts. 2691.9Sapb newestfile="$( ${LS} -1dt ${allfiles} | ${SED} '1q' )" 2701.9Sapb} 2711.1Sagc 2721.9Sapb# 2731.9Sapb# Various ways of getting parts of the syspkg version number: 2741.9Sapb# 2751.9Sapb# get_osvers() - get the OS version number from osrelease.sh or $(uname -r), 2761.9Sapb# return it in ${osvers}, and set ${method}. 2771.9Sapb# get_tinyvers() - get the tiny version number from the "versions" file, 2781.9Sapb# and return it in ${tinyvers}. Does not set ${method}. 2791.9Sapb# get_newest_rcsid_date() - get the newest RCS date, 2801.9Sapb# and return it in ${newest}. Does not set ${method}. 2811.9Sapb# get_newest_mtime_date() - get the newest file modification date, 2821.9Sapb# and return it in ${newest}. Does not set ${method}. 2831.9Sapb# get_newest_date() - get date from rcsid or mtime, return it in ${newest}, 2841.9Sapb# and set ${method}. 2851.9Sapb# 2861.9Sapbget_osvers () 2871.9Sapb{ 2881.3Sagc if [ -f ../../sys/conf/osrelease.sh ]; then 2891.8Sapb osvers="$(${HOST_SH} ../../sys/conf/osrelease.sh)" 2901.4Sdyoung method=osreleases 2911.3Sagc else 2921.8Sapb osvers="$(${UNAME} -r)" 2931.3Sagc method=uname 2941.3Sagc fi 2951.9Sapb #echo "${osvers}" 2961.9Sapb} 2971.9Sapbget_tinyvers () 2981.9Sapb{ 2991.9Sapb tinyvers="$( ${AWK} '$1 ~ '/"${pkg}"/' { print $2 }' \ 3001.9Sapb "${rundir}/versions" )" 3011.9Sapb case "${tinyvers}" in 3021.9Sapb "") tinyvers=0 3031.9Sapb ;; 3041.9Sapb esac 3051.9Sapb #echo "${tinyvers}" 3061.9Sapb} 3071.9Sapbget_newest_rcsid_date() 3081.9Sapb{ 3091.9Sapb [ -s "${allfiles}" ] || init_allfiles 3101.9Sapb 3111.9Sapb # Old RCS identifiers might have 2-digit years, so we match both 3121.9Sapb # YY/MM/DD and YYYY/MM/DD. We also try to deal with the Y10K 3131.9Sapb # problem by allowing >4 digit years. 3141.9Sapb newest=0 3151.9Sapb case "${allfiles}" in 3161.3Sagc "") ;; 3171.9Sapb *) newest="$( ${IDENT} ${allfiles} 2>/dev/null | ${AWK} ' 3181.3Sagc BEGIN { last = 0 } 3191.3Sagc $2 == "crt0.c,v" { next } 3201.9Sapb NF == 8 && \ 3211.9Sapb $4 ~ /^[0-9][0-9]\/[0-9][0-9]\/[0-9][0-9]$/ \ 3221.9Sapb { t = "19" $4; gsub("/", "", t); 3231.9Sapb if (t > last) last = t; } 3241.9Sapb NF == 8 && \ 3251.9Sapb $4 ~ /^[0-9][0-9][0-9][0-9][0-9]*\/[0-9][0-9]\/[0-9][0-9]$/ \ 3261.9Sapb { t = $4; gsub("/", "", t); 3271.9Sapb if (t > last) last = t; } 3281.9Sapb END { print last }' )" 3291.3Sagc method=ident 3301.3Sagc ;; 3311.3Sagc esac 3321.9Sapb #echo "${newest}" 3331.9Sapb} 3341.9Sapbget_newest_mtime_date () 3351.9Sapb{ 3361.9Sapb [ -s "${newestfile}" ] || init_newestfile 3371.9Sapb 3381.9Sapb # We could simplify the awk program to take advantage of the 3391.9Sapb # fact thet it should have exactly one line of input. 3401.9Sapb newest="$( ${ENV_CMD} TZ=UTC LOCALE=C ${LS} -lT "${newestfile}" \ 3411.9Sapb | ${AWK} ' 3421.9Sapb BEGIN { newest = 0 } 3431.9Sapb { 3441.9Sapb t = $9 ""; 3451.9Sapb if ($6 == "Jan") t = t "01"; 3461.9Sapb if ($6 == "Feb") t = t "02"; 3471.9Sapb if ($6 == "Mar") t = t "03"; 3481.9Sapb if ($6 == "Apr") t = t "04"; 3491.9Sapb if ($6 == "May") t = t "05"; 3501.9Sapb if ($6 == "Jun") t = t "06"; 3511.9Sapb if ($6 == "Jul") t = t "07"; 3521.9Sapb if ($6 == "Aug") t = t "08"; 3531.9Sapb if ($6 == "Sep") t = t "09"; 3541.9Sapb if ($6 == "Oct") t = t "10"; 3551.9Sapb if ($6 == "Nov") t = t "11"; 3561.9Sapb if ($6 == "Dec") t = t "12"; 3571.9Sapb if ($7 < 10) t = t "0"; 3581.9Sapb t = t $7; 3591.9Sapb #these next two lines add the 24h clock onto the date 3601.9Sapb #gsub(":", "", $8); 3611.9Sapb #t = sprintf("%s.%4.4s", t, $8); 3621.9Sapb if (t > newest) newest = t; 3631.9Sapb } 3641.9Sapb END { print newest }' )" 3651.9Sapb #echo "${newest}" 3661.9Sapb} 3671.9Sapbget_newest_date () 3681.9Sapb{ 3691.9Sapb get_newest_rcsid_date 3701.9Sapb case "${newest}" in 3711.9Sapb ""|0) get_newest_mtime_date 3721.3Sagc method=ls 3731.3Sagc ;; 3741.9Sapb *) method=rcsid 3751.9Sapb ;; 3761.3Sagc esac 3771.9Sapb #echo "${newest}" 3781.9Sapb} 3791.9Sapb 3801.9Sapb# 3811.9Sapb# choose_version_number() chooses the syspkg version number, 3821.9Sapb# by concatenating several components (OS version, syspkg "tiny" 3831.9Sapb# version and date). We end up with something like 3841.9Sapb# osvers="3.99.15", tinyvers="0", newest="20060104", 3851.9Sapb# and t="3.99.15.0.20060104". 3861.9Sapb# 3871.9Sapb# The result is stored in the variables ${t} and ${method}. 3881.9Sapb# 3891.9Sapbmethod='' 3901.9Sapbt='' 3911.9Sapbchoose_version_number () 3921.9Sapb{ 3931.9Sapb get_osvers ; m1="${method}" 3941.9Sapb get_tinyvers # does not set ${method} 3951.9Sapb get_newest_date ; m2="${method}" 3961.9Sapb t="${osvers}.${tinyvers}.${newest}" 3971.9Sapb method="${m1}.${m2}" 3981.9Sapb 3991.9Sapb # print version number that we're using 4001.9Sapb if ${verbose}; then 4011.9Sapb echo "${pkg} - ${t} version using ${method} method" 4021.9Sapb fi 4031.9Sapb} 4041.9Sapb 4051.9Sapb# 4061.9Sapb# print_dir_exec_lines outputs an "@exec install" line for each 4071.9Sapb# directory in ${PLIST} 4081.9Sapb# 4091.9Sapbprint_dir_exec_lines () 4101.9Sapb{ 4111.9Sapb local dir uname gname mode 4121.9Sapb local dot_slash_dir 4131.9Sapb local no_dot_dir 4141.9Sapb local word line 4151.9Sapb ${AWK} '/^@dirrm/ { print $2 }' <"${PLIST}" | \ 4161.9Sapb ${SORT} | \ 4171.9Sapb while read dir ; do 4181.9Sapb # Sanitise the name. ${dir} could be an absolute or 4191.9Sapb # relative name, with or without a leading "./". 4201.9Sapb # ${dot_slash_dir} always has a leading "./" (except when 4211.9Sapb # it's exactly equal to "."). ${no_dot_dir} never has a 4221.9Sapb # leading "." or "/" (except when it's exactly equal to 4231.9Sapb # "."). 4241.9Sapb case "${dir}" in 4251.9Sapb .|./|/) dot_slash_dir=. ;; 4261.9Sapb ./*) dot_slash_dir="${dir}" ;; 4271.9Sapb /*) dot_slash_dir=".${dir}" ;; 4281.9Sapb *) dot_slash_dir="./${dir}" ;; 4291.9Sapb esac 4301.9Sapb no_dot_dir="${dot_slash_dir#./}" 4311.9Sapb # Get the directory's owner, group, and mode 4321.9Sapb # from the live file system, or let it be overridden 4331.9Sapb # by the metalog. 4341.9Sapb eval "$( ${STAT} -f 'uname=%Su gname=%Sg mode=%#OLp' \ 4351.9Sapb "${DESTDIR}/${dot_slash_dir}" )" 4361.9Sapb if [ -n "${metalog}" ]; then 4371.9Sapb line="$( echo "${dot_slash_dir}" | \ 4381.9Sapb ${AWK} -f "${rundir}/join.awk" \ 4391.9Sapb /dev/stdin "${metalog}" )" 4401.9Sapb for word in ${line} ; do 4411.9Sapb case "${word}" in 4421.9Sapb uname=*|gname=*|mode=*) eval "${word}" ;; 4431.9Sapb esac 4441.9Sapb done 4451.9Sapb fi 4461.9Sapb # XXX: Work around yet another pkg_add bug: @cwd lines 4471.9Sapb # do not actually cause the working directory to change, 4481.9Sapb # so file names in @exec lines need to be qualified by 4491.9Sapb # %D, which (in our case, since we know there's an 4501.9Sapb # "@cwd /" line) will be the dir name passed to 4511.9Sapb # "pkg_add -p PREFIX". 4521.9Sapb case "${no_dot_dir}" in 4531.9Sapb .) d="%D" ;; 4541.9Sapb *) d="%D/${no_dot_dir}" ;; 4551.9Sapb esac 4561.9Sapb cat <<EOF 4571.9Sapb@exec install -d -o ${uname} -g ${gname} -m ${mode} ${d} 4581.9SapbEOF 4591.9Sapb done 4601.9Sapb} 4611.2Sjwise 4621.9Sapb# 4631.9Sapb# register_syspkg() registers the syspkg in ${SYSPKG_DB_TOPDIR}. 4641.9Sapb# This involves creating the subdirectory ${SYSPKG_DB_SUBDIR} 4651.9Sapb# and populating it with several files. 4661.9Sapb# 4671.9Sapbregister_syspkg () 4681.9Sapb{ 4691.9Sapb cleanup_must_delete_dbsubdir=true 4701.9Sapb [ -n "${SYSPKG_DB_SUBDIR}" ] || bomb 4711.9Sapb mkdir -p "${SYSPKG_DB_SUBDIR}" 4721.9Sapb 4731.9Sapb # 4741.9Sapb # Guess what versions of other packages to depend on. 4751.9Sapb # 4761.9Sapb # If we are using the OS version as part of the pkg 4771.9Sapb # version, then depend on any version ">=${osvers}". For 4781.9Sapb # example, etc-sys-etc-1.6ZI.0.20040206 might depend on 4791.9Sapb # base-sys-root>=1.6ZI. 4801.9Sapb # 4811.9Sapb # Failing that, depend on any version "-[0-9]*". 4821.9Sapb # 4831.9Sapb # XXX: We could extend the format of the "deps" file to carry 4841.9Sapb # this sort of information, so we wouldn't have to guess. 4851.9Sapb # 4861.9Sapb case "${t}" in 4871.9Sapb ${osvers}.*) depversion=">=${osvers}" ;; 4881.9Sapb *) depversion="-[0-9]*" ;; 4891.9Sapb esac 4901.9Sapb 4911.9Sapb # 4921.9Sapb # Add the dependencies. 4931.9Sapb # 4941.9Sapb # We always add a "@pkgdep" line for each prerequisite package. 4951.9Sapb # 4961.9Sapb # If the prerequisite pkg is already registered (as it should be 4971.9Sapb # if our caller is doing things in the right order), then we put 4981.9Sapb # its exact version number in a "@blddep" line. 4991.9Sapb # 5001.9Sapb ${AWK} '$1 ~ '/"${pkg}"/' { print $2 }' "${rundir}/deps" | ${SORT} | \ 5011.9Sapb while read depname ; do 5021.9Sapb # ${pkgdepglob} is a shell glob pattern that should match 5031.9Sapb # any version of a pkg. ${pkgdep} uses the special syntax 5041.9Sapb # for pkg dependencies, and is not usable as a shell 5051.9Sapb # glob pattern. 5061.9Sapb pkgdepglob="${depname}-[0-9]*" 5071.9Sapb pkgdep="${depname}${depversion}" 5081.9Sapb echo "@pkgdep ${pkgdep}" 5091.9Sapb blddep="$( cd "${SYSPKG_DB_TOPDIR}" && echo ${pkgdepglob} \ 5101.9Sapb || bomb )" 5111.9Sapb case "${blddep}" in 5121.9Sapb *\*) # pkgdepglob did not match anything 5131.9Sapb echo >&2 "${WARNING}${pkg} depends on '${pkgdep}' but there is no matching syspkg in ${SYSPKG_DB_TOPDIR}" 5141.9Sapb ;; 5151.9Sapb *\ *) # pkgdepglob matched more than once. 5161.9Sapb echo >&2 "${ERRWARN}${pkg} depends on '${pkgdep}' but there are multiple matching syspkgs in ${SYSPKG_DB_TOPDIR}" 5171.9Sapb ${force} || bomb 5181.9Sapb # If ${force} is set, then assume that the last 5191.9Sapb # match is the most recent. 5201.9Sapb # XXX: This might be wrong, because of 5211.9Sapb # differences between lexical sorting and 5221.9Sapb # numeric sorting. 5231.9Sapb lastmatch="${blddep##* }" 5241.9Sapb echo "@blddep ${lastmatch}" 5251.9Sapb ;; 5261.9Sapb *) # exactly one match. 5271.9Sapb # XXX: We ignore the possibility that the 5281.9Sapb # version we found via ${pkgdepglob} might not 5291.9Sapb # satisfy ${pkgdep}. We could conceivably use 5301.9Sapb # "pkg_admin pmatch" to check, but that's not a 5311.9Sapb # host tool so we can't assume that it will be 5321.9Sapb # available. 5331.9Sapb echo "@blddep ${blddep}" 5341.9Sapb ;; 5351.9Sapb esac 5361.9Sapb done >>"${PLIST}" 5371.9Sapb 5381.9Sapb # create the comment (should be one line) 5391.9Sapb comment="$( ${AWK} '$1 ~ '/"${pkg}"/' \ 5401.9Sapb { print substr($0, length($1) + 2) }' \ 5411.9Sapb "${rundir}/comments" )" 5421.9Sapb case "${comment}" in 5431.9Sapb "") echo >&2 "${WARNING}no comment for \"${pkg}\" (using placeholder)" 5441.9Sapb comment="System package for ${pkg}" 5451.9Sapb ;; 5461.9Sapb *"${nl}"*) 5471.9Sapb echo >&2 "${ERRWARN}multi-line comment for \"${pkg}\"" 5481.9Sapb ${force} || bomb 5491.9Sapb ;; 5501.9Sapb esac 5511.9Sapb echo "${comment}" > "${SYSPKG_DB_SUBDIR}/+COMMENT" 5521.1Sagc 5531.9Sapb # create the description (could be multiple lines) 5541.9Sapb descr="$( ${AWK} '$1 ~ '/"${pkg}"/' { 5551.9Sapb print substr($0, length($1) + 2) }' \ 5561.9Sapb "${rundir}/descrs" )" 5571.9Sapb case "${descr}" in 5581.9Sapb "") echo >&2 "${WARNING}no description for \"${pkg}\" (re-using comment)" 2>&1 5591.9Sapb descr="${comment}" 5601.9Sapb ;; 5611.9Sapb esac 5621.9Sapb echo "${descr}" > "${SYSPKG_DB_SUBDIR}/+DESC" 5631.9Sapb ${PRINTF} "\nHomepage:\nhttp://www.NetBSD.org/\n" >> "${SYSPKG_DB_SUBDIR}/+DESC" 5641.1Sagc 5651.9Sapb # create the build information 5661.9Sapb if [ x"${BUILD_INFO_CACHE}" = x ]; then 5671.9Sapb { 5681.9Sapb # These variables describe the build 5691.9Sapb # environment, not the target. 5701.9Sapb echo "OPSYS=$(${UNAME} -s)" 5711.9Sapb echo "OS_VERSION=$(${UNAME} -r)" 5721.9Sapb ${MAKE} -f- all <<EOF 5731.4Sdyoung.include <bsd.own.mk> 5741.4Sdyoungall: 5751.4Sdyoung @echo OBJECT_FMT=${OBJECT_FMT} 5761.4Sdyoung @echo MACHINE_ARCH=${MACHINE_ARCH} 5771.4Sdyoung @echo MACHINE_GNU_ARCH=${MACHINE_GNU_ARCH} 5781.4SdyoungEOF 5791.9Sapb # XXX: what's the point of reporting _PKGTOOLS_VER 5801.9Sapb # when we roll everything by hand without using 5811.9Sapb # the pkg tools? 5821.9Sapb echo "_PKGTOOLS_VER=$(${PKG_CREATE} -V)" 5831.9Sapb } > "${SYSPKG_DB_SUBDIR}/+BUILD_INFO" 5841.9Sapb else 5851.9Sapb cp "${BUILD_INFO_CACHE}" "${SYSPKG_DB_SUBDIR}/+BUILD_INFO" 5861.9Sapb fi 5871.9Sapb 5881.9Sapb # test for attributes 5891.9Sapb args="" 5901.9Sapb attrs="$( ${AWK} '$1 ~ '/"${pkg}"/' { \ 5911.9Sapb print substr($0, length($1) + 2) }' \ 5921.9Sapb "${rundir}/attrs" )" 5931.9Sapb for a in "${attrs}"; do 5941.9Sapb case "${attrs}" in 5951.9Sapb "") ;; 5961.9Sapb preserve) 5971.9Sapb echo "${pkg}-${t}" >"${SYSPKG_DB_SUBDIR}/+PRESERVE" 5981.9Sapb args="${args} -n ${SYSPKG_DB_SUBDIR}/+PRESERVE" 5991.9Sapb ;; 6001.9Sapb esac 6011.9Sapb done 6021.9Sapb 6031.9Sapb # 6041.9Sapb # Create ${SYSPKGSIR}/+CONTENTS from ${PLIST}, by adding an 6051.9Sapb # "@name" line and a lot of "@comment MD5:" lines. 6061.9Sapb # 6071.9Sapb { 6081.9Sapb rcsid='$NetBSD: regpkg,v 1.9 2006/01/04 14:14:35 apb Exp $' 6091.9Sapb utcdate="$( ${ENV_CMD} TZ=UTC LOCALE=C \ 6101.9Sapb ${DATE} '+%Y-%m-%d %H:%M' )" 6111.9Sapb user="${USER:-root}" 6121.9Sapb host="$( ${HOSTNAME} )" 6131.9Sapb echo "@name ${pkg}-${t}" 6141.9Sapb echo "@comment Packaged at ${utcdate} UTC by ${user}@${host}" 6151.9Sapb echo "@comment Packaged using ${prog} ${rcsid}" 6161.9Sapb # XXX: "option extract-in-place" might help to get 6171.9Sapb # pkg_add to create directories. 6181.9Sapb # XXX: no, it doesn't work. Yet another pkg_add bug. 6191.9Sapb ## echo "@option extract-in-place" 6201.9Sapb # Move the @pkgdep and @blddep lines up, so that 6211.9Sapb # they are easy to see when people do "less 6221.9Sapb # ${DESTDIR}/var/db/syspkg/*/+CONTENTS". 6231.9Sapb ${EGREP} '^(@pkgdep|@blddep)' "${PLIST}" || true 6241.9Sapb # Now do the remainder of the file. 6251.9Sapb while read line ; do 6261.9Sapb case "${line}" in 6271.9Sapb @pkgdep*|@blddep*) 6281.9Sapb # already handled by grep above 6291.9Sapb ;; 6301.9Sapb @cwd*) 6311.9Sapb # There should be exactly one @cwd line. 6321.9Sapb # Just after it, add an "@exec mkdir" 6331.9Sapb # line for every directory. This is to 6341.9Sapb # work around a pkg-add bug (see 6351.9Sapb # <http://mail-index.NetBSD.org/tech-pkg/2003/12/11/0018.html>) 6361.9Sapb echo "${line}" 6371.9Sapb print_dir_exec_lines 6381.9Sapb ;; 6391.9Sapb @*) 6401.9Sapb # just pass through all other @foo lines 6411.9Sapb echo "${line}" 6421.9Sapb ;; 6431.9Sapb *) 6441.9Sapb # This should be a file name. Pass it 6451.9Sapb # through, and append "@comment MD5:". 6461.9Sapb # XXX why not SHA256 ? 6471.9Sapb echo "${line}" 6481.9Sapb file="${DESTDIR}${line}" 6491.9Sapb if [ -f "${file}" -a -r "${file}" ]; 6501.9Sapb then 6511.9Sapb md5sum="$( ${CKSUM} -n -m "${file}" \ 6521.9Sapb | ${AWK} '{print $1}' 6531.9Sapb )" 6541.9Sapb echo "@comment MD5:${md5sum}" 6551.9Sapb fi 6561.9Sapb ;; 6571.9Sapb esac 6581.9Sapb done <"${PLIST}" 6591.9Sapb } >"${SYSPKG_DB_SUBDIR}/+CONTENTS" 6601.9Sapb 6611.9Sapb # 6621.9Sapb # Update ${SYSPKG_DB_TOPDIR}/pkgdb.byfile.db. 6631.9Sapb # 6641.9Sapb { 6651.9Sapb dbfile="${SYSPKG_DB_TOPDIR}/pkgdb.byfile.db" 6661.9Sapb dbtype="btree" 6671.9Sapb db_opts='' 6681.9Sapb # XXX: cross builds should really add "-E B" or "-E L" 6691.9Sapb # (big-endian or little-endian) to db_opts, but we don't 6701.9Sapb # do that yet. 6711.9Sapb if ${update} || ${force} ; then 6721.9Sapb # overwriting an existing entry is not an error 6731.9Sapb db_opts="${db_opts} -R" 6741.9Sapb fi 6751.9Sapb if [ ${verbosity} -lt 2 ]; then 6761.9Sapb # don't print all the keys added to the database 6771.9Sapb db_opts="${db_opts} -q" 6781.9Sapb fi 6791.9Sapb 6801.9Sapb # Transform ${PLIST} into a form to be used as keys in 6811.9Sapb # ${dbfile}. The results look like absolute paths, 6821.9Sapb # but they are really relative to ${DESTDIR}. 6831.9Sapb # 6841.9Sapb # "@dirrm ." -> "/" 6851.9Sapb # "@dirrm foo/bar" -> "/foo/bar" 6861.9Sapb # "@dirrm ./foo/bar" -> "/foo/bar" 6871.9Sapb # "foo/bar/baz" -> "/foo/bar/baz" 6881.9Sapb # "./foo/bar/baz" -> "/foo/bar/baz" 6891.9Sapb # 6901.9Sapb dblist="${SCRATCH}/dblist" 6911.9Sapb ${AWK} '/^@dirrm \.\// {gsub("^.", "", $2); print $2; next} 6921.9Sapb /^@dirrm \.$/ {print "/"; next} 6931.9Sapb /^@dirrm/ {print "/" $2; next} 6941.9Sapb /^@/ {next} 6951.9Sapb /^\.\// {gsub("^.", "", $0); print $0; next} 6961.9Sapb /./ {print "/" $0; next}' \ 6971.9Sapb <"${PLIST}" >"${dblist}" 6981.9Sapb # Add all the path names to the database. 6991.9Sapb ${AWK} '{print $1 "\t" "'"${pkg}-${t}"'"}' <"${dblist}" \ 7001.9Sapb | ${DB} -w ${db_opts} -F "${tab}" -f - "${dbtype}" "${dbfile}" 7011.9Sapb } 7021.9Sapb 7031.9Sapb if ${verbose} ; then 7041.9Sapb echo "Registered ${pkg}-${t} in ${SYSPKG_DB_TOPDIR}" 7051.9Sapb elif ! ${quiet} ; then 7061.9Sapb echo "Registered ${pkg}-${t}" 7071.9Sapb fi 7081.9Sapb 7091.9Sapb cleanup_must_delete_dbsubdir=false 7101.9Sapb} 7111.9Sapb 7121.9Sapb# 7131.9Sapb# create_syspkg_tgz() creates the *.tgz file for the package. 7141.9Sapb# 7151.9Sapb# The output file is ${binpkgdir}/${pkg}-${t}.tgz. 7161.9Sapb# 7171.9Sapbcreate_syspkg_tgz () 7181.9Sapb{ 7191.9Sapb # 7201.9Sapb # pkg_create does not understand metalog files, so we have to 7211.9Sapb # use pax directly. 7221.9Sapb # 7231.9Sapb # We create two specfiles: specfile_overhead describes the 7241.9Sapb # special files that are part of the package system's metadata 7251.9Sapb # (+CONTENTS, +COMMENT, +DESCR, and more); and specfile_payload 7261.9Sapb # describes the files and directories that we actually want as 7271.9Sapb # part of the package's payload. 7281.9Sapb # 7291.9Sapb # We then use the specfiles to create a compressed tarball that 7301.9Sapb # contains both the overhead files and the payload files. 7311.9Sapb # 7321.9Sapb # There's no trivial way to get a single pax run to do 7331.9Sapb # everything we want, so we run pax twice, with a different 7341.9Sapb # working directory and a different specfile each time. 7351.9Sapb # 7361.9Sapb # We could conceivably make clever use of pax's "-s" option to 7371.9Sapb # get what we want from a single pax run with a single (more 7381.9Sapb # complicated) specfile, but the extra trouble doesn't seem 7391.9Sapb # warranted. 7401.9Sapb # 7411.9Sapb cleanup_must_delete_binpkgfile=true 7421.9Sapb specfile_overhead="${SCRATCH}/spec_overhead" 7431.9Sapb specfile_payload="${SCRATCH}/spec_payload" 7441.9Sapb tarball_uncompressed="${SCRATCH}/tarball_uncompressed" 7451.9Sapb 7461.9Sapb # Create a specfile for all the overhead files (+CONTENTS and 7471.9Sapb # friends). 7481.9Sapb { 7491.9Sapb plusnames_first="${SCRATCH}/plusnames_first" 7501.9Sapb plusnames_rest="${SCRATCH}/plusnames_rest" 7511.9Sapb 7521.9Sapb # Ensure that the first few files are in the same order 7531.9Sapb # that "pkg_create" would have used, just in case anything 7541.9Sapb # depends on that. Other files in alphabetical order. 7551.9Sapb SHOULD_BE_FIRST="+CONTENTS +COMMENT +DESC" 7561.9Sapb ( 7571.9Sapb cd "${SYSPKG_DB_SUBDIR}" || bomb 7581.9Sapb for file in ${SHOULD_BE_FIRST}; do 7591.9Sapb [ -e "./${file}" ] && echo "${file}" 7601.9Sapb done >"${plusnames_first}" 7611.9Sapb ${LS} -1 | ${FGREP} -v -f "${plusnames_first}" \ 7621.9Sapb >"${plusnames_rest}" \ 7631.9Sapb || true 7641.9Sapb ) 7651.9Sapb 7661.9Sapb # Convert the file list to specfile format, and override the 7671.9Sapb # uid/gid/mode. 7681.9Sapb { 7691.9Sapb echo ". optional type=dir" 7701.9Sapb ${AWK} '{print "./" $0 " type=file uid=0 gid=0 mode=0444" 7711.9Sapb }' "${plusnames_first}" "${plusnames_rest}" 7721.9Sapb } >"${specfile_overhead}" 7731.9Sapb } 7741.9Sapb 7751.9Sapb # Create a specfile for the payload of the package. 7761.9Sapb { 7771.9Sapb spec1="${SCRATCH}/spec1" 7781.9Sapb spec2="${SCRATCH}/spec2" 7791.9Sapb 7801.9Sapb # Transform ${PLIST} into simple specfile format: 7811.9Sapb # 7821.9Sapb # "@dirrm ." -> "." 7831.9Sapb # "@dirrm foo/bar" -> "./foo/bar" 7841.9Sapb # "@dirrm ./foo/bar" -> "./foo/bar" 7851.9Sapb # "foo/bar/baz" -> "./foo/bar/baz" 7861.9Sapb # "./foo/bar/baz" -> "./foo/bar/baz" 7871.9Sapb # 7881.9Sapb # Ignores @cwd lines. This should be safe, given how 7891.9Sapb # makeplist works. 7901.9Sapb ${AWK} '/^@dirrm \.\// {print $2; next} 7911.9Sapb /^@dirrm \.$/ {print "."; next} 7921.9Sapb /^@dirrm/ {print "./" $2; next} 7931.9Sapb /^@/ {next} 7941.9Sapb /^\.\// {print $0; next} 7951.9Sapb /./ {print "./" $0; next}' \ 7961.9Sapb <"${PLIST}" >"${spec1}" 7971.9Sapb 7981.9Sapb # If metalog was specified, attributes from metalog override 7991.9Sapb # attributes in the file system. We also fake up an 8001.9Sapb # entry for the ./etc/mtree/set.${pkgset} file. 8011.9Sapb { 8021.9Sapb if [ -n "${metalog}" ]; then 8031.9Sapb ${AWK} -f "${rundir}/join.awk" \ 8041.9Sapb "${spec1}" "${metalog}" 8051.9Sapb ${AWK} -f "${rundir}/join.awk" \ 8061.9Sapb "${spec1}" /dev/stdin <<EOF 8071.9Sapb./etc/mtree/set.${pkgset} type=file mode=0444 uname=root gname=wheel 8081.9SapbEOF 8091.9Sapb else 8101.9Sapb cat "${spec1}" 8111.9Sapb fi 8121.9Sapb } >"${spec2}" 8131.9Sapb 8141.9Sapb # 8151.9Sapb # If a file or directory to was mentioned explicitly 8161.9Sapb # in ${PLIST} but not mentioned in ${metalog}, then the 8171.9Sapb # file or directory will not be mentioned in ${spec2}. 8181.9Sapb # This is an error, and means that the metalog was 8191.9Sapb # not built correctly. 8201.9Sapb # 8211.9Sapb if [ -n "${metalog}" ]; then 8221.9Sapb names1="${SCRATCH}/names1" 8231.9Sapb names2="${SCRATCH}/names2" 8241.9Sapb ${AWK} '{print $1}' <"${spec1}" | ${SORT} >"${names1}" 8251.9Sapb ${AWK} '{print $1}' <"${spec2}" | ${SORT} >"${names2}" 8261.9Sapb if ${FGREP} -v -f "${names2}" "${spec1}" >/dev/null 8271.9Sapb then 8281.9Sapb cat >&2 <<EOM 8291.9Sapb${ERRWARN}The metalog file (${metalog}) does not 8301.9Sapb contain entries for the following files or directories 8311.9Sapb which should be part of the ${pkg} syspkg: 8321.9SapbEOM 8331.9Sapb ${FGREP} -v -f "${names2}" "${spec1}" >&2 8341.9Sapb ${force} || bomb 8351.9Sapb fi 8361.9Sapb if ${FGREP} -v -f "${names1}" "${spec2}" >/dev/null 8371.9Sapb then 8381.9Sapb cat >&2 <<EOM 8391.9Sapb${ERRWARN}The following lines are in the metalog file 8401.9Sapb (${metalog}), and the corresponding files or directories 8411.9Sapb should be in the ${pkg} syspkg, but something is wrong: 8421.9SapbEOM 8431.9Sapb ${FGREP} -v -f "${names1}" "${spec2}" >&2 8441.9Sapb bomb 8451.9Sapb fi 8461.9Sapb fi 8471.9Sapb 8481.9Sapb # Add lines (tagged "optional") for any implicit directories. 8491.9Sapb # 8501.9Sapb # For example, if we have a file ./foo/bar/baz, then we add 8511.9Sapb # "./foo/bar optional type=dir", "./foo optional type=dir", 8521.9Sapb # and ". optional type=dir", unless those directories were 8531.9Sapb # already mentioned explicitly. 8541.9Sapb # 8551.9Sapb ${AWK} -f "${rundir}/getdirs.awk" "${spec2}" \ 8561.9Sapb | ${SORT} -u >"${specfile_payload}" 8571.9Sapb } 8581.9Sapb 8591.9Sapb # Use two pax invocations followed by gzip to create 8601.9Sapb # the tgz file. 8611.9Sapb # 8621.9Sapb # Remove any leading "./" from path names, because that 8631.9Sapb # could confuse tools that work with binary packages. 8641.9Sapb ( 8651.9Sapb cd "${SYSPKG_DB_SUBDIR}" && \ 8661.9Sapb ${PAX} -O -w -d -N"${etcdir}" -M '-s,^\./,,' \ 8671.9Sapb -f "${tarball_uncompressed}" \ 8681.9Sapb <"${specfile_overhead}" \ 8691.9Sapb || bomb 8701.9Sapb ) 8711.9Sapb ( 8721.9Sapb cd "${DESTDIR:-/}" && \ 8731.9Sapb ${PAX} -O -w -d -N"${etcdir}" -M '-s,^\./,,' \ 8741.9Sapb -a -f "${tarball_uncompressed}" \ 8751.9Sapb <"${specfile_payload}" \ 8761.9Sapb || bomb 8771.9Sapb ) 8781.9Sapb ${GZIP_CMD} -9 <"${tarball_uncompressed}" >"${binpkgfile}" || bomb 8791.9Sapb 8801.9Sapb # (Extra space is to make message line up with "Registered" message.) 8811.9Sapb if ${verbose} ; then 8821.9Sapb echo " Packaged ${binpkgfile}" 8831.9Sapb elif ! ${quiet} ; then 8841.9Sapb echo " Packaged ${binpkgfile##*/}" 8851.9Sapb fi 8861.9Sapb 8871.9Sapb cleanup_must_delete_binpkgfile=false 8881.9Sapb 8891.9Sapb} 8901.9Sapb 8911.9Sapb# 8921.9Sapb# do_register_syspkg() registers the syspkg if appropriate. 8931.9Sapb# 8941.9Sapb# If SYSPKG_DB_SUBDIR already exists, that might be an error, depending 8951.9Sapb# on ${force} and ${update} flags. 8961.9Sapb# 8971.9Sapbdo_register_syspkg () 8981.9Sapb{ 8991.9Sapb # Check that necessary variables are defined 9001.9Sapb [ -n "${SYSPKG_DB_TOPDIR}" ] || bomb 9011.9Sapb [ -n "${SYSPKG_DB_SUBDIR}" ] || bomb 9021.9Sapb 9031.9Sapb # Create SYSPKG_DB_TOPDIR if necessary 9041.9Sapb [ -d "${SYSPKG_DB_TOPDIR}" ] || mkdir -p "${SYSPKG_DB_TOPDIR}" || bomb 9051.9Sapb 9061.9Sapb # A function to delete and re-register a syspkg 9071.9Sapb delete_and_reregister () 9081.9Sapb { 9091.9Sapb echo >&2 "${ERRWARNNOTE}deleting and re-registering ${pkg}-${t}" 9101.9Sapb cleanup_must_delete_dbsubdir=true 9111.9Sapb rm -rf "${SYSPKG_DB_SUBDIR}" 9121.9Sapb register_syspkg 9131.9Sapb } 9141.9Sapb 9151.9Sapb # Check whether another version of ${pkg} is already registered. 9161.9Sapb pattern="${pkg}-[0-9]*" 9171.9Sapb matches="$( cd "${SYSPKG_DB_TOPDIR}" && echo ${pattern} || bomb )" 9181.9Sapb case "${matches}" in 9191.9Sapb *\*) ;; # wildcard did not match anything 9201.9Sapb "${pkg}-${t}") ;; # exact match 9211.9Sapb *) echo >&2 "${ERRWARN}another version of ${pkg} is already registered in ${SYSPKG_DB_TOPDIR} (while creating ${pkg}-${t})" 9221.9Sapb ${force} || bomb 9231.9Sapb ;; 9241.9Sapb esac 9251.9Sapb 9261.9Sapb # Check whether the desired version of ${pkg} is already registered, 9271.9Sapb # and create it if appropriate. 9281.9Sapb if [ -d "${SYSPKG_DB_SUBDIR}" ]; then 9291.9Sapb echo >&2 "${ERRWARNNOTE}${pkg}-${t} is already registered" 9301.9Sapb ${verbose} && echo >&2 " in ${SYSPKG_DB_TOPDIR}" 9311.9Sapb if ${force}; then 9321.9Sapb delete_and_reregister 9331.9Sapb elif ${update}; then 9341.9Sapb # 9351.9Sapb # If all files in SYSPKG_DB_SUBDIR are newer 9361.9Sapb # than all files in the pkg, then do nothing. 9371.9Sapb # Else delete and re-register the pkg. 9381.9Sapb # 9391.9Sapb [ -n "${newestfile}" ] || init_newestfile 9401.9Sapb if [ -n "${newestfile}" ]; then 9411.9Sapb case "$( ${FIND} "${SYSPKG_DB_SUBDIR}" -type f \ 9421.9Sapb ! -newer "${newestfile}" -print )" \ 9431.9Sapb in 9441.9Sapb "") ;; 9451.9Sapb *) delete_and_reregister ;; 9461.9Sapb esac 9471.9Sapb 9481.9Sapb else 9491.9Sapb # No files in the pkg? (This could happen 9501.9Sapb # if a pkg contains only directories.) 9511.9Sapb # Do nothing. 9521.9Sapb fi 9531.9Sapb else 9541.9Sapb bomb 9551.9Sapb fi 9561.9Sapb else 9571.9Sapb register_syspkg 9581.9Sapb fi 9591.9Sapb} 9601.9Sapb 9611.9Sapb# 9621.9Sapb# do_create_syspkg_tgz() creates the the binary pkg (*.tgz) if 9631.9Sapb# appropriate. 9641.9Sapb# 9651.9Sapb# If binpkgfile already exists, that might be an error, depending on 9661.9Sapb# ${force} and ${update} flags. 9671.9Sapb# 9681.9Sapbdo_create_syspkg_tgz () 9691.9Sapb{ 9701.9Sapb [ -n "${binpkgfile}" ] || bomb 9711.9Sapb 9721.9Sapb delete_and_recreate () 9731.9Sapb { 9741.9Sapb echo >&2 "${ERRWARNNOTE}deleting and re-creating ${pkg}-${t}.tgz" 9751.9Sapb rm -f "${binpkgfile}" 9761.9Sapb create_syspkg_tgz 9771.9Sapb } 9781.9Sapb 9791.9Sapb # Check whether another version of ${pkg} already exists. 9801.9Sapb pattern="${pkg}-[0-9]*" 9811.9Sapb matches="$( cd "${binpkgdir}" && echo ${pattern} || bomb )" 9821.9Sapb case "${matches}" in 9831.9Sapb *\*) ;; # wildcard did not match anything 9841.9Sapb "${pkg}-${t}.tgz") ;; # exact match 9851.9Sapb *) echo >&2 "${ERRWARN}another version of ${pkg} already exists in ${binpkgdir} (while creating ${pkg}-${t}.tgz)" 9861.9Sapb ${force} || bomb 9871.9Sapb ;; 9881.9Sapb esac 9891.9Sapb 9901.9Sapb # Check whether the desired version of ${pkg} already exists, 9911.9Sapb # and create it if appropriate. 9921.9Sapb if [ -e "${binpkgfile}" ]; then 9931.9Sapb echo >&2 "${ERRWARNNOTE}${pkg}-${t}.tgz already exists" 9941.9Sapb ${verbose} && echo >&2 " in ${binpkgdir}" 9951.9Sapb if ${force}; then 9961.9Sapb delete_and_recreate 9971.9Sapb elif ${update}; then 9981.9Sapb # 9991.9Sapb # If all files in SYSPKG_DB_SUBDIR are older 10001.9Sapb # than ${binpkgfile}, then do nothing. 10011.9Sapb # Else delete and re-create the tgz. 10021.9Sapb # 10031.9Sapb case "$( ${FIND} "${SYSPKG_DB_SUBDIR}" -type f \ 10041.9Sapb -newer "${binpkgfile}" -print )" \ 10051.9Sapb in 10061.9Sapb "") ;; 10071.9Sapb *) delete_and_recreate ;; 10081.9Sapb esac 10091.9Sapb else 10101.9Sapb bomb 10111.9Sapb fi 10121.9Sapb else 10131.9Sapb create_syspkg_tgz 10141.9Sapb fi 10151.9Sapb} 10161.9Sapb 10171.9Sapb#################### 10181.9Sapb# begin main program 10191.9Sapb 10201.9Sapbparse_args ${1+"$@"} 10211.9Sapbmake_PLIST 10221.9Sapbchoose_version_number 10231.9SapbSYSPKG_DB_SUBDIR="${SYSPKG_DB_TOPDIR}/${pkg}-${t}" 10241.9Sapbdo_register_syspkg 10251.9Sapbif [ -n "${binpkgdir}" ]; then 10261.9Sapb binpkgfile="${binpkgdir}/${pkg}-${t}.tgz" 10271.9Sapb do_create_syspkg_tgz 10281.5Sdyoungfi 10291.1Sagc 10301.9Sapbexit 0 1031