#!/bin/sh

set -u

show_usage() {
  cat >&2 <<EO_USAGE
Usage: ${0##*/} [OPTIONS] [PATTERN]

Show messages in the syslog buffer, optionally filtered through grep.

OPTIONS:
	-n N	Only print last N lines
	-f	Follow output
	-S	Strip timestamps (can't be used with PATTERN)
	-V	Print version information and exit
Passed to grep:
	-o	Show only the matching part of line
	-v	Select non-matching lines
	-i	Ignore case
	-w	Match whole words only
	-x	Match whole lines only
	-F	PATTERN is a literal (not regexp)
	-E	PATTERN is an extended regexp
	-m N	Match up to N times per file
	-A N	Print N lines of trailing context
	-B N	Print N lines of leading context
	-C N	Same as '-A N -B N'

EO_USAGE
}

logsrc() {
  if ! logread "$@" 2>/dev/null; then
    local logfile=/var/log/messages

    if [ ! -e "$logfile" ]; then
      printf "%s doesn't exist - syslogd running?\n" "$logfile" >&2
      return 1
    elif [ $# -eq 0 ]; then
      cat "$logfile"
    else
      tail -n0 "$@" "$logfile"
    fi
  fi
}

filter() {
  # The follow (-f) option won't work properly if we set up a
  # pipeline because the output won't be line buffered any more.
  # Until stdbuf is available in the platform, support the -S
  # option only if a PATTERN hasn't been specified.
  if [ -n "${PATTERN:-}" ]; then
    grep ${GREP_ARGS:+$GREP_ARGS }-e "$PATTERN"
  elif [ "${OPT_SMALL:-}" = "true" ]; then
    awk '{ sub(/^... .. ..:..:.. /, "", $0); print $0; }'
  else
    cat
  fi
}

main() {
  # Initial output
  if [ -z "${OPT_LINES:-}" ]; then
    logsrc | filter
  elif [ ${OPT_LINES:-0} -gt 0 ]; then
    logsrc | filter | tail -n $OPT_LINES
  fi

  # Follow
  if [ "${OPT_FOLLOW:-}" = "true" ]; then
    logsrc -f | filter
  fi
}

OPTS=$(getopt -n "${0##*/}" -l help,version -- n:SfVoviwxFEm:A:B:C: "$@") || exit 2
eval set -- "$OPTS"
unset OPTS

while : ; do
  case $1 in
    -n)	OPT_LINES=$(($2)); shift 2 ;;
    -S)	OPT_SMALL=true;    shift ;;
    -f)	OPT_FOLLOW=true;   shift ;;
    -[oviwx])
	GREP_ARGS="${GREP_ARGS:+$GREP_ARGS }$1"; shift ;;
    -[mABC])
	GREP_ARGS="${GREP_ARGS:+$GREP_ARGS }$1 $2"; shift 2 ;;
    -V|--version)
	printf "%s version 1\n" "${0##*/}"; exit 0 ;;
    --help)
	show_usage; exit 0 ;;
    --)	shift; break ;;
  esac
done

PATTERN="$@" # Whatever is left
main
