mailstat   [plain text]


#! /bin/sh
: &&O='cd .' || exec /bin/sh "$0" $argv:q # we're in a csh, feed myself to sh
$O || exec /bin/sh "$0" "$@"		  # we're in a buggy zsh
#################################################################
#	mailstat	shows mail-arrival statistics		#
#								#
#	Parses a procmail-generated $LOGFILE and displays	#
#	a summary about the messages delivered to all folders	#
#	(total size, average size, nr of messages).		#
#	Exit code 0 if mail arrived, 1 if no mail arrived.	#
#								#
#	For help try, "mailstat -h"				#
#								#
#	Customise to your heart's content, this file is only	#
#	provided as a guideline.				#
#								#
#	Created by S.R. van den Berg, The Netherlands		#
#	This file can be freely copied for any use.		#
#################################################################
#$Id: mailstat,v 1.1.1.2 2001/07/20 19:38:13 bbraun Exp $

#	This shell script expects the following programs to be in the
#	PATH (paths given here are the standard locations, your mileage
#	may vary (if the programs can not be found, extend the PATH or
#	put their absolute pathnames in here):

test=test		# /bin/test
echo=echo		# /bin/echo
expr=expr		# /bin/expr
tty=tty			# /bin/tty
sed=sed			# /bin/sed
sort=sort		# /bin/sort
awk=awk			# /usr/bin/awk
cat=cat			# /bin/cat
mv=mv			# /bin/mv
ls=ls			# /bin/ls

PATH=/bin:/usr/bin
SHELL=/bin/sh		# just in case
export SHELL PATH

umask 077		# we don't allow everyone to read the tmpfiles
OLDSUFFIX=.old

DEVNULL=/dev/null
EX_USAGE=64

########
#	(Concatenated) flags parsing in pure, portable, structured (it
#	would have been more elegant if gotos were permitted) shellscript
#	language.  For added pleasure: a quick demonstration of the shell's
#	quoting capabilities :-).
########

while $test $# != 0 -a a"$1" != a-- -a \
 \( 0 != `$expr "X$1" : X-.` -o $# != 1 \)
do
  if $expr "X$1" : X-. >$DEVNULL	# structured-programming spaghetti
  then
     flags="$1"; shift
  else
     flags=-h				# force help page
  fi
  while flags=`$expr "X$flags" : 'X.\(.*\)'`; $test ."$flags" != .
  do
     case "$flags" in
	 k*) MSkeeplogfile=1;;
	 l*) MSlong=1;;
	 m*) MSmergerror=1;;
	 o*) MSoldlog=1; MSkeeplogfile=1;;
	 t*) MSterse=1;;
	 s*) MSsilent=1;;
	 h*|\?*) $echo 'Usage: mailstat [-klmots] [logfile]' 1>&2
	    $echo '	-k	keep logfile intact' 1>&2
	    $echo '	-l	long display format' 1>&2
	    $echo '	-m	merge any errors into one line' 1>&2
	    $echo '	-o	use the old logfile' 1>&2
	    $echo '	-t	terse display format' 1>&2
	    $echo '	-s	silent in case of no mail' 1>&2
	    exit $EX_USAGE;;
	 *) $echo 'Usage: mailstat [-klmots] [logfile]' 1>&2; exit $EX_USAGE;;
     esac
  done
done

$test a"$1" = a-- && shift

LOGFILE="$1"

case "$LOGFILE" in
  *$OLDSUFFIX) MSkeeplogfile=1; OLDLOGFILE="$LOGFILE";;
  *) OLDLOGFILE="$LOGFILE$OLDSUFFIX";;
esac

if test .$MSoldlog = .1
then
  LOGFILE="$OLDLOGFILE"
fi

