Re: [exim] 4.77: inlist condition

Top Page
Delete this message
Reply to this message
Author: John Horne
Date:  
To: exim-users
Subject: Re: [exim] 4.77: inlist condition
On Fri, 2011-10-14 at 10:00 -0400, Phil Pennock wrote:
> On 2011-10-14 at 12:54 +0100, John Horne wrote:
> > Hello,
> >
> > The Exim 4.77 spec.txt file states for the 'inlist' condition:
> >
> >     ...the second string is treated as a list of simple
> >     strings;

> >
> > Is this strictly 'simple', that is, literal strings? No regex?
>
> Correct. The idea was that people were trying to use match_address{}{}
> and friends for this and there was too much power, so I added something
> which was very simple and did what people were trying to do already.
>
> For regexps, use the forany condition:
>
> ${if forany{foo:bar:wibble}{match{$item}{\Ne$\N}}}
>
> Note that conceptually, inlist is equivalent to forany with an eq{}{}
> comparison in the test section.
>

Hi,

Unfortunately the way we used the match_ functions was very useful in
that it took one line and was pretty easy to see what was going on :-)
As far as I can tell I'll need to change things to use an 'or' condition
with eq, inlist, forany and match.

For example, a data file ('abc') of domains may contain the following
where the data are local parts:

    example.org: *
    example.com: fred : ^def : ^.*xyz$


In exim we would use:


    set acl_m_temp = ${lookup {${domain:$h_From:}} lsearch \
                        {FILES/abc} {$value} {} }
    condition = ${if ! eq {$acl_m_temp} {} }
    condition = ${if match_local_part {${local_part:$h_From:}} \
                                      {$acl_m_temp} }


This is fairly easy to see that we are doing a lookup of the domain, and
storing the result. If something was found, then we do a local_part
match against the stored result.

However, avoiding the match_local_part call, we still need to cater for
literals, '*', as well as regular expressions. So, as far as I can see
we possibly end up with:

   set acl_m_temp2 = ${local_part:$h_From:}
   condition = ${if or { {eq {$acl_m_temp} {*} } \
                         {inlisti {$acl_m_temp2} {$acl_m_temp} } \
                         {forany {$acl_m_temp} {${if match {$item} {\N^
\^\N} {${if match {$acl_m_temp2} {$item}}} {false} }} } \
                       } }


The 'eq' checks for an asterisk, and the 'inlisti' will match literals
(I make the assumption that a local_part will not match a regex
beginning with '^' in the list). The 'forany' first checks that the item
begins with '^', and then sees if we have a regex match for that item.
We need to do this since a local_part such as 'abc.def' in the file
would otherwise be treated as a regex and would match 'abcxdef',
'abckdef' etc. (Thinking about it, we could replace this slightly with
an 'and' condition in the 'forany'.)

To me the statement is less 'readable' and more complex, but I guess it
works (I haven't tested it). The use of match_local_part was easier :-)




John.

-- 
John Horne                   Tel: +44 (0)1752 587287
Plymouth University, UK      Fax: +44 (0)1752 587001