Re: format and output all received: lines in an e-mail message

2019-11-21 Thread Steffen Nurpmeso
Andy Bradford wrote in <20191121072709.1303.qm...@angmar.bradfordfamily.org>:
 |Thus said Greg Minshall on Wed, 20 Nov 2019 10:41:34 +0530:
 |> then, i'd like  to use something like fmttest(1) to  print out all the
 |> "Received:" lines in an e-mail message. ideally, each "Received:" line
 |> would come  out on a  separate line; less  ideally, but i'm  sure very
 |> practical, a very  long line would come out, with  some odd ascii code
 |> separating the individual lines.
 |
 |I usually use  822field (from mess822 [1]) for this  kind of thing which
 |takes all received lines and reformats them one per line (odd ascii code
 |separating them is a newline).
 |
 |For example, your message looks like:
 |
 |$ 822field received < `mhpath cur` | tail -6   
 | from eggs.gnu.org ([2001:470:142:3::10]:33280) by lists.gnu.org with \
 ...

Well, yes, it is a bit restricted, but you could also use S-nail
v14.9.11 or later:

  $ printf 'dig c 25 -;dig 25 h s received;digmsg r 25' |\
s-nail -#Rf +download
  212 Received
  from lists.gnu.org (lists.gnu.org [209.51.188.17]) by sdaoden.eu (Postfix) 
with ESMTPS id 977431604A for ; Thu, 21 Nov 2019 15:28:01 
+0100 (CET)
  from localhost ([::1]:41250 helo=lists1p.gnu.org) by lists.gnu.org with esmtp 
(Exim 4.90_1) (envelope-from 
) id 1iXnR9-000318-IA for 
stef...@sdaoden.eu; Thu, 21 Nov 2019 09:27:59 -0500
  from eggs.gnu.org ([2001:470:142:3::10]:39911) by lists.gnu.org with esmtp 
(Exim 4.90_1) (envelope-from ) id 1iXnQr-0002zm-Am for 
nmh-workers@nongnu.org; Thu, 21 Nov 2019 09:27:42 -0500
  from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from 
) id 1iXnQq-0007yp-1j for nmh-workers@nongnu.org; Thu, 
21 Nov 2019 09:27:41 -0500
  from pellegrino.bradfordfamily.org ([208.53.44.231]:50897) by eggs.gnu.org 
with smtp (Exim 4.71) (envelope-from ) id 
1iXnQp-0007uL-NM for nmh-workers@nongnu.org; Thu, 21 Nov 2019 09:27:39 -0500
  (qmail 73392 invoked from network); 21 Nov 2019 14:27:26 -
  from localhost (HELO arnor.bradfordfamily.org) (127.0.0.1) by localhost with 
SMTP; 21 Nov 2019 14:27:26 -
  (qmail 71469 invoked from network); 21 Nov 2019 14:27:10 -
  from localhost (HELO edoras.bradfordfamily.org) (127.0.0.1) by localhost with 
SMTP; 21 Nov 2019 14:27:10 -
  (qmail 50445 invoked from network); 21 Nov 2019 14:27:10 -
  from angmar.bradfordfamily.org (50.77.44.21) by edoras.bradfordfamily.org 
with SMTP; 21 Nov 2019 14:27:10 -
  (qmail 27684 invoked by uid 1000); 21 Nov 2019 14:27:10 -

Where dig is actually digmsg, c is create, h is header, s is show,
and r is remove.  String matching etc. via the csop and vexpr
commands.
I have heared someone revived qmail and wants to include some
patches for builtin TLS etc.  That sounded very much interesting,
especially if its mailing-list manager would be maintained again!

 |Andy
 |
 |[1] https://cr.yp.to/mess822.html
 ...

--steffen
|
|Der Kragenbaer,The moon bear,
|der holt sich munter   he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)



Re: format and output all received: lines in an e-mail message

2019-11-21 Thread Andy Bradford
Thus said Greg Minshall on Wed, 20 Nov 2019 10:41:34 +0530:

> then, i'd like  to use something like fmttest(1) to  print out all the
> "Received:" lines in an e-mail message. ideally, each "Received:" line
> would come  out on a  separate line; less  ideally, but i'm  sure very
> practical, a very  long line would come out, with  some odd ascii code
> separating the individual lines.

I usually use  822field (from mess822 [1]) for this  kind of thing which
takes all received lines and reformats them one per line (odd ascii code
separating them is a newline).

For example, your message looks like:

$ 822field received < `mhpath cur` | tail -6   
 from eggs.gnu.org ([2001:470:142:3::10]:33280) by lists.gnu.org with esmtp 
(Exim 4.90_1) (envelope-from ) id 1iXIOr-0005CP-UD for 
nmh-workers@nongnu.org; Wed, 20 Nov 2019 00:19:34 -0500
 from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from 
) id 1iXIOq-00089z-NS for nmh-workers@nongnu.org; Wed, 20 Nov 
2019 00:19:33 -0500
 from hiwela.pair.com ([209.68.5.201]:21038) by eggs.gnu.org with esmtp (Exim 
4.71) (envelope-from ) id 1iXIOq-00088d-K6 for 
nmh-workers@nongnu.org; Wed, 20 Nov 2019 00:19:32 -0500
 from hiwela.pair.com (localhost [127.0.0.1]) by hiwela.pair.com (Postfix) with 
ESMTP id 001419805E3 for ; Wed, 20 Nov 2019 00:11:43 
-0500 (EST)
 from minshall-entroware-apollo.cliq.com (unknown [59.95.74.169]) (using 
TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client 
certificate requested) by hiwela.pair.com (Postfix) with ESMTPSA id 89AEF8F084C 
for ; Wed, 20 Nov 2019 00:11:43 -0500 (EST)
 from apollo2.minshall.org (localhost [IPv6:::1]) by 
