#!/bin/bash

# Copyright (C) 2004, 2005  Moreno 'baro' Baricevic
#                                      <baro AT democritos DOT it>
#
# Redistribution and use of this script, with or without modification, is 
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#

#=====================================#
# Author: Moreno 'baro' Baricevic     #
# Contact: baro AT democritos DOT it  #
# Path: /bin                          #
# File: pkginfo                       #
# Date: 14 Oct 2004                   #
#-------------------------------------#
# Prev Modified: 14 Oct 2004          #
# Last Modified: 17 Oct 2004          #
#=====================================#
#
# Display info about installed packages.
#
# Inspired by Slackware pkgtool (some code has
# been simply adapted and translated to bash).
#
# Dependencies:
#	bash, test/[, ls, sed, printf, less
#


ADM_DIR=/var/log
PKG_DIR=$ADM_DIR/packages
test -d "$PKG_DIR" || { echo >&2 "!!! Directory '$PKG_DIR' does not exist !!!" ; exit -1 ; }


# faster basename
#
function mybasename()
{
  basename="${1##*/}"
  test "$2x" != "x" && basename="${basename%$2}"
  echo $basename
} # mybasename #


# enabling bash extended pattern matching
#
shopt -s extglob


# extract short package name
# (bash translation of package_name() from pkgtool)
#
function package_name()
{
  # Check for old style package name with one segment:
  if [ "${1%%-*}x" = "${1#*-}x" ]
  then
    echo ${1%%-*}
  else # has more than one dash delimited segment
    # Count number of segments:
    index=1
    next="$1"
    last="${1##*-}"
    while [ "${next}x" != "${last}x" ]
    do
      next="${next#*-}"
      let ++index
    done
    # If we don't have four segments, return the old-style (or out of spec) package name:
    if [ "$index" = "2" -o "$index" = "3" ]
    then
      echo $1
    else # we have four or more segments, so we'll consider this a new-style name:
      echo ${1%%-+([^-])-+([^-])-+([^-])}
    fi
  fi
} # package_name #


# extract one-line package description
#
function package_desc()
{
  name="$1"
  file="$2"
  descr="$(sed -n "/$name:/{s/\"//g;p;q;}" $PKG_DIR/$file 2>/dev/null)"
  echo ${descr#*:}
} # package_desc #


# display package(s) info
#
function package_list()
{
  declare -a args
  test $# -eq 0 && args=( `ls $PKG_DIR 2>/dev/null` ) || args=( $@ )
  for pkg in ${args[@]}
  do
    pkg_file="$(mybasename $pkg)"
    pkg_name="$(package_name $pkg_file)"
    pkg_desc="$(package_desc $pkg_name $pkg_file)"
    # Let's have some backward compatibility with the interim beta (for now):
    test -z "$pkg_desc" && pkg_desc="$(package_desc $pkg_file $pkg_file)" # FIXME

    printf "%-20.20s %-34.34s %-${w}.${w}s\n" "$pkg_name" "$pkg_file" "$pkg_desc"
  done
} # package_list #


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

# check window size
#
eval `resize 2>/dev/null` # X?
test "$COLUMNS" = "" -o "$COLUMNS" -lt 80 && COLUMNS=80
w=$(($COLUMNS-56))	# '56' comes from printf fmt (package_list())


# check argument
#
if [ $# -eq 1 -a "$1x" = "-lx" ]
then
  # list all the installed packages
  #
  echo >&2 "=========================== Scanning system for installed packages ==========================="
  package_list
  exit 0
elif [ $# -ne 1 -o "$1x" = "x" -o "${1//[a-zA-Z]*([a-zA-Z0-9_\+\-\.,:])/}x" != "x" ]
then
  # mmh, something's wrong on the cmdline
  #
  myself="$(mybasename $0)"
  cat <<_USAGE_ >&2

Usage: $myself [ -l | PACKAGE ]
	-l		list installed packages
	PACKAGE		view PACKAGE info

NOTES:
   when PACKAGE match more packages, a short list is displayed:

   $myself p                         # list of "p*" packages
   $myself pkgtools                  # "pkgtools" info
   $myself -l | grep "tool"          # "*tool*" list (!match description too!)
   $myself -l | grep "^[^ ]*tool"    # "*tool*" list (match only package name)

_USAGE_
  exit 1
else
  # look for candidates
  #
  package="$1"

  declare -a candidates
  candidates=( `ls $PKG_DIR/"$package"* 2>/dev/null` )
  num=${#candidates[*]}
  if [ $num -eq 0 ]
  then	# mmh, no candidates found
    echo >&2 "Package '$package': no match found in $PKG_DIR/"
    test ${#package} -gt 1 && echo >&2 "Hint: try '${package%?}'"
  elif [ $num -gt 1 ]
  then	# we have more packages that match given argument
    echo >&2 "$num possible candidates:"
    package_list ${candidates[@]}
  else	# we have just one match
    trap "exec 2>/dev/null ; exit 0 ;" SIGPIPE
    less ${candidates[*]}
  fi
  exit 0
fi

exit -1	# WTF???

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

#EOF