#! /bin/bash -u
# hosts.allow-journal Display "hosts.allow" activity recorded by journald for
# current (unfinished) boot.
# RP 2015-12-05

VERSION="1.0"

# Print user messages
function msg-user {
   echo -e "$1"
}

TEMPFILE=`mktemp`
BASENAME=`basename $0`

# Read the arguments - classic Bash space separated technique
# Default values
INCLUDE="SuSEfirewall|SFW2|hosts.allow|TRACE:"  # Include records which match this RE
EXCLUDE="<nil>"                                  # Exclude records which match this RE
T="2000-01-01"                                   # Show journal records younger than this

while [[ $#>0 ]]
do KEY=$1  # Next keyword
   case $KEY in
   --help|-h)
      msg-user ""
      msg-user "        ${BASENAME}      Version $VERSION      GPL V3"
      msg-user "        (C) 2015 Roger Price     hosts.allow@rogerprice.org"
      msg-user ""
      msg-user "Present those records accumulated by journald for the current boot that are"
      msg-user "of interest to a user of the TCP Wrappers script hosts.allow."
      msg-user ""
      msg-user "Usage: ${BASENAME} [options]"
      msg-user "Where the options are:"
      msg-user " --include|+ RE"
      msg-user "           Display only the journal records which satisfy this regular expression."
      msg-user "           The default RE is $INCLUDE .  The effect of this option is additive,"  
      msg-user "           it adds further expressions to the initial default RE."
      msg-user "           This option may be used more than once, the effect is cumulative."
      msg-user " --exclude|- RE"
      msg-user "           Exclude from the display any records which match this RE."
      msg-user "           This option may be used more than once, the effect is cumulative."
      msg-user " --since|-T hh:mm"
      msg-user "           Display only the journal records since this time today,"
      msg-user "           e.g. --since 18:05"
      msg-user ""
      exit 0
   ;;
   --include|+) # Addiionaly, accept those records with this regular expression
      if [[ "$2" =~ ^([[:graph:]]+)$ ]]
      then INCLUDE="$INCLUDE|${BASH_REMATCH[1]}"
      else msg-user "$BASENAME: Invalid --include $2 regular expression.  Should be something like \"kernel|SFW2\" ."
           exit 1
      fi
      shift # past argument   
   ;;
   --exclude|-) # Refuse those records containing this regular expression
      if [[ "$2" =~ ^([[:graph:]]+)$ ]]
      then EXCLUDE="$EXCLUDE|${BASH_REMATCH[1]}"
      else msg-user "$BASENAME: Invalid --exclude $2 regular expression.  Should be something like 10.0.0.[0-9]+ ."
           exit 1
      fi
      shift # past argument   
   ;;
   --since|-T) # Accept only those records more recent than time HH:MM today
      if [[ "$2" =~ ^([0-9][0-9]):([0-9][0-9])$ ]]
      then T="${BASH_REMATCH[1]}:${BASH_REMATCH[2]}:00"
      else msg-user "$BASENAME: Invalid --since value $2.  Should be something like 02:39 ."
           exit 1
      fi
      shift # past argument   
   ;;
   *) msg-user "$BASENAME: Unknown argument $KEY"
      exit 1
   ;;
   esac
   shift # past argument or value
done # KEY in $1

# Where does this distribution hide journalctl?
JOURNALCTL="journalctl"
WHERE=`whereis -b $JOURNALCTL`
if [[ "$WHERE" =~ ^[[:graph:]]+[[:space:]][[:graph:]]+$ ]]
then # Does user have access to journalctl for upsd?
     $JOURNALCTL -b 0 -n 10 --no-pager > /dev/null
     if [ $? -eq 0 ]; then : 
        else msg-user "        Welcome to $BASENAME"
             msg-user "You do not seem to have access to the journal"
             msg-user "for system commands such as those of NUT."
             msg-user "Ask your system administrator to add your"
             msg-user "account to the systemd-journal group."
             msg-user "When this is done, log out and then log in"
             msg-user "and try again."  
             exit 1
     fi
     msg-user "        Current boot" > $TEMPFILE
     # Regular expression removes MAC and trailing hexa value from TRACE 
     #RE="s_(.*) MAC=[0-9a-f:]* (.*) (\([0-9A-F]*\))?_\1 \2_"
     # Regular expression removes MAC from LOG 
     RE="s_([[:print:]]+) MAC=[0-9a-f:]+ ([[:print:]])_\1 \2_"
     $JOURNALCTL -b 0 --since=$T --no-pager | grep -E "$INCLUDE" | grep -v -E "$EXCLUDE" | sed -r "$RE" >> $TEMPFILE
else
     # No journalctl, maybe there is a /var/log/messages file
     LOG="/var/log/messages"
     msg-user "Cannot find ${JOURNALCTL}, trying $LOG ..."
     if [[ -e "$LOG" && -r "$LOG" ]]
     then # Search through the last 1000 records in the file.
          LINE=`tail --lines=1 "$LOG"`
          if [[ "$LINE" =~ ^([[:graph:]]+[[:space:]]+[0-9]{1,2})[[:space:]].*$ ]]
          then DAY="${BASH_REMATCH[1]}"
               msg-user "Displaying records for $DAY only."
          else DAY=""
               msg-user "Cannot determine month and day in $LOG"
          fi
          tail --lines=1000 "$LOG" | grep -E "$DAY" | grep -E "$INCLUDE" | grep -v -E "$EXCLUDE" >> $TEMPFILE
     else msg-user "Sorry, I cannot find the program $JOURNALCTL, or the log file $LOG needed to run this script."
     exit 1
     fi
fi

# Customer gets to see something
less --chop-long-lines $TEMPFILE
msg-user "I applied the --include filter \"$INCLUDE\" and then the --exclude filter \"$EXCLUDE\"."

# Trap exits and clean up
trap '# Remove temporary files used as variables
      rm $TEMPFILE
      exit $?
     ' EXIT
