procmail
[Top] [All Lists]

Re: selective mail forwarding

1997-06-29 10:58:00
On Sun, 29 Jun 1997 12:05:38 -0400 (EDT),
Tam Ho <tam(_at_)tis(_dot_)nerc(_dot_)com> wrote:
I'm thinking I could do it this way:

     <have procmail output entire message> | \
     <an external perl or c program proccesses message and
             outputs e-mail addresses> | \
     <procmail takes e-mail addresses and forwards messages to them>

I'm thinking this is more like it:

    :0
    * criteria? 
    ! `an external perl or c program ...`

Anything executed by backticks in a procmail recipe file gets the
message on its standard input so what remains is merely to write the
program you need. 

The criteria:  In the tag, there is a PROVIDER {} section (refer
to below).  There can be anywhere from 0 to 20 lines in this section.
<...>
PROVIDER,{
"SRP",,"SRPM","G;F",,,"","",""
,"SRP","SPRM","F","SRP-LIB","T","","",""
"WALC",,,,"LIB",,"","",""
,,"SRPM","F","LIB-MED2",,"","",""
,,,,"MED2",,"","",""
,"NEVP","NEVPP","F","MED2-NEVP","T","","",""
"NEVP",,"NEVPP","L",,,"","",""

Ugh, are you using Microsoft programs to produce this? 

Should we assume every string inside double quotes is a tag you want
to extract, or do you want only the first one on each line? 

Can a record continue on the next line? (Relevant if you only want the
first field of each.)

Assuming you want them all, but don't want the empty records, the
extraction could be done something like this: 

    sed -e '1,/^PROVIDER,{/d' -e '/}/,$d' -e 'y/",/  /' | \
        tr -s ' ' '\012' | grep . | sort -u    

You can pipe this to `join' to get the corresponding e-mail address,
provided that you can keep the tag-to-address list in sorted order
(join requires this). See the manual page for join for all the gory
details -- join is a bit cumbersome to get right, so I'll not risk
giving you any false leads you need to debug later. 

In the end, it might just be easier to do it all in Perl (the silly
comments are because I assume you are not fluent in Perl):

    # Set up associative array of tag-to-address mappings

    %tags = ( 'SRP' => 's(_at_)rp(_dot_)whatever', 'MOO' => 
'moo(_at_)iki(_dot_)fi', # ... );

    # Read a message with tags on standard input

    while (<>)
    {
        # React only on stuff in the PROVIDER,{ ... } block (kinda like awk)

        if (/^PROVIDER,{/ .. /^}/)
        {
            next if (/^PROVIDER/ || /^}/);   # Skip block beg && end
            chomp;                      # Eat trailing newline

            for $tag (split (/,/))      # Divide on commas
            {
                $tag =~ s/^"|"$//g;     # Eat fragging quotes on both sides
                                        # (ugh, tastes horrible)
                # Ignore emtpy tag and unknown; complain if unknown, tho

                if (!$tags{$tag})
                {
                    warn "Eeek: unknown tag `$tag'" unless ($tag eq "");
                    next;
                }

                # If this is a tag we haven't seen before, add the
                #  corresponding address to the @addies array

                push (@addies, $tags{$tag}) unless ($done{$tag});
                $done{$tag} = "Yeah, I've seen this tag already";
            }
        }

    }

    # Print out the stuff that ended up in @addies

    print join (" ", @addies), "\n";

This is, as usual, off the top of my head and largely untested. 
  Still, hope this helps,

/* era */

-- 
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>