common driver structs for routers
authorJeremy Harris <jgh146exb@wizmail.org>
Fri, 9 Aug 2024 22:12:24 +0000 (23:12 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Sat, 10 Aug 2024 14:29:43 +0000 (15:29 +0100)
27 files changed:
src/src/deliver.c
src/src/drtables.c
src/src/expand.c
src/src/functions.h
src/src/globals.c
src/src/globals.h
src/src/readconf.c
src/src/route.c
src/src/routers/accept.c
src/src/routers/accept.h
src/src/routers/dnslookup.c
src/src/routers/dnslookup.h
src/src/routers/ipliteral.c
src/src/routers/ipliteral.h
src/src/routers/manualroute.c
src/src/routers/manualroute.h
src/src/routers/queryprogram.c
src/src/routers/queryprogram.h
src/src/routers/redirect.c
src/src/routers/redirect.h
src/src/routers/rf_get_errors_address.c
src/src/routers/rf_get_munge_headers.c
src/src/routers/rf_get_ugid.c
src/src/routers/rf_lookup_hostlist.c
src/src/structs.h
src/src/transports/smtp.c
src/src/verify.c

index 67ba505d1a1d3a489eb9870dba394549e04be565..a4ec5f7980fb84be7dafcce7298f5da74cdf8e72 100644 (file)
@@ -903,10 +903,11 @@ const uschar * save_domain = deliver_domain;
 const uschar * save_local =  deliver_localpart;
 const uschar * save_host = deliver_host;
 const uschar * save_address = deliver_host_address;
-uschar * save_rn = router_name, * save_tn = transport_name;
+const uschar * save_rn = router_name;
+uschar * save_tn = transport_name;
 const int      save_port =   deliver_host_port;
 
-router_name =    addr->router ? addr->router->name : NULL;
+router_name =    addr->router ? addr->router->drinst.name : NULL;
 deliver_domain = addr->domain;
 deliver_localpart = addr->local_part;
 deliver_host =   addr->host_used ? addr->host_used->name : NULL;
@@ -1177,7 +1178,7 @@ if (msg)
 
 /* For a delivery from a system filter, there may not be a router */
 if (addr->router)
-  g = string_append(g, 2, US" R=", addr->router->name);
+  g = string_append(g, 2, US" R=", addr->router->drinst.name);
 
 g = string_append(g, 2, US" T=", addr->transport->name);
 
@@ -1329,7 +1330,7 @@ so nothing has been done at all, both variables contain null strings. */
 if (driver_name)
   {
   if (driver_kind[1] == 't' && addr->router)
-    g = string_append(g, 2, US" R=", addr->router->name);
+    g = string_append(g, 2, US" R=", addr->router->drinst.name);
   g = string_fmt_append(g, " %c=%s", toupper(driver_kind[1]), driver_name);
   }
 else if (driver_kind)
@@ -1406,7 +1407,7 @@ if (used_return_path && LOGGING(return_path_on_delivery))
   g = string_append(g, 3, US" P=<", used_return_path, US">");
 
 if (addr->router)
-  g = string_append(g, 2, US" R=", addr->router->name);
+  g = string_append(g, 2, US" R=", addr->router->drinst.name);
 if (addr->transport)
   g = string_append(g, 2, US" T=", addr->transport->name);
 
@@ -1487,7 +1488,7 @@ else if (driver_type == EXIM_DTYPE_ROUTER)
   {
   if (addr->router)
     {
-    driver_name = addr->router->name;
+    driver_name = addr->router->drinst.name;
     driver_kind = US" router";
     f.disable_logging = addr->router->disable_logging;
     }
@@ -2377,7 +2378,7 @@ if ((pid = exim_fork(US"delivery-local")) == 0)
     /* Setting these globals in the subprocess means we need never clear them */
 
     transport_name = tp->name;
-    if (addr->router) router_name = addr->router->name;
+    if (addr->router) router_name = addr->router->drinst.name;
     driver_srcfile = tp->srcfile;
     driver_srcline = tp->srcline;
 
@@ -2742,7 +2743,7 @@ while (addr_local)
     logflags |= LOG_PANIC;
     f.disable_logging = FALSE;  /* Jic */
     addr->message = addr->router
-      ? string_sprintf("No transport set by %s router", addr->router->name)
+      ? string_sprintf("No transport set by %s router", addr->router->drinst.name)
       : US"No transport set by system filter";
     post_process_one(addr, DEFER, logflags, EXIM_DTYPE_TRANSPORT, 0);
     continue;
@@ -4818,7 +4819,7 @@ do_remote_deliveries par_reduce par_wait par_read_pipe
     /* Setting these globals in the subprocess means we need never clear them */
 
     transport_name = tp->name;
-    if (addr->router) router_name = addr->router->name;
+    if (addr->router) router_name = addr->router->drinst.name;
     driver_srcfile = tp->srcfile;
     driver_srcline = tp->srcline;
 
@@ -6459,7 +6460,7 @@ for (const address_item * a = addr_succeed; a; a = a->next)
       "DSN: envid: %s  ret: %d\n"
       "DSN: Final recipient: %s\n"
       "DSN: Remote SMTP server supports DSN: %d\n",
-      a->router ? a->router->name : US"(unknown)",
+      a->router ? a->router->drinst.name : US"(unknown)",
       a->address,
       sender_address,
       a->dsn_orcpt ? a->dsn_orcpt : US"NULL",
index 9dd369a435deec500d09a6038b50d3db5c88a0ec..6f3cffe1ec2b2080b8f324f1b8bd96ec3ec8f372 100644 (file)
@@ -212,55 +212,55 @@ exim binary. */
 #include "routers/rf_functions.h"
 
 #ifdef ROUTER_ACCEPT
-#include "routers/accept.h"
+# include "routers/accept.h"
 #endif
 
 #ifdef ROUTER_DNSLOOKUP
-#include "routers/dnslookup.h"
+# include "routers/dnslookup.h"
 #endif
 
 #ifdef ROUTER_MANUALROUTE
-#include "routers/manualroute.h"
+# include "routers/manualroute.h"
 #endif
 
 #ifdef ROUTER_IPLITERAL
-#include "routers/ipliteral.h"
+# include "routers/ipliteral.h"
 #endif
 
 #ifdef ROUTER_IPLOOKUP
-#include "routers/iplookup.h"
+# include "routers/iplookup.h"
 #endif
 
 #ifdef ROUTER_QUERYPROGRAM
-#include "routers/queryprogram.h"
+# include "routers/queryprogram.h"
 #endif
 
 #ifdef ROUTER_REDIRECT
-#include "routers/redirect.h"
+# include "routers/redirect.h"
 #endif
 
 #ifdef TRANSPORT_APPENDFILE
-#include "transports/appendfile.h"
+# include "transports/appendfile.h"
 #endif
 
 #ifdef TRANSPORT_AUTOREPLY
-#include "transports/autoreply.h"
+# include "transports/autoreply.h"
 #endif
 
 #ifdef TRANSPORT_LMTP
-#include "transports/lmtp.h"
+# include "transports/lmtp.h"
 #endif
 
 #ifdef TRANSPORT_PIPE
-#include "transports/pipe.h"
+# include "transports/pipe.h"
 #endif
 
 #ifdef EXPERIMENTAL_QUEUEFILE
-#include "transports/queuefile.h"
+# include "transports/queuefile.h"
 #endif
 
 #ifdef TRANSPORT_SMTP
-#include "transports/smtp.h"
+# include "transports/smtp.h"
 #endif
 
 
@@ -269,12 +269,14 @@ exim binary. */
 router_info routers_available[] = {
 #ifdef ROUTER_ACCEPT
   {
-  .driver_name =       US"accept",
-  .options =           accept_router_options,
-  .options_count =     &accept_router_options_count,
-  .options_block =     &accept_router_option_defaults,
-  .options_len =       sizeof(accept_router_options_block),
-  .init =              accept_router_init,
+  .drinfo = {
+    .driver_name =     US"accept",
+    .options =         accept_router_options,
+    .options_count =   &accept_router_options_count,
+    .options_block =   &accept_router_option_defaults,
+    .options_len =     sizeof(accept_router_options_block),
+    .init =            accept_router_init,
+    },
   .code =              accept_router_entry,
   .tidyup =            NULL,     /* no tidyup entry */
   .ri_flags =          ri_yestransport
@@ -282,12 +284,14 @@ router_info routers_available[] = {
 #endif
 #ifdef ROUTER_DNSLOOKUP
   {
-  .driver_name =       US"dnslookup",
-  .options =           dnslookup_router_options,
-  .options_count =     &dnslookup_router_options_count,
-  .options_block =     &dnslookup_router_option_defaults,
-  .options_len =       sizeof(dnslookup_router_options_block),
-  .init =              dnslookup_router_init,
+  .drinfo = {
+    .driver_name =     US"dnslookup",
+    .options =         dnslookup_router_options,
+    .options_count =   &dnslookup_router_options_count,
+    .options_block =   &dnslookup_router_option_defaults,
+    .options_len =     sizeof(dnslookup_router_options_block),
+    .init =            dnslookup_router_init,
+    },
   .code =              dnslookup_router_entry,
   .tidyup =            NULL,     /* no tidyup entry */
   .ri_flags =          ri_yestransport
@@ -295,12 +299,14 @@ router_info routers_available[] = {
 #endif
 #ifdef ROUTER_IPLITERAL
   {
-  .driver_name =       US"ipliteral",
-  .options =           ipliteral_router_options,
-  .options_count =     &ipliteral_router_options_count,
-  .options_block =     &ipliteral_router_option_defaults,
-  .options_len =       sizeof(ipliteral_router_options_block),
-  .init =              ipliteral_router_init,
+  .drinfo = {
+    .driver_name =     US"ipliteral",
+    .options =         ipliteral_router_options,
+    .options_count =   &ipliteral_router_options_count,
+    .options_block =   &ipliteral_router_option_defaults,
+    .options_len =     sizeof(ipliteral_router_options_block),
+    .init =            ipliteral_router_init,
+    },
   .code =              ipliteral_router_entry,
   .tidyup =            NULL,     /* no tidyup entry */
   .ri_flags =          ri_yestransport
@@ -308,12 +314,14 @@ router_info routers_available[] = {
 #endif
 #ifdef ROUTER_IPLOOKUP
   {
-  .driver_name =       US"iplookup",
-  .options =           iplookup_router_options,
-  .options_count =     &iplookup_router_options_count,
-  .options_block =     &iplookup_router_option_defaults,
-  .options_len =       sizeof(iplookup_router_options_block),
-  .init =              iplookup_router_init,
+  .drinfo = {
+    .driver_name =     US"iplookup",
+    .options =         iplookup_router_options,
+    .options_count =   &iplookup_router_options_count,
+    .options_block =   &iplookup_router_option_defaults,
+    .options_len =     sizeof(iplookup_router_options_block),
+    .init =            iplookup_router_init,
+    },
   .code =              iplookup_router_entry,
   .tidyup =            NULL,     /* no tidyup entry */
   .ri_flags =          ri_notransport
@@ -321,12 +329,14 @@ router_info routers_available[] = {
 #endif
 #ifdef ROUTER_MANUALROUTE
   {
-  .driver_name =       US"manualroute",
-  .options =           manualroute_router_options,
-  .options_count =     &manualroute_router_options_count,
-  .options_block =     &manualroute_router_option_defaults,
-  .options_len =       sizeof(manualroute_router_options_block),
-  .init =              manualroute_router_init,
+  .drinfo = {
+    .driver_name =     US"manualroute",
+    .options =         manualroute_router_options,
+    .options_count =   &manualroute_router_options_count,
+    .options_block =   &manualroute_router_option_defaults,
+    .options_len =     sizeof(manualroute_router_options_block),
+    .init =            manualroute_router_init,
+    },
   .code =              manualroute_router_entry,
   .tidyup =            NULL,     /* no tidyup entry */
   .ri_flags =          0
@@ -334,12 +344,14 @@ router_info routers_available[] = {
 #endif
 #ifdef ROUTER_QUERYPROGRAM
   {
-  .driver_name =       US"queryprogram",
-  .options =           queryprogram_router_options,
-  .options_count =     &queryprogram_router_options_count,
-  .options_block =     &queryprogram_router_option_defaults,
-  .options_len =       sizeof(queryprogram_router_options_block),
-  .init =              queryprogram_router_init,
+  .drinfo = {
+    .driver_name =     US"queryprogram",
+    .options =         queryprogram_router_options,
+    .options_count =   &queryprogram_router_options_count,
+    .options_block =   &queryprogram_router_option_defaults,
+    .options_len =     sizeof(queryprogram_router_options_block),
+    .init =            queryprogram_router_init,
+    },
   .code =              queryprogram_router_entry,
   .tidyup =            NULL,     /* no tidyup entry */
   .ri_flags =          0
@@ -347,12 +359,14 @@ router_info routers_available[] = {
 #endif
 #ifdef ROUTER_REDIRECT
   {
-  .driver_name =       US"redirect",
-  .options =           redirect_router_options,
-  .options_count =     &redirect_router_options_count,
-  .options_block =     &redirect_router_option_defaults,
-  .options_len =       sizeof(redirect_router_options_block),
-  .init =              redirect_router_init,
+  .drinfo = {
+    .driver_name =     US"redirect",
+    .options =         redirect_router_options,
+    .options_count =   &redirect_router_options_count,
+    .options_block =   &redirect_router_option_defaults,
+    .options_len =     sizeof(redirect_router_options_block),
+    .init =            redirect_router_init,
+    },
   .code =              redirect_router_entry,
   .tidyup =            NULL,     /* no tidyup entry */
   .ri_flags =          ri_notransport
@@ -466,8 +480,8 @@ gstring *
 route_show_supported(gstring * g)
 {
 g = string_cat(g, US"Routers:");
-for (router_info * rr = routers_available; rr->driver_name[0]; rr++)
-               g = string_fmt_append(g, " %s", rr->driver_name);
+for (router_info * rr = routers_available; rr->drinfo.driver_name[0]; rr++)
+               g = string_fmt_append(g, " %s", rr->drinfo.driver_name);
 return string_cat(g, US"\n");
 }
 
@@ -555,8 +569,8 @@ lookup_list[pos] = info;
 
 
 /* These need to be at file level for old versions of gcc (2.95.2 reported),
- * which give parse errors on an extern in function scope.  Each entry needs
- * to also be invoked in init_lookup_list() below  */
+which give parse errors on an extern in function scope.  Each entry needs
+to also be invoked in init_lookup_list() below  */
 
 #if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
 extern lookup_module_info cdb_lookup_module_info;
index 4135574d6b7f90de130602a653494cd745fcdbc1..2ed802fd4f8374a3a0604612fb10cb465a81440d 100644 (file)
@@ -1044,9 +1044,10 @@ Returns:        TRUE if condition is met, FALSE if not
 */
 
 BOOL
-expand_check_condition(uschar *condition, uschar *m1, uschar *m2)
+expand_check_condition(const uschar * condition,
+  const uschar * m1, const uschar * m2)
 {
-uschar * ss = expand_string(condition);
+const uschar * ss = expand_cstring(condition);
 if (!ss)
   {
   if (!f.expand_string_forcedfail && !f.search_find_defer)
@@ -8701,16 +8702,16 @@ Returns:     OK     value placed in rvalue
 
 int
 exp_bool(address_item * addr,
-  uschar * mtype, uschar * mname, unsigned dbg_opt,
+  const uschar * mtype, const uschar * mname, unsigned dbg_opt,
   uschar * oname, BOOL bvalue,
-  uschar * svalue, BOOL * rvalue)
+  const uschar * svalue, BOOL * rvalue)
 {
-uschar * expanded;
+const uschar * expanded;
 
 DEBUG(D_expand) debug_printf("try option %s\n", oname);
 if (!svalue) { *rvalue = bvalue; return OK; }
 
-if (!(expanded = expand_string(svalue)))
+if (!(expanded = expand_cstring(svalue)))
   {
   if (f.expand_string_forcedfail)
     {
index 5d20bb2fcf91032ec286bd3a991ff93ca0c06aa2..884b6fd77019b42477efa84f3eed766d61528793 100644 (file)
@@ -263,10 +263,10 @@ extern void    exim_nullstd(void);
 extern void    exim_setugid(uid_t, gid_t, BOOL, const uschar *);
 extern void    exim_underbar_exit(int) NORETURN;
 extern void    exim_wait_tick(struct timeval *, int);
-extern int     exp_bool(address_item *addr,
-  uschar *mtype, uschar *mname, unsigned dgb_opt, uschar *oname, BOOL bvalue,
-  uschar *svalue, BOOL *rvalue);
-extern BOOL    expand_check_condition(uschar *, uschar *, uschar *);
+extern int     exp_bool(address_item *,
+  const uschar *, const uschar *, unsigned, uschar *, BOOL bvalue,
+  const uschar *, BOOL *);
+extern BOOL    expand_check_condition(const uschar *, const uschar *, const uschar *);
 extern uschar *expand_file_big_buffer(const uschar *);
 extern uschar *expand_string(uschar *);        /* public, cannot make const */
 extern const uschar *expand_string_2(const uschar *, BOOL *);
index 02349497f0f27bf93a725ad770b48de0bec5da22..6f43b97d8c59460093726bb00d614cd4673f5798 100644 (file)
@@ -1367,88 +1367,28 @@ uid_t   root_gid               = ROOT_GID;
 uid_t   root_uid               = ROOT_UID;
 
 router_instance  *routers  = NULL;
-router_instance  router_defaults = {
-    .next =                    NULL,
-    .name =                    NULL,
-    .info =                    NULL,
-    .options_block =           NULL,
-    .driver_name =             NULL,
 
-    .address_data =            NULL,
-#ifdef EXPERIMENTAL_BRIGHTMAIL
-    .bmi_rule =                        NULL,
-#endif
-    .cannot_route_message =    NULL,
-    .condition =               NULL,
-    .current_directory =       NULL,
-    .debug_string =            NULL,
-    .domains =                 NULL,
-    .errors_to =               NULL,
-    .expand_gid =              NULL,
-    .expand_uid =              NULL,
-    .expand_more =             NULL,
-    .expand_unseen =           NULL,
-    .extra_headers =           NULL,
-    .fallback_hosts =          NULL,
-    .home_directory =          NULL,
-    .ignore_target_hosts =     NULL,
-    .local_parts =             NULL,
-    .pass_router_name =                NULL,
-    .prefix =                  NULL,
-    .redirect_router_name =    NULL,
-    .remove_headers =          NULL,
-    .require_files =           NULL,
-    .router_home_directory =   NULL,
+/* All elements not mentioned will be 0/NULL/FALSE */
+router_instance  router_defaults = {
     .self =                    US"freeze",
-    .senders =                 NULL,
-    .suffix =                  NULL,
-    .translate_ip_address =    NULL,
-    .transport_name =          NULL,
 
     .address_test =            TRUE,
-#ifdef EXPERIMENTAL_BRIGHTMAIL
-    .bmi_deliver_alternate =   FALSE,
-    .bmi_deliver_default =     FALSE,
-    .bmi_dont_deliver =                FALSE,
-#endif
     .expn =                    TRUE,
-    .caseful_local_part =      FALSE,
-    .check_local_user =                FALSE,
-    .disable_logging =         FALSE,
-    .fail_verify_recipient =   FALSE,
-    .fail_verify_sender =      FALSE,
-    .gid_set =                 FALSE,
-    .initgroups =              FALSE,
     .log_as_local =            TRUE_UNSET,
     .more =                    TRUE,
-    .pass_on_timeout =         FALSE,
-    .prefix_optional =         FALSE,
     .repeat_use =              TRUE,
     .retry_use_local_part =    TRUE_UNSET,
-    .same_domain_copy_routing =        FALSE,
-    .self_rewrite =            FALSE,
-    .set =                     NULL,
-    .suffix_optional =         FALSE,
-    .verify_only =             FALSE,
     .verify_recipient =                TRUE,
     .verify_sender =           TRUE,
-    .uid_set =                 FALSE,
-    .unseen =                  FALSE,
-    .dsn_lasthop =             FALSE,
 
     .self_code =               self_freeze,
     .uid =                     (uid_t)(-1),
     .gid =                     (gid_t)(-1),
 
-    .fallback_hostlist =       NULL,
-    .transport =               NULL,
-    .pass_router =             NULL,
-    .redirect_router =         NULL,
-
     .dnssec =                   { .request= US"*", .require=NULL },
 };
 
-uschar *router_name            = NULL;
+const uschar *router_name      = NULL;
 tree_node *router_var         = NULL;
 
 ip_address_item *running_interfaces = NULL;
index 65eb4e4a582f14f7700179456167b9608c87ebb7..698bbd12f2114f6f41e53dd3e2dc182e1d977c35 100644 (file)
@@ -949,7 +949,7 @@ extern uid_t   root_uid;               /* The uid for root */
 extern router_info routers_available[];/* Vector of available routers */
 extern router_instance *routers;       /* Chain of instantiated routers */
 extern router_instance router_defaults;/* Default values */
-extern uschar *router_name;            /* Name of router last started */
+extern const uschar *router_name;      /* Name of router last started */
 extern tree_node *router_var;         /* Variables set by router */
 extern ip_address_item *running_interfaces; /* Host's running interfaces */
 extern uschar *running_status;         /* Flag string for testing */
index 940c5d4d3734e3dec15d26803c17287384884872..80b66a91020a768fbf91a9afd5ef63b2efdcdc0a 100644 (file)
@@ -615,85 +615,92 @@ for (optionlist * o = optionlist_config;         /* main-config options */
   if (listptr == o->v.value)
     return US o->name;
 
-for (router_instance * r = routers; r; r = r->next)
-  if (router_name && Ustrcmp(r->name, router_name) == 0)
-  {
-  const router_info * ri = r->info;
-
-  /* Check for a listptr match first */
-
-  for (optionlist * o = optionlist_routers;            /* generic options */
-      o < optionlist_routers + optionlist_routers_size; o++)
-    if (  (o->type & opt_mask) == opt_stringptr
-       && listptr == CS r + o->v.offset)
-      return US o->name;
-
-  for (optionlist * o = ri->options;                   /* private options */
-      o < ri->options + *ri->options_count; o++)
-    if (  (o->type & opt_mask) == opt_stringptr
-       && listptr == CS (r->options_block) + o->v.offset)
-      return US o->name;
-
-  /* Check for a list addr match, unless null */
-
-  if (!list) continue;
-
-  for (optionlist * o = optionlist_routers;            /* generic options */
-      o < optionlist_routers + optionlist_routers_size; o++)
-    if (  (o->type & opt_mask) == opt_stringptr
-       && list == * USS(CS r + o->v.offset))
-      if (name) return string_sprintf("DUP: %s %s vs. %s %s",
-       drname, name, r->name, o->name);
-      else { name = US o->name; drname = r->name; }
-
-  for (optionlist * o = ri->options;                   /* private options */
-      o < ri->options + *ri->options_count; o++)
-    if (  (o->type & opt_mask) == opt_stringptr
-       && list == * USS(CS (r->options_block) + o->v.offset))
-      if (name) return string_sprintf("DUP: %s %s vs. %s %s",
-       drname, name, r->name, o->name);
-      else { name = US o->name; drname = r->name; }
-  }
+if (router_name)
+  for (const driver_instance * rd = (driver_instance *)routers;
+       rd; rd = rd->next) if (Ustrcmp(rd->name, router_name) == 0)
+    {
+    const router_instance * r = (router_instance *)rd;
+    const router_info * ri = (router_info *)rd->info;
+
+    /* Check for a listptr match first */
+
+    for (optionlist * o = optionlist_routers;          /* generic options */
+       o < optionlist_routers + optionlist_routers_size; o++)
+      if (  (o->type & opt_mask) == opt_stringptr
+        && listptr == CS r + o->v.offset)
+       return US o->name;
+
+    for (optionlist * o = ri->drinfo.options;          /* private options */
+       o < ri->drinfo.options + *ri->drinfo.options_count; o++)
+      if (  (o->type & opt_mask) == opt_stringptr
+        && listptr == CS rd->options_block + o->v.offset)
+       return US o->name;
+
+    /* Check for a list addr match, unless null */
+
+    if (!list) continue;
+
+    for (optionlist * o = optionlist_routers;          /* generic options */
+       o < optionlist_routers + optionlist_routers_size; o++)
+      if (  (o->type & opt_mask) == opt_stringptr
+        && list == * USS(CS r + o->v.offset))
+       if (name)
+         return string_sprintf("DUP: %s %s vs. %s %s",
+                               drname, name, rd->name, o->name);
+       else
+         { name = US o->name; drname = rd->name; }
+
+    for (optionlist * o = ri->drinfo.options;          /* private options */
+       o < ri->drinfo.options + *ri->drinfo.options_count; o++)
+      if (  (o->type & opt_mask) == opt_stringptr
+        && list == * USS(CS rd->options_block + o->v.offset))
+       if (name)
+         return string_sprintf("DUP: %s %s vs. %s %s",
+                               drname, name, rd->name, o->name);
+       else
+         { name = US o->name; drname = rd->name; }
+    }
 
-for (transport_instance * t = transports; t; t = t->next)
-  if (transport_name && Ustrcmp(t->name, transport_name) == 0)
-  {
-  const transport_info * ti = t->info;
-
-  /* Check for a listptr match first */
-
-  for (optionlist * o = optionlist_transports;         /* generic options */
-      o < optionlist_transports + optionlist_transports_size; o++)
-    if (  (o->type & opt_mask) == opt_stringptr
-       && listptr == CS t + o->v.offset)
-      return US o->name;
-
-  for (optionlist * o = ti->options;                   /* private options */
-      o < ti->options + *ti->options_count; o++)
-    if (  (o->type & opt_mask) == opt_stringptr
-       && listptr == CS t->options_block + o->v.offset)
-      return US o->name;
-
-  /* Check for a list addr match, unless null */
-
-  if (!list) continue;
-
-  for (optionlist * o = optionlist_transports;         /* generic options */
-      o < optionlist_transports + optionlist_transports_size; o++)
-    if (  (o->type & opt_mask) == opt_stringptr
-       && list == * USS(CS t + o->v.offset))
-      if (name) return string_sprintf("DUP: %s %s vs. %s %s",
-       drname, name, t->name, o->name);
-      else { name = US o->name; drname = t->name; }
-
-  for (optionlist * o = ti->options;                   /* private options */
-      o < ti->options + *ti->options_count; o++)
-    if (  (o->type & opt_mask) == opt_stringptr
-       && list == * USS(CS t->options_block + o->v.offset))
-      if (name) return string_sprintf("DUP: %s %s vs. %s %s",
-       drname, name, t->name, o->name);
-      else { name = US o->name; drname = t->name; }
-  }
+if (transport_name)
+  for (transport_instance * t = transports; t; t = t->next)
+    if (Ustrcmp(t->name, transport_name) == 0)
+      {
+      const transport_info * ti = t->info;
+
+      /* Check for a listptr match first */
+
+      for (optionlist * o = optionlist_transports;             /* generic options */
+         o < optionlist_transports + optionlist_transports_size; o++)
+       if (  (o->type & opt_mask) == opt_stringptr
+          && listptr == CS t + o->v.offset)
+         return US o->name;
+
+      for (optionlist * o = ti->options;                       /* private options */
+         o < ti->options + *ti->options_count; o++)
+       if (  (o->type & opt_mask) == opt_stringptr
+          && listptr == CS t->options_block + o->v.offset)
+         return US o->name;
+
+      /* Check for a list addr match, unless null */
+
+      if (!list) continue;
+
+      for (optionlist * o = optionlist_transports;             /* generic options */
+         o < optionlist_transports + optionlist_transports_size; o++)
+       if (  (o->type & opt_mask) == opt_stringptr
+          && list == * USS(CS t + o->v.offset))
+         if (name) return string_sprintf("DUP: %s %s vs. %s %s",
+           drname, name, t->name, o->name);
+         else { name = US o->name; drname = t->name; }
+
+      for (optionlist * o = ti->options;                       /* private options */
+         o < ti->options + *ti->options_count; o++)
+       if (  (o->type & opt_mask) == opt_stringptr
+          && list == * USS(CS t->options_block + o->v.offset))
+         if (name) return string_sprintf("DUP: %s %s vs. %s %s",
+           drname, name, t->name, o->name);
+         else { name = US o->name; drname = t->name; }
+      }
 
 return name ? name : US"";
 }
@@ -3008,6 +3015,8 @@ if (names_only)
 for (; d; d = d->next)
   {
   BOOL rc = FALSE;
+  driver_info * di = d->info;
+
   if (!name)
     printf("\n%s %s:\n", d->name, type);
   else if (Ustrcmp(d->name, name) != 0) continue;
@@ -3016,11 +3025,11 @@ for (; d; d = d->next)
     if (!(ol->type & opt_hidden))
       rc |= print_ol(ol, US ol->name, d, ol2, size, no_labels);
 
-  for (optionlist * ol = d->info->options;
-       ol < d->info->options + *(d->info->options_count); ol++)
+  for (optionlist * ol = di->options;
+       ol < di->options + *di->options_count; ol++)
     if (!(ol->type & opt_hidden))
-      rc |= print_ol(ol, US ol->name, d, d->info->options,
-                   *d->info->options_count, no_labels);
+      rc |= print_ol(ol, US ol->name, d, di->options,
+                   *di->options_count, no_labels);
 
   if (name) return rc;
   }
@@ -3727,10 +3736,12 @@ return NULL;   /* never obeyed */
 static void
 driver_init_fini(driver_instance * d, const uschar * class)
 {
+driver_info * di = d->info;
+
 if (!d->driver_name)
   log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
     "no driver defined for %s \"%s\"", class, d->name);
-(d->info->init)(d);
+(di->init)(d);
 }
 
 
@@ -3826,7 +3837,7 @@ while ((buffer = get_config_line()))
     d = store_get_perm(instance_size, FALSE);
     memcpy(d, instance_default, instance_size);
     *p = d;
-    p = &d->next;
+    p = (driver_instance **)&d->next;
     d->name = string_copy(name);
     d->srcfile = config_filename;
     d->srcline = config_lineno; 
@@ -3865,8 +3876,11 @@ while ((buffer = get_config_line()))
   block. */
 
   else if (d->info)
-    readconf_handle_option(buffer, d->info->options,
-      *(d->info->options_count), d, US"option \"%s\" unknown");
+    {
+    driver_info * di = d->info;
+    readconf_handle_option(buffer, di->options,
+      *di->options_count, d, US"option \"%s\" unknown");
+    }
 
   /* The option is not generic and the driver name has not yet been given. */
 
@@ -3898,12 +3912,13 @@ Returns:   TRUE if a dependency is found
 */
 
 BOOL
-readconf_depends(driver_instance *d, uschar *s)
+readconf_depends(driver_instance * d, uschar * s)
 {
-int count = *(d->info->options_count);
-uschar *ss;
+driver_info * di = d->info;
+int count = *di->options_count;
+uschar * ss;
 
-for (optionlist * ol = d->info->options; ol < d->info->options + count; ol++)
+for (optionlist * ol = di->options; ol < di->options + count; ol++)
   if ((ol->type & opt_mask) == opt_stringptr)
     {
     void * options_block = ol->type & opt_public ? (void *)d : d->options_block;
index f42afd2efb885b4ee42ced44b0b5f12aec26ab58..c7ea67609e10c22bd83d35e8ac8659064bca8652 100644 (file)
@@ -64,7 +64,7 @@ optionlist optionlist_routers[] = {
   { "domains",            opt_stringptr|opt_public,
                  LOFF(domains) },
   { "driver",             opt_stringptr|opt_public,
-                 LOFF(driver_name) },
+                 LOFF(drinst.driver_name) },
   { "dsn_lasthop",        opt_bool|opt_public,
                  LOFF(dsn_lasthop) },
   { "errors_to",          opt_stringptr|opt_public,
@@ -159,11 +159,12 @@ uschar buf[64];
 
 options_from_list(optionlist_routers, nelem(optionlist_routers), US"ROUTERS", NULL);
 
-for (router_info * ri = routers_available; ri->driver_name[0]; ri++)
+for (router_info * ri = routers_available; ri->drinfo.driver_name[0]; ri++)
   {
-  spf(buf, sizeof(buf), US"_DRIVER_ROUTER_%T", ri->driver_name);
+  spf(buf, sizeof(buf), US"_DRIVER_ROUTER_%T", ri->drinfo.driver_name);
   builtin_macro_create(buf);
-  options_from_list(ri->options, (unsigned)*ri->options_count, US"ROUTER", ri->driver_name);
+  options_from_list(ri->drinfo.options, (unsigned)*ri->drinfo.options_count,
+                   US"ROUTER", ri->drinfo.driver_name);
   }
 }
 
@@ -191,9 +192,9 @@ set_router(router_instance *r, uschar *name, router_instance **ptr, BOOL after)
 BOOL afterthis = FALSE;
 router_instance *rr;
 
-for (rr = routers; rr; rr = rr->next)
+for (rr = routers; rr; rr = rr->drinst.next)
   {
-  if (Ustrcmp(name, rr->name) == 0)
+  if (Ustrcmp(name, rr->drinst.name) == 0)
     {
     *ptr = rr;
     break;
@@ -203,11 +204,11 @@ for (rr = routers; rr; rr = rr->next)
 
 if (!rr)
   log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
-    "new_router \"%s\" not found for \"%s\" router", name, r->name);
+    "new_router \"%s\" not found for \"%s\" router", name, r->drinst.name);
 
 if (after && !afterthis)
   log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
-    "new_router \"%s\" does not follow \"%s\" router", name, r->name);
+    "new_router \"%s\" does not follow \"%s\" router", name, r->drinst.name);
 }
 
 
@@ -235,9 +236,10 @@ readconf_driver_init(US"router",
   optionlist_routers,                 /* generic options */
   optionlist_routers_size);
 
-for (router_instance * r = routers; r; r = r->next)
+for (router_instance * r = routers; r; r = r->drinst.next)
   {
-  uschar *s = r->self;
+  uschar * s = r->self;
+  router_info * ri = r->drinst.info;
 
   /* If log_as_local is unset, its overall default is FALSE. (The accept
   router defaults it to TRUE.) */
@@ -246,14 +248,13 @@ for (router_instance * r = routers; r; r = r->next)
 
   /* Check for transport or no transport on certain routers */
 
-  if (  (r->info->ri_flags & ri_yestransport)
-     && !r->transport_name && !r->verify_only)
+  if (ri->ri_flags & ri_yestransport && !r->transport_name && !r->verify_only)
     log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "%s router:\n  "
-      "a transport is required for this router", r->name);
+      "a transport is required for this router", r->drinst.name);
 
-  if ((r->info->ri_flags & ri_notransport) && r->transport_name)
+  if (ri->ri_flags & ri_notransport && r->transport_name)
     log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "%s router:\n  "
-      "a transport must not be defined for this router", r->name);
+      "a transport must not be defined for this router", r->drinst.name);
 
   /* The "self" option needs to be decoded into a code value and possibly a
   new domain string and a rewrite boolean. */
@@ -278,7 +279,7 @@ for (router_instance * r = routers; r; r = r->next)
     }
 
   else log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s router:\n  "
-      "%s is not valid for the self option", r->name, s);
+      "%s is not valid for the self option", r->drinst.name, s);
 
   /* If any router has check_local_user set, default retry_use_local_part
   TRUE; otherwise its default is FALSE. */
@@ -325,8 +326,11 @@ is finished, via this function. */
 void
 route_tidyup(void)
 {
-for (router_instance * r = routers; r; r = r->next)
-  if (r->info->tidyup) (r->info->tidyup)(r);
+for (router_instance * r = routers; r; r = r->drinst.next)
+  {
+  router_info * ri = r->drinst.info;
+  if (ri->tidyup) (ri->tidyup)(r);
+  }
 }
 
 
@@ -463,9 +467,9 @@ Returns:         OK     item is in list
 */
 
 static int
-route_check_dls(uschar *rname, uschar *type, const uschar *list,
-  tree_node **anchorptr, unsigned int *cache_bits, int listtype,
-  const uschar *domloc, const uschar **ldata, BOOL caseless, uschar **perror)
+route_check_dls(const uschar * rname, const uschar * type, const uschar * list,
+  tree_node ** anchorptr, unsigned int * cache_bits, int listtype,
+  const uschar * domloc, const uschar ** ldata, BOOL caseless, uschar ** perror)
 {
 if (!list) return OK;   /* Empty list always succeeds */
 
@@ -863,6 +867,7 @@ check_router_conditions(router_instance * r, address_item * addr, int verify,
 int rc;
 uschar * check_local_part;
 unsigned int * localpart_cache;
+const uschar * rname = r->drinst.name;
 
 /* Reset variables to hold a home directory and data from lookup of a domain or
 local part, and ensure search_find_defer is unset, in case there aren't any
@@ -880,7 +885,7 @@ f.search_find_defer = FALSE;
 
 if ((verify == v_none || verify == v_expn) && r->verify_only)
   {
-  DEBUG(D_route) debug_printf("%s router skipped: verify_only set\n", r->name);
+  DEBUG(D_route) debug_printf("%s router skipped: verify_only set\n", rname);
   return SKIP;
   }
 
@@ -889,7 +894,7 @@ if ((verify == v_none || verify == v_expn) && r->verify_only)
 if (f.address_test_mode && !r->address_test)
   {
   DEBUG(D_route) debug_printf("%s router skipped: address_test is unset\n",
-    r->name);
+    rname);
   return SKIP;
   }
 
@@ -900,7 +905,7 @@ if ((verify == v_sender && !r->verify_sender) ||
     (verify == v_recipient && !r->verify_recipient))
   {
   DEBUG(D_route) debug_printf("%s router skipped: verify %d %d %d\n",
-    r->name, verify, r->verify_sender, r->verify_recipient);
+    rname, verify, r->verify_sender, r->verify_recipient);
   return SKIP;
   }
 
@@ -908,13 +913,13 @@ if ((verify == v_sender && !r->verify_sender) ||
 
 if (verify == v_expn && !r->expn)
   {
-  DEBUG(D_route) debug_printf("%s router skipped: no_expn set\n", r->name);
+  DEBUG(D_route) debug_printf("%s router skipped: no_expn set\n", rname);
   return SKIP;
   }
 
 /* Skip this router if there's a domain mismatch. */
 
-if ((rc = route_check_dls(r->name, US"domains", r->domains, &domainlist_anchor,
+if ((rc = route_check_dls(rname, US"domains", r->domains, &domainlist_anchor,
      addr->domain_cache, TRUE, addr->domain, CUSS &deliver_domain_data,
      MCL_DOMAIN, perror)) != OK)
   return rc;
@@ -938,7 +943,7 @@ else
     check_local_part[Ustrlen(check_local_part) - Ustrlen(addr->suffix)] = 0;
   }
 
-if ((rc = route_check_dls(r->name, US"local_parts", r->local_parts,
+if ((rc = route_check_dls(rname, US"local_parts", r->local_parts,
        &localpartlist_anchor, localpart_cache, MCL_LOCALPART,
        check_local_part, CUSS &deliver_localpart_data,
        !r->caseful_local_part, perror)) != OK)
@@ -956,7 +961,7 @@ if (r->check_local_user)
   if (!route_finduser(addr->local_part, pw, NULL))
     {
     DEBUG(D_route) debug_printf("%s router skipped: %s is not a local user\n",
-      r->name, addr->local_part);
+      rname, addr->local_part);
     return SKIP;
     }
   addr->prop.localpart_data =
@@ -994,7 +999,7 @@ if (r->router_home_directory)
 local user check so that $home is set - enabling the possibility of letting
 individual recipients specify lists of acceptable/unacceptable senders. */
 
-if ((rc = route_check_dls(r->name, US"senders", r->senders, NULL,
+if ((rc = route_check_dls(rname, US"senders", r->senders, NULL,
      sender_address_cache, MCL_ADDRESS, NULL, NULL, FALSE, perror)) != OK)
   return rc;
 
@@ -1008,7 +1013,7 @@ debug_print_string(r->debug_string);
 
 if ((rc = check_files(r->require_files, perror)) != OK)
   {
-  DEBUG(D_route) debug_printf("%s router %s: file check\n", r->name,
+  DEBUG(D_route) debug_printf("%s router %s: file check\n", rname,
     (rc == SKIP)? "skipped" : "deferred");
   return rc;
   }
@@ -1019,7 +1024,7 @@ if (r->condition)
   {
   DEBUG(D_route|D_expand)
     debug_printf("checking \"condition\" \"%.80s\"...\n", r->condition);
-  if (!expand_check_condition(r->condition, r->name, US"router"))
+  if (!expand_check_condition(r->condition, rname, US"router"))
     {
     if (f.search_find_defer)
       {
@@ -1028,7 +1033,7 @@ if (r->condition)
       return DEFER;
       }
     DEBUG(D_route)
-      debug_printf("%s router skipped: condition failure\n", r->name);
+      debug_printf("%s router skipped: condition failure\n", rname);
     return SKIP;
     }
   }
@@ -1041,7 +1046,7 @@ if (r->bmi_rule)
   if (bmi_check_rule(bmi_base64_verdict, r->bmi_rule) == 0)
     {    /* none of the rules fired */
     DEBUG(D_route)
-      debug_printf("%s router skipped: none of bmi_rule rules fired\n", r->name);
+      debug_printf("%s router skipped: none of bmi_rule rules fired\n", rname);
     return SKIP;
     }
   }
@@ -1050,7 +1055,7 @@ if (r->bmi_rule)
 if (r->bmi_dont_deliver && bmi_deliver == 1)
   {
   DEBUG(D_route)
-    debug_printf("%s router skipped: bmi_dont_deliver is FALSE\n", r->name);
+    debug_printf("%s router skipped: bmi_dont_deliver is FALSE\n", rname);
   return SKIP;
   }
 
@@ -1060,7 +1065,7 @@ if (  r->bmi_deliver_alternate
    )
   {
   DEBUG(D_route)
-    debug_printf("%s router skipped: bmi_deliver_alternate is FALSE\n", r->name);
+    debug_printf("%s router skipped: bmi_deliver_alternate is FALSE\n", rname);
   return SKIP;
   }
 
@@ -1070,7 +1075,7 @@ if (  r->bmi_deliver_default
    )
   {
   DEBUG(D_route)
-    debug_printf("%s router skipped: bmi_deliver_default is FALSE\n", r->name);
+    debug_printf("%s router skipped: bmi_deliver_default is FALSE\n", rname);
   return SKIP;
   }
 #endif
@@ -1355,8 +1360,9 @@ Returns:        nothing
 */
 
 static void
-route_unseen(uschar *name, address_item *addr, address_item **paddr_local,
-  address_item **paddr_remote, address_item **addr_new)
+route_unseen(const uschar * name, address_item * addr,
+  address_item **paddr_local, address_item ** paddr_remote,
+  address_item ** addr_new)
 {
 address_item *parent = deliver_make_addr(addr->address, TRUE);
 address_item *new = deliver_make_addr(addr->address, TRUE);
@@ -1392,17 +1398,16 @@ new->dsn_orcpt = addr->dsn_orcpt;
 
 
 /* As it has turned out, we haven't set headers_add or headers_remove for the
- * clone. Thinking about it, it isn't entirely clear whether they should be
- * copied from the original parent, like errors_address, or taken from the
- * unseen router, like address_data and the flags. Until somebody brings this
- * up, I propose to leave the code as it is.
- */
+clone. Thinking about it, it isn't entirely clear whether they should be
+copied from the original parent, like errors_address, or taken from the
+unseen router, like address_data and the flags. Until somebody brings this
+up, I propose to leave the code as it is.  */
 
 
 /* Set the cloned address to start at the next router, and put it onto the
 chain of new addresses. */
 
-new->start_router = addr->router->next;
+new->start_router = addr->router->drinst.next;
 new->next = *addr_new;
 *addr_new = new;
 
@@ -1439,6 +1444,7 @@ set_router_vars(address_item * addr, const router_instance * r)
 const uschar * varlist = r->set;
 tree_node ** root = (tree_node **) &addr->prop.variables;
 int sep = ';';
+const uschar * drname = r->drinst.name;
 
 GET_OPTION("set");
 if (!varlist) return OK;
@@ -1458,7 +1464,7 @@ for (uschar * ele; (ele = string_nextinlist(&varlist, &sep, NULL, 0)); )
   if (!name || name[0] != 'r' || name[1] != '_' || !name[2])
     {
     log_write(0, LOG_MAIN|LOG_PANIC,
-       "bad router variable name '%s' in router '%s'\n", name, r->name);
+       "bad router variable name '%s' in router '%s'\n", name, drname);
     return FAIL;
     }
   name += 2;
@@ -1476,7 +1482,7 @@ for (uschar * ele; (ele = string_nextinlist(&varlist, &sep, NULL, 0)); )
       /* Expand "more" if necessary; DEFER => an expansion failed */
 
       GET_OPTION("more");
-      yield = exp_bool(addr, US"router", r->name, D_route,
+      yield = exp_bool(addr, US"router", drname, D_route,
                      US"more", r->more, r->expand_more, &more);
       if (yield != OK) return yield;
 
@@ -1493,7 +1499,7 @@ for (uschar * ele; (ele = string_nextinlist(&varlist, &sep, NULL, 0)); )
     else
       {
       addr->message = string_sprintf("expansion of \"%s\" failed "
-       "in %s router: %s", ele, r->name, expand_string_message);
+       "in %s router: %s", ele, drname, expand_string_message);
       /* Caller will replace that for logging, if a DB lookup, to avoid exposing
       passwords */
       DEBUG(D_route) debug_printf("%s\n", addr->message);
@@ -1554,6 +1560,7 @@ int yield = OK;
 BOOL unseen;
 router_instance * r, * nextr;
 const uschar * old_domain = addr->domain;
+const uschar * rname_l;
 
 HDEBUG(D_route)
   {
@@ -1570,12 +1577,11 @@ for (r = addr->start_router ? addr->start_router : routers; r; r = nextr)
   uschar * error;
   struct passwd * pw = NULL;
   struct passwd pwcopy;
-  BOOL loop_detected = FALSE;
-  BOOL more;
-  int loopcount = 0;
-  int rc;
+  BOOL loop_detected = FALSE, more;
+  int loopcount = 0, rc;
 
-  DEBUG(D_route) debug_printf("--------> %s router <--------\n", r->name);
+  rname_l = r->drinst.name;
+  DEBUG(D_route) debug_printf("--------> %s router <--------\n", rname_l);
 
   /* Reset any search error message from the previous router. */
 
@@ -1589,7 +1595,7 @@ for (r = addr->start_router ? addr->start_router : routers; r; r = nextr)
   next router. */
 
   addr->router = r;
-  nextr = r->next;
+  nextr = r->drinst.next;
 
   /* Loop protection: If this address has an ancestor with the same address,
   and that ancestor was routed by this router, we skip this router. This
@@ -1625,7 +1631,7 @@ for (r = addr->start_router ? addr->start_router : routers; r; r = nextr)
       if (break_loop)
         {
         DEBUG(D_route) debug_printf("%s router skipped: previously routed %s\n",
-          r->name, parent->address);
+          rname_l, parent->address);
         loop_detected = TRUE;
         break;
         }
@@ -1680,8 +1686,8 @@ for (r = addr->start_router ? addr->start_router : routers; r; r = nextr)
       }
     else if (!r->prefix_optional)
       {
-      DEBUG(D_route) debug_printf("%s router skipped: prefix mismatch\n",
-        r->name);
+      DEBUG(D_route)
+       debug_printf("%s router skipped: prefix mismatch\n", rname_l);
       continue;
       }
     }
@@ -1704,8 +1710,8 @@ for (r = addr->start_router ? addr->start_router : routers; r; r = nextr)
       }
     else if (!r->suffix_optional)
       {
-      DEBUG(D_route) debug_printf("%s router skipped: suffix mismatch\n",
-        r->name);
+      DEBUG(D_route)
+       debug_printf("%s router skipped: suffix mismatch\n", rname_l);
       continue;
       }
     }
@@ -1713,9 +1719,9 @@ for (r = addr->start_router ? addr->start_router : routers; r; r = nextr)
   /* Set the expansion variables now that we have the affixes and the case of
   the local part sorted. */
 
-  router_name = r->name;
-  driver_srcfile = r->srcfile;
-  driver_srcline = r->srcline;
+  router_name = rname_l;
+  driver_srcfile = r->drinst.srcfile;
+  driver_srcline = r->drinst.srcline;
   deliver_set_expansions(addr);
 
   /* For convenience, the pre-router checks are in a separate function, which
@@ -1767,7 +1773,7 @@ for (r = addr->start_router ? addr->start_router : routers; r; r = nextr)
         /* Expand "more" if necessary; DEFER => an expansion failed */
 
        GET_OPTION("more");
-        yield = exp_bool(addr, US"router", r->name, D_route,
+        yield = exp_bool(addr, US"router", rname_l, D_route,
                        US"more", r->more, r->expand_more, &more);
         if (yield != OK) goto ROUTE_EXIT;
 
@@ -1785,7 +1791,7 @@ for (r = addr->start_router ? addr->start_router : routers; r; r = nextr)
       else
         {
         addr->message = string_sprintf("expansion of \"%s\" failed "
-          "in %s router: %s", r->address_data, r->name, expand_string_message);
+          "in %s router: %s", r->address_data, rname_l, expand_string_message);
         yield = DEFER;
         goto ROUTE_EXIT;
         }
@@ -1822,16 +1828,19 @@ for (r = addr->start_router ? addr->start_router : routers; r; r = nextr)
 
   /* Run the router, and handle the consequences. */
 
-  HDEBUG(D_route) debug_printf("calling %s router\n", r->name);
+  HDEBUG(D_route) debug_printf("calling %s router\n", rname_l);
 
-  yield = (r->info->code)(r, addr, pw, verify, paddr_local, paddr_remote,
-    addr_new, addr_succeed);
+    {
+    router_info * ri = r->drinst.info;
+    yield = (ri->code)(r, addr, pw, verify, paddr_local, paddr_remote,
+      addr_new, addr_succeed);
+    }
 
   driver_srcfile = router_name = NULL; driver_srcline = 0;
 
   if (yield == FAIL)
     {
-    HDEBUG(D_route) debug_printf("%s router forced address failure\n", r->name);
+    HDEBUG(D_route) debug_printf("%s router forced address failure\n", rname_l);
     goto ROUTE_EXIT;
     }
 
@@ -1843,7 +1852,7 @@ for (r = addr->start_router ? addr->start_router : routers; r; r = nextr)
        )
      && (yield == OK || yield == PASS))
     {
-    addr->message = string_sprintf("%s router forced verify failure", r->name);
+    addr->message = string_sprintf("%s router forced verify failure", rname_l);
     if (*paddr_remote == addr) *paddr_remote = addr->next;
     if (*paddr_local == addr) *paddr_local = addr->next;
     yield = FAIL;
@@ -1857,7 +1866,7 @@ for (r = addr->start_router ? addr->start_router : routers; r; r = nextr)
 
   HDEBUG(D_route)
     {
-    debug_printf("%s router %s for %s\n", r->name,
+    debug_printf("%s router %s for %s\n", rname_l,
       yield == PASS ? "passed" : "declined", addr->address);
     if (Ustrcmp(old_domain, addr->domain) != 0)
       debug_printf("domain %s rewritten\n", old_domain);
@@ -1876,7 +1885,7 @@ for (r = addr->start_router ? addr->start_router : routers; r; r = nextr)
     /* Expand "more" if necessary */
 
     GET_OPTION("more");
-    yield = exp_bool(addr, US"router", r->name, D_route,
+    yield = exp_bool(addr, US"router", rname_l, D_route,
                        US"more", r->more, r->expand_more, &more);
     if (yield != OK) goto ROUTE_EXIT;
 
@@ -1913,7 +1922,8 @@ if (!r)
        else
          if (!f.expand_string_forcedfail)
            log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand "
-             "cannot_route_message in %s router: %s", addr->router->name,
+             "cannot_route_message in %s router: %s",
+             addr->router->drinst.name,
              expand_string_message);
        }
       }
@@ -1927,7 +1937,7 @@ if (!r)
 if (yield == DEFER)
   {
   HDEBUG(D_route) debug_printf("%s router: defer for %s\n  message: %s\n",
-      r->name, addr->address, addr->message ? addr->message : US"<none>");
+      rname_l, addr->address, addr->message ? addr->message : US"<none>");
   goto ROUTE_EXIT;
   }
 
@@ -1937,7 +1947,7 @@ if (yield == DISCARD) goto ROUTE_EXIT;
 
 if (yield != OK && yield != REROUTED)
   log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s router returned unknown value %d",
-    r->name, yield);
+    rname_l, yield);
 
 /* If the yield was REROUTED, the router put a child address on the new chain
 as a result of a domain change of some sort (widening, typically). */
@@ -2016,14 +2026,14 @@ if (r->translate_ip_address)
 /* See if this is an unseen routing; first expand the option if necessary.
 DEFER can be given if the expansion fails */
 
-yield = exp_bool(addr, US"router", r->name, D_route,
+yield = exp_bool(addr, US"router", rname_l, D_route,
                US"unseen", r->unseen, r->expand_unseen, &unseen);
 if (yield != OK) goto ROUTE_EXIT;
 
 /* Debugging output recording a successful routing */
 
-HDEBUG(D_route) debug_printf("routed by %s router%s\n", r->name,
-    unseen? " (unseen)" : "");
+HDEBUG(D_route) debug_printf("routed by %s router%s\n", rname_l,
+    unseen ? " (unseen)" : "");
 
 DEBUG(D_route)
   {
@@ -2050,8 +2060,8 @@ DEBUG(D_route)
 the "unseen" option (ignore if there are no further routers). */
 
 addr->message = NULL;
-if (unseen && r->next)
-  route_unseen(r->name, addr, paddr_local, paddr_remote, addr_new);
+if (unseen && r->drinst.next)
+  route_unseen(rname_l, addr, paddr_local, paddr_remote, addr_new);
 
 /* Unset the address expansions, and return the final result. */
 
index c747a8ba31792c86bdafcec8be4eeedde9813c85..6cbde6decefbbbb92c3fb395268115f2e5ce53be 100644 (file)
@@ -39,7 +39,7 @@ accept_router_options_block accept_router_option_defaults = {
 #ifdef MACRO_PREDEF
 
 /* Dummy entries */
-void accept_router_init(router_instance *rblock) {}
+void accept_router_init(driver_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,
@@ -56,8 +56,10 @@ int accept_router_entry(router_instance *rblock, address_item *addr,
 /* Called for each instance, after its options have been read, to enable
 consistency checks to be done, or anything else that needs to be set up. */
 
-void accept_router_init(router_instance *rblock)
+void
+accept_router_init(driver_instance * r)
 {
+router_instance * rblock = (router_instance *)r;
 /*
 accept_router_options_block *ob =
   (accept_router_options_block *)(rblock->options_block);
@@ -111,7 +113,7 @@ uschar * remove_headers;
 header_line * extra_headers;
 
 DEBUG(D_route) debug_printf("%s router called for %s\n  domain = %s\n",
-  rblock->name, addr->address, addr->domain);
+  rblock->drinst.name, addr->address, addr->domain);
 
 /* Set up the errors address, if any. */
 
@@ -128,7 +130,7 @@ header munging. Initialization ensures that there is a transport except when
 verifying. */
 
 if (!rf_get_transport(rblock->transport_name, &(rblock->transport),
-  addr, rblock->name, NULL)) return DEFER;
+  addr, rblock->drinst.name, NULL)) return DEFER;
 
 addr->transport = rblock->transport;
 addr->prop.errors_address = errors_to;
index ca768b26e299a6a540da161a7dac272765e117c9..655056af1c1fd82cf63ecc76c61e87fcf89c2356 100644 (file)
@@ -27,6 +27,6 @@ extern int accept_router_entry(router_instance *, address_item *,
   struct passwd *, int, address_item **, address_item **,
   address_item **, address_item **);
 
-extern void accept_router_init(router_instance *);
+extern void accept_router_init(driver_instance *);
 
 /* End of routers/accept.h */
index ef82438183124026d69ef74df0b266308d25687b..8a6f72d5d65f270824628598338cad8f0d25b93d 100644 (file)
@@ -45,7 +45,7 @@ int dnslookup_router_options_count =
 
 /* Dummy entries */
 dnslookup_router_options_block dnslookup_router_option_defaults = {0};
-void dnslookup_router_init(router_instance *rblock) {}
+void dnslookup_router_init(driver_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,
@@ -83,7 +83,7 @@ dnslookup_router_options_block dnslookup_router_option_defaults = {
 consistency checks to be done, or anything else that needs to be set up. */
 
 void
-dnslookup_router_init(router_instance *rblock)
+dnslookup_router_init(driver_instance *rblock)
 {
 /*
 dnslookup_router_options_block *ob =
@@ -154,7 +154,7 @@ int rc;
 int widen_sep = 0;
 int whichrrs = HOST_FIND_BY_MX | HOST_FIND_BY_A | HOST_FIND_BY_AAAA;
 dnslookup_router_options_block * ob =
-  (dnslookup_router_options_block *)(rblock->options_block);
+  (dnslookup_router_options_block *)(rblock->drinst.options_block);
 uschar * srv_service = NULL, * widen = NULL;
 const uschar * pre_widen = addr->domain, * post_widen = NULL;
 const uschar * fully_qualified_name, * listptr;
@@ -162,7 +162,7 @@ uschar widen_buffer[256];
 
 DEBUG(D_route)
   debug_printf("%s router called for %s\n  domain = %s\n",
-    rblock->name, addr->address, addr->domain);
+    rblock->drinst.name, addr->address, addr->domain);
 
 /* If an SRV check is required, expand the service name */
 
@@ -172,7 +172,7 @@ if (ob->check_srv)
      && !f.expand_string_forcedfail)
     {
     addr->message = string_sprintf("%s router: failed to expand \"%s\": %s",
-      rblock->name, ob->check_srv, expand_string_message);
+      rblock->drinst.name, ob->check_srv, expand_string_message);
     return DEFER;
     }
   else
@@ -237,27 +237,27 @@ for (;;)
     /* not expanded so should never be tainted */
     widen = string_nextinlist(&listptr, &widen_sep, widen_buffer,
       sizeof(widen_buffer));
-    DEBUG(D_route) debug_printf("%s router widened %s to %s\n", rblock->name,
-      addr->domain, h.name);
+    DEBUG(D_route) debug_printf("%s router widened %s to %s\n",
+      rblock->drinst.name, addr->domain, h.name);
     }
   else if (post_widen)
     {
     h.name = post_widen;
     post_widen = NULL;
     DEBUG(D_route) debug_printf("%s router trying %s after widening failed\n",
-      rblock->name, h.name);
+      rblock->drinst.name, h.name);
     }
   else return DECLINE;
 
   /* Check if we must request only. or prefer, ipv4 */
 
   if (  ob->ipv4_only
-     && expand_check_condition(ob->ipv4_only, rblock->name, US"router"))
+     && expand_check_condition(ob->ipv4_only, rblock->drinst.name, US"router"))
     flags = flags & ~HOST_FIND_BY_AAAA | HOST_FIND_IPV4_ONLY;
   else if (f.search_find_defer)
     return DEFER;
   if (  ob->ipv4_prefer
-     && expand_check_condition(ob->ipv4_prefer, rblock->name, US"router"))
+     && expand_check_condition(ob->ipv4_prefer, rblock->drinst.name, US"router"))
     flags |= HOST_FIND_IPV4_FIRST;
   else if (f.search_find_defer)
     return DEFER;
@@ -314,7 +314,7 @@ for (;;)
 
       case OK:
       DEBUG(D_route) debug_printf("%s router rejected %s: no MX record(s)\n",
-        rblock->name, fully_qualified_name);
+        rblock->drinst.name, fully_qualified_name);
       continue;
       }
 
@@ -331,7 +331,7 @@ for (;;)
     if (rblock->pass_on_timeout)
       {
       DEBUG(D_route) debug_printf("%s router timed out, and pass_on_timeout is set\n",
-        rblock->name);
+        rblock->drinst.name);
       return PASS;
       }
     addr->message = US"host lookup did not complete";
@@ -351,7 +351,7 @@ for (;;)
 
       case OK:
        DEBUG(D_route) debug_printf("%s router: matched fail_defer_domains\n",
-         rblock->name);
+         rblock->drinst.name);
        addr->message = US"missing MX, or all MXs point to missing A records,"
          " and defer requested";
        return DEFER;
@@ -467,13 +467,12 @@ addr->host_list[0] = h;
 /* Fill in the transport and queue the address for delivery. */
 
 if (!rf_get_transport(rblock->transport_name, &(rblock->transport),
-      addr, rblock->name, NULL))
+      addr, rblock->drinst.name, NULL))
   return DEFER;
 
 addr->transport = rblock->transport;
 
-return rf_queue_add(addr, addr_local, addr_remote, rblock, pw)?
-  OK : DEFER;
+return rf_queue_add(addr, addr_local, addr_remote, rblock, pw) ?  OK : DEFER;
 }
 
 #endif /*!MACRO_PREDEF*/
index ce1daf3c0782adc2646097c96ec009337560a50c..41c671132cd7a24dbddf5b6693e99cf845ed6490 100644 (file)
@@ -38,6 +38,6 @@ extern int dnslookup_router_entry(router_instance *, address_item *,
   struct passwd *, int, address_item **, address_item **,
   address_item **, address_item **);
 
-extern void dnslookup_router_init(router_instance *);
+extern void dnslookup_router_init(driver_instance *);
 
 /* End of routers/dnslookup.h */
index 27c7fe6b34dde99993918c414655f369a7cb3b1f..790ef15f0816c52e4f3a96dc7d30268ca4455bd4 100644 (file)
@@ -37,7 +37,7 @@ ipliteral_router_options_block ipliteral_router_option_defaults = { 0 };
 #ifdef MACRO_PREDEF
 
 /* Dummy entries */
-void ipliteral_router_init(router_instance *rblock) {}
+void ipliteral_router_init(driver_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,
@@ -54,7 +54,7 @@ int ipliteral_router_entry(router_instance *rblock, address_item *addr,
 consistency checks to be done, or anything else that needs to be set up. */
 
 void
-ipliteral_router_init(router_instance *rblock)
+ipliteral_router_init(driver_instance *rblock)
 {
 /*
 ipliteral_router_options_block *ob =
@@ -119,7 +119,7 @@ int len = Ustrlen(domain);
 int rc, ipv;
 
 DEBUG(D_route) debug_printf("%s router called for %s: domain = %s\n",
-  rblock->name, addr->address, addr->domain);
+  rblock->drinst.name, addr->address, addr->domain);
 
 /* Check that the domain is an IP address enclosed in square brackets. Remember
 to allow for the "official" form of IPv6 addresses. If not, the router
@@ -191,8 +191,8 @@ just verifying, there need not be a transport, in which case it doesn't matter
 which queue we put the address on. This is all now handled by the route_queue()
 function. */
 
-if (!rf_get_transport(rblock->transport_name, &(rblock->transport),
-      addr, rblock->name, NULL))
+if (!rf_get_transport(rblock->transport_name, &rblock->transport,
+      addr, rblock->drinst.name, NULL))
   return DEFER;
 
 addr->transport = rblock->transport;
index 7db24cfd13ad6bcaa3440c2b1978e55cdb8dae7f..897fd298a4f27e132e8c9ad67231e96e48195a18 100644 (file)
@@ -30,6 +30,6 @@ extern int ipliteral_router_entry(router_instance *, address_item *,
   struct passwd *, int, address_item **, address_item **,
   address_item **, address_item **);
 
-extern void ipliteral_router_init(router_instance *);
+extern void ipliteral_router_init(driver_instance *);
 
 /* End of routers/ipliteral.h */
index d07ea3490f1cf7eb71a547f80a33419b99747317..e2062bc8e063064c14aa5e87070d02153f62ed1f 100644 (file)
@@ -43,7 +43,7 @@ int manualroute_router_options_count =
 
 /* Dummy entries */
 manualroute_router_options_block manualroute_router_option_defaults = {0};
-void manualroute_router_init(router_instance *rblock) {}
+void manualroute_router_init(driver_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,
@@ -91,7 +91,7 @@ static int hff_count= sizeof(hff_codes)/sizeof(int);
 consistency checks to be done, or anything else that needs to be set up. */
 
 void
-manualroute_router_init(router_instance *rblock)
+manualroute_router_init(driver_instance *rblock)
 {
 manualroute_router_options_block *ob =
   (manualroute_router_options_block *)(rblock->options_block);
@@ -245,14 +245,14 @@ const uschar *hostlist = NULL;
 const uschar *domain;
 uschar *newhostlist;
 const uschar *listptr;
-manualroute_router_options_block *ob =
-  (manualroute_router_options_block *)(rblock->options_block);
+manualroute_router_options_block * ob =
+  (manualroute_router_options_block *)(rblock->drinst.options_block);
 transport_instance *transport = NULL;
 BOOL individual_transport_set = FALSE;
 BOOL randomize = ob->hosts_randomize;
 
 DEBUG(D_route) debug_printf("%s router called for %s\n  domain = %s\n",
-  rblock->name, addr->address, addr->domain);
+  rblock->drinst.name, addr->address, addr->domain);
 
 /* The initialization check ensures that either route_list or route_data is
 set. */
@@ -318,7 +318,7 @@ if (!newhostlist)
   {
   if (f.expand_string_forcedfail) return DECLINE;
   addr->message = string_sprintf("%s router: failed to expand \"%s\": %s",
-    rblock->name, hostlist, expand_string_message);
+    rblock->drinst.name, hostlist, expand_string_message);
   return DEFER;
   }
 else hostlist = newhostlist;
@@ -360,7 +360,7 @@ while (*options)
     if (!t)
       {
       s = string_sprintf("unknown routing option or transport name \"%s\"", s);
-      log_write(0, LOG_MAIN, "Error in %s router: %s", rblock->name, s);
+      log_write(0, LOG_MAIN, "Error in %s router: %s", rblock->drinst.name, s);
       addr->message = string_sprintf("error in router: %s", s);
       return DEFER;
       }
@@ -390,8 +390,8 @@ set. */
 
 if (!individual_transport_set)
   {
-  if (!rf_get_transport(rblock->transport_name, &(rblock->transport), addr,
-      rblock->name, NULL))
+  if (!rf_get_transport(rblock->transport_name, &rblock->transport, addr,
+      rblock->drinst.name, NULL))
     return DEFER;
   transport = rblock->transport;
   }
@@ -420,8 +420,7 @@ if (transport && transport->info->local)
   rf_queue_add() function. */
 
   addr->transport = transport;
-  return rf_queue_add(addr, addr_local, addr_remote, rblock, pw)?
-    OK : DEFER;
+  return rf_queue_add(addr, addr_local, addr_remote, rblock, pw) ?  OK : DEFER;
   }
 
 /* There is either no transport (verify_only) or a remote transport. A host
@@ -432,7 +431,7 @@ if (!hostlist[0])
   {
   if (verify != v_none) goto ROUTED;
   addr->message = string_sprintf("error in %s router: no host(s) specified "
-    "for domain %s", rblock->name, addr->domain);
+    "for domain %s", rblock->drinst.name, addr->domain);
   log_write(0, LOG_MAIN, "%s", addr->message);
   return DEFER;
   }
@@ -460,7 +459,8 @@ if (!addr->host_list)
     if (ob->hai_code == hff_codes[i]) break;
 
   addr->message = string_sprintf("lookup failed for all hosts in %s router: "
-    "host_find_failed=ignore host_all_ignored=%s", rblock->name, hff_names[i]);
+    "host_find_failed=ignore host_all_ignored=%s",
+    rblock->drinst.name, hff_names[i]);
 
   if (ob->hai_code == hff_defer) return DEFER;
   if (ob->hai_code == hff_fail) return FAIL;
@@ -476,7 +476,7 @@ dealt with above. However, we don't need one if verifying only. */
 if (!transport && verify == v_none)
     {
     log_write(0, LOG_MAIN, "Error in %s router: no transport defined",
-      rblock->name);
+      rblock->drinst.name);
     addr->message = US"error in router: transport missing";
     return DEFER;
     }
index 1201c8362963b635c6443149586331bb38eb644a..dc2745769e5a13e235fb324718d38568680373aa 100644 (file)
@@ -35,6 +35,6 @@ extern int manualroute_router_entry(router_instance *, address_item *,
   struct passwd *, int, address_item **, address_item **,
   address_item **, address_item **);
 
-extern void manualroute_router_init(router_instance *);
+extern void manualroute_router_init(driver_instance *);
 
 /* End of routers/manualroute.h */
index 235d0e769033949fb9043d1944ac76117e7f5f5f..83ffe239a548e0fbbf0b80374d5d001c3a175a23 100644 (file)
@@ -49,7 +49,7 @@ int queryprogram_router_options_count =
 
 /* Dummy entries */
 queryprogram_router_options_block queryprogram_router_option_defaults = {0};
-void queryprogram_router_init(router_instance *rblock) {}
+void queryprogram_router_init(driver_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,
@@ -82,7 +82,7 @@ queryprogram_router_options_block queryprogram_router_option_defaults = {
 consistency checks to be done, or anything else that needs to be set up. */
 
 void
-queryprogram_router_init(router_instance *rblock)
+queryprogram_router_init(driver_instance * rblock)
 {
 queryprogram_router_options_block *ob =
   (queryprogram_router_options_block *)(rblock->options_block);
@@ -142,11 +142,11 @@ while (generated != NULL)
 
   if (addr->child_count == USHRT_MAX)
     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s router generated more than %d "
-      "child addresses for <%s>", rblock->name, USHRT_MAX, addr->address);
+      "child addresses for <%s>", rblock->drinst.name, USHRT_MAX, addr->address);
   addr->child_count++;
 
   DEBUG(D_route)
-    debug_printf("%s router generated %s\n", rblock->name, next->address);
+    debug_printf("%s router generated %s\n", rblock->drinst.name, next->address);
   }
 }
 
@@ -215,8 +215,8 @@ uschar buffer[1024];
 const uschar **argvptr;
 uschar *rword, *rdata, *s;
 address_item_propagated addr_prop;
-queryprogram_router_options_block *ob =
-  (queryprogram_router_options_block *)(rblock->options_block);
+queryprogram_router_options_block * ob =
+  (queryprogram_router_options_block *)(rblock->drinst.options_block);
 uschar *current_directory = ob->current_directory;
 ugid_block ugid;
 uid_t curr_uid = getuid();
@@ -227,7 +227,7 @@ uid_t *puid = &uid;
 gid_t *pgid = &gid;
 
 DEBUG(D_route) debug_printf("%s router called for %s: domain = %s\n",
-  rblock->name, addr->address, addr->domain);
+  rblock->drinst.name, addr->address, addr->domain);
 
 ugid.uid_set = ugid.gid_set = FALSE;
 
@@ -249,8 +249,8 @@ if (rc != OK) return rc;
 (initialization ensures that one or the other is set). */
 
 if (  !ob->cmd_uid_set
-   && !route_find_expanded_user(ob->expand_cmd_uid, rblock->name, US"router",
-       &upw, &uid, &(addr->message)))
+   && !route_find_expanded_user(ob->expand_cmd_uid, rblock->drinst.name,
+       US"router", &upw, &uid, &(addr->message)))
     return DEFER;
 
 /* Get the fixed or expanded gid, or take the gid from the passwd entry. */
@@ -258,7 +258,7 @@ if (  !ob->cmd_uid_set
 if (!ob->cmd_gid_set)
   if (ob->expand_cmd_gid)
     {
-    if (route_find_expanded_group(ob->expand_cmd_gid, rblock->name,
+    if (route_find_expanded_group(ob->expand_cmd_gid, rblock->drinst.name,
         US"router", &gid, &(addr->message)))
       return DEFER;
     }
@@ -267,7 +267,7 @@ if (!ob->cmd_gid_set)
   else
     {
     addr->message = string_sprintf("command_user set without command_group "
-      "for %s router", rblock->name);
+      "for %s router", rblock->drinst.name);
     return DEFER;
     }
 
@@ -305,7 +305,7 @@ if ((pid = child_open_uid(argvptr, NULL, 0077, puid, pgid, &fd_in, &fd_out,
                          current_directory, TRUE, US"queryprogram-cmd")) < 0)
   {
   addr->message = string_sprintf("%s router couldn't create child process: %s",
-    rblock->name, strerror(errno));
+    rblock->drinst.name, strerror(errno));
   return DEFER;
   }
 
@@ -320,22 +320,22 @@ if ((rc = child_close(pid, ob->timeout)) != 0)
   {
   if (rc > 0)
     addr->message = string_sprintf("%s router: command returned non-zero "
-      "code %d", rblock->name, rc);
+      "code %d", rblock->drinst.name, rc);
 
   else if (rc == -256)
     {
     addr->message = string_sprintf("%s router: command timed out",
-      rblock->name);
+      rblock->drinst.name);
     killpg(pid, SIGKILL);       /* Kill the whole process group */
     }
 
   else if (rc == -257)
     addr->message = string_sprintf("%s router: wait() failed: %s",
-      rblock->name, strerror(errno));
+      rblock->drinst.name, strerror(errno));
 
   else
     addr->message = string_sprintf("%s router: command killed by signal %d",
-      rblock->name, -rc);
+      rblock->drinst.name, -rc);
 
   return DEFER;
   }
@@ -350,7 +350,7 @@ len = read(fd_out, buffer, sizeof(buffer) - 1);
 if (len <= 0)
   {
   addr->message = string_sprintf("%s router: command failed to return data",
-    rblock->name);
+    rblock->drinst.name);
   return DEFER;
   }
 
@@ -394,7 +394,7 @@ if (strcmpic(rword, US"REDIRECT") == 0)
     &addr->message,              /* where to put messages */
     NULL,                        /* don't skip syntax errors */
     &filtertype,                 /* not used; will always be FILTER_FORWARD */
-    string_sprintf("%s router", rblock->name));
+    string_sprintf("%s router", rblock->drinst.name));
 
   switch (rc)
     {
@@ -456,7 +456,7 @@ if (strcmpic(rword, US"accept") != 0)
   else if (strcmpic(rword, US"defer") != 0)
     {
     addr->message = string_sprintf("bad command yield: %s %s", rword, rdata);
-    log_write(0, LOG_PANIC, "%s router: %s", rblock->name, addr->message);
+    log_write(0, LOG_PANIC, "%s router: %s", rblock->drinst.name, addr->message);
     }
   return DEFER;
   }
@@ -479,7 +479,7 @@ if ((s = expand_getkeyed(US"transport", rdata)) && *s)
     {
     addr->message = string_sprintf("unknown transport name %s yielded by "
       "command", s);
-    log_write(0, LOG_PANIC, "%s router: %s", rblock->name, addr->message);
+    log_write(0, LOG_PANIC, "%s router: %s", rblock->drinst.name, addr->message);
     return DEFER;
     }
   addr->transport = transport;
@@ -492,7 +492,7 @@ the last argument not being NULL. */
 else
   {
   if (!rf_get_transport(rblock->transport_name, &rblock->transport, addr,
-       rblock->name, US"transport"))
+       rblock->drinst.name, US"transport"))
     return DEFER;
   addr->transport = rblock->transport;
   }
@@ -512,7 +512,7 @@ if ((s = expand_getkeyed(US"hosts", rdata)) && *s)
       {
       addr->message = string_sprintf("bad lookup type \"%s\" yielded by "
         "command", ss);
-      log_write(0, LOG_PANIC, "%s router: %s", rblock->name, addr->message);
+      log_write(0, LOG_PANIC, "%s router: %s", rblock->drinst.name, addr->message);
       return DEFER;
       }
     }
index f2cff1dabbb701ab4eefa436a07848174a9b152b..67c0ba7bc4b64e9710cc55b07505c65fa98b7664 100644 (file)
@@ -36,6 +36,6 @@ extern int queryprogram_router_entry(router_instance *, address_item *,
   struct passwd *, int, address_item **, address_item **,
   address_item **, address_item **);
 
-extern void queryprogram_router_init(router_instance *);
+extern void queryprogram_router_init(driver_instance *);
 
 /* End of routers/queryprogram.h */
index 4da658781a5105d220565d88186a47e884545271..97e609413b5bef4f4e7d13e5909a5dc0120c34a4 100644 (file)
@@ -112,7 +112,7 @@ int redirect_router_options_count =
 
 /* Dummy entries */
 redirect_router_options_block redirect_router_option_defaults = {0};
-void redirect_router_init(router_instance *rblock) {}
+void redirect_router_init(driver_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,
@@ -141,17 +141,19 @@ redirect_router_options_block redirect_router_option_defaults = {
 /* Called for each instance, after its options have been read, to enable
 consistency checks to be done, or anything else that needs to be set up. */
 
-void redirect_router_init(router_instance *rblock)
+void
+redirect_router_init(driver_instance * r)
 {
-redirect_router_options_block *ob =
-  (redirect_router_options_block *)(rblock->options_block);
+router_instance * rblock = (router_instance *)r;
+redirect_router_options_block * ob =
+  (redirect_router_options_block *)(r->options_block);
 
 /* Either file or data must be set, but not both */
 
 if ((ob->file == NULL) == (ob->data == NULL))
   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s router:\n  "
     "%sone of \"file\" or \"data\" must be specified",
-    rblock->name, (ob->file == NULL)? "" : "only ");
+    r->name, ob->file ? "only " : "");
 
 /* Onetime aliases can only be real addresses. Headers can't be manipulated.
 The combination of one_time and unseen is not allowed. We can't check the
@@ -164,10 +166,10 @@ if (ob->one_time)
   if (rblock->extra_headers || rblock->remove_headers)
     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s router:\n  "
       "\"headers_add\" and \"headers_remove\" are not permitted with "
-      "\"one_time\"", rblock->name);
+      "\"one_time\"", r->name);
   if (rblock->unseen || rblock->expand_unseen)
     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s router:\n  "
-      "\"unseen\" may not be used with \"one_time\"", rblock->name);
+      "\"unseen\" may not be used with \"one_time\"", r->name);
   }
 
 /* The defaults for check_owner and check_group depend on other settings. The
@@ -188,7 +190,7 @@ if (ob->check_group == TRUE_UNSET)
 if (ob->qualify_domain && ob->qualify_preserve_domain)
   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s router:\n  "
     "only one of \"qualify_domain\" or \"qualify_preserve_domain\" must be set",
-    rblock->name);
+    r->name);
 
 /* If allow_filter is set, either user or check_local_user must be set. */
 
@@ -198,7 +200,7 @@ if (!rblock->check_local_user &&
     (ob->bit_options & RDO_FILTER) != 0)
   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s router:\n  "
     "\"user\" or \"check_local_user\" must be set with \"allow_filter\"",
-    rblock->name);
+    r->name);
 }
 
 
@@ -275,8 +277,8 @@ add_generated(router_instance *rblock, address_item **addr_new,
   address_item *addr, address_item *generated,
   address_item_propagated *addr_prop, ugid_block *ugidptr, struct passwd *pw)
 {
-redirect_router_options_block *ob =
-  (redirect_router_options_block *)(rblock->options_block);
+redirect_router_options_block * ob =
+  (redirect_router_options_block *)(rblock->drinst.options_block);
 
 while (generated)
   {
@@ -288,7 +290,7 @@ while (generated)
   next->start_router = rblock->redirect_router;
   if (addr->child_count == USHRT_MAX)
     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s router generated more than %d "
-      "child addresses for <%s>", rblock->name, USHRT_MAX, addr->address);
+      "child addresses for <%s>", rblock->drinst.name, USHRT_MAX, addr->address);
   addr->child_count++;
 
   next->next = *addr_new;
@@ -370,7 +372,7 @@ while (generated)
       address_pipe = next->address;
       GET_OPTION("pipe_transport");
       if (rf_get_transport(ob->pipe_transport_name, &ob->pipe_transport,
-          next, rblock->name, US"pipe_transport"))
+          next, rblock->drinst.name, US"pipe_transport"))
         next->transport = ob->pipe_transport;
       address_pipe = NULL;
       }
