Author: W B Hacker Date: To: exim users Subject: Re: [exim] Pass custom variable on to next router
Online4You wrote: > Hi,
>
> We're trying to setup some extra routers in our Debian exim4 config to check
> for per-mailbox anti-spam settings. Some of these routers just check the
> mySQL database for the customer setting in the "condition" and then add a
> mail header so it is marked for later on. Then after several checks, the
> mail is checked for these marks and should be acted on accordingly.
>
> Now I've just found out that adding and removing headers isn't the way to
> exchange information between routers because those are not effective until a
> transport is reached.
>
> How can I pass on information between routers so the next router can check
> for something set in the previous router?
>
> I'm looking for something like the $acl_m0 - $acl_m9 facility in the ACL but
> then for use in routers.
>
> Thanks for helping out on this!
>
> Martijn
>
>
You are in luck. Maybe. All the acl_m(x) variable 'final state', i.e. on
leaving acl_smtp_data, are stored in the queue with the message headers & body.
Even though any given 'label' for a variable, 'acl_m4', for example, will have
been re-used, perhaps hundreds of times, by other child processes or later
arrivals, those that were in effect at the time acl_smtp_data completed can
still be called on by a router or transport and by the same label they had when
stored, e.g. acl_m4, (for that message) etc.
That's the good news, and if all you need is per-message, not per-recipient,
then you are home free. Read no further.
The 'maybe' is the case where you DO want per-recipient information.
Just as headers added in acl_smtp_data are per-message, not per-recipient, so
too are the acl_m(x) values. TANSTAAFL.
Headers added in router/transport code OTOH, are per-delivery - i.e per
recipient for on-box delivery, per connection for remote_smtp, so don't overlook
their value.
There is a kludge with aclM(x) variables, wherein it is easy to *store*
per-recipient information into an acl_m variable, because you can build a string
of arbitrary format by successive concatenation during the acl_smtp_rcpt phase.
Getting specific information back *out* of the structure you have built, on the
other hand, may requires either some form of 'calculated' lookup, BFBI, or a
for-next loop or 'do while'.
The first is provided for by certain of the lookup tools and by 'extract'.
How you tell a router where to look, when, why, and whether to do it more than
once, is harder.
The BFBI way is a massive chain of successive routers, each looking for a field
one step further to the right than its predecessor. Works fine for small batches.
;-)
OR - a more clever equivalent where router A takes a look, passes to router B,
B takes a step to the right and looks, B hands back to A set to look one step
further right, until 'all gone' and off to the races with the results.
Complex rules rules apply to prevent loops. Discarding prior router data or
headers is one of these.
Finally, calling for some sort of *external* step-by-step iterative routine that
walks the records *within* a process, takes what it needs, passes on.
Other than clever routing pass and 'goto' directives, Exim does not provide a
lot of 'for-next' looping tools where we can easily tap them, so a call to
external tools might be easiest.
OTOH, once you are into the router/transports, the submitting host has gone
away, and there is more time to do these things.
But rest assured - you *can* store the information with Exim's built-ins.
Now ... If someone will get the lights, there will probably be an SQLLite
tutorial shortly....