procmail
[Top] [All Lists]

Re: Create new mail with procmaily

1997-01-15 09:31:48
Jim Dennis <jimd(_at_)starshine(_dot_)org> writes:
      If I understand it correctly the default
      is to pass the header and the body to the 
      action (filter, file, or forward).  If one adds
      the 'h' or 'b' flags to the :0 line if affects
      which parts of the message are fed to the action
      and the 'H' and 'B' flags affect which parts are
      parsed by the various Condition lines.
...

Yes.


      If I understand further it is possible to overide
      the flags on the :0 line for a given conditional
      using the '??' operator on a '*' line.  I gather
      this works like so:

              :0 B
              * H ?? !^TO_whoever
              * (rich quick)
              # search the header for "not To: whoever"
              # and the body for the phrase "rich quick"
              # feed header and body to the action.

Correct.



      I also noticed something inscrutable about using
      variables before the ?? operator.  I didn't find
      any examples of this in procmailex (the only one
      there was using it to over-ride the :0 flags)

      Would that be something like:

              :0
              * $HOME ?? ^X-HomeDir:\/.*

      Matches any header with a X-HomDir line that matches
      my home directory environment variable?

Not quite.  You put just the name of the variable before the ??,
without a $.  This causes procmail to, instead of grepping the header
and/or body (as specified by the H and B flags), instead try to match
the given regexp against what is stored in the variable specified.
I.e.:

        # Execute something if SOMEVAR contains the value "foo"
        :0
        * SOMEVAR ?? ^^foo^^
        |something

The partial recipe you show, once the '$' on "$HOME" is removed, checks
to see whether the path of your home directory starts with
"X-Homedir:".  It doesn't (unless you've been screwing with HOME).  If
you want to do something iff there's an X-Homedir: header that contians
your home directory, then you should just interpolate HOME into the
condition:

        :0
        * $ ^X-Homedir: *$HOME\$
        |something

The trailing dollar is backwhacked to keep procmail from trying to do
variable interpolation.  After the expansion it will look like a naked
dollar and will match end-o'-line.  If you're feeling really paranoid
you can use $\HOME instead of $HOME to protect against HOME containing
regexp meta-characters, but since all the home directories I know of
contain just alphanumeric and slashes, I don't think that's particularly
necessary.

Now, let's say you want a match if the X-Homedir: header's value is a
path-wise prefix for you home directory.  For example, if the header's
value was "/Net/solen/u8" then it would be a match if your home
directory was "/Net/solen/u8/accstaff/guenther", but not if your home
directory was "/Net/solen/u8b/something" or "/Net/solen/u1/something".
To do that, we'll have to extract the value into MATCH, then use that
($MATCH) as the regexp to match against HOME:

        :0
        * ^X-Homedir: *\/[^ ]+
        * HOME ?? $ ^$MATCH(/|\$)
        |something

Okay, let's break this apart:

        * ^X-Homedir: *\/[^ ]+

Attempt to match the regexp "^X-Homedir: *[^ ]+" against the header.
If it matches, then take what matched the "[^ ]+" part and stick it
in the variable MATCH and keep going:

        * HOME ?? $ ^$MATCH(/|\$)

First, expand as if it was double quoted the following:

                ^$MATCH(/|\$)

This will presumably turn into something like:

                ^/Net/solen/u8(/|$)

Now take that as a regexp and match it against the contents of the
variable HOME.  Perform the action if it matches.

Make sense?


       It also seems like I can do something like:

              :0
              * ? /path/to/some/script

      ... which apparently tells procmail to run the 
      external script or binary and use that program's
      exit status as the truth value for the whole line.
      Does procmail feed the header (H -- default) to 
      the external script?

It appears from the source that the specified program will have
whatever would have been grepped at it's standard in.  You could
even say:

        :0
        * HOME ?? /some/program/that/wants/$HOME/on/its/stdin
        ...etc

Though you're more likely to this feature via the H and/or B flags,
or with "HB ??" to get the entire message at stdin.


      If that's true then:

              :0
              * ? /bin/egrep

      Would be almost identical to testing using the internal
      egrep.

Yes, only slower, no \/ with $MATCH, etc.


      Sorry to be so pesky -- but this stuff isn't really
      clear from the docs and it takes a long time to 
      reverse engineer it through experimentation.  I'll
      be delighted to share anything that I do put together.

Use The Source, Luke!

Philip Guenther