@@ -378,7 +380,7 @@ while (generated)
       {
       GET_OPTION("reply_transport");
       if (rf_get_transport(ob->reply_transport_name, &ob->reply_transport,
-          next, rblock->name, US"reply_transport"))
+          next, rblock->drinst.name, US"reply_transport"))
         next->transport = ob->reply_transport;
       }
     else  /* must be file or directory */
@@ -389,7 +391,7 @@ while (generated)
         {
        GET_OPTION("directory_transport");
         if (rf_get_transport(ob->directory_transport_name,
-            &(ob->directory_transport), next, rblock->name,
+            &ob->directory_transport, next, rblock->drinst.name,
             US"directory_transport"))
           next->transport = ob->directory_transport;
         }
@@ -397,7 +399,7 @@ while (generated)
        {
        GET_OPTION("file_transport");
         if (rf_get_transport(ob->file_transport_name, &ob->file_transport,
-            next, rblock->name, US"file_transport"))
+            next, rblock->drinst.name, US"file_transport"))
           next->transport = ob->file_transport;
        }
 
@@ -414,7 +416,7 @@ while (generated)
   DEBUG(D_route)
     {
     debug_printf("%s router generated %s\n  %serrors_to=%s transport=%s\n",
-      rblock->name,
+      rblock->drinst.name,
       next->address,
       testflag(next, af_pfr)? "pipe, file, or autoreply\n  " : "",
       next->prop.errors_address,
@@ -478,8 +480,8 @@ int redirect_router_entry(
   address_item **addr_new,        /* put new addresses on here */
   address_item **addr_succeed)    /* put old address here on success */
 {
-redirect_router_options_block *ob =
-  (redirect_router_options_block *)(rblock->options_block);
+redirect_router_options_block * ob =
+  (redirect_router_options_block *)(rblock->drinst.options_block);
 address_item *generated = NULL;
 const uschar *save_qualify_domain_recipient = qualify_domain_recipient;
 uschar *discarded = US"discarded";
@@ -525,13 +527,13 @@ can't be found in the password file. Other errors set the freezing bit. */
 
 if (!rf_get_ugid(rblock, addr, &ugid)) return DEFER;
 
-if (!ugid.uid_set && pw != NULL)
+if (!ugid.uid_set && pw)
   {
   ugid.uid = pw->pw_uid;
   ugid.uid_set = TRUE;
   }
 
-if (!ugid.gid_set && pw != NULL)
+if (!ugid.gid_set && pw)
   {
   ugid.gid = pw->pw_gid;
   ugid.gid_set = TRUE;
@@ -575,8 +577,8 @@ sieve.enotify_mailto_owner = ob->sieve_enotify_mailto_owner;
 
 frc = rda_interpret(&redirect, options, ob->include_directory, &sieve, &ugid,
   &generated, &addr->message, ob->skip_syntax_errors ? &eblock : NULL,
-  &filtertype, string_sprintf("%s router (recipient is %s)", rblock->name,
-  addr->address));
+  &filtertype, string_sprintf("%s router (recipient is %s)",
+  rblock->drinst.name, addr->address));
 
 qualify_domain_recipient = save_qualify_domain_recipient;
 
@@ -701,7 +703,7 @@ dealing with it, the router declines. */
 if (eblock != NULL)
   {
   if (!moan_skipped_syntax_errors(
-        rblock->name,                            /* For message content */
+        rblock->drinst.name,                    /* For message content */
         eblock,                                  /* Ditto */
         (verify != v_none || f.address_test_mode)?
           NULL : ob->syntax_errors_to,           /* Who to mail */
@@ -738,7 +740,7 @@ if (frc == FF_DELIVERED)
   if (generated == NULL && verify == v_none && !f.address_test_mode)
     {
     log_write(0, LOG_MAIN, "=> %s <%s> R=%s", discarded, addr->address,
-      rblock->name);
+      rblock->drinst.name);
     yield = DISCARD;
     }
   }
@@ -769,7 +771,7 @@ else
   next->prop = addr_prop;
 
   DEBUG(D_route) debug_printf("%s router autogenerated %s\n%s%s%s",
-    rblock->name,
+    rblock->drinst.name,
     next->address,
     (addr_prop.errors_address != NULL)? "  errors to " : "",
     (addr_prop.errors_address != NULL)? addr_prop.errors_address : US"",
index 86c24d80c0d9a467e6b2ba011306b024e8e2db76..f36db1600d236689ea44f02126e61f778e0e3715 100644 (file)
@@ -69,6 +69,6 @@ extern int redirect_router_entry(router_instance *, address_item *,
   struct passwd *, int, address_item **, address_item **,
   address_item **, address_item **);
 
-extern void redirect_router_init(router_instance *);
+extern void redirect_router_init(driver_instance *);
 
 /* End of routers/redirect.h */
index 6f8f7c7c30865c70d1173f5427612b95954fc540..6593ef2b6ede6e728d3d619f8097ea632b24a5f8 100644 (file)
@@ -53,7 +53,7 @@ if (!(s = expand_string(rblock->errors_to)))
     return OK;
     }
   addr->message = string_sprintf("%s router failed to expand \"%s\": %s",
-    rblock->name, rblock->errors_to, expand_string_message);
+    rblock->drinst.name, rblock->errors_to, expand_string_message);
   return DEFER;
   }
 
index 58b5bc7ad92a749a03cb1a810a684cb0ae15b4b5..a9cffab72fcdcec4f5cfb3ee512f16b5dc1c1153 100644 (file)
@@ -50,7 +50,7 @@ if (rblock->extra_headers)
        {
        addr->message = string_sprintf(
          "%s router failed to expand add_headers item \"%s\": %s",
-         rblock->name, t, expand_string_message);
+         rblock->drinst.name, t, expand_string_message);
        return DEFER;
        }
       }
