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