procmail
[Top] [All Lists]

Re: Please check my procmail recipe

1996-02-20 11:03:55
Pamela Greene <pgreene(_at_)optics(_dot_)rochester(_dot_)edu> writes:
If the message is to "submit", not a loop, and not also sent to "queue",
{
       pass it to the file_message script
       also pass it to the save-faq program
       if save-faq exited with nonzero status
       {
               send the reply save-faq generated (in stdout)
               exit this recipe, but continue on to later recipes
       }
       otherwise
       {
               send the reply save-faq generated
               send the incoming mail to "queue"
              continue on to later recipes
       }
}

Since you're *always* going to be continuing on, just place a 'c' flag
on the outside block, and don't continue past the last two of the
inner.  The rephrased and rearranged:

If the message is to "submit" but not "queue", and not a loop, then
fork and do the following: {
        feed a copy into the file_message program
        feed a copy into the save-faq program, saving the stdout in
                the variable OUTPUT
        if save-faq was successful, then
                send a copy of the message to "queue"
        reverse the headers
        send $OUTPUT to the (now reversed) headers
}


## If the message is to "submit" but not "queue", and not a loop, then
## fork and do the following: {
:0 c
* ^TOsubmit
* !^TOqueue
* !^FROM_DAEMON
{
        ## feed a copy into the file_message program
        :0 c
        |/usr/local/file_message

        ## feed a copy into the save-faq program, saving the stdout
        ##      in the variable OUTPUT
        :0 c
        OUTPUT=|/usr/local/save-faq

        ## if save-faq was successful, then
        ##      send a copy of the message to "queue"
        :0 a
        | formail -i "Resent-To: queue" | $SENDMAIL -oi queue
        # The "Resent-To:" bit is so that the message shows the
        # fact that it's going to the "queue" address.  Leave this
        # off and the condition at the top of the block recipe won't
        # work right.

        ## reverse the headers
        :0 fh
        |formail -rt

        ## send $OUTPUT to the (now reversed) headers
        :0 h
        | (cat -; echo $OUTPUT) | $SENDMAIL -oi -t
}


NOTES:
a)      Always put a zero after the colon that begins the recipe.
        In the first versions of procmail, you would put the number
        of conditions, with a default of 1.  That was annoying, and
        the computer can do the counting easier, so Stephen made it
        so that a count of 0 indicates that the condition are all the
        lines beginning with a '*'.  However, if you leave out the
        number, IT WILL STILL DEFAULT TO 1.
        Always put a zero after the colon.  :-)

b)      From the procmailrc(5) manpage CAVEATS:

     Continued lines in an action line that specifies  a  program
     always  have  to  end in a backslash, even if the underlying
     shell would not need or want the backslash to indicate  con-
     tinuation.   This  is  due  to  the two pass parsing process
     needed (first procmail, then the shell (or not, depending on
     SHELLMETAS)).
...
     Environment variables set inside  the  shell-interpreted-`|'
     action  part  of  a recipe will not retain their value after
     the recipe has finished since they are set in a subshell  of
     procmail.  To make sure the value of an environment variable
     is retained you have to put the assignment to  the  variable
     before  the  leading `|' of a recipe, so that it can capture
     stdout of the program.

        Your attempt suffered from both of these 'gotchas'.
        This can usually be fixed by not relying on the shell
        so much, but rather doing the 'if/then/else' processing
        via procmail's 'a' and 'E' flags.  This particular
        problem does require carrying around two message bodies
        momentarily (the output of save-faq and the original message
        that still needs to be sent to "queue"), so you have to
        do the FOO=| action bit.

c)      Always extract common actions out of loops and blocks.
        Since you'll always want continue past the block, just make
        the block do the continuing.  Since you'll always mail
        the output of save-faq back to the user, don't put that
        in the conditional.  This generally simplifies things.
        For example, since we put a 'c' flag on the block, we
        can go ahead and reverse the message headers using a
        filter without losing the original message for later
        recipes.


Have fun!


Philip Guenther

----------------------------------------------------------------
Philip Guenther                 UNIX Systems and Network Administrator
Internet: guenther(_at_)gac(_dot_)edu   Phonenet: (507) 933-7596
Gustavus Adolphus College       St. Peter, MN 56082-1498
Source code never lies (it just misleads).  (Programming by Purloined Letter?)

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