#! /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.28 1999/11/16 06:32:54 guenther 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? :-) ########