@@ -105,7 +105,7 @@ if (rblock->remove_headers)
        {
        addr->message = string_sprintf(
          "%s router failed to expand remove_headers item \"%s\": %s",
-         rblock->name, t, expand_string_message);
+         rblock->drinst.name, t, expand_string_message);
        return DEFER;
        }
       }
index cefe527a530d1201c64c7d2cc68825b5e4c6082c..a0197b409cf5be6b17dee7595eb24d55bb80d43e 100644 (file)
@@ -41,20 +41,22 @@ ugid->initgroups = rblock->initgroups;
 /* If there is no fixed uid set, see if there's a dynamic one that can
 be expanded and possibly looked up. */
 
-if (!ugid->uid_set && rblock->expand_uid != NULL)
+if (!ugid->uid_set && rblock->expand_uid)
   {
-  if (route_find_expanded_user(rblock->expand_uid, rblock->name, US"router",
-    &upw, &(ugid->uid), &(addr->message))) ugid->uid_set = TRUE;
-  else return FALSE;
+  if (!route_find_expanded_user(rblock->expand_uid, rblock->drinst.name,
+                             US"router", &upw, &ugid->uid, &addr->message))
+    return FALSE;
+  ugid->uid_set = TRUE;
   }
 
 /* Likewise for the gid */
 
