From: Jeremy Harris Date: Mon, 10 Oct 2016 19:24:34 +0000 (+0100) Subject: Lazy-create builtin macros X-Git-Tag: exim-4_88_RC3~38 X-Git-Url: https://git.exim.org/users/heiko/exim.git/commitdiff_plain/8e6c4db10e5b9bc2fa89a7b5d38fcf12bb03fd2f Lazy-create builtin macros By only filling out the internal macro representation for the builtin macros when a config line includes an underscore followed by a letter which might be one we should save startup effort on configs which never use a builtin. --- diff --git a/src/src/exim.c b/src/src/exim.c index 95f8cef3b..905314cad 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -1688,8 +1688,6 @@ big_buffer = store_malloc(big_buffer_size); descriptive text. */ set_process_info("initializing"); -readconf_features(); -readconf_options(); os_restarting_signal(SIGUSR1, usr1_handler); /* SIGHUP is used to get the daemon to reconfigure. It gets set as appropriate @@ -2448,7 +2446,7 @@ for (i = 1; i < argc; i++) exit(EXIT_FAILURE); } - m = macro_create(name, s, TRUE); + m = macro_create(name, s, TRUE, FALSE); if (clmacro_count >= MAX_CLMACROS) { diff --git a/src/src/functions.h b/src/src/functions.h index fd1e11d1b..03751a8e0 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -245,7 +245,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); +extern macro_item * macro_create(const uschar *, const uschar *, BOOL, BOOL); extern void mainlog_close(void); #ifdef WITH_CONTENT_SCAN extern int malware(const uschar *, int); @@ -315,8 +315,6 @@ extern int rda_is_filter(const uschar *); extern BOOL readconf_depends(driver_instance *, uschar *); extern void readconf_driver_init(uschar *, driver_instance **, driver_info *, int, void *, int, optionlist *, int); -extern void readconf_features(void); -extern void readconf_options(void); extern uschar *readconf_find_option(void *); extern void readconf_main(BOOL); extern void readconf_options_from_list(optionlist *, unsigned, uschar *); diff --git a/src/src/globals.c b/src/src/globals.c index df3696c33..28cb06028 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -926,6 +926,7 @@ 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 6615d338b..0084a99e7 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -555,6 +555,7 @@ 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/readconf.c b/src/src/readconf.c index edc09aa4e..a452a46d5 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -556,17 +556,34 @@ return US""; /* We have a new definition. The macro_item structure includes a final vector called "name" which is one byte long. Thus, adding "namelen" gives us enough -room to store the "name" string. */ +room to store the "name" string. +If a builtin macro we place at head of list, else tail. This lets us lazy-create +builtins. */ macro_item * -macro_create(const uschar * name, const uschar * val, BOOL command_line) +macro_create(const uschar * name, const uschar * val, + BOOL command_line, BOOL builtin) { unsigned namelen = Ustrlen(name); macro_item * m = store_get(sizeof(macro_item) + namelen); -if (!macros) macros = m; else mlast->next = m; -mlast = m; -m->next = NULL; +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; + } m->command_line = command_line; m->namelen = namelen; m->replacement = string_copy(val); @@ -664,11 +681,209 @@ if (redef) /* We have a new definition. */ else - (void) macro_create(name, s, FALSE); + (void) macro_create(name, 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 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_LKUP_LSEARCH", US"y", FALSE, TRUE); +#endif +#ifdef LOOKUP_CDB + macro_create(US"_HAVE_LKUP_CDB", US"y", FALSE, TRUE); +#endif +#ifdef LOOKUP_DBM + macro_create(US"_HAVE_LKUP_DBM", US"y", FALSE, TRUE); +#endif +#ifdef LOOKUP_DNSDB + macro_create(US"_HAVE_LKUP_DNSDB", US"y", FALSE, TRUE); +#endif +#ifdef LOOKUP_DSEARCH + macro_create(US"_HAVE_LKUP_DSEARCH", US"y", FALSE, TRUE); +#endif +#ifdef LOOKUP_IBASE + macro_create(US"_HAVE_LKUP_IBASE", US"y", FALSE, TRUE); +#endif +#ifdef LOOKUP_LDAP + macro_create(US"_HAVE_LKUP_LDAP", US"y", FALSE, TRUE); +#endif +#ifdef EXPERIMENTAL_LMDB + macro_create(US"_HAVE_LKUP_LMDB", US"y", FALSE, TRUE); +#endif +#ifdef LOOKUP_MYSQL + macro_create(US"_HAVE_LKUP_MYSQL", US"y", FALSE, TRUE); +#endif +#ifdef LOOKUP_NIS + macro_create(US"_HAVE_LKUP_NIS", US"y", FALSE, TRUE); +#endif +#ifdef LOOKUP_NISPLUS + macro_create(US"_HAVE_LKUP_NISPLUS", US"y", FALSE, TRUE); +#endif +#ifdef LOOKUP_ORACLE + macro_create(US"_HAVE_LKUP_ORACLE", US"y", FALSE, TRUE); +#endif +#ifdef LOOKUP_PASSWD + macro_create(US"_HAVE_LKUP_PASSWD", US"y", FALSE, TRUE); +#endif +#ifdef LOOKUP_PGSQL + macro_create(US"_HAVE_LKUP_PGSQL", US"y", FALSE, TRUE); +#endif +#ifdef LOOKUP_REDIS + macro_create(US"_HAVE_LKUP_REDIS", US"y", FALSE, TRUE); +#endif +#ifdef LOOKUP_SQLITE + macro_create(US"_HAVE_LKUP_SQLITE", US"y", FALSE, TRUE); +#endif +#ifdef LOOKUP_TESTDB + macro_create(US"_HAVE_LKUP_TESTDB", US"y", FALSE, TRUE); +#endif +#ifdef LOOKUP_WHOSON + macro_create(US"_HAVE_LKUP_WHOSON", US"y", FALSE, TRUE); +#endif + +#ifdef TRANSPORT_APPENDFILE +# ifdef SUPPORT_MAILDIR + macro_create(US"_HAVE_TPT_APPEND_MAILDR", US"y", FALSE, TRUE); +# endif +# ifdef SUPPORT_MAILSTORE + macro_create(US"_HAVE_TPT_APPEND_MAILSTORE", US"y", FALSE, TRUE); +# endif +# ifdef SUPPORT_MBX + macro_create(US"_HAVE_TPT_APPEND_MBX", US"y", FALSE, TRUE); +# endif +#endif +} + + +void +readconf_options_from_list(optionlist * opts, unsigned nopt, uschar * group) +{ +int i; +const uschar * s; + +/* Walk the array backwards to get substring-conflict names */ +for (i = nopt-1; i >= 0; i--) if (*(s = opts[i].name) && *s != '*') + macro_create(string_sprintf("_OPT_%T_%T", group, s), US"y", FALSE, TRUE); } +static void +readconf_options(void) +{ +readconf_options_from_list(optionlist_config, nelem(optionlist_config), US"MAIN"); +readconf_options_routers(); +readconf_options_transports(); +readconf_options_auths(); +} +static void +macros_create_builtin(void) +{ +readconf_features(); +readconf_options(); +macros_builtin_created = TRUE; +} /************************************************* @@ -780,6 +995,22 @@ 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') + { + macros_create_builtin(); + break; + } + } + /* For each defined macro, scan the line (from after XXX= if present), replacing all occurrences of the macro. */ @@ -2769,6 +3000,7 @@ 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) { @@ -3009,196 +3241,6 @@ return status == 0; -/*************************************************/ -/* Create compile-time feature macros */ -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); -#endif -#if HAVE_ICONV - macro_create(US"_HAVE_ICONV", US"y", FALSE); -#endif -#if HAVE_IPV6 - macro_create(US"_HAVE_IPV6", US"y", FALSE); -#endif -#ifdef HAVE_SETCLASSRESOURCES - macro_create(US"_HAVE_SETCLASSRESOURCES", US"y", FALSE); -#endif -#ifdef SUPPORT_PAM - macro_create(US"_HAVE_PAM", US"y", FALSE); -#endif -#ifdef EXIM_PERL - macro_create(US"_HAVE_PERL", US"y", FALSE); -#endif -#ifdef EXPAND_DLFUNC - macro_create(US"_HAVE_DLFUNC", US"y", FALSE); -#endif -#ifdef USE_TCP_WRAPPERS - macro_create(US"_HAVE_TCPWRAPPERS", US"y", FALSE); -#endif -#ifdef SUPPORT_TLS - macro_create(US"_HAVE_TLS", US"y", FALSE); -# ifdef USE_GNUTLS - macro_create(US"_HAVE_GNUTLS", US"y", FALSE); -# else - macro_create(US"_HAVE_OPENSSL", US"y", FALSE); -# endif -#endif -#ifdef SUPPORT_TRANSLATE_IP_ADDRESS - macro_create(US"_HAVE_TRANSLATE_IP_ADDRESS", US"y", FALSE); -#endif -#ifdef SUPPORT_MOVE_FROZEN_MESSAGES - macro_create(US"_HAVE_MOVE_FROZEN_MESSAGES", US"y", FALSE); -#endif -#ifdef WITH_CONTENT_SCAN - macro_create(US"_HAVE_CONTENT_SCANNING", US"y", FALSE); -#endif -#ifndef DISABLE_DKIM - macro_create(US"_HAVE_DKIM", US"y", FALSE); -#endif -#ifndef DISABLE_DNSSEC - macro_create(US"_HAVE_DNSSEC", US"y", FALSE); -#endif -#ifndef DISABLE_EVENT - macro_create(US"_HAVE_EVENT", US"y", FALSE); -#endif -#ifdef SUPPORT_I18N - macro_create(US"_HAVE_I18N", US"y", FALSE); -#endif -#ifndef DISABLE_OCSP - macro_create(US"_HAVE_OCSP", US"y", FALSE); -#endif -#ifndef DISABLE_PRDR - macro_create(US"_HAVE_PRDR", US"y", FALSE); -#endif -#ifdef SUPPORT_PROXY - macro_create(US"_HAVE_PROXY", US"y", FALSE); -#endif -#ifdef SUPPORT_SOCKS - macro_create(US"_HAVE_SOCKS", US"y", FALSE); -#endif -#ifdef EXPERIMENTAL_LMDB - macro_create(US"_HAVE_LMDB", US"y", FALSE); -#endif -#ifdef EXPERIMENTAL_SPF - macro_create(US"_HAVE_SPF", US"y", FALSE); -#endif -#ifdef EXPERIMENTAL_SRS - macro_create(US"_HAVE_SRS", US"y", FALSE); -#endif -#ifdef EXPERIMENTAL_BRIGHTMAIL - macro_create(US"_HAVE_BRIGHTMAIL", US"y", FALSE); -#endif -#ifdef EXPERIMENTAL_DANE - macro_create(US"_HAVE_DANE", US"y", FALSE); -#endif -#ifdef EXPERIMENTAL_DCC - macro_create(US"_HAVE_DCC", US"y", FALSE); -#endif -#ifdef EXPERIMENTAL_DMARC - macro_create(US"_HAVE_DMARC", US"y", FALSE); -#endif -#ifdef EXPERIMENTAL_DSN_INFO - macro_create(US"_HAVE_DSN_INFO", US"y", FALSE); -#endif - -#ifdef LOOKUP_LSEARCH - macro_create(US"_HAVE_LKUP_LSEARCH", US"y", FALSE); -#endif -#ifdef LOOKUP_CDB - macro_create(US"_HAVE_LKUP_CDB", US"y", FALSE); -#endif -#ifdef LOOKUP_DBM - macro_create(US"_HAVE_LKUP_DBM", US"y", FALSE); -#endif -#ifdef LOOKUP_DNSDB - macro_create(US"_HAVE_LKUP_DNSDB", US"y", FALSE); -#endif -#ifdef LOOKUP_DSEARCH - macro_create(US"_HAVE_LKUP_DSEARCH", US"y", FALSE); -#endif -#ifdef LOOKUP_IBASE - macro_create(US"_HAVE_LKUP_IBASE", US"y", FALSE); -#endif -#ifdef LOOKUP_LDAP - macro_create(US"_HAVE_LKUP_LDAP", US"y", FALSE); -#endif -#ifdef EXPERIMENTAL_LMDB - macro_create(US"_HAVE_LKUP_LMDB", US"y", FALSE); -#endif -#ifdef LOOKUP_MYSQL - macro_create(US"_HAVE_LKUP_MYSQL", US"y", FALSE); -#endif -#ifdef LOOKUP_NIS - macro_create(US"_HAVE_LKUP_NIS", US"y", FALSE); -#endif -#ifdef LOOKUP_NISPLUS - macro_create(US"_HAVE_LKUP_NISPLUS", US"y", FALSE); -#endif -#ifdef LOOKUP_ORACLE - macro_create(US"_HAVE_LKUP_ORACLE", US"y", FALSE); -#endif -#ifdef LOOKUP_PASSWD - macro_create(US"_HAVE_LKUP_PASSWD", US"y", FALSE); -#endif -#ifdef LOOKUP_PGSQL - macro_create(US"_HAVE_LKUP_PGSQL", US"y", FALSE); -#endif -#ifdef LOOKUP_REDIS - macro_create(US"_HAVE_LKUP_REDIS", US"y", FALSE); -#endif -#ifdef LOOKUP_SQLITE - macro_create(US"_HAVE_LKUP_SQLITE", US"y", FALSE); -#endif -#ifdef LOOKUP_TESTDB - macro_create(US"_HAVE_LKUP_TESTDB", US"y", FALSE); -#endif -#ifdef LOOKUP_WHOSON - macro_create(US"_HAVE_LKUP_WHOSON", US"y", FALSE); -#endif - -#ifdef TRANSPORT_APPENDFILE -# ifdef SUPPORT_MAILDIR - macro_create(US"_HAVE_TPT_APPEND_MAILDR", US"y", FALSE); -# endif -# ifdef SUPPORT_MAILSTORE - macro_create(US"_HAVE_TPT_APPEND_MAILSTORE", US"y", FALSE); -# endif -# ifdef SUPPORT_MBX - macro_create(US"_HAVE_TPT_APPEND_MBX", US"y", FALSE); -# endif -#endif -} - - -void -readconf_options_from_list(optionlist * opts, unsigned nopt, uschar * group) -{ -int i; -const uschar * s; - -/* Walk the array backwards to get substring-conflict names */ -for (i = nopt-1; i >= 0; i--) if (*(s = opts[i].name) && *s != '*') - macro_create(string_sprintf("_OPT_%T_%T", group, s), US"y", FALSE); -} - - -void -readconf_options(void) -{ -readconf_options_from_list(optionlist_config, nelem(optionlist_config), US"MAIN"); -readconf_options_routers(); -readconf_options_transports(); -readconf_options_auths(); -} - - /************************************************* * Read main configuration options * *************************************************/ @@ -3237,8 +3279,7 @@ const uschar *list = config_main_filelist; /* Loop through the possible file names */ -while((filename = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)) - != NULL) +while((filename = string_nextinlist(&list, &sep, big_buffer, big_buffer_size))) { /* Cut out all the fancy processing unless specifically wanted */ @@ -4249,7 +4290,7 @@ readconf_options_from_list(optionlist_auths, optionlist_auths_size, US"AU"); for (ai = auths_available; ai->driver_name[0]; ai++) { - macro_create(string_sprintf("_DRVR_AUTH_%T", ai->driver_name), US"y", FALSE); + macro_create(string_sprintf("_DRVR_AUTH_%T", ai->driver_name), US"y", FALSE, TRUE); readconf_options_from_list(ai->options, (unsigned)*ai->options_count, ai->driver_name); } } diff --git a/src/src/route.c b/src/src/route.c index be91949b8..3ca1afbfb 100644 --- a/src/src/route.c +++ b/src/src/route.c @@ -152,7 +152,7 @@ readconf_options_from_list(optionlist_routers, nelem(optionlist_routers), US"RT" for (ri = routers_available; ri->driver_name[0]; ri++) { - macro_create(string_sprintf("_DRVR_RTR_%T", ri->driver_name), US"y", FALSE); + macro_create(string_sprintf("_DRVR_RTR_%T", ri->driver_name), US"y", FALSE, TRUE); readconf_options_from_list(ri->options, (unsigned)*ri->options_count, ri->driver_name); } } diff --git a/src/src/transport.c b/src/src/transport.c index 869e87f16..8381913fc 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -120,7 +120,7 @@ readconf_options_from_list(optionlist_transports, nelem(optionlist_transports), for (ti = transports_available; ti->driver_name[0]; ti++) { - macro_create(string_sprintf("_DRVR_TPT_%T", ti->driver_name), US"y", FALSE); + macro_create(string_sprintf("_DRVR_TPT_%T", ti->driver_name), US"y", FALSE, TRUE); readconf_options_from_list(ti->options, (unsigned)*ti->options_count, ti->driver_name); } } diff --git a/test/confs/2100 b/test/confs/2100 index f61091683..bce339b19 100644 --- a/test/confs/2100 +++ b/test/confs/2100 @@ -6,6 +6,9 @@ SERVER= primary_hostname = myhost.test.ex +.ifdef _HAVE_TLS +# that was purely to trigger the lazy-create of builtin macros +.endif # ----- Main settings ----- acl_smtp_rcpt = accept