1. Added Tony F's ${dlfunc expansion, slightly modified (see NewStuff).
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Tue, 22 Mar 2005 14:11:54 +0000 (14:11 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Tue, 22 Mar 2005 14:11:54 +0000 (14:11 +0000)
2. Recognize ${perl even if not compiled, and give suitable error
message.

13 files changed:
doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
src/ACKNOWLEDGMENTS
src/src/EDITME
src/src/config.h.defaults
src/src/exim.c
src/src/exim.h
src/src/expand.c
src/src/globals.c
src/src/globals.h
src/src/local_scan.h
src/src/macros.h
src/src/routers/redirect.c

index b2a43652cdc560574359f2f8ff6a8e839b29e5a6..f366edf2cbf20f747efd8e50d2bd11df3ea18052 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.93 2005/03/22 10:11:42 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.94 2005/03/22 14:11:54 ph10 Exp $
 
 Change log file for Exim from version 4.21
 -------------------------------------------
 
 Change log file for Exim from version 4.21
 -------------------------------------------
@@ -7,53 +7,59 @@ Change log file for Exim from version 4.21
 Exim version 4.51
 -----------------
 
 Exim version 4.51
 -----------------
 
-TK/01. Added Yahoo DomainKeys support via libdomainkeys. See
-       doc/experimental-spec.txt for details. (http://domainkeys.sf.net)
-
-TK/02. Fix ACL "control" statment not being available in MIME ACL.
-
-TK/03. Fix ACL "regex" condition not being available in MIME ACL.
-
-PH/01. Installed a patch from the Sieve maintainer that allows -bf to be used
-       to test Sieve filters that use "vacation".
-
-PH/02. Installed a slightly modified version of Nikos Mavrogiannopoulos' patch
-       that changes the way the GnuTLS parameters are stored in the cache file.
-       The new format can be generated externally. For backward compatibility,
-       if the data in the cache doesn't make sense, Exim assumes it has read an
-       old-format file, and it generates new data and writes a new file. This
-       means that you can't go back to an older release without removing the
-       file.
-
-PH/03. A redirect router that has both "unseen" and "one_time" set does not
-       work if there are any delivery delays because "one_time" forces the
-       parent to be marked "delivered", so its unseen clone is never tried
-       again. For this reason, Exim now forbids the simultaneous setting of
-       these two options.
-
-PH/04. Change 4.11/85 fixed an obscure bug concerned with addresses that are
-       redirected to themselves ("homonym" addresses). Read the long ChangeLog
-       entry if you want to know the details. The fix, however, neglected to
-       consider the case when local delivery batching is involved. The test for
-       "previously delivered" was not happening when checking to see if an
-       address could be batched with a previous (undelivered) one; under
-       certain circumstances this could lead to multiple deliveries to the same
-       address. A one-line patch to add the appropriate test fixes the bug.
-
-PH/05. Renamed the macro SOCKLEN_T as EXIM_SOCKLEN_T because AIX uses SOCKLEN_T
-       in its include files, and this causes problems building Exim.
-
-PH/06. A number of "verify =" ACL conditions have no options (e.g. verify =
-       header_syntax) but Exim was just ignoring anything given after a slash.
-       In particular, this caused confusion with an attempt to use "verify =
-       reverse_host_lookup/defer_ok". An error is now given when options are
-       supplied for verify items that do not have them. (Maybe reverse_host_
-       lookup should have a defer_ok option, but that's a different point.)
-
-PH/07. Increase the size of the buffer for incoming SMTP commands from 512 (as
-       defined by RFC 821) to 2048, because there were problems with some AUTH
-       commands, and RFC 1869 says the size should be increased for extended
-       SMTP commands that take arguments.
+TK/01 Added Yahoo DomainKeys support via libdomainkeys. See
+      doc/experimental-spec.txt for details. (http://domainkeys.sf.net)
+
+TK/02 Fix ACL "control" statment not being available in MIME ACL.
+
+TK/03 Fix ACL "regex" condition not being available in MIME ACL.
+
+PH/01 Installed a patch from the Sieve maintainer that allows -bf to be used
+      to test Sieve filters that use "vacation".
+
+PH/02 Installed a slightly modified version of Nikos Mavrogiannopoulos' patch
+      that changes the way the GnuTLS parameters are stored in the cache file.
+      The new format can be generated externally. For backward compatibility,
+      if the data in the cache doesn't make sense, Exim assumes it has read an
+      old-format file, and it generates new data and writes a new file. This
+      means that you can't go back to an older release without removing the
+      file.
+
+PH/03 A redirect router that has both "unseen" and "one_time" set does not
+      work if there are any delivery delays because "one_time" forces the
+      parent to be marked "delivered", so its unseen clone is never tried
+      again. For this reason, Exim now forbids the simultaneous setting of
+      these two options.
+
+PH/04 Change 4.11/85 fixed an obscure bug concerned with addresses that are
+      redirected to themselves ("homonym" addresses). Read the long ChangeLog
+      entry if you want to know the details. The fix, however, neglected to
+      consider the case when local delivery batching is involved. The test for
+      "previously delivered" was not happening when checking to see if an
+      address could be batched with a previous (undelivered) one; under
+      certain circumstances this could lead to multiple deliveries to the same
+      address. A one-line patch to add the appropriate test fixes the bug.
+
+PH/05 Renamed the macro SOCKLEN_T as EXIM_SOCKLEN_T because AIX uses SOCKLEN_T
+      in its include files, and this causes problems building Exim.
+
+PH/06 A number of "verify =" ACL conditions have no options (e.g. verify =
+      header_syntax) but Exim was just ignoring anything given after a slash.
+      In particular, this caused confusion with an attempt to use "verify =
+      reverse_host_lookup/defer_ok". An error is now given when options are
+      supplied for verify items that do not have them. (Maybe reverse_host_
+      lookup should have a defer_ok option, but that's a different point.)
+
+PH/07 Increase the size of the buffer for incoming SMTP commands from 512 (as
+      defined by RFC 821) to 2048, because there were problems with some AUTH
+      commands, and RFC 1869 says the size should be increased for extended
+      SMTP commands that take arguments.
+
+PH/08 Added ${dlfunc dynamically loaded function for expansion (code from Tony
+      Finch).
+
+PH/09 Previously, an attempt to use ${perl when it wasn't compiled gave an
+      "unknown" error; now it says that the functionality isn't in the binary.
 
 
 A note about Exim versions 4.44 and 4.50
 
 
 A note about Exim versions 4.44 and 4.50
index 827c5d1dce664164bab87beb954e99829498907b..383c0f6f4fab857ac060e61b84b28d91e3f7c9d1 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/NewStuff,v 1.27 2005/03/08 11:38:21 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/NewStuff,v 1.28 2005/03/22 14:11:54 ph10 Exp $
 
 New Features in Exim
 --------------------
 
 New Features in Exim
 --------------------
@@ -12,32 +12,72 @@ file contains a listing of all changes, including bug fixes.
 Version 4.51
 ------------
 
 Version 4.51
 ------------
 
-PH/01. The format in which GnuTLS parameters are written to the gnutls-param
-       file in the spool directory has been changed. This change has been made
-       to alleviate problems that some people had with the generation of the
-       parameters by Exim when /dev/random was exhausted. In this situation,
-       Exim would hang until /dev/random acquired some more entropy.
-
-       The new code exports and imports the DH and RSA parameters in PEM
-       format. This means that the parameters can be generated externally using
-       the certtool command that is part of GnuTLS.
-
-       To replace the parameters with new ones, instead of deleting the file
-       and letting Exim re-create it, you can generate new parameters using
-       certtool and, when this has been done, replace Exim's cache file by
-       renaming. The relevant commands are something like this:
-
-         # rm -f new.params
-         # touch new.params
-         # chown exim:exim new.params
-         # chmod 0400 new.params
-         # certtool --generate-privkey --bits 512 >new.params
-         # echo "" >>new.params
-         # certtool --generate-dh-params --bits 1024 >> new.params
-         # mv new.params params
-
-       If Exim never has to generate the parameters itself, the possibility of
-       stalling is removed.
+PH/01 The format in which GnuTLS parameters are written to the gnutls-param
+      file in the spool directory has been changed. This change has been made
+      to alleviate problems that some people had with the generation of the
+      parameters by Exim when /dev/random was exhausted. In this situation,
+      Exim would hang until /dev/random acquired some more entropy.
+
+      The new code exports and imports the DH and RSA parameters in PEM
+      format. This means that the parameters can be generated externally using
+      the certtool command that is part of GnuTLS.
+
+      To replace the parameters with new ones, instead of deleting the file
+      and letting Exim re-create it, you can generate new parameters using
+      certtool and, when this has been done, replace Exim's cache file by
+      renaming. The relevant commands are something like this:
+
+        # rm -f new.params
+        # touch new.params
+        # chown exim:exim new.params
+        # chmod 0400 new.params
+        # certtool --generate-privkey --bits 512 >new.params
+        # echo "" >>new.params
+        # certtool --generate-dh-params --bits 1024 >> new.params
+        # mv new.params params
+
+      If Exim never has to generate the parameters itself, the possibility of
+      stalling is removed.
+
+PH/02 A new expansion item for dynamically loading and calling a locally-
+      written C function is now provided, if Exim is compiled with
+
+        EXPAND_DLFUNC=yes
+
+      set in Local/Makefile. The facility is not included by default (a
+      suitable error is given if you try to use it when it is not there.)
+      You load and call the function like this:
+
+        ${dlfunc{/some/file}{function}{arg1}{arg2}...}
+
+      Once loaded, Exim remembers it so that it doesn't reload it in the same
+      Exim process (but of course Exim does start new processes frequently).
+
+      There may be from zero to eight arguments to the function. When compiling
+      a local function that is to be called in this way, local_scan.h should be
+      included. The Exim variables and functions that are defined by that API
+      are also available for dynamically loaded functions. The function itself
+      must have the following type:
+
+        int dlfunction(uschar **yield, int argc, uschar *argv[])
+
+      Where "uschar" is a typedef for "unsigned char" in local_scan.h. The
+      function should return one of the following values:
+
+      OK            Success. The string that is placed in "yield" is put into
+                    the expanded string that is being built.
+
+      FAIL          A non-forced expansion failure occurs, with the error
+                    message taken from "yield", if it is set.
+
+      FAIL_FORCED   A forced expansion failure occurs, with the error message
+                    taken from "yield" if it is set.
+
+      ERROR         Same as FAIL, except that a panic log entry is written.
+
+      When compiling a function that is to be used in this way with gcc,
+      you need to add -shared to the gcc command. Also, in the Exim build-time
+      configuration, you must add -export-dynamic to EXTRALIBS.
 
 
 Version 4.50
 
 
 Version 4.50
index 8314c699af17a40db1d48957f87ef0e6d18de016..0982973d2e5383dfc30c2d1ee7bb9b1a18c8fde9 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/src/ACKNOWLEDGMENTS,v 1.15 2005/03/15 12:27:54 ph10 Exp $
+$Cambridge: exim/src/ACKNOWLEDGMENTS,v 1.16 2005/03/22 14:11:54 ph10 Exp $
 
 EXIM ACKNOWLEDGEMENTS
 
 
 EXIM ACKNOWLEDGEMENTS
 
@@ -20,7 +20,7 @@ relatively small patches.
 Philip Hazel
 
 Lists created: 20 November 2002
 Philip Hazel
 
 Lists created: 20 November 2002
-Last updated:  15 March 2005
+Last updated:  22 March 2005
 
 
 THE OLD LIST
 
 
 THE OLD LIST
@@ -78,7 +78,7 @@ Richard Birkett           Fix for empty -f address crash
 Nick Burrett              Patch for CONFIGURE_FILE_USE_EUID in exicyclog
 Matthew Byng-Maddick      Patch for qualify_domain in redirect router
                           Patch for ignore_target_hosts in ipliteral router
 Nick Burrett              Patch for CONFIGURE_FILE_USE_EUID in exicyclog
 Matthew Byng-Maddick      Patch for qualify_domain in redirect router
                           Patch for ignore_target_hosts in ipliteral router
-                          The cyrus_sasl authenticator 
+                          The cyrus_sasl authenticator
 Steve Campbell            eximstats extensions and continued maintenance
 Brian Candler             Use h_errno for gethostbyname()
                           Suggested patch for .ifdef etc
 Steve Campbell            eximstats extensions and continued maintenance
 Brian Candler             Use h_errno for gethostbyname()
                           Suggested patch for .ifdef etc
@@ -93,7 +93,7 @@ Andrew Doran              Patch for NetBSD configuration files
                           Patch for ifreq alignment and size problems
 Michael Deutschmann       Suggested patch for treating bind() failure like connect()
                           Patch for $sender_data and $recipient_data
                           Patch for ifreq alignment and size problems
 Michael Deutschmann       Suggested patch for treating bind() failure like connect()
                           Patch for $sender_data and $recipient_data
-                          Suggested patch for null address match lookup bug 
+                          Suggested patch for null address match lookup bug
 Oliver Eikemeier          Patch to skip Received: if expansion is empty
                           Patch for "eqi"
 Nico Erfurth              Fix for bug in ${readfile}
 Oliver Eikemeier          Patch to skip Received: if expansion is empty
                           Patch for "eqi"
 Nico Erfurth              Fix for bug in ${readfile}
@@ -121,9 +121,10 @@ Tony Finch                Expansion extensions
                             A number of useful code criticisms
                             Timezone patch for exiwhat
                             Patch for more daemon exiwhat information
                             A number of useful code criticisms
                             Timezone patch for exiwhat
                             Patch for more daemon exiwhat information
-                            Patch for -dd 
-                            Patch for mxh lookup type in dnsdb 
-                            Patch for defer_foo in dndsb 
+                            Patch for -dd
+                            Patch for mxh lookup type in dnsdb
+                            Patch for defer_foo in dndsb
+                            Patch for ${dlfunc
 Giuliano Gavazzi          Patches for OSX compilation
 Dominic Germain           Patch for exiqgrep MacOS X bug
 Oliver Gorwits            $load_average patch
 Giuliano Gavazzi          Patches for OSX compilation
 Dominic Germain           Patch for exiqgrep MacOS X bug
 Oliver Gorwits            $load_average patch
@@ -138,7 +139,7 @@ Michael Haardt            Tidies to make the code stricter
                           Module to support Sieve (RFC 3028) filters and
                             continued maintenance of same
                           Patch for faster sort algorithm in queue.c
                           Module to support Sieve (RFC 3028) filters and
                             continued maintenance of same
                           Patch for faster sort algorithm in queue.c
-                          Patch for LDAP timeout handling 
+                          Patch for LDAP timeout handling
 Thomas Hager              Patch for saslauthd crash bug
 Richard Hall              Fix for file descriptor leak in redirection
 Steve Haslam              Lots of stuff, including
 Thomas Hager              Patch for saslauthd crash bug
 Richard Hall              Fix for file descriptor leak in redirection
 Steve Haslam              Lots of stuff, including
@@ -154,7 +155,7 @@ Christian Kellner         Patch for LDAP dereferencing
 Alex Kiernan              Patch for libradius
                           Diagnosis of milliwait clock-backwards bug
 Tom Kistner               SPA server code
 Alex Kiernan              Patch for libradius
                           Diagnosis of milliwait clock-backwards bug
 Tom Kistner               SPA server code
-                          Writing and maintaining the content scanning 
+                          Writing and maintaining the content scanning
                             extension (exiscan)
 Friso Kuipers             Patch for GDBM problem
 Chris Liddiard            Fix for bug in exiqsumm
                             extension (exiscan)
 Friso Kuipers             Patch for GDBM problem
 Chris Liddiard            Fix for bug in exiqsumm
@@ -174,9 +175,9 @@ Marc Merlin               Many suggestions and patches for callouts and
                             SMTP error message features
 Andreas Metzler           Patch for message_id_header_domain
                           Suggested patch for multi-config files in scripts bug
                             SMTP error message features
 Andreas Metzler           Patch for message_id_header_domain
                           Suggested patch for multi-config files in scripts bug
-Alex Miller               Suggested readline() patch                           
+Alex Miller               Suggested readline() patch
                           Patch for LDAP_RES_SEARCH_REFERENCE handling
                           Patch for LDAP_RES_SEARCH_REFERENCE handling
-                          Support for the DrWeb content scanner 
+                          Support for the DrWeb content scanner
 Andreas Mueller           Patch for logging uncompleted SMTP transactions
 Pete Naylor               Patch for LDAP TCP connect timeout setting
 Marcin Owsiany            Diagnosis of a tricky timeout failure bug
 Andreas Mueller           Patch for logging uncompleted SMTP transactions
 Pete Naylor               Patch for LDAP TCP connect timeout setting
 Marcin Owsiany            Diagnosis of a tricky timeout failure bug
index 60774cf498757150eed498dcb9f799bf855ca33c..72f797bb355ab23ae1fbe1d7a62eeac3c51a7aee 100644 (file)
@@ -1,4 +1,4 @@
-# $Cambridge: exim/src/src/EDITME,v 1.8 2005/02/17 11:58:25 ph10 Exp $
+# $Cambridge: exim/src/src/EDITME,v 1.9 2005/03/22 14:11:54 ph10 Exp $
 
 ##################################################
 #          The Exim mail transport agent         #
 
 ##################################################
 #          The Exim mail transport agent         #
@@ -689,6 +689,15 @@ ZCAT_COMMAND=/usr/bin/zcat
 # EXIM_PERL=perl.o
 
 
 # EXIM_PERL=perl.o
 
 
+#------------------------------------------------------------------------------
+# Support for dynamically-loaded string expansion functions via ${dlfunc. If
+# you are using gcc the dynamically-loaded object must be compiled with the
+# -shared option, and you will need to add -export-dynamic to EXTRALIBS so
+# that the local_scan API is made available by the linker.
+
+# EXPAND_DLFUNC=yes
+
+
 #------------------------------------------------------------------------------
 # Exim has support for PAM (Pluggable Authentication Modules), a facility
 # which is available in the latest releases of Solaris and in some GNU/Linux
 #------------------------------------------------------------------------------
 # Exim has support for PAM (Pluggable Authentication Modules), a facility
 # which is available in the latest releases of Solaris and in some GNU/Linux
index ea63c888f9465ea56b908ab8f72a2a67ad0e6e4a..2825f98c1ca35649824c068bee90c56aa54f562f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/config.h.defaults,v 1.5 2005/03/08 15:32:02 tom Exp $ */
+/* $Cambridge: exim/src/src/config.h.defaults,v 1.6 2005/03/22 14:11:54 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -42,11 +42,10 @@ in config.h unless some value is defined in Local/Makefile. */
 #define EXIMDB_LOCK_TIMEOUT          60
 #define EXIMDB_LOCKFILE_MODE       0640
 #define EXIMDB_MODE                0640
 #define EXIMDB_LOCK_TIMEOUT          60
 #define EXIMDB_LOCKFILE_MODE       0640
 #define EXIMDB_MODE                0640
-
 #define EXIM_PERL
 #define EXIM_PERL
-
 /* Both uid and gid are triggered by this */
 #define EXIM_UID
 /* Both uid and gid are triggered by this */
 #define EXIM_UID
+#define EXPAND_DLFUNC
 
 #define FIXED_NEVER_USERS         "root"
 
 
 #define FIXED_NEVER_USERS         "root"
 
index 14cd032280eca7305e12d480b5b27812cac95b68..ffe596d15d8cdbe879a5c92521b29406ac2d3aa8 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/exim.c,v 1.16 2005/03/15 14:09:12 ph10 Exp $ */
+/* $Cambridge: exim/src/src/exim.c,v 1.17 2005/03/22 14:11:54 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -829,6 +829,9 @@ fprintf(f, "Support for:");
 #ifdef EXIM_PERL
   fprintf(f, " Perl");
 #endif
 #ifdef EXIM_PERL
   fprintf(f, " Perl");
 #endif
+#ifdef EXPAND_DLFUNC
+  fprintf(f, " Expand_dlfunc");
+#endif
 #ifdef USE_TCP_WRAPPERS
   fprintf(f, " TCPwrappers");
 #endif
 #ifdef USE_TCP_WRAPPERS
   fprintf(f, " TCPwrappers");
 #endif
index 42f7980c2ec0b23223022d66e7bc04359976f317..b28edb79bf80ab90ef14b7bec3650f0440f1a6e8 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/exim.h,v 1.9 2005/03/15 14:09:12 ph10 Exp $ */
+/* $Cambridge: exim/src/src/exim.h,v 1.10 2005/03/22 14:11:54 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -60,7 +60,7 @@ making unique names. */
 /* Unix includes */
 
 #include <errno.h>
 /* Unix includes */
 
 #include <errno.h>
-#if    defined(__svr4__) && defined(__sparc) && ! defined(__EXTENSIONS__)
+#if defined(__svr4__) && defined(__sparc) && ! defined(__EXTENSIONS__)
 #define __EXTENSIONS__  /* so that SunOS 5 gets NGROUPS_MAX */
 #include <limits.h>
 #undef  __EXTENSIONS__
 #define __EXTENSIONS__  /* so that SunOS 5 gets NGROUPS_MAX */
 #include <limits.h>
 #undef  __EXTENSIONS__
@@ -207,7 +207,7 @@ or a macro with entries f_frsize and f_bsize. */
 #endif
 
 
 #endif
 
 
-#ifndef  SIOCGIFCONF    /* HACK for SunOS 5 */
+#ifndef  SIOCGIFCONF   /* HACK for SunOS 5 */
 #include <sys/sockio.h>
 #endif
 
 #include <sys/sockio.h>
 #endif
 
@@ -414,7 +414,7 @@ requires various things that are set therein. */
 #include <iconv.h>
 #endif
 
 #include <iconv.h>
 #endif
 
-#ifdef USE_READLINE
+#if defined(USE_READLINE) || defined(EXPAND_DLFUNC)
 #include <dlfcn.h>
 #endif
 
 #include <dlfcn.h>
 #endif
 
index 6e7d3550f41b7a4d360d3b4659ee7c52ff515644..d27530bd7b16059ce9beb9bc4e313b02792c55c5 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/expand.c,v 1.16 2005/03/09 08:27:51 tom Exp $ */
+/* $Cambridge: exim/src/src/expand.c,v 1.17 2005/03/22 14:11:54 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -48,6 +48,7 @@ static uschar *expand_string_internal(uschar *, BOOL, uschar **, BOOL);
 alphabetical order. */
 
 static uschar *item_table[] = {
 alphabetical order. */
 
 static uschar *item_table[] = {
+  US"dlfunc",
   US"extract",
   US"hash",
   US"hmac",
   US"extract",
   US"hash",
   US"hmac",
@@ -55,9 +56,7 @@ static uschar *item_table[] = {
   US"length",
   US"lookup",
   US"nhash",
   US"length",
   US"lookup",
   US"nhash",
-  #ifdef EXIM_PERL
-    US"perl",
-  #endif
+  US"perl",
   US"readfile",
   US"readsocket",
   US"run",
   US"readfile",
   US"readsocket",
   US"run",
@@ -66,6 +65,7 @@ static uschar *item_table[] = {
   US"tr" };
 
 enum {
   US"tr" };
 
 enum {
+  EITEM_DLFUNC,
   EITEM_EXTRACT,
   EITEM_HASH,
   EITEM_HMAC,
   EITEM_EXTRACT,
   EITEM_HASH,
   EITEM_HMAC,
@@ -73,9 +73,7 @@ enum {
   EITEM_LENGTH,
   EITEM_LOOKUP,
   EITEM_NHASH,
   EITEM_LENGTH,
   EITEM_LOOKUP,
   EITEM_NHASH,
-  #ifdef EXIM_PERL
-    EITEM_PERL,
-  #endif
+  EITEM_PERL,
   EITEM_READFILE,
   EITEM_READSOCK,
   EITEM_RUN,
   EITEM_READFILE,
   EITEM_READSOCK,
   EITEM_RUN,
@@ -3072,10 +3070,15 @@ while (*s != 0)
     or ${perl{sub}{arg1}{arg2}} or up to a maximum of EXIM_PERL_MAX_ARGS
     arguments (defined below). */
 
     or ${perl{sub}{arg1}{arg2}} or up to a maximum of EXIM_PERL_MAX_ARGS
     arguments (defined below). */
 
-    #ifdef EXIM_PERL
     #define EXIM_PERL_MAX_ARGS 8
 
     case EITEM_PERL:
     #define EXIM_PERL_MAX_ARGS 8
 
     case EITEM_PERL:
+    #ifndef EXIM_PERL
+    expand_string_message = US"\"${perl\" encountered, but this facility "
+      "is not included in this binary";
+    goto EXPAND_FAILED;
+
+    #else   /* EXIM_PERL */
       {
       uschar *sub_arg[EXIM_PERL_MAX_ARGS + 2];
       uschar *new_yield;
       {
       uschar *sub_arg[EXIM_PERL_MAX_ARGS + 2];
       uschar *new_yield;
@@ -3847,6 +3850,106 @@ while (*s != 0)
 
       continue;
       }
 
       continue;
       }
+
+
+    /* If ${dlfunc support is configured, handle calling dynamically-loaded
+    functions, unless locked out at this time. Syntax is ${dlfunc{file}{func}}
+    or ${dlfunc{file}{func}{arg}} or ${dlfunc{file}{func}{arg1}{arg2}} or up to
+    a maximum of EXPAND_DLFUNC_MAX_ARGS arguments (defined below). */
+
+    #define EXPAND_DLFUNC_MAX_ARGS 8
+
+    case EITEM_DLFUNC:
+    #ifndef EXPAND_DLFUNC
+    expand_string_message = US"\"${dlfunc\" encountered, but this facility "
+      "is not included in this binary";
+    goto EXPAND_FAILED;
+
+    #else   /* EXPAND_DLFUNC */
+      {
+      tree_node *t;
+      exim_dlfunc_t *func;
+      uschar *result;
+      int status, argc;
+      uschar *argv[EXPAND_DLFUNC_MAX_ARGS + 3];
+
+      if ((expand_forbid & RDO_DLFUNC) != 0)
+        {
+        expand_string_message =
+          US"dynamically-loaded functions are not permitted";
+        goto EXPAND_FAILED;
+        }
+
+      switch(read_subs(argv, EXPAND_DLFUNC_MAX_ARGS + 2, 2, &s, skipping,
+           TRUE, US"dlfunc"))
+        {
+        case 1: goto EXPAND_FAILED_CURLY;
+        case 2:
+        case 3: goto EXPAND_FAILED;
+        }
+
+      /* If skipping, we don't actually do anything */
+
+      if (skipping) continue;
+
+      /* Look up the dynamically loaded object handle in the tree. If it isn't
+      found, dlopen() the file and put the handle in the tree for next time. */
+
+      t = tree_search(dlobj_anchor, argv[0]);
+      if (t == NULL)
+        {
+        void *handle = dlopen(CS argv[0], RTLD_LAZY);
+        if (handle == NULL)
+          {
+          expand_string_message = string_sprintf("dlopen \"%s\" failed: %s",
+            argv[0], dlerror());
+          log_write(0, LOG_MAIN|LOG_PANIC, "%s", expand_string_message);
+          goto EXPAND_FAILED;
+          }
+        t = store_get_perm(sizeof(tree_node) + Ustrlen(argv[0]));
+        Ustrcpy(t->name, argv[0]);
+        t->data.ptr = handle;
+        (void)tree_insertnode(&dlobj_anchor, t);
+        }
+
+      /* Having obtained the dynamically loaded object handle, look up the
+      function pointer. */
+
+      func = (exim_dlfunc_t *)dlsym(t->data.ptr, CS argv[1]);
+      if (func == NULL)
+        {
+        expand_string_message = string_sprintf("dlsym \"%s\" in \"%s\" failed: "
+          "%s", argv[1], argv[0], dlerror());
+       log_write(0, LOG_MAIN|LOG_PANIC, "%s", expand_string_message);
+        goto EXPAND_FAILED;
+        }
+
+      /* Call the function and work out what to do with the result. If it
+      returns OK, we have a replacement string; if it returns DEFER then
+      expansion has failed in a non-forced manner; if it returns FAIL then
+      failure was forced; if it returns ERROR or any other value there's a
+      problem, so panic slightly. */
+
+      result = NULL;
+      for (argc = 0; argv[argc] != NULL; argc++);
+      status = func(&result, argc - 2, &argv[2]);
+      if(status == OK)
+        {
+        if (result == NULL) result = US"";
+        yield = string_cat(yield, &size, &ptr, result, Ustrlen(result));
+        continue;
+        }
+      else
+        {
+        expand_string_message = result == NULL ? US"(no message)" : result;
+        if(status == FAIL_FORCED) expand_string_forcedfail = TRUE;
+          else if(status != FAIL)
+            log_write(0, LOG_MAIN|LOG_PANIC, "dlfunc{%s}{%s} failed (%d): %s",
+              argv[0], argv[1], status, expand_string_message);
+        goto EXPAND_FAILED;
+        }
+      }
+    #endif /* EXPAND_DLFUNC */
     }
 
   /* Control reaches here if the name is not recognized as one of the more
     }
 
   /* Control reaches here if the name is not recognized as one of the more
index fdccc0b989165a36f10b0dedb1ea3a07472ece4c..2324e40723a99f27581c95c18b44ea1a8fc903c3 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.c,v 1.19 2005/03/08 15:32:02 tom Exp $ */
+/* $Cambridge: exim/src/src/globals.c,v 1.20 2005/03/22 14:11:54 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -62,6 +62,10 @@ BOOL    opt_perl_at_start      = FALSE;
 BOOL    opt_perl_started       = FALSE;
 #endif
 
 BOOL    opt_perl_started       = FALSE;
 #endif
 
+#ifdef EXPAND_DLFUNC
+tree_node *dlobj_anchor        = NULL;
+#endif
+
 #ifdef LOOKUP_IBASE
 uschar *ibase_servers          = NULL;
 #endif
 #ifdef LOOKUP_IBASE
 uschar *ibase_servers          = NULL;
 #endif
index 2bb61c14534a7ff05ffeddd3e62781b089a8c153..404838126e355c8901c31f913de462b5e2cde7f9 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.h,v 1.12 2005/03/08 15:32:02 tom Exp $ */
+/* $Cambridge: exim/src/src/globals.h,v 1.13 2005/03/22 14:11:54 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -26,6 +26,10 @@ extern BOOL    opt_perl_at_start;      /* Start Perl interpreter at start */
 extern BOOL    opt_perl_started;       /* Set once interpreter started */
 #endif
 
 extern BOOL    opt_perl_started;       /* Set once interpreter started */
 #endif
 
+#ifdef EXPAND_DLFUNC
+extern tree_node *dlobj_anchor;        /* Tree of dynamically-loaded objects */
+#endif
+
 #ifdef LOOKUP_IBASE
 extern uschar *ibase_servers;
 #endif
 #ifdef LOOKUP_IBASE
 extern uschar *ibase_servers;
 #endif
index e612ccd84c6dc9bd8a35bb6ef7b74e9a5de4336b..fdc73bed57d9cc7d7a20697681cc293fb5207c64 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/local_scan.h,v 1.3 2005/01/04 10:00:42 ph10 Exp $ */
+/* $Cambridge: exim/src/src/local_scan.h,v 1.4 2005/03/22 14:11:54 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -9,7 +9,9 @@
 
 /* This file is the header that is the only Exim header to be included in the
 source for the local_scan.c() function. It contains definitions that are made
 
 /* This file is the header that is the only Exim header to be included in the
 source for the local_scan.c() function. It contains definitions that are made
-available for use in that function, and which are documented. */
+available for use in that function, and which are documented.
+
+This API is also used for functions called by the ${dlfunc expansion item. */
 
 
 /* Some basic types that make some things easier, and the store functions. */
 
 
 /* Some basic types that make some things easier, and the store functions. */
@@ -34,13 +36,27 @@ enum {
 };
 
 
 };
 
 
-/* Return codes from the support functions lss_match_xxx(). */
+/* Functions called by ${dlfunc{file}{func}{arg}...} return one of the five
+status codes defined immediately below. The function's first argument is either
+the result of expansion, or the error message in case of failure. The second
+and third arguments are standard argument count and vector, comprising the
+{arg} values specified in the expansion item. */
+
+typedef int exim_dlfunc_t(uschar **yield, int argc, uschar *argv[]);
+
+
+/* Return codes from the support functions lss_match_xxx(). These are also the
+codes that dynamically-loaded ${dlfunc functions must return. */
 
 #define  OK            0          /* Successful match */
 #define  DEFER         1          /* Defer - some problem */
 #define  FAIL          2          /* Matching failed */
 #define  ERROR         3          /* Internal or config error */
 
 
 #define  OK            0          /* Successful match */
 #define  DEFER         1          /* Defer - some problem */
 #define  FAIL          2          /* Matching failed */
 #define  ERROR         3          /* Internal or config error */
 
+/* Extra return code for ${dlfunc functions */
+
+#define  FAIL_FORCED   4          /* "Forced" failure */
+
 
 /* Available logging destinations */
 
 
 /* Available logging destinations */
 
index d69da22f7cc048c3d3c7a6e855fa5544cc5d4e69..86bb84f1281dbb295d64aff5435e1def3f1b9a1f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/macros.h,v 1.10 2005/03/10 08:56:03 tom Exp $ */
+/* $Cambridge: exim/src/src/macros.h,v 1.11 2005/03/22 14:11:54 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -237,27 +237,29 @@ enum {
 apply to all of them). Some other functions also use these convenient values,
 and some additional values are used only by non-driver functions.
 
 apply to all of them). Some other functions also use these convenient values,
 and some additional values are used only by non-driver functions.
 
-OK, FAIL, DEFER, and ERROR are also declared in local_scan.h for use in the
-local_scan() function. Do not change them unilaterally. */
+OK, FAIL, DEFER, ERROR, and FAIL_FORCED are also declared in local_scan.h for
+use in the local_scan() function and in ${dlfunc loaded functions. Do not
+change them unilaterally. */
 
 #define  OK            0    /* Successful match */
 #define  DEFER         1    /* Defer - some problem */
 #define  FAIL          2    /* Matching failed */
 #define  ERROR         3    /* Internal or config error */
 
 #define  OK            0    /* Successful match */
 #define  DEFER         1    /* Defer - some problem */
 #define  FAIL          2    /* Matching failed */
 #define  ERROR         3    /* Internal or config error */
+#define  FAIL_FORCED   4    /* "Forced" failure */
 /***********/
 /***********/
-#define DECLINE        4    /* Declined to handle the address, pass to next
+#define DECLINE        5    /* Declined to handle the address, pass to next
                                  router unless no_more is set */
                                  router unless no_more is set */
-#define PASS           5    /* Pass to next driver, or to pass_router,
+#define PASS           6    /* Pass to next driver, or to pass_router,
                                  even if no_more is set */
                                  even if no_more is set */
-#define DISCARD        6    /* Address routed to :blackhole: or "seen finish" */
-#define SKIP           7    /* Skip this router (used in route_address only) */
-#define REROUTED       8    /* Address was changed and child created*/
-#define PANIC          9    /* Hard failed with internal error */
-#define BAD64         10    /* Bad base64 data (auth) */
-#define UNEXPECTED    11    /* Unexpected initial auth data */
-#define CANCELLED     12    /* Authentication cancelled */
-#define FAIL_SEND     13    /* send() failed in authenticator */
-#define FAIL_DROP     14    /* Fail and drop connection (used in ACL) */
+#define DISCARD        7    /* Address routed to :blackhole: or "seen finish" */
+#define SKIP           8    /* Skip this router (used in route_address only) */
+#define REROUTED       9    /* Address was changed and child created*/
+#define PANIC         10    /* Hard failed with internal error */
+#define BAD64         11    /* Bad base64 data (auth) */
+#define UNEXPECTED    12    /* Unexpected initial auth data */
+#define CANCELLED     13    /* Authentication cancelled */
+#define FAIL_SEND     14    /* send() failed in authenticator */
+#define FAIL_DROP     15    /* Fail and drop connection (used in ACL) */
 
 /* Returns from the deliver_message() function */
 
 
 /* Returns from the deliver_message() function */
 
@@ -489,15 +491,16 @@ router, which were chosen to represent the standard situation for users'
 #define RDO_READFILE     0x00001000  /* Forbid "readfile" in exp in filter */
 #define RDO_READSOCK     0x00002000  /* Forbid "readsocket" in exp in filter */
 #define RDO_RUN          0x00004000  /* Forbid "run" in expansion in filter */
 #define RDO_READFILE     0x00001000  /* Forbid "readfile" in exp in filter */
 #define RDO_READSOCK     0x00002000  /* Forbid "readsocket" in exp in filter */
 #define RDO_RUN          0x00004000  /* Forbid "run" in expansion in filter */
-#define RDO_REALLOG      0x00008000  /* Really do log (not testing/verifying) */
-#define RDO_REWRITE      0x00010000  /* Rewrite generated addresses */
-#define RDO_EXIM_FILTER  0x00020000  /* Forbid Exim filters */
-#define RDO_SIEVE_FILTER 0x00040000  /* Forbid Sieve filters */
+#define RDO_DLFUNC       0x00008000  /* Forbid "dlfunc" in expansion in filter */
+#define RDO_REALLOG      0x00010000  /* Really do log (not testing/verifying) */
+#define RDO_REWRITE      0x00020000  /* Rewrite generated addresses */
+#define RDO_EXIM_FILTER  0x00040000  /* Forbid Exim filters */
+#define RDO_SIEVE_FILTER 0x00080000  /* Forbid Sieve filters */
 
 /* This is the set that apply to expansions in filters */
 
 #define RDO_FILTER_EXPANSIONS \
 
 /* This is the set that apply to expansions in filters */
 
 #define RDO_FILTER_EXPANSIONS \
-  (RDO_EXISTS|RDO_LOOKUP|RDO_PERL|RDO_READFILE|RDO_READSOCK|RDO_RUN)
+  (RDO_EXISTS|RDO_LOOKUP|RDO_PERL|RDO_READFILE|RDO_READSOCK|RDO_RUN|RDO_DLFUNC)
 
 /* As well as the RDO bits themselves, we need the bit numbers in order to
 access (most of) the individual bits as separate options. This could be
 
 /* As well as the RDO bits themselves, we need the bit numbers in order to
 access (most of) the individual bits as separate options. This could be
@@ -505,7 +508,7 @@ automated, but I haven't bothered. Keep this list in step with the above! */
 
 enum { RDON_BLACKHOLE, RDON_DEFER, RDON_EACCES, RDON_ENOTDIR, RDON_EXISTS,
   RDON_FAIL, RDON_FILTER, RDON_FREEZE, RDON_INCLUDE, RDON_LOG, RDON_LOOKUP,
 
 enum { RDON_BLACKHOLE, RDON_DEFER, RDON_EACCES, RDON_ENOTDIR, RDON_EXISTS,
   RDON_FAIL, RDON_FILTER, RDON_FREEZE, RDON_INCLUDE, RDON_LOG, RDON_LOOKUP,
-  RDON_PERL, RDON_READFILE, RDON_READSOCK, RDON_RUN, RDON_REALLOG,
+  RDON_PERL, RDON_READFILE, RDON_READSOCK, RDON_RUN, RDON_DLFUNC, RDON_REALLOG,
   RDON_REWRITE, RDON_EXIM_FILTER, RDON_SIEVE_FILTER };
 
 /* Results of filter or forward file processing. Some are only from a filter;
   RDON_REWRITE, RDON_EXIM_FILTER, RDON_SIEVE_FILTER };
 
 /* Results of filter or forward file processing. Some are only from a filter;
index 461fc5d92252e136b6a547e72c974837310419c3..65b5e40994cc75fed58eafcdc8595a2d031a4a5d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/routers/redirect.c,v 1.6 2005/03/15 11:37:21 ph10 Exp $ */
+/* $Cambridge: exim/src/src/routers/redirect.c,v 1.7 2005/03/22 14:11:55 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -45,6 +45,10 @@ optionlist redirect_router_options[] = {
       (void *)offsetof(redirect_router_options_block, bit_options) },
   { "forbid_file",        opt_bool,
       (void *)offsetof(redirect_router_options_block, forbid_file) },
       (void *)offsetof(redirect_router_options_block, bit_options) },
   { "forbid_file",        opt_bool,
       (void *)offsetof(redirect_router_options_block, forbid_file) },
+  #ifdef EXPAND_DLFUNC
+  { "forbid_filter_dlfunc", opt_bit | (RDON_DLFUNC << 16),
+      (void *)offsetof(redirect_router_options_block, bit_options) },
+  #endif
   { "forbid_filter_existstest",  opt_bit | (RDON_EXISTS << 16),
       (void *)offsetof(redirect_router_options_block, bit_options) },
   { "forbid_filter_logwrite",opt_bit | (RDON_LOG << 16),
   { "forbid_filter_existstest",  opt_bit | (RDON_EXISTS << 16),
       (void *)offsetof(redirect_router_options_block, bit_options) },
   { "forbid_filter_logwrite",opt_bit | (RDON_LOG << 16),