Add automatic macros for config-file options. Bug 1819
authorJeremy Harris <jgh146exb@wizmail.org>
Sun, 25 Sep 2016 21:59:36 +0000 (22:59 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Sun, 25 Sep 2016 22:02:57 +0000 (23:02 +0100)
doc/doc-txt/NewStuff
src/src/exim.c
src/src/functions.h
src/src/globals.c
src/src/readconf.c
src/src/route.c
src/src/string.c
src/src/transport.c

index 33b726536780db2317104061633740fccdfd8913..9d248bc023b101aaaef7296701f7101546492d61 100644 (file)
@@ -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.
index 91636fb30fc16ddb1648b085dfb74b6166434b95..a3606c75314f6df00ea7e9002a4b9bd9a30b51b3 100644 (file)
@@ -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
index 85a7e81eb3044e0adc303ffdef2e0e968f829993..e3d19cd38b8eb51988522c9a8f2c9925b8949439 100644 (file)
@@ -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);
index 8d201027352483291ec141bf260102c9a9099d83..cb71a60949b56e063be1c84d3e1f0ef44bd42791 100644 (file)
@@ -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. */
 
index 3e82b71198f77f41c57e2ebaf01114f6bf6be1aa..7a7299f2ea021585913b4383a391dcc62ae9d56e 100644 (file)
@@ -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 */
index cd44389dbbfe1b267cccd424458b2556dde7e9f4..1764de853d6d8fe50be421207ad48e7cda12c386 100644 (file)
@@ -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          *
index ad074e37e152acd28e7e4782206fc84434e2508d..b59ed668f703c51856464591f0ab0edae9589d1b 100644 (file)
@@ -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;
index 6ec5f372096ec7f940541029c3b291ffbaecdeda..330dd5b1d927007186429c24ed3f47a575c58610 100644 (file)
@@ -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           *
 *************************************************/