From: Jeremy Harris Date: Sat, 8 Jul 2017 12:24:38 +0000 (+0100) Subject: Prebuild the data structure for builtin macros X-Git-Url: https://git.exim.org/users/jgh/exim.git/commitdiff_plain/d185889f47b9b27088e777f7d382295c51271586?ds=inline Prebuild the data structure for builtin macros --- 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 = ""; - -/* 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 = ""; + +/* 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 */