11.1Sdyoung#!/bin/sh 21.1Sdyoung# 31.1Sdyoung# syspkgdeps [-a arch] [-m machine] [-s setsdir] [-p prefix] sets 41.1Sdyoung# 51.1Sdyoung# Compute naive package dependencies based on file & directory 61.1Sdyoung# nesting. E.g., if pkg P contains /foo/bar and Q contains /foo, 71.1Sdyoung# then Q is considered a dependency of P. 81.1Sdyoung# 91.12Sapb# Each line of output contains two syspkg names, 101.12Sapb# where the first syspkg depends on the second syspkg. 111.12Sapb# 121.1Sdyoung 131.1Sdyoung#set -u 141.1Sdyoung 151.10Sapbprog="${0##*/}" 161.7Sapbrundir="$(dirname "$0")" # ${0%/*} isn't good enough when there's no "/" 171.7Sapb. "${rundir}/sets.subr" 181.7Sapb 191.10Sapb# 201.10Sapb# set defaults 211.10Sapb# 221.10Sapbprefix=/ 231.1Sdyoung 241.3Slukemusage() 251.3Slukem{ 261.3Slukem cat 1>&2 <<USAGE 271.3SlukemUsage: ${0##*/} [-a arch] [-m machine] [-s setsdir] [-p prefix] setname [...] 281.9Sapb -a arch set arch (e.g, m68k, mips, powerpc) [${MACHINE_ARCH}] 291.9Sapb -m machine set machine (e.g, amiga, i386, macppc) [${MACHINE}] 301.9Sapb -s setsdir directory to find sets [${setsdir}] 311.9Sapb -p prefix prefix for created plist [${prefix}] 321.3Slukem setname [...] sets to find dependencies for 331.3SlukemUSAGE 341.3Slukem exit 1 351.1Sdyoung} 361.1Sdyoung 371.1Sdyoung# parse arguments 381.10Sapbwhile getopts a:m:p:s: ch; do 391.3Slukem case ${ch} in 401.3Slukem a) 411.9Sapb MACHINE_ARCH="${OPTARG}" 421.9Sapb MACHINE_CPU="$(arch_to_cpu "${OPTARG}")" 431.1Sdyoung ;; 441.3Slukem m) 451.9Sapb MACHINE="${OPTARG}" 461.1Sdyoung ;; 471.3Slukem p) 481.9Sapb prefix="${OPTARG}" 491.1Sdyoung ;; 501.3Slukem s) 511.9Sapb setsdir="${OPTARG}" 521.1Sdyoung ;; 531.3Slukem *) 541.1Sdyoung usage 551.1Sdyoung ;; 561.1Sdyoung esac 571.1Sdyoungdone 581.3Slukemshift $((${OPTIND} - 1)) 591.1Sdyoungif [ $# -lt 1 ]; then 601.1Sdyoung usage 611.1Sdyoungfi 621.1Sdyoung 631.9Sapbsets="$*" 641.10Sapbcase "${sets}" in 651.10Sapball) sets="${nlists}" ;; 661.10Sapbesac 671.1Sdyoung 681.1Sdyoung# TBD clean up 691.10SapbSCRATCH="$(${MKTEMP} -d "/var/tmp/${prog}.XXXXXX")" 701.1Sdyoung 711.11Sapbif [ $? -ne 0 ]; then 721.11Sapb echo >&2 "${prog}: Could not create scratch directory." 731.11Sapb exit 1 741.11Sapbfi 751.1Sdyoung 761.9SapbPATH_MEMBERSHIP="${SCRATCH}/path-membership" 771.9SapbPATH_TO_PKGNAME="${SCRATCH}/pathpkg.db" 781.9SapbPARENT_PKGNAMES="${SCRATCH}/parent-pkgnames" 791.9SapbPARENT_PATHNAMES="${SCRATCH}/parent-pathnames" 801.1Sdyoung 811.11Sapbecho >&2 "${prog}: indexing packages by pathnames" 821.1Sdyoung 831.9Sapblist_set_files ${sets} | ${SED} 's/^\.\///' | \ 841.9Sapb${ENV_CMD} PREFIX="${prefix}" ${AWK} '{ 851.1Sdyoung if ($1 == ".") { 861.1Sdyoung print ENVIRON["PREFIX"] " " $2; 871.1Sdyoung } else { 881.1Sdyoung print ENVIRON["PREFIX"] $1 " " $2; 891.1Sdyoung } 901.9Sapb}' | ${SORT} -k 1 -u > "${PATH_MEMBERSHIP}" 911.1Sdyoung 921.11Sapb${DB} -q -w -f - btree "${PATH_TO_PKGNAME}" < "${PATH_MEMBERSHIP}" 931.11Sapb 941.11Sapbif [ $? -ne 0 ]; then 951.11Sapb echo >&2 "${prog}: error creating database, aborting" 961.11Sapb exit 1 971.11Sapbfi 981.1Sdyoung 991.11Sapbecho >&2 "${prog}: computing parent pathnames" 1001.1Sdyoung 1011.1Sdyoungwhile read pathname pkgname; do 1021.10Sapb # print parent pathname. 1031.10Sapb # (This uses a cheap implementation of dirname from sets.subr.) 1041.10Sapb dirname "${pathname}" 1051.9Sapbdone < "${PATH_MEMBERSHIP}" > "${PARENT_PATHNAMES}" 1061.1Sdyoung 1071.11Sapbecho >&2 "${prog}: selecting parent packages using parent pathnames" 1081.1Sdyoung 1091.9Sapb${DB} -q -f - btree "${PATH_TO_PKGNAME}" < "${PARENT_PATHNAMES}" | \ 1101.9Sapb ${PASTE} "${PATH_MEMBERSHIP}" - | \ 1111.8Sapb ${AWK} '{ if ($2 != $4) print $2 " " $4; }' | \ 1121.13Sapb ${SORT} -u > "${SCRATCH}/alldeps" 1131.1Sdyoung 1141.1Sdyoungif [ $? -ne 0 ]; then 1151.11Sapb echo >&2 "${prog}: error in parent-directory lookup, aborting" 1161.1Sdyoung exit 1 1171.1Sdyoungfi 1181.13Sapb 1191.14Sapbecho >&2 "${prog}: checking for cyclic dependencies" 1201.13Sapb 1211.15Sapbtsort_errors="$(${TSORT} < "${SCRATCH}/alldeps" 2>&1 >/dev/null)" 1221.13Sapb 1231.13Sapbif [ -n "${tsort_errors}" ]; then 1241.13Sapb # Errors from tsort are usually to do with cyclic dependencies. 1251.13Sapb # The most likely underlying cause is that /foo and /foo/bar/baz 1261.13Sapb # are in syspkg A, but /foo/bar is in syspkg B. 1271.14Sapb echo >&2 "${tsort_errors}" # this is likely to be multiple lines 1281.14Sapb echo >&2 "${prog}: Above messages probably indicate an error in the lists" 1291.13Sapb exit 1 1301.13Sapbfi 1311.13Sapb 1321.14Sapbecho >&2 "${prog}: removing redundant dependencies" 1331.13Sapb 1341.13Sapb${HOST_SH} "${rundir}/culldeps" < "${SCRATCH}/alldeps" 1351.13Sapb 1361.13Sapbif [ $? -ne 0 ]; then 1371.14Sapb echo >&2 "${prog}: error in culldeps, aborting" 1381.13Sapb exit 1 1391.13Sapbfi 140