1 1.1 dyoung #!/bin/sh 2 1.1 dyoung # 3 1.1 dyoung # syspkgdeps [-a arch] [-m machine] [-s setsdir] [-p prefix] sets 4 1.1 dyoung # 5 1.1 dyoung # Compute naive package dependencies based on file & directory 6 1.1 dyoung # nesting. E.g., if pkg P contains /foo/bar and Q contains /foo, 7 1.1 dyoung # then Q is considered a dependency of P. 8 1.1 dyoung # 9 1.12 apb # Each line of output contains two syspkg names, 10 1.12 apb # where the first syspkg depends on the second syspkg. 11 1.12 apb # 12 1.1 dyoung 13 1.1 dyoung #set -u 14 1.1 dyoung 15 1.10 apb prog="${0##*/}" 16 1.7 apb rundir="$(dirname "$0")" # ${0%/*} isn't good enough when there's no "/" 17 1.7 apb . "${rundir}/sets.subr" 18 1.7 apb 19 1.10 apb # 20 1.10 apb # set defaults 21 1.10 apb # 22 1.10 apb prefix=/ 23 1.1 dyoung 24 1.3 lukem usage() 25 1.3 lukem { 26 1.3 lukem cat 1>&2 <<USAGE 27 1.3 lukem Usage: ${0##*/} [-a arch] [-m machine] [-s setsdir] [-p prefix] setname [...] 28 1.9 apb -a arch set arch (e.g, m68k, mips, powerpc) [${MACHINE_ARCH}] 29 1.9 apb -m machine set machine (e.g, amiga, i386, macppc) [${MACHINE}] 30 1.9 apb -s setsdir directory to find sets [${setsdir}] 31 1.9 apb -p prefix prefix for created plist [${prefix}] 32 1.3 lukem setname [...] sets to find dependencies for 33 1.3 lukem USAGE 34 1.3 lukem exit 1 35 1.1 dyoung } 36 1.1 dyoung 37 1.1 dyoung # parse arguments 38 1.10 apb while getopts a:m:p:s: ch; do 39 1.3 lukem case ${ch} in 40 1.3 lukem a) 41 1.9 apb MACHINE_ARCH="${OPTARG}" 42 1.9 apb MACHINE_CPU="$(arch_to_cpu "${OPTARG}")" 43 1.1 dyoung ;; 44 1.3 lukem m) 45 1.9 apb MACHINE="${OPTARG}" 46 1.1 dyoung ;; 47 1.3 lukem p) 48 1.9 apb prefix="${OPTARG}" 49 1.1 dyoung ;; 50 1.3 lukem s) 51 1.9 apb setsdir="${OPTARG}" 52 1.1 dyoung ;; 53 1.3 lukem *) 54 1.1 dyoung usage 55 1.1 dyoung ;; 56 1.1 dyoung esac 57 1.1 dyoung done 58 1.3 lukem shift $((${OPTIND} - 1)) 59 1.1 dyoung if [ $# -lt 1 ]; then 60 1.1 dyoung usage 61 1.1 dyoung fi 62 1.1 dyoung 63 1.9 apb sets="$*" 64 1.10 apb case "${sets}" in 65 1.10 apb all) sets="${nlists}" ;; 66 1.10 apb esac 67 1.1 dyoung 68 1.1 dyoung # TBD clean up 69 1.10 apb SCRATCH="$(${MKTEMP} -d "/var/tmp/${prog}.XXXXXX")" 70 1.1 dyoung 71 1.11 apb if [ $? -ne 0 ]; then 72 1.11 apb echo >&2 "${prog}: Could not create scratch directory." 73 1.11 apb exit 1 74 1.11 apb fi 75 1.1 dyoung 76 1.9 apb PATH_MEMBERSHIP="${SCRATCH}/path-membership" 77 1.9 apb PATH_TO_PKGNAME="${SCRATCH}/pathpkg.db" 78 1.9 apb PARENT_PKGNAMES="${SCRATCH}/parent-pkgnames" 79 1.9 apb PARENT_PATHNAMES="${SCRATCH}/parent-pathnames" 80 1.1 dyoung 81 1.11 apb echo >&2 "${prog}: indexing packages by pathnames" 82 1.1 dyoung 83 1.9 apb list_set_files ${sets} | ${SED} 's/^\.\///' | \ 84 1.9 apb ${ENV_CMD} PREFIX="${prefix}" ${AWK} '{ 85 1.1 dyoung if ($1 == ".") { 86 1.1 dyoung print ENVIRON["PREFIX"] " " $2; 87 1.1 dyoung } else { 88 1.1 dyoung print ENVIRON["PREFIX"] $1 " " $2; 89 1.1 dyoung } 90 1.9 apb }' | ${SORT} -k 1 -u > "${PATH_MEMBERSHIP}" 91 1.1 dyoung 92 1.11 apb ${DB} -q -w -f - btree "${PATH_TO_PKGNAME}" < "${PATH_MEMBERSHIP}" 93 1.11 apb 94 1.11 apb if [ $? -ne 0 ]; then 95 1.11 apb echo >&2 "${prog}: error creating database, aborting" 96 1.11 apb exit 1 97 1.11 apb fi 98 1.1 dyoung 99 1.11 apb echo >&2 "${prog}: computing parent pathnames" 100 1.1 dyoung 101 1.1 dyoung while read pathname pkgname; do 102 1.10 apb # print parent pathname. 103 1.10 apb # (This uses a cheap implementation of dirname from sets.subr.) 104 1.10 apb dirname "${pathname}" 105 1.9 apb done < "${PATH_MEMBERSHIP}" > "${PARENT_PATHNAMES}" 106 1.1 dyoung 107 1.11 apb echo >&2 "${prog}: selecting parent packages using parent pathnames" 108 1.1 dyoung 109 1.9 apb ${DB} -q -f - btree "${PATH_TO_PKGNAME}" < "${PARENT_PATHNAMES}" | \ 110 1.9 apb ${PASTE} "${PATH_MEMBERSHIP}" - | \ 111 1.8 apb ${AWK} '{ if ($2 != $4) print $2 " " $4; }' | \ 112 1.13 apb ${SORT} -u > "${SCRATCH}/alldeps" 113 1.1 dyoung 114 1.1 dyoung if [ $? -ne 0 ]; then 115 1.11 apb echo >&2 "${prog}: error in parent-directory lookup, aborting" 116 1.1 dyoung exit 1 117 1.1 dyoung fi 118 1.13 apb 119 1.14 apb echo >&2 "${prog}: checking for cyclic dependencies" 120 1.13 apb 121 1.15 apb tsort_errors="$(${TSORT} < "${SCRATCH}/alldeps" 2>&1 >/dev/null)" 122 1.13 apb 123 1.13 apb if [ -n "${tsort_errors}" ]; then 124 1.13 apb # Errors from tsort are usually to do with cyclic dependencies. 125 1.13 apb # The most likely underlying cause is that /foo and /foo/bar/baz 126 1.13 apb # are in syspkg A, but /foo/bar is in syspkg B. 127 1.14 apb echo >&2 "${tsort_errors}" # this is likely to be multiple lines 128 1.14 apb echo >&2 "${prog}: Above messages probably indicate an error in the lists" 129 1.13 apb exit 1 130 1.13 apb fi 131 1.13 apb 132 1.14 apb echo >&2 "${prog}: removing redundant dependencies" 133 1.13 apb 134 1.13 apb ${HOST_SH} "${rundir}/culldeps" < "${SCRATCH}/alldeps" 135 1.13 apb 136 1.13 apb if [ $? -ne 0 ]; then 137 1.14 apb echo >&2 "${prog}: error in culldeps, aborting" 138 1.13 apb exit 1 139 1.13 apb fi 140