#!/bin/sh

# $Id: p.sh.html,v 1.1 2004/10/25 09:35:23 john Exp $
#
# JW.

if [ -f "/etc/pkgsh.conf" ]; then
   . /etc/pkgsh.conf
fi
if [ -f "./pkgsh.conf" ]; then
   . ./pkgsh.conf
fi

release=${release:=`uname -r`}
machine=${machine:=`uname -m`}
verbose=${verbose:="/dev/null"}

DOWNLOAD=${DOWNLOAD:=false}

_expand() {
   _release=`echo $release | tr . _`
   echo "$1" | sed \
      -e "s%@_RELEASE@%${_release}%g" \
      -e "s%@RELEASE@%$release%g" \
      -e "s%@MACHINE@%$machine%g"
}

packagesdb=`_expand "$packagesdb"`
portsdb=`_expand "$portsdb"`
ftp_path=`_expand "$ftp_path"`
cvs_tag=`_expand "$cvs_tag"`

echo "CVS: $cvs_cmd; $cvs_root; $cvs_tag"
echo "FTP: $ftp_cmd; $ftp_host;"
echo "     $ftp_path"
echo

# Port description lookup.
portdescr() {
   echo "Port description:"
   portpattern="$1"
   IFS='|'
   cut -d '|' -f 1,5 "$portsdb" | grep -i "^$portpattern|" |
      while :; do
         read port descr
         if [ -z "$port" ]; then
            break
         fi
         echo "$port, $descr"
         _cvsfetch "ports/$descr" "/dev/stdout"
      done
}

# Description search.
descsearch() {
   echo "Description search:"
   pattern="$1"
   IFS='|'
   cut -d '|' -f 1,4,11 "$portsdb" | grep -i "$pattern" |
      while :; do
         read name desc arch
         if [ -z "$name" ]; then
            break
         fi
         thisarch=0
         if [ "$arch" = "any" ]; then
            # Any architecture.
            thisarch=1
         elif [ $(echo "$arch" | grep -c "$machine") -gt 0 ]; then
            # Our architecture is listed.
            if [ $(echo "$arch" | fgrep -c '!') -gt 0 ]; then
               # Architecture list is a NOT.
               thisarch=0
            else
               # It's for us.
               thisarch=1
            fi
         elif [ $(echo "$arch" | fgrep -c '!') -gt 0 ]; then
            # We're not listed but the list is a NOT.
            thisarch=1
         fi
         if [ $thisarch -eq 1 ]; then
            printf '%s, %s\n   %s\n' "$name" "$arch" "$desc"
         fi
      done
}

# Perform an install or download.
install() {
   package="ftp://$ftp_host$ftp_path$1"
   if $DOWNLOAD; then
      "$ftp_cmd" "$package"
   else
      if [ -z "$SUDO" ]; then
         pkg_add "$package"
      else
         echo "You may be prompted for your sudo password here."
         "$SUDO" pkg_add "$package"
      fi
   fi
}

# Count lines and tidy up the output from wc -l.
countfile() {
   wc -l "$1" | cut -b -8 | tr -d " "
}

# CVS file fetcher.
_cvsfetch() {
   src="$1"
   dst="$2"
   "$cvs_cmd" -q -d "$cvs_root" get -PAp -r "$cvs_tag" "$src" > "$dst"
}

# Update packagedb and portsdb.
update() {
   echo "Fetching ports database."
   _cvsfetch "ports/INDEX" "$portsdb"
   count=`countfile "$portsdb"`
   echo "Found $count ports."

   echo "Fetching packages database."
   tmp=`mktemp updateXXXX`
   "$ftp_cmd" -Va "$ftp_host" > "$verbose" <<EOF
   cd "$ftp_path"
   prompt
   ls . $tmp
   quit
EOF
   fgrep '.tgz' "$tmp" | awk '{ print $5, $NF }' > "$packagesdb"
   rm -f "$tmp"
   count=`countfile "$packagesdb"`
   echo "Found $count packages."
}

# Search packages database.
search() {
   pattern="$1"
   awk '{ print $NF }' "$packagesdb" | grep -i "$pattern"
}

# List installed packages.
installed() {
   pkg_info | awk '{ print $1".tgz" }'
}

# MAIN:
command="$1"

case "$command" in
update)
   update
   ;;
desc)
   shift
   portdescr "$@"
   ;;
apropos)
   shift
   descsearch "$@"
   ;;
search)
   shift
   _matches=`search "$@"`
   if [ -z "$_matches" ]; then
      echo "No matches found"
      exit 1;
   fi
   set -A matches $_matches
   for match in `jot ${#matches[*]} 0`; do
      printf '%3d %s\n' $match ${matches[$match]}
   done
   if $DOWNLOAD; then
      echo -n "Download? "
   else
      echo -n "Install? "
   fi
   read choicen
   if [ -z "$choicen" -o "$choicen" -lt 0 -o "$choicen" -ge ${#matches[*]} ]; then
      echo "No choice or out of range"
      exit 0
   fi
   install ${matches[$choicen]}
   ;;
*)
   echo "Usage: $0 {update|search|apropos|desc} ..." >&2
   echo "update  Refresh packages and ports database files." >&2
   echo "search  Search for a named package." >&2
   echo "apropos Search port descriptions." >&2
   echo "desc    Lookup a port's description." >&2
   exit 1
   ;;
esac