+2010-03-06 01:32 Jochen Striepe
+
+ * t-prot: Release as v2.97.
+
+2010-03-06 01:31 Jochen Striepe
+
+ * t-prot, t-prot.1: Standard diff(1) output now is protected by
+ --diff, too. Many thanks to Martin Neitzel and Matthias Kilian.
+
+2010-03-04 22:01 Jochen Striepe
+
+ * t-prot: Release as v2.96.
+
+2010-03-04 21:48 Jochen Striepe
+
+ * t-prot: Allow -o /dev/null without bitching around.
+
+2010-03-04 21:40 Jochen Striepe
+
+ * t-prot.1: Give some emergency help how to write to /dev/null. You
+ never know.
+
+2010-03-04 21:19 Jochen Striepe
+
+ * t-prot.1: Remove repetition.
+
+2010-03-04 21:12 Jochen Striepe
+
+ * t-prot: More syntax help fixes.
+
+2010-03-04 21:09 Jochen Striepe
+
+ * t-prot.1: Update date string.
+
+2010-03-04 21:09 Jochen Striepe
+
+ * t-prot.1: Fix --version description.
+
+2010-03-04 21:07 Jochen Striepe
+
+ * t-prot.1: More syntax fixes.
+
+2010-03-04 21:02 Jochen Striepe
+
+ * t-prot.1: Change option order for footer options.
+
+2010-03-04 20:48 Jochen Striepe
+
+ * t-prot.1: More grouping: Footers.
+
+2010-03-04 20:34 Jochen Striepe
+
+ * t-prot.1: Fix typo.
+
+2010-03-04 20:32 Jochen Striepe
+
+ * t-prot, t-prot.1: Special output to "NONE" is not required. You
+ can use /dev/null.
+
+2010-03-04 20:24 Jochen Striepe
+
+ * t-prot.1: Improve word flow.
+
+2010-03-04 20:22 Jochen Striepe
+
+ * t-prot.1: Fix -i and -o syntax.
+
+2010-03-04 20:21 Jochen Striepe
+
+ * t-prot.1: Improve MIME handling description.
+
+2010-03-04 20:19 Jochen Striepe
+
+ * t-prot.1: Explain grouping of options and what happens if none
+ are specified. Be specific how MIME is handled.
+
+2010-03-04 18:45 Jochen Striepe
+
+ * contrib/: mailcap.t-prot, nailrc.t-prot: New files: configuration
+ samples for metamail and Heirloom mailx (a.k.a. nail). Many thanks
+ to Martin Neitzel!
+
+2010-03-04 17:26 Jochen Striepe
+
+ * t-prot.1: Fix -S syntax.
+
+2010-03-04 17:25 Jochen Striepe
+
+ * t-prot: Fix -S syntax help.
+
+2010-03-04 17:24 Jochen Striepe
+
+ * t-prot.1: Group options by meaning, rather than alphabetically.
+ Thanks to Martin Neitzel for suggesting.
+
+2010-03-04 16:53 Jochen Striepe
+
+ * t-prot: Fix --help output order.
+
+2010-03-04 16:52 Jochen Striepe
+
+ * t-prot: Fix -c syntax in --help, too.
+
+2010-03-03 22:39 Jochen Striepe
+
+ * t-prot.1: Precisify wording for --ms-smart.
+
+2010-03-03 22:36 Jochen Striepe
+
+ * t-prot.1: Be a little more specific as to what --ms-smart really
+ does.
+
+2010-03-03 22:30 Jochen Striepe
+
+ * t-prot.1: Specify more clearly what locale to specify with
+ --locale. Thanks to Martin Neitzel for suggesting.
+
+2010-03-03 22:24 Jochen Striepe
+
+ * t-prot.1: Fix -c syntax help.
+
+2010-03-03 20:09 Jochen Striepe
+
+ * t-prot: Fix bad typo. Thanks to Martin Neitzel.
+
+2010-03-03 16:50 Jochen Striepe
+
+ * t-prot: Big changes, we step a great deal towards the next major
+ version number. Release as v2.95.
+
+2010-03-03 16:27 Jochen Striepe
+
+ * t-prot: Since Getopt::Mixed would break existing configurations
+ with the new -c command line switch behaviour, the migration to
+ Getopt::Long has been finished by now: This commit merges the big
+ bad Getopt::Long patch. Hope the performance issue does not turn
+ out to be too grave. Thanks to everyone for testing and providing
+ feedback.
+
+2010-02-19 16:20 Jochen Striepe
+
+ * t-prot, t-prot.1, contrib/muttrc.t-prot, contrib/t-prot.sl: The
+ command line option -c now accepts an optional parameter specifying
+ the number of empty lines to remain. Thanks to Simon Ruderich.
+
2010-02-15 20:13 Jochen Striepe
* t-prot: Release as v2.15.
entire inspiration for this hack came from the "TOFU protection" line of
his script on many usenet postings.
-
-T-PROT AND SUPPORT FOR GETOPT::LONG
-===================================
-
-Most distributions (it seems to me) are quite eager to abandon Getopt::Mixed,
-having Getopt::Long in the official Perl package, which does everything the
-former module did. Getopt::Mixed is unmaintained and marked deprecated by
-its author, so why keep it?
-
-The answer is simple: because it's much faster (GNU time(1) tells me 28%
-faster for running my complete t-prot release test suite consisting of
-real-life emails) than anything I could get out of Getopt::Long. Plus,
-from my point of view, there are no problems having a package installed
-that is well-tested and just works fine (you don't need updates and more
-new shiny features if the software just does what you want it to do).
-
-So we have the choice between easy maintainance and better performance.
-
-For the time being, I made my choice and keep sticking to Getopt::Mixed as
-long as it works as-is with current stable perl versions. That does not mean
-I don't see the merits of a well-maintained standard module, which is already
-available on any perl system out there. Thus, a patch is provided to allow
-easy migration to Getopt::Long for anyone who likes this better. I hope
-this solution is fine for everyone.
-
configuration file -- /etc/Muttrc system-wide, or ~/.muttrc for your
very personal configuration.
+mailcap.t-prot, nailrc.t-prot
+=============================
+Nice and small one-line configuration examples showing how to set up
+metamail and Heirloom mailx ("nail") to use t-prot filtering.
+
t-prot.sl
=========
A small S-Lang macro to show how to use t-prot from within slrn[2].
t-prot package maintainer(s) of your distribution (if the distribution
makes use of said Slang, mutt and gnupg versions).
-t-prot-*-gol.diff
-=================
-Getopt::Mixed is abandoned and marked deprecated by its author, and many
-distributions would like nothing better than to get rid of it. Using this
-patch, you can make t-prot use Getopt::Long (which comes bundled with
-standard perl).
-
-If you know how to deal with the serious performance impacts Getopt::Long
-brings along, please drop me an email. Thanks.
-
-
t-prot-*-mutt15*.diff and t-prot-*-gpg1*.diff
=============================================
You want to be on the bleeding edge, using a developer version of mutt?
OBSOLETE PATCHES
================
+t-prot-*-gol.diff (2nd version)
+===============================
+This patch has been incorporated in t-prot since version 2.95, when
+Getopt::Mixed would have broken existing configurations with the new
+behaviour of the -c command line switch. The performance issues are
+still not solved, though, so if you have an idea how to improve the
+performance of Getopt::Long, please drop a note.
+
t-prot-*-adjtz.diff
===================
This patch has been dropped. Noone seems to make use of it, and it
--- /dev/null
+# $Id: mailcap.t-prot,v 1.1 2010/03/04 18:45:52 jochen Exp $
+# sample line for metamail(1) tools. Put this into your ~/.mailcap.
+text/plain; t-prot --body -mtS --bigq=5,2 -c1 -i %s; copiousoutput
-# $Id: muttrc.t-prot,v 1.10 2010/02/01 23:48:06 jochen Exp $
+# $Id: muttrc.t-prot,v 1.11 2010/02/19 16:21:14 jochen Exp $
# This all works only if you have mutt-1.3.12 or newer
# or if you use something like the pagerfilter patch
# (http://www.escape.de/users/tolot/mutt/).
-set display_filter='t-prot -acelmtS --bigq -Mmutt --spass -L$HOME/.mutt/mlfooters -A$HOME/.mutt/adfooters'
+set display_filter='t-prot -aelmtS -c --bigq -Mmutt --spass -L$HOME/.mutt/mlfooters -A$HOME/.mutt/adfooters'
# toggle TOFU protection with ESC-0 and ESC-1
macro generic \e0 ":unset display_filter\n" "Turn TOFU protection off"
-macro generic \e1 ":set display_filter='t-prot -acelmtS --bigq -Mmutt --spass -L$HOME/.mutt/mlfooters -A$HOME/.mutt/adfooters'\n" "Turn TOFU protection on"
+macro generic \e1 ":set display_filter='t-prot -aclmtS -c --bigq -Mmutt --spass -L$HOME/.mutt/mlfooters -A$HOME/.mutt/adfooters'\n" "Turn TOFU protection on"
# same in pager mode - ugly but what the hell...
macro pager \e0 ":unset display_filter; exec exit\n:exec display-message\n" "Turn TOFU protection off"
-macro pager \e1 ":set display_filter='t-prot -acelmtS --bigq -Mmutt --spass -L$HOME/.mutt/mlfooters -A$HOME/.mutt/adfooters'; exec exit\n:exec display-message\n" "Turn TOFU protection on"
+macro pager \e1 ":set display_filter='t-prot -aelmtS -c --bigq -Mmutt --spass -L$HOME/.mutt/mlfooters -A$HOME/.mutt/adfooters'; exec exit\n:exec display-message\n" "Turn TOFU protection on"
# highlight TOFU protection:
color body brightmagenta black "^\\[---.*"
--- /dev/null
+# This all works only if you have mutt-1.3.12 or newer
+# or if you use something like the pagerfilter patch
+# (http://www.escape.de/users/tolot/mutt/).
+#
+# The $my_tprot variable works since mutt-1.5.12, in older
+# versions you must copy its value in each macro.
+
+set my_tprot='t-prot -aelmtS -c --bigq -Mmutt --spass -L$HOME/.mutt/mlfooters -A$HOME/.mutt/adfooters'
+set display_filter=$my_tprot
+
+# toggle TOFU protection with ESC-0 and ESC-1
+macro generic \e0 ":unset display_filter\n" "Turn TOFU protection off"
+macro generic \e1 ":set display_filter='$my_tprot'\n" "Turn TOFU protection on"
+
+# same in pager mode - ugly but what the hell...
+macro pager \e0 ":unset display_filter; exec exit\n:exec display-message\n" "Turn TOFU protection off"
+macro pager \e1 ":set display_filter='$my_tprot'; exec exit\n:exec display-message\n" "Turn TOFU protection on"
+
+# highlight TOFU protection:
+color body brightmagenta black "^\\[---.*"
+color body green black "^#v[-+]"
--- /dev/null
+# $Id: nailrc.t-prot,v 1.1 2010/03/04 18:45:52 jochen Exp $
+# Use t-prot together with Heirloom mailx(1) (aka "nail").
+# Put something like this definition into your ~/.mailrc.
+set pipe-text/plain="t-prot --body -mtS --bigq"
+++ /dev/null
---- t-prot 2010-02-15 21:13:00.000000000 +0100
-+++ t-prot-gol 2010-02-15 21:20:35.000000000 +0100
-@@ -4,7 +4,7 @@
- require 5.006;
- use strict;
- use Fcntl qw(O_EXCL O_WRONLY O_CREAT);
--use Getopt::Mixed qw(nextOption);
-+use Getopt::Long qw(:config gnu_getopt no_ignore_case);
- use constant VER => '2.15';
- use constant REV => '';
- use constant REL => q$Revision: 1.285 $=~m/(\d+(?:\.\d+)+)/;
-@@ -986,87 +986,87 @@
- (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- my $ifile = '-'; # use STDIN if nothing specified
-
-+# temp vals:
-+my ($_t1, $_t2, $_t3, $_t4, $_t5, $_t6, $_t7, $_t8, $_t9, $_ta, $_tb, $_tc) = undef;
-+
- # get command line params:
--Getopt::Mixed::init('a A=s c d e h i=s k L=s l m M=s o=s P=s p:s r S:i'.
-- ' s t v w bigq:s body check:s debug>d diff ftr-ad ftr-ml groupwise'.
-- ' help>h kminl=i kmaxl=i kdiff=i lax-security locale=s max-lines=i'.
-- ' ms-smart mua>M pgp-short pgp-move pgp-move-vrf reply sani sigsmax:i'.
-- ' spass version>v');
--while (my ($opt, $val, $pretty) = nextOption()) {
-- if ($opt eq 'a') { $ad = 1; }
-- elsif ($opt eq 'A') { $ads = $val; }
-- elsif ($opt eq 'bigq') {
-- if ($val !~ /^(?:(\d+)(?:,(\d+))?)?$/) { help(); }
-- $bigqn = $1?$1:30;
-- $bigqx = $2?$2:10;
-- if ($bigqn<=0 || $bigqx<=0 || $bigqn<=$bigqx) { help(); }
-- }
-- elsif ($opt eq 'body') { $nohdr = 1; $hdrs = 1; }
-- elsif ($opt eq 'c') { $cr = 1; }
-- elsif ($opt eq 'check') {
-- $check = 1;
-- while ($val && $val =~ /^([^,\s]+)(?:,(\S+))?$/) {
-- my $foo = $1;
-- $val = $2;
--
-- if ($foo =~ /^ratio(?:=(0?\.\d+))?$/) {
-- $check_ratio = $1?$1:0.75;
-- }
-- }
-- }
-- elsif ($opt eq 'd') { $sysl = 1; }
-- elsif ($opt eq 'diff') { $diff = 1; }
-- elsif ($opt eq 'e') { $elli = 1; }
-- elsif ($opt eq 'ftr-ad') { $ftr_ad = 1; $ad = 1; }
-- elsif ($opt eq 'ftr-ml') { $ftr_ml = 1; $ml = 1; }
-- elsif ($opt eq 'groupwise') { $gw = 1; }
-- elsif ($opt eq 'i') { $ifile = $val; }
-- elsif ($opt eq 'k') { $kamm = 1; }
-- elsif ($opt eq 'kminl') { $kminl = $val; $kamm = 1; }
-- elsif ($opt eq 'kmaxl') { $kmaxl = $val; $kamm = 1; }
-- elsif ($opt eq 'kdiff') { $kdiff = $val; $kamm = 1; }
-- elsif ($opt eq 'L') { $footers = $val; }
-- elsif ($opt eq 'l') { $ml = 1; }
-- elsif ($opt eq 'lax-security') { $lax = 1; }
-- elsif ($opt eq 'locale') { $locale = $val; }
-- elsif ($opt eq 'm') { $ms = 1; }
-- elsif ($opt eq 'max-lines') { $maxlines = $val; }
-- elsif ($opt eq 'ms-smart') { $ms_smart = 1; $ms = 1; }
-- elsif ($opt eq 'M') {
-- $mua = lc($val);
-+if (!Getopt::Long::GetOptions(
-+ 'a' => \$ad,
-+ 'A=s' => \$ads,
-+ 'bigq:s' => \$_t1,
-+ 'body' => \$_tc,
-+ 'c' => \$cr,
-+ 'check:s' => \$_t9,
-+ 'debug|d' => \$sysl,
-+ 'diff' => \$diff,
-+ 'e' => \$elli,
-+ 'ftr-ad' => \$ftr_ad,
-+ 'ftr-ml' => \$ftr_ml,
-+ 'groupwise' => \$gw,
-+ 'help|h' => \$_t2,
-+ 'i=s' => \$ifile,
-+ 'k' => \$kamm,
-+ 'kminl=i' => \$_t3,
-+ 'kmaxl=i' => \$_t4,
-+ 'kdiff=i' => \$_t5,
-+ 'L=s' => \$footers,
-+ 'l' => \$ml,
-+ 'lax-security' => \$lax,
-+ 'locale=s' => \$locale,
-+ 'max-lines=i' => \$maxlines,
-+ 'ms-smart' => \$ms_smart,
-+ 'mua|M=s' => \$_t7,
-+ 'm' => \$ms,
-+ 'o=s' => \$ofile,
-+ 'P=s' => \$boun,
-+ 'p:s' => \$_t8,
-+ 'pgp-short' => \$pgpshort,
-+ 'pgp-move' => \$pgpmove,
-+ 'pgp-move-vrf' => \$pgpmovevrf,
-+ 'r' => \$hdrs,
-+ 'reply' => \$reply,
-+ 'S:i' => \$_t6,
-+ 's' => \$sig,
-+ 'sani' => \$sani,
-+ 'sigsmax:i' => \$_ta,
-+ 'spass' => \$spass,
-+ 't' => \$trad,
-+ 'version|v' => \$_tb,
-+ 'w' => \$trsp
-+ )) {
-+ help();
-+}
-
-- if ($mua eq 'mutt') {
-- # mutt still displays the message when ^C'ing pgp verification:
-- $SIG{'INT'} = 'sigint_handler';
-- }
-+# clean up temp vals:
-+if (defined $_t1) {
-+ if ($_t1 !~ /^(?:(\d+)(?:,(\d+))?)?$/) { help(); }
-+ $bigqn = $1?$1:30;
-+ $bigqx = $2?$2:10;
-+ if ($bigqn<=0 || $bigqx<=0 || $bigqn<=$bigqx) { help(); }
-+}
-+if (defined $_t2) { help(); }
-+if (defined $_t3) { $kminl = $_t3; $kamm = 1; }
-+if (defined $_t4) { $kmaxl = $_t4; $kamm = 1; }
-+if (defined $_t5) { $kdiff = $_t5; $kamm = 1; }
-+if (defined $_t6) { $lsig = $_t6 ? $_t6 : $maxsig; }
-+if (defined $_t7) {
-+ $mua = lc($_t7);
-+ # mutt still displays the message when ^C'ing pgp verification:
-+ if ($mua eq 'mutt') { $SIG{'INT'} = 'sigint_handler'; }
-+}
-+if (defined $_t8) { $mda = $_t8 ? $_t8 : '1'; }
-+if (defined $_t9) {
-+ $check = 1;
-+ while ($_t9 && $_t9 =~ /^([^,\s]+)(?:,(\S+))?$/) {
-+ my $foo = $1;
-+ $_t9 = $2;
-+ if ($foo =~ /^ratio(?:=(0?\.\d+))?$/) { $check_ratio = $1?$1:0.75; }
- }
-- elsif ($opt eq 'o') { $ofile = $val; }
-- elsif ($opt eq 'P') { $boun = $val; }
-- elsif ($opt eq 'p') { $mda = $val ? $val : '1'; }
-- elsif ($opt eq 'pgp-short') { $pgpshort = 1; }
-- elsif ($opt eq 'pgp-move') { $pgpmove = 1; }
-- elsif ($opt eq 'pgp-move-vrf') { $pgpmovevrf = 1; }
-- elsif ($opt eq 'r') { $hdrs = 1; }
-- elsif ($opt eq 'reply') { $reply = 1; }
-- elsif ($opt eq 'S') { $lsig = $val ? $val : $maxsig; }
-- elsif ($opt eq 's') { $sig = 1; }
-- elsif ($opt eq 'sani') { $sani = 1; }
-- elsif ($opt eq 'sigsmax') { $sign = $val ? $val : undef; }
-- elsif ($opt eq 'spass') { $spass = 1; }
-- elsif ($opt eq 't') { $trad = 1; }
-- elsif ($opt eq 'v') { version(); }
-- elsif ($opt eq 'w') { $trsp = 1; }
-- else { help(); }
- }
--Getopt::Mixed::cleanup();
--if (($ml && $footers eq '')|| # no -l without -L
-- ($ad && $ads eq '')|| # no -a without -A
-- ($nohdr && $pgpshort)|| # --body and --pgp-short are oil and water
-- (($nohdr||$hdrs) && ($sani||$reply))|| # no sanitazing without headers :)
-- ($ifile eq '')|| # no empty -i
-- ($ofile eq '')) # no empty -o
--{ help(); }
--
-+if (defined $_ta) { $sign = $_ta ? $_ta : undef; }
-+if (defined $_tb) { version(); }
-+if (defined $_tc) { $nohdr=1; $hdrs=1; }
-+if ($ms_smart) { $ms = 1; }
-
- if ($mua eq 'mutt') {
- if (defined $locale && $locale ne '' && $locale ne 'C' && $locale ne 'POSIX') {
-@@ -1131,6 +1131,14 @@
-
- }
- elsif ($ms_smart || $pgpshort || $pgpmove || $pgpmovevrf) { help(); }
-+
-+if (($ml && $footers eq '')|| # no -l without -L
-+ ($ad && $ads eq '')|| # no -a without -A
-+ ($nohdr && $pgpshort)|| # --body and --pgp-short are like oil and water
-+ (($nohdr||$hdrs) || ($sani||$reply))|| # no sanitizing without headers :)
-+ ($ifile eq '')|| # no empty -i
-+ ($ofile eq '')) # no empty -o
-+{ help(); }
-
-
- # Read message:
-% $Id: t-prot.sl,v 1.17 2006/05/16 11:33:32 jochen Exp $
+% $Id: t-prot.sl,v 1.18 2010/02/19 16:21:14 jochen Exp $
% Copyright (c) 2003-2005 Jochen Striepe <t-prot@tolot.escape.de>
%
% This file is provided as an example implemention for articles to be
%
% If you are not happy with the suggested t-prot default parameters,
% put something like
-% variable t_prot_params = "-cemtS";
+% variable t_prot_params = "-c -emtS";
% variable t_prot_tmpdir = "$HOME/.tmpdir";
% variable t_prot_qp = "";
% into ~/.slrn/t-prot-cfg and add
% these should be reasonable defaults (they work fine for me, SCNR):
-variable t_prot_params = "-aceklmtS --diff --bigq -L$HOME/.slrn/mlfooters -A$HOME/.slrn/adfooters";
+variable t_prot_params = "-aeklmtc -S --diff --bigq -L$HOME/.slrn/mlfooters -A$HOME/.slrn/adfooters";
variable t_prot_tmpdir = "$HOME/tmp/slrn"; % you better make sure it exists
variable t_prot_qp = "perl -i -p -e '$p=1 if /^Content-Transfer-Encoding: quoted-printable/i; if ($p==1) { s/=([0-9a-f][0-9a-f])/chr(hex($1))/egi; s/=\n//eg; };'";
#!/usr/bin/perl -w
-# $Id: t-prot,v 1.285 2010/02/15 20:13:00 jochen Exp $
+# $Id: t-prot,v 1.298 2010/03/06 01:32:50 jochen Exp $
require 5.006;
use strict;
use Fcntl qw(O_EXCL O_WRONLY O_CREAT);
-use Getopt::Mixed qw(nextOption);
-use constant VER => '2.15';
+use Getopt::Long qw(:config gnu_getopt no_ignore_case);
+use constant VER => '2.97';
use constant REV => '';
-use constant REL => q$Revision: 1.285 $=~m/(\d+(?:\.\d+)+)/;
+use constant REL => q$Revision: 1.298 $=~m/(\d+(?:\.\d+)+)/;
# MTA expecting mail on STDIN
# (you might have to adjust this if using a different MTA)
use constant SENDMAIL => '/usr/sbin/sendmail -oi';
use constant EX_IOERR => 74;
use constant EX_BOUNCE => EX_UNAVAILABLE;
use vars qw(
- $ad $ads $bigqn $bigqx $boun $check $check_ratio $cr $diff $elli
+ $ad $ads $bigqn $bigqx $boun $check $check_ratio $cr $crshrink $diff $elli
$footers $ftr_ad $ftr_ml $hdrs $indent $kamm $kdiff $kminl $kmaxl
$lax $lsig $maxsig $maxlines $mda $ml $gw $ms $ms_smart $msg_quote
$msg_ratio $mua $nohdr $ofile $pgpshort $pgpmove $pgpmovevrf $reply
$0 =~ s!^.*/!!;
$maxsig = 4; # max. valid signature length
$maxlines = undef; # no limit of message lines
+$crshrink = 2; # multiple blank lines are shrunk to $crshrink lines
$indent = '>'; # Indent string, regexp to identify a quoted line
$kminl = 65; # see decomb() for details
$kmaxl = 80;
# help(): print help text and exit with appropriate exit code
sub help {
print "Usage: $0 [options]
- -A=DIRECTORY ad footer directory, treat ad footers as signature
+ -A DIRECTORY ad footer directory, treat ad footers as signature
-a remove ad footers; requires -A
--bigq[=n[,x]] remove all but x lines of quotes with more than n
lines; default is n=30 and x=10
--body input has no headers; does not work with --pgp-short;
multipart messages will not be detected
- -c merge multiple blank lines
+ -c[n] merge multiple blank lines to n lines (default is 2)
--check[=FLAGS] check various criteria, print error message and quit;
see man page for details
-d, --debug print notice to syslog when bouncing; requires -p
- --diff tolerate diffs appended *after* the signature
+ --diff tolerate diffs
-e force ellipsis for excessive punctuation
--ftr-ad enable aggressive ad footer matching; requires -A
--ftr-ml enable aggressive mailing list footer matching; req. -L
--groupwise delete Novell Groupwise style TOFU
-h, --help show this short help and exit
- -i=INFILE file to be read; '-' for STDIN (default)
+ -i INFILE file to be read; '-' for STDIN (default)
-k try to fix \"Kammquotes\"
- --kminl=n min. line length for wrapped line; requires -k
- --kmaxl=n max. line length for wrapped line; requires -k
--kdiff=n max. length difference between wrapped lines; req. -k
- -L=DIRECTORY mailing list footer directory, treat mailing list
+ --kmaxl=n max. line length for wrapped line; requires -k
+ --kminl=n min. line length for wrapped line; requires -k
+ -L DIRECTORY mailing list footer directory, treat mailing list
footers as signature
-l delete mailing list footer; requires -L
--lax-security use unsafe writing method; USE ON YOUR OWN RISK!
-m delete MS style TOFU; careful: might be too agressive
--max-lines=x maximum number of message lines
--ms-smart try to be smart with MS style TOFU; req. -Mmutt and -m
- -o=OUTFILE file to be written to; '-' for STDOUT (default), 'NONE'
- for no output at all
- -P=MESSAGE user defined bounce message; requires -p
- -p[=ADDRESS] redirect to ADDRESS if no TOFU was found
+ -o OUTFILE file to be written to; '-' for STDOUT (default)
+ -P MESSAGE user defined bounce message; requires -p
+ -p[ADDRESS] redirect to ADDRESS if no TOFU was found
--pgp-move move pgp verification output to bottom; requires -Mmutt
--pgp-move-vrf move pgp output if verified and good; requires -Mmutt
--pgp-short hide non-relevant pgp key uids; requires -Mmutt
-r delete mail header lines
--reply squeeze multiple reply prefixes in subject line
- -S[=n] supress signatures with more than n lines (default $maxsig)
+ -S[n] supress signatures with more than n lines (default $maxsig)
-s delete signature
--sani sanitize some header fields
--sigsmax[=n] max number of sigs tolerated, no value for unlimited
my $x = $k-$bigqx;
$i -= $k;
- $$L[$i] = "[---=| Quote block shrinked by $0: " .
+ $$L[$i] = "[---=| Quote block shrunk by $0: " .
"$x lines snipped |=---]\n";
$i++;
splice(@$L, $i, $x-1);
my $O = shift;
my $l;
- if ((!$lax) && ($O =~ /^>(.*)/) && ($1 ne '-')) {
+ if ((!$lax) && ($O =~ /^>(.*)/) && ($1 ne '-') && ($1 ne '/dev/null')) {
if (!sysopen(OUT, $1, O_EXCL|O_CREAT|O_WRONLY)) {
print STDERR "Could not open $1: $!\n"; exit(EX_IOERR);
}
if ($$lines[$x] =~ /^\s*#v([+-])$/) {
$verb = $1 eq '+' ? 1 : 0;
$vrb[$x] = 1;
+ } elsif ($diff && $$lines[$x] =~ /^[0-9]+a([0-9]+),([0-9]+)$/) {
+ # Detect and protect standard diffs.
+ # Skip and proceed to next line if premature file end or diff line
+ # numbers implausible (so it might be not a diff at all).
+ if ($1>$2 || $x+$2-$1+1>$#$lines) { next; }
+ $vrb[$x] = 1;
+ for (my $i=0; $i<$2-$1+1; $i++) { $vrb[++$x] = 1; }
+ } elsif ($diff && $$lines[$x] =~ /^([0-9]+),([0-9]+)c([0-9]+),([0-9]+)$/) {
+ if ($1!=$3 || $1>$2 || $3>$4 || $x+$2-$1+$4-$3+3>$#$lines) { next; }
+ $vrb[$x] = 1;
+ for (my $i=0; $i<$2-$1+$4-$3+3; $i++) { $vrb[++$x] = 1; }
} else { $vrb[$x] = $verb; }
}
my $x = 1;
for (my $i=$#$lines; $i>=0; $i--) {
+ if ($vrb[$i]) { last; }
if ($$lines[$i] =~ /^$indent/o) {
$j++;
$k = $i;
(($mua eq 'mutt' && $$lines[$x] =~ /^\e[^\a]+\a\s*$/o) ||
$$lines[$x] =~ /^\s*$/o))
{
- if ($t<2) { $t++; } else { splice(@$lines, $x, 1); }
+ if ($t<$cr) { $t++; } else { splice(@$lines, $x, 1); }
}
else { $t = 0; }
}
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
my $ifile = '-'; # use STDIN if nothing specified
+# temp vals:
+my ($_t1, $_t2, $_t3, $_t4, $_t5, $_t6, $_t7, $_t8, $_t9, $_ta, $_tb, $_tc,
+ $_td) = undef;
+
# get command line params:
-Getopt::Mixed::init('a A=s c d e h i=s k L=s l m M=s o=s P=s p:s r S:i'.
- ' s t v w bigq:s body check:s debug>d diff ftr-ad ftr-ml groupwise'.
- ' help>h kminl=i kmaxl=i kdiff=i lax-security locale=s max-lines=i'.
- ' ms-smart mua>M pgp-short pgp-move pgp-move-vrf reply sani sigsmax:i'.
- ' spass version>v');
-while (my ($opt, $val, $pretty) = nextOption()) {
- if ($opt eq 'a') { $ad = 1; }
- elsif ($opt eq 'A') { $ads = $val; }
- elsif ($opt eq 'bigq') {
- if ($val !~ /^(?:(\d+)(?:,(\d+))?)?$/) { help(); }
- $bigqn = $1?$1:30;
- $bigqx = $2?$2:10;
- if ($bigqn<=0 || $bigqx<=0 || $bigqn<=$bigqx) { help(); }
- }
- elsif ($opt eq 'body') { $nohdr = 1; $hdrs = 1; }
- elsif ($opt eq 'c') { $cr = 1; }
- elsif ($opt eq 'check') {
- $check = 1;
- while ($val && $val =~ /^([^,\s]+)(?:,(\S+))?$/) {
- my $foo = $1;
- $val = $2;
-
- if ($foo =~ /^ratio(?:=(0?\.\d+))?$/) {
- $check_ratio = $1?$1:0.75;
- }
- }
- }
- elsif ($opt eq 'd') { $sysl = 1; }
- elsif ($opt eq 'diff') { $diff = 1; }
- elsif ($opt eq 'e') { $elli = 1; }
- elsif ($opt eq 'ftr-ad') { $ftr_ad = 1; $ad = 1; }
- elsif ($opt eq 'ftr-ml') { $ftr_ml = 1; $ml = 1; }
- elsif ($opt eq 'groupwise') { $gw = 1; }
- elsif ($opt eq 'i') { $ifile = $val; }
- elsif ($opt eq 'k') { $kamm = 1; }
- elsif ($opt eq 'kminl') { $kminl = $val; $kamm = 1; }
- elsif ($opt eq 'kmaxl') { $kmaxl = $val; $kamm = 1; }
- elsif ($opt eq 'kdiff') { $kdiff = $val; $kamm = 1; }
- elsif ($opt eq 'L') { $footers = $val; }
- elsif ($opt eq 'l') { $ml = 1; }
- elsif ($opt eq 'lax-security') { $lax = 1; }
- elsif ($opt eq 'locale') { $locale = $val; }
- elsif ($opt eq 'm') { $ms = 1; }
- elsif ($opt eq 'max-lines') { $maxlines = $val; }
- elsif ($opt eq 'ms-smart') { $ms_smart = 1; $ms = 1; }
- elsif ($opt eq 'M') {
- $mua = lc($val);
-
- if ($mua eq 'mutt') {
- # mutt still displays the message when ^C'ing pgp verification:
- $SIG{'INT'} = 'sigint_handler';
- }
- }
- elsif ($opt eq 'o') { $ofile = $val; }
- elsif ($opt eq 'P') { $boun = $val; }
- elsif ($opt eq 'p') { $mda = $val ? $val : '1'; }
- elsif ($opt eq 'pgp-short') { $pgpshort = 1; }
- elsif ($opt eq 'pgp-move') { $pgpmove = 1; }
- elsif ($opt eq 'pgp-move-vrf') { $pgpmovevrf = 1; }
- elsif ($opt eq 'r') { $hdrs = 1; }
- elsif ($opt eq 'reply') { $reply = 1; }
- elsif ($opt eq 'S') { $lsig = $val ? $val : $maxsig; }
- elsif ($opt eq 's') { $sig = 1; }
- elsif ($opt eq 'sani') { $sani = 1; }
- elsif ($opt eq 'sigsmax') { $sign = $val ? $val : undef; }
- elsif ($opt eq 'spass') { $spass = 1; }
- elsif ($opt eq 't') { $trad = 1; }
- elsif ($opt eq 'v') { version(); }
- elsif ($opt eq 'w') { $trsp = 1; }
- else { help(); }
+if (!Getopt::Long::GetOptions(
+ 'a' => \$ad,
+ 'A=s' => \$ads,
+ 'bigq:s' => \$_t1,
+ 'body' => \$_tc,
+ 'c:i' => \$_td,
+ 'check:s' => \$_t9,
+ 'debug|d' => \$sysl,
+ 'diff' => \$diff,
+ 'e' => \$elli,
+ 'ftr-ad' => \$ftr_ad,
+ 'ftr-ml' => \$ftr_ml,
+ 'groupwise' => \$gw,
+ 'help|h' => \$_t2,
+ 'i=s' => \$ifile,
+ 'k' => \$kamm,
+ 'kminl=i' => \$_t3,
+ 'kmaxl=i' => \$_t4,
+ 'kdiff=i' => \$_t5,
+ 'L=s' => \$footers,
+ 'l' => \$ml,
+ 'lax-security' => \$lax,
+ 'locale=s' => \$locale,
+ 'max-lines:i' => \$maxlines,
+ 'ms-smart' => \$ms_smart,
+ 'mua|M=s' => \$_t7,
+ 'm' => \$ms,
+ 'o=s' => \$ofile,
+ 'P=s' => \$boun,
+ 'p:s' => \$_t8,
+ 'pgp-short' => \$pgpshort,
+ 'pgp-move' => \$pgpmove,
+ 'pgp-move-vrf' => \$pgpmovevrf,
+ 'r' => \$hdrs,
+ 'reply' => \$reply,
+ 'S:i' => \$_t6,
+ 's' => \$sig,
+ 'sani' => \$sani,
+ 'sigsmax:i' => \$_ta,
+ 'spass' => \$spass,
+ 't' => \$trad,
+ 'version|v' => \$_tb,
+ 'w' => \$trsp
+ )) {
+ help();
}
-Getopt::Mixed::cleanup();
-if (($ml && $footers eq '')|| # no -l without -L
- ($ad && $ads eq '')|| # no -a without -A
- ($nohdr && $pgpshort)|| # --body and --pgp-short are oil and water
- (($nohdr||$hdrs) && ($sani||$reply))|| # no sanitazing without headers :)
- ($ifile eq '')|| # no empty -i
- ($ofile eq '')) # no empty -o
-{ help(); }
+# clean up temp vals:
+if (defined $_t1) {
+ if ($_t1 !~ /^(?:(\d+)(?:,(\d+))?)?$/) { help(); }
+ $bigqn = $1?$1:30;
+ $bigqx = $2?$2:10;
+ if ($bigqn<=0 || $bigqx<=0 || $bigqn<=$bigqx) { help(); }
+}
+if (defined $_t2) { help(); }
+if (defined $_t3) { $kminl = $_t3; $kamm = 1; }
+if (defined $_t4) { $kmaxl = $_t4; $kamm = 1; }
+if (defined $_t5) { $kdiff = $_t5; $kamm = 1; }
+if (defined $_t6) { $lsig = $_t6 ? $_t6 : $maxsig; }
+if (defined $_t7) {
+ $mua = lc($_t7);
+ # mutt still displays the message when ^C'ing pgp verification:
+ if ($mua eq 'mutt') { $SIG{'INT'} = 'sigint_handler'; }
+}
+if (defined $_t8) { $mda = $_t8 ? $_t8 : '1'; }
+if (defined $_t9) {
+ $check = 1;
+ while ($_t9 && $_t9 =~ /^([^,\s]+)(?:,(\S+))?$/) {
+ my $foo = $1;
+ $_t9 = $2;
+ if ($foo =~ /^ratio(?:=(0?\.\d+))?$/) { $check_ratio = $1?$1:0.75; }
+ }
+}
+if (defined $_ta) { $sign = $_ta ? $_ta : undef; }
+if (defined $_tb) { version(); }
+if (defined $_tc) { $nohdr=1; $hdrs=1; }
+if (defined $_td) { $cr = $_td ? $_td : $crshrink; }
+if ($ms_smart) { $ms = 1; }
if ($mua eq 'mutt') {
if (defined $locale && $locale ne '' && $locale ne 'C' && $locale ne 'POSIX') {
}
elsif ($ms_smart || $pgpshort || $pgpmove || $pgpmovevrf) { help(); }
+
+if (($ml && $footers eq '')|| # no -l without -L
+ ($ad && $ads eq '')|| # no -a without -A
+ ($nohdr && $pgpshort)|| # --body and --pgp-short are like oil and water
+ (($nohdr||$hdrs) && ($sani||$reply))|| # no sanitizing without headers :)
+ ($ifile eq '')|| # no empty -i
+ ($ofile eq '')) # no empty -o
+{ help(); }
# Read message:
# First, check msg length and stop processing if msg is too long:
if ((defined $maxlines) && (@message > $maxlines)) {
- if ($ofile ne 'NONE') {
- if ($mua eq 'mutt') {
- my $x = 0;
- if (!$nohdr) {
- do { $x++; } while ($x<$#message && $message[$x]!~/^$/);
- $x++;
- }
- splice(@message, $x, 0,
- ("[---=| Processing by $0 skipped: message too long |=---]\n\n"));
+ if ($mua eq 'mutt') {
+ my $x = 0;
+ if (!$nohdr) {
+ do { $x++; } while ($x<$#message && $message[$x]!~/^$/);
+ $x++;
}
-
- write_msg(($mda?'|'.SENDMAIL." $mda":">$ofile"), \@message);
+ splice(@message, $x, 0,
+ ("[---=| Processing by $0 skipped: message too long |=---]\n\n"));
}
+ write_msg(($mda?'|'.SENDMAIL." $mda":">$ofile"), \@message);
+
if ($mua eq 'mutt') { exit(EX_OK); }
exit(EX_DATAERR);
}
process_msg(\@message);
# Finally, print clean lines:
-if ($ofile ne 'NONE') {
- write_msg(($mda?'|'.SENDMAIL." $mda":">$ofile"), \@message);
-}
+write_msg(($mda?'|'.SENDMAIL." $mda":">$ofile"), \@message);
# vim600:set foldmethod=marker:
# eof
-.\" $Id: t-prot.1,v 1.157 2010/02/15 20:08:19 jochen Exp $
+.\" $Id: t-prot.1,v 1.178 2010/03/06 01:31:33 jochen Exp $
.\"
-.TH T-PROT "1" "February 2010" "T-PROT"
+.TH T-PROT "1" "March 2010" "T-PROT"
.SH NAME
t-prot \- TOFU Protection - Display Filter for RFC 5322 messages
.SH SYNOPSIS
.br
The filter is written in Perl and relies on input to be a single
message conforming to RFC 822 or its successors, RFC 2822 and RFC 5322.
-Messages conforming to RFCs 2045-2049 should be treated reasonably correct.
+In messages conforming to MIME (RFCs 2045-2049) t\-prot handles text/plain
+parts, others are not touched.
.PP
Already reformatted messages are handled well: the script was
initially designed to cope with the output of the MUA mutt (which
proof\-of\-concept filter for INN2, which you will have to adapt to
the needs of the news site you host (please see the file for details).
.SH OPTIONS
+.PP
+If you do not specify any options, t\-prot does ... nothing. Every
+feature you want must be turned on explicitely.
+Admittedly, we have quite a number of options for t\-prot. To limit
+confusion they are grouped into five sections: Input/Output Options,
+Advertisement And Mailing List Footers, Filtering Options, Detection
+Options, and Other Options. While the others should be quite clear,
+filtering and detection might deserve a word (or two).
+.PP
+If you want to tune the appearance of your mail from within your MUA
+(or news messages from within your NUA), then go for the Filtering
+Options section.
+.PP
+If you want to use t\-prot to check on mails before they are submitted
+to mailing lists, fed to your news server, or delivered by your MDA,
+then have a peek at the Detection Options section. You may accept or
+reject/bounce messages depending on t\-prot's result.
+.SH INPUT/OUTPUT OPTIONS
.TP
-.BR "\-A" =DIRECTORY
-"ad footer directory":
-Defines the directory which contains the advertisement list footers (one
-footer per file) which are to be tested when removing them with options
-.B \-a
-or
-.BR \-\-ftr\-ad .
-.br
-This option is also needed if you do not want signature lengths to be
-counted wrong or fullquotes get undetected when an ad footer is
-appended at the bottom of the message (especially when using
-.B "\-S"
-or
-.BR "\-t" ).
+.BR "\-i" " FILE"
+Defines an input file; default is '\-' i.e. STDIN.
+.TP
+.BR "\-o" " FILE"
+Defines the output file; default is STDOUT.
+.TP
+.B "\-\-body"
+Input consists just of the message's body. There are no RFC 5322 header
+lines.
+.IP
+.IR NOTE :
+This does not work with \-\-pgp\-short, and multipart messages will not
+be detected due to missing headers.
+.TP
+.B "\-\-lax\-security"
+Allow insecure writing method. DO NOT USE UNLESS YOU REALLY KNOW WHAT
+YOU ARE DOING. (This ugly workaround is needed for some early mutt versions
+and should NEVER be used as a default, otherwise it will probably turn into
+a security issue.)
+.sp
+You can use this option safely to enable
+.BR "\-o" " /dev/null."
+.TP
+.BR "\-\-max\-lines" =x
+Maximum number of lines a message may count (with headers). If the message
+is longer than x lines, the message will not be processed but printed
+unmodified. Exit status will be EX_DATAERR except when called with \-Mmutt.
+.SH ADVERTISEMENT AND MAILING LIST FOOTERS
.TP
.B "\-a"
"commercial signature":
.br
This option compares the last lines of the message body with any
footer file found in the directory specified with
-.BR "\-A" =DIRECTORY
+.BR "\-A" " DIRECTORY"
(which is mandatory for this option). The comparison is done by perl's
.B index()
function (please try
.B \-\-ftr\-ad
is specified.
.TP
-.BR "\-\-bigq" [=n[,x]]
-"shrink big quotes":
-Blocks of quotes with more than n lines will be shrunk to x lines.
-Defaults are 30 for n and 10 for x.
-.TP
-.B "\-\-body"
-Input consists just of the message's body. There are no RFC 5322 header
-lines.
-.IP
-.IR NOTE :
-This does not work with \-\-pgp\-short, and multipart messages will not
-be detected due to missing headers.
-.TP
-.B "\-c"
-"compress":
-Squeezes a sequence of blank lines to just two blank lines.
-.TP
-.BR "\-\-check" [=FLAGS]
-Run checks. If successful, print an error message and quit with
-an appropriate exit code. Useful e.g. for rejecting messages from
-within INN2.
-.IP
-Flags are separated by commas (no whitespaces), and can be the
-following (right now just one flag):
-.IP
-.IR ratio [=n]
-.br
-If the quoting ratio is n or more, the message is rejected. Must be
-between 0 and 1, or else it is entirely disabled. Default is 0.75
-(i.e., 75% of the message lines are quotes).
-.TP
-.B "\-d, \-\-debug"
-Print envelope info to syslog when bouncing TOFU contaminated email.
-Default syslog facility is mail.debug. Requires
-.BR \-p .
-.TP
-.B "\-\-diff"
-"tolerate diff":
-Tolerate unified diff (see
-.BR diff (1)
-and
-.BR patch (1))
-appended *after* the signature (which usually makes the signature too long
-to be valid). Not entirely consequent but sometimes useful, e.g. at the
-Linux kernel mailing list.
-.TP
-.B "\-e"
-"ellipsis":
-Squeezes a sequence of four or more dots, exclamation marks, or question marks
-to only three dots or marks, respectively.
-.TP
.B "\-\-ftr\-ad"
"enable aggressive ad footer matching":
With this option enabled, t-prot makes footer detection really greedy: We
.sp
.IR NOTE :
This requires a directory with footer files to be given with option
-.BR "\-A" =DIRECTORY.
+.BR "\-A" " DIRECTORY".
+.TP
+.BR "\-A" " DIRECTORY"
+"ad footer directory":
+Defines the directory which contains the advertisement list footers (one
+footer per file) which are to be tested when removing them with options
+.B \-a
+or
+.BR \-\-ftr\-ad .
+.br
+This option is also needed if you do not want signature lengths to be
+counted wrong or fullquotes get undetected when an ad footer is
+appended at the bottom of the message (especially when using
+.B "\-S"
+or
+.BR "\-t" ).
+.TP
+.B "\-l"
+"list signature":
+Hides "footers" (signatures) from mailing lists. Footer detection works like the
+.B "\-a"
+option.
+.sp
+.IR NOTE :
+This requires a directory with footer files to be given with option
+.BR "\-L" " DIRECTORY".
+.B \-l
+is not needed if
+.B \-\-ftr\-ml
+is specified.
.TP
.B "\-\-ftr\-ml"
"enable aggressive mailing list footer matching":
.sp
.IR NOTE :
This requires a directory with footer files to be given with option
-.BR "\-L" =DIRECTORY.
+.BR "\-L" " DIRECTORY".
.TP
-.B "\-\-groupwise"
-Hides TOFU as produced by Novell Groupwise.
+.BR "\-L" " DIRECTORY"
+"list footer directory":
+Defines the directory which contains the mailing list footers (one footer
+per file) which are to be tested when removing them with the options
+.B \-l
+or
+.BR \-\-ftr\-ml .
+.br
+This option is also needed if you do not want signature lengths to be
+counted wrong or fullquotes get undetected when a mailing list footer is
+appended at the bottom of the message (especially when using
+.B "\-S"
+or
+.BR "\-t" ).
+.SH FILTER OPTIONS
.TP
-.B "\-h, \-\-help"
-Displays a short help text with a summary on all options, and exits.
+.BR "\-\-bigq" [=n[,x]]
+"shrink big quotes":
+Blocks of quotes with more than n lines will be shrunk to x lines.
+Defaults are 30 for n and 10 for x.
.TP
-.BR "\-i" =FILE
-"input file":
-Defines a file for input; the default input is from '\-' i.e. STDIN.
+.BR "\-c" " [n]"
+"compress":
+Squeezes a sequence of blank lines to just n blank lines. n defaults to 2.
+.TP
+.B "\-\-diff"
+Tolerate unified diff (see
+.BR diff (1)
+and
+.BR patch (1))
+appended after the signature (which usually makes the signature too long
+to be valid).
+.sp
+Also, protect diff standard output from hiding (which would otherwise be easy
+prey for
+.BR "\-t" ).
+.TP
+.B "\-e"
+"ellipsis":
+Squeezes a sequence of four or more dots, exclamation marks, or question marks
+to only three dots or marks, respectively.
+.TP
+.B "\-\-groupwise"
+Hides TOFU as produced by Novell Groupwise.
.TP
.B "\-k"
"anti Kammquote":
Requires
.BR "\-k" .
.TP
-.BR "\-L" =DIRECTORY
-"list footer directory":
-Defines the directory which contains the mailing list footers (one footer
-per file) which are to be tested when removing them with the options
-.B \-l
-or
-.BR \-\-ftr\-ml .
-.br
-This option is also needed if you do not want signature lengths to be
-counted wrong or fullquotes get undetected when a mailing list footer is
-appended at the bottom of the message (especially when using
-.B "\-S"
-or
-.BR "\-t" ).
-.TP
-.B "\-l"
-"list signature":
-Hides "footers" (signatures) from mailing lists. Footer detection works like the
-.B "\-a"
-option.
-.sp
-.IR NOTE :
-This requires a directory with footer files to be given with option
-.BR "\-L" =DIRECTORY.
-.B \-l
-is not needed if
-.B \-\-ftr\-ml
-is specified.
-.TP
-.B "\-\-lax\-security"
-Allow insecure writing method. DO NOT USE UNLESS YOU REALLY KNOW WHAT
-YOU ARE DOING. (This ugly workaround is needed for some early mutt versions
-and should NEVER be used as a default, otherwise it will probably turn into
-a security issue.)
-.TP
.BR "\-\-locale" =LOCALE
-"locale to use":
-Here you can specify which locale to use. Right now this option is only
-used when
+Specify which locale to use for correct parsing of your MUA's formatting
+of the displayed message (usually it is the locale your MUA uses). Right
+now this option is only used when
.I "\-Mmutt"
is specified, but this may change in future. You need the Perl module
.I "Locale::gettext"
.br
and some header lines...)
.TP
-.BR "\-\-max\-lines" =x
-Maximum number of lines a message may count (with headers). If the message
-is longer than x lines, the message will not be processed but printed
-unmodified. Exit status will be EX_DATAERR except when called with \-Mmutt.
-.TP
.B "\-\-ms\-smart"
-Burn CPU cycles trying to be smart with MS style TOFU.
+Burn CPU cycles trying to be smart with MS style TOFU: If there are PGP
+signed parts inside the TOFU, the text still might conceal other message
+parts and therefore should not be deleted.
.sp
Please note that this is probably just a waste of time because most
MS Outlook users who do produce this kind of TOFU won't care about
.BR "\-Mmutt" " and"
.BR "\-m" .
.TP
-.BR "\-o" =FILE
-"output file":
-Define the file to be written *to*; the default output is to STDOUT.
-.sp
-If "NONE" is specified as file name, there will be no output at all (useful
-if all you need is t-prot's exit code). Use something like "./NONE" if you
-really want to write to a file of this name.
-.TP
-.BR "\-P" =MESSAGE
-"user defined bounce message for picky delivery":
-You may specify your own bounce message to be returned when we try to deliver
-an email and bounce it because there is TOFU inside. See
-.BR "\-p" .
-.TP
-.BR "\-p" [=ADDRESS]
-"picky delivery":
-If we really find some TOFU, abort with exit code
-.IR EX_UNAVAILABLE .
-Otherwise redirect the message to ADDRESS if given.
-.sp
-Intended for use from within mail delivery agents (MDAs) or mail transport
-agents (MTAs), or even from with INN, so the message bounces if TOFU is
-detected, and does not get on *your* nerves. :)
-.sp
-As an example for usage with
-.BR sendmail ,
-put this line into your alias file and invoke
-.BR newaliases :
-.sp
-notofu: |"/usr/local/bin/t\-prot \-mt \-p=user@mydomain"
-.sp
-This will bounce messages for <notofu@domainname> if any TOFU is detected
-inside the message, and deliver it to <user@mydomain> otherwise.
-.I Note
-that TOFU is only detected if you specify
-.B "\-t"
-respectively
-.BR "\-m" .
-.sp
-.B PLEASE be careful not to bounce messages to mailing lists!
-.TP
.B \-\-pgp\-move
Move PGP verification output to bottom; requires
.BR "\-Mmutt" .
.TP
.B \-\-pgp\-move\-vrf
-Move PGP verification outout to bottom only if verification shows a good signature
+Move PGP verification output to bottom only if verification shows a good signature
and the signature could be verified as authentic (using a trust path). If there is
any problem with the signature, the PGP output should not be moved so the user is
more likely to notice. Requires
Subject lines with multiple reply prefixes (Re: and translations into other
languages) get squeezed to only one prefix.
.TP
-.BR "\-S" [=n]
+.BR "\-S" " [n]"
"supression of overlong signatures":
Signatures are to be n lines (not including the one containing dash-dash-space)
or less. If there are more, it is probably not that spirited after all.
Hides trailing whitespace (sequences of space and tab).
CAVEAT: This may lead to interesting effects with crossposts
between mailing lists or with undetected signature attempts.
+.SH DETECTION OPTIONS
+.TP
+.BR "\-P" " MESSAGE"
+"user defined bounce message for picky delivery":
+You may specify your own bounce message to be returned when we try to deliver
+an email and bounce it because there is TOFU inside. See
+.BR "\-p" .
+.TP
+.BR "\-p" " [ADDRESS]"
+"picky delivery":
+If we really find some TOFU, abort with exit code
+.IR EX_UNAVAILABLE .
+Otherwise redirect the message to ADDRESS if given.
+.sp
+Intended for use from within mail delivery agents (MDAs) or mail transport
+agents (MTAs), or even from with INN, so the message bounces if TOFU is
+detected, and does not get on *your* nerves. :)
+.sp
+As an example for usage with
+.BR sendmail ,
+put this line into your alias file and invoke
+.BR newaliases :
+.sp
+notofu: |"/usr/local/bin/t\-prot \-mt \-p=user@mydomain"
+.sp
+This will bounce messages for <notofu@domainname> if any TOFU is detected
+inside the message, and deliver it to <user@mydomain> otherwise.
+.I Note
+that TOFU is only detected if you specify
+.B "\-t"
+respectively
+.BR "\-m" .
+.sp
+.B PLEASE be careful not to bounce messages to mailing lists!
+.TP
+.BR "\-\-check" [=FLAGS]
+Run checks. If successful, print an error message and quit with
+an appropriate exit code. Useful e.g. for rejecting messages from
+within INN2.
+.IP
+Flags are separated by commas (no whitespaces), and can be the
+following (right now just one flag):
+.IP
+.IR ratio [=n]
+.br
+If the quoting ratio is n or more, the message is rejected. Must be
+between 0 and 1, or else it is entirely disabled. Default is 0.75
+(i.e., 75% of the message lines are quotes).
+.TP
+.B "\-d, \-\-debug"
+Print envelope info to syslog when bouncing TOFU contaminated email.
+Default syslog facility is mail.debug. Requires
+.BR \-p .
+.SH OTHER OPTIONS
+.TP
+.B "\-h, \-\-help"
+Displays a short help text with a summary on all options, and exits.
.TP
.B "\-v, \-\-version"
-Prints the current version number and release date, and exits.
+Prints the current version number and exits.
.SH ENVIRONMENT
The environment variables
.IR LC_ALL ,