188 lines
4.8 KiB
Bash
188 lines
4.8 KiB
Bash
#! /usr/bin/ksh
|
|
|
|
# Original Author: Tim Mooney <mooney@golem.phys.ndsu.NoDak.edu>
|
|
#
|
|
# This file is distributed under the terms of the GNU Public License
|
|
#
|
|
# find-provides is part of RPM, the Red Hat Package Manager. find-provides
|
|
# reads a list of full pathnames (in a package) on stdin, and outputs all
|
|
# shared libraries provided by (contained in) the package.
|
|
#
|
|
#
|
|
# On Digital/Tru64 Unix (OSF1), use `odump -D' to find what libraries a
|
|
# package provides. Note that Tru64 Unix 5.x and later come with `ldd',
|
|
# but sticking with `odump' works with versions of the OS back to at least
|
|
# 3.x, so it's the preferred method.
|
|
#
|
|
# Example `odump -D' output:
|
|
#
|
|
#$odump -D /usr/shlib/libc.so
|
|
#
|
|
#
|
|
#
|
|
#
|
|
# ***DYNAMIC SECTION***
|
|
# Tag Value
|
|
#
|
|
#/usr/shlib/libc.so:
|
|
# UNREFEXTNO: 14.
|
|
# LOCAL_GOTNO: 521.
|
|
# GOTSYM: 2205.
|
|
# LOCAL_GOTNO: 1606.
|
|
# GOTSYM: 3289.
|
|
# SONAME: libc.so
|
|
# TIME_STAMP: (0x34a82daa) Mon Dec 29 17:09:30 1997
|
|
#
|
|
# ICHECKSUM: 0x5e955f9b
|
|
# IVERSION: osf.1
|
|
# CONFLICTNO: 0.
|
|
# RLD_VERSION: 2.
|
|
# HASH: 0x000003ff800a82e0
|
|
# STRTAB: 0x000003ff8008aad0
|
|
# SYMTAB: 0x000003ff80094ab0
|
|
# MSYM: 0x000003ff800842c0
|
|
# STRSZ: 40922.
|
|
# SYMENT: 24.
|
|
# PLTGOT: 0x000003ffc008f240
|
|
# SYMTABNO: 3330.
|
|
# BASE_ADDRESS: 0x000003ff80080000
|
|
# HIPAGENO: 0.
|
|
# RELSZ: 15296.
|
|
# RELENT: 16.
|
|
# REL: 0x000003ff80080700
|
|
# LIBLISTNO: 0.
|
|
# INIT: 0x000003ff8019c520
|
|
# FINI: 0x000003ff8019c570
|
|
# FLAGS: 0x00000001
|
|
#
|
|
|
|
PATH=/usr/bin:/usr/sbin:/sbin:/usr/ccs/bin
|
|
export PATH
|
|
|
|
#
|
|
# TVM: Marc Stephenson (marc@austin.ibm.com) points out we run things
|
|
# like `file', et. al. and expect the output to be what we see in the
|
|
# C/POSIX locale. Make sure it is so.
|
|
#
|
|
LANG=C
|
|
export LANG
|
|
|
|
#
|
|
# Use `while read ...' instead of a `for f in ...', because there may
|
|
# be too many files to stuff into one shell variable.
|
|
#
|
|
IFS=""
|
|
while read f
|
|
do
|
|
|
|
#
|
|
# if it's a shared library, run odump on it.
|
|
#
|
|
maybe_shared_lib=`file $f | egrep 'COFF.*shared library'`
|
|
if test X"$maybe_shared_lib" != X ; then
|
|
odump -D $f 2>/dev/null | awk '
|
|
|
|
BEGIN {
|
|
FS = " ";
|
|
RS = "\n";
|
|
OFS = "";
|
|
|
|
found_soname = 0;
|
|
found_iversion = 0;
|
|
|
|
}
|
|
|
|
# Uncomment the next line for some debugging info.
|
|
#{ print NR , ":", $0 }
|
|
|
|
/^[ ]+SONAME: .*[ ]*$/ {
|
|
found_soname = 1;
|
|
numfields = split($0, internal_name)
|
|
if (numfields == 2) {
|
|
soname = $2
|
|
#
|
|
# we should probably check to see if the soname ends with
|
|
# a number (indicating that it contains versioning info,
|
|
# possibly in addition to the versioning info in the
|
|
# versions field) and generate a warning here. Shared
|
|
# libraries should not be built with version info in
|
|
# the soname on Digital/Tru64 Unix.
|
|
#
|
|
} else {
|
|
#
|
|
# Should never be here.
|
|
#
|
|
print "Really odd looking soname:", $0 | "cat 1>&2"
|
|
exit
|
|
}
|
|
}
|
|
|
|
/^[ ]+IVERSION: .*[ ]*$/ {
|
|
if (found_soname == 1) {
|
|
numfields = split($0, iversion)
|
|
if (numfields == 2) {
|
|
version = $2
|
|
#
|
|
# handle libraries with multiple versions, like
|
|
# 1.1:1.2. Since they really provide both versions,
|
|
# we need to generate output for each version.
|
|
#
|
|
numfields = split(version, versions, ":")
|
|
if (numfields > 1) {
|
|
for (i = 1; i < numfields; i++) {
|
|
print soname, "(", versions[i], ")"
|
|
}
|
|
#
|
|
# let our END routine print out the *last* version
|
|
# provided
|
|
#
|
|
version = versions[numfields]
|
|
}
|
|
#
|
|
# stick a fork in us.
|
|
#
|
|
found_iversion = 1;
|
|
exit
|
|
} else {
|
|
#
|
|
# Should never be here.
|
|
#
|
|
print "Odd looking library version:", $0 | "cat 1>&2"
|
|
exit
|
|
}
|
|
} else {
|
|
#
|
|
# found an iversion without an soname. Is that possible?
|
|
#
|
|
print "Found version but no soname:", $0 | "cat 1>&2"
|
|
exit
|
|
}
|
|
}
|
|
|
|
#
|
|
# we could probably watch for some other token (like RLD_VERSION)
|
|
# that *generally* occurs later in the input than the stuff we watch
|
|
# for, and exit if we see it, but it is just as easy to read all
|
|
# the output, even after we have seen what we are looking for.
|
|
#
|
|
|
|
END {
|
|
# Uncomment the next line for debugging info
|
|
#{ print "END: NR: ", NR }
|
|
if ( (found_soname == 1) && (found_iversion == 1) ) {
|
|
print soname, "(", version, ")"
|
|
exit
|
|
} else if (found_soname == 1) {
|
|
#
|
|
# no library version information
|
|
#
|
|
print soname
|
|
}
|
|
# else do nothing
|
|
}
|
|
' # end of awk
|
|
fi
|
|
done | sort -u
|
|
#comment out the previous line and uncomment the next line when debugging
|
|
#done
|