Macros for module func call numbers
authorJeremy Harris <jgh146exb@wizmail.org>
Sat, 31 Aug 2024 21:07:17 +0000 (22:07 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Sun, 1 Sep 2024 00:28:00 +0000 (01:28 +0100)
12 files changed:
src/OS/Makefile-Base
src/scripts/MakeLinks
src/src/acl.c
src/src/exim.h
src/src/expand.c
src/src/lookups/spf.c
src/src/miscmods/README [new file with mode: 0644]
src/src/miscmods/dmarc.c
src/src/miscmods/dmarc_api.h [new file with mode: 0644]
src/src/miscmods/spf.c
src/src/miscmods/spf_api.h [new file with mode: 0644]
src/src/receive.c

index 43cec361cdcb74cacf0606d196a827f342641ee6..591b4261c006a18fc05ee5321e6d1d9229eea378 100644 (file)
@@ -685,6 +685,8 @@ HDRS  =     blob.h \
        hintsdb/hints_tdb.h \
        local_scan.h \
        macros.h \
        hintsdb/hints_tdb.h \
        local_scan.h \
        macros.h \
+       miscmods/dmarc_api.h \
+       miscmods/spf_api.h \
        mytypes.h \
        path_max.h \
        sha_ver.h \
        mytypes.h \
        path_max.h \
        sha_ver.h \
@@ -704,6 +706,8 @@ PHDRS = ../config.h \
        ../hintsdb/hints_tdb.h \
        ../local_scan.h \
        ../macros.h \
        ../hintsdb/hints_tdb.h \
        ../local_scan.h \
        ../macros.h \
+       ../miscmods/dmarc_api.h \
+       ../miscmods/spf_api.h \
        ../mytypes.h \
        ../path_max.h \
        ../structs.h \
        ../mytypes.h \
        ../path_max.h \
        ../structs.h \
index e45097243be93382064e37a3e71eb516031741ff..0be066352b9236889c3b4b087d89ceda6d1e26fe 100755 (executable)
@@ -94,7 +94,7 @@ d="miscmods"
 mkdir $d
 cd $d
 # Makefile is generated
 mkdir $d
 cd $d
 # Makefile is generated
-for f in dmarc.c dmarc.h spf.c spf.h
+for f in dmarc.c dmarc.h dmarc_api.h spf.c spf.h spf_api.h
 do
   ln -s ../../src/$d/$f $f
 done
 do
   ln -s ../../src/$d/$f $f
 done
index 30fc09174177514eb48af43c6142cc5d4f6028a9..023ac2ff6ee1d8afa08a02ae1722e9873702015b 100644 (file)
@@ -3961,29 +3961,24 @@ for (; cb; cb = cb->next)
       typedef uschar * (*efn_t)(int);
       uschar * expanded_query;
 
       typedef uschar * (*efn_t)(int);
       uschar * expanded_query;
 
-debug_printf("%s %d\n", __FUNCTION__, __LINE__);
       if (!mi)
        { rc = DEFER; break; }                  /* shouldn't happen */
 
       if (!mi)
        { rc = DEFER; break; }                  /* shouldn't happen */
 
-debug_printf("%s %d: mi %p\n", __FUNCTION__, __LINE__, mi);
       if (!f.dmarc_has_been_checked)
        {
        typedef int (*pfn_t)(void);
       if (!f.dmarc_has_been_checked)
        {
        typedef int (*pfn_t)(void);
-       (void) (((pfn_t *) mi->functions)[0]) ();       /* dmarc_process */
+       (void) (((pfn_t *) mi->functions)[DMARC_PROCESS]) ();
        f.dmarc_has_been_checked = TRUE;
        }
 
        f.dmarc_has_been_checked = TRUE;
        }
 
-debug_printf("%s %d\n", __FUNCTION__, __LINE__);
       /* used long way of dmarc_exim_expand_query() in case we need more
       view into the process in the future. */
 
       /*XXX is this call used with any other arg? */
       /* used long way of dmarc_exim_expand_query() in case we need more
       view into the process in the future. */
 
       /*XXX is this call used with any other arg? */
-      expanded_query = (((efn_t *) mi->functions)[1]) (DMARC_VERIFY_STATUS);
-
-debug_printf("%s %d\n", __FUNCTION__, __LINE__);
+      expanded_query = (((efn_t *) mi->functions)[DMARC_EXPAND_QUERY])
+                                                     (DMARC_VERIFY_STATUS);
       rc = match_isinlist(expanded_query,
                          &arg, 0, NULL, NULL, MCL_STRING, TRUE, NULL);
       rc = match_isinlist(expanded_query,
                          &arg, 0, NULL, NULL, MCL_STRING, TRUE, NULL);
-debug_printf("%s %d\n", __FUNCTION__, __LINE__);
       }
       break;
 #endif
       }
       break;
 #endif
