[exim-cvs] perl dynamic module

Αρχική Σελίδα
Delete this message
Reply to this message
Συντάκτης: Exim Git Commits Mailing List
Ημερομηνία:  
Προς: exim-cvs
Αντικείμενο: [exim-cvs] perl dynamic module
Gitweb: https://git.exim.org/exim.git/commitdiff/142fd50739f5ba92bac4a0162d03d818e78dd3b7
Commit:     142fd50739f5ba92bac4a0162d03d818e78dd3b7
Parent:     3875eb02bed6a9fb66e76879698d89109c308ac6
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Sun Sep 8 21:22:41 2024 +0100
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Sun Sep 8 21:22:41 2024 +0100


    perl dynamic module
---
 doc/doc-txt/NewStuff           |  6 +++---
 src/OS/Makefile-Base           | 10 +++-------
 src/scripts/Configure-Makefile | 33 ++++++++++++++++++++++++++++-----
 src/scripts/MakeLinks          |  3 ++-
 src/src/EDITME                 |  6 ++++++
 src/src/config.h.defaults      |  1 +
 src/src/drtables.c             | 30 ++++++++++++++++++------------
 src/src/exim.c                 | 11 +++++++++--
 src/src/exim.h                 |  3 +++
 src/src/expand.c               | 22 +++++++++++++++++++---
 src/src/functions.h            |  8 --------
 src/src/miscmods/Makefile      | 24 ++++++++++++++++--------
 src/src/{ => miscmods}/perl.c  | 32 ++++++++++++++++++++++++++++----
 src/src/miscmods/perl_api.h    | 16 ++++++++++++++++
 test/runtest                   |  4 +++-
 15 files changed, 155 insertions(+), 54 deletions(-)


diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff
index 935efb59a..01326b488 100644
--- a/doc/doc-txt/NewStuff
+++ b/doc/doc-txt/NewStuff
@@ -14,9 +14,9 @@ Version 4.98

3. Events smtp:fail:protocol and smtp:fail:syntax

- 4. JSON and LDAP lookup support, PAM, RADIUS, SPF, DKIM, DMARC and ARC support,
-    all the router and authenticator drivers, and all the transport drivers
-    except smtp, can now be built as loadable modules
+ 4. JSON and LDAP lookup support, PAM, RADIUS, perl, SPF, DKIM, DMARC and ARC
+    support, all the router and authenticator drivers, and all the transport
+    drivers except smtp, can now be built as loadable modules


 Version 4.98
 ------------
diff --git a/src/OS/Makefile-Base b/src/OS/Makefile-Base
index 22b56aae5..d8df29672 100644
--- a/src/OS/Makefile-Base
+++ b/src/OS/Makefile-Base
@@ -522,7 +522,7 @@ OBJ_EXIM = acl.o base64.o child.o crypt16.o daemon.o dbfn.o debug.o deliver.o \
         std-crypto.o store.o string.o tls.o tod.o transport.o tree.o verify.o \
         xtextencode.o environment.o macro.o \
         $(OBJ_LOOKUPS) $(OBJ_ROUTERS) $(OBJ_AUTHS) \
-        local_scan.o $(EXIM_PERL) $(OBJ_WITH_CONTENT_SCAN) \
+        local_scan.o $(OBJ_WITH_CONTENT_SCAN) \
         $(OBJ_EXPERIMENTAL)


exim: buildlookups buildauths \
@@ -738,12 +738,6 @@ version.o: $(HDRS) cnumber.h version.h version.c

 dummies.o:       dummies.c


-# Compile instructions for perl.o for when EXIM_PERL is set
-
-perl.o:          $(HDRS) perl.c
-    @echo "$(PERL_CC) perl.c"
-    $(FE)$(PERL_CC) $(PERL_CCOPTS) $(CFLAGS) $(INCLUDE) -c perl.c
-
 # Compile instructions for the database utility modules


 exim_dumpdb.o:   $(HDRS) exim_dbutil.c
@@ -1065,6 +1059,8 @@ buildmisc: config
          CFLAGS_DYNAMIC="$(CFLAGS_DYNAMIC)" \
          LDFLAGS_PARTIAL="$(LDFLAGS_PARTIAL)" HDRS="../version.h $(PHDRS)" \
          FE="$(FE)" RANLIB="$(RANLIB)" RM_COMMAND="$(RM_COMMAND)" \
