Subject: Re: Yet Another Mail Splitting Question (YAMSQ)

From: Alan Stebbens <[email-masked]>
Date: Tue, 11 Apr 1995 16:04:01 -0700

> folks,  I've got a bunch of separate files where procmail has carefully
> squirreled away incoming messages per my own specifications.  So far
> so good.  Now, it turns out that every now and then I'd like to
> perform one or more of the following operations:
> 
> 1) split the mail out into separate files, of the form: msg.####,
>    with the twist that the timestamp on the file is the same as
>    the date/time the message was received.  This lets me use standard
>    Unix tools for schlepping through the messages.
> 
>    (we have the "touch" command thst accepts an explicit timestamp,
>     if that helps).

Try this Perl script in combination with "formail -s".

First, create the Perl script "makemsg", which acts as a filter:

(OH yeah: warning! this is untested -- use at your own risk).

============================= cut here ===================================
#!/bin/sh
# Feed this to "sh"
cat <<'EOF' > makemsg
#!/usr/bin/perl
# script to make incoming mail go into "msg.###", where ###
# is a serial number and the file is time-stamped to the date of the mail
#
# Uses "timelocal.pl" to convert parts of a timestamp into seconds of
# the Epoch.
require 'timelocal.pl';

@msgs = (<msg.*>);		# get the list of current
if (@msgs) {
    $last = pop(@msgs);
    $last = s/msg\.//;
    ($next = $last)++;		# autoincrement the serial number
} else {
    $next = '1';
}
$msg = sprintf("msg.%04d",$next);	# ensure leading zeroes
print STDERR "Creating $msg..\n";
open(MSG,">$msg") || die "Can't create $msg: $!\n";
while (<>) {
    if (!$date && /^Date:\s*(\S.*\S/\s*$/) {	# date field?
	$date = $1;			# get the date filed
    }
    print MSG;				# output
}
close MSG;
if ($date =~ /\w+, (\d+) (\w+) (\d+) (\d+):(\d+):(\d+)) {
    ($dd,$month,$yyy,$hh,$mm,$ss) = ($1,$2,$3,$4,$5);
    @Months = split('Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec');
    @Months{@Months} = (0..11);
    $mon = $Months{$month};
    $time = &timelocal($ss,$mm,$hh,$dd,$mon,$yy);
    utime($time,$time,$msg);
}
exit;
EOF
chmod +x makemsg
============================= cut here ===================================

Next, to process a bunch of mail in, say, MAILSPOOL, use "formail":

    formail -s makemsg < MAILSPOOL

> 2) split the mail in separate files, of the form: author.####, where
>    'author' might be either the domain-qualified return address in
>    the From: line, or some reworked version of the "human readable"
>    name that is usually set off in parens, or quotes on the From line.
>    Assume that there's a suitable awk or perl script called "munge"
>    that will rework the printable name.  Oh, and best is if the ####
>    sequence is uniquel for each author, ie, fred,0001, fred.0002,
>    george.0001, george.0002.  And lastly, each file timestamped
>    as in 1) above.
> 
> Any help, hints, or code fragments would be greatly appreciated.

Use a script similar to the above.  The details are left to the reader.