@@ -4223,7 +4218,9 @@ debug_printf("%s %d\n", __FUNCTION__, __LINE__);
       /* We have hardwired function-call numbers, and also prototypes for the
       functions.  We could do a function name table search for the number
       but I can't see how to deal with prototypes.  Is a K&R non-prototyped
       /* We have hardwired function-call numbers, and also prototypes for the
       functions.  We could do a function name table search for the number
       but I can't see how to deal with prototypes.  Is a K&R non-prototyped
-      function still usable with today's compilers? */
+      function still usable with today's compilers (but we would lose on
+      type-checking)?  We could macroize the typedef, and even the function
+      table access - but it obscures how it works rather. */
       {
       misc_module_info * mi = misc_mod_find(US"spf", &log_message);
       typedef int (*fn_t)(const uschar **, const uschar *, int);
       {
       misc_module_info * mi = misc_mod_find(US"spf", &log_message);
       typedef int (*fn_t)(const uschar **, const uschar *, int);
@@ -4232,7 +4229,7 @@ debug_printf("%s %d\n", __FUNCTION__, __LINE__);
       if (!mi)
        { rc = DEFER; break; }                  /* shouldn't happen */
 
       if (!mi)
        { rc = DEFER; break; }                  /* shouldn't happen */
 
-      fn = ((fn_t *) mi->functions)[0];                /* spf_process() */
+      fn = ((fn_t *) mi->functions)[SPF_PROCESS];
 
       rc = fn(&arg, sender_address,
              cb->type == ACLC_SPF ? SPF_PROCESS_NORMAL : SPF_PROCESS_GUESS);
 
       rc = fn(&arg, sender_address,
              cb->type == ACLC_SPF ? SPF_PROCESS_NORMAL : SPF_PROCESS_GUESS);
index 284748c5d79087ac7aef8debcabde120687a8d50..c996a2f8cb28980954b9ed46b06e6381509b8433 100644 (file)
@@ -544,12 +544,14 @@ config.h, mytypes.h, and store.h, so we don't need to mention them explicitly.
 #endif
 #ifdef SUPPORT_SPF
 # include "miscmods/spf.h"
 #endif
 #ifdef SUPPORT_SPF
 # include "miscmods/spf.h"
+# include "miscmods/spf_api.h"
 #endif
 #ifndef DISABLE_DKIM
 # include "dkim.h"
 #endif
 #ifdef SUPPORT_DMARC
 # include "miscmods/dmarc.h"
 #endif
 #ifndef DISABLE_DKIM
 # include "dkim.h"
 #endif
 #ifdef SUPPORT_DMARC
 # include "miscmods/dmarc.h"
+# include "miscmods/dmarc_api.h"
 # include <opendmarc/dmarc.h>
 #endif
 
 # include <opendmarc/dmarc.h>
 #endif
 
index a6b05bd879b66a3c39db72c02f477542c8b19ae9..af38160516afa9ab98a3960b63cb3d775fdba4c6 100644 (file)
@@ -4888,7 +4888,7 @@ while (*s)
        if (mi)
          {
          typedef gstring * (*fn_t)(gstring *);
        if (mi)
          {
          typedef gstring * (*fn_t)(gstring *);
-         fn_t fn = ((fn_t *) mi->functions)[1];        /* authres_spf */
+         fn_t fn = ((fn_t *) mi->functions)[SPF_AUTHRES];
          yield = fn(yield);
          }
        }
          yield = fn(yield);
          }
        }
@@ -4903,7 +4903,7 @@ while (*s)
          {
          /*XXX is authres common enough to be generic? */
          typedef gstring * (*fn_t)(gstring *);
          {
          /*XXX is authres common enough to be generic? */
          typedef gstring * (*fn_t)(gstring *);
-         fn_t fn = ((fn_t *) mi->functions)[2];        /* authres_dmarc*/
+         fn_t fn = ((fn_t *) mi->functions)[DMARC_AUTHRES];
          yield = fn(yield);
          }
        }
          yield = fn(yield);
          }
        }