+         PERL_CC="$(PERL_CC)" PERL_CCOPTS="$(PERL_CCOPTS)" \
+         PERL_CFLAGS="$(PERL_CFLAGS)" PERL_LFLAGS="$(PERL_LFLAGS)" \
          INCLUDE="$(INCLUDE) $(IPV6_INCLUDE)"
      @echo " "


diff --git a/src/scripts/Configure-Makefile b/src/scripts/Configure-Makefile
index 4fc917dc9..df6323f3b 100755
--- a/src/scripts/Configure-Makefile
+++ b/src/scripts/Configure-Makefile
@@ -284,11 +284,17 @@ then
fi
rm -f $mftt

-#XXX look for RADIUS in $mft; add a SUPPORT_
+
+# look for RADIUS in $mft; add a SUPPORT_
if $egrep -q "^RADIUS_CONFIG_FILE" $mft; then
echo "# radius fixup"
$egrep -q "^SUPPORT_RADIUS" $mft || echo "SUPPORT_RADIUS=yes" >> $mft
fi
+# also PERL
+if $egrep -q "^EXIM_PERL" $mft; then
+ echo "# perl fixup"
+ $egrep -q "^SUPPORT_PERL" $mft || echo "SUPPORT_PERL=yes" >> $mft
+fi


 # make the lookups Makefile with the definitions
@@ -309,7 +315,7 @@ done <<-END
  routers    ROUTER    ACCEPT DNSLOOKUP IPLITERAL IPLOOKUP MANUALROUTE QUERYPROGRAM REDIRECT
  transports TRANSPORT    APPENDFILE AUTOREPLY LMTP PIPE QUEUEFILE SMTP
  auths        AUTH    CRAM_MD5 CYRUS_SASL DOVECOT EXTERNAL GSASL HEIMDAL_GSSAPI PLAINTEXT SPA TLS
- miscmods   SUPPORT    ARC _DKIM DMARC PAM RADIUS SPF
+ miscmods   SUPPORT    ARC _DKIM DMARC PAM PERL RADIUS SPF
 END


 # See if there is a definition of EXIM_PERL in what we have built so far.
@@ -338,10 +344,27 @@ if [ "${EXIM_PERL}" != "" ] ; then
     exit 1;
   fi


+  perl_cc="`$PERL_COMMAND -MConfig -e 'print $Config{cc}'`"
+  perl_ccopts="`$PERL_COMMAND -MExtUtils::Embed -e ccopts`"
+  perl_libs="`$PERL_COMMAND -MExtUtils::Embed -e ldopts`"
+
+  # For the dynamic-module build, pull out all the -D & -I into another var,
+  # and -L (maybe & -l?) to another, both for feed to miscmods
+  # ending up as SUPPORT_PERL_INCLUDE & SUPPORT_PERL_LIB respectively
+
+  perl_cflags=`PERL_CCOPTS="$perl_ccopts" $PERL_COMMAND \
+        -e 'my @list = split(" ", $ENV{PERL_CCOPTS});' \
+        -e 'foreach (@list) {print "$_ " if (/^-[DI]/)}'`
+  perl_lflags=`PERL_LIBS="$perl_libs" $PERL_COMMAND \
+        -e 'my @list = split(" ", $ENV{PERL_LIBS});' \
+        -e 'foreach (@list) {print "$_ " if (/^-L/)}'`
+
   mv $mft $mftt
-  echo "PERL_CC=`$PERL_COMMAND -MConfig -e 'print $Config{cc}'`" >>$mft
-  echo "PERL_CCOPTS=`$PERL_COMMAND -MExtUtils::Embed -e ccopts`" >>$mft
-  echo "PERL_LIBS=`$PERL_COMMAND -MExtUtils::Embed -e ldopts`" >>$mft
+  echo "PERL_CC=${perl_cc}" >>$mft
+  echo "PERL_CCOPTS=${perl_ccopts}" >>$mft
+  echo "PERL_LIBS=${perl_libs}" >>$mft
+  echo "PERL_CFLAGS=${perl_cflags}" >>$mft
+  echo "PERL_LFLAGS=${perl_lflags}" >>$mft
   echo "" >>$mft
   cat $mftt >> $mft
   rm -f $mftt
