Article 12675 of comp.lang.perl:
Xref: feenix.metronet.com comp.mail.mh:1938 comp.lang.perl:12675
Newsgroups: comp.mail.mh,comp.lang.perl
Path: feenix.metronet.com!news.utdallas.edu!chpc.utexas.edu!cs.utexas.edu!howland.reston.ans.net!europa.eng.gtefsd.com!emory!news-feed-2.peachnet.edu!concert!sas!mozart.unx.sas.com!sherman
From: [email protected] (Chris Sherman)
Subject: Re: Trying to get back the "From {from} {date}" field...
Sender: [email protected] (Noter of Newsworthy Events)
Message-ID: <sherman.766278429@charger>
Date: Wed, 13 Apr 1994 23:07:09 GMT
References: <[email protected]>
Nntp-Posting-Host: charger.unx.sas.com
Organization: SAS Institute Inc.
Lines: 196

In <[email protected]> [email protected] (DJ AladdinSane) writes:

>       Here's the problem: When a mail message gets dropped in my
>spool file, it has a header that looks remarkably like this:

>From [email protected]  Tue Mar 29 22:53:08 1994

>       However, by the time it gets into my mh folders, this header
>has been cruelly snatched away. For my own arcane reasons (I want to
>use either Eudora or Easy View as off-line readers for old mail on my
>Mac) I need to recover this field and put it back where it belongs at
>the head of the mail message.

Perhaps the following program will help...  It attempts to reconstruct
the From line using several rules...  It's not perfect, but it usually
works.

Standard disclaimers apply.  Always be careful where your mail files are
concerned.  Don't blindly trust that this program worked correctly before
you go to blow away your old mh files.

Please send me any bug reports along with whatever amounts of heinous
verbal abuse you think applies.

Remember to adjust the first line of the script to point to your perl
binary.

-------- Cut -- Cut --  Ouch!!! -- snip -- snip ------------------
#!/usr/local/bin/perl

# To format of the command line should be:
#   mh2elm <elm file> <mh files>
#
# where <elm file> is the resulting elm-formatted mail file, and <mh files>
# is a list of files which are mh-formatted mail files.
#
# This program will then convert all the mh-formated files into one
# elm-formated file.
#
# Be careful not to name the elm file the same as any of the mh files.
#
# This program will run on any machine which has perl installed

&show_usage if ($#ARGV < 1);

$true = 1;
$false = 0;

$elm_file = shift;      # get the first argument, shift the rest left

# renamed the old elm file, if one exists
if (-r $elm_file)
{
 print "$elm_file exists, renaming to ${elm_file}.old\n";
 rename($elm_file, $elm_file . ".old");
}

# open elm file for writing
open($ELM,">$elm_file");

foreach $mh_file (@ARGV)                # On the remaining mh files...
{
 $header = $true;                      # we are in the header of the mail
 $return_path_found = $false;          # true if we have found a return path
 $from_found = $false;                 # true if we have a valid from: line
 $date_found = $false;
 @whole_thing = ();                    # clear array;

 print "Adding $mh_file to $elm_file...  ";
 $no_problem = open(MH,$mh_file);
 if (! $no_problem)
 {
   print "Can't open $mh_file, skipping...\n";
   next;
 }

 while (<MH>)
 {
   if ($header == $true)
   {
     if (/^Reply-To: ([^ \n]+)/)
     {
       $reply_to = $1;
       $reply_to_found = $true;
     }

     elsif (/^Return-Path: ([^ \n]+)/)
     {
       $return_path = $1;
       $return_path_found = $true;
     }

     # look for line with 'From: name <address>' in it
     elsif (/^From: [^<]*<([^>]+)>/)
     {
        $from = $1;
        $from_found = $true;
     }

     # look for line with 'From: address'
     elsif (/^From: ([^ \n]+)/ && $from_found == $false)
     {
        $from = $1;
        $from_found = $true;
     }

     elsif (/^Date: /)
     {
       ($Date, $day, $date, $month, $year, $time, $zone) = split;
       $zone =~ tr/a-z/A-Z/;           # convert to upper case
       $year =~ s/^([0-9])([0-9])$/19$1$2/;    # convert 2 digit year to 4
       $time =~ s/(..:..):../$1/;      # removed seconds part
       $day  =~ s/(...),/$1/;          # remove comma
       $date_found = $true;
     }

     $header = $false if length == 1;
   }
 } continue {
   push(@whole_thing, $_);             # add line to array
 }

 close(MH);

 # use the return_path as the sender if we have it, otherwise use from: line
 if ($reply_to_found == $true)
 {
   $sender = $reply_to;
 }

 # use the return_path as the sender if we have it, otherwise use from: line
 elsif ($return_path_found == $true)
 {
   $sender = $return_path;
 }

 # use the return_path as the sender if we have it, otherwise use from: line
 elsif ($from_found == $true)
 {
   $sender = $from;
 }

 # if none of them were found, give an error and skip
 else
 {
   print "A Reply-To, Return-Path: nor From: line was not found in ";
   print "$mh_file, skipping...\n";
   next;
 }

 if ($date_found == $false)
 {
   print "The Date: line was not found in $mh_file, skipping...\n";
   next;
 }

 $from_line = sprintf("From %s %s %s %2s %s %s %s\n",
   $sender, $day, $month, $date, $time, $zone, $year);

 # output the new letter
 print $ELM $from_line;                # print the new from line
 print $ELM @whole_thing,"\n";         # print everything else
 print "Done.\n";
}

close(ELM);

exit;

sub show_usage
{
 print <<"*EOF*";

Usage:

To format of the command line should be:
 mh2elm <elm file> <mh files>

where <elm file> is the resulting elm-formatted mail file, and <mh files>
is a list of files which are mh-formatted mail files.

This program will then convert all the mh-formated files into one
elm-formated file.

Be careful not to name the elm file the same as any of the mh files.

This program will run on any machine which has perl installed.

*EOF*
}

--
    ____/     /     /     __  /    _  _/    ____/
   /         /     /     /   /      /     /          Chris Sherman
  /         ___   /        _/      /          /
_____/   __/   __/   __/ _\    _____/   _____/           [email protected]