#!/bin/ksh
##
## RPM: find-provides for multi-platforms
## Copyright (c) 2010-2012 SATOH Fumiyasu @ OSS Technology Corp., Japan
##               <http://www.OSSTech.co.jp/>
##
## License: GNU General Public License version 2 or later
## Date: 2012-11-01, since 2009-11-10
##

LC_ALL="C"
PATH=/usr/bin:/usr/ccs/bin:/usr/sfw/bin:/bin:/usr/sbin:/sbin
export LC_ALL PATH

pdie() { echo "$0: ERROR: ${1-}" 1>&2; exit "${2-1}"; }

escape_meta()
{
  sed 's/[^a-zA-Z0-9_]/\\&/g'
}

xargs_wrap()
{
  escape_meta |xargs ${1+"$@"}
}

## ======================================================================

vendor_id="${VENDOR_ID:-osstech}"
vendor_prefix="${VENDOR_PREFIX:-/opt/osstech}"

uname=$(uname)
rpm_configdir="${RPM_CONFIGDIR:-/usr/lib/rpm}"

progress_flag=""
perl_provides="${RPM_PERL_PROVIDES-}"
python_provides="${RPM_PYTHON_PROVIDES-}"
mono_provides="${RPM_MONO_PROVIDES-}"

root=""

## ----------------------------------------------------------------------

while [ "$#" -gt 0 ]; do
  OPT="$1"; shift
  case "$OPT" in
  --progress)
    progress_flag="yes"
    ;;
  --perl-provides)
    perl_provides="$1"; shift
    ;;
  --python-provides)
    python_provides="$1"; shift
    ;;
  --mono-provides)
    mono_provides="$1"; shift
    ;;
  --)
    break
    ;;
  -*)
    pdie "Invalid option: $OPT"
    ;;
  *)
    set -- "$OPT" ${1+"$@"}
    break
    ;;
  esac
done

## ----------------------------------------------------------------------

[ -n "${1+set}" ] && { root="$1"; shift; }

export PATH="$vendor_prefix/bin:$PATH"

## ======================================================================

## Set options for GNU by default

lib_re='/[a-z][-+a-zA-Z0-9_.]+\.so(\.[0-9]+)*$'
lib_skip_symlink='yes'
file_opts='-L'
file_lib_re=' (shared object|dynamic lib)[, ]'
objdump_cmd='objdump'

get_lib_soname() {
  typeset lib="$1"; shift
  "$objdump_cmd" -p "$lib" |sed -n '/^Dynamic Section:/,/^$/s/^ *SONAME  *//p'
}

get_lib_vers() {
  typeset lib="$1"; shift
  typeset lib_soname="$1"; shift
  [ -z "$lib_soname" ] && return

  typeset lib_ver
  "$objdump_cmd" -p "$lib" \
  |sed -n '/^Version definitions:/,/^$/s/^[0-9].* //p' \
  |while read -r lib_ver; do
    [ x"$lib_ver" != x"$lib_soname" ] && echo "$lib_ver"
  done
}

## ----------------------------------------------------------------------

## Adjust options for non-GNU systems

case "$uname" in
SunOS)
  file_opts=''
  objdump_cmd='gobjdump'
  ;;
AIX)
  lib_re='/[a-z][-a-zA-Z0-9_.]+\.a$'
  lib_skip_symlink='no'
  file_opts=''
  file_lib_re=' archive '
  objdump_cmd=':'
  get_lib_vers() {
    ar -t -X any "$1"
  }
  ;;
esac

## ======================================================================

trap 'rm -f ${stdin_tmp:+"$stdin_tmp"}' 0 HUP INT QUIT TERM PIPE
stdin_tmp=$(mktemp "/tmp/${0##*/}.XXXXXX") || exit 1

while read -r f; do
  [ x"$lib_skip_symlink" = x"yes" ] && [ -L "$f" ] && continue
  echo "$f"
done \
>"$stdin_tmp"

## ----------------------------------------------------------------------

[ -n "$progress_flag" ] && print -n 'Generating libraries provides...' 1>&2


egrep "$lib_re" <"$stdin_tmp" \
|xargs_wrap file $file_opts 2>/dev/null \
|egrep "$file_lib_re" \
|while read -r file_out; do
  lib="${file_out%%:*}"
  lib_soname=$(get_lib_soname "$lib")
  lib_vers=$(get_lib_vers "$lib" "$lib_soname")
  lib_bit=$(echo "$file_out" |sed -n 's|^.* \([0-9]*\)-bit .*|\1|p')

  [ -n "$root" ] && lib="/${lib#$root/}"
  [ -z "$lib_soname" ] && lib_soname="${lib##*/}"
  [ -f "$root${lib%/*}/$lib_soname" ] || continue

  case "$lib" in
  $vendor_prefix/*)
    ## Vendor specific libraries
    lib_name="${lib%/*}/$lib_soname"
    ;;
  *)
    ## OS-bundled libraries
    lib_name="$lib_soname"
    ;;
  esac

  [ x"$lib_bit" = x"32" ] && lib_bit=""
  #[ -z "${lib_name##*/lib$lib_bit/*}" ] && lib_bit=""

  for lib_ver in "" $lib_vers; do
    print -n "$lib_name"
    [ -n "$lib_ver$lib_bit" ] && print -n "($lib_ver)"
    [ -n "$lib_bit" ] && print -n "(${lib_bit}bit)"
    echo
  done

  [ -n "$progress_flag" ] && print -n '.' 1>&2
done \
|sort -u

[ -n "$progress_flag" ] && echo " Done." 1>&2

## ----------------------------------------------------------------------

[ -n "$progress_flag" ] && print -n 'Generating others provides by rpmdeps...' 1>&2

egrep -v "$lib_re" <"$stdin_tmp" \
|"$rpm_configdir/rpmdeps" \
  --provides \
  ${perl_provides:+--define "__perl_provides $perl_provides"} \
  ${python_provides:+--define "__python_provides $python_provides"} \
  ${mono_provides:+--define "__mono_provides $mono_provides"} \
|grep -v '^lib'

[ -n "$progress_flag" ] && echo " Done." 1>&2

## ======================================================================

exit 0