diff --git a/src/scripts/MakeLinks b/src/scripts/MakeLinks
index a3a3131a2..d7441ef0d 100755
--- a/src/scripts/MakeLinks
+++ b/src/scripts/MakeLinks
@@ -103,6 +103,7 @@ for f in dummy.c \
     pdkim/pdkim_hash.h pdkim/signing.c pdkim/signing.h \
     dmarc.c dmarc.h dmarc_api.h \
     pam.c pam_api.h \
+    perl.c perl_api.h \
     radius.c radius_api.h \
     spf.c spf.h spf_api.h
 do
@@ -133,7 +134,7 @@ for f in blob.h dbfunctions.h exim.h functions.h globals.h \
   deliver.c directory.c dns.c dnsbl.c drtables.c dummies.c enq.c exim.c \
   exim_dbmbuild.c exim_dbutil.c exim_lock.c expand.c filter.c filtertest.c \
   globals.c hash.c header.c host.c host_address.c ip.c log.c lss.c match.c md5.c moan.c \
-  parse.c perl.c priv.c proxy.c queue.c rda.c readconf.c receive.c retry.c rewrite.c \
+  parse.c priv.c proxy.c queue.c rda.c readconf.c receive.c retry.c rewrite.c \
   regex_cache.c rfc2047.c route.c search.c setenv.c environment.c \
   sieve.c smtp_in.c smtp_out.c spool_in.c spool_out.c std-crypto.c store.c \
   string.c tls.c tlscert-gnu.c tlscert-openssl.c tls-cipher-stdname.c \
diff --git a/src/src/EDITME b/src/src/EDITME
index c12d74c35..757e94746 100644
--- a/src/src/EDITME
+++ b/src/src/EDITME
@@ -1069,9 +1069,15 @@ ZCAT_COMMAND=/usr/bin/zcat
 # use Perl code in Exim's string manipulation language and you have Perl
 # (version 5.004 or later) installed, set EXIM_PERL to perl.o. Using embedded
 # Perl costs quite a lot of resources. Only do this if you really need it.
+#


# EXIM_PERL=perl.o

+# For a dynamic module build add also SUPPORT_PERL=2 and SUPPORT_PAM_(INCLUED,LIBS)
+#SUPPORT_PERL=2
+#SUPPORT_PERL_INCLUDE=$(PERL_CFLAGS)
+#SUPPORT_PERL_LIBS=$(PERL_LFLAGS) -lperl
+

#------------------------------------------------------------------------------
# Support for dynamically-loaded string expansion functions via ${dlfunc. If
diff --git a/src/src/config.h.defaults b/src/src/config.h.defaults
index 60aacee5b..e6ded1e8f 100644
--- a/src/src/config.h.defaults
+++ b/src/src/config.h.defaults
@@ -170,6 +170,7 @@ Do not put spaces between # and the 'define'.
/* Required to support dynamic-module build */
#define SUPPORT_ARC
#define SUPPORT_DKIM
+#define SUPPORT_PERL
#define SUPPORT_RADIUS

 #define SYSLOG_LOG_PID
diff --git a/src/src/drtables.c b/src/src/drtables.c
index b9d4650f1..8bde47666 100644
--- a/src/src/drtables.c
+++ b/src/src/drtables.c
@@ -431,16 +431,16 @@ misc_module_info * misc_module_list = NULL;
 static void
 misc_mod_add(misc_module_info * mi)
 {
-if (mi->init && mi->init(mi))
-  {
-  DEBUG(D_any) if (mi->lib_vers_report)
-    debug_printf_indent("%Y", mi->lib_vers_report(NULL));
+mi->next = misc_module_list;
+misc_module_list = mi;
+
+if (mi->init && !mi->init(mi))
+  DEBUG(D_any)
+    debug_printf_indent("module init call failed for %s\n", mi->name);
+
+DEBUG(D_any) if (mi->lib_vers_report)
+  debug_printf_indent("%Y", mi->lib_vers_report(NULL));


- mi->next = misc_module_list;
- misc_module_list = mi;
- }
-else DEBUG(D_any)
- debug_printf_indent("module init call failed for %s\n", mi->name);
/* fprintf(stderr,"misc_mod_add: added %s\n", mi->name); */
}

@@ -459,7 +459,7 @@ const char * errormsg;
DEBUG(D_any) debug_printf_indent("loading module '%s'\n", name);
if (!(dl = mod_open(name, US"miscmod", errstr)))
{
- DEBUG(D_any) debug_printf_indent(" mod_open: %s\n", *errstr);
+ DEBUG(D_any) if (errstr) debug_printf_indent(" mod_open: %s\n", *errstr);
return NULL;
}

