procmail
[Top] [All Lists]

Re: Mail Again question

1997-08-13 00:43:00
On Tue, 12 Aug 1997 16:05:00 -0400 (EDT), Charles Gagnon
<charlesg(_at_)Nynexst(_dot_)COM> wrote:
At first, I thought of writing something in Perl that would do the job
but afterwards I figured I could probably do the same thing with
procmail. Do you think I could write some sort of mail file filter that
would:
  procmail -m mail.aging.rc /var/mail/$username
And the mail file would come out with only 90 days old or younger
messages in it. Procmail would've deleted all the older messages in the
file?

The hard part, whether you do it in Procmail or in Perl, is getting
reliable date parsing. A reasonable approximation would be to assume
that the messages in the mbox file are in chronological order, and
ditch everything up to the first From_ line that has a new enough date
stamp. 
  There's GNU date, which often does a fair job of parsing odd-looking
dates, or you could try mdate, a program which was posted to this list
last spring. (You'll find a pointer at 
    <http://www.iki.fi/~era/procmail/links.html#mdate>)
I don't think you particularly need or benefit from using Procmail,
but formail and lockfile are good tools to have for this kind of
thing.

    # untested pseudo code -- test, debug, and/or use at your own risk
    # Requires GNU date

    # snatch old spool file to /tmp

    lockfile /var/mail/$username
    mv /var/mail/$username /tmp/mail.$username
    lockfile -u /var/mail/$username

    # process old spool file -- use ditch-if-old to ditch old messages

    formail -s ditch-if-old /tmp/ditchdata `date -d'90 days ago' +'%s'` \
        < /tmp/mail.$username >/tmp/new.$username

    # merge whatever is left with what mail might have arrived meanwhile

    lockfile /var/mail/$username
    cat /var/mail/$username >>/tmp/new.$username
    mv -f /tmp/new.$username /var/mail/$username
    lockfile -u /var/mail/$username

    # clean up

    rm /tmp/mail.$username /tmp/new.$username

ditch-if-old:

    # untested pseudo code -- test, debug, and/or use at your own risk
    # Requires GNU date

    # once we've stopped ditching, we cat everything straight back out

    test -f "$1" && exec cat -

    # read From_ line with the date stamp; extract it

    read line1

    datestamp=`echo "$line1" | sed -e 's/^From [^ ]* *//'`
    newdate=`date -d"$datestamp" +'%s'`

    # if the date stamp is newer than $2, stop ditching

    if [ "$2" -lt "$newdate" ]; then
        touch "$1"
        echo "$line1"
        exec cat -
    fi

    # silently ignore standard input, i.e. ditch it

Yes, it might be more efficient to do it all, or part of it, in Perl.
The big win is that formail does the hairy details of taking apart the
mbox file, and date does the date parsing for you, but you could of
course call them from within Perl, for example. 

/* era */

I haven't tested if my shell's test can cope with those big numbers. 
date +%s gives 871455488 (this %s thing is also a GNU extension).

-- 
Defin-i-t-e-ly. Sep-a-r-a-te. Gram-m-a-r.  <http://www.iki.fi/~era/>
 * Enjoy receiving spam? Register at <http://www.iki.fi/~era/spam.html>

<Prev in Thread] Current Thread [Next in Thread>