minshall-entroware-apollo.cliq.com (Postfix) with ESMTP id E305D6089A for 
; Wed, 20 Nov 2019 10:41:34 +0530 (IST)

Andy

[1] https://cr.yp.to/mess822.html
-- 
TAI64 timestamp: 40005dd69ee2





Re: format and output all received: lines in an e-mail message

2019-11-21 Thread Paul Fox
greg wrote:
 > ps -- the goal is a little "blame" script for e-mail that tells you how
 > long a given message spent moving from A to B.  (this relies, of course,
 > on globally synchronized clocks, but that seems much more likely to be
 > true today than it did when Received: lines were first introduced.)

Oh, why didn't you say so. :-)  Don't know if he's still on the list,
but I cribbed this from Chris Garrigues many many years ago.  Takes a
raw message on stdin.

paul

#!/usr/bin/perl -w
#
# mailroute by Chris Garrigues 
#
# Reads an email message on stdin and pretty prints the contents of the
# recieved headers.
#
# When given an email message as it's argument will parse out the received
# headers and display the route it took to get to you and the times it
# arrived at each of the locations in your local timezone.
#
# It also tries to be clever in how it displays things:  (1) It only shows
# what changed in the date/time rather than the entire date/time each time. 
# (2) It breaks the line before the keywords "from", "by", and "with"
# unless they appear in comments.

# Changes by Mikko H�nninen 
#
# - match non-numeric timezones, as well as more liberal number checking
# - allow for two digit years as well as four digits (actually, any number
#   of digits)
# - also display Delivered-To: lines amidst Received: information
# - timezone conversion works even with timezones like +0745
# - somewhat prettier output (split at by/with/from) for non-recognised
#   date lines
# - print time difference from first entry
# - print time different always, even if it's the same as previous time
#   (so you can see where each hop is)
# - added "id" and "for" to keywords before which a linebreak is added
# - print date information on a separate line, so there's no need to reserve
#   columns for it on every line
# - print malformed received lines (cannot parse date) "as-is" with no
#   offset


use Time::Local;

# Global variable for date parsing
%mon = ('jan' => 0,
'feb' => 1,
'mar' => 2,
'apr' => 3,
'may' => 4,
'jun' => 5,
'jul' => 6,
'aug' => 7,
'sep' => 8,
'oct' => 9,
'nov' => 10,
'dec' => 11);

# Initialize some variables to keep -w quiet
($owd, $om, $od, $ot, $oy) = ("", "", "", "", "");


# Perl trim function to remove whitespace from the start and end of the string
sub trim($)
{
my $string = shift;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return $string;
}


# Read the headers into $_
($_ = "\n" . join("", <>)) =~ s/\n\n.*$//sg;

# Parse the contents of the received headers into an array
@rec = ();
while (/\n(received|delivered-to):(.*?)(\n\S)/gis) {
unshift(@rec, "$1:$2");
#print "Adding $1: $2\n";
$_ = "$3$'";
}
#while (/\nreceived:(.*?)(\n\S)/gis) {
#unshift(@rec, $1);
#print "Adding Received: $1\n";
#$_ = "$2$'";
#}


for (@rec) {
if (/^delivered-to:/i) {
  s/^delivered-to://i;  # strip Delivered-To:
  s/\s+/ /gs;
  s/^\s+//;
  print "   Delivered-To: $_\n";
}
else {
  s/^received://i;  # strip Received:
  s/\s+/ /gs;

  # Format is "information; date"
  ($line, $date) = /^\s*(.*?)\s*;\s*(.*?)$/;
  if (!$date) {
# no date, must be malformed? simscan will produce these
# just print it out and go to next
print "   ", trim($_), "\n";
next;
  }

  $date =~ s/\(.*\)//g;
  $date =~ s/\s+/ /gs;
  # Parse the sucker
  if ($date =~ /(\d+) (jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec) 
(\d+) (\d+):(\d\d):(\d\d) ([+-]?\d+|\w+)/i) {
# Coerce the date into something we can give to timegm
$d = $1;
($m = $2) =~ tr/A-Z/a-z/;
$y = $3;
$h = $4;
$mi = $5;
$s = $6;
$tz = $7;
if ($tz =~ /[+-]?\d+/) { ($zs, $zh, $zm) = $tz =~ 
/^([-+])(\d\d)(\d\d)$/; }
  else { $zs = "+"; $zh = $zm = 0; }  # word tz def, assume GMT
$m = $mon{$m};
if ($y > 1900) { $y -= 1900; } elsif ($y < 70) { $y += 100; }  # Y2K fix
if ($zs eq "+") { $zs = 1; } else { $zs = -1; }
$ts = timegm($s, $mi, $h, $d, $m, $y) -
 $zs * ($zh*60*60 + $zm*60);
$begints = $ts unless ($begints);
($wd, $m, $d, $t, $y) = split(' ', localtime($ts));
$d = " $d" if ($d < 10);
# Insert line breaks
$line =~ s/\b(by|with|from|id|for)\b/\n   $1/g;
# But take them back out if they're in a comment
while ($line =~ s/\(([^()]*?)\s\s+?(.*?)\)/\($1 $2\)/gs) {};
$line =~ s/\( /\(/g;
$line =~ s/^\s*//s;
# Figure out what parts of the date we want to display
($pwd, $pm, $pd, $pt, $py) = ($wd, $m, $d, $t, $y);
$pwd = "" if ($wd eq $owd);
$pm = "" if ($d eq $od);
#$pm = "" if ($m eq $om);
$pd = "" if ($d eq $od);
$pt = "" if ($t eq