@@ -753,12 +753,15 @@ extern misc_module_info spf_module_info;
#if defined(EXPERIMENTAL_ARC) && (!defined(SUPPORT_ARC) || SUPPORT_ARC!=2)
extern misc_module_info arc_module_info;
#endif
-#if defined(RADIUS_CONFIG_FILE) && (!defined(SUPPORT_RADIUS) || SUPPORT_RADUIS!=2)
+#if defined(RADIUS_CONFIG_FILE) && (!defined(SUPPORT_RADIUS) || SUPPORT_RADIUS!=2)
extern misc_module_info radius_module_info;
#endif
#if defined(SUPPORT_PAM) && SUPPORT_PAM!=2
extern misc_module_info pam_module_info;
#endif
+#if defined(EXIM_PERL) && (!defined(SUPPORT_PERL) || SUPPORT_PERL!=2)
+extern misc_module_info perl_module_info;
+#endif

void
init_misc_mod_list(void)
@@ -780,12 +783,15 @@ onetime = TRUE;
#if defined(EXPERIMENTAL_ARC) && (!defined(SUPPORT_ARC) || SUPPORT_ARC!=2)
misc_mod_add(&arc_module_info);
#endif
-#if defined(RADIUS_CONFIG_FILE) && (!defined(SUPPORT_RADIUS) || SUPPORT_RADUIS!=2)
+#if defined(RADIUS_CONFIG_FILE) && (!defined(SUPPORT_RADIUS) || SUPPORT_RADIUS!=2)
misc_mod_add(&radius_module_info);
#endif
#if defined(SUPPORT_PAM) && SUPPORT_PAM!=2
misc_mod_add(&pam_module_info);
#endif
+#if defined(EXIM_PERL) && (!defined(SUPPORT_PERL) || SUPPORT_PERL!=2)
+ misc_mod_add(&perl_module_info);
+#endif
}


diff --git a/src/src/exim.c b/src/src/exim.c
index 2349260df..9774281e4 100644
--- a/src/src/exim.c
+++ b/src/src/exim.c
@@ -4499,9 +4499,16 @@ if (perl_start_option != 0)
   opt_perl_at_start = (perl_start_option > 0);
 if (opt_perl_at_start && opt_perl_startup != NULL)
   {
-  uschar *errstr;
+  uschar * errstr;
+  const misc_module_info * mi = misc_mod_find(US"perl", &errstr);
+  typedef uschar * (*fn_t)(uschar *);
+
+  if (!mi)
+    exim_fail("exim: error finding perl module: %s\n", errstr);
+
   DEBUG(D_any) debug_printf("Starting Perl interpreter\n");
-  if ((errstr = init_perl(opt_perl_startup)))
+
+  if ((errstr = (((fn_t *) mi->functions)[PERL_STARTUP]) (opt_perl_startup)))
     exim_fail("exim: error in perl_startup code: %s\n", errstr);
   opt_perl_started = TRUE;
   }
diff --git a/src/src/exim.h b/src/src/exim.h
index a3b7112a6..771c00df8 100644
--- a/src/src/exim.h
+++ b/src/src/exim.h
@@ -564,6 +564,9 @@ config.h, mytypes.h, and store.h, so we don't need to mention them explicitly.
 #ifdef SUPPORT_PAM
 # include "miscmods/pam_api.h"
 #endif
+#ifdef EXIM_PERL
+# include "miscmods/perl_api.h"
+#endif


 /* The following stuff must follow the inclusion of config.h because it
 requires various things that are set therein. */
diff --git a/src/src/expand.c b/src/src/expand.c
index d9e71897e..e1e6e1999 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -5192,6 +5192,8 @@ while (*s)
       {
       uschar * sub_arg[EXIM_PERL_MAX_ARGS + 2];
       gstring * new_yield;
+      const misc_module_info * mi;
+      uschar * errstr;


       if (expand_forbid & RDO_PERL)
         {
@@ -5199,6 +5201,13 @@ while (*s)
         goto EXPAND_FAILED;
         }


+      if (!(mi = misc_mod_find(US"perl", &errstr)))
+        {
+        expand_string_message =
+      string_sprintf("failed to locate perl module: %s", errstr);
+        goto EXPAND_FAILED;
+        }
+
       switch(read_subs(sub_arg, EXIM_PERL_MAX_ARGS + 1, 1, &s, flags, TRUE,
            name, &resetok, NULL))
         {
@@ -5213,6 +5222,8 @@ while (*s)
       if (!opt_perl_started)
         {
         uschar * initerror;
+    typedef uschar * (*fn_t)(uschar *);
+
         if (!opt_perl_startup)
           {
           expand_string_message = US"A setting of perl_startup is needed when "
@@ -5220,7 +5231,8 @@ while (*s)
           goto EXPAND_FAILED;
           }
         DEBUG(D_any) debug_printf("Starting Perl interpreter\n");
-        if ((initerror = init_perl(opt_perl_startup)))
+    initerror = (((fn_t *) mi->functions)[PERL_STARTUP]) (opt_perl_startup);
+        if (initerror)
           {
           expand_string_message =
             string_sprintf("error in perl_startup code: %s\n", initerror);
@@ -5232,8 +5244,12 @@ while (*s)
       /* Call the function */


       sub_arg[EXIM_PERL_MAX_ARGS + 1] = NULL;
-      new_yield = call_perl_cat(yield, &expand_string_message,
-        sub_arg[0], sub_arg + 1);
+    {
+    typedef gstring * (*fn_t)(gstring *, uschar **, uschar *, uschar **);
+    new_yield = (((fn_t *) mi->functions)[PERL_CAT])
+                          (yield, &expand_string_message,
+                        sub_arg[0], sub_arg + 1);
+    }


       /* NULL yield indicates failure; if the message pointer has been set to
       NULL, the yield was undef, indicating a forced failure. Otherwise the
diff --git a/src/src/functions.h b/src/src/functions.h
index cb470bcb3..9b645a85f 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -19,14 +19,6 @@ are in in fact in separate headers. */
 #include <sys/time.h>



-#ifdef EXIM_PERL
-extern gstring *call_perl_cat(gstring *, uschar **, uschar *,
-                 uschar **) WARN_UNUSED_RESULT;
-extern void    cleanup_perl(void);
-extern uschar *init_perl(uschar *);
-#endif
-
-
 #ifndef DISABLE_TLS
 extern const char *
                std_dh_prime_default(void);
diff --git a/src/src/miscmods/Makefile b/src/src/miscmods/Makefile
index 8f53088ff..c1489d6e8 100644
--- a/src/src/miscmods/Makefile
+++ b/src/src/miscmods/Makefile
@@ -38,19 +38,27 @@ dkim.o  dkim.so:    $(HDRS) dkim.h dkim.c dkim_transport.c \
 dmarc.o dmarc.so:    $(HDRS) pdkim.h dmarc.h dmarc.c
 dummy.o:        dummy.c
 pam.o   pam.so:        $(HDRS) pam.c
+perl.o perl.so:         $(HDRS) perl.c
 radius.o radius.so:    $(HDRS) radius.c
 spf.o   spf.so:        $(HDRS) spf.h spf.c


 dkim.o:
-        @echo "$(CC) dkim.c dkim_transport.c pdkim.c signing.c"
-        $(FE)$(CC) -r $(LDFLAGS_PARTIAL) -o $@ $(CFLAGS) $(INCLUDE) \
-            dkim.c dkim_transport.c pdkim.c signing.c
+    @echo "$(CC) dkim.c dkim_transport.c pdkim.c signing.c"
+    $(FE)$(CC) -r $(LDFLAGS_PARTIAL) -o $@ $(CFLAGS) $(INCLUDE) \
+        dkim.c dkim_transport.c pdkim.c signing.c


 dkim.so:
-        @echo "$(CC) -shared dkim.c dkim_transport.c pdkim.c signing.c"
-        $(FE)$(CC) -DDYNLOOKUP $(CFLAGS_DYNAMIC) -o $@ \
-            $(SUPPORT_$*_INCLUDE) $(SUPPORT_$*_LIBS) \
-            $(CFLAGS) $(INCLUDE) $(DLFLAGS) \
-            dkim.c dkim_transport.c pdkim.c signing.c
+    @echo "$(CC) -shared dkim.c dkim_transport.c pdkim.c signing.c"
+    $(FE)$(CC) -DDYNLOOKUP $(CFLAGS_DYNAMIC) -o $@ \
+        $(SUPPORT_$*_INCLUDE) $(SUPPORT_$*_LIBS) \
+        $(CFLAGS) $(INCLUDE) $(DLFLAGS) \
+        dkim.c dkim_transport.c pdkim.c signing.c
+
+# Compile instructions for static perl.o for when EXIM_PERL is set
+# Dynamic is managed all via scripts/Configure-Makefile
+
+perl.o:
+    @echo "$(PERL_CC) perl.c"
+    $(FE)$(PERL_CC) $(PERL_CCOPTS) $(CFLAGS) $(INCLUDE) -c perl.c


# End
diff --git a/src/src/perl.c b/src/src/miscmods/perl.c
similarity index 89%
rename from src/src/perl.c
rename to src/src/miscmods/perl.c
index 2a10452d3..901494743 100644
--- a/src/src/perl.c
+++ b/src/src/miscmods/perl.c
@@ -20,7 +20,7 @@
#define HINTSDB_H
#define DBFUNCTIONS_H

-#include "exim.h"
+#include "../exim.h"

#define EXIM_TRUE TRUE
#undef TRUE
@@ -99,7 +99,7 @@ static void xs_init(pTHX)
newXS("Exim::log_write", xs_log_write, file);
}

-uschar *
+static uschar *
 init_perl(uschar *startup_code)
 {
   static int argc = 1;
@@ -146,7 +146,8 @@ init_perl(uschar *startup_code)
     }
 }


-void
+#ifdef notdef
+static void
cleanup_perl(void)
{
if (!interp_perl)
@@ -155,8 +156,9 @@ cleanup_perl(void)
perl_free(interp_perl);
interp_perl = 0;
}
+#endif

-gstring *
+static gstring *
call_perl_cat(gstring * yield, uschar **errstrp, uschar *name, uschar **arg)
{
dSP;
@@ -199,4 +201,26 @@ call_perl_cat(gstring * yield, uschar **errstrp, uschar *name, uschar **arg)
return yield;
}

+
+
+
+/******************************************************************************/
+/* Module API */
+
+static void * perl_functions[] = {
+  [PERL_STARTUP] =    init_perl,
+  [PERL_CAT] =        call_perl_cat,
+};
+
+misc_module_info perl_module_info =
+{
+  .name =        US"perl",
+# ifdef DYNLOOKUP
+  .dyn_magic =        MISC_MODULE_MAGIC,
+# endif
+
+  .functions =        perl_functions,
+  .functions_count =    nelem(perl_functions),
+};
+
 /* End of perl.c */
diff --git a/src/src/miscmods/perl_api.h b/src/src/miscmods/perl_api.h
new file mode 100644
index 000000000..44fa4288b
--- /dev/null
+++ b/src/src/miscmods/perl_api.h
@@ -0,0 +1,16 @@
+/*************************************************
+*     Exim - an Internet mail transport agent    *
+*************************************************/
+
+/* Copyright (c) The Exim Maintainers 2024 */
+/* See the file NOTICE for conditions of use and distribution. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/* API definitions for the perlmodule */
+
+
+/* Function table entry numbers */
+
+#define    PERL_STARTUP    0
+#define    PERL_CAT    1
+#define    PERL_CLEANUP    2
diff --git a/test/runtest b/test/runtest
index 83659ea19..7226c4b0c 100755
--- a/test/runtest
+++ b/test/runtest
@@ -1554,13 +1554,15 @@ RESET_AFTER_EXTRA_LINE_READ:
       <IN>; <IN>; <IN>; <IN>; <IN>; next;
       }


+    # various features can be built as dynamic-load modules
+    next if /loading module '(?:arc|dkim|dmarc|pam|perl|radius|spf)'$/;
+
     # Not all platforms build with DKIM enabled
     next if /^DKIM >> Body data for hash, canonicalized/;


     # Not all platforms build with SPF enabled
     next if /(^$time_pid?spf_conn_init|spf_compile\.c)/;
     next if /try option spf_smtp_comment_template$/;
-    next if /loading module '(?:dkim|dmarc|spf)'$/;
     next if /^$time_pid?Loaded "(?:dkim|dmarc|spf)"$/;


     # Not all platforms have sendfile support


--
## subscription configuration (requires account):
## https://lists.exim.org/mailman3/postorius/lists/exim-cvs.lists.exim.org/
## unsubscribe (doesn't require an account):
## exim-cvs-unsubscribe@???
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/