#!/bin/sh
#
#     tiger - A UN*X security checking system
#     Copyright (C) 1993 Douglas Lee Schales, David K. Hess, David R. Safford
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 1, or (at your option)
#    any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#     Please see the file `COPYING' for the complete copyright notice.
#
# tigexp  - 06/13/93
# tigexp  - 05/23/2003 - changed so that it is managed by autoconf
# tigexp  - 11/27/2008 - Proper handling of errors and existance (or
#                        lack of) idx file. Also, regenerate the index
#                        file only if running as root.
# tigexp  - 04/25/2009 - proper wording for error messages
#
# This program retrieves information explaining what a given message 
# (INFO, WARN, ALERT, FAIL or ERROR) given out by Tiger means.
#
#-----------------------------------------------------------------------------
TigerInstallDir="."

#
# Set default base directory.
# Order or preference:
#      -B option
#      TIGERHOMEDIR environment variable
#      TigerInstallDir installed location
#
basedir=${TIGERHOMEDIR:=$TigerInstallDir}
findbase=1

for parm
do
   case $parm in
   -B) basedir=$2; findbase=0; break;;
   esac
done

#
# Routines for verifying environment
#
# haveallcmds - verify command variables
# haveallfiles - verify files
# haveallvars - verify variables
#
haveallcmds()
{
  __retval=0

  for __file
  do
    eval __cmdstr=\$$__file
    set X $__cmdstr
    __cmd=$2
    if [ ! -n "$__cmdstr" ]; then
      echo "--ERROR-- [init001e] Don't have a value for required command $__file."
      __retval=1
    elif [ ! -f "$__cmd" ]; then
      echo "--ERROR-- [init004e] \`$__cmd' is not executable (command $__file)."
      __retval=1
    fi
  done
  return $__retval
}

haveallfiles()
{
  __retval=0

  for __var
  do
    eval __file=\$$__var
    if [ ! -n "$__file" ]; then
      echo "--ERROR-- [init005e] Don't have a value for required file or directory $__var."
      __retval=1
    elif [ ! -f "$__file" -a ! -d "$__file" ]; then
      echo "--ERROR-- [init006e] \`$__file' does not exist (file or directory $__var)."
      __retval=1
    fi
  done

  return $__retval
}

haveallvars()
{
  __retval=0

  for __var
  do
    eval __val=\$$__var
    if [ ! -n "$__val" ]; then
      echo "--ERROR-- [init007e] Don't have required variable $__var."
      __retval=1
    fi
  done

  return $__retval
}


findcmd()
{
  cmd=$1

  srch=/usr/ucb:/usr/bin:/bin:/etc:/usr/etc
  
  saveifs=$IFS
  IFS=:
  set $srch
  IFS=$saveifs
  for dir
  do
    [ -f $dir/$cmd ] && {
      echo $dir/$cmd
      return
    }
  done
}

GREP=`findcmd grep`
SED=`findcmd sed`
FMT=`findcmd fmt`
SORT=`findcmd sort`
LS=`findcmd ls`

[ ! -n "$FMT" ] && FMT=`findcmd cat`

dirname()
{
  _path="$1"

  saveifs=$IFS
  IFS=/
  set X $_path
  IFS=$saveifs

  shift

  if [ $# -eq 1 ]; then
    _dirname='./'
  else
    _dirname=$1
    shift
    while [ $# -ne 1 ]
    do
      _dirname="$_dirname/$1"
      shift
    done
  fi
  
  echo "$_dirname"
}


[ $findbase -ne 0 ] && {
  if [ ! -d "$basedir/doc" -o ! -d "$basedir/systems" ]; then
    tempdir="`dirname $0`"
    if [ -d "$tempdir/doc" -a -d "$tempdir/systems" ]; then
      basedir="$tempdir"
    elif [ -d ../doc -a -d ../systems ]; then
      basedir=..
    fi
  fi
}

BASEDIR="$basedir"
export BASEDIR

params="$*"

haveallcmds GREP FMT SED SORT LS || exit 1
haveallfiles BASEDIR || exit 1

check_idx()
{
 [ "$UUID" = "" ] && UNAME=`whoami`

# Check if the index is up to date
 if [ "$UNAME" != "root" ] ; then 
  {
# Not running as root, just warn if the index file is out of date, do not
# regenerate it
    cd $BASEDIR/doc
    $LS -t
  } | {
    read file
    [ "$file" != "explain.idx" ] && {
        if [ -e "doc/explain.idx" ] ; then
	    echo "Warning: Explain index is out of date and I am unable to rebuild it."
            echo "Warning: Please regenerate it by running, as root, the following command: "
            echo "Warning: cd $BASEDIR && util/genmsgidx doc/*txt"
        fi
    }
  }
  else
  {
# Not running as root, just warn if the index file is out of date, do not
# regenerate it
    cd $BASEDIR/doc
    $LS -t
  } | {
    read file
    [ "$file" != "explain.idx" ] && {
      echo "Rebuilding explain index file"
      $BASEDIR/util/genmsgidx $BASEDIR/doc/*.txt 
    }
  } 
  fi
}

explain()
{
  message="$1"
  if [ ! -e "$BASEDIR/doc/explain.idx" ] ; then
    echo "Error: Explain index file ($BASEDIR/doc/explain.idx) does not exist."
    echo "Error: Please create it by running, as root, the following command: "
    echo "Error: cd $BASEDIR && util/genmsgidx doc/*txt"
    exit 1
  fi
  $GREP "$message" $BASEDIR/doc/explain.idx |
  {
    read msgid file start end
    echo
    if [ -n "$start" -a -n "$end" ]; then
      $SED -e "$start,${end}p" -e '1,$d' $BASEDIR/doc/$file |
      $FMT
    else
      echo "Can not find explanation for message-id $message"
    fi
    echo
  }
}

explainfile()
{
  file=$1
  if [ ! -r "$file" ] ; then
    echo "Error: Cannot read file provided as argument: $file"
    exit 1
  fi
  $GREP '^--[A-Z]*-- \[.*\]' $file |
  $SED -e 's/^.*\[\(.*\)\].*$/\1/' |
  $SORT -u |
  while read msgid
  do
    echo "Message ID: $msgid"
    explain "$msgid"
  done
}

explaininsert()
{
  file=$1
  msgid=
  [ -f "$file" ] &&  {
  {
    while read line
    do
      case "$line" in
	--[A-Z]*)
	[ -n "$msgid" ] && {
	  explain "$msgid"
	  msgid=
	}
	msgid="`echo \"$line\" | $SED -e 's/^.*\[\(.*\)\].*$/\1/' -e '/\-/d'`"
	;;
	\#*)
	[ -n "$msgid" ] && {
	  explain "$msgid"
	  msgid=
	};;
      esac
      echo "$line"
    done

    [ -n "$msgid" ] && {
      explain "$msgid"
    }
  } < $file
  }
}

set x $params

shift

if [ "$1" = "-f" ]; then
  explainfile $2
elif [ "$1" = "-F" ]; then
  check_idx
  explaininsert $2
elif [ $# -eq 1 ]; then
  check_idx
  explain "$1"
else
  check_idx
  for msg
  do
    echo "[$msg]"
    explain $msg
  done
fi