if $test ."$LOGFILE" != .- -a ."$LOGFILE" != .
then
  if $test ! -s "$LOGFILE"
  then
     if $test .$MSsilent = .
     then
	if $test -f "$LOGFILE"	# split up the following nested backquote
	then			# expression, some shells (NET2) choked on it
	   info=`LANG= LC_TIME= $ls -l "$OLDLOGFILE"`
	   $echo No mail arrived since \
	    `$expr "X$info" : \
	     '.*[0-9] \(... .[^ ] .....\) [^ ]'`
	else
	   $echo "Can't find your LOGFILE=$LOGFILE"
	fi
     fi
     exit 1
  fi
else
  if $test ."$LOGFILE" != .- && $tty -s
  then
     $echo \
      "Most people don't type their own logfiles;  but, what do I care?" 1>&2
     MSterse=1
  fi
  MSkeeplogfile=1; LOGFILE=
fi

if $test .$MSkeeplogfile = .
then $mv "$LOGFILE" "$OLDLOGFILE"; $cat $DEVNULL >>"$LOGFILE"
else OLDLOGFILE="$LOGFILE"
fi

if $test .$MSterse = .
then
  if $test .$MSlong = .1
  then
     $echo ""
     $echo "  Total Average  Number Folder"
     $echo "  ----- -------  ------ ------"
     # We use MStrs here to place the spaces in columns that won't be
     # converted to tabs by detab when this is checked into CVS
     MStrs='"  ----- -------  ------\n%7d %7d %7d\n",\
	gtotal,gtotal/gmessages,gmessages'
  else
     $echo ""
     $echo "  Total  Number Folder"
     $echo "  -----  ------ ------"
     MStrs='"  -----  ------\n%7d %7d\n",gtotal,gmessages'
  fi
else
  MStrs='""'
fi

if $test .$MSlong = .1
then MSlong='"%7d %7d %7d %s\n",total,total/messages,messages,folder'
else MSlong='"%7d %7d %s\n",total,messages,folder'
fi

########
#	And now we descend into the wonderful mix of shell-quoting and
#	portable awk-programming :-)
########

dq='"'
awkscript="
BEGIN {
    FS=$dq\\t$dq;
  }
  { if(folder!=\$1)
     { if(folder!=$dq$dq)
	  printf($MSlong);
       gmessages+=messages;gtotal+=total;
       messages=0;total=0;folder=\$1;
     }
    ++messages;total+=\$2;
  }
END {
    if(folder!=$dq$dq)
       printf($MSlong);
    gmessages+=messages;gtotal+=total;
    printf($MStrs);
  }
"

########
#	Only to end in a grand finale with your average sed script
########

if $test .$MSmergerror = .
then
  $sed	-e '/^From /d' -e '/^ [Ss][uU][bB][jJ][eE][cC][tT]:/d' \
   -e '/^  Folder/s/		*/	/' \
   -e '/^  Folder/s/\/msg\.[-0-9A-Za-z_][-0-9A-Za-z_]*	/\/	/' \
   -e '/^  Folder/s/\/new\/[-0-9A-Za-z_][-0-9A-Za-z_.,+:%@]*	/\/	/' \
   -e '/^  Folder/s/\/[0-9][0-9]*	/\/.	/' \
   -e 's/^  Folder: \(.*\)/\1/' -e t -e 's/	/\\t/g' \
   -e 's/^/ ## /' $OLDLOGFILE | $sort | $awk "$awkscript" -
else
  $sed	-e '/^From /d' -e '/^ [Ss][uU][bB][jJ][eE][cC][tT]:/d' \
   -e '/^  Folder/s/		*/	/' \
   -e '/^  Folder/s/\/msg\.[-0-9A-Za-z_][-0-9A-Za-z_]*	/\/	/' \
   -e '/^  Folder/s/\/new\/[-0-9A-Za-z_][-0-9A-Za-z_.,+:%@]*	/\/	/' \
   -e '/^  Folder/s/\/[0-9][0-9]*	/\/.	/' \
   -e 's/^  Folder: \(.*\)/\1/' -e t \
   -e 's/.*/ ## diagnostic messages ##/' $OLDLOGFILE | $sort | \
	$awk "$awkscript" -
fi

########
#	Nifty little script, isn't it?
#	Now why didn't *you* come up with this truly trivial script? :-)
########