3 # summarise-mailbox-preserving-privacy \
4 # [<our options>] [--] <email>
6 # -S<subject> default: "summary of messages on <mailname>"
7 # -F<state file> default: $HOME/.summarise-mailbox/last<from options>
8 # -f<mailbox> passed to from(1) must use -F if it contains / or |
9 # -s<sender> passed to from(1) must use -F if it contains / or |
10 # -q throw away stderr and always exit 0
11 # -- end of our options
13 # Copyright 2006 Ian Jackson <ian@chiark.greenend.org.uk>
15 # This script and its documentation (if any) are free software; you
16 # can redistribute it and/or modify them under the terms of the GNU
17 # General Public License as published by the Free Software Foundation;
18 # either version 3, or (at your option) any later version.
20 # chiark-named-conf and its manpage are distributed in the hope that
21 # it will be useful, but WITHOUT ANY WARRANTY; without even the
22 # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
23 # PURPOSE. See the GNU General Public License for more details.
25 # You should have received a copy of the GNU General Public License along
26 # with this program; if not, consult the Free Software Foundation's
27 # website at www.fsf.org, or the GNU Project website at www.gnu.org.
30 use strict (qw(refs));
33 use Fcntl (qw(:flock));
36 $sendmail= '/usr/sbin/sendmail -odi -oee -oi -t';
39 while (@ARGV && $ARGV[0] =~ m/\-/) {
42 push @from_options, $_;
49 open STDERR, ">/dev/null";
50 eval('END { $?=0; }');
54 die "$0: unknown option \`$_'\n";
58 $emailto= shift @ARGV;
60 unless (defined $subject) {
62 open M, "/etc/mailname" or die $!;
63 defined($our_hostname= <M>) or die $!;
66 $subject= "summary of messages on $our_hostname";
69 unless (defined $statefile) {
71 die "$0: -F needed with that -f or -s\n"
72 if grep m:[|/]:, @from_options;
73 die "$0: no HOME in environment\n" unless defined $ENV{'HOME'};
74 $dir= $ENV{'HOME'}.'/.summarise-mailbox';
75 mkdir $dir, 02700 or $!==&EEXIST or die "$dir: $!";
76 $statefile= $dir.'/last'.
77 join('|',@from_options);
80 $statefile= "./$statefile" unless $statefile =~ m,^/,;
81 $lockfile= $statefile.'.lock';
82 $errfile= $statefile.'.err';
84 open L, "+> $lockfile" or die "$lockfile: $!";
85 flock L, LOCK_EX or die "$lockfile: $!";
88 open STDERR, "> $errfile";
92 my ($incr, $lasttime) = @_;
94 while (defined($_= <F>)) {
95 print N or die "$statefile.new: $!" if $incr>0;
98 m/^From .* (\w+ \w+ \d+ [0-9:]+ \d+)$/ or die "$_ ?";
105 if (open F, "< $statefile\0") {
106 $old_lasttime= parse(-1);
108 } elsif ($! != &ENOENT) {
112 open N, "> $statefile.new" or die "$statefile.new: $!";
114 $child= open F, "-|"; defined $child or die $!;
116 exec "from",@from_options;
121 $new_lasttime= parse(+1);
122 $?=0; close F or die "$? $!";
124 close N or die "$statefile.new: $!";
126 if ($new_lasttime ne $old_lasttime and $new_lasttime ne '') {
127 push @reasons, "Timestamp of last message in mailbox changed.";
130 map { $total_more+=$_ if $_>0 } values %have;
133 push @reasons, "$total_more message(s)".
134 " which were not previously present.";
136 push @reasons, "More messages than previously reported.";
139 exit 0 unless @reasons;
141 $new_have= $have - $did_have;
147 Regarding your mailbox @from_options:
149 Changes detected since last report:
153 $msg .= join "\n", map { " $_" } @reasons;
159 There are $new_have message(s).
160 The last is dated: $new_lasttime.
167 open S, "| $sendmail" or die $!;
168 print S $msg or die $!;
169 $?=0; close S or die "$? $!";
171 rename "$statefile.new", $statefile or die $!;