index a06f9117d83a7aa630563a7534cd08b6ba185b47..996bae294919ae0d317528c990a212d2501d1a6e 100644 (file)
@@ -39,7 +39,7 @@ misc_module_info * mi = misc_mod_find(US"spf", errmsg);
 if (mi)
   {
   typedef void * (*fn_t)(const uschar *, uschar **);
 if (mi)
   {
   typedef void * (*fn_t)(const uschar *, uschar **);
-  return (((fn_t *) mi->functions)[3]) (filename, errmsg);
+  return (((fn_t *) mi->functions)[SPF_OPEN]) (filename, errmsg);
   }
 return NULL;
 }
   }
 return NULL;
 }
@@ -52,7 +52,7 @@ misc_module_info * mi = misc_mod_find(US"spf", NULL);
 if (mi)
   {
   typedef void (*fn_t)(void *);
 if (mi)
   {
   typedef void (*fn_t)(void *);
-  return (((fn_t *) mi->functions)[4]) (handle);
+  return (((fn_t *) mi->functions)[SPF_CLOSE]) (handle);
   }
 }
 
   }
 }
 
@@ -67,7 +67,8 @@ if (mi)
   {
   typedef int (*fn_t) (void *, const uschar *, const uschar *,
                      int, uschar **, uschar **, uint *, const uschar *);
   {
   typedef int (*fn_t) (void *, const uschar *, const uschar *,
                      int, uschar **, uschar **, uint *, const uschar *);
-  return (((fn_t *) mi->functions)[5]) (handle, filename, keystring, key_len,
+  return (((fn_t *) mi->functions)[SPF_FIND])
+                                     (handle, filename, keystring, key_len,
                                      result, errmsg, do_cache, opts);
   }
 return FAIL;
                                      result, errmsg, do_cache, opts);
   }
 return FAIL;
diff --git a/src/src/miscmods/README b/src/src/miscmods/README
new file mode 100644 (file)
index 0000000..e534a4e
--- /dev/null
@@ -0,0 +1,84 @@
+/*************************************************
+*     Exim - an Internet mail transport agent    *
+*************************************************/
+
+Copyright (c) The Exim Maintainers 2024
+
+This directory contains source for modules that can be built as part
+of Exim, either static-linked or as dynamic-load modules. Doing the
+latter keeps the runtime binary smaller when a feature is not used
+by the configuration, especially when a library is involved.
+
+Which modules are built, and the choice of static vs. dynamic, is
+under the control of the Local/Makefile at build time.
+Any combination of static/dynamic is valid.
+
+Moudules built for dynamic load must be installed in a directory
+which is defined in Local/Makefile.
+
+The API starts with a struct with a known name <foo>_module_info.
+For dynamic builds this includes a magic number permitting versioning
+of the highlevel interface.
+The structure has elements for some commonly-needed call types
+(init, version-report etc.).  Any my be left as null pointers;
+those present will be called at appropriate times.
+
+The current list is
+       init
+       lib_vers_report
+       smtp_reset
+       msg_init
+
+Then there are three pair of elements, each being a table pointer
+and table length, for options, functions, and variable that the
+module provides.
+
+The options table defines main-section configuration options, using
+the same definition entry struct as the main table in readconf.c;
+entries here should have their proper opt_<type> and
+should be duplicated in the main table, but with opt_module and the
+module name (this supports both getting the module loaded, if dynamic,
+and writing the value from the config). Entries must be in order by
+the option name.
+
+The functions table defines service functions additional to the "common"
+ones noted above.  Each offset in the table should have a #define in an
+include-file brought in to the general set by exim.h.
+
+The variables table defins $variables for expansion, using the same
+definition entry struct as the main var_table in expand.c;
+entries here should have their proper vtype_<type> and should be duplicated
+in the main table but with vtype_module and the module name.
+
+There are service functions to locate and to locate-or-load modules
+by name; these hide the static/dynamic aspect of a module.  Most
+new coding will only need these for calls to the "additiona" custom
+functions a module provides. The example code is:
+
+      {
+      /* You need to know the function's prototype */
+      typedef int (*fn_t)(const uschar **, const uschar *, int);
+      fn_t fn;
+      misc_module_info * mi = misc_mod_find(US"spf", &log_message);
+
+      if (mi)
+       {
+       fn = ((fn_t *) mi->functions)[SPF_PROCESS];
+       rc = fn(args...);
+       }
+      }
+
+
+
+Adding new modules
+------------------
+
+Put the code in this directory.  Use filenames starting with the module name.
+Write an include file with anything callers need to know, in particular
+#defines for the function call numbers.  Include that file from exim.h
+and add it to HDRS and PHDRS in OS/Makefile-Base.
+Add a SUPPORT_<foo> line to Local/Makefile, and (if dynamic) any
+SUPPORT_<foo>_INCLUDE or SUPPORT_<foo>_LIBS required.
+Add the capitalised module name <foo> to the "miscmods" like in
+scripts/Configure-Makefile.
+Add all the filenames to the "miscmods" list in scripts/Makelinks
index 0a97bf6b709c93a89a31739dbb17605183b2551a..37648d0452c19c7a03b58fcfda61c803c1ff9074 100644 (file)
@@ -461,7 +461,8 @@ if (!dmarc_abort && !sender_host_authenticated)
     {
     typedef SPF_response_t * (*fn_t)(void);
     if (spf_mod_info)
     {
     typedef SPF_response_t * (*fn_t)(void);
     if (spf_mod_info)
-      spf_response_p = ((fn_t *) spf_mod_info->functions)[2]();        /* spf_get_response */
+      /*XXX ugly use of a pointer */
+      spf_response_p = ((fn_t *) spf_mod_info->functions)[SPF_GET_RESPONSE]();
     }
 
   if (!spf_response_p)
     }
 
   if (!spf_response_p)
