Refactor driver feature-macro generation to be driven by existing tables
[exim.git] / src / src / readconf.c
index 0a06559f48df83dfd3a16ccfe6faeb522a7d9e7c..29181cbcb29ad2dce6cf459e04218e84e2be41fa 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)
@@ -565,7 +566,7 @@ Arguments:
 Returns:       nothing
 */
 
-static void
+void
 read_macro_assignment(uschar *s)
 {
 uschar name[64];
@@ -1462,7 +1463,6 @@ int intbase = 0;
 uschar *inttype = US"";
 uschar *sptr;
 uschar *s = buffer;
-uschar *saved_condition, *strtemp;
 uschar **str_target;
 uschar name[64];
 uschar name2[64];
@@ -1597,19 +1597,18 @@ switch (type)
     control block and flags word. */
 
     case opt_stringptr:
-    if (data_block == NULL)
-      str_target = (uschar **)(ol->value);
-    else
-      str_target = (uschar **)((uschar *)data_block + (long int)(ol->value));
+    str_target = data_block ? USS (US data_block + (long int)(ol->value))
+                           : USS (ol->value);
     if (ol->type & opt_rep_con)
       {
+      uschar * saved_condition;
       /* We already have a condition, we're conducting a crude hack to let
       multiple condition rules be chained together, despite storing them in
       text form. */
-      saved_condition = *str_target;
-      strtemp = string_sprintf("${if and{{bool_lax{%s}}{bool_lax{%s}}}}",
-          saved_condition, sptr);
-      *str_target = string_copy_malloc(strtemp);
+      *str_target = string_copy_malloc( (saved_condition = *str_target)
+       ? string_sprintf("${if and{{bool_lax{%s}}{bool_lax{%s}}}}",
+           saved_condition, sptr)
+       : sptr);
       /* TODO(pdp): there is a memory leak here and just below
       when we set 3 or more conditions; I still don't
       understand the store mechanism enough to know
@@ -1645,10 +1644,10 @@ switch (type)
     break;
 
     case opt_rewrite:
-    if (data_block == NULL)
-      *((uschar **)(ol->value)) = sptr;
+    if (data_block)
+      *USS (US data_block + (long int)(ol->value)) = sptr;
     else
-      *((uschar **)((uschar *)data_block + (long int)(ol->value))) = sptr;
+      *USS (ol->value) = sptr;
     freesptr = FALSE;
     if (type == opt_rewrite)
       {
@@ -2626,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;
@@ -2728,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;
     }
   }
@@ -3012,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
@@ -3164,55 +3163,7 @@ due to conflicts with other common macros. */
   read_macro_assignment(US"_HAVE_LKUP_WHOSON=y");
 #endif
 
-#ifdef AUTH_CRAM_MD5
-  read_macro_assignment(US"_HAVE_AUTH_CRAM_MD5=y");
-#endif
-#ifdef AUTH_CYRUS_SASL
-  read_macro_assignment(US"_HAVE_AUTH_CYRUS_SASL=y");
-#endif
-#ifdef AUTH_DOVECOT
-  read_macro_assignment(US"_HAVE_AUTH_DOVECOT=y");
-#endif
-#ifdef AUTH_GSASL
-  read_macro_assignment(US"_HAVE_AUTH_GSASL=y");
-#endif
-#ifdef AUTH_HEIMDAL_GSSAPI
-  read_macro_assignment(US"_HAVE_AUTH_HEIMDAL_GSSAPI=y");
-#endif
-#ifdef AUTH_PLAINTEXT
-  read_macro_assignment(US"_HAVE_AUTH_PLAINTEXT=y");
-#endif
-#ifdef AUTH_SPA
-  read_macro_assignment(US"_HAVE_AUTH_SPA=y");
-#endif
-#ifdef AUTH_TLS
-  read_macro_assignment(US"_HAVE_AUTH_TLS=y");
-#endif
-
-#ifdef ROUTER_ACCEPT
-  read_macro_assignment(US"_HAVE_RTR_ACCEPT=y");
-#endif
-#ifdef ROUTER_DNSLOOKUP
-  read_macro_assignment(US"_HAVE_RTR_DNSLOOKUP=y");
-#endif
-#ifdef ROUTER_IPLITERAL
-  read_macro_assignment(US"_HAVE_RTR_IPLITERAL=y");
-#endif
-#ifdef ROUTER_IPLOOKUP
-  read_macro_assignment(US"_HAVE_RTR_IPLOOKUP=y");
-#endif
-#ifdef ROUTER_MANUALROUTE
-  read_macro_assignment(US"_HAVE_RTR_MANUALROUTE=y");
-#endif
-#ifdef ROUTER_QUERYPROGRAM
-  read_macro_assignment(US"_HAVE_RTR_QUERYPROGRAM=y");
-#endif
-#ifdef ROUTER_REDIRECT
-  read_macro_assignment(US"_HAVE_RTR_REDRCT=y");
-#endif
-
 #ifdef TRANSPORT_APPENDFILE
-  read_macro_assignment(US"_HAVE_TPT_APPENDFILE=y");
 # ifdef SUPPORT_MAILDIR
   read_macro_assignment(US"_HAVE_TPT_APPEND_MAILDR=y");
 # endif
@@ -3223,18 +3174,28 @@ due to conflicts with other common macros. */
   read_macro_assignment(US"_HAVE_TPT_APPEND_MBX=y");
 # endif
 #endif
-#ifdef TRANSPORT_AUTOREPLY
-  read_macro_assignment(US"_HAVE_TPT_AUTOREPLY=y");
-#endif
-#ifdef TRANSPORT_LMTP
-  read_macro_assignment(US"_HAVE_TPT_LMTP=y");
-#endif
-#ifdef TRANSPORT_PIPE
-  read_macro_assignment(US"_HAVE_TPT_PIPE=y");
-#endif
-#ifdef TRANSPORT_SMTP
-  read_macro_assignment(US"_HAVE_TPT_SMTP=y");
-#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 != '*')
+  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();
 }
 
 
@@ -3274,9 +3235,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))
@@ -4282,6 +4240,21 @@ 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++)
+  {
+  read_macro_assignment(string_sprintf("_DRVR_AUTH_%T=y", ai->driver_name));
+  readconf_options_from_list(ai->options, (unsigned)*ai->options_count, ai->driver_name);
+  }
+}
+
+
 /* Read the authenticators section of the configuration file.
 
 Arguments:   none
@@ -4292,6 +4265,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 */