summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/doc-txt/ChangeLog102
-rw-r--r--doc/doc-txt/NewStuff94
-rw-r--r--src/ACKNOWLEDGMENTS23
-rw-r--r--src/src/EDITME11
-rw-r--r--src/src/config.h.defaults5
-rw-r--r--src/src/exim.c5
-rw-r--r--src/src/exim.h8
-rw-r--r--src/src/expand.c119
-rw-r--r--src/src/globals.c6
-rw-r--r--src/src/globals.h6
-rw-r--r--src/src/local_scan.h22
-rw-r--r--src/src/macros.h43
-rw-r--r--src/src/routers/redirect.c6
13 files changed, 321 insertions, 129 deletions
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index b2a43652c..f366edf2c 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -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
-------------------------------------------
@@ -7,53 +7,59 @@ Change log file for Exim from version 4.21
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
diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff
index 827c5d1dc..383c0f6f4 100644
--- a/doc/doc-txt/NewStuff
+++ b/doc/doc-txt/NewStuff
@@ -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
--------------------
@@ -12,32 +12,72 @@ file contains a listing of all changes, including bug fixes.
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
diff --git a/src/ACKNOWLEDGMENTS b/src/ACKNOWLEDGMENTS
index 8314c699a..0982973d2 100644
--- a/src/ACKNOWLEDGMENTS
+++ b/src/ACKNOWLEDGMENTS
@@ -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
@@ -20,7 +20,7 @@ relatively small patches.
Philip Hazel
Lists created: 20 November 2002
-Last updated: 15 March 2005
+Last updated: 22 March 2005
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
- 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
@@ -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
- 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}
@@ -121,9 +121,10 @@ Tony Finch Expansion extensions
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
@@ -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
- 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
@@ -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
- 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
@@ -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
-Alex Miller Suggested readline() patch
+Alex Miller Suggested readline() patch
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
diff --git a/src/src/EDITME b/src/src/EDITME
index 60774cf49..72f797bb3 100644
--- a/src/src/EDITME
+++ b/src/src/EDITME
@@ -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 #
@@ -690,6 +690,15 @@ ZCAT_COMMAND=/usr/bin/zcat
#------------------------------------------------------------------------------
+# 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
# distributions (see http://ftp.kernel.org/pub/linux/libs/pam/). The Exim
diff --git a/src/src/config.h.defaults b/src/src/config.h.defaults
index ea63c888f..2825f98c1 100644
--- a/src/src/config.h.defaults
+++ b/src/src/config.h.defaults
@@ -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 *
@@ -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 EXIM_PERL
-
/* Both uid and gid are triggered by this */
#define EXIM_UID
+#define EXPAND_DLFUNC
#define FIXED_NEVER_USERS "root"
diff --git a/src/src/exim.c b/src/src/exim.c
index 14cd03228..ffe596d15 100644
--- a/src/src/exim.c
+++ b/src/src/exim.c
@@ -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 *
@@ -829,6 +829,9 @@ fprintf(f, "Support for:");
#ifdef EXIM_PERL
fprintf(f, " Perl");
#endif
+#ifdef EXPAND_DLFUNC
+ fprintf(f, " Expand_dlfunc");
+#endif
#ifdef USE_TCP_WRAPPERS
fprintf(f, " TCPwrappers");
#endif
diff --git a/src/src/exim.h b/src/src/exim.h
index 42f7980c2..b28edb79b 100644
--- a/src/src/exim.h
+++ b/src/src/exim.h
@@ -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 *
@@ -60,7 +60,7 @@ making unique names. */
/* 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__
@@ -207,7 +207,7 @@ or a macro with entries f_frsize and f_bsize. */
#endif
-#ifndef SIOCGIFCONF /* HACK for SunOS 5 */
+#ifndef SIOCGIFCONF /* HACK for SunOS 5 */
#include <sys/sockio.h>
#endif
@@ -414,7 +414,7 @@ requires various things that are set therein. */
#include <iconv.h>
#endif
-#ifdef USE_READLINE
+#if defined(USE_READLINE) || defined(EXPAND_DLFUNC)
#include <dlfcn.h>
#endif
diff --git a/src/src/expand.c b/src/src/expand.c
index 6e7d3550f..d27530bd7 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -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 *
@@ -48,6 +48,7 @@ static uschar *expand_string_internal(uschar *, BOOL, uschar **, BOOL);
alphabetical order. */
static uschar *item_table[] = {
+ US"dlfunc",
US"extract",
US"hash",
US"hmac",
@@ -55,9 +56,7 @@ static uschar *item_table[] = {
US"length",
US"lookup",
US"nhash",
- #ifdef EXIM_PERL
- US"perl",
- #endif
+ US"perl",
US"readfile",
US"readsocket",
US"run",
@@ -66,6 +65,7 @@ static uschar *item_table[] = {
US"tr" };
enum {
+ EITEM_DLFUNC,
EITEM_EXTRACT,
EITEM_HASH,
EITEM_HMAC,
@@ -73,9 +73,7 @@ enum {
EITEM_LENGTH,
EITEM_LOOKUP,
EITEM_NHASH,
- #ifdef EXIM_PERL
- EITEM_PERL,
- #endif
+ EITEM_PERL,
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). */
- #ifdef EXIM_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;
@@ -3847,6 +3850,106 @@ while (*s != 0)
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
diff --git a/src/src/globals.c b/src/src/globals.c
index fdccc0b98..2324e4072 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -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 *
@@ -62,6 +62,10 @@ BOOL opt_perl_at_start = FALSE;
BOOL opt_perl_started = FALSE;
#endif
+#ifdef EXPAND_DLFUNC
+tree_node *dlobj_anchor = NULL;
+#endif
+
#ifdef LOOKUP_IBASE
uschar *ibase_servers = NULL;
#endif
diff --git a/src/src/globals.h b/src/src/globals.h
index 2bb61c145..404838126 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -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 *
@@ -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
+#ifdef EXPAND_DLFUNC
+extern tree_node *dlobj_anchor; /* Tree of dynamically-loaded objects */
+#endif
+
#ifdef LOOKUP_IBASE
extern uschar *ibase_servers;
#endif
diff --git a/src/src/local_scan.h b/src/src/local_scan.h
index e612ccd84..fdc73bed5 100644
--- a/src/src/local_scan.h
+++ b/src/src/local_scan.h
@@ -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 *
@@ -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
-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. */
@@ -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 */
+/* Extra return code for ${dlfunc functions */
+
+#define FAIL_FORCED 4 /* "Forced" failure */
+
/* Available logging destinations */
diff --git a/src/src/macros.h b/src/src/macros.h
index d69da22f7..86bb84f12 100644
--- a/src/src/macros.h
+++ b/src/src/macros.h
@@ -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 *
@@ -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.
-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 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 */
-#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 */
-#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 */
@@ -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_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 \
- (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
@@ -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,
- 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;
diff --git a/src/src/routers/redirect.c b/src/src/routers/redirect.c
index 461fc5d92..65b5e4099 100644
--- a/src/src/routers/redirect.c
+++ b/src/src/routers/redirect.c
@@ -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 *
@@ -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) },
+ #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),