From c0b9d3e87264ae274b37116103ecc9e1d1b0c647 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sun, 25 Sep 2016 22:59:36 +0100 Subject: [PATCH] Add automatic macros for config-file options. Bug 1819 --- doc/doc-txt/NewStuff | 3 ++- src/src/exim.c | 2 ++ src/src/functions.h | 7 +++++- src/src/globals.c | 2 +- src/src/readconf.c | 51 ++++++++++++++++++++++++++++++++++++-------- src/src/route.c | 10 +++++++++ src/src/string.c | 11 ++++++---- src/src/transport.c | 14 ++++++++++-- 8 files changed, 82 insertions(+), 18 deletions(-) diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index 33b726536..9d248bc02 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -38,7 +38,8 @@ Version 4.88 9. Expansion operator escape8bit, like escape but not touching newline etc.. 10. Feature macros, generated from compile options. All start with "_HAVE_" - and go on with some roughly recognisable name. Use the "-bP macros" + and go on with some roughly recognisable name. Option macros, for each + configuration-file option; all start with "_OPT_". Use the "-bP macros" command-line option to see what is present. 11. Integer values for options can take a "G" multiplier. diff --git a/src/src/exim.c b/src/src/exim.c index 91636fb30..a3606c753 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -1686,6 +1686,8 @@ 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 diff --git a/src/src/functions.h b/src/src/functions.h index 85a7e81eb..e3d19cd38 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -313,9 +313,14 @@ 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_print(uschar *, uschar *, BOOL no_labels); +extern void readconf_options_from_list(optionlist *, unsigned, 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 *); extern int readconf_readtime(const uschar *, int, BOOL); diff --git a/src/src/globals.c b/src/src/globals.c index 8d2010273..cb71a6094 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -35,7 +35,7 @@ optionlist optionlist_auths[] = { (void *)(offsetof(auth_instance, set_id)) } }; -int optionlist_auths_size = sizeof(optionlist_auths)/sizeof(optionlist); +int optionlist_auths_size = nelem(optionlist_auths); /* An empty host aliases list. */ diff --git a/src/src/readconf.c b/src/src/readconf.c index 3e82b7119..7a7299f2e 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -17,6 +17,7 @@ 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 @@ -513,7 +514,7 @@ int i; router_instance *r; transport_instance *t; -for (i = 0; i < optionlist_config_size; i++) +for (i = 0; i < nelem(optionlist_config); i++) if (p == optionlist_config[i].value) return US optionlist_config[i].name; for (r = routers; r; r = r->next) @@ -2624,11 +2625,11 @@ if (type == NULL) if (Ustrcmp(name, "all") == 0) { for (ol = optionlist_config; - ol < optionlist_config + optionlist_config_size; ol++) + ol < optionlist_config + nelem(optionlist_config); ol++) { if ((ol->type & opt_hidden) == 0) print_ol(ol, US ol->name, NULL, - optionlist_config, optionlist_config_size, + optionlist_config, nelem(optionlist_config), no_labels); } return; @@ -2726,8 +2727,8 @@ if (type == NULL) else { - print_ol(find_option(name, optionlist_config, optionlist_config_size), - name, NULL, optionlist_config, optionlist_config_size, no_labels); + print_ol(find_option(name, optionlist_config, nelem(optionlist_config)), + name, NULL, optionlist_config, nelem(optionlist_config), no_labels); return; } } @@ -3010,7 +3011,7 @@ return status == 0; /*************************************************/ /* Create compile-time feature macros */ -static void +void readconf_features(void) { /* Probably we could work out a static initialiser for wherever @@ -3236,6 +3237,28 @@ due to conflicts with other common macros. */ } +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 != '*') + read_macro_assignment(string_sprintf("_OPT_%T_%T=y", group, s)); +} + + +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 * *************************************************/ @@ -3272,9 +3295,6 @@ struct stat statbuf; uschar *s, *filename; const uschar *list = config_main_filelist; -/* First create compile-time feature macros */ -readconf_features(); - /* Loop through the possible file names */ while((filename = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)) @@ -4280,6 +4300,18 @@ 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"AU"); + +for (ai = auths_available; ai->driver_name[0]; ai++) + readconf_options_from_list(ai->options, (unsigned)*ai->options_count, ai->driver_name); +} + + /* Read the authenticators section of the configuration file. Arguments: none @@ -4290,6 +4322,7 @@ static void auths_init(void) { auth_instance *au, *bu; + readconf_driver_init(US"authenticator", (driver_instance **)(&auths), /* chain anchor */ (driver_info *)auths_available, /* available drivers */ diff --git a/src/src/route.c b/src/src/route.c index cd44389db..1764de853 100644 --- a/src/src/route.c +++ b/src/src/route.c @@ -143,6 +143,16 @@ optionlist optionlist_routers[] = { int optionlist_routers_size = sizeof(optionlist_routers)/sizeof(optionlist); +void +readconf_options_routers(void) +{ +struct router_info * ri; + +readconf_options_from_list(optionlist_routers, nelem(optionlist_routers), US"RT"); + +for (ri = routers_available; ri->driver_name[0]; ri++) + readconf_options_from_list(ri->options, (unsigned)*ri->options_count, ri->driver_name); +} /************************************************* * Set router pointer from name * diff --git a/src/src/string.c b/src/src/string.c index ad074e37e..b59ed668f 100644 --- a/src/src/string.c +++ b/src/src/string.c @@ -1212,10 +1212,10 @@ on whether the variable length list of data arguments are given explicitly or as a va_list item. The formats are the usual printf() ones, with some omissions (never used) and -two additions for strings: %S forces lower case, and %#s or %#S prints nothing -for a NULL string. Without the # "NULL" is printed (useful in debugging). There -is also the addition of %D and %M, which insert the date in the form used for -datestamped log files. +three additions for strings: %S forces lower case, %T forces upper case, and +%#s or %#S prints nothing for a NULL string. Without thr # "NULL" is printed +(useful in debugging). There is also the addition of %D and %M, which insert +the date in the form used for datestamped log files. Arguments: buffer a buffer in which to put the formatted string @@ -1428,6 +1428,7 @@ while (*fp != 0) case 's': case 'S': /* Forces *lower* case */ + case 'T': /* Forces *upper* case */ s = va_arg(ap, char *); if (s == NULL) s = null; @@ -1475,6 +1476,8 @@ while (*fp != 0) sprintf(CS p, "%*.*s", width, precision, s); if (fp[-1] == 'S') while (*p) { *p = tolower(*p); p++; } + else if (fp[-1] == 'T') + while (*p) { *p = toupper(*p); p++; } else while (*p) p++; if (!yield) goto END_FORMAT; diff --git a/src/src/transport.c b/src/src/transport.c index 6ec5f3720..330dd5b1d 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -108,10 +108,20 @@ optionlist optionlist_transports[] = { (void *)offsetof(transport_instance, uid) } }; -int optionlist_transports_size = - sizeof(optionlist_transports)/sizeof(optionlist); +int optionlist_transports_size = nelem(optionlist_transports); +void +readconf_options_transports(void) +{ +struct transport_info * ti; + +readconf_options_from_list(optionlist_transports, nelem(optionlist_transports), US"TP"); + +for (ti = transports_available; ti->driver_name[0]; ti++) + readconf_options_from_list(ti->options, (unsigned)*ti->options_count, ti->driver_name); +} + /************************************************* * Initialize transport list * *************************************************/ -- 2.30.2