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