procmail
[Top] [All Lists]

Re: The results of the help I got here.

1999-08-18 04:28:06
On Wed, 18 Aug 1999 13:08:24 +0300 (EET DST), era eriksson
<era(_at_)iki(_dot_)fi> wrote:
    # Set SUBJECT and FROM as proposed earlier

    :0b
    | support.pl

and then in support.pl, 

    $From=$ENV{"FROM"}
    $Subj=$ENV{"SUBJECT"}  # instead of $ARGV trickery
    $Inbox = <>;           # slurp message body from standard input

Sorry, my "quick notes" grew rather long already but there's one thing
I wanted to clarify because this is one of the things that get asked a
lot and I'm not sure if anybody ever posted an explicit solution to
handling headers in your Perl script instead of letting Procmail do
the FROM and SUBJECT grabbing.

So, you could of course pass in the headers as well and let the script
figure this out for itself. The main thing you have to look out for is
continued header fields. Something like this:

    while (<>)
    {
        last if /^$/;  # end of headers, move to body processing

        if (/\^s/) # or maybe if s/^\s\s+/ /;
        {   # continued header field, glue this line onto the previous one
            $value{$header} .= $_;
            next;
        }

        unless (m/^([-A-Za-z0-9_]+):/)
        {
            warn "Weird non-header $_";
            next;
        }

        $header = lc($1);

        # The if is unnecessary here, you might as well grab all headers
        if ($header eq "from" || $header eq "subject")
        {
            $value{$header} = $_;
        }
    }

    # What remains of stdin is the body
    $Inbox = <>;

    # If you want to, copy the captured hash values to scalars
    # $From = $value{"from"} || warn "No From header\n";
    # $Subject = $value{"subject"} || warn "No Subject header\n";

You could play around with references instead of hashes if you
understand how to do that but it's probably more trouble than it's
worth. Hashes are a good solution to a lot of problems. I put in the
(commented-out) copying into $From and $Subject in case you don't want
to change the other parts of your script which already use these
variable names, but it's otherwise unnecessary.

Some locking issues still preoccupy me, does Perl's dbm routines take
care of concurrency issues if you have two messages arriving roughly

Some of the recipes I posted still had concurrency problems; it's
necessary to lock fromt until support.pl has finished running if I
analyzed your logic correctly. But I think getting rid of fromt and
the temporary files in general is a better solution. Even if dbm takes
care of locking for you, it might be prudent to use a local lock file
on the recipe which calls support.pl (now with headers as well as body
being piped to the script):

    :0:support.lock
    | support.pl

Hope this helps,

/* era */

-- 
 Too much to say to fit into this .signature anyway: <http://www.iki.fi/era/>
  Fight spam in Europe: <http://www.euro.cauce.org/> * Sign the EU petition