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