#!/usr/bin/gawk -f
# Find providers of libraries that are dynamically linked to a port's /usr/lib 
#  and /usr/bin files, by looking at the output of ldd
#
# based on the bash script by Johannes Winkelmann
# gawk stuff by Juergen Daubert and John McQuah

BEGIN {
 if (ARGV[1] ~ /^-/ || ARGC < 1) {
     print ("\n usage: " ARGV[0] " <port>\n") > "/dev/stderr"
     exit 0
 } else PORT = ARGV[1]

 ENVIRON["LD_LIBRARY_PATH"] = ("/lib:/usr/lib:/lib32:/usr/lib32:" ENVIRON["LD_LIBRARY_PATH"])
 PKGDB = "/var/lib/pkg/db"
 isInst = 0
 RS = ""
 while ((getline < PKGDB) > 0 && isInst == 0) {
   if ($1 == PORT) { isInst=1; for(i=2; i<=NF; ++i) { if ($i ~ /(sbin|bin|lib|lib32)\//) BinFiles[$i] } }
 }
 close(PKGDB)

 if (isInst == 0) { print (PORT " not installed.\n") > "/dev/stderr"; exit 1 }

 # reset the record separator to accommodate the output of ldd
 RS="\n"
 for (b in BinFiles) {
     LDDCMD = ("/usr/bin/ldd \"/" b "\" 2>/dev/null")
     while ((LDDCMD | getline) > 0) { if (!/(linux-gate)|(dynamic)|(not found)/) Deps[$(NF-1)] }
     close(LDDCMD)
 }

 if (typeof(Deps) == "array") {
     RP_CMD = "/usr/bin/realpath"
 } else {
     print (PORT " has no dynamically-linked binaries.\n")
     exit 0
 }

 # assemble the complete set of args passed to realpath
 for (d in Deps) { RP_CMD=(RP_CMD " " d) }

 # chop off the first character, as PKGDB does not list files with the leading /
 while ( (RP_CMD|getline) > 0 ) { rDeps[substr($0,2)] }
 close(RP_CMD)

 # reset the record separator to scan PKGDB more rapidly,
 # then look for any ports that provide the dynamically-linked libraries
 RS=""
 while ((getline < PKGDB) > 0) {
   if ($1 != PORT) {
       split($0,files,/\n/)
       for (f in files) { if (files[f] in rDeps) { printDep[$1]; break; } }
   }
 }
 close(PKGDB)

 # reset the record separator to accommodate the output of prt-get
 RS="\n"
 PRTGET="prt-get printf '%n (%p)\n'"
 while ((PRTGET|getline) > 0) {
    if ($1 in printDep) { gsub(/\(.*\//,"(",$2); print }
 }

 # post-process with `sort -k 2` if desired
}