-if (!ugid->gid_set && rblock->expand_gid != NULL)
+if (!ugid->gid_set && rblock->expand_gid)
   {
-  if (route_find_expanded_group(rblock->expand_gid, rblock->name, US"router",
-    &(ugid->gid), &(addr->message))) ugid->gid_set = TRUE;
-  else return FALSE;
+  if (!route_find_expanded_group(rblock->expand_gid, rblock->drinst.name,
+                             US"router", &ugid->gid, &addr->message))
+    return FALSE;
+  ugid->gid_set = TRUE;
   }
 
 /* If a uid is set, then a gid must also be available; use one from the passwd
@@ -62,7 +64,7 @@ lookup if it happened. */
 
 if (ugid->uid_set && !ugid->gid_set)
   {
-  if (upw != NULL)
+  if (upw)
     {
     ugid->gid = upw->pw_gid;
     ugid->gid_set = TRUE;
@@ -70,7 +72,7 @@ if (ugid->uid_set && !ugid->gid_set)
   else
     {
     addr->message = string_sprintf("user set without group for %s router",
-      rblock->name);
+      rblock->drinst.name);
     return FALSE;
     }
   }
index f10ff59218ee72093a0b71c44c4506ed32081877..54a614e05821333e1eebb9ccf7d4cbfdca767aa2 100644 (file)
@@ -174,7 +174,7 @@ for (host_item * prev = NULL, * h = addr->host_list, *next_h; h; h = next_h)
       {
       DEBUG(D_route)
         debug_printf("%s router timed out and pass_on_timeout set\n",
-          rblock->name);
+          rblock->drinst.name);
       return PASS;
       }
     addr->message = string_sprintf("host lookup for %s did not complete "
@@ -199,7 +199,7 @@ for (host_item * prev = NULL, * h = addr->host_list, *next_h; h; h = next_h)
     addr->basic_errno = ERRNO_UNKNOWNHOST;
     addr->message =
       string_sprintf("lookup of host \"%s\" failed in %s router%s",
-        h->name, rblock->name,
+        h->name, rblock->drinst.name,
         f.host_find_failed_syntax? ": syntax error in name" : "");
 
     if (hff_code == hff_defer) return DEFER;
index 95a1c10997cccf64ad2723d2978c77091961d380..ddebd18d5168eb04ed261e404a435733ca1ee9e4 100644 (file)
@@ -130,9 +130,9 @@ three, the layout of the start of the blocks is kept the same, and represented
 by the generic structures driver_info and driver_instance. */
 
 typedef struct driver_instance {
-  struct driver_instance *next;
+  void   *next;
   uschar *name;                   /* Instance name */
-  struct driver_info *info;       /* Points to info for this driver */
+  void   *info;                          /* Points to info for this driver */
   void   *options_block;          /* Pointer to private options */
 
   uschar *driver_name;            /* All start with this generic option */
@@ -148,7 +148,7 @@ typedef struct driver_info {
   void   *options_block;          /* Points to default private block */
   int     options_len;            /* Length of same in bytes */
   void  (*init)(                  /* Initialization entry point */
-    struct driver_instance *);
+         struct driver_instance *);
 } driver_info;
 
 
@@ -286,13 +286,7 @@ typedef struct {
 /* Structure for holding information about the configured routers. */
 
 typedef struct router_instance {
-  struct router_instance *next;
-  uschar *name;
-  struct router_info *info;
-  void   *options_block;          /* Pointer to private options */
-  uschar *driver_name;            /* Must be first */
-  const uschar *srcfile;
-  int    srcline;
+  driver_instance drinst;
 
   uschar *address_data;           /* Arbitrary data */
 #ifdef EXPERIMENTAL_BRIGHTMAIL
@@ -369,18 +363,12 @@ typedef struct router_instance {
 } router_instance;
 
 
-/* Structure for holding information about a type of router. The first six
-fields must match driver_info above. */
+/* Structure for holding information about a type of router.  The first element
+must be a struct driver_info, to match auths and transports. */
 
 typedef struct router_info {
-  uschar *driver_name;
-  optionlist *options;            /* Table of private options names */
-  int    *options_count;          /* -> Number of entries in table */
-  void   *options_block;          /* Points to default private block */
-  int     options_len;            /* Length of same in bytes */
-  void (*init)(                   /* Initialization function */
-    struct router_instance *);
-/****/
+  driver_info drinfo;
+
   int (*code)(                    /* Main entry point */
     router_instance *,
     struct address_item *,
index 03de9dcaddf887d91e23e2a0019a89bf706ee128..f80afbc0af2aaa52ddaaafb13c0049afda051d9c 100644 (file)
@@ -672,7 +672,8 @@ deferred_event_raise(address_item * addr, host_item * host, uschar * evstr)
 {
 uschar * action = addr->transport->event_action;
 const uschar * save_domain, * save_local;
-uschar * save_rn, * save_tn;
+const uschar * save_rn;
+uschar * save_tn;
 
 if (!action)
   return;
@@ -687,7 +688,7 @@ deliver_host_address = string_copy(host->address);
 deliver_host_port =    host->port == PORT_NONE ? 25 : host->port;
 event_defer_errno =    addr->basic_errno;
 
-router_name =    addr->router->name;
+router_name =    addr->router->drinst.name;
 transport_name = addr->transport->name;
 deliver_domain = addr->domain;
 deliver_localpart = addr->local_part;
index 25fc700f94560f820a763455344cb648e7a8b560..ad6b0afaf1d86fd9e09a112f9d9f0d4012fb5481 100644 (file)
@@ -2235,7 +2235,7 @@ for (addr_list = addr_local, i = 0; i < 2; addr_list = addr_remote, i++)
     /* Show router, and transport */
 
     fprintf(fp, "router = %s, transport = %s\n",
-      addr->router->name, tp ? tp->name : US"unset");
+      addr->router->drinst.name, tp ? tp->name : US"unset");
 
     /* Show any hosts that are set up by a router unless the transport
     is going to override them; fiddle a bit to get a nice format. */