chiark / gitweb /
new script summarise-mailbox-preserving-privacy debian_version_4_1_11
authorianmdlvl <ianmdlvl>
Wed, 22 Nov 2006 19:53:31 +0000 (19:53 +0000)
committerianmdlvl <ianmdlvl>
Wed, 22 Nov 2006 19:53:31 +0000 (19:53 +0000)
debian/changelog
scripts/Makefile
scripts/summarise-mailbox-preserving-privacy [new file with mode: 0755]

index 424dbcf..9da722f 100644 (file)
@@ -4,8 +4,9 @@ chiark-utils (4.1.11) unstable; urgency=low
     on 2.6.x, but not with 2.4.x due to stupid stupid LVM bug where
     sizes are reported in 512-byte kilobytes but only sometimes.  Also
     fixed to cope better with dm-based LVM volumes.
+  * New script `summarise-mailbox-preserving-privacy'.
 
- --
+ -- Ian Jackson <ian@davenant.greenend.org.uk>  Wed, 22 Nov 2006 19:53:17 +0000
 
 chiark-utils (4.1.10) unstable; urgency=low
 
index c029306..2d78f27 100644 (file)
@@ -24,7 +24,7 @@ include ../settings.make
 SCRIPTS=       palm-datebook-reminders random-word expire-iso8601 \
                genspic2gnuplot gnucap2genspic ngspice2genspic \
                cvs-repomove cvs-adjustroot remountresizereiserfs \
-               hexterm
+               hexterm summarise-mailbox-preserving-privacy
 MANPAGES1=     palm-datebook-reminders
 
 CSCRIPTS=      named-conf
diff --git a/scripts/summarise-mailbox-preserving-privacy b/scripts/summarise-mailbox-preserving-privacy
new file mode 100755 (executable)
index 0000000..fe39a6e
--- /dev/null
@@ -0,0 +1,154 @@
+#!/usr/bin/perl
+# usage:
+#     summarise-mailbox-preserving-privacy \
+#          [<our options>] [--] <email>
+# our options:
+#  -S<subject>       default: "summary of messages on <mailname>"
+#  -F<state file>    default: $HOME/.summarise-mailbox/last<from options>
+#  -f<mailbox>       passed to from(1)  must use -F if it contains / or |
+#  -s<sender>        passed to from(1)  must use -F if it contains / or |
+#  -q                throw away stderr and always exit 0
+#  --          end of our options
+
+use strict (qw(refs));
+use POSIX;
+use IO::Handle;
+use Fcntl (qw(:flock));
+
+@from_options=();
+$sendmail= '/usr/sbin/sendmail -odi -oee -oi -t';
+
+umask 077;
+while (@ARGV && $ARGV[0] =~ m/\-/) {
+    $_= shift;
+    if (m/^\-[fs]/) {
+       push @from_options, $_;
+    } elsif (s/^\-S//) {
+       $subject= $_;
+    } elsif (s/^\-F//) {
+       $statefile= $_;
+    } elsif (s/^\-q$//) {
+       $quiet= 1;
+       open STDERR, ">/dev/null";
+       eval('END { $?=0; }');
+    } elsif (m/^\-\-$/) {
+       last;
+    } else {
+       die "$0: unknown option \`$_'\n";
+    }
+}
+die unless @ARGV==1;
+$emailto= shift @ARGV;
+
+unless (defined $subject) {
+    my ($our_hostname);
+    open M, "/etc/mailname" or die $!;
+    defined($our_hostname= <M>) or die $!;
+    chomp($our_hostname);
+    close M;
+    $subject= "summary of messages on $our_hostname";
+}
+
+unless (defined $statefile) {
+    my ($dir);
+    die "$0: -F needed with that -f or -s\n"
+       if grep m:[|/]:, @from_options;
+    die "$0: no HOME in environment\n" unless defined $ENV{'HOME'};
+    $dir= $ENV{'HOME'}.'/.summarise-mailbox';
+    mkdir $dir, 02700 or $!==&EEXIST or die "$dir: $!";
+    $statefile= $dir.'/last'.
+       join('|',@from_options);
+}
+
+$statefile= "./$statefile" unless $statefile =~ m,^/,;
+$lockfile= $statefile.'.lock';
+$errfile= $statefile.'.err';
+
+open L, "+> $lockfile" or die "$lockfile: $!";
+flock L, LOCK_EX or die "$lockfile: $!";
+
+if ($quiet) {
+    open STDERR, "> $errfile";
+}
+
+sub parse($) {
+    my ($incr, $lasttime) = @_;
+    $lasttime= '';
+    while (defined($_= <F>)) {
+       print N or die "$statefile.new: $!" if $incr>0;
+       $have{$_} += $incr;
+       $have += $incr;
+       m/^From .* (\w+ \w+ \d+ [0-9:]+ \d+)$/ or die "$_ ?";
+       $lasttime= $1;
+    }
+    die $! if F->error;
+    return $lasttime;
+}
+
+if (open F, "< $statefile\0") {
+    $old_lasttime= parse(-1);
+    close F or die $!;
+} elsif ($! != &ENOENT) {
+    die "$statefile $!";
+}
+
+open N, "> $statefile.new" or die "$statefile.new: $!";
+
+$child= open F, "-|"; defined $child or die $!;
+if (!$child) {
+    exec "from",@from_options;
+    die "$!";
+}
+
+$did_have= $have;
+$new_lasttime= parse(+1);
+$?=0; close F or die "$? $!";
+
+close N or die "$statefile.new: $!";
+
+if ($new_lasttime ne $old_lasttime and $new_lasttime ne '') {
+    push @reasons, "Timestamp of last message in mailbox changed.";
+}
+
+map { $total_more+=$_ if $_>0 } values %have;
+
+if ($total_more) {
+    push @reasons, "$total_more message(s)".
+       " which were not previously present.";
+} elsif ($have>0) {
+    push @reasons, "More messages than previously reported.";
+}
+
+exit 0 unless @reasons;
+
+$new_have= $have - $did_have;
+
+$msg= <<END
+To: $emailto
+Subject: $subject
+
+Regarding your mailbox @from_options:
+
+Changes detected since last report:
+END
+    ;
+
+$msg .= join "\n", map { "    $_" } @reasons;
+
+$msg .= <<END
+
+
+Now:
+    There are $new_have message(s).
+    The last is dated: $new_lasttime.
+
+--
+generated by $0
+END
+    ;
+
+open S, "| $sendmail" or die $!;
+print S $msg or die $!;
+$?=0; close S or die "$? $!";
+
+rename "$statefile.new", $statefile or die $!;