@@ -746,10 +747,10 @@ static optionlist dmarc_options[] = {
 };
 
 static void * dmarc_functions[] = {
 };
 
 static void * dmarc_functions[] = {
-  dmarc_process,
-  dmarc_exim_expand_query,
-  authres_dmarc,
-  dmarc_store_data,
+  [DMARC_PROCESS] =    dmarc_process,
+  [DMARC_EXPAND_QUERY] = dmarc_exim_expand_query,
+  [DMARC_AUTHRES] =    authres_dmarc,
+  [DMARC_STORE_DATA] = dmarc_store_data,
 };
 
 /* dmarc_forensic_sender is provided for visibility of the the option setting
 };
 
 /* dmarc_forensic_sender is provided for visibility of the the option setting
diff --git a/src/src/miscmods/dmarc_api.h b/src/src/miscmods/dmarc_api.h
new file mode 100644 (file)
index 0000000..6ba8a50
--- /dev/null
@@ -0,0 +1,17 @@
+/*************************************************
+*     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 dmarc module */
+
+
+/* Function table entry numbers */
+
+#define        DMARC_PROCESS           0
+#define DMARC_EXPAND_QUERY     1
+#define DMARC_AUTHRES          2
+#define DMARC_STORE_DATA       3
index f28fd0cbfe33b3bc9531af3ccf170651aae8ea9e..ea23c1c655ce546a0099900058589215212a163c 100644 (file)
@@ -565,13 +565,13 @@ static optionlist spf_options[] = {
 };
 
 static void * spf_functions[] = {
 };
 
 static void * spf_functions[] = {
-  spf_process,
-  authres_spf,
-  spf_get_response,            /* ugly; for dmarc */
+  [SPF_PROCESS] =      spf_process,
+  [SPF_AUTHRES] =      authres_spf,
+  [SPF_GET_RESPONSE] = spf_get_response,               /* ugly; for dmarc */
   
   
-  spf_lookup_open,
-  spf_lookup_close,
-  spf_lookup_find,
+  [SPF_OPEN] =         spf_lookup_open,
+  [SPF_CLOSE] =                spf_lookup_close,
+  [SPF_FIND] =         spf_lookup_find,
 };
 
 static var_entry spf_variables[] = {
 };
 
 static var_entry spf_variables[] = {
diff --git a/src/src/miscmods/spf_api.h b/src/src/miscmods/spf_api.h
new file mode 100644 (file)
index 0000000..3801e3e
--- /dev/null
@@ -0,0 +1,19 @@
+/*************************************************
+*     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 spfmodule */
+
+
+/* Function table entry numbers */
+
+#define        SPF_PROCESS             0
+#define SPF_AUTHRES            1
+#define SPF_GET_RESPONSE       2
+#define SPF_OPEN               3
+#define SPF_CLOSE              4
+#define SPF_FIND               5
index 37b152f48b6036bdda14a50852754be601189969..a6b7722bfc9d0b0958207be7ad0e70b57fca1125 100644 (file)
@@ -3631,7 +3631,7 @@ else
     if (mi)
       {
       typedef int (*fn_t)(header_line *);
     if (mi)
       {
       typedef int (*fn_t)(header_line *);
-      (((fn_t *) mi->functions)[3]) (dmarc_from_header);
+      (((fn_t *) mi->functions)[DMARC_STORE_DATA]) (dmarc_from_header);
       }
     }
 #endif
       }
     }
 #endif