summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/doc-txt/ChangeLog5
-rw-r--r--src/OS/Makefile-Base27
-rwxr-xr-xsrc/scripts/MakeLinks3
-rw-r--r--src/src/auths/cram_md5.c14
-rw-r--r--src/src/auths/cyrus_sasl.c14
-rw-r--r--src/src/auths/dovecot.c16
-rw-r--r--src/src/auths/gsasl_exim.c14
-rw-r--r--src/src/auths/heimdal_gssapi.c14
-rw-r--r--src/src/auths/plaintext.c13
-rw-r--r--src/src/auths/spa.c14
-rw-r--r--src/src/auths/tls.c14
-rw-r--r--src/src/drtables.c4
-rw-r--r--src/src/exim.c2
-rw-r--r--src/src/functions.h4
-rw-r--r--src/src/globals.c5
-rw-r--r--src/src/globals.h1
-rw-r--r--src/src/macro_predef.c276
-rw-r--r--src/src/macro_predef.h17
-rw-r--r--src/src/readconf.c569
-rw-r--r--src/src/route.c17
-rw-r--r--src/src/routers/accept.c13
-rw-r--r--src/src/routers/dnslookup.c17
-rw-r--r--src/src/routers/ipliteral.c12
-rw-r--r--src/src/routers/iplookup.c15
-rw-r--r--src/src/routers/manualroute.c16
-rw-r--r--src/src/routers/queryprogram.c15
-rw-r--r--src/src/routers/redirect.c16
-rw-r--r--src/src/transport.c54
-rw-r--r--src/src/transports/appendfile.c43
-rw-r--r--src/src/transports/autoreply.c12
-rw-r--r--src/src/transports/lmtp.c12
-rw-r--r--src/src/transports/pipe.c12
-rw-r--r--src/src/transports/queuefile.c15
-rw-r--r--src/src/transports/smtp.c13
34 files changed, 855 insertions, 453 deletions
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 7544e35a4..da6f19820 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -118,6 +118,11 @@ HS/01 Cleanup, prevent repeated use of -p/-oMr (CVE-2017-1000369)
JH/17 Change the list-building routines interface to use the expanding-string
triplet model, for better allocation and copying behaviour.
+JH/18 Prebuild the data-structure for "builtin" macros, for faster startup.
+ Previously it was constructed the first time a possibly-matching string
+ was met in the configuration file input during startup; now it is done
+ during compilation.
+
Exim version 4.89
-----------------
diff --git a/src/OS/Makefile-Base b/src/OS/Makefile-Base
index 3b7246109..bddd313ee 100644
--- a/src/OS/Makefile-Base
+++ b/src/OS/Makefile-Base
@@ -36,7 +36,7 @@ FE = $(FULLECHO)
# are set up, and finally it goes to the main Exim target.
all: utils exim
-config: $(EDITME) checklocalmake Makefile os.c config.h version.h
+config: $(EDITME) checklocalmake Makefile os.c config.h version.h macro.c
checklocalmake:
@if $(SHELL) $(SCRIPTS)/newer $(EDITME)-$(OSTYPE) $(EDITME) || \
@@ -109,6 +109,29 @@ os.c: ../src/os.c \
config.h: Makefile buildconfig ../src/config.h.defaults $(EDITME)
$(SHELL) $(SCRIPTS)/Configure-config.h "$(MAKE)"
+# Build the builtin-macros data struct
+
+MACRO_CSRC = macro_predef.c globals.c readconf.c route.c transport.c \
+ drtables.c \
+ transports/appendfile.c transports/autoreply.c transports/lmtp.c \
+ transports/pipe.c transports/queuefile.c transports/smtp.c \
+ routers/accept.c routers/dnslookup.c routers/ipliteral.c \
+ routers/iplookup.c routers/manualroute.c routers/queryprogram.c \
+ routers/redirect.c \
+ auths/auth-spa.c auths/cram_md5.c auths/cyrus_sasl.c auths/dovecot.c \
+ auths/gsasl_exim.c auths/heimdal_gssapi.c auths/plaintext.c auths/spa.c \
+ auths/tls.c
+MACRO_HSRC = macro_predef.h os.h globals.h config.h \
+ routers/accept.h routers/dnslookup.h routers/ipliteral.h \
+ routers/iplookup.h routers/manualroute.h routers/queryprogram.h \
+ routers/redirect.h
+
+macro_predef: $(MACRO_CSRC) $(MACRO_HSRC)
+ @echo "$(CC) -DMACRO_PREDEF macro_predef.c"
+ $(FE)$(CC) $(CFLAGS) -DMACRO_PREDEF -o macro_predef $(MACRO_CSRC)
+
+macro.c: macro_predef
+ ./macro_predef > macro.c
# This target is recognized specially by GNU make. It records those targets
# that do not correspond to files that are being built and which should
@@ -337,7 +360,7 @@ OBJ_EXIM = acl.o base64.o child.o crypt16.o daemon.o dbfn.o debug.o deliver.o \
rda.o readconf.o receive.o retry.o rewrite.o rfc2047.o \
route.o search.o sieve.o smtp_in.o smtp_out.o spool_in.o spool_out.o \
std-crypto.o store.o string.o tls.o tod.o transport.o tree.o verify.o \
- environment.o \
+ environment.o macro.o \
$(OBJ_LOOKUPS) \
local_scan.o $(EXIM_PERL) $(OBJ_WITH_CONTENT_SCAN) \
$(OBJ_EXPERIMENTAL)
diff --git a/src/scripts/MakeLinks b/src/scripts/MakeLinks
index d361487cf..44e3a4ebc 100755
--- a/src/scripts/MakeLinks
+++ b/src/scripts/MakeLinks
@@ -109,7 +109,8 @@ for f in blob.h dbfunctions.h dbstuff.h exim.h functions.h globals.h \
string.c tls.c tlscert-gnu.c tlscert-openssl.c tls-gnu.c tls-openssl.c \
tod.c transport.c tree.c verify.c version.c \
dkim.c dkim.h dkim_transport.c dmarc.c dmarc.h \
- valgrind.h memcheck.h
+ valgrind.h memcheck.h \
+ macro_predef.c macro_predef.h
do
ln -s ../src/$f $f
done
diff --git a/src/src/auths/cram_md5.c b/src/src/auths/cram_md5.c
index 9c89cb23c..95f7cc543 100644
--- a/src/src/auths/cram_md5.c
+++ b/src/src/auths/cram_md5.c
@@ -47,6 +47,17 @@ auth_cram_md5_options_block auth_cram_md5_option_defaults = {
};
+#ifdef MACRO_PREDEF
+
+/* Dummy values */
+void auth_cram_md5_init(auth_instance *ablock) {}
+int auth_cram_md5_server(auth_instance *ablock, uschar *data) {return 0;}
+int auth_cram_md5_client(auth_instance *ablock, smtp_inblock *inblock,
+ smtp_outblock *outblock, int timeout, uschar *buffer, int buffsize) {return 0;}
+
+#else /*!MACRO_PREDEF*/
+
+
/*************************************************
* Initialization entry point *
*************************************************/
@@ -68,10 +79,12 @@ if (ob->client_secret != NULL)
}
}
+#endif /*!MACRO_PREDEF*/
#endif /* STAND_ALONE */
+#ifndef MACRO_PREDEF
/*************************************************
* Perform the CRAM-MD5 algorithm *
*************************************************/
@@ -348,4 +361,5 @@ return 0;
#endif
+#endif /*!MACRO_PREDEF*/
/* End of cram_md5.c */
diff --git a/src/src/auths/cyrus_sasl.c b/src/src/auths/cyrus_sasl.c
index bab2be36c..5b9b594af 100644
--- a/src/src/auths/cyrus_sasl.c
+++ b/src/src/auths/cyrus_sasl.c
@@ -63,6 +63,19 @@ auth_cyrus_sasl_options_block auth_cyrus_sasl_option_defaults = {
};
+#ifdef MACRO_PREDEF
+
+/* Dummy values */
+void auth_cyrus_sasl_init(auth_instance *ablock) {}
+int auth_cyrus_sasl_server(auth_instance *ablock, uschar *data) {return 0;}
+int auth_cyrus_sasl_client(auth_instance *ablock, smtp_inblock *inblock,
+ smtp_outblock *outblock, int timeout, uschar *buffer, int buffsize) {return 0;}
+
+#else /*!MACRO_PREDEF*/
+
+
+
+
/*************************************************
* Initialization entry point *
*************************************************/
@@ -525,6 +538,7 @@ auth_cyrus_sasl_client(
return FAIL;
}
+#endif /*!MACRO_PREDEF*/
#endif /* AUTH_CYRUS_SASL */
/* End of cyrus_sasl.c */
diff --git a/src/src/auths/dovecot.c b/src/src/auths/dovecot.c
index 5bf7b9cc3..6378c1642 100644
--- a/src/src/auths/dovecot.c
+++ b/src/src/auths/dovecot.c
@@ -71,6 +71,19 @@ auth_dovecot_options_block auth_dovecot_option_defaults = {
};
+
+
+#ifdef MACRO_PREDEF
+
+/* Dummy values */
+void auth_dovecot_init(auth_instance *ablock) {}
+int auth_dovecot_server(auth_instance *ablock, uschar *data) {return 0;}
+int auth_dovecot_client(auth_instance *ablock, smtp_inblock *inblock,
+ smtp_outblock *outblock, int timeout, uschar *buffer, int buffsize) {return 0;}
+
+#else /*!MACRO_PREDEF*/
+
+
/* Static variables for reading from the socket */
static uschar sbuffer[256];
@@ -495,3 +508,6 @@ if (fd >= 0)
/* Expand server_condition as an authorization check */
return ret == OK ? auth_check_serv_cond(ablock) : ret;
}
+
+
+#endif /*!MACRO_PREDEF*/
diff --git a/src/src/auths/gsasl_exim.c b/src/src/auths/gsasl_exim.c
index 77db2e775..6326eaa02 100644
--- a/src/src/auths/gsasl_exim.c
+++ b/src/src/auths/gsasl_exim.c
@@ -78,6 +78,19 @@ auth_gsasl_options_block auth_gsasl_option_defaults = {
FALSE /* server_channelbinding */
};
+
+#ifdef MACRO_PREDEF
+
+/* Dummy values */
+void auth_gsasl_init(auth_instance *ablock) {}
+int auth_gsasl_server(auth_instance *ablock, uschar *data) {return 0;}
+int auth_gsasl_client(auth_instance *ablock, smtp_inblock *inblock,
+ smtp_outblock *outblock, int timeout, uschar *buffer, int buffsize) {return 0;}
+
+#else /*!MACRO_PREDEF*/
+
+
+
/* "Globals" for managing the gsasl interface. */
static Gsasl *gsasl_ctx = NULL;
@@ -614,6 +627,7 @@ auth_gsasl_version_report(FILE *f)
GSASL_VERSION, runtime);
}
+#endif /*!MACRO_PREDEF*/
#endif /* AUTH_GSASL */
/* End of gsasl_exim.c */
diff --git a/src/src/auths/heimdal_gssapi.c b/src/src/auths/heimdal_gssapi.c
index 732a67381..c840be227 100644
--- a/src/src/auths/heimdal_gssapi.c
+++ b/src/src/auths/heimdal_gssapi.c
@@ -76,6 +76,19 @@ auth_heimdal_gssapi_options_block auth_heimdal_gssapi_option_defaults = {
US"smtp", /* server_service */
};
+
+#ifdef MACRO_PREDEF
+
+/* Dummy values */
+void auth_heimdal_init(auth_instance *ablock) {}
+int auth_heimdal_server(auth_instance *ablock, uschar *data) {return 0;}
+int auth_heimdal_client(auth_instance *ablock, smtp_inblock *inblock,
+ smtp_outblock *outblock, int timeout, uschar *buffer, int buffsize) {return 0;}
+
+#else /*!MACRO_PREDEF*/
+
+
+
/* "Globals" for managing the heimdal_gssapi interface. */
/* Utility functions */
@@ -590,6 +603,7 @@ auth_heimdal_gssapi_version_report(FILE *f)
heimdal_version, heimdal_long_version);
}
+#endif /*!MACRO_PREDEF*/
#endif /* AUTH_HEIMDAL_GSSAPI */
/* End of heimdal_gssapi.c */
diff --git a/src/src/auths/plaintext.c b/src/src/auths/plaintext.c
index 32f8fd575..8bba05823 100644
--- a/src/src/auths/plaintext.c
+++ b/src/src/auths/plaintext.c
@@ -35,6 +35,18 @@ auth_plaintext_options_block auth_plaintext_option_defaults = {
};
+#ifdef MACRO_PREDEF
+
+/* Dummy values */
+void auth_plaintext_init(auth_instance *ablock) {}
+int auth_plaintext_server(auth_instance *ablock, uschar *data) {return 0;}
+int auth_plaintext_client(auth_instance *ablock, smtp_inblock *inblock,
+ smtp_outblock *outblock, int timeout, uschar *buffer, int buffsize) {return 0;}
+
+#else /*!MACRO_PREDEF*/
+
+
+
/*************************************************
* Initialization entry point *
*************************************************/
@@ -294,4 +306,5 @@ while ((s = string_nextinlist(&text, &sep, big_buffer, big_buffer_size)))
return FAIL;
}
+#endif /*!MACRO_PREDEF*/
/* End of plaintext.c */
diff --git a/src/src/auths/spa.c b/src/src/auths/spa.c
index 378d4f602..439086f1c 100644
--- a/src/src/auths/spa.c
+++ b/src/src/auths/spa.c
@@ -71,6 +71,19 @@ auth_spa_options_block auth_spa_option_defaults = {
};
+#ifdef MACRO_PREDEF
+
+/* Dummy values */
+void auth_spa_init(auth_instance *ablock) {}
+int auth_spa_server(auth_instance *ablock, uschar *data) {return 0;}
+int auth_spa_client(auth_instance *ablock, smtp_inblock *inblock,
+ smtp_outblock *outblock, int timeout, uschar *buffer, int buffsize) {return 0;}
+
+#else /*!MACRO_PREDEF*/
+
+
+
+
/*************************************************
* Initialization entry point *
*************************************************/
@@ -360,4 +373,5 @@ if (errno != 0 || buffer[0] != '3')
return FAIL;
}
+#endif /*!MACRO_PREDEF*/
/* End of spa.c */
diff --git a/src/src/auths/tls.c b/src/src/auths/tls.c
index 99c756374..bdcae3194 100644
--- a/src/src/auths/tls.c
+++ b/src/src/auths/tls.c
@@ -40,6 +40,19 @@ auth_tls_options_block auth_tls_option_defaults = {
};
+#ifdef MACRO_PREDEF
+
+/* Dummy values */
+void auth_tls_init(auth_instance *ablock) {}
+int auth_tls_server(auth_instance *ablock, uschar *data) {return 0;}
+int auth_tls_client(auth_instance *ablock, smtp_inblock *inblock,
+ smtp_outblock *outblock, int timeout, uschar *buffer, int buffsize) {return 0;}
+
+#else /*!MACRO_PREDEF*/
+
+
+
+
/*************************************************
* Initialization entry point *
*************************************************/
@@ -77,4 +90,5 @@ return auth_check_serv_cond(ablock);
}
+#endif /*!MACRO_PREDEF*/
/* End of tls.c */
diff --git a/src/src/drtables.c b/src/src/drtables.c
index 3e1c5e626..629953e58 100644
--- a/src/src/drtables.c
+++ b/src/src/drtables.c
@@ -424,6 +424,9 @@ transport_info transports_available[] = {
{ US"", NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, FALSE }
};
+
+#ifndef MACRO_PREDEF
+
struct lookupmodulestr
{
void *dl;
@@ -721,4 +724,5 @@ init_lookup_list(void)
lookupmodules = NULL;
}
+#endif /*!MACRO_PREDEF*/
/* End of drtables.c */
diff --git a/src/src/exim.c b/src/src/exim.c
index e816fd9c6..42cb710eb 100644
--- a/src/src/exim.c
+++ b/src/src/exim.c
@@ -2457,7 +2457,7 @@ for (i = 1; i < argc; i++)
exit(EXIT_FAILURE);
}
- m = macro_create(string_copy(name), string_copy(s), TRUE, FALSE);
+ m = macro_create(string_copy(name), string_copy(s), TRUE);
if (clmacro_count >= MAX_CLMACROS)
{
diff --git a/src/src/functions.h b/src/src/functions.h
index 41e3ec163..f7173576b 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -255,7 +255,7 @@ extern int log_create(uschar *);
extern int log_create_as_exim(uschar *);
extern void log_close_all(void);
-extern macro_item * macro_create(const uschar *, const uschar *, BOOL, BOOL);
+extern macro_item * macro_create(const uschar *, const uschar *, BOOL);
extern void mainlog_close(void);
#ifdef WITH_CONTENT_SCAN
extern int malware(const uschar *, int);
@@ -329,8 +329,6 @@ extern void readconf_driver_init(uschar *, driver_instance **,
extern uschar *readconf_find_option(void *);
extern void readconf_main(BOOL);
extern void readconf_options_from_list(optionlist *, unsigned, const uschar *, uschar *);
-extern void readconf_options_routers(void);
-extern void readconf_options_transports(void);
extern void readconf_print(uschar *, uschar *, BOOL);
extern uschar *readconf_printtime(int);
extern uschar *readconf_readname(uschar *, int, uschar *);
diff --git a/src/src/globals.c b/src/src/globals.c
index 9b455c9db..bfb1c2166 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -182,7 +182,7 @@ const pcre *regex_UTF8 = NULL;
incoming TCP/IP. The defaults use stdin. We never need these for any
stand-alone tests. */
-#ifndef STAND_ALONE
+#if !defined(STAND_ALONE) && !defined(MACRO_PREDEF)
int (*lwr_receive_getc)(unsigned) = stdin_getc;
uschar * (*lwr_receive_getbuf)(unsigned *) = NULL;
int (*lwr_receive_ungetc)(int) = stdin_ungetc;
@@ -939,9 +939,6 @@ uschar *lookup_dnssec_authenticated = NULL;
int lookup_open_max = 25;
uschar *lookup_value = NULL;
-macro_item *macros = NULL;
-macro_item *mlast = NULL;
-BOOL macros_builtin_created = FALSE;
uschar *mailstore_basename = NULL;
#ifdef WITH_CONTENT_SCAN
uschar *malware_name = NULL; /* Virus Name */
diff --git a/src/src/globals.h b/src/src/globals.h
index 056f1c213..4a54c3c73 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -565,7 +565,6 @@ extern uschar *lookup_value; /* Value looked up from file */
extern macro_item *macros; /* Configuration macros */
extern macro_item *mlast; /* Last item in macro list */
-extern BOOL macros_builtin_created; /* Flag for lazy-create */
extern uschar *mailstore_basename; /* For mailstore deliveries */
#ifdef WITH_CONTENT_SCAN
extern uschar *malware_name; /* Name of virus or malware ("W32/Klez-H") */
diff --git a/src/src/macro_predef.c b/src/src/macro_predef.c
new file mode 100644
index 000000000..e133b8e1b
--- /dev/null
+++ b/src/src/macro_predef.c
@@ -0,0 +1,276 @@
+/*************************************************
+* Exim - an Internet mail transport agent *
+*************************************************/
+
+/* Copyright (c) Jeremy Harris 2017 */
+/* See the file NOTICE for conditions of use and distribution. */
+
+/* Create a static data structure with the predefined macros, to be
+included in the main Exim build */
+
+#include "exim.h"
+#include "macro_predef.h"
+
+unsigned mp_index = 0;
+
+/* Global dummy variables */
+
+void fn_smtp_receive_timeout(const uschar * name, const uschar * str) {}
+uschar * syslog_facility_str;
+
+/******************************************************************************/
+
+void
+builtin_macro_create(const uschar * name)
+{
+printf ("static macro_item p%d = { ", mp_index);
+if (mp_index == 0)
+ printf("NULL,");
+else
+ printf("&p%d,", mp_index-1);
+
+printf(" FALSE, %d, \"%s\", \"y\" };\n", Ustrlen(name), name);
+mp_index++;
+}
+
+static void
+spf(uschar * buf, int len, const uschar * fmt, ...)
+{
+va_list ap;
+va_start(ap, fmt);
+
+while (*fmt && len > 1)
+ if (*fmt == '%' && fmt[1] == 'T')
+ {
+ uschar * s = va_arg(ap, uschar *);
+ while (*s && len-- > 1)
+ *buf++ = toupper(*s++);
+ fmt += 2;
+ }
+ else
+ {
+ *buf++ = *fmt++; len--;
+ }
+*buf = '\0';
+va_end(ap);
+}
+
+void
+options_from_list(optionlist * opts, unsigned nopt,
+ const uschar * section, uschar * group)
+{
+int i;
+const uschar * s;
+uschar buf[64];
+
+/* The 'previously-defined-substring' rule for macros in config file
+lines is done thus for these builtin macros: we know that the table
+we source from is in strict alpha order, hence the builtins portion
+of the macros list is in reverse-alpha (we prepend them) - so longer
+macros that have substrings are always discovered first during
+expansion. */
+
+for (i = 0; i < nopt; i++) if (*(s = US opts[i].name) && *s != '*')
+ {
+ if (group)
+ spf(buf, sizeof(buf), "_OPT_%T_%T_%T", section, group, s);
+ else
+ spf(buf, sizeof(buf), "_OPT_%T_%T", section, s);
+ builtin_macro_create(buf);
+ }
+}
+
+
+/******************************************************************************/
+
+
+/* Create compile-time feature macros */
+static void
+features(void)
+{
+/* Probably we could work out a static initialiser for wherever
+macros are stored, but this will do for now. Some names are awkward
+due to conflicts with other common macros. */
+
+#ifdef SUPPORT_CRYPTEQ
+ builtin_macro_create(US"_HAVE_CRYPTEQ");
+#endif
+#if HAVE_ICONV
+ builtin_macro_create(US"_HAVE_ICONV");
+#endif
+#if HAVE_IPV6
+ builtin_macro_create(US"_HAVE_IPV6");
+#endif
+#ifdef HAVE_SETCLASSRESOURCES
+ builtin_macro_create(US"_HAVE_SETCLASSRESOURCES");
+#endif
+#ifdef SUPPORT_PAM
+ builtin_macro_create(US"_HAVE_PAM");
+#endif
+#ifdef EXIM_PERL
+ builtin_macro_create(US"_HAVE_PERL");
+#endif
+#ifdef EXPAND_DLFUNC
+ builtin_macro_create(US"_HAVE_DLFUNC");
+#endif
+#ifdef USE_TCP_WRAPPERS
+ builtin_macro_create(US"_HAVE_TCPWRAPPERS");
+#endif
+#ifdef SUPPORT_TLS
+ builtin_macro_create(US"_HAVE_TLS");
+# ifdef USE_GNUTLS
+ builtin_macro_create(US"_HAVE_GNUTLS");
+# else
+ builtin_macro_create(US"_HAVE_OPENSSL");
+# endif
+#endif
+#ifdef SUPPORT_TRANSLATE_IP_ADDRESS
+ builtin_macro_create(US"_HAVE_TRANSLATE_IP_ADDRESS");
+#endif
+#ifdef SUPPORT_MOVE_FROZEN_MESSAGES
+ builtin_macro_create(US"_HAVE_MOVE_FROZEN_MESSAGES");
+#endif
+#ifdef WITH_CONTENT_SCAN
+ builtin_macro_create(US"_HAVE_CONTENT_SCANNING");
+#endif
+#ifndef DISABLE_DKIM
+ builtin_macro_create(US"_HAVE_DKIM");
+#endif
+#ifndef DISABLE_DNSSEC
+ builtin_macro_create(US"_HAVE_DNSSEC");
+#endif
+#ifndef DISABLE_EVENT
+ builtin_macro_create(US"_HAVE_EVENT");
+#endif
+#ifdef SUPPORT_I18N
+ builtin_macro_create(US"_HAVE_I18N");
+#endif
+#ifndef DISABLE_OCSP
+ builtin_macro_create(US"_HAVE_OCSP");
+#endif
+#ifndef DISABLE_PRDR
+ builtin_macro_create(US"_HAVE_PRDR");
+#endif
+#ifdef SUPPORT_PROXY
+ builtin_macro_create(US"_HAVE_PROXY");
+#endif
+#ifdef SUPPORT_SOCKS
+ builtin_macro_create(US"_HAVE_SOCKS");
+#endif
+#ifdef TCP_FASTOPEN
+ builtin_macro_create(US"_HAVE_TCP_FASTOPEN");
+#endif
+#ifdef EXPERIMENTAL_LMDB
+ builtin_macro_create(US"_HAVE_LMDB");
+#endif
+#ifdef EXPERIMENTAL_SPF
+ builtin_macro_create(US"_HAVE_SPF");
+#endif
+#ifdef EXPERIMENTAL_SRS
+ builtin_macro_create(US"_HAVE_SRS");
+#endif
+#ifdef EXPERIMENTAL_BRIGHTMAIL
+ builtin_macro_create(US"_HAVE_BRIGHTMAIL");
+#endif
+#ifdef EXPERIMENTAL_DANE
+ builtin_macro_create(US"_HAVE_DANE");
+#endif
+#ifdef EXPERIMENTAL_DCC
+ builtin_macro_create(US"_HAVE_DCC");
+#endif
+#ifdef EXPERIMENTAL_DMARC
+ builtin_macro_create(US"_HAVE_DMARC");
+#endif
+#ifdef EXPERIMENTAL_DSN_INFO
+ builtin_macro_create(US"_HAVE_DSN_INFO");
+#endif
+
+#ifdef LOOKUP_LSEARCH
+ builtin_macro_create(US"_HAVE_LOOKUP_LSEARCH");
+#endif
+#ifdef LOOKUP_CDB
+ builtin_macro_create(US"_HAVE_LOOKUP_CDB");
+#endif
+#ifdef LOOKUP_DBM
+ builtin_macro_create(US"_HAVE_LOOKUP_DBM");
+#endif
+#ifdef LOOKUP_DNSDB
+ builtin_macro_create(US"_HAVE_LOOKUP_DNSDB");
+#endif
+#ifdef LOOKUP_DSEARCH
+ builtin_macro_create(US"_HAVE_LOOKUP_DSEARCH");
+#endif
+#ifdef LOOKUP_IBASE
+ builtin_macro_create(US"_HAVE_LOOKUP_IBASE");
+#endif
+#ifdef LOOKUP_LDAP
+ builtin_macro_create(US"_HAVE_LOOKUP_LDAP");
+#endif
+#ifdef EXPERIMENTAL_LMDB
+ builtin_macro_create(US"_HAVE_LOOKUP_LMDB");
+#endif
+#ifdef LOOKUP_MYSQL
+ builtin_macro_create(US"_HAVE_LOOKUP_MYSQL");
+#endif
+#ifdef LOOKUP_NIS
+ builtin_macro_create(US"_HAVE_LOOKUP_NIS");
+#endif
+#ifdef LOOKUP_NISPLUS
+ builtin_macro_create(US"_HAVE_LOOKUP_NISPLUS");
+#endif
+#ifdef LOOKUP_ORACLE
+ builtin_macro_create(US"_HAVE_LOOKUP_ORACLE");
+#endif
+#ifdef LOOKUP_PASSWD
+ builtin_macro_create(US"_HAVE_LOOKUP_PASSWD");
+#endif
+#ifdef LOOKUP_PGSQL
+ builtin_macro_create(US"_HAVE_LOOKUP_PGSQL");
+#endif
+#ifdef LOOKUP_REDIS
+ builtin_macro_create(US"_HAVE_LOOKUP_REDIS");
+#endif
+#ifdef LOOKUP_SQLITE
+ builtin_macro_create(US"_HAVE_LOOKUP_SQLITE");
+#endif
+#ifdef LOOKUP_TESTDB
+ builtin_macro_create(US"_HAVE_LOOKUP_TESTDB");
+#endif
+#ifdef LOOKUP_WHOSON
+ builtin_macro_create(US"_HAVE_LOOKUP_WHOSON");
+#endif
+
+#ifdef TRANSPORT_APPENDFILE
+# ifdef SUPPORT_MAILDIR
+ builtin_macro_create(US"_HAVE_TRANSPORT_APPEND_MAILDIR");
+# endif
+# ifdef SUPPORT_MAILSTORE
+ builtin_macro_create(US"_HAVE_TRANSPORT_APPEND_MAILSTORE");
+# endif
+# ifdef SUPPORT_MBX
+ builtin_macro_create(US"_HAVE_TRANSPORT_APPEND_MBX");
+# endif
+#endif
+}
+
+
+static void
+options(void)
+{
+options_main();
+options_routers();
+options_transports();
+options_auths();
+}
+
+
+int
+main(void)
+{
+printf("#include \"exim.h\"\n");
+features();
+options();
+
+printf("macro_item * macros = &p%d;\n", mp_index-1);
+printf("macro_item * mlast = &p0;\n");
+}
diff --git a/src/src/macro_predef.h b/src/src/macro_predef.h
new file mode 100644
index 000000000..e77f4bec1
--- /dev/null
+++ b/src/src/macro_predef.h
@@ -0,0 +1,17 @@
+/*************************************************
+* Exim - an Internet mail transport agent *
+*************************************************/
+
+/* Copyright (c) Jeremy Harris 2017 */
+/* See the file NOTICE for conditions of use and distribution. */
+
+/* Global functions */
+
+extern void builtin_macro_create(const uschar *);
+extern void options_from_list(optionlist *, unsigned, const uschar *, uschar *);
+
+extern void options_main(void);
+extern void options_routers(void);
+extern void options_transports(void);
+extern void options_auths(void);
+
diff --git a/src/src/readconf.c b/src/src/readconf.c
index e0f9d2ddc..045b992a4 100644
--- a/src/src/readconf.c
+++ b/src/src/readconf.c
@@ -11,136 +11,12 @@ implementation of the conditional .ifdef etc. */
#include "exim.h"
-extern char **environ;
-
-static void fn_smtp_receive_timeout(const uschar * name, const uschar * str);
-static void save_config_line(const uschar* line);
-static void save_config_position(const uschar *file, int line);
-static void print_config(BOOL admin, BOOL terse);
-static void readconf_options_auths(void);
-
-
-#define CSTATE_STACK_SIZE 10
-
-const uschar *config_directory = NULL;
-
-
-/* Structure for chain (stack) of .included files */
-
-typedef struct config_file_item {
- struct config_file_item *next;
- const uschar *filename;
- const uschar *directory;
- FILE *file;
- int lineno;
-} config_file_item;
-
-/* Structure for chain of configuration lines (-bP config) */
-
-typedef struct config_line_item {
- struct config_line_item *next;
- uschar *line;
-} config_line_item;
-
-static config_line_item* config_lines;
-
-/* Structure of table of conditional words and their state transitions */
-
-typedef struct cond_item {
- uschar *name;
- int namelen;
- int action1;
- int action2;
- int pushpop;
-} cond_item;
-
-/* Structure of table of syslog facility names and values */
-
-typedef struct syslog_fac_item {
- uschar *name;
- int value;
-} syslog_fac_item;
-
-/* constants */
-static const char * const hidden = "<value not displayable>";
-
-/* Static variables */
-
-static config_file_item *config_file_stack = NULL; /* For includes */
-
-static uschar *syslog_facility_str = NULL;
-static uschar next_section[24];
-static uschar time_buffer[24];
-
-/* State variables for conditional loading (.ifdef / .else / .endif) */
-
-static int cstate = 0;
-static int cstate_stack_ptr = -1;
-static int cstate_stack[CSTATE_STACK_SIZE];
-
-/* Table of state transitions for handling conditional inclusions. There are
-four possible state transitions:
-
- .ifdef true
- .ifdef false
- .elifdef true (or .else)
- .elifdef false
-
-.endif just causes the previous cstate to be popped off the stack */
-
-static int next_cstate[3][4] =
- {
- /* State 0: reading from file, or reading until next .else or .endif */
- { 0, 1, 2, 2 },
- /* State 1: condition failed, skipping until next .else or .endif */
- { 2, 2, 0, 1 },
- /* State 2: skipping until .endif */
- { 2, 2, 2, 2 },
- };
-
-/* Table of conditionals and the states to set. For each name, there are four
-values: the length of the name (to save computing it each time), the state to
-set if a macro was found in the line, the state to set if a macro was not found
-in the line, and a stack manipulation setting which is:
-
- -1 pull state value off the stack
- 0 don't alter the stack
- +1 push value onto stack, before setting new state
-*/
-
-static cond_item cond_list[] = {
- { US"ifdef", 5, 0, 1, 1 },
- { US"ifndef", 6, 1, 0, 1 },
- { US"elifdef", 7, 2, 3, 0 },
- { US"elifndef", 8, 3, 2, 0 },
- { US"else", 4, 2, 2, 0 },
- { US"endif", 5, 0, 0, -1 }
-};
-
-static int cond_list_size = sizeof(cond_list)/sizeof(cond_item);
-
-/* Table of syslog facility names and their values */
-
-static syslog_fac_item syslog_list[] = {
- { US"mail", LOG_MAIL },
- { US"user", LOG_USER },
- { US"news", LOG_NEWS },
- { US"uucp", LOG_UUCP },
- { US"local0", LOG_LOCAL0 },
- { US"local1", LOG_LOCAL1 },
- { US"local2", LOG_LOCAL2 },
- { US"local3", LOG_LOCAL3 },
- { US"local4", LOG_LOCAL4 },
- { US"local5", LOG_LOCAL5 },
- { US"local6", LOG_LOCAL6 },
- { US"local7", LOG_LOCAL7 },
- { US"daemon", LOG_DAEMON }
-};
-
-static int syslog_list_size = sizeof(syslog_list)/sizeof(syslog_fac_item);
-
-
+#ifdef MACRO_PREDEF
+# include "macro_predef.h"
+#endif
+static uschar * syslog_facility_str;
+static void fn_smtp_receive_timeout(const uschar *, const uschar *);
/*************************************************
* Main configuration options *
@@ -499,6 +375,163 @@ static optionlist optionlist_config[] = {
static int optionlist_config_size = nelem(optionlist_config);
+#ifdef MACRO_PREDEF
+
+static void fn_smtp_receive_timeout(const uschar * name, const uschar * str) {/*Dummy*/}
+
+void
+options_main(void)
+{
+options_from_list(optionlist_config, nelem(optionlist_config), US"MAIN", NULL);
+}
+
+void
+options_auths(void)
+{
+struct auth_info * ai;
+uschar buf[64];
+
+options_from_list(optionlist_auths, optionlist_auths_size, US"AUTHENTICATORS", NULL);
+
+for (ai = auths_available; ai->driver_name[0]; ai++)
+ {
+ snprintf(buf, sizeof(buf), "_DRIVER_AUTHENTICATOR_%T", ai->driver_name);
+ builtin_macro_create(buf);
+ options_from_list(ai->options, (unsigned)*ai->options_count, US"AUTHENTICATOR", ai->driver_name);
+ }
+}
+
+
+#else /*!MACRO_PREDEF*/
+
+extern char **environ;
+
+static void save_config_line(const uschar* line);
+static void save_config_position(const uschar *file, int line);
+static void print_config(BOOL admin, BOOL terse);
+
+
+#define CSTATE_STACK_SIZE 10
+
+const uschar *config_directory = NULL;
+
+
+/* Structure for chain (stack) of .included files */
+
+typedef struct config_file_item {
+ struct config_file_item *next;
+ const uschar *filename;
+ const uschar *directory;
+ FILE *file;
+ int lineno;
+} config_file_item;
+
+/* Structure for chain of configuration lines (-bP config) */
+
+typedef struct config_line_item {
+ struct config_line_item *next;
+ uschar *line;
+} config_line_item;
+
+static config_line_item* config_lines;
+
+/* Structure of table of conditional words and their state transitions */
+
+typedef struct cond_item {
+ uschar *name;
+ int namelen;
+ int action1;
+ int action2;
+ int pushpop;
+} cond_item;
+
+/* Structure of table of syslog facility names and values */
+
+typedef struct syslog_fac_item {
+ uschar *name;
+ int value;
+} syslog_fac_item;
+
+/* constants */
+static const char * const hidden = "<value not displayable>";
+
+/* Static variables */
+
+static config_file_item *config_file_stack = NULL; /* For includes */
+
+static uschar *syslog_facility_str = NULL;
+static uschar next_section[24];
+static uschar time_buffer[24];
+
+/* State variables for conditional loading (.ifdef / .else / .endif) */
+
+static int cstate = 0;
+static int cstate_stack_ptr = -1;
+static int cstate_stack[CSTATE_STACK_SIZE];
+
+/* Table of state transitions for handling conditional inclusions. There are
+four possible state transitions:
+
+ .ifdef true
+ .ifdef false
+ .elifdef true (or .else)
+ .elifdef false
+
+.endif just causes the previous cstate to be popped off the stack */
+
+static int next_cstate[3][4] =
+ {
+ /* State 0: reading from file, or reading until next .else or .endif */
+ { 0, 1, 2, 2 },
+ /* State 1: condition failed, skipping until next .else or .endif */
+ { 2, 2, 0, 1 },
+ /* State 2: skipping until .endif */
+ { 2, 2, 2, 2 },
+ };
+
+/* Table of conditionals and the states to set. For each name, there are four
+values: the length of the name (to save computing it each time), the state to
+set if a macro was found in the line, the state to set if a macro was not found
+in the line, and a stack manipulation setting which is:
+
+ -1 pull state value off the stack
+ 0 don't alter the stack
+ +1 push value onto stack, before setting new state
+*/
+
+static cond_item cond_list[] = {
+ { US"ifdef", 5, 0, 1, 1 },
+ { US"ifndef", 6, 1, 0, 1 },
+ { US"elifdef", 7, 2, 3, 0 },
+ { US"elifndef", 8, 3, 2, 0 },
+ { US"else", 4, 2, 2, 0 },
+ { US"endif", 5, 0, 0, -1 }
+};
+
+static int cond_list_size = sizeof(cond_list)/sizeof(cond_item);
+
+/* Table of syslog facility names and their values */
+
+static syslog_fac_item syslog_list[] = {
+ { US"mail", LOG_MAIL },
+ { US"user", LOG_USER },
+ { US"news", LOG_NEWS },
+ { US"uucp", LOG_UUCP },
+ { US"local0", LOG_LOCAL0 },
+ { US"local1", LOG_LOCAL1 },
+ { US"local2", LOG_LOCAL2 },
+ { US"local3", LOG_LOCAL3 },
+ { US"local4", LOG_LOCAL4 },
+ { US"local5", LOG_LOCAL5 },
+ { US"local6", LOG_LOCAL6 },
+ { US"local7", LOG_LOCAL7 },
+ { US"daemon", LOG_DAEMON }
+};
+
+static int syslog_list_size = sizeof(syslog_list)/sizeof(syslog_fac_item);
+
+
+
/*************************************************
* Find the name of an option *
@@ -561,9 +594,7 @@ return US"";
* Deal with an assignment to a macro *
*************************************************/
-/* We have a new definition.
-If a builtin macro we place at head of list, else tail. This lets us lazy-create
-builtins.
+/* We have a new definition; append to the list.
Args:
name Name of the macro. Must be in storage persistent past the call
@@ -571,34 +602,19 @@ Args:
*/
macro_item *
-macro_create(const uschar * name, const uschar * val,
- BOOL command_line, BOOL builtin)
+macro_create(const uschar * name, const uschar * val, BOOL command_line)
{
unsigned namelen = Ustrlen(name);
macro_item * m = store_get(sizeof(macro_item));
-/* fprintf(stderr, "%s: '%s' '%s'\n", __FUNCTION__, name, val) */
-if (!macros)
- {
- macros = m;
- mlast = m;
- m->next = NULL;
- }
-else if (builtin)
- {
- m->next = macros;
- macros = m;
- }
-else
- {
- mlast->next = m;
- mlast = m;
- m->next = NULL;
- }
+/* fprintf(stderr, "%s: '%s' '%s'\n", __FUNCTION__, name, val); */
+m->next = NULL;
m->command_line = command_line;
m->namelen = namelen;
m->name = name;
m->replacement = val;
+mlast->next = m;
+mlast = m;
return m;
}
@@ -692,222 +708,12 @@ if (redef)
/* We have a new definition. */
else
- (void) macro_create(string_copy(name), string_copy(s), FALSE, FALSE);
-}
-
-
-
-
-
-/*************************************************/
-/* Create compile-time feature macros */
-static void
-readconf_features(void)
-{
-/* Probably we could work out a static initialiser for wherever
-macros are stored, but this will do for now. Some names are awkward
-due to conflicts with other common macros. */
-
-#ifdef SUPPORT_CRYPTEQ
- macro_create(US"_HAVE_CRYPTEQ", US"y", FALSE, TRUE);
-#endif
-#if HAVE_ICONV
- macro_create(US"_HAVE_ICONV", US"y", FALSE, TRUE);
-#endif
-#if HAVE_IPV6
- macro_create(US"_HAVE_IPV6", US"y", FALSE, TRUE);
-#endif
-#ifdef HAVE_SETCLASSRESOURCES
- macro_create(US"_HAVE_SETCLASSRESOURCES", US"y", FALSE, TRUE);
-#endif
-#ifdef SUPPORT_PAM
- macro_create(US"_HAVE_PAM", US"y", FALSE, TRUE);
-#endif
-#ifdef EXIM_PERL
- macro_create(US"_HAVE_PERL", US"y", FALSE, TRUE);
-#endif
-#ifdef EXPAND_DLFUNC
- macro_create(US"_HAVE_DLFUNC", US"y", FALSE, TRUE);
-#endif
-#ifdef USE_TCP_WRAPPERS
- macro_create(US"_HAVE_TCPWRAPPERS", US"y", FALSE, TRUE);
-#endif
-#ifdef SUPPORT_TLS
- macro_create(US"_HAVE_TLS", US"y", FALSE, TRUE);
-# ifdef USE_GNUTLS
- macro_create(US"_HAVE_GNUTLS", US"y", FALSE, TRUE);
-# else
- macro_create(US"_HAVE_OPENSSL", US"y", FALSE, TRUE);
-# endif
-#endif
-#ifdef SUPPORT_TRANSLATE_IP_ADDRESS
- macro_create(US"_HAVE_TRANSLATE_IP_ADDRESS", US"y", FALSE, TRUE);
-#endif
-#ifdef SUPPORT_MOVE_FROZEN_MESSAGES
- macro_create(US"_HAVE_MOVE_FROZEN_MESSAGES", US"y", FALSE, TRUE);
-#endif
-#ifdef WITH_CONTENT_SCAN
- macro_create(US"_HAVE_CONTENT_SCANNING", US"y", FALSE, TRUE);
-#endif
-#ifndef DISABLE_DKIM
- macro_create(US"_HAVE_DKIM", US"y", FALSE, TRUE);
-#endif
-#ifndef DISABLE_DNSSEC
- macro_create(US"_HAVE_DNSSEC", US"y", FALSE, TRUE);
-#endif
-#ifndef DISABLE_EVENT
- macro_create(US"_HAVE_EVENT", US"y", FALSE, TRUE);
-#endif
-#ifdef SUPPORT_I18N
- macro_create(US"_HAVE_I18N", US"y", FALSE, TRUE);
-#endif
-#ifndef DISABLE_OCSP
- macro_create(US"_HAVE_OCSP", US"y", FALSE, TRUE);
-#endif
-#ifndef DISABLE_PRDR
- macro_create(US"_HAVE_PRDR", US"y", FALSE, TRUE);
-#endif
-#ifdef SUPPORT_PROXY
- macro_create(US"_HAVE_PROXY", US"y", FALSE, TRUE);
-#endif
-#ifdef SUPPORT_SOCKS
- macro_create(US"_HAVE_SOCKS", US"y", FALSE, TRUE);
-#endif
-#ifdef TCP_FASTOPEN
- macro_create(US"_HAVE_TCP_FASTOPEN", US"y", FALSE, TRUE);
-#endif
-#ifdef EXPERIMENTAL_LMDB
- macro_create(US"_HAVE_LMDB", US"y", FALSE, TRUE);
-#endif
-#ifdef EXPERIMENTAL_SPF
- macro_create(US"_HAVE_SPF", US"y", FALSE, TRUE);
-#endif
-#ifdef EXPERIMENTAL_SRS
- macro_create(US"_HAVE_SRS", US"y", FALSE, TRUE);
-#endif
-#ifdef EXPERIMENTAL_BRIGHTMAIL
- macro_create(US"_HAVE_BRIGHTMAIL", US"y", FALSE, TRUE);
-#endif
-#ifdef EXPERIMENTAL_DANE
- macro_create(US"_HAVE_DANE", US"y", FALSE, TRUE);
-#endif
-#ifdef EXPERIMENTAL_DCC
- macro_create(US"_HAVE_DCC", US"y", FALSE, TRUE);
-#endif
-#ifdef EXPERIMENTAL_DMARC
- macro_create(US"_HAVE_DMARC", US"y", FALSE, TRUE);
-#endif
-#ifdef EXPERIMENTAL_DSN_INFO
- macro_create(US"_HAVE_DSN_INFO", US"y", FALSE, TRUE);
-#endif
-
-#ifdef LOOKUP_LSEARCH
- macro_create(US"_HAVE_LOOKUP_LSEARCH", US"y", FALSE, TRUE);
-#endif
-#ifdef LOOKUP_CDB
- macro_create(US"_HAVE_LOOKUP_CDB", US"y", FALSE, TRUE);
-#endif
-#ifdef LOOKUP_DBM
- macro_create(US"_HAVE_LOOKUP_DBM", US"y", FALSE, TRUE);
-#endif
-#ifdef LOOKUP_DNSDB
- macro_create(US"_HAVE_LOOKUP_DNSDB", US"y", FALSE, TRUE);
-#endif
-#ifdef LOOKUP_DSEARCH
- macro_create(US"_HAVE_LOOKUP_DSEARCH", US"y", FALSE, TRUE);
-#endif
-#ifdef LOOKUP_IBASE
- macro_create(US"_HAVE_LOOKUP_IBASE", US"y", FALSE, TRUE);
-#endif
-#ifdef LOOKUP_LDAP
- macro_create(US"_HAVE_LOOKUP_LDAP", US"y", FALSE, TRUE);
-#endif
-#ifdef EXPERIMENTAL_LMDB
- macro_create(US"_HAVE_LOOKUP_LMDB", US"y", FALSE, TRUE);
-#endif
-#ifdef LOOKUP_MYSQL
- macro_create(US"_HAVE_LOOKUP_MYSQL", US"y", FALSE, TRUE);
-#endif
-#ifdef LOOKUP_NIS
- macro_create(US"_HAVE_LOOKUP_NIS", US"y", FALSE, TRUE);
-#endif
-#ifdef LOOKUP_NISPLUS
- macro_create(US"_HAVE_LOOKUP_NISPLUS", US"y", FALSE, TRUE);
-#endif
-#ifdef LOOKUP_ORACLE
- macro_create(US"_HAVE_LOOKUP_ORACLE", US"y", FALSE, TRUE);
-#endif
-#ifdef LOOKUP_PASSWD
- macro_create(US"_HAVE_LOOKUP_PASSWD", US"y", FALSE, TRUE);
-#endif
-#ifdef LOOKUP_PGSQL
- macro_create(US"_HAVE_LOOKUP_PGSQL", US"y", FALSE, TRUE);
-#endif
-#ifdef LOOKUP_REDIS
- macro_create(US"_HAVE_LOOKUP_REDIS", US"y", FALSE, TRUE);
-#endif
-#ifdef LOOKUP_SQLITE
- macro_create(US"_HAVE_LOOKUP_SQLITE", US"y", FALSE, TRUE);
-#endif
-#ifdef LOOKUP_TESTDB
- macro_create(US"_HAVE_LOOKUP_TESTDB", US"y", FALSE, TRUE);
-#endif
-#ifdef LOOKUP_WHOSON
- macro_create(US"_HAVE_LOOKUP_WHOSON", US"y", FALSE, TRUE);
-#endif
-
-#ifdef TRANSPORT_APPENDFILE
-# ifdef SUPPORT_MAILDIR
- macro_create(US"_HAVE_TRANSPORT_APPEND_MAILDIR", US"y", FALSE, TRUE);
-# endif
-# ifdef SUPPORT_MAILSTORE
- macro_create(US"_HAVE_TRANSPORT_APPEND_MAILSTORE", US"y", FALSE, TRUE);
-# endif
-# ifdef SUPPORT_MBX
- macro_create(US"_HAVE_TRANSPORT_APPEND_MBX", US"y", FALSE, TRUE);
-# endif
-#endif
+ (void) macro_create(string_copy(name), string_copy(s), FALSE);
}
-void
-readconf_options_from_list(optionlist * opts, unsigned nopt, const uschar * section, uschar * group)
-{
-int i;
-const uschar * s;
-
-/* The 'previously-defined-substring' rule for macros in config file
-lines is done so for these builtin macros: we know that the table
-we source from is in strict alpha order, hence the builtins portion
-of the macros list is in reverse-alpha (we prepend them) - so longer
-macros that have substrings are always discovered first during
-expansion. */
-
-for (i = 0; i < nopt; i++) if (*(s = US opts[i].name) && *s != '*')
- if (group)
- macro_create(string_sprintf("_OPT_%T_%T_%T", section, group, s), US"y", FALSE, TRUE);
- else
- macro_create(string_sprintf("_OPT_%T_%T", section, s), US"y", FALSE, TRUE);
-}
-static void
-readconf_options(void)
-{
-readconf_options_from_list(optionlist_config, nelem(optionlist_config), US"MAIN", NULL);
-readconf_options_routers();
-readconf_options_transports();
-readconf_options_auths();
-}
-
-static void
-macros_create_builtin(void)
-{
-readconf_features();
-readconf_options();
-macros_builtin_created = TRUE;
-}
-
/*************************************************
* Read configuration line *
@@ -1019,24 +825,6 @@ for (;;)
if (*s != '=') s = ss; /* Not a macro definition */
}
- /* If the builtin macros are not yet defined, and the line contains an
- underscrore followed by an one of the three possible chars used by
- builtins, create them. */
-
- if (!macros_builtin_created)
- {
- const uschar * t, * p;
- uschar c;
- for (t = s; (p = CUstrchr(t, '_')); t = p+1)
- if (c = p[1], c == 'O' || c == 'D' || c == 'H')
- {
-/* fprintf(stderr, "%s: builtins create triggered by '%s'\n", __FUNCTION__, s); */
- builtin_macros_create_trigger = string_copy(s);
- macros_create_builtin();
- break;
- }
- }
-
/* For each defined macro, scan the line (from after XXX= if present),
replacing all occurrences of the macro. */
@@ -1051,7 +839,7 @@ for (;;)
int moveby;
int replen = Ustrlen(m->replacement);
-/* fprintf(stderr, "%s: matched '%s' in '%s'\n", __FUNCTION__, m->name, t) */
+/* fprintf(stderr, "%s: matched '%s' in '%s'\n", __FUNCTION__, m->name, t); */
/* Expand the buffer if necessary */
while (newlen - m->namelen + replen + 1 > big_buffer_size)
@@ -3048,7 +2836,6 @@ else if (Ustrcmp(type, "macro") == 0)
fprintf(stderr, "exim: permission denied\n");
exit(EXIT_FAILURE);
}
- if (!macros_builtin_created) macros_create_builtin();
for (m = macros; m; m = m->next)
if (!name || Ustrcmp(name, m->name) == 0)
{
@@ -4362,21 +4149,6 @@ while ((p = get_config_line()))
* Initialize authenticators *
*************************************************/
-static void
-readconf_options_auths(void)
-{
-struct auth_info * ai;
-
-readconf_options_from_list(optionlist_auths, optionlist_auths_size, US"AUTHENTICATORS", NULL);
-
-for (ai = auths_available; ai->driver_name[0]; ai++)
- {
- macro_create(string_sprintf("_DRIVER_AUTHENTICATOR_%T", ai->driver_name), US"y", FALSE, TRUE);
- readconf_options_from_list(ai->options, (unsigned)*ai->options_count, US"AUTHENTICATOR", ai->driver_name);
- }
-}
-
-
/* Read the authenticators section of the configuration file.
Arguments: none
@@ -4708,6 +4480,7 @@ for (i = config_lines; i; i = i->next)
}
}
+#endif /*!MACRO_PREDEF*/
/* vi: aw ai sw=2
*/
/* End of readconf.c */
diff --git a/src/src/route.c b/src/src/route.c
index 08b3e055d..e30ae0e68 100644
--- a/src/src/route.c
+++ b/src/src/route.c
@@ -143,20 +143,28 @@ optionlist optionlist_routers[] = {
int optionlist_routers_size = sizeof(optionlist_routers)/sizeof(optionlist);
+#ifdef MACRO_PREDEF
+
+# include "macro_predef.h"
+
void
-readconf_options_routers(void)
+options_routers(void)
{
struct router_info * ri;
+uschar buf[64];
-readconf_options_from_list(optionlist_routers, nelem(optionlist_routers), US"ROUTERS", NULL);
+options_from_list(optionlist_routers, nelem(optionlist_routers), US"ROUTERS", NULL);
for (ri = routers_available; ri->driver_name[0]; ri++)
{
- macro_create(string_sprintf("_DRIVER_ROUTER_%T", ri->driver_name), US"y", FALSE, TRUE);
- readconf_options_from_list(ri->options, (unsigned)*ri->options_count, US"ROUTER", ri->driver_name);
+ snprintf(buf, sizeof(buf), "_DRIVER_ROUTER_%T", ri->driver_name);
+ builtin_macro_create(buf);
+ options_from_list(ri->options, (unsigned)*ri->options_count, US"ROUTER", ri->driver_name);
}
}
+#else /*!MACRO_PREDEF*/
+
/*************************************************
* Set router pointer from name *
*************************************************/
@@ -1919,4 +1927,5 @@ disable_logging = FALSE;
return yield;
}
+#endif /*!MACRO_PREDEF*/
/* End of route.c */
diff --git a/src/src/routers/accept.c b/src/src/routers/accept.c
index 6c76c7119..c08a0c20b 100644
--- a/src/src/routers/accept.c
+++ b/src/src/routers/accept.c
@@ -32,6 +32,18 @@ accept_router_options_block accept_router_option_defaults = {
};
+#ifdef MACRO_PREDEF
+
+/* Dummy entries */
+void accept_router_init(router_instance *rblock) {}
+int accept_router_entry(router_instance *rblock, address_item *addr,
+ struct passwd *pw, int verify, address_item **addr_local,
+ address_item **addr_remote, address_item **addr_new,
+ address_item **addr_succeed) {}
+
+#else /*!MACRO_PREDEF*/
+
+
/*************************************************
* Initialization entry point *
@@ -125,4 +137,5 @@ addr->prop.remove_headers = remove_headers;
return rf_queue_add(addr, addr_local, addr_remote, rblock, pw)? OK : DEFER;
}
+#endif /*!MACRO_PREDEF*/
/* End of routers/accept.c */
diff --git a/src/src/routers/dnslookup.c b/src/src/routers/dnslookup.c
index e4f7a2539..c1cbd4bf1 100644
--- a/src/src/routers/dnslookup.c
+++ b/src/src/routers/dnslookup.c
@@ -44,6 +44,22 @@ address can appear in the tables drtables.c. */
int dnslookup_router_options_count =
sizeof(dnslookup_router_options)/sizeof(optionlist);
+
+#ifdef MACRO_PREDEF
+
+/* Dummy entries */
+dnslookup_router_options_block dnslookup_router_option_defaults = {0};
+void dnslookup_router_init(router_instance *rblock) {}
+int dnslookup_router_entry(router_instance *rblock, address_item *addr,
+ struct passwd *pw, int verify, address_item **addr_local,
+ address_item **addr_remote, address_item **addr_new,
+ address_item **addr_succeed) {}
+
+#else /*!MACRO_PREDEF*/
+
+
+
+
/* Default private options block for the dnslookup router. */
dnslookup_router_options_block dnslookup_router_option_defaults = {
@@ -446,6 +462,7 @@ return rf_queue_add(addr, addr_local, addr_remote, rblock, pw)?
OK : DEFER;
}
+#endif /*!MACRO_PREDEF*/
/* End of routers/dnslookup.c */
/* vi: aw ai sw=2
*/
diff --git a/src/src/routers/ipliteral.c b/src/src/routers/ipliteral.c
index 22d292d88..c84bd952b 100644
--- a/src/src/routers/ipliteral.c
+++ b/src/src/routers/ipliteral.c
@@ -30,6 +30,17 @@ value is present to keep some compilers happy. */
ipliteral_router_options_block ipliteral_router_option_defaults = { 0 };
+#ifdef MACRO_PREDEF
+
+/* Dummy entries */
+void ipliteral_router_init(router_instance *rblock) {}
+int ipliteral_router_entry(router_instance *rblock, address_item *addr,
+ struct passwd *pw, int verify, address_item **addr_local,
+ address_item **addr_remote, address_item **addr_new,
+ address_item **addr_succeed) {}
+
+#else /*!MACRO_PREDEF*/
+
/*************************************************
* Initialization entry point *
@@ -190,4 +201,5 @@ return rf_queue_add(addr, addr_local, addr_remote, rblock, pw)?
OK : DEFER;
}
+#endif /*!MACRO_PREDEF*/
/* End of routers/ipliteral.c */
diff --git a/src/src/routers/iplookup.c b/src/src/routers/iplookup.c
index 96e9626df..9dd7f4fb5 100644
--- a/src/src/routers/iplookup.c
+++ b/src/src/routers/iplookup.c
@@ -44,6 +44,20 @@ address can appear in the tables drtables.c. */
int iplookup_router_options_count =
sizeof(iplookup_router_options)/sizeof(optionlist);
+
+#ifdef MACRO_PREDEF
+
+/* Dummy entries */
+iplookup_router_options_block iplookup_router_option_defaults = {0};
+void iplookup_router_init(router_instance *rblock) {}
+int iplookup_router_entry(router_instance *rblock, address_item *addr,
+ struct passwd *pw, int verify, address_item **addr_local,
+ address_item **addr_remote, address_item **addr_new,
+ address_item **addr_succeed) {}
+
+#else /*!MACRO_PREDEF*/
+
+
/* Default private options block for the iplookup router. */
iplookup_router_options_block iplookup_router_option_defaults = {
@@ -402,4 +416,5 @@ if (rc != OK) return rc;
return OK;
}
+#endif /*!MACRO_PREDEF*/
/* End of routers/iplookup.c */
diff --git a/src/src/routers/manualroute.c b/src/src/routers/manualroute.c
index 31185e160..639185bd6 100644
--- a/src/src/routers/manualroute.c
+++ b/src/src/routers/manualroute.c
@@ -34,6 +34,21 @@ address can appear in the tables drtables.c. */
int manualroute_router_options_count =
sizeof(manualroute_router_options)/sizeof(optionlist);
+
+#ifdef MACRO_PREDEF
+
+/* Dummy entries */
+manualroute_router_options_block manualroute_router_option_defaults = {0};
+void manualroute_router_init(router_instance *rblock) {}
+int manualroute_router_entry(router_instance *rblock, address_item *addr,
+ struct passwd *pw, int verify, address_item **addr_local,
+ address_item **addr_remote, address_item **addr_new,
+ address_item **addr_succeed) {}
+
+#else /*!MACRO_PREDEF*/
+
+
+
/* Default private options block for the manualroute router. */
manualroute_router_options_block manualroute_router_option_defaults = {
@@ -474,4 +489,5 @@ addr->transport = transport;
return OK;
}
+#endif /*!MACRO_PREDEF*/
/* End of routers/manualroute.c */
diff --git a/src/src/routers/queryprogram.c b/src/src/routers/queryprogram.c
index cd02f366f..535eb57e4 100644
--- a/src/src/routers/queryprogram.c
+++ b/src/src/routers/queryprogram.c
@@ -40,6 +40,20 @@ address can appear in the tables drtables.c. */
int queryprogram_router_options_count =
sizeof(queryprogram_router_options)/sizeof(optionlist);
+
+#ifdef MACRO_PREDEF
+
+/* Dummy entries */
+queryprogram_router_options_block queryprogram_router_option_defaults = {0};
+void queryprogram_router_init(router_instance *rblock) {}
+int queryprogram_router_entry(router_instance *rblock, address_item *addr,
+ struct passwd *pw, int verify, address_item **addr_local,
+ address_item **addr_remote, address_item **addr_new,
+ address_item **addr_succeed) {}
+
+#else /*!MACRO_PREDEF*/
+
+
/* Default private options block for the queryprogram router. */
queryprogram_router_options_block queryprogram_router_option_defaults = {
@@ -539,4 +553,5 @@ return rf_queue_add(addr, addr_local, addr_remote, rblock, pw)?
OK : DEFER;
}
+#endif /*!MACRO_PREDEF*/
/* End of routers/queryprogram.c */
diff --git a/src/src/routers/redirect.c b/src/src/routers/redirect.c
index 29537baae..0ccc1a968 100644
--- a/src/src/routers/redirect.c
+++ b/src/src/routers/redirect.c
@@ -133,6 +133,21 @@ address can appear in the tables drtables.c. */
int redirect_router_options_count =
sizeof(redirect_router_options)/sizeof(optionlist);
+
+#ifdef MACRO_PREDEF
+
+/* Dummy entries */
+redirect_router_options_block redirect_router_option_defaults = {0};
+void redirect_router_init(router_instance *rblock) {}
+int redirect_router_entry(router_instance *rblock, address_item *addr,
+ struct passwd *pw, int verify, address_item **addr_local,
+ address_item **addr_remote, address_item **addr_new,
+ address_item **addr_succeed) {}
+
+#else /*!MACRO_PREDEF*/
+
+
+
/* Default private options block for the redirect router. */
redirect_router_options_block redirect_router_option_defaults = {
@@ -921,4 +936,5 @@ addr->next = *addr_succeed;
return yield;
}
+#endif /*!MACRO_PREDEF*/
/* End of routers/redirect.c */
diff --git a/src/src/transport.c b/src/src/transport.c
index 20d0b8a52..49ea29e0a 100644
--- a/src/src/transport.c
+++ b/src/src/transport.c
@@ -11,25 +11,6 @@ transports. */
#include "exim.h"
-/* Structure for keeping list of addresses that have been added to
-Envelope-To:, in order to avoid duplication. */
-
-struct aci {
- struct aci *next;
- address_item *ptr;
- };
-
-
-/* Static data for write_chunk() */
-
-static uschar *chunk_ptr; /* chunk pointer */
-static uschar *nl_check; /* string to look for at line start */
-static int nl_check_length; /* length of same */
-static uschar *nl_escape; /* string to insert */
-static int nl_escape_length; /* length of same */
-static int nl_partial_match; /* length matched at chunk end */
-
-
/* Generic options for transports, all of which live inside transport_instance
data blocks and which therefore have the opt_public flag set. Note that there
are other options living inside this structure which can be set only from
@@ -106,21 +87,47 @@ optionlist optionlist_transports[] = {
int optionlist_transports_size = nelem(optionlist_transports);
+#ifdef MACRO_PREDEF
+
+# include "macro_predef.h"
void
-readconf_options_transports(void)
+options_transports(void)
{
struct transport_info * ti;
+uschar buf[64];
-readconf_options_from_list(optionlist_transports, nelem(optionlist_transports), US"TRANSPORTS", NULL);
+options_from_list(optionlist_transports, nelem(optionlist_transports), US"TRANSPORTS", NULL);
for (ti = transports_available; ti->driver_name[0]; ti++)
{
- macro_create(string_sprintf("_DRIVER_TRANSPORT_%T", ti->driver_name), US"y", FALSE, TRUE);
- readconf_options_from_list(ti->options, (unsigned)*ti->options_count, US"TRANSPORT", ti->driver_name);
+ snprintf(buf, sizeof(buf), "_DRIVER_TRANSPORT_%T", ti->driver_name);
+ builtin_macro_create(buf);
+ options_from_list(ti->options, (unsigned)*ti->options_count, US"TRANSPORT", ti->driver_name);
}
}
+#else /*!MACRO_PREDEF*/
+
+/* Structure for keeping list of addresses that have been added to
+Envelope-To:, in order to avoid duplication. */
+
+struct aci {
+ struct aci *next;
+ address_item *ptr;
+ };
+
+
+/* Static data for write_chunk() */
+
+static uschar *chunk_ptr; /* chunk pointer */
+static uschar *nl_check; /* string to look for at line start */
+static int nl_check_length; /* length of same */
+static uschar *nl_escape; /* string to insert */
+static int nl_escape_length; /* length of same */
+static int nl_partial_match; /* length matched at chunk end */
+
+
/*************************************************
* Initialize transport list *
*************************************************/
@@ -2267,6 +2274,7 @@ if (expand_arguments)
return TRUE;
}
+#endif /*!MACRO_PREDEF*/
/* vi: aw ai sw=2
*/
/* End of transport.c */
diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c
index 9210ca8de..a9abe8ad0 100644
--- a/src/src/transports/appendfile.c
+++ b/src/src/transports/appendfile.c
@@ -14,22 +14,6 @@
#endif
-/* Encodings for mailbox formats, and their names. MBX format is actually
-supported only if SUPPORT_MBX is set. */
-
-enum { mbf_unix, mbf_mbx, mbf_smail, mbf_maildir, mbf_mailstore };
-
-static const char *mailbox_formats[] = {
- "unix", "mbx", "smail", "maildir", "mailstore" };
-
-
-/* Check warn threshold only if quota size set or not a percentage threshold
- percentage check should only be done if quota > 0 */
-
-#define THRESHOLD_CHECK (ob->quota_warn_threshold_value > 0 && \
- (!ob->quota_warn_threshold_is_percent || ob->quota_value > 0))
-
-
/* Options specific to the appendfile transport. They must be in alphabetic
order (note that "_" comes before the lower case letters). Some of them are
stored in the publicly visible instance block - these are flagged with the
@@ -170,6 +154,16 @@ address can appear in the tables drtables.c. */
int appendfile_transport_options_count =
sizeof(appendfile_transport_options)/sizeof(optionlist);
+
+#ifdef MACRO_PREDEF
+
+/* Dummy values */
+appendfile_transport_options_block appendfile_transport_option_defaults = {0};
+void appendfile_transport_init(transport_instance *tblock) {}
+BOOL appendfile_transport_entry(transport_instance *tblock, address_item *addr) {return FALSE;}
+
+#else /*!MACRO_PREDEF*/
+
/* Default private options block for the appendfile transport. */
appendfile_transport_options_block appendfile_transport_option_defaults = {
@@ -240,6 +234,22 @@ appendfile_transport_options_block appendfile_transport_option_defaults = {
};
+/* Encodings for mailbox formats, and their names. MBX format is actually
+supported only if SUPPORT_MBX is set. */
+
+enum { mbf_unix, mbf_mbx, mbf_smail, mbf_maildir, mbf_mailstore };
+
+static const char *mailbox_formats[] = {
+ "unix", "mbx", "smail", "maildir", "mailstore" };
+
+
+/* Check warn threshold only if quota size set or not a percentage threshold
+ percentage check should only be done if quota > 0 */
+
+#define THRESHOLD_CHECK (ob->quota_warn_threshold_value > 0 && \
+ (!ob->quota_warn_threshold_is_percent || ob->quota_value > 0))
+
+
/*************************************************
* Setup entry point *
@@ -3407,4 +3417,5 @@ put in the first address of a batch. */
return FALSE;
}
+#endif /*!MACRO_PREDEF*/
/* End of transport/appendfile.c */
diff --git a/src/src/transports/autoreply.c b/src/src/transports/autoreply.c
index 3b4463075..2f0efaa55 100644
--- a/src/src/transports/autoreply.c
+++ b/src/src/transports/autoreply.c
@@ -62,6 +62,17 @@ address can appear in the tables drtables.c. */
int autoreply_transport_options_count =
sizeof(autoreply_transport_options)/sizeof(optionlist);
+
+#ifdef MACRO_PREDEF
+
+/* Dummy values */
+autoreply_transport_options_block autoreply_transport_option_defaults = {0};
+void autoreply_transport_init(transport_instance *tblock) {}
+BOOL autoreply_transport_entry(transport_instance *tblock, address_item *addr) {return FALSE;}
+
+#else /*!MACRO_PREDEF*/
+
+
/* Default private options block for the autoreply transport. */
autoreply_transport_options_block autoreply_transport_option_defaults = {
@@ -879,4 +890,5 @@ DEBUG(D_transport) debug_printf("%s transport succeeded\n", tblock->name);
return FALSE;
}
+#endif /*!MACRO_PREDEF*/
/* End of transport/autoreply.c */
diff --git a/src/src/transports/lmtp.c b/src/src/transports/lmtp.c
index 610320c25..46215fb5f 100644
--- a/src/src/transports/lmtp.c
+++ b/src/src/transports/lmtp.c
@@ -40,6 +40,17 @@ address can appear in the tables drtables.c. */
int lmtp_transport_options_count =
sizeof(lmtp_transport_options)/sizeof(optionlist);
+
+#ifdef MACRO_PREDEF
+
+/* Dummy values */
+lmtp_transport_options_block lmtp_transport_option_defaults = {0};
+void lmtp_transport_init(transport_instance *tblock) {}
+BOOL lmtp_transport_entry(transport_instance *tblock, address_item *addr) {return FALSE;}
+
+#else /*!MACRO_PREDEF*/
+
+
/* Default private options block for the lmtp transport. */
lmtp_transport_options_block lmtp_transport_option_defaults = {
@@ -791,4 +802,5 @@ MINUS_N:
return FALSE;
}
+#endif /*!MACRO_PREDEF*/
/* End of transport/lmtp.c */
diff --git a/src/src/transports/pipe.c b/src/src/transports/pipe.c
index f7f0e590a..294b9fe7b 100644
--- a/src/src/transports/pipe.c
+++ b/src/src/transports/pipe.c
@@ -95,6 +95,17 @@ address can appear in the tables drtables.c. */
int pipe_transport_options_count =
sizeof(pipe_transport_options)/sizeof(optionlist);
+
+#ifdef MACRO_PREDEF
+
+/* Dummy values */
+pipe_transport_options_block pipe_transport_option_defaults = {0};
+void pipe_transport_init(transport_instance *tblock) {}
+BOOL pipe_transport_entry(transport_instance *tblock, address_item *addr) {return FALSE;}
+
+#else /*!MACRO_PREDEF*/
+
+
/* Default private options block for the pipe transport. */
pipe_transport_options_block pipe_transport_option_defaults = {
@@ -1152,4 +1163,5 @@ if (addr->transport_return != OK)
return FALSE;
}
+#endif /*!MACRO_PREDEF*/
/* End of transport/pipe.c */
diff --git a/src/src/transports/queuefile.c b/src/src/transports/queuefile.c
index 7f10706c1..bc4ed3f40 100644
--- a/src/src/transports/queuefile.c
+++ b/src/src/transports/queuefile.c
@@ -20,12 +20,25 @@ optionlist queuefile_transport_options[] = {
(void *)offsetof(queuefile_transport_options_block, dirname) },
};
+
/* Size of the options list. An extern variable has to be used so that its
address can appear in the tables drtables.c. */
int queuefile_transport_options_count =
sizeof(queuefile_transport_options) / sizeof(optionlist);
+
+#ifdef MACRO_PREDEF
+
+/* Dummy values */
+queuefile_transport_options_block queuefile_transport_option_defaults = {0};
+void queuefile_transport_init(transport_instance *tblock) {}
+BOOL queuefile_transport_entry(transport_instance *tblock, address_item *addr) {return FALSE;}
+
+#else /*!MACRO_PREDEF*/
+
+
+
/* Default private options block for the appendfile transport. */
queuefile_transport_options_block queuefile_transport_option_defaults = {
@@ -254,3 +267,5 @@ if (sdfd >= 0) (void) close(sdfd);
put in the first address of a batch. */
return FALSE;
}
+
+#endif /*!MACRO_PREDEF*/
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index fc2c0ea4d..477cdac4d 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -186,6 +186,18 @@ address can appear in the tables drtables.c. */
int smtp_transport_options_count =
sizeof(smtp_transport_options)/sizeof(optionlist);
+
+#ifdef MACRO_PREDEF
+
+/* Dummy values */
+smtp_transport_options_block smtp_transport_option_defaults = {0};
+void smtp_transport_init(transport_instance *tblock) {}
+BOOL smtp_transport_entry(transport_instance *tblock, address_item *addr) {return FALSE;}
+void smtp_transport_closedown(transport_instance *tblock) {}
+
+#else /*!MACRO_PREDEF*/
+
+
/* Default private options block for the smtp transport. */
smtp_transport_options_block smtp_transport_option_defaults = {
@@ -4609,6 +4621,7 @@ DEBUG(D_transport) debug_printf("Leaving %s transport\n", tblock->name);
return TRUE; /* Each address has its status */
}
+#endif /*!MACRO_PREDEF*/
/* vi: aw ai sw=2
*/
/* End of transport/smtp.c */