This question is about the use of regular expressions with Exim, so while it is a bit exotic, I believe it is on topic here. If the consensus is that this is not the case, I would appreciate suggestions about where to post it.
I am using Exim 4.94.2-7 on Debian 11.6 (bullseye), and I'm also using the Debian configuration system for Exim4, which involves files like /etc/exim4/update-exim4.conf.conf
.
I have been trying to configure Exim to select the smarthost based on the From address (the sender's address). The solution described by Marc Auslander [debian-user] exim4 smarthost selection based on sender works for me, though it may not be perfect.
For more context on this, see the first post by me in the thread at [Pkg-exim4-users] How to choose a smarthost based on From: address in Exim4
My slightly adapted version of Marc Auslander's solution sets the value for dc_smarthost in /etc/exim4/update-exim4.conf.conf as follows.
dc_smarthost='"${if match{${lc:$header_from:}}{.*gmail.com}{smtp.gmail.com::587}{${if match{${lc:$header_from:}}{.*mydomain}{smtp.mailbox.org::587}{secure-email-32.luxsci.com::587}}}}"'
This uses syntax as described in [Exim Internet Mailer] Chapter 11 - String expansions in Section 5: Expansion items, namely
${if <condition> {<string1>}{<string2>}}
and Section 7: Expansion conditions, namely
match {<string1>}{<string2>}
Alternatively, if you have the official Exim book, "The Exim SMTP Mail
Server" (my version is "Official Guide for Release 4", First Edition,
published 2003), this syntax is discussed in Section 17.7, with
match
covered in Section 17.7.3.
In pseudocode, this is
if the from header matches the regex .*gmail.com
then
use smtp.gmail.com::587
else if the from header matches .*mydomain
then
use smtp.mailbox.org::587
else # default if nothing else matches
use secure-email-32.luxsci.com::587
This works for me, though there may be some problematic edge cases. However, I get a strange error when I try to modify it as follows.
dc_smarthost='"${if match{${lc:$header_from:}}{.*gmail.com}{smtp.gmail.com::587}{${if match{${lc:$header_from:}}{.*mydomain|.*mailbox.org}{smtp.mailbox.org::587}{secure-email-32.luxsci.com::587}}}}"'
This is similar to the previous version, but in terms of pseudocode, this just replaces
else if the from header matches .*mydomain
with
else if the from header matches .*mydomain|.*mailbox.org
i.e. the from header matches either .*mydomain
or .*mailbox.org
.
The error is:
Mar 30 01:59:54 orwell exim4[3626569]: sed: -e expression #1, char 861: unknown option to `s'
I did a search for this error, and it most commonly seems to happen
when sed
is trying to process text with forward slashes. But I have
no idea what this error means here. As far as I can tell I'm using the
syntax correctly; Exim4 uses PCRE regular expressions.
Explanations of this error would be much appreciated. A version of this regex that works would be even more appreciated. Additionally, if you see any problems with the general approach, please let me know. The other solutions I've seen all involve transports, routers, and lots of boilerplate, and look quite complicated.