ph10 2005/03/22 14:11:55 GMT
Modified files:
exim-doc/doc-txt ChangeLog NewStuff
exim-src ACKNOWLEDGMENTS
exim-src/src EDITME config.h.defaults exim.c exim.h
expand.c globals.c globals.h local_scan.h
macros.h
exim-src/src/routers redirect.c
exim-test-orig/AutoTest/confs 002
exim-test-orig/AutoTest/stdout 001 002
Added files:
exim-test-orig/AutoTest/confs 905
exim-test-orig/AutoTest/scripts 905
exim-test-orig/AutoTest/src loaded.c
exim-test-orig/AutoTest/stderr 905
exim-test-orig/AutoTest/stdout 905
Log:
1. Added Tony F's ${dlfunc expansion, slightly modified (see NewStuff).
2. Recognize ${perl even if not compiled, and give suitable error
message.
Revision Changes Path
1.94 +50 -44 exim/exim-doc/doc-txt/ChangeLog
1.28 +65 -25 exim/exim-doc/doc-txt/NewStuff
1.16 +11 -10 exim/exim-src/ACKNOWLEDGMENTS
1.9 +9 -0 exim/exim-src/src/EDITME
1.6 +1 -2 exim/exim-src/src/config.h.defaults
1.17 +3 -0 exim/exim-src/src/exim.c
1.10 +3 -3 exim/exim-src/src/exim.h
1.17 +110 -7 exim/exim-src/src/expand.c
1.20 +4 -0 exim/exim-src/src/globals.c
1.13 +4 -0 exim/exim-src/src/globals.h
1.4 +18 -2 exim/exim-src/src/local_scan.h
1.11 +22 -19 exim/exim-src/src/macros.h
1.7 +4 -0 exim/exim-src/src/routers/redirect.c
1.5 +1 -0 exim/exim-test-orig/AutoTest/confs/002
1.1 +18 -0 exim/exim-test-orig/AutoTest/confs/905 (new)
1.1 +7 -0 exim/exim-test-orig/AutoTest/scripts/905 (new)
1.1 +25 -0 exim/exim-test-orig/AutoTest/src/loaded.c (new)
1.1 +1 -0 exim/exim-test-orig/AutoTest/stderr/905 (new)
1.7 +2 -0 exim/exim-test-orig/AutoTest/stdout/001
1.5 +4 -0 exim/exim-test-orig/AutoTest/stdout/002
1.1 +5 -0 exim/exim-test-orig/AutoTest/stdout/905 (new)
Index: ChangeLog
===================================================================
RCS file: /home/cvs/exim/exim-doc/doc-txt/ChangeLog,v
retrieving revision 1.93
retrieving revision 1.94
diff -u -r1.93 -r1.94
--- ChangeLog 22 Mar 2005 10:11:42 -0000 1.93
+++ ChangeLog 22 Mar 2005 14:11:54 -0000 1.94
@@ -1,4 +1,4 @@
-$Cambridge: exim/exim-doc/doc-txt/ChangeLog,v 1.93 2005/03/22 10:11:42 ph10 Exp $
+$Cambridge: exim/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 @@
Exim version 4.51
-----------------
-TK/01. Added Yahoo DomainKeys support via libdomainkeys. See
- doc/experimental-spec.txt for details. (http://domainkeys.sf.net)
+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/02 Fix ACL "control" statment not being available in MIME ACL.
-TK/03. Fix ACL "regex" condition 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/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
Index: NewStuff
===================================================================
RCS file: /home/cvs/exim/exim-doc/doc-txt/NewStuff,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- NewStuff 8 Mar 2005 11:38:21 -0000 1.27
+++ NewStuff 22 Mar 2005 14:11:54 -0000 1.28
@@ -1,4 +1,4 @@
-$Cambridge: exim/exim-doc/doc-txt/NewStuff,v 1.27 2005/03/08 11:38:21 ph10 Exp $
+$Cambridge: exim/exim-doc/doc-txt/NewStuff,v 1.28 2005/03/22 14:11:54 ph10 Exp $
New Features in Exim
--------------------
@@ -12,32 +12,72 @@
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
+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.
- If Exim never has to generate the parameters itself, the possibility of
- stalling is removed.
+ 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
Index: ACKNOWLEDGMENTS
===================================================================
RCS file: /home/cvs/exim/exim-src/ACKNOWLEDGMENTS,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- ACKNOWLEDGMENTS 15 Mar 2005 12:27:54 -0000 1.15
+++ ACKNOWLEDGMENTS 22 Mar 2005 14:11:54 -0000 1.16
@@ -1,4 +1,4 @@
-$Cambridge: exim/exim-src/ACKNOWLEDGMENTS,v 1.15 2005/03/15 12:27:54 ph10 Exp $
+$Cambridge: exim/exim-src/ACKNOWLEDGMENTS,v 1.16 2005/03/22 14:11:54 ph10 Exp $
EXIM ACKNOWLEDGEMENTS
@@ -20,7 +20,7 @@
Philip Hazel
Lists created: 20 November 2002
-Last updated: 15 March 2005
+Last updated: 22 March 2005
THE OLD LIST
@@ -78,7 +78,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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
Index: EDITME
===================================================================
RCS file: /home/cvs/exim/exim-src/src/EDITME,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- EDITME 17 Feb 2005 11:58:25 -0000 1.8
+++ EDITME 22 Mar 2005 14:11:54 -0000 1.9
@@ -1,4 +1,4 @@
-# $Cambridge: exim/exim-src/src/EDITME,v 1.8 2005/02/17 11:58:25 ph10 Exp $
+# $Cambridge: exim/exim-src/src/EDITME,v 1.9 2005/03/22 14:11:54 ph10 Exp $
##################################################
# The Exim mail transport agent #
@@ -687,6 +687,15 @@
# Perl costs quite a lot of resources. Only do this if you really need it.
# 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
#------------------------------------------------------------------------------
Index: config.h.defaults
===================================================================
RCS file: /home/cvs/exim/exim-src/src/config.h.defaults,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- config.h.defaults 8 Mar 2005 15:32:02 -0000 1.5
+++ config.h.defaults 22 Mar 2005 14:11:54 -0000 1.6
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/config.h.defaults,v 1.5 2005/03/08 15:32:02 tom Exp $ */
+/* $Cambridge: exim/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 @@
#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"
Index: exim.c
===================================================================
RCS file: /home/cvs/exim/exim-src/src/exim.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- exim.c 15 Mar 2005 14:09:12 -0000 1.16
+++ exim.c 22 Mar 2005 14:11:54 -0000 1.17
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/exim.c,v 1.16 2005/03/15 14:09:12 ph10 Exp $ */
+/* $Cambridge: exim/exim-src/src/exim.c,v 1.17 2005/03/22 14:11:54 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -828,6 +828,9 @@
#endif
#ifdef EXIM_PERL
fprintf(f, " Perl");
+#endif
+#ifdef EXPAND_DLFUNC
+ fprintf(f, " Expand_dlfunc");
#endif
#ifdef USE_TCP_WRAPPERS
fprintf(f, " TCPwrappers");
Index: exim.h
===================================================================
RCS file: /home/cvs/exim/exim-src/src/exim.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- exim.h 15 Mar 2005 14:09:12 -0000 1.9
+++ exim.h 22 Mar 2005 14:11:54 -0000 1.10
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/exim.h,v 1.9 2005/03/15 14:09:12 ph10 Exp $ */
+/* $Cambridge: exim/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 @@
/* 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 @@
#endif
-#ifndef SIOCGIFCONF /* HACK for SunOS 5 */
+#ifndef SIOCGIFCONF /* HACK for SunOS 5 */
#include <sys/sockio.h>
#endif
@@ -414,7 +414,7 @@
#include <iconv.h>
#endif
-#ifdef USE_READLINE
+#if defined(USE_READLINE) || defined(EXPAND_DLFUNC)
#include <dlfcn.h>
#endif
Index: expand.c
===================================================================
RCS file: /home/cvs/exim/exim-src/src/expand.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- expand.c 9 Mar 2005 08:27:51 -0000 1.16
+++ expand.c 22 Mar 2005 14:11:54 -0000 1.17
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/expand.c,v 1.16 2005/03/09 08:27:51 tom Exp $ */
+/* $Cambridge: exim/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 @@
alphabetical order. */
static uschar *item_table[] = {
+ US"dlfunc",
US"extract",
US"hash",
US"hmac",
@@ -55,9 +56,7 @@
US"length",
US"lookup",
US"nhash",
- #ifdef EXIM_PERL
- US"perl",
- #endif
+ US"perl",
US"readfile",
US"readsocket",
US"run",
@@ -66,6 +65,7 @@
US"tr" };
enum {
+ EITEM_DLFUNC,
EITEM_EXTRACT,
EITEM_HASH,
EITEM_HMAC,
@@ -73,9 +73,7 @@
EITEM_LENGTH,
EITEM_LOOKUP,
EITEM_NHASH,
- #ifdef EXIM_PERL
- EITEM_PERL,
- #endif
+ EITEM_PERL,
EITEM_READFILE,
EITEM_READSOCK,
EITEM_RUN,
@@ -3072,10 +3070,15 @@
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 @@
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
Index: globals.c
===================================================================
RCS file: /home/cvs/exim/exim-src/src/globals.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- globals.c 8 Mar 2005 15:32:02 -0000 1.19
+++ globals.c 22 Mar 2005 14:11:54 -0000 1.20
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/globals.c,v 1.19 2005/03/08 15:32:02 tom Exp $ */
+/* $Cambridge: exim/exim-src/src/globals.c,v 1.20 2005/03/22 14:11:54 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -60,6 +60,10 @@
uschar *opt_perl_startup = NULL;
BOOL opt_perl_at_start = FALSE;
BOOL opt_perl_started = FALSE;
+#endif
+
+#ifdef EXPAND_DLFUNC
+tree_node *dlobj_anchor = NULL;
#endif
#ifdef LOOKUP_IBASE
Index: globals.h
===================================================================
RCS file: /home/cvs/exim/exim-src/src/globals.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- globals.h 8 Mar 2005 15:32:02 -0000 1.12
+++ globals.h 22 Mar 2005 14:11:54 -0000 1.13
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/globals.h,v 1.12 2005/03/08 15:32:02 tom Exp $ */
+/* $Cambridge: exim/exim-src/src/globals.h,v 1.13 2005/03/22 14:11:54 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -24,6 +24,10 @@
extern uschar *opt_perl_startup; /* Startup code for Perl interpreter */
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
Index: local_scan.h
===================================================================
RCS file: /home/cvs/exim/exim-src/src/local_scan.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- local_scan.h 4 Jan 2005 10:00:42 -0000 1.3
+++ local_scan.h 22 Mar 2005 14:11:54 -0000 1.4
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/local_scan.h,v 1.3 2005/01/04 10:00:42 ph10 Exp $ */
+/* $Cambridge: exim/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,12 +36,26 @@
};
-/* 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 */
Index: macros.h
===================================================================
RCS file: /home/cvs/exim/exim-src/src/macros.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- macros.h 10 Mar 2005 08:56:03 -0000 1.10
+++ macros.h 22 Mar 2005 14:11:54 -0000 1.11
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/macros.h,v 1.10 2005/03/10 08:56:03 tom Exp $ */
+/* $Cambridge: exim/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 @@
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 @@
#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 @@
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;
Index: redirect.c
===================================================================
RCS file: /home/cvs/exim/exim-src/src/routers/redirect.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- redirect.c 15 Mar 2005 11:37:21 -0000 1.6
+++ redirect.c 22 Mar 2005 14:11:55 -0000 1.7
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/routers/redirect.c,v 1.6 2005/03/15 11:37:21 ph10 Exp $ */
+/* $Cambridge: exim/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 @@
(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),
Index: 905
====================================================================
# Exim test configuration 905
# Macros are set externally in order to get the path
# of the Exim that is being tested, and the directory
# in which the test data lives.
exim_path = EXIM_PATH
primary_hostname = myhost.test.ex
qualify_domain = test.ex
spool_directory = DIR/spool
# ----- Main settings -----
# ----- ACLs -----
# End of Exim 4 configuration
Index: 002
===================================================================
RCS file: /home/cvs/exim/exim-test-orig/AutoTest/confs/002,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- 002 4 Jan 2005 16:36:28 -0000 1.4
+++ 002 22 Mar 2005 14:11:55 -0000 1.5
@@ -505,6 +505,7 @@
forbid_blackhole
forbid_filter_existstest
no_forbid_filter_logwrite
+ forbid_filter_dlfunc
forbid_filter_lookup
forbid_filter_readfile
forbid_filter_readsocket
Index: 905
====================================================================
0 dlfunc expansion
exim -be
${dlfunc{/source/exim4/AutoTest/loaded}{dltest}}
${dlfunc{/source/exim4/AutoTest/loaded}{dltest}{one argument}}
${dlfunc{/source/exim4/AutoTest/loaded}{dltest}{1}{2}}
${dlfunc{/source/exim4/AutoTest/loaded}{dltest}{1}{2}{3}}
****
Index: loaded.c
====================================================================
/* This is a test function for dynamic loading in Exim expansions. It uses the
number of arguments to control the result. */
#include "local_scan.h"
int dltest(unsigned char **yield, int argc, unsigned char *argv[])
{
switch (argc)
{
case 0:
return ERROR;
case 1:
*yield = argv[0];
return OK;
case 2:
*yield = (unsigned char *)"yield FAIL_FORCED";
return FAIL_FORCED;
default:
*yield = (unsigned char *)"yield FAIL";
return FAIL;
}
}
Index: 905
====================================================================
1999-03-02 09:44:33 dlfunc{/source/exim4/AutoTest/loaded}{dltest} failed (3): (no message)
Index: 905
====================================================================
> Failed: (no message)
> one argument
> Failed: yield FAIL_FORCED
> Failed: yield FAIL
>
Index: 001
===================================================================
RCS file: /home/cvs/exim/exim-test-orig/AutoTest/stdout/001,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- 001 16 Feb 2005 16:28:37 -0000 1.6
+++ 001 22 Mar 2005 14:11:55 -0000 1.7
@@ -466,6 +466,7 @@
no_forbid_blackhole
no_forbid_exim_filter
no_forbid_file
+no_forbid_filter_dlfunc
no_forbid_filter_existstest
no_forbid_filter_logwrite
no_forbid_filter_lookup
@@ -555,6 +556,7 @@
no_forbid_blackhole
no_forbid_exim_filter
no_forbid_file
+no_forbid_filter_dlfunc
no_forbid_filter_existstest
no_forbid_filter_logwrite
no_forbid_filter_lookup
Index: 002
===================================================================
RCS file: /home/cvs/exim/exim-test-orig/AutoTest/stdout/002,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- 002 4 Jan 2005 16:36:28 -0000 1.4
+++ 002 22 Mar 2005 14:11:55 -0000 1.5
@@ -471,6 +471,7 @@
forbid_blackhole
no_forbid_exim_filter
no_forbid_file
+no_forbid_filter_dlfunc
no_forbid_filter_existstest
no_forbid_filter_logwrite
no_forbid_filter_lookup
@@ -560,6 +561,7 @@
no_forbid_blackhole
no_forbid_exim_filter
no_forbid_file
+no_forbid_filter_dlfunc
no_forbid_filter_existstest
no_forbid_filter_logwrite
no_forbid_filter_lookup
@@ -649,6 +651,7 @@
forbid_blackhole
forbid_exim_filter
no_forbid_file
+forbid_filter_dlfunc
forbid_filter_existstest
no_forbid_filter_logwrite
forbid_filter_lookup
@@ -784,6 +787,7 @@
no_forbid_blackhole
no_forbid_exim_filter
forbid_file
+no_forbid_filter_dlfunc
no_forbid_filter_existstest
no_forbid_filter_logwrite
no_forbid_filter_lookup