#! /usr/bin/ksh

# Original Author: Tim Mooney <mooney@golem.phys.ndsu.NoDak.edu>
# $Id: hpux.prov,v 1.8 2001/09/15 13:49:11 jbj Exp $
#
# 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 HP-UX, use `chatr' to find what libraries a package provides
#
# Example chatr output:
#
#$chatr /usr/lib/libc.sl
#
#/usr/lib/libc.sl: 
#         shared library 
#         shared library dynamic path search:
#             SHLIB_PATH     disabled  second 
#             embedded path  disabled  first  Not Defined
#         internal name:
#             libc.1
#         shared library list:
#             dynamic   /usr/lib/libdld.1
#         static branch prediction disabled
#         kernel assisted branch predictionenabled
#         lazy swap allocationdisabled
#         text segment lockingdisabled
#         data segment lockingdisabled
#         data page size: 4K
#         instruction page size: 4K
#

#
# Implementation notes: some of the system libraries are built without an
# `internal name' (HP-UX's equivalent to a SONAME), so I need to track what
# chatr outputs as its first line.  We'll use the basename of that line in
# the event of no internal name.
#

PATH=/usr/bin:/usr/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

#
# TVM: use `while read ...' instead of `for f in ...', because there may
# be too many files to stuff into one shell variable.
#
IFS=""
while read f
do
	# It's possible that I should be testing to make sure that the file
	# we're trying isn't a symlink,  and skipping it if it is, because of
	# the possible odd situation where we could have a link to a library
	# with no internal name.  This would need more investigation, though.
	chatr $f 2>/dev/null \
	| awk '

		BEGIN { 
			FS = " ";
			RS = "\n";

			# This flag signifies that we have seen the internal name:
			# marker.  Once we see that, we set the flag to 1.  The next
			# line we read should contain the library internal name, the
			# SOM equivalent of an soname.  At that point we set the flag
			# found_internal_name to 1 and exit
			# the main body of the awk script, going through the END
			in_internal_name = 0;

			#
			# We have seen the internal name: section (yet)?
			#
			found_internal_name = 0;

			#
			# assume it is a shared library, until record 2 proves us wrong.
			#
			isa_shared_library = 1;
		}

		# Uncomment the next line for some debugging info.
		#{ print NR , ":", $0  }

		#
		# save the first line in case there is no internal name built
		# into this object.
		#
		NR == 1 {
			my_name = $0
			opened_something = 1;
		}

		#
		# Check the second line (record).  Clear the flag if it is not a
		# shared library.
		#
		NR == 2 && $0 !~ /^[ 	]+shared library[ 	]*$/ {
			# It is not a shared library.  Bow out early
			isa_shared_library = 0;
			exit
		}

		in_internal_name == 1 {
		
			# We found the library internal name.  If it does not contain
			# a path, print it.  At least a couple of the system libraries
			# have a full path as the internal name (this is probably a bug).

			if ( $0 ~ /\// ) {
				numfields = split($0, internal_name, "/")
				print internal_name[numfields]
			} else {
				print $1
			}

			#
			# Set a flag for the EXIT section, to indicate that we found
			# an internal name
			#
			found_internal_name = 1;
			in_internal_name = 0
			exit
		}

		#
		# we have hit the internal name section.  Set the flag.  The next
		# line should be what we are looking for.
		#
		/^ +internal name: *$/ {
			in_internal_name = 1
		}

		END {
			# Uncomment the next line for debugging info
			#{ print "END: NR: ", NR }
			if ( (isa_shared_library == 0) || (NR < 2) ) {
				# both of these indicate error conditions, for which we
				# should not generate any output.
				exit;
			} else {
				if (found_internal_name == 1) {
					exit;
				} else {
					#
					# chop the : off the end of the line
					#
					colon = index(my_name, ":")
					colon = colon - 1
					temp = substr(my_name, 1, colon)
					#
					# get the basename
					#
					numfields = split(temp, basename, "/")
					# Uncomment the next line for debugging info
					#print "In END:",  numfields, ":", temp
					print basename[numfields]
					exit
				}
			}
		}
	' # end of awk
done | sort -u
#comment out the previous line and uncomment the next line when debugging
#done
