1#! /bin/sh 2: &&O='cd .' || exec /bin/sh "$0" $argv:q # we're in a csh, feed myself to sh 3$O || exec /bin/sh "$0" "$@" # we're in a buggy zsh 4################################################################# 5# mailstat shows mail-arrival statistics # 6# # 7# Parses a procmail-generated $LOGFILE and displays # 8# a summary about the messages delivered to all folders # 9# (total size, average size, nr of messages). # 10# Exit code 0 if mail arrived, 1 if no mail arrived. # 11# # 12# For help try, "mailstat -h" # 13# # 14# Customise to your heart's content, this file is only # 15# provided as a guideline. # 16# # 17# Created by S.R. van den Berg, The Netherlands # 18# This file can be freely copied for any use. # 19################################################################# 20#$Id: mailstat,v 1.28 1999/11/16 06:32:54 guenther Exp $ 21 22# This shell script expects the following programs to be in the 23# PATH (paths given here are the standard locations, your mileage 24# may vary (if the programs can not be found, extend the PATH or 25# put their absolute pathnames in here): 26 27test=test # /bin/test 28echo=echo # /bin/echo 29expr=expr # /bin/expr 30tty=tty # /bin/tty 31sed=sed # /bin/sed 32sort=sort # /bin/sort 33awk=awk # /usr/bin/awk 34cat=cat # /bin/cat 35mv=mv # /bin/mv 36ls=ls # /bin/ls 37 38PATH=/bin:/usr/bin 39SHELL=/bin/sh # just in case 40export SHELL PATH 41 42umask 077 # we don't allow everyone to read the tmpfiles 43OLDSUFFIX=.old 44 45DEVNULL=/dev/null 46EX_USAGE=64 47 48######## 49# (Concatenated) flags parsing in pure, portable, structured (it 50# would have been more elegant if gotos were permitted) shellscript 51# language. For added pleasure: a quick demonstration of the shell's 52# quoting capabilities :-). 53######## 54 55while $test $# != 0 -a a"$1" != a-- -a \ 56 \( 0 != `$expr "X$1" : X-.` -o $# != 1 \) 57do 58 if $expr "X$1" : X-. >$DEVNULL # structured-programming spaghetti 59 then 60 flags="$1"; shift 61 else 62 flags=-h # force help page 63 fi 64 while flags=`$expr "X$flags" : 'X.\(.*\)'`; $test ."$flags" != . 65 do 66 case "$flags" in 67 k*) MSkeeplogfile=1;; 68 l*) MSlong=1;; 69 m*) MSmergerror=1;; 70 o*) MSoldlog=1; MSkeeplogfile=1;; 71 t*) MSterse=1;; 72 s*) MSsilent=1;; 73 h*|\?*) $echo 'Usage: mailstat [-klmots] [logfile]' 1>&2 74 $echo ' -k keep logfile intact' 1>&2 75 $echo ' -l long display format' 1>&2 76 $echo ' -m merge any errors into one line' 1>&2 77 $echo ' -o use the old logfile' 1>&2 78 $echo ' -t terse display format' 1>&2 79 $echo ' -s silent in case of no mail' 1>&2 80 exit $EX_USAGE;; 81 *) $echo 'Usage: mailstat [-klmots] [logfile]' 1>&2; exit $EX_USAGE;; 82 esac 83 done 84done 85 86$test a"$1" = a-- && shift 87 88LOGFILE="$1" 89 90case "$LOGFILE" in 91 *$OLDSUFFIX) MSkeeplogfile=1; OLDLOGFILE="$LOGFILE";; 92 *) OLDLOGFILE="$LOGFILE$OLDSUFFIX";; 93esac 94 95if test .$MSoldlog = .1 96then 97 LOGFILE="$OLDLOGFILE" 98fi 99 100if $test ."$LOGFILE" != .- -a ."$LOGFILE" != . 101then 102 if $test ! -s "$LOGFILE" 103 then 104 if $test .$MSsilent = . 105 then 106 if $test -f "$LOGFILE" # split up the following nested backquote 107 then # expression, some shells (NET2) choked on it 108 info=`LANG= LC_TIME= $ls -l "$OLDLOGFILE"` 109 $echo No mail arrived since \ 110 `$expr "X$info" : \ 111 '.*[0-9] \(... .[^ ] .....\) [^ ]'` 112 else 113 $echo "Can't find your LOGFILE=$LOGFILE" 114 fi 115 fi 116 exit 1 117 fi 118else 119 if $test ."$LOGFILE" != .- && $tty -s 120 then 121 $echo \ 122 "Most people don't type their own logfiles; but, what do I care?" 1>&2 123 MSterse=1 124 fi 125 MSkeeplogfile=1; LOGFILE= 126fi 127 128if $test .$MSkeeplogfile = . 129then $mv "$LOGFILE" "$OLDLOGFILE"; $cat $DEVNULL >>"$LOGFILE" 130else OLDLOGFILE="$LOGFILE" 131fi 132 133if $test .$MSterse = . 134then 135 if $test .$MSlong = .1 136 then 137 $echo "" 138 $echo " Total Average Number Folder" 139 $echo " ----- ------- ------ ------" 140 # We use MStrs here to place the spaces in columns that won't be 141 # converted to tabs by detab when this is checked into CVS 142 MStrs='" ----- ------- ------\n%7d %7d %7d\n",\ 143 gtotal,gtotal/gmessages,gmessages' 144 else 145 $echo "" 146 $echo " Total Number Folder" 147 $echo " ----- ------ ------" 148 MStrs='" ----- ------\n%7d %7d\n",gtotal,gmessages' 149 fi 150else 151 MStrs='""' 152fi 153 154if $test .$MSlong = .1 155then MSlong='"%7d %7d %7d %s\n",total,total/messages,messages,folder' 156else MSlong='"%7d %7d %s\n",total,messages,folder' 157fi 158 159######## 160# And now we descend into the wonderful mix of shell-quoting and 161# portable awk-programming :-) 162######## 163 164dq='"' 165awkscript=" 166BEGIN { 167 FS=$dq\\t$dq; 168 } 169 { if(folder!=\$1) 170 { if(folder!=$dq$dq) 171 printf($MSlong); 172 gmessages+=messages;gtotal+=total; 173 messages=0;total=0;folder=\$1; 174 } 175 ++messages;total+=\$2; 176 } 177END { 178 if(folder!=$dq$dq) 179 printf($MSlong); 180 gmessages+=messages;gtotal+=total; 181 printf($MStrs); 182 } 183" 184 185######## 186# Only to end in a grand finale with your average sed script 187######## 188 189if $test .$MSmergerror = . 190then 191 $sed -e '/^From /d' -e '/^ [Ss][uU][bB][jJ][eE][cC][tT]:/d' \ 192 -e '/^ Folder/s/ */ /' \ 193 -e '/^ Folder/s/\/msg\.[-0-9A-Za-z_][-0-9A-Za-z_]* /\/ /' \ 194 -e '/^ Folder/s/\/new\/[-0-9A-Za-z_][-0-9A-Za-z_.,+:%@]* /\/ /' \ 195 -e '/^ Folder/s/\/[0-9][0-9]* /\/. /' \ 196 -e 's/^ Folder: \(.*\)/\1/' -e t -e 's/ /\\t/g' \ 197 -e 's/^/ ## /' $OLDLOGFILE | $sort | $awk "$awkscript" - 198else 199 $sed -e '/^From /d' -e '/^ [Ss][uU][bB][jJ][eE][cC][tT]:/d' \ 200 -e '/^ Folder/s/ */ /' \ 201 -e '/^ Folder/s/\/msg\.[-0-9A-Za-z_][-0-9A-Za-z_]* /\/ /' \ 202 -e '/^ Folder/s/\/new\/[-0-9A-Za-z_][-0-9A-Za-z_.,+:%@]* /\/ /' \ 203 -e '/^ Folder/s/\/[0-9][0-9]* /\/. /' \ 204 -e 's/^ Folder: \(.*\)/\1/' -e t \ 205 -e 's/.*/ ## diagnostic messages ##/' $OLDLOGFILE | $sort | \ 206 $awk "$awkscript" - 207fi 208 209######## 210# Nifty little script, isn't it? 211# Now why didn't *you* come up with this truly trivial script? :-) 212######## 213