[exim-cvs] Use dedicated union member for option offsets

トップ ページ
このメッセージを削除
このメッセージに返信
著者: Exim Git Commits Mailing List
日付:  
To: exim-cvs
題目: [exim-cvs] Use dedicated union member for option offsets
Gitweb: https://git.exim.org/exim.git/commitdiff/13a4b4c1810a1a9f3c956f1e92807a0d86c6f5bf
Commit:     13a4b4c1810a1a9f3c956f1e92807a0d86c6f5bf
Parent:     a73f05479a4bed3bf77d21a75da9515c4ae83a62
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Tue Jan 21 16:47:56 2020 +0000
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Tue Jan 21 16:47:56 2020 +0000


    Use dedicated union member for option offsets
---
 src/src/auths/cram_md5.c        |   6 +-
 src/src/auths/cyrus_sasl.c      |   8 +-
 src/src/auths/dovecot.c         |   6 +-
 src/src/auths/gsasl_exim.c      |  49 ++++-----
 src/src/auths/heimdal_gssapi.c  |   6 +-
 src/src/auths/plaintext.c       |   6 +-
 src/src/auths/spa.c             |   8 +-
 src/src/auths/tls.c             |   8 +-
 src/src/globals.c               |  18 ++--
 src/src/local_scan.h            |   8 +-
 src/src/readconf.c              |  76 +++++++------
 src/src/route.c                 | 121 ++++++++++-----------
 src/src/routers/dnslookup.c     |  40 +++----
 src/src/routers/iplookup.c      |  16 +--
 src/src/routers/manualroute.c   |  12 +--
 src/src/routers/queryprogram.c  |  18 ++--
 src/src/routers/redirect.c      | 142 ++++++++++--------------
 src/src/transport.c             |  65 +++++------
 src/src/transports/appendfile.c | 172 ++++++++++-------------------
 src/src/transports/autoreply.c  |  55 ++++------
 src/src/transports/lmtp.c       |  12 +--
 src/src/transports/pipe.c       |  86 ++++++---------
 src/src/transports/queuefile.c  |   2 +-
 src/src/transports/smtp.c       | 233 ++++++++++++++--------------------------
 24 files changed, 480 insertions(+), 693 deletions(-)


diff --git a/src/src/auths/cram_md5.c b/src/src/auths/cram_md5.c
index a60db56..4b4602f 100644
--- a/src/src/auths/cram_md5.c
+++ b/src/src/auths/cram_md5.c
@@ -25,11 +25,11 @@ program. */

 optionlist auth_cram_md5_options[] = {
   { "client_name",        opt_stringptr,
-      (void *)(offsetof(auth_cram_md5_options_block, client_name)) },
+      OPT_OFF(auth_cram_md5_options_block, client_name) },
   { "client_secret",      opt_stringptr,
-      (void *)(offsetof(auth_cram_md5_options_block, client_secret)) },
+      OPT_OFF(auth_cram_md5_options_block, client_secret) },
   { "server_secret",      opt_stringptr,
-      (void *)(offsetof(auth_cram_md5_options_block, server_secret)) }
+      OPT_OFF(auth_cram_md5_options_block, server_secret) }
 };


/* Size of the options list. An extern variable has to be used so that its
diff --git a/src/src/auths/cyrus_sasl.c b/src/src/auths/cyrus_sasl.c
index 37e7898..bb6c02c 100644
--- a/src/src/auths/cyrus_sasl.c
+++ b/src/src/auths/cyrus_sasl.c
@@ -38,13 +38,13 @@ static void dummy(int x) { dummy2(x-1); }

 optionlist auth_cyrus_sasl_options[] = {
   { "server_hostname",      opt_stringptr,
-      (void *)(offsetof(auth_cyrus_sasl_options_block, server_hostname)) },
+      OPT_OFF(auth_cyrus_sasl_options_block, server_hostname) },
   { "server_mech",          opt_stringptr,
-      (void *)(offsetof(auth_cyrus_sasl_options_block, server_mech)) },
+      OPT_OFF(auth_cyrus_sasl_options_block, server_mech) },
   { "server_realm",         opt_stringptr,
-      (void *)(offsetof(auth_cyrus_sasl_options_block, server_realm)) },
+      OPT_OFF(auth_cyrus_sasl_options_block, server_realm) },
   { "server_service",       opt_stringptr,
-      (void *)(offsetof(auth_cyrus_sasl_options_block, server_service)) }
+      OPT_OFF(auth_cyrus_sasl_options_block, server_service) }
 };


/* Size of the options list. An extern variable has to be used so that its
diff --git a/src/src/auths/dovecot.c b/src/src/auths/dovecot.c
index a83fdfd..c337510 100644
--- a/src/src/auths/dovecot.c
+++ b/src/src/auths/dovecot.c
@@ -51,10 +51,8 @@ The cost is the length of an array of pointers on the stack.

 /* Options specific to the authentication mechanism. */
 optionlist auth_dovecot_options[] = {
-       {
-       "server_socket",
-       opt_stringptr,
-       (void *)(offsetof(auth_dovecot_options_block, server_socket))
+       { "server_socket", opt_stringptr,
+     OPT_OFF(auth_dovecot_options_block, server_socket)
        },
 };


diff --git a/src/src/auths/gsasl_exim.c b/src/src/auths/gsasl_exim.c
index 1c4af92..b50c780 100644
--- a/src/src/auths/gsasl_exim.c
+++ b/src/src/auths/gsasl_exim.c
@@ -54,42 +54,29 @@ static void dummy(int x) { dummy2(x-1); }
 we only ever handle one mechanism at a time, I didn't see the point in keeping
 that.  In case someone sees a point, I've left the condition_check() API
 alone. */
+#define LOFF(field) OPT_OFF(auth_gsasl_options_block, field)
+
 optionlist auth_gsasl_options[] = {
-  { "client_authz",        opt_stringptr,
-      (void *)(offsetof(auth_gsasl_options_block, client_authz)) },
-  { "client_channelbinding",    opt_bool,
-      (void *)(offsetof(auth_gsasl_options_block, client_channelbinding)) },
-  { "client_password",        opt_stringptr,
-      (void *)(offsetof(auth_gsasl_options_block, client_password)) },
-  { "client_spassword",        opt_stringptr,
-      (void *)(offsetof(auth_gsasl_options_block, client_spassword)) },
-  { "client_username",        opt_stringptr,
-      (void *)(offsetof(auth_gsasl_options_block, client_username)) },
-
-  { "server_channelbinding",    opt_bool,
-      (void *)(offsetof(auth_gsasl_options_block, server_channelbinding)) },
-  { "server_hostname",        opt_stringptr,
-      (void *)(offsetof(auth_gsasl_options_block, server_hostname)) },
+  { "client_authz",        opt_stringptr,    LOFF(client_authz) },
+  { "client_channelbinding",    opt_bool,    LOFF(client_channelbinding) },
+  { "client_password",        opt_stringptr,    LOFF(client_password) },
+  { "client_spassword",        opt_stringptr,    LOFF(client_spassword) },
+  { "client_username",        opt_stringptr,    LOFF(client_username) },
+
+  { "server_channelbinding",    opt_bool,    LOFF(server_channelbinding) },
+  { "server_hostname",        opt_stringptr,    LOFF(server_hostname) },
 #ifdef EXIM_GSASL_SCRAM_S_KEY
-  { "server_key",        opt_stringptr,
-      (void *)(offsetof(auth_gsasl_options_block, server_key)) },
+  { "server_key",        opt_stringptr,    LOFF(server_key) },
 #endif
-  { "server_mech",        opt_stringptr,
-      (void *)(offsetof(auth_gsasl_options_block, server_mech)) },
-  { "server_password",        opt_stringptr,
-      (void *)(offsetof(auth_gsasl_options_block, server_password)) },
-  { "server_realm",        opt_stringptr,
-      (void *)(offsetof(auth_gsasl_options_block, server_realm)) },
-  { "server_scram_iter",    opt_stringptr,
-      (void *)(offsetof(auth_gsasl_options_block, server_scram_iter)) },
-  { "server_scram_salt",    opt_stringptr,
-      (void *)(offsetof(auth_gsasl_options_block, server_scram_salt)) },
+  { "server_mech",        opt_stringptr,    LOFF(server_mech) },
+  { "server_password",        opt_stringptr,    LOFF(server_password) },
+  { "server_realm",        opt_stringptr,    LOFF(server_realm) },
+  { "server_scram_iter",    opt_stringptr,    LOFF(server_scram_iter) },
+  { "server_scram_salt",    opt_stringptr,    LOFF(server_scram_salt) },
 #ifdef EXIM_GSASL_SCRAM_S_KEY
-  { "server_skey",        opt_stringptr,
-      (void *)(offsetof(auth_gsasl_options_block, server_s_key)) },
+  { "server_skey",        opt_stringptr,    LOFF(server_s_key) },
 #endif
-  { "server_service",        opt_stringptr,
-      (void *)(offsetof(auth_gsasl_options_block, server_service)) }
+  { "server_service",        opt_stringptr,    LOFF(server_service) }
 };


 int auth_gsasl_options_count =
diff --git a/src/src/auths/heimdal_gssapi.c b/src/src/auths/heimdal_gssapi.c
index 82eb6a3..f6d09d5 100644
--- a/src/src/auths/heimdal_gssapi.c
+++ b/src/src/auths/heimdal_gssapi.c
@@ -59,11 +59,11 @@ static void dummy(int x) { dummy2(x-1); }
 /* Authenticator-specific options. */
 optionlist auth_heimdal_gssapi_options[] = {
   { "server_hostname",      opt_stringptr,
-      (void *)(offsetof(auth_heimdal_gssapi_options_block, server_hostname)) },
+      OPT_OFF(auth_heimdal_gssapi_options_block, server_hostname) },
   { "server_keytab",        opt_stringptr,
-      (void *)(offsetof(auth_heimdal_gssapi_options_block, server_keytab)) },
+      OPT_OFF(auth_heimdal_gssapi_options_block, server_keytab) },
   { "server_service",       opt_stringptr,
-      (void *)(offsetof(auth_heimdal_gssapi_options_block, server_service)) }
+      OPT_OFF(auth_heimdal_gssapi_options_block, server_service) }
 };


int auth_heimdal_gssapi_options_count =
diff --git a/src/src/auths/plaintext.c b/src/src/auths/plaintext.c
index 29c8b49..c120375 100644
--- a/src/src/auths/plaintext.c
+++ b/src/src/auths/plaintext.c
@@ -13,11 +13,11 @@

 optionlist auth_plaintext_options[] = {
   { "client_ignore_invalid_base64", opt_bool,
-      (void *)(offsetof(auth_plaintext_options_block, client_ignore_invalid_base64)) },
+      OPT_OFF(auth_plaintext_options_block, client_ignore_invalid_base64) },
   { "client_send",        opt_stringptr,
-      (void *)(offsetof(auth_plaintext_options_block, client_send)) },
+      OPT_OFF(auth_plaintext_options_block, client_send) },
   { "server_prompts",     opt_stringptr,
-      (void *)(offsetof(auth_plaintext_options_block, server_prompts)) }
+      OPT_OFF(auth_plaintext_options_block, server_prompts) }
 };


/* Size of the options list. An extern variable has to be used so that its
diff --git a/src/src/auths/spa.c b/src/src/auths/spa.c
index 97e3b10..4c014b9 100644
--- a/src/src/auths/spa.c
+++ b/src/src/auths/spa.c
@@ -46,13 +46,13 @@ References:

 optionlist auth_spa_options[] = {
   { "client_domain",             opt_stringptr,
-      (void *)(offsetof(auth_spa_options_block, spa_domain)) },
+      OPT_OFF(auth_spa_options_block, spa_domain) },
   { "client_password",           opt_stringptr,
-      (void *)(offsetof(auth_spa_options_block, spa_password)) },
+      OPT_OFF(auth_spa_options_block, spa_password) },
   { "client_username",           opt_stringptr,
-      (void *)(offsetof(auth_spa_options_block, spa_username)) },
+      OPT_OFF(auth_spa_options_block, spa_username) },
   { "server_password",           opt_stringptr,
-      (void *)(offsetof(auth_spa_options_block, spa_serverpassword)) }
+      OPT_OFF(auth_spa_options_block, spa_serverpassword) }
 };


/* Size of the options list. An extern variable has to be used so that its
diff --git a/src/src/auths/tls.c b/src/src/auths/tls.c
index 56f5f5e..319c4f9 100644
--- a/src/src/auths/tls.c
+++ b/src/src/auths/tls.c
@@ -17,13 +17,13 @@ a server to verify a client SSL certificate

 optionlist auth_tls_options[] = {
   { "server_param",     opt_stringptr,
-      (void *)(offsetof(auth_tls_options_block, server_param1)) },
+      OPT_OFF(auth_tls_options_block, server_param1) },
   { "server_param1",    opt_stringptr,
-      (void *)(offsetof(auth_tls_options_block, server_param1)) },
+      OPT_OFF(auth_tls_options_block, server_param1) },
   { "server_param2",    opt_stringptr,
-      (void *)(offsetof(auth_tls_options_block, server_param2)) },
+      OPT_OFF(auth_tls_options_block, server_param2) },
   { "server_param3",    opt_stringptr,
-      (void *)(offsetof(auth_tls_options_block, server_param3)) },
+      OPT_OFF(auth_tls_options_block, server_param3) },
 };


/* Size of the options list. An extern variable has to be used so that its
diff --git a/src/src/globals.c b/src/src/globals.c
index f16e19b..53a4d12 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -16,23 +16,23 @@ data blocks and hence have the opt_public flag set. */

 optionlist optionlist_auths[] = {
   { "client_condition", opt_stringptr | opt_public,
-                 (void *)(offsetof(auth_instance, client_condition)) },
+                 OPT_OFF(auth_instance, client_condition) },
   { "client_set_id", opt_stringptr | opt_public,
-                 (void *)(offsetof(auth_instance, set_client_id)) },
+                 OPT_OFF(auth_instance, set_client_id) },
   { "driver",        opt_stringptr | opt_public,
-                 (void *)(offsetof(auth_instance, driver_name)) },
+                 OPT_OFF(auth_instance, driver_name) },
   { "public_name",   opt_stringptr | opt_public,
-                 (void *)(offsetof(auth_instance, public_name)) },
+                 OPT_OFF(auth_instance, public_name) },
   { "server_advertise_condition", opt_stringptr | opt_public,
-                 (void *)(offsetof(auth_instance, advertise_condition))},
+                 OPT_OFF(auth_instance, advertise_condition)},
   { "server_condition", opt_stringptr | opt_public,
-                 (void *)(offsetof(auth_instance, server_condition)) },
+                 OPT_OFF(auth_instance, server_condition) },
   { "server_debug_print", opt_stringptr | opt_public,
-                 (void *)(offsetof(auth_instance, server_debug_string)) },
+                 OPT_OFF(auth_instance, server_debug_string) },
   { "server_mail_auth_condition", opt_stringptr | opt_public,
-                 (void *)(offsetof(auth_instance, mail_auth_condition)) },
+                 OPT_OFF(auth_instance, mail_auth_condition) },
   { "server_set_id", opt_stringptr | opt_public,
-                 (void *)(offsetof(auth_instance, set_id)) }
+                 OPT_OFF(auth_instance, set_id) }
 };


 int     optionlist_auths_size = nelem(optionlist_auths);
diff --git a/src/src/local_scan.h b/src/src/local_scan.h
index 00a45bd..7243f6a 100644
--- a/src/src/local_scan.h
+++ b/src/src/local_scan.h
@@ -2,7 +2,7 @@
 *     Exim - an Internet mail transport agent    *
 *************************************************/


-/* Copyright (c) University of Cambridge 1995 - 2019 */
+/* Copyright (c) University of Cambridge 1995 - 2020 */
/* See the file NOTICE for conditions of use and distribution. */

/* This file is the header that is the only Exim header to be included in the
@@ -103,8 +103,8 @@ ABI is changed in a non backward compatible way. The minor number is increased
each time a new feature is added (in a way that doesn't break backward
compatibility). */

-#define LOCAL_SCAN_ABI_VERSION_MAJOR 3
-#define LOCAL_SCAN_ABI_VERSION_MINOR 1
+#define LOCAL_SCAN_ABI_VERSION_MAJOR 4
+#define LOCAL_SCAN_ABI_VERSION_MINOR 0
#define LOCAL_SCAN_ABI_VERSION \
LOCAL_SCAN_ABI_VERSION_MAJOR.LOCAL_SCAN_ABI_VERSION_MINOR

@@ -124,9 +124,11 @@ typedef struct {
   int        type;
   union {
     void *    value;
+    long    offset;
     void (*    fn)();
   } v;
 } optionlist;
+#define OPT_OFF(s, field) {.offset = offsetof(s, field)}


 /* Structure for holding information about an envelope address. The errors_to
 field is always NULL except for one_time aliases that had errors_to on the
diff --git a/src/src/readconf.c b/src/src/readconf.c
index 6f379f0..9a8b834 100644
--- a/src/src/readconf.c
+++ b/src/src/readconf.c
@@ -309,7 +309,7 @@ static optionlist optionlist_config[] = {
   { "smtp_ratelimit_hosts",     opt_stringptr,   &smtp_ratelimit_hosts },
   { "smtp_ratelimit_mail",      opt_stringptr,   &smtp_ratelimit_mail },
   { "smtp_ratelimit_rcpt",      opt_stringptr,   &smtp_ratelimit_rcpt },
-  { "smtp_receive_timeout",     opt_func,        (void *) &fn_smtp_receive_timeout },
+  { "smtp_receive_timeout",     opt_func,        {.fn = &fn_smtp_receive_timeout} },
   { "smtp_reserve_hosts",       opt_stringptr,   &smtp_reserve_hosts },
   { "smtp_return_error_details",opt_bool,        &smtp_return_error_details },
 #ifdef SUPPORT_I18N
@@ -594,7 +594,7 @@ for (router_instance * r = routers; r; r = r->next)
   for (int i = 0; i < *ri->options_count; i++)
     {
     if ((ri->options[i].type & opt_mask) != opt_stringptr) continue;
-    if (p == CS (r->options_block) + (long int)(ri->options[i].v.value))
+    if (p == CS (r->options_block) + ri->options[i].v.offset)
       return US ri->options[i].name;
     }
   }
@@ -610,7 +610,7 @@ for (transport_instance * t = transports; t; t = t->next)
          ? CS t
          : CS t->options_block
          )
-         + (long int)op->v.value)
+         + op->v.offset)
     return US op->name;
     }
   }
@@ -1347,7 +1347,7 @@ if (!(ol = find_option(name2, oltop, last)))
   log_write(0, LOG_MAIN|LOG_PANIC_DIE,
     "Exim internal error: missing set flag for %s", name);
 return data_block
-  ? (BOOL *)(US data_block + (long int)ol->v.value) : (BOOL *)ol->v.value;
+  ? (BOOL *)(US data_block + ol->v.offset) : (BOOL *)ol->v.value;
 }



@@ -1748,7 +1748,7 @@ switch (type)
     control block and flags word. */


     case opt_stringptr:
-    str_target = data_block ? USS (US data_block + (long int)ol->v.value)
+    str_target = data_block ? USS (US data_block + ol->v.offset)
                 : USS ol->v.value;
     if (ol->type & opt_rep_con)
       {
@@ -1807,7 +1807,7 @@ switch (type)


     case opt_rewrite:
     if (data_block)
-      *USS (US data_block + (long int)ol->v.value) = sptr;
+      *USS (US data_block + ol->v.offset) = sptr;
     else
       *USS ol->v.value = sptr;
     freesptr = FALSE;
@@ -1830,8 +1830,8 @@ switch (type)


       if (data_block)
         {
-        chain = (rewrite_rule **)(US data_block + (long int)ol2->v.value);
-        flagptr = (int *)(US data_block + (long int)ol3->v.value);
+        chain = (rewrite_rule **)(US data_block + ol2->v.offset);
+        flagptr = (int *)(US data_block + ol3->v.offset);
         }
       else
         {
@@ -1865,7 +1865,7 @@ switch (type)
       uschar *ss = (Ustrchr(sptr, '$') != NULL) ? sptr : NULL;


       if (data_block)
-        *(USS(US data_block + (long int)ol2->v.value)) = ss;
+        *(USS(US data_block + ol2->v.offset)) = ss;
       else
         *(USS ol2->v.value) = ss;


@@ -1884,7 +1884,7 @@ switch (type)
     if (!route_finduser(sptr, &pw, &uid))
       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "user %s was not found", sptr);
     if (data_block)
-      *(uid_t *)(US data_block + (long int)(ol->v.value)) = uid;
+      *(uid_t *)(US data_block + ol->v.offset) = uid;
     else
       *(uid_t *)ol->v.value = uid;


@@ -1906,7 +1906,7 @@ switch (type)
       if (!*set_flag)
         {
         if (data_block)
-          *((gid_t *)(US data_block + (long int)ol2->v.value)) = pw->pw_gid;
+          *((gid_t *)(US data_block + ol2->v.offset)) = pw->pw_gid;
         else
           *((gid_t *)ol2->v.value) = pw->pw_gid;
         *set_flag = TRUE;
@@ -1927,7 +1927,7 @@ switch (type)
       uschar *ss = (Ustrchr(sptr, '$') != NULL) ? sptr : NULL;


       if (data_block)
-        *(USS(US data_block + (long int)ol2->v.value)) = ss;
+        *(USS(US data_block + ol2->v.offset)) = ss;
       else
         *(USS ol2->v.value) = ss;


@@ -1945,7 +1945,7 @@ switch (type)
     if (!route_findgroup(sptr, &gid))
       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "group %s was not found", sptr);
     if (data_block)
-      *((gid_t *)(US data_block + (long int)ol->v.value)) = gid;
+      *((gid_t *)(US data_block + ol->v.offset)) = gid;
     else
       *((gid_t *)ol->v.value) = gid;
     *(get_set_flag(name, oltop, last, data_block)) = TRUE;
@@ -1975,7 +1975,7 @@ switch (type)
       list[ptr++] = (uid_t)(count - 1);


       if (data_block)
-        *((uid_t **)(US data_block + (long int)ol->v.value)) = list;
+        *((uid_t **)(US data_block + ol->v.offset)) = list;
       else
         *((uid_t **)ol->v.value) = list;


@@ -2016,7 +2016,7 @@ switch (type)
       list[ptr++] = (gid_t)(count - 1);


       if (data_block)
-        *((gid_t **)(US data_block + (long int)ol->v.value)) = list;
+        *((gid_t **)(US data_block + ol->v.offset)) = list;
       else
         *((gid_t **)ol->v.value) = list;


@@ -2052,7 +2052,7 @@ switch (type)
       reset_point = store_mark();
       sptr = read_string(s, name);
       if (data_block)
-        *(USS(US data_block + (long int)ol2->v.value)) = sptr;
+        *(USS(US data_block + ol2->v.offset)) = sptr;
       else
         *(USS ol2->v.value) = sptr;
       freesptr = FALSE;
@@ -2091,7 +2091,7 @@ switch (type)
     {
     int bit = 1 << ((ol->type >> 16) & 31);
     int * ptr = data_block
-      ? (int *)(US data_block + (long int)ol->v.value)
+      ? (int *)(US data_block + ol->v.offset)
       : (int *)ol->v.value;
     if (boolvalue) *ptr |= bit; else *ptr &= ~bit;
     break;
@@ -2100,7 +2100,7 @@ switch (type)
   /* Handle full BOOL types */


   if (data_block)
-    *((BOOL *)(US data_block + (long int)ol->v.value)) = boolvalue;
+    *((BOOL *)(US data_block + ol->v.offset)) = boolvalue;
   else
     *((BOOL *)ol->v.value) = boolvalue;


@@ -2111,7 +2111,7 @@ switch (type)
     sprintf(CS name2, "%.50s_recipient", name + offset);
     if ((ol2 = find_option(name2, oltop, last)))
       if (data_block)
-        *((BOOL *)(US data_block + (long int)ol2->v.value)) = boolvalue;
+        *((BOOL *)(US data_block + ol2->v.offset)) = boolvalue;
       else
         *((BOOL *)ol2->v.value) = boolvalue;
     }
@@ -2123,7 +2123,7 @@ switch (type)
     sprintf(CS name2, "*set_%.50s", name + offset);
     if ((ol2 = find_option(name2, oltop, last)))
       if (data_block)
-        *((BOOL *)(US data_block + (long int)ol2->v.value)) = TRUE;
+        *((BOOL *)(US data_block + ol2->v.offset)) = TRUE;
       else
         *((BOOL *)ol2->v.value) = TRUE;
     }
@@ -2183,7 +2183,7 @@ switch (type)
     }


   if (data_block)
-    *(int *)(US data_block + (long int)ol->v.value) = value;
+    *(int *)(US data_block + ol->v.offset) = value;
   else
     *(int *)ol->v.value = value;
   break;
@@ -2229,7 +2229,7 @@ switch (type)
       extra_chars_error(endptr, inttype, US"integer value for ", name);


     if (data_block)
-      *(int_eximarith_t *)(US data_block + (long int)ol->v.value) = lvalue;
+      *(int_eximarith_t *)(US data_block + ol->v.offset) = lvalue;
     else
       *(int_eximarith_t *)ol->v.value = lvalue;
     break;
@@ -2271,7 +2271,7 @@ switch (type)
     extra_chars_error(s+count, US"fixed-point value for ", name, US"");


   if (data_block)
-    *((int *)(US data_block + (long int)ol->v.value)) = value;
+    *((int *)(US data_block + ol->v.offset)) = value;
   else
     *((int *)ol->v.value) = value;
   break;
@@ -2284,7 +2284,7 @@ switch (type)
     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "invalid time value for %s",
       name);
   if (data_block)
-    *((int *)(US data_block + (long int)ol->v.value)) = value;
+    *((int *)(US data_block + ol->v.offset)) = value;
   else
     *((int *)ol->v.value) = value;
   break;
@@ -2297,7 +2297,7 @@ switch (type)
     {
     int count = 0;
     int * list = data_block
-      ? (int *)(US data_block + (long int)ol->v.value)
+      ? (int *)(US data_block + ol->v.offset)
       : (int *)ol->v.value;


     if (*s != 0) for (count = 1; count <= list[0] - 2; count++)
@@ -2536,10 +2536,10 @@ switch(ol->type & opt_mask)
       sprintf(CS name2, "*expand_%.50s", name);
       if ((ol2 = find_option(name2, oltop, last)))
     {
-    void * value2 = ol2->v.value;
     if (options_block)
-      value2 = (void *)(US options_block + (long int)value2);
-    s = *(USS value2);
+      s = *USS (US options_block + ol2->v.offset);
+    else
+      s = *USS ol2->v.value;
     if (!no_labels) printf("%s = ", name);
     printf("%s\n", s ? string_printing(s) : US"");
     break;
@@ -2568,10 +2568,10 @@ switch(ol->type & opt_mask)
       if (  (ol2 = find_option(name2, oltop, last))
      && (ol2->type & opt_mask) == opt_stringptr)
     {
-    void * value2 = ol2->v.value;
     if (options_block)
-      value2 = (void *)(US options_block + (long int)value2);
-    s = *(USS value2);
+      s = *USS (US options_block + ol2->v.offset);
+    else
+      s = *USS ol2->v.value;
     if (!no_labels) printf("%s = ", name);
     printf("%s\n", s ? string_printing(s) : US"");
     break;
@@ -2653,10 +2653,11 @@ switch(ol->type & opt_mask)
     sprintf(CS name2, "*expand_%.50s", name);
     if ((ol2 = find_option(name2, oltop, last)) && ol2->v.value)
       {
-      void * value2 = ol2->v.value;
       if (options_block)
-    value2 = (void *)(US options_block + (long int)value2);
-      if ((s = *(USS value2)))
+    s = *USS (US options_block + ol2->v.offset);
+      else
+    s = *USS ol2->v.value;
+      if (s)
     {
     if (!no_labels) printf("%s = ", name);
     printf("%s\n", string_printing(s));
@@ -2674,11 +2675,8 @@ switch(ol->type & opt_mask)
     break;


   case opt_func:
-    {
-    void (*fn)() = ol->v.fn;
-    fn(name, NULL, no_labels ? opt_fn_print : opt_fn_print|opt_fn_print_label);
+    ol->v.fn(name, NULL, no_labels ? opt_fn_print : opt_fn_print|opt_fn_print_label);
     break;
-    }
   }
 return TRUE;
 }
@@ -3834,7 +3832,7 @@ for (optionlist * ol = d->info->options; ol < d->info->options + count; ol++)
   if ((ol->type & opt_mask) == opt_stringptr)
     {
     void * options_block = ol->type & opt_public ? (void *)d : d->options_block;
-    uschar * value = *USS(US options_block + (long int)ol->v.value);
+    uschar * value = *USS(US options_block + ol->v.offset);


     if (value && (ss = Ustrstr(value, s)) != NULL)
       {
diff --git a/src/src/route.c b/src/src/route.c
index 16ce72c..a1426d5 100644
--- a/src/src/route.c
+++ b/src/src/route.c
@@ -14,132 +14,133 @@


/* Generic options for routers, all of which live inside router_instance
data blocks and which therefore have the opt_public flag set. */
+#define LOFF(field) OPT_OFF(router_instance, field)

 optionlist optionlist_routers[] = {
   { "*expand_group",      opt_stringptr | opt_hidden | opt_public,
-                 (void *)(offsetof(router_instance, expand_gid)) },
+                 LOFF(expand_gid) },
   { "*expand_more",       opt_stringptr | opt_hidden | opt_public,
-                 (void *)(offsetof(router_instance, expand_more)) },
+                 LOFF(expand_more) },
   { "*expand_unseen",     opt_stringptr | opt_hidden | opt_public,
-                 (void *)(offsetof(router_instance, expand_unseen)) },
+                 LOFF(expand_unseen) },
   { "*expand_user",       opt_stringptr | opt_hidden | opt_public,
-                 (void *)(offsetof(router_instance, expand_uid)) },
+                 LOFF(expand_uid) },
   { "*set_group",         opt_bool | opt_hidden | opt_public,
-                 (void *)(offsetof(router_instance, gid_set)) },
+                 LOFF(gid_set) },
   { "*set_user",          opt_bool | opt_hidden | opt_public,
-                 (void *)(offsetof(router_instance, uid_set)) },
+                 LOFF(uid_set) },
   { "address_data",       opt_stringptr|opt_public,
-                 (void *)(offsetof(router_instance, address_data)) },
+                 LOFF(address_data) },
   { "address_test",       opt_bool|opt_public,
-                 (void *)(offsetof(router_instance, address_test)) },
+                 LOFF(address_test) },
 #ifdef EXPERIMENTAL_BRIGHTMAIL
   { "bmi_deliver_alternate",   opt_bool | opt_public,
-                 (void *)(offsetof(router_instance, bmi_deliver_alternate)) },
+                 LOFF(bmi_deliver_alternate) },
   { "bmi_deliver_default",   opt_bool | opt_public,
-                 (void *)(offsetof(router_instance, bmi_deliver_default)) },
+                 LOFF(bmi_deliver_default) },
   { "bmi_dont_deliver",   opt_bool | opt_public,
-                 (void *)(offsetof(router_instance, bmi_dont_deliver)) },
+                 LOFF(bmi_dont_deliver) },
   { "bmi_rule",           opt_stringptr|opt_public,
-                 (void *)(offsetof(router_instance, bmi_rule)) },
+                 LOFF(bmi_rule) },
 #endif
   { "cannot_route_message", opt_stringptr | opt_public,
-                 (void *)(offsetof(router_instance, cannot_route_message)) },
+                 LOFF(cannot_route_message) },
   { "caseful_local_part", opt_bool | opt_public,
-                 (void *)(offsetof(router_instance, caseful_local_part)) },
+                 LOFF(caseful_local_part) },
   { "check_local_user",   opt_bool | opt_public,
-                 (void *)(offsetof(router_instance, check_local_user)) },
+                 LOFF(check_local_user) },
   { "condition",          opt_stringptr|opt_public|opt_rep_con,
-                 (void *)offsetof(router_instance, condition) },
+                 LOFF(condition) },
   { "debug_print",        opt_stringptr | opt_public,
-                 (void *)offsetof(router_instance, debug_string) },
+                 LOFF(debug_string) },
   { "disable_logging",    opt_bool | opt_public,
-                 (void *)offsetof(router_instance, disable_logging) },
+                 LOFF(disable_logging) },
   { "dnssec_request_domains",            opt_stringptr|opt_public,
-                 (void *)offsetof(router_instance, dnssec.request) },
+                 LOFF(dnssec.request) },
   { "dnssec_require_domains",            opt_stringptr|opt_public,
-                 (void *)offsetof(router_instance, dnssec.require) },
+                 LOFF(dnssec.require) },
   { "domains",            opt_stringptr|opt_public,
-                 (void *)offsetof(router_instance, domains) },
+                 LOFF(domains) },
   { "driver",             opt_stringptr|opt_public,
-                 (void *)offsetof(router_instance, driver_name) },
+                 LOFF(driver_name) },
   { "dsn_lasthop",        opt_bool|opt_public,
-                 (void *)offsetof(router_instance, dsn_lasthop) },
+                 LOFF(dsn_lasthop) },
   { "errors_to",          opt_stringptr|opt_public,
-                 (void *)(offsetof(router_instance, errors_to)) },
+                 LOFF(errors_to) },
   { "expn",               opt_bool|opt_public,
-                 (void *)offsetof(router_instance, expn) },
+                 LOFF(expn) },
   { "fail_verify",        opt_bool_verify|opt_hidden|opt_public,
-                 (void *)offsetof(router_instance, fail_verify_sender) },
+                 LOFF(fail_verify_sender) },
   { "fail_verify_recipient", opt_bool|opt_public,
-                 (void *)offsetof(router_instance, fail_verify_recipient) },
+                 LOFF(fail_verify_recipient) },
   { "fail_verify_sender", opt_bool|opt_public,
-                 (void *)offsetof(router_instance, fail_verify_sender) },
+                 LOFF(fail_verify_sender) },
   { "fallback_hosts",     opt_stringptr|opt_public,
-                 (void *)offsetof(router_instance, fallback_hosts) },
+                 LOFF(fallback_hosts) },
   { "group",              opt_expand_gid | opt_public,
-                 (void *)(offsetof(router_instance, gid)) },
+                 LOFF(gid) },
   { "headers_add",        opt_stringptr|opt_public|opt_rep_str,
-                 (void *)offsetof(router_instance, extra_headers) },
+                 LOFF(extra_headers) },
   { "headers_remove",     opt_stringptr|opt_public|opt_rep_str,
-                 (void *)offsetof(router_instance, remove_headers) },
+                 LOFF(remove_headers) },
   { "ignore_target_hosts",opt_stringptr|opt_public,
-                 (void *)offsetof(router_instance, ignore_target_hosts) },
+                 LOFF(ignore_target_hosts) },
   { "initgroups",         opt_bool | opt_public,
-                 (void *)(offsetof(router_instance, initgroups)) },
+                 LOFF(initgroups) },
   { "local_part_prefix",  opt_stringptr|opt_public,
-                 (void *)offsetof(router_instance, prefix) },
+                 LOFF(prefix) },
   { "local_part_prefix_optional",opt_bool|opt_public,
-                 (void *)offsetof(router_instance, prefix_optional) },
+                 LOFF(prefix_optional) },
   { "local_part_suffix",  opt_stringptr|opt_public,
-                 (void *)offsetof(router_instance, suffix) },
+                 LOFF(suffix) },
   { "local_part_suffix_optional",opt_bool|opt_public,
-                 (void *)offsetof(router_instance, suffix_optional) },
+                 LOFF(suffix_optional) },
   { "local_parts",        opt_stringptr|opt_public,
-                 (void *)offsetof(router_instance, local_parts) },
+                 LOFF(local_parts) },
   { "log_as_local",       opt_bool|opt_public,
-                 (void *)offsetof(router_instance, log_as_local) },
+                 LOFF(log_as_local) },
   { "more",               opt_expand_bool|opt_public,
-                 (void *)offsetof(router_instance, more) },
+                 LOFF(more) },
   { "pass_on_timeout",    opt_bool|opt_public,
-                 (void *)offsetof(router_instance, pass_on_timeout) },
+                 LOFF(pass_on_timeout) },
   { "pass_router",       opt_stringptr|opt_public,
-                 (void *)offsetof(router_instance, pass_router_name) },
+                 LOFF(pass_router_name) },
   { "redirect_router",    opt_stringptr|opt_public,
-                 (void *)offsetof(router_instance, redirect_router_name) },
+                 LOFF(redirect_router_name) },
   { "require_files",      opt_stringptr|opt_public,
-                 (void *)offsetof(router_instance, require_files) },
+                 LOFF(require_files) },
   { "retry_use_local_part", opt_bool|opt_public,
-                 (void *)offsetof(router_instance, retry_use_local_part) },
+                 LOFF(retry_use_local_part) },
   { "router_home_directory", opt_stringptr|opt_public,
-                 (void *)offsetof(router_instance, router_home_directory) },
+                 LOFF(router_home_directory) },
   { "self",               opt_stringptr|opt_public,
-                 (void *)(offsetof(router_instance, self)) },
+                 LOFF(self) },
   { "senders",            opt_stringptr|opt_public,
-                 (void *)offsetof(router_instance, senders) },
+                 LOFF(senders) },
   { "set",                opt_stringptr|opt_public|opt_rep_str,
-                 (void *)offsetof(router_instance, set) },
+                 LOFF(set) },
   #ifdef SUPPORT_TRANSLATE_IP_ADDRESS
   { "translate_ip_address", opt_stringptr|opt_public,
-                 (void *)offsetof(router_instance, translate_ip_address) },
+                 LOFF(translate_ip_address) },
   #endif
   { "transport",          opt_stringptr|opt_public,
-                 (void *)offsetof(router_instance, transport_name) },
+                 LOFF(transport_name) },
   { "transport_current_directory", opt_stringptr|opt_public,
-                 (void *)offsetof(router_instance, current_directory) },
+                 LOFF(current_directory) },
   { "transport_home_directory", opt_stringptr|opt_public,
-                 (void *)offsetof(router_instance, home_directory) },
+                 LOFF(home_directory) },
   { "unseen",             opt_expand_bool|opt_public,
-                 (void *)offsetof(router_instance, unseen) },
+                 LOFF(unseen) },
   { "user",               opt_expand_uid | opt_public,
-                 (void *)(offsetof(router_instance, uid)) },
+                 LOFF(uid) },
   { "verify",             opt_bool_verify|opt_hidden|opt_public,
-                 (void *)offsetof(router_instance, verify_sender) },
+                 LOFF(verify_sender) },
   { "verify_only",        opt_bool|opt_public,
-                 (void *)offsetof(router_instance, verify_only) },
+                 LOFF(verify_only) },
   { "verify_recipient",   opt_bool|opt_public,
-                 (void *)offsetof(router_instance, verify_recipient) },
+                 LOFF(verify_recipient) },
   { "verify_sender",      opt_bool|opt_public,
-                 (void *)offsetof(router_instance, verify_sender) }
+                 LOFF(verify_sender) }
 };


int optionlist_routers_size = nelem(optionlist_routers);
diff --git a/src/src/routers/dnslookup.c b/src/src/routers/dnslookup.c
index 2a2dd46..7e074c2 100644
--- a/src/src/routers/dnslookup.c
+++ b/src/src/routers/dnslookup.c
@@ -12,34 +12,22 @@


/* Options specific to the dnslookup router. */
+#define LOFF(field) OPT_OFF(dnslookup_router_options_block, field)

 optionlist dnslookup_router_options[] = {
-  { "check_secondary_mx", opt_bool,
-      (void *)(offsetof(dnslookup_router_options_block, check_secondary_mx)) },
-  { "check_srv",          opt_stringptr,
-      (void *)(offsetof(dnslookup_router_options_block, check_srv)) },
-  { "fail_defer_domains", opt_stringptr,
-      (void *)(offsetof(dnslookup_router_options_block, fail_defer_domains)) },
-  { "ipv4_only",          opt_stringptr,
-      (void *)(offsetof(dnslookup_router_options_block, ipv4_only)) },
-  { "ipv4_prefer",        opt_stringptr,
-      (void *)(offsetof(dnslookup_router_options_block, ipv4_prefer)) },
-  { "mx_domains",         opt_stringptr,
-      (void *)(offsetof(dnslookup_router_options_block, mx_domains)) },
-  { "mx_fail_domains",    opt_stringptr,
-      (void *)(offsetof(dnslookup_router_options_block, mx_fail_domains)) },
-  { "qualify_single",     opt_bool,
-      (void *)(offsetof(dnslookup_router_options_block, qualify_single)) },
-  { "rewrite_headers",    opt_bool,
-      (void *)(offsetof(dnslookup_router_options_block, rewrite_headers)) },
-  { "same_domain_copy_routing", opt_bool|opt_public,
-      (void *)(offsetof(router_instance, same_domain_copy_routing)) },
-  { "search_parents",     opt_bool,
-      (void *)(offsetof(dnslookup_router_options_block, search_parents)) },
-  { "srv_fail_domains",   opt_stringptr,
-      (void *)(offsetof(dnslookup_router_options_block, srv_fail_domains)) },
-  { "widen_domains",      opt_stringptr,
-      (void *)(offsetof(dnslookup_router_options_block, widen_domains)) }
+  { "check_secondary_mx", opt_bool,        LOFF(check_secondary_mx) },
+  { "check_srv",          opt_stringptr,    LOFF(check_srv) },
+  { "fail_defer_domains", opt_stringptr,    LOFF(fail_defer_domains) },
+  { "ipv4_only",          opt_stringptr,    LOFF(ipv4_only) },
+  { "ipv4_prefer",        opt_stringptr,    LOFF(ipv4_prefer) },
+  { "mx_domains",         opt_stringptr,    LOFF(mx_domains) },
+  { "mx_fail_domains",    opt_stringptr,    LOFF(mx_fail_domains) },
+  { "qualify_single",     opt_bool,        LOFF(qualify_single) },
+  { "rewrite_headers",    opt_bool,        LOFF(rewrite_headers) },
+  { "same_domain_copy_routing", opt_bool|opt_public, OPT_OFF(router_instance, same_domain_copy_routing) },
+  { "search_parents",     opt_bool,        LOFF(search_parents) },
+  { "srv_fail_domains",   opt_stringptr,    LOFF(srv_fail_domains) },
+  { "widen_domains",      opt_stringptr,    LOFF(widen_domains) }
 };


/* Size of the options list. An extern variable has to be used so that its
diff --git a/src/src/routers/iplookup.c b/src/src/routers/iplookup.c
index 4ceb1f5..21a65f3 100644
--- a/src/src/routers/iplookup.c
+++ b/src/src/routers/iplookup.c
@@ -21,21 +21,21 @@

 optionlist iplookup_router_options[] = {
   { "hosts",    opt_stringptr,
-      (void *)(offsetof(iplookup_router_options_block, hosts)) },
+      OPT_OFF(iplookup_router_options_block, hosts) },
   { "optional", opt_bool,
-      (void *)(offsetof(iplookup_router_options_block, optional)) },
+      OPT_OFF(iplookup_router_options_block, optional) },
   { "port",     opt_int,
-      (void *)(offsetof(iplookup_router_options_block, port)) },
+      OPT_OFF(iplookup_router_options_block, port) },
   { "protocol", opt_stringptr,
-      (void *)(offsetof(iplookup_router_options_block, protocol_name)) },
+      OPT_OFF(iplookup_router_options_block, protocol_name) },
   { "query",    opt_stringptr,
-      (void *)(offsetof(iplookup_router_options_block, query)) },
+      OPT_OFF(iplookup_router_options_block, query) },
   { "reroute",  opt_stringptr,
-      (void *)(offsetof(iplookup_router_options_block, reroute)) },
+      OPT_OFF(iplookup_router_options_block, reroute) },
   { "response_pattern", opt_stringptr,
-      (void *)(offsetof(iplookup_router_options_block, response_pattern)) },
+      OPT_OFF(iplookup_router_options_block, response_pattern) },
   { "timeout",  opt_time,
-      (void *)(offsetof(iplookup_router_options_block, timeout)) }
+      OPT_OFF(iplookup_router_options_block, timeout) }
 };


/* Size of the options list. An extern variable has to be used so that its
diff --git a/src/src/routers/manualroute.c b/src/src/routers/manualroute.c
index c9ddd27..0b5b27e 100644
--- a/src/src/routers/manualroute.c
+++ b/src/src/routers/manualroute.c
@@ -15,17 +15,17 @@

 optionlist manualroute_router_options[] = {
   { "host_all_ignored", opt_stringptr,
-      (void *)(offsetof(manualroute_router_options_block, host_all_ignored)) },
+      OPT_OFF(manualroute_router_options_block, host_all_ignored) },
   { "host_find_failed", opt_stringptr,
-      (void *)(offsetof(manualroute_router_options_block, host_find_failed)) },
+      OPT_OFF(manualroute_router_options_block, host_find_failed) },
   { "hosts_randomize",  opt_bool,
-      (void *)(offsetof(manualroute_router_options_block, hosts_randomize)) },
+      OPT_OFF(manualroute_router_options_block, hosts_randomize) },
   { "route_data",       opt_stringptr,
-      (void *)(offsetof(manualroute_router_options_block, route_data)) },
+      OPT_OFF(manualroute_router_options_block, route_data) },
   { "route_list",       opt_stringptr,
-      (void *)(offsetof(manualroute_router_options_block, route_list)) },
+      OPT_OFF(manualroute_router_options_block, route_list) },
   { "same_domain_copy_routing", opt_bool|opt_public,
-      (void *)(offsetof(router_instance, same_domain_copy_routing)) }
+      OPT_OFF(router_instance, same_domain_copy_routing) }
 };


/* Size of the options list. An extern variable has to be used so that its
diff --git a/src/src/routers/queryprogram.c b/src/src/routers/queryprogram.c
index 4532133..107632f 100644
--- a/src/src/routers/queryprogram.c
+++ b/src/src/routers/queryprogram.c
@@ -15,23 +15,23 @@

 optionlist queryprogram_router_options[] = {
   { "*expand_command_group", opt_bool | opt_hidden,
-      (void *)(offsetof(queryprogram_router_options_block, expand_cmd_gid)) },
+      OPT_OFF(queryprogram_router_options_block, expand_cmd_gid) },
   { "*expand_command_user", opt_bool | opt_hidden,
-      (void *)(offsetof(queryprogram_router_options_block, expand_cmd_uid)) },
+      OPT_OFF(queryprogram_router_options_block, expand_cmd_uid) },
   { "*set_command_group",   opt_bool | opt_hidden,
-      (void *)(offsetof(queryprogram_router_options_block, cmd_gid_set)) },
+      OPT_OFF(queryprogram_router_options_block, cmd_gid_set) },
   { "*set_command_user",    opt_bool | opt_hidden,
-      (void *)(offsetof(queryprogram_router_options_block, cmd_uid_set)) },
+      OPT_OFF(queryprogram_router_options_block, cmd_uid_set) },
   { "command",      opt_stringptr,
-      (void *)(offsetof(queryprogram_router_options_block, command)) },
+      OPT_OFF(queryprogram_router_options_block, command) },
   { "command_group",opt_expand_gid,
-      (void *)(offsetof(queryprogram_router_options_block, cmd_gid)) },
+      OPT_OFF(queryprogram_router_options_block, cmd_gid) },
   { "command_user", opt_expand_uid,
-      (void *)(offsetof(queryprogram_router_options_block, cmd_uid)) },
+      OPT_OFF(queryprogram_router_options_block, cmd_uid) },
   { "current_directory", opt_stringptr,
-      (void *)(offsetof(queryprogram_router_options_block, current_directory)) },
+      OPT_OFF(queryprogram_router_options_block, current_directory) },
   { "timeout",      opt_time,
-      (void *)(offsetof(queryprogram_router_options_block, timeout)) }
+      OPT_OFF(queryprogram_router_options_block, timeout) }
 };


/* Size of the options list. An extern variable has to be used so that its
diff --git a/src/src/routers/redirect.c b/src/src/routers/redirect.c
index 6bbbf37..9cf9866 100644
--- a/src/src/routers/redirect.c
+++ b/src/src/routers/redirect.c
@@ -13,118 +13,94 @@


/* Options specific to the redirect router. */
+#define LOFF(field) OPT_OFF(redirect_router_options_block, field)

 optionlist redirect_router_options[] = {
   { "allow_defer",        opt_bit | (RDON_DEFER << 16),
-      (void *)offsetof(redirect_router_options_block, bit_options) },
+      LOFF(bit_options) },
   { "allow_fail",         opt_bit | (RDON_FAIL << 16),
-      (void *)offsetof(redirect_router_options_block, bit_options) },
+      LOFF(bit_options) },
   { "allow_filter",       opt_bit | (RDON_FILTER << 16),
-      (void *)offsetof(redirect_router_options_block, bit_options) },
+      LOFF(bit_options) },
   { "allow_freeze",       opt_bit | (RDON_FREEZE << 16),
-      (void *)offsetof(redirect_router_options_block, bit_options) },
-  { "check_ancestor",     opt_bool,
-      (void *)offsetof(redirect_router_options_block, check_ancestor) },
-  { "check_group",        opt_bool,
-      (void *)offsetof(redirect_router_options_block, check_group) },
-  { "check_owner",        opt_bool,
-      (void *)offsetof(redirect_router_options_block, check_owner) },
-  { "data",               opt_stringptr,
-      (void *)offsetof(redirect_router_options_block, data) },
-  { "directory_transport",opt_stringptr,
-      (void *)offsetof(redirect_router_options_block, directory_transport_name) },
-  { "file",               opt_stringptr,
-      (void *)offsetof(redirect_router_options_block, file) },
-  { "file_transport",     opt_stringptr,
-      (void *)offsetof(redirect_router_options_block, file_transport_name) },
+      LOFF(bit_options) },
+  { "check_ancestor",     opt_bool,        LOFF(check_ancestor) },
+  { "check_group",        opt_bool,        LOFF(check_group) },
+  { "check_owner",        opt_bool,        LOFF(check_owner) },
+  { "data",               opt_stringptr,    LOFF(data) },
+  { "directory_transport",opt_stringptr,    LOFF(directory_transport_name) },
+  { "file",               opt_stringptr,    LOFF(file) },
+  { "file_transport",     opt_stringptr,    LOFF(file_transport_name) },
+
   { "filter_prepend_home",opt_bit | (RDON_PREPEND_HOME << 16),
-      (void *)offsetof(redirect_router_options_block, bit_options) },
+      LOFF(bit_options) },
   { "forbid_blackhole",   opt_bit | (RDON_BLACKHOLE << 16),
-      (void *)offsetof(redirect_router_options_block, bit_options) },
+      LOFF(bit_options) },
   { "forbid_exim_filter", opt_bit | (RDON_EXIM_FILTER << 16),
-      (void *)offsetof(redirect_router_options_block, bit_options) },
+      LOFF(bit_options) },
   { "forbid_file",        opt_bool,
-      (void *)offsetof(redirect_router_options_block, forbid_file) },
+      LOFF(forbid_file) },
   { "forbid_filter_dlfunc", opt_bit | (RDON_DLFUNC << 16),
-      (void *)offsetof(redirect_router_options_block, bit_options) },
+      LOFF(bit_options) },
   { "forbid_filter_existstest",  opt_bit | (RDON_EXISTS << 16),
-      (void *)offsetof(redirect_router_options_block, bit_options) },
+      LOFF(bit_options) },
   { "forbid_filter_logwrite",opt_bit | (RDON_LOG << 16),
-      (void *)offsetof(redirect_router_options_block, bit_options) },
+      LOFF(bit_options) },
   { "forbid_filter_lookup", opt_bit | (RDON_LOOKUP << 16),
-      (void *)offsetof(redirect_router_options_block, bit_options) },
+      LOFF(bit_options) },
   { "forbid_filter_perl", opt_bit | (RDON_PERL << 16),
-      (void *)offsetof(redirect_router_options_block, bit_options) },
+      LOFF(bit_options) },
   { "forbid_filter_readfile", opt_bit | (RDON_READFILE << 16),
-      (void *)offsetof(redirect_router_options_block, bit_options) },
+      LOFF(bit_options) },
   { "forbid_filter_readsocket", opt_bit | (RDON_READSOCK << 16),
-      (void *)offsetof(redirect_router_options_block, bit_options) },
+      LOFF(bit_options) },
   { "forbid_filter_reply",opt_bool,
-      (void *)offsetof(redirect_router_options_block, forbid_filter_reply) },
+      LOFF(forbid_filter_reply) },
   { "forbid_filter_run",  opt_bit | (RDON_RUN << 16),
-      (void *)offsetof(redirect_router_options_block, bit_options) },
+      LOFF(bit_options) },
   { "forbid_include",     opt_bit | (RDON_INCLUDE << 16),
-      (void *)offsetof(redirect_router_options_block, bit_options) },
+      LOFF(bit_options) },
   { "forbid_pipe",        opt_bool,
-      (void *)offsetof(redirect_router_options_block, forbid_pipe) },
+      LOFF(forbid_pipe) },
   { "forbid_sieve_filter",opt_bit | (RDON_SIEVE_FILTER << 16),
-      (void *)offsetof(redirect_router_options_block, bit_options) },
+      LOFF(bit_options) },
   { "forbid_smtp_code",     opt_bool,
-      (void *)offsetof(redirect_router_options_block, forbid_smtp_code) },
+      LOFF(forbid_smtp_code) },
   { "hide_child_in_errmsg", opt_bool,
-      (void *)offsetof(redirect_router_options_block,  hide_child_in_errmsg) },
+      LOFF( hide_child_in_errmsg) },
   { "ignore_eacces",      opt_bit | (RDON_EACCES << 16),
-      (void *)offsetof(redirect_router_options_block, bit_options) },
+      LOFF(bit_options) },
   { "ignore_enotdir",     opt_bit | (RDON_ENOTDIR << 16),
-      (void *)offsetof(redirect_router_options_block, bit_options) },
-  { "include_directory",  opt_stringptr,
-      (void *)offsetof(redirect_router_options_block,  include_directory) },
-  { "modemask",           opt_octint,
-      (void *)offsetof(redirect_router_options_block, modemask) },
-  { "one_time",           opt_bool,
-      (void *)offsetof(redirect_router_options_block, one_time) },
-  { "owners",             opt_uidlist,
-      (void *)offsetof(redirect_router_options_block, owners) },
-  { "owngroups",          opt_gidlist,
-      (void *)offsetof(redirect_router_options_block, owngroups) },
-  { "pipe_transport",     opt_stringptr,
-      (void *)offsetof(redirect_router_options_block, pipe_transport_name) },
-  { "qualify_domain",     opt_stringptr,
-      (void *)offsetof(redirect_router_options_block, qualify_domain) },
-  { "qualify_preserve_domain", opt_bool,
-      (void *)offsetof(redirect_router_options_block, qualify_preserve_domain) },
-  { "repeat_use",         opt_bool | opt_public,
-      (void *)offsetof(router_instance, repeat_use) },
-  { "reply_transport",    opt_stringptr,
-      (void *)offsetof(redirect_router_options_block, reply_transport_name) },
+      LOFF(bit_options) },
+
+  { "include_directory",  opt_stringptr,    LOFF( include_directory) },
+  { "modemask",           opt_octint,        LOFF(modemask) },
+  { "one_time",           opt_bool,        LOFF(one_time) },
+  { "owners",             opt_uidlist,        LOFF(owners) },
+  { "owngroups",          opt_gidlist,        LOFF(owngroups) },
+  { "pipe_transport",     opt_stringptr,    LOFF(pipe_transport_name) },
+  { "qualify_domain",     opt_stringptr,    LOFF(qualify_domain) },
+  { "qualify_preserve_domain", opt_bool,    LOFF(qualify_preserve_domain) },
+  { "repeat_use",         opt_bool | opt_public, OPT_OFF(router_instance, repeat_use) },
+  { "reply_transport",    opt_stringptr,    LOFF(reply_transport_name) },
+
   { "rewrite",            opt_bit | (RDON_REWRITE << 16),
-      (void *)offsetof(redirect_router_options_block, bit_options) },
-  { "sieve_enotify_mailto_owner", opt_stringptr,
-      (void *)offsetof(redirect_router_options_block, sieve_enotify_mailto_owner) },
-  { "sieve_subaddress", opt_stringptr,
-      (void *)offsetof(redirect_router_options_block, sieve_subaddress) },
-  { "sieve_useraddress", opt_stringptr,
-      (void *)offsetof(redirect_router_options_block, sieve_useraddress) },
-  { "sieve_vacation_directory", opt_stringptr,
-      (void *)offsetof(redirect_router_options_block, sieve_vacation_directory) },
-  { "skip_syntax_errors", opt_bool,
-      (void *)offsetof(redirect_router_options_block, skip_syntax_errors) },
+      LOFF(bit_options) },
+
+  { "sieve_enotify_mailto_owner", opt_stringptr, LOFF(sieve_enotify_mailto_owner) },
+  { "sieve_subaddress", opt_stringptr,        LOFF(sieve_subaddress) },
+  { "sieve_useraddress", opt_stringptr,        LOFF(sieve_useraddress) },
+  { "sieve_vacation_directory", opt_stringptr,    LOFF(sieve_vacation_directory) },
+  { "skip_syntax_errors", opt_bool,        LOFF(skip_syntax_errors) },
 #ifdef EXPERIMENTAL_SRS
-  { "srs",                opt_stringptr,
-      (void *)offsetof(redirect_router_options_block, srs) },
-  { "srs_alias",          opt_stringptr,
-      (void *)offsetof(redirect_router_options_block, srs_alias) },
-  { "srs_condition",      opt_stringptr,
-      (void *)offsetof(redirect_router_options_block, srs_condition) },
-  { "srs_dbinsert",       opt_stringptr,
-      (void *)offsetof(redirect_router_options_block, srs_dbinsert) },
-  { "srs_dbselect",       opt_stringptr,
-      (void *)offsetof(redirect_router_options_block, srs_dbselect) },
+  { "srs",                opt_stringptr,    LOFF(srs) },
+  { "srs_alias",          opt_stringptr,    LOFF(srs_alias) },
+  { "srs_condition",      opt_stringptr,    LOFF(srs_condition) },
+  { "srs_dbinsert",       opt_stringptr,    LOFF(srs_dbinsert) },
+  { "srs_dbselect",       opt_stringptr,    LOFF(srs_dbselect) },
 #endif
-  { "syntax_errors_text", opt_stringptr,
-      (void *)offsetof(redirect_router_options_block, syntax_errors_text) },
-  { "syntax_errors_to",   opt_stringptr,
-      (void *)offsetof(redirect_router_options_block, syntax_errors_to) }
+  { "syntax_errors_text", opt_stringptr,    LOFF(syntax_errors_text) },
+  { "syntax_errors_to",   opt_stringptr,    LOFF(syntax_errors_to) }
 };


/* Size of the options list. An extern variable has to be used so that its
diff --git a/src/src/transport.c b/src/src/transport.c
index b2a65ed..ed3dcf0 100644
--- a/src/src/transport.c
+++ b/src/src/transport.c
@@ -15,75 +15,76 @@ transports. */
data blocks and which therefore have the opt_public flag set. Note that there
are other options living inside this structure which can be set only from
certain transports. */
+#define LOFF(field) OPT_OFF(transport_instance, field)

 optionlist optionlist_transports[] = {
   /*    name        type                    value */
   { "*expand_group",    opt_stringptr|opt_hidden|opt_public,
-                 (void *)offsetof(transport_instance, expand_gid) },
+                 LOFF(expand_gid) },
   { "*expand_user",     opt_stringptr|opt_hidden|opt_public,
-                 (void *)offsetof(transport_instance, expand_uid) },
+                 LOFF(expand_uid) },
   { "*headers_rewrite_flags", opt_int|opt_public|opt_hidden,
-                 (void *)offsetof(transport_instance, rewrite_existflags) },
+                 LOFF(rewrite_existflags) },
   { "*headers_rewrite_rules", opt_void|opt_public|opt_hidden,
-                 (void *)offsetof(transport_instance, rewrite_rules) },
+                 LOFF(rewrite_rules) },
   { "*set_group",       opt_bool|opt_hidden|opt_public,
-                 (void *)offsetof(transport_instance, gid_set) },
+                 LOFF(gid_set) },
   { "*set_user",        opt_bool|opt_hidden|opt_public,
-                 (void *)offsetof(transport_instance, uid_set) },
+                 LOFF(uid_set) },
   { "body_only",        opt_bool|opt_public,
-                 (void *)offsetof(transport_instance, body_only) },
+                 LOFF(body_only) },
   { "current_directory", opt_stringptr|opt_public,
-                 (void *)offsetof(transport_instance, current_dir) },
+                 LOFF(current_dir) },
   { "debug_print",      opt_stringptr | opt_public,
-                 (void *)offsetof(transport_instance, debug_string) },
+                 LOFF(debug_string) },
   { "delivery_date_add", opt_bool|opt_public,
-                 (void *)(offsetof(transport_instance, delivery_date_add)) },
+                 LOFF(delivery_date_add) },
   { "disable_logging",  opt_bool|opt_public,
-                 (void *)(offsetof(transport_instance, disable_logging)) },
+                 LOFF(disable_logging) },
   { "driver",           opt_stringptr|opt_public,
-                 (void *)offsetof(transport_instance, driver_name) },
+                 LOFF(driver_name) },
   { "envelope_to_add",   opt_bool|opt_public,
-                 (void *)(offsetof(transport_instance, envelope_to_add)) },
+                 LOFF(envelope_to_add) },
 #ifndef DISABLE_EVENT
   { "event_action",     opt_stringptr | opt_public,
-                 (void *)offsetof(transport_instance, event_action) },
+                 LOFF(event_action) },
 #endif
   { "group",             opt_expand_gid|opt_public,
-                 (void *)offsetof(transport_instance, gid) },
+                 LOFF(gid) },
   { "headers_add",      opt_stringptr|opt_public|opt_rep_str,
-                 (void *)offsetof(transport_instance, add_headers) },
+                 LOFF(add_headers) },
   { "headers_only",     opt_bool|opt_public,
-                 (void *)offsetof(transport_instance, headers_only) },
+                 LOFF(headers_only) },
   { "headers_remove",   opt_stringptr|opt_public|opt_rep_str,
-                 (void *)offsetof(transport_instance, remove_headers) },
+                 LOFF(remove_headers) },
   { "headers_rewrite",  opt_rewrite|opt_public,
-                 (void *)offsetof(transport_instance, headers_rewrite) },
+                 LOFF(headers_rewrite) },
   { "home_directory",   opt_stringptr|opt_public,
-                 (void *)offsetof(transport_instance, home_dir) },
+                 LOFF(home_dir) },
   { "initgroups",       opt_bool|opt_public,
-                 (void *)offsetof(transport_instance, initgroups) },
+                 LOFF(initgroups) },
   { "max_parallel",     opt_stringptr|opt_public,
-                 (void *)offsetof(transport_instance, max_parallel) },
+                 LOFF(max_parallel) },
   { "message_size_limit", opt_stringptr|opt_public,
-                 (void *)offsetof(transport_instance, message_size_limit) },
+                 LOFF(message_size_limit) },
   { "rcpt_include_affixes", opt_bool|opt_public,
-                 (void *)offsetof(transport_instance, rcpt_include_affixes) },
+                 LOFF(rcpt_include_affixes) },
   { "retry_use_local_part", opt_bool|opt_public,
-                 (void *)offsetof(transport_instance, retry_use_local_part) },
+                 LOFF(retry_use_local_part) },
   { "return_path",      opt_stringptr|opt_public,
-                 (void *)(offsetof(transport_instance, return_path)) },
+                 LOFF(return_path) },
   { "return_path_add",   opt_bool|opt_public,
-                 (void *)(offsetof(transport_instance, return_path_add)) },
+                 LOFF(return_path_add) },
   { "shadow_condition", opt_stringptr|opt_public,
-                 (void *)offsetof(transport_instance, shadow_condition) },
+                 LOFF(shadow_condition) },
   { "shadow_transport", opt_stringptr|opt_public,
-                 (void *)offsetof(transport_instance, shadow) },
+                 LOFF(shadow) },
   { "transport_filter", opt_stringptr|opt_public,
-                 (void *)offsetof(transport_instance, filter_command) },
+                 LOFF(filter_command) },
   { "transport_filter_timeout", opt_time|opt_public,
-                 (void *)offsetof(transport_instance, filter_timeout) },
+                 LOFF(filter_timeout) },
   { "user",             opt_expand_uid|opt_public,
-                 (void *)offsetof(transport_instance, uid) }
+                 LOFF(uid) }
 };


int optionlist_transports_size = nelem(optionlist_transports);
diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c
index de193db..f4baf0c 100644
--- a/src/src/transports/appendfile.c
+++ b/src/src/transports/appendfile.c
@@ -19,133 +19,77 @@
order (note that "_" comes before the lower case letters). Some of them are
stored in the publicly visible instance block - these are flagged with the
opt_public flag. */
+#define LOFF(field) OPT_OFF(appendfile_transport_options_block, field)

 optionlist appendfile_transport_options[] = {
 #ifdef SUPPORT_MAILDIR
-  { "*expand_maildir_use_size_file", opt_stringptr,
-      (void *)offsetof(appendfile_transport_options_block, expand_maildir_use_size_file) },
+  { "*expand_maildir_use_size_file", opt_stringptr, LOFF(expand_maildir_use_size_file) },
 #endif
-  { "*set_use_fcntl_lock",opt_bool | opt_hidden,
-      (void *)offsetof(appendfile_transport_options_block, set_use_fcntl) },
-  { "*set_use_flock_lock",opt_bool | opt_hidden,
-      (void *)offsetof(appendfile_transport_options_block, set_use_flock) },
-  { "*set_use_lockfile", opt_bool | opt_hidden,
-      (void *)offsetof(appendfile_transport_options_block, set_use_lockfile) },
+  { "*set_use_fcntl_lock",opt_bool | opt_hidden, LOFF(set_use_fcntl) },
+  { "*set_use_flock_lock",opt_bool | opt_hidden, LOFF(set_use_flock) },
+  { "*set_use_lockfile", opt_bool | opt_hidden,    LOFF(set_use_lockfile) },
 #ifdef SUPPORT_MBX
-  { "*set_use_mbx_lock", opt_bool | opt_hidden,
-      (void *)offsetof(appendfile_transport_options_block, set_use_mbx_lock) },
+  { "*set_use_mbx_lock", opt_bool | opt_hidden,    LOFF(set_use_mbx_lock) },
 #endif
-  { "allow_fifo",        opt_bool,
-      (void *)offsetof(appendfile_transport_options_block, allow_fifo) },
-  { "allow_symlink",     opt_bool,
-      (void *)offsetof(appendfile_transport_options_block, allow_symlink) },
-  { "batch_id",          opt_stringptr | opt_public,
-      (void *)offsetof(transport_instance, batch_id) },
-  { "batch_max",         opt_int | opt_public,
-      (void *)offsetof(transport_instance, batch_max) },
-  { "check_group",       opt_bool,
-      (void *)offsetof(appendfile_transport_options_block, check_group) },
-  { "check_owner",       opt_bool,
-      (void *)offsetof(appendfile_transport_options_block, check_owner) },
-  { "check_string",      opt_stringptr,
-      (void *)offsetof(appendfile_transport_options_block, check_string) },
-  { "create_directory",  opt_bool,
-      (void *)offsetof(appendfile_transport_options_block, create_directory) },
-  { "create_file",       opt_stringptr,
-      (void *)offsetof(appendfile_transport_options_block, create_file_string) },
-  { "directory",         opt_stringptr,
-      (void *)offsetof(appendfile_transport_options_block, dirname) },
-  { "directory_file",    opt_stringptr,
-      (void *)offsetof(appendfile_transport_options_block, dirfilename) },
-  { "directory_mode",    opt_octint,
-      (void *)offsetof(appendfile_transport_options_block, dirmode) },
-  { "escape_string",     opt_stringptr,
-      (void *)offsetof(appendfile_transport_options_block, escape_string) },
-  { "file",              opt_stringptr,
-      (void *)offsetof(appendfile_transport_options_block, filename) },
-  { "file_format",       opt_stringptr,
-      (void *)offsetof(appendfile_transport_options_block, file_format) },
-  { "file_must_exist",   opt_bool,
-      (void *)offsetof(appendfile_transport_options_block, file_must_exist) },
-  { "lock_fcntl_timeout", opt_time,
-      (void *)offsetof(appendfile_transport_options_block, lock_fcntl_timeout) },
-  { "lock_flock_timeout", opt_time,
-      (void *)offsetof(appendfile_transport_options_block, lock_flock_timeout) },
-  { "lock_interval",     opt_time,
-      (void *)offsetof(appendfile_transport_options_block, lock_interval) },
-  { "lock_retries",      opt_int,
-      (void *)offsetof(appendfile_transport_options_block, lock_retries) },
-  { "lockfile_mode",     opt_octint,
-      (void *)offsetof(appendfile_transport_options_block, lockfile_mode) },
-  { "lockfile_timeout",  opt_time,
-      (void *)offsetof(appendfile_transport_options_block, lockfile_timeout) },
-  { "mailbox_filecount", opt_stringptr,
-      (void *)offsetof(appendfile_transport_options_block, mailbox_filecount_string) },
-  { "mailbox_size",      opt_stringptr,
-      (void *)offsetof(appendfile_transport_options_block, mailbox_size_string) },
+  { "allow_fifo",        opt_bool,    LOFF(allow_fifo) },
+  { "allow_symlink",     opt_bool,    LOFF(allow_symlink) },
+  { "batch_id",          opt_stringptr | opt_public, OPT_OFF(transport_instance, batch_id) },
+  { "batch_max",         opt_int | opt_public, OPT_OFF(transport_instance, batch_max) },
+  { "check_group",       opt_bool,    LOFF(check_group) },
+  { "check_owner",       opt_bool,    LOFF(check_owner) },
+  { "check_string",      opt_stringptr,    LOFF(check_string) },
+  { "create_directory",  opt_bool,    LOFF(create_directory) },
+  { "create_file",       opt_stringptr,    LOFF(create_file_string) },
+  { "directory",         opt_stringptr,    LOFF(dirname) },
+  { "directory_file",    opt_stringptr,    LOFF(dirfilename) },
+  { "directory_mode",    opt_octint,    LOFF(dirmode) },
+  { "escape_string",     opt_stringptr,    LOFF(escape_string) },
+  { "file",              opt_stringptr,    LOFF(filename) },
+  { "file_format",       opt_stringptr,    LOFF(file_format) },
+  { "file_must_exist",   opt_bool,    LOFF(file_must_exist) },
+  { "lock_fcntl_timeout", opt_time,    LOFF(lock_fcntl_timeout) },
+  { "lock_flock_timeout", opt_time,    LOFF(lock_flock_timeout) },
+  { "lock_interval",     opt_time,    LOFF(lock_interval) },
+  { "lock_retries",      opt_int,    LOFF(lock_retries) },
+  { "lockfile_mode",     opt_octint,    LOFF(lockfile_mode) },
+  { "lockfile_timeout",  opt_time,    LOFF(lockfile_timeout) },
+  { "mailbox_filecount", opt_stringptr,    LOFF(mailbox_filecount_string) },
+  { "mailbox_size",      opt_stringptr,    LOFF(mailbox_size_string) },
 #ifdef SUPPORT_MAILDIR
-  { "maildir_format",    opt_bool,
-      (void *)offsetof(appendfile_transport_options_block, maildir_format ) } ,
-  { "maildir_quota_directory_regex", opt_stringptr,
-      (void *)offsetof(appendfile_transport_options_block, maildir_dir_regex) },
-  { "maildir_retries",   opt_int,
-      (void *)offsetof(appendfile_transport_options_block, maildir_retries) },
-  { "maildir_tag",       opt_stringptr,
-      (void *)offsetof(appendfile_transport_options_block, maildir_tag) },
-  { "maildir_use_size_file", opt_expand_bool,
-      (void *)offsetof(appendfile_transport_options_block, maildir_use_size_file ) } ,
-  { "maildirfolder_create_regex", opt_stringptr,
-      (void *)offsetof(appendfile_transport_options_block, maildirfolder_create_regex ) },
+  { "maildir_format",    opt_bool,    LOFF(maildir_format ) } ,
+  { "maildir_quota_directory_regex", opt_stringptr, LOFF(maildir_dir_regex) },
+  { "maildir_retries",   opt_int,    LOFF(maildir_retries) },
+  { "maildir_tag",       opt_stringptr,    LOFF(maildir_tag) },
+  { "maildir_use_size_file", opt_expand_bool, LOFF(maildir_use_size_file ) } ,
+  { "maildirfolder_create_regex", opt_stringptr, LOFF(maildirfolder_create_regex ) },
 #endif  /* SUPPORT_MAILDIR */
 #ifdef SUPPORT_MAILSTORE
-  { "mailstore_format",  opt_bool,
-      (void *)offsetof(appendfile_transport_options_block, mailstore_format ) },
-  { "mailstore_prefix",  opt_stringptr,
-      (void *)offsetof(appendfile_transport_options_block, mailstore_prefix ) },
-  { "mailstore_suffix",  opt_stringptr,
-      (void *)offsetof(appendfile_transport_options_block, mailstore_suffix ) },
+  { "mailstore_format",  opt_bool,    LOFF(mailstore_format ) },
+  { "mailstore_prefix",  opt_stringptr,    LOFF(mailstore_prefix ) },
+  { "mailstore_suffix",  opt_stringptr,    LOFF(mailstore_suffix ) },
 #endif  /* SUPPORT_MAILSTORE */
 #ifdef SUPPORT_MBX
-  { "mbx_format",        opt_bool,
-      (void *)offsetof(appendfile_transport_options_block, mbx_format ) } ,
+  { "mbx_format",        opt_bool,    LOFF(mbx_format ) } ,
 #endif  /* SUPPORT_MBX */
-  { "message_prefix",    opt_stringptr,
-      (void *)offsetof(appendfile_transport_options_block, message_prefix) },
-  { "message_suffix",    opt_stringptr,
-      (void *)offsetof(appendfile_transport_options_block, message_suffix) },
-  { "mode",              opt_octint,
-      (void *)offsetof(appendfile_transport_options_block, mode) },
-  { "mode_fail_narrower",opt_bool,
-      (void *)offsetof(appendfile_transport_options_block, mode_fail_narrower) },
-  { "notify_comsat",     opt_bool,
-      (void *)offsetof(appendfile_transport_options_block, notify_comsat) },
-  { "quota",             opt_stringptr,
-      (void *)offsetof(appendfile_transport_options_block, quota) },
-  { "quota_directory",   opt_stringptr,
-      (void *)offsetof(appendfile_transport_options_block, quota_directory) },
-  { "quota_filecount",   opt_stringptr,
-      (void *)offsetof(appendfile_transport_options_block, quota_filecount) },
-  { "quota_is_inclusive", opt_bool,
-      (void *)offsetof(appendfile_transport_options_block, quota_is_inclusive) },
-  { "quota_size_regex",   opt_stringptr,
-      (void *)offsetof(appendfile_transport_options_block, quota_size_regex) },
-  { "quota_warn_message", opt_stringptr | opt_public,
-      (void *)offsetof(transport_instance, warn_message) },
-  { "quota_warn_threshold", opt_stringptr,
-      (void *)offsetof(appendfile_transport_options_block, quota_warn_threshold) },
-  { "use_bsmtp",         opt_bool,
-      (void *)offsetof(appendfile_transport_options_block, use_bsmtp) },
-  { "use_crlf",          opt_bool,
-      (void *)offsetof(appendfile_transport_options_block, use_crlf) },
-  { "use_fcntl_lock",    opt_bool_set,
-      (void *)offsetof(appendfile_transport_options_block, use_fcntl) },
-  { "use_flock_lock",    opt_bool_set,
-      (void *)offsetof(appendfile_transport_options_block, use_flock) },
-  { "use_lockfile",      opt_bool_set,
-      (void *)offsetof(appendfile_transport_options_block, use_lockfile) },
+  { "message_prefix",    opt_stringptr,    LOFF(message_prefix) },
+  { "message_suffix",    opt_stringptr,    LOFF(message_suffix) },
+  { "mode",              opt_octint,    LOFF(mode) },
+  { "mode_fail_narrower",opt_bool,    LOFF(mode_fail_narrower) },
+  { "notify_comsat",     opt_bool,    LOFF(notify_comsat) },
+  { "quota",             opt_stringptr,    LOFF(quota) },
+  { "quota_directory",   opt_stringptr,    LOFF(quota_directory) },
+  { "quota_filecount",   opt_stringptr,    LOFF(quota_filecount) },
+  { "quota_is_inclusive", opt_bool,    LOFF(quota_is_inclusive) },
+  { "quota_size_regex",   opt_stringptr, LOFF(quota_size_regex) },
+  { "quota_warn_message", opt_stringptr | opt_public, OPT_OFF(transport_instance, warn_message) },
+  { "quota_warn_threshold", opt_stringptr, LOFF(quota_warn_threshold) },
+  { "use_bsmtp",         opt_bool,    LOFF(use_bsmtp) },
+  { "use_crlf",          opt_bool,    LOFF(use_crlf) },
+  { "use_fcntl_lock",    opt_bool_set,    LOFF(use_fcntl) },
+  { "use_flock_lock",    opt_bool_set,    LOFF(use_flock) },
+  { "use_lockfile",      opt_bool_set,    LOFF(use_lockfile) },
 #ifdef SUPPORT_MBX
-  { "use_mbx_lock",      opt_bool_set,
-      (void *)offsetof(appendfile_transport_options_block, use_mbx_lock) },
+  { "use_mbx_lock",      opt_bool_set,    LOFF(use_mbx_lock) },
 #endif  /* SUPPORT_MBX */
 };


diff --git a/src/src/transports/autoreply.c b/src/src/transports/autoreply.c
index 666591b..4b5ef8e 100644
--- a/src/src/transports/autoreply.c
+++ b/src/src/transports/autoreply.c
@@ -16,44 +16,27 @@ order (note that "_" comes before the lower case letters). Those starting
with "*" are not settable by the user but are used by the option-reading
software for alternative value types. Some options are publicly visible and so
are stored in the driver instance block. These are flagged with opt_public. */
+#define LOFF(field) OPT_OFF(autoreply_transport_options_block, field)

 optionlist autoreply_transport_options[] = {
-  { "bcc",               opt_stringptr,
-      (void *)offsetof(autoreply_transport_options_block, bcc) },
-  { "cc",                opt_stringptr,
-      (void *)offsetof(autoreply_transport_options_block, cc) },
-  { "file",              opt_stringptr,
-      (void *)offsetof(autoreply_transport_options_block, file) },
-  { "file_expand",     opt_bool,
-      (void *)offsetof(autoreply_transport_options_block, file_expand) },
-  { "file_optional",     opt_bool,
-      (void *)offsetof(autoreply_transport_options_block, file_optional) },
-  { "from",              opt_stringptr,
-      (void *)offsetof(autoreply_transport_options_block, from) },
-  { "headers",           opt_stringptr,
-      (void *)offsetof(autoreply_transport_options_block, headers) },
-  { "log",               opt_stringptr,
-      (void *)offsetof(autoreply_transport_options_block, logfile) },
-  { "mode",              opt_octint,
-      (void *)offsetof(autoreply_transport_options_block, mode) },
-  { "never_mail",        opt_stringptr,
-      (void *)offsetof(autoreply_transport_options_block, never_mail) },
-  { "once",              opt_stringptr,
-      (void *)offsetof(autoreply_transport_options_block, oncelog) },
-  { "once_file_size",    opt_int,
-      (void *)offsetof(autoreply_transport_options_block, once_file_size) },
-  { "once_repeat",       opt_stringptr,
-      (void *)offsetof(autoreply_transport_options_block, once_repeat) },
-  { "reply_to",          opt_stringptr,
-      (void *)offsetof(autoreply_transport_options_block, reply_to) },
-  { "return_message",    opt_bool,
-      (void *)offsetof(autoreply_transport_options_block, return_message) },
-  { "subject",           opt_stringptr,
-      (void *)offsetof(autoreply_transport_options_block, subject) },
-  { "text",              opt_stringptr,
-      (void *)offsetof(autoreply_transport_options_block, text) },
-  { "to",                opt_stringptr,
-      (void *)offsetof(autoreply_transport_options_block, to) },
+  { "bcc",               opt_stringptr,    LOFF(bcc) },
+  { "cc",                opt_stringptr,    LOFF(cc) },
+  { "file",              opt_stringptr,    LOFF(file) },
+  { "file_expand",     opt_bool,    LOFF(file_expand) },
+  { "file_optional",     opt_bool,    LOFF(file_optional) },
+  { "from",              opt_stringptr,    LOFF(from) },
+  { "headers",           opt_stringptr,    LOFF(headers) },
+  { "log",               opt_stringptr,    LOFF(logfile) },
+  { "mode",              opt_octint,    LOFF(mode) },
+  { "never_mail",        opt_stringptr,    LOFF(never_mail) },
+  { "once",              opt_stringptr,    LOFF(oncelog) },
+  { "once_file_size",    opt_int,    LOFF(once_file_size) },
+  { "once_repeat",       opt_stringptr,    LOFF(once_repeat) },
+  { "reply_to",          opt_stringptr,    LOFF(reply_to) },
+  { "return_message",    opt_bool,    LOFF(return_message) },
+  { "subject",           opt_stringptr,    LOFF(subject) },
+  { "text",              opt_stringptr,    LOFF(text) },
+  { "to",                opt_stringptr,    LOFF(to) },
 };


/* Size of the options list. An extern variable has to be used so that its
diff --git a/src/src/transports/lmtp.c b/src/src/transports/lmtp.c
index 306ec45..32c5716 100644
--- a/src/src/transports/lmtp.c
+++ b/src/src/transports/lmtp.c
@@ -21,17 +21,17 @@ instance block so as to be publicly visible; these are flagged with opt_public.

 optionlist lmtp_transport_options[] = {
   { "batch_id",          opt_stringptr | opt_public,
-      (void *)offsetof(transport_instance, batch_id) },
+      OPT_OFF(transport_instance, batch_id) },
   { "batch_max",         opt_int | opt_public,
-      (void *)offsetof(transport_instance, batch_max) },
+      OPT_OFF(transport_instance, batch_max) },
   { "command",           opt_stringptr,
-      (void *)offsetof(lmtp_transport_options_block, cmd) },
+      OPT_OFF(lmtp_transport_options_block, cmd) },
   { "ignore_quota",      opt_bool,
-      (void *)offsetof(lmtp_transport_options_block, ignore_quota) },
+      OPT_OFF(lmtp_transport_options_block, ignore_quota) },
   { "socket",            opt_stringptr,
-      (void *)offsetof(lmtp_transport_options_block, skt) },
+      OPT_OFF(lmtp_transport_options_block, skt) },
   { "timeout",           opt_time,
-      (void *)offsetof(lmtp_transport_options_block, timeout) }
+      OPT_OFF(lmtp_transport_options_block, timeout) }
 };


/* Size of the options list. An extern variable has to be used so that its
diff --git a/src/src/transports/pipe.c b/src/src/transports/pipe.c
index 4ca35aa..ca22f26 100644
--- a/src/src/transports/pipe.c
+++ b/src/src/transports/pipe.c
@@ -22,72 +22,50 @@ with "*" are not settable by the user but are used by the option-reading
software for alternative value types. Some options are stored in the transport
instance block so as to be publicly visible; these are flagged with opt_public.
*/
+#define LOFF(field) OPT_OFF(pipe_transport_options_block, field)

 optionlist pipe_transport_options[] = {
-  { "allow_commands",    opt_stringptr,
-      (void *)offsetof(pipe_transport_options_block, allow_commands) },
+  { "allow_commands",    opt_stringptr,    LOFF(allow_commands) },
   { "batch_id",          opt_stringptr | opt_public,
-      (void *)offsetof(transport_instance, batch_id) },
+      OPT_OFF(transport_instance, batch_id) },
   { "batch_max",         opt_int | opt_public,
-      (void *)offsetof(transport_instance, batch_max) },
-  { "check_string",      opt_stringptr,
-      (void *)offsetof(pipe_transport_options_block, check_string) },
-  { "command",           opt_stringptr,
-      (void *)offsetof(pipe_transport_options_block, cmd) },
-  { "environment",       opt_stringptr,
-      (void *)offsetof(pipe_transport_options_block, environment) },
-  { "escape_string",     opt_stringptr,
-      (void *)offsetof(pipe_transport_options_block, escape_string) },
-  { "force_command",         opt_bool,
-      (void *)offsetof(pipe_transport_options_block, force_command) },
-  { "freeze_exec_fail",  opt_bool,
-      (void *)offsetof(pipe_transport_options_block, freeze_exec_fail) },
-  { "freeze_signal",     opt_bool,
-      (void *)offsetof(pipe_transport_options_block, freeze_signal) },
-  { "ignore_status",     opt_bool,
-      (void *)offsetof(pipe_transport_options_block, ignore_status) },
+      OPT_OFF(transport_instance, batch_max) },
+  { "check_string",      opt_stringptr,    LOFF(check_string) },
+  { "command",           opt_stringptr,    LOFF(cmd) },
+  { "environment",       opt_stringptr,    LOFF(environment) },
+  { "escape_string",     opt_stringptr,    LOFF(escape_string) },
+  { "force_command",         opt_bool,    LOFF(force_command) },
+  { "freeze_exec_fail",  opt_bool,    LOFF(freeze_exec_fail) },
+  { "freeze_signal",     opt_bool,    LOFF(freeze_signal) },
+  { "ignore_status",     opt_bool,    LOFF(ignore_status) },
   { "log_defer_output",  opt_bool | opt_public,
-      (void *)offsetof(transport_instance, log_defer_output) },
+      OPT_OFF(transport_instance, log_defer_output) },
   { "log_fail_output",   opt_bool | opt_public,
-      (void *)offsetof(transport_instance, log_fail_output) },
+      OPT_OFF(transport_instance, log_fail_output) },
   { "log_output",        opt_bool | opt_public,
-      (void *)offsetof(transport_instance, log_output) },
-  { "max_output",        opt_mkint,
-      (void *)offsetof(pipe_transport_options_block, max_output) },
-  { "message_prefix",    opt_stringptr,
-      (void *)offsetof(pipe_transport_options_block, message_prefix) },
-  { "message_suffix",    opt_stringptr,
-      (void *)offsetof(pipe_transport_options_block, message_suffix) },
-  { "path",              opt_stringptr,
-      (void *)offsetof(pipe_transport_options_block, path) },
-  { "permit_coredump",   opt_bool,
-      (void *)offsetof(pipe_transport_options_block, permit_coredump) },
+      OPT_OFF(transport_instance, log_output) },
+  { "max_output",        opt_mkint,    LOFF(max_output) },
+  { "message_prefix",    opt_stringptr,    LOFF(message_prefix) },
+  { "message_suffix",    opt_stringptr,    LOFF(message_suffix) },
+  { "path",              opt_stringptr,    LOFF(path) },
+  { "permit_coredump",   opt_bool,    LOFF(permit_coredump) },
   { "pipe_as_creator",   opt_bool | opt_public,
-      (void *)offsetof(transport_instance, deliver_as_creator) },
-  { "restrict_to_path",  opt_bool,
-      (void *)offsetof(pipe_transport_options_block, restrict_to_path) },
+      OPT_OFF(transport_instance, deliver_as_creator) },
+  { "restrict_to_path",  opt_bool,    LOFF(restrict_to_path) },
   { "return_fail_output",opt_bool | opt_public,
-      (void *)offsetof(transport_instance, return_fail_output) },
+      OPT_OFF(transport_instance, return_fail_output) },
   { "return_output",     opt_bool | opt_public,
-      (void *)offsetof(transport_instance, return_output) },
-  { "temp_errors",       opt_stringptr,
-      (void *)offsetof(pipe_transport_options_block, temp_errors) },
-  { "timeout",           opt_time,
-      (void *)offsetof(pipe_transport_options_block, timeout) },
-  { "timeout_defer",     opt_bool,
-      (void *)offsetof(pipe_transport_options_block, timeout_defer) },
-  { "umask",             opt_octint,
-      (void *)offsetof(pipe_transport_options_block, umask) },
-  { "use_bsmtp",         opt_bool,
-      (void *)offsetof(pipe_transport_options_block, use_bsmtp) },
+      OPT_OFF(transport_instance, return_output) },
+  { "temp_errors",       opt_stringptr,    LOFF(temp_errors) },
+  { "timeout",           opt_time,    LOFF(timeout) },
+  { "timeout_defer",     opt_bool,    LOFF(timeout_defer) },
+  { "umask",             opt_octint,    LOFF(umask) },
+  { "use_bsmtp",         opt_bool,    LOFF(use_bsmtp) },
   #ifdef HAVE_SETCLASSRESOURCES
-  { "use_classresources", opt_bool,
-      (void *)offsetof(pipe_transport_options_block, use_classresources) },
+  { "use_classresources", opt_bool,    LOFF(use_classresources) },
   #endif
-  { "use_crlf",          opt_bool,
-      (void *)offsetof(pipe_transport_options_block, use_crlf) },
-  { "use_shell",         opt_bool,
-      (void *)offsetof(pipe_transport_options_block, use_shell) },
+  { "use_crlf",          opt_bool,    LOFF(use_crlf) },
+  { "use_shell",         opt_bool,    LOFF(use_shell) },
 };


/* Size of the options list. An extern variable has to be used so that its
diff --git a/src/src/transports/queuefile.c b/src/src/transports/queuefile.c
index 4339d1f..76b994d 100644
--- a/src/src/transports/queuefile.c
+++ b/src/src/transports/queuefile.c
@@ -18,7 +18,7 @@ opt_public flag. */

 optionlist queuefile_transport_options[] = {
   { "directory", opt_stringptr,
-    (void *)offsetof(queuefile_transport_options_block, dirname) },
+    OPT_OFF(queuefile_transport_options_block, dirname) },
 };



diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index d7147b2..58fe055 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -18,195 +18,126 @@ over TCP/IP. The options must be in alphabetic order (note that "_" comes
before the lower case letters). Some live in the transport_instance block so as
to be publicly visible; these are flagged with opt_public. */

+#define LOFF(field) OPT_OFF(smtp_transport_options_block, field)
+
 optionlist smtp_transport_options[] = {
   { "*expand_multi_domain",             opt_stringptr | opt_hidden | opt_public,
-      (void *)offsetof(transport_instance, expand_multi_domain) },
+      OPT_OFF(transport_instance, expand_multi_domain) },
   { "*expand_retry_include_ip_address", opt_stringptr | opt_hidden,
-       (void *)(offsetof(smtp_transport_options_block, expand_retry_include_ip_address)) },
+      LOFF(expand_retry_include_ip_address) },


   { "address_retry_include_sender", opt_bool,
-      (void *)offsetof(smtp_transport_options_block, address_retry_include_sender) },
-  { "allow_localhost",      opt_bool,
-      (void *)offsetof(smtp_transport_options_block, allow_localhost) },
+      LOFF(address_retry_include_sender) },
+  { "allow_localhost",      opt_bool,       LOFF(allow_localhost) },
 #ifdef EXPERIMENTAL_ARC
-  { "arc_sign", opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, arc_sign) },
-#endif
-  { "authenticated_sender", opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, authenticated_sender) },
-  { "authenticated_sender_force", opt_bool,
-      (void *)offsetof(smtp_transport_options_block, authenticated_sender_force) },
-  { "command_timeout",      opt_time,
-      (void *)offsetof(smtp_transport_options_block, command_timeout) },
-  { "connect_timeout",      opt_time,
-      (void *)offsetof(smtp_transport_options_block, connect_timeout) },
+  { "arc_sign", opt_stringptr,           LOFF(arc_sign) },
+#endif
+  { "authenticated_sender", opt_stringptr, LOFF(authenticated_sender) },
+  { "authenticated_sender_force", opt_bool, LOFF(authenticated_sender_force) },
+  { "command_timeout",      opt_time,       LOFF(command_timeout) },
+  { "connect_timeout",      opt_time,       LOFF(connect_timeout) },
   { "connection_max_messages", opt_int | opt_public,
-      (void *)offsetof(transport_instance, connection_max_messages) },
+      OPT_OFF(transport_instance, connection_max_messages) },
 # ifdef SUPPORT_DANE
-  { "dane_require_tls_ciphers", opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, dane_require_tls_ciphers) },
+  { "dane_require_tls_ciphers", opt_stringptr, LOFF(dane_require_tls_ciphers) },
 # endif
-  { "data_timeout",         opt_time,
-      (void *)offsetof(smtp_transport_options_block, data_timeout) },
-  { "delay_after_cutoff", opt_bool,
-      (void *)offsetof(smtp_transport_options_block, delay_after_cutoff) },
+  { "data_timeout",         opt_time,       LOFF(data_timeout) },
+  { "delay_after_cutoff", opt_bool,       LOFF(delay_after_cutoff) },
 #ifndef DISABLE_DKIM
-  { "dkim_canon", opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, dkim.dkim_canon) },
-  { "dkim_domain", opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, dkim.dkim_domain) },
-  { "dkim_hash", opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, dkim.dkim_hash) },
-  { "dkim_identity", opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, dkim.dkim_identity) },
-  { "dkim_private_key", opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, dkim.dkim_private_key) },
-  { "dkim_selector", opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, dkim.dkim_selector) },
-  { "dkim_sign_headers", opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, dkim.dkim_sign_headers) },
-  { "dkim_strict", opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, dkim.dkim_strict) },
-  { "dkim_timestamps", opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, dkim.dkim_timestamps) },
-#endif
-  { "dns_qualify_single",   opt_bool,
-      (void *)offsetof(smtp_transport_options_block, dns_qualify_single) },
-  { "dns_search_parents",   opt_bool,
-      (void *)offsetof(smtp_transport_options_block, dns_search_parents) },
-  { "dnssec_request_domains", opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, dnssec.request) },
-  { "dnssec_require_domains", opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, dnssec.require) },
-  { "dscp",                 opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, dscp) },
-  { "fallback_hosts",       opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, fallback_hosts) },
-  { "final_timeout",        opt_time,
-      (void *)offsetof(smtp_transport_options_block, final_timeout) },
-  { "gethostbyname",        opt_bool,
-      (void *)offsetof(smtp_transport_options_block, gethostbyname) },
-  { "helo_data",            opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, helo_data) },
-  { "hosts",                opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, hosts) },
-  { "hosts_avoid_esmtp",    opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, hosts_avoid_esmtp) },
-  { "hosts_avoid_pipelining", opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, hosts_avoid_pipelining) },
+  { "dkim_canon", opt_stringptr,       LOFF(dkim.dkim_canon) },
+  { "dkim_domain", opt_stringptr,       LOFF(dkim.dkim_domain) },
+  { "dkim_hash", opt_stringptr,           LOFF(dkim.dkim_hash) },
+  { "dkim_identity", opt_stringptr,       LOFF(dkim.dkim_identity) },
+  { "dkim_private_key", opt_stringptr,       LOFF(dkim.dkim_private_key) },
+  { "dkim_selector", opt_stringptr,       LOFF(dkim.dkim_selector) },
+  { "dkim_sign_headers", opt_stringptr,       LOFF(dkim.dkim_sign_headers) },
+  { "dkim_strict", opt_stringptr,       LOFF(dkim.dkim_strict) },
+  { "dkim_timestamps", opt_stringptr,       LOFF(dkim.dkim_timestamps) },
+#endif
+  { "dns_qualify_single",   opt_bool,       LOFF(dns_qualify_single) },
+  { "dns_search_parents",   opt_bool,       LOFF(dns_search_parents) },
+  { "dnssec_request_domains", opt_stringptr, LOFF(dnssec.request) },
+  { "dnssec_require_domains", opt_stringptr, LOFF(dnssec.require) },
+  { "dscp",                 opt_stringptr, LOFF(dscp) },
+  { "fallback_hosts",       opt_stringptr, LOFF(fallback_hosts) },
+  { "final_timeout",        opt_time,       LOFF(final_timeout) },
+  { "gethostbyname",        opt_bool,       LOFF(gethostbyname) },
+  { "helo_data",            opt_stringptr, LOFF(helo_data) },
+  { "hosts",                opt_stringptr, LOFF(hosts) },
+  { "hosts_avoid_esmtp",    opt_stringptr, LOFF(hosts_avoid_esmtp) },
+  { "hosts_avoid_pipelining", opt_stringptr, LOFF(hosts_avoid_pipelining) },
 #ifndef DISABLE_TLS
-  { "hosts_avoid_tls",      opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, hosts_avoid_tls) },
+  { "hosts_avoid_tls",      opt_stringptr, LOFF(hosts_avoid_tls) },
 #endif
-  { "hosts_max_try",        opt_int,
-      (void *)offsetof(smtp_transport_options_block, hosts_max_try) },
-  { "hosts_max_try_hardlimit", opt_int,
-      (void *)offsetof(smtp_transport_options_block, hosts_max_try_hardlimit) },
+  { "hosts_max_try",        opt_int,       LOFF(hosts_max_try) },
+  { "hosts_max_try_hardlimit", opt_int,       LOFF(hosts_max_try_hardlimit) },
 #ifndef DISABLE_TLS
-  { "hosts_nopass_tls",     opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, hosts_nopass_tls) },
-  { "hosts_noproxy_tls",    opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, hosts_noproxy_tls) },
+  { "hosts_nopass_tls",     opt_stringptr, LOFF(hosts_nopass_tls) },
+  { "hosts_noproxy_tls",    opt_stringptr, LOFF(hosts_noproxy_tls) },
 #endif
-  { "hosts_override",       opt_bool,
-      (void *)offsetof(smtp_transport_options_block, hosts_override) },
+  { "hosts_override",       opt_bool,       LOFF(hosts_override) },
 #ifndef DISABLE_PIPE_CONNECT
-  { "hosts_pipe_connect",   opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, hosts_pipe_connect) },
+  { "hosts_pipe_connect",   opt_stringptr, LOFF(hosts_pipe_connect) },
 #endif
-  { "hosts_randomize",      opt_bool,
-      (void *)offsetof(smtp_transport_options_block, hosts_randomize) },
+  { "hosts_randomize",      opt_bool,       LOFF(hosts_randomize) },
 #if !defined(DISABLE_TLS) && !defined(DISABLE_OCSP)
-  { "hosts_request_ocsp",   opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, hosts_request_ocsp) },
+  { "hosts_request_ocsp",   opt_stringptr, LOFF(hosts_request_ocsp) },
 #endif
-  { "hosts_require_auth",   opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, hosts_require_auth) },
+  { "hosts_require_auth",   opt_stringptr, LOFF(hosts_require_auth) },
 #ifndef DISABLE_TLS
 # ifdef SUPPORT_DANE
-  { "hosts_require_dane",   opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, hosts_require_dane) },
+  { "hosts_require_dane",   opt_stringptr, LOFF(hosts_require_dane) },
 # endif
 # ifndef DISABLE_OCSP
-  { "hosts_require_ocsp",   opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, hosts_require_ocsp) },
+  { "hosts_require_ocsp",   opt_stringptr, LOFF(hosts_require_ocsp) },
 # endif
-  { "hosts_require_tls",    opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, hosts_require_tls) },
+  { "hosts_require_tls",    opt_stringptr, LOFF(hosts_require_tls) },
 #endif
-  { "hosts_try_auth",       opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, hosts_try_auth) },
-  { "hosts_try_chunking",   opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, hosts_try_chunking) },
+  { "hosts_try_auth",       opt_stringptr, LOFF(hosts_try_auth) },
+  { "hosts_try_chunking",   opt_stringptr, LOFF(hosts_try_chunking) },
 #ifdef SUPPORT_DANE
-  { "hosts_try_dane",       opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, hosts_try_dane) },
+  { "hosts_try_dane",       opt_stringptr, LOFF(hosts_try_dane) },
 #endif
-  { "hosts_try_fastopen",   opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, hosts_try_fastopen) },
+  { "hosts_try_fastopen",   opt_stringptr, LOFF(hosts_try_fastopen) },
 #ifndef DISABLE_PRDR
-  { "hosts_try_prdr",       opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, hosts_try_prdr) },
+  { "hosts_try_prdr",       opt_stringptr, LOFF(hosts_try_prdr) },
 #endif
 #ifndef DISABLE_TLS
-  { "hosts_verify_avoid_tls", opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, hosts_verify_avoid_tls) },
-#endif
-  { "interface",            opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, interface) },
-  { "keepalive",            opt_bool,
-      (void *)offsetof(smtp_transport_options_block, keepalive) },
-  { "lmtp_ignore_quota",    opt_bool,
-      (void *)offsetof(smtp_transport_options_block, lmtp_ignore_quota) },
+  { "hosts_verify_avoid_tls", opt_stringptr, LOFF(hosts_verify_avoid_tls) },
+#endif
+  { "interface",            opt_stringptr, LOFF(interface) },
+  { "keepalive",            opt_bool,       LOFF(keepalive) },
+  { "lmtp_ignore_quota",    opt_bool,       LOFF(lmtp_ignore_quota) },
   { "max_rcpt",             opt_int | opt_public,
-      (void *)offsetof(transport_instance, max_addresses) },
+      OPT_OFF(transport_instance, max_addresses) },
   { "multi_domain",         opt_expand_bool | opt_public,
-      (void *)offsetof(transport_instance, multi_domain) },
-  { "port",                 opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, port) },
-  { "protocol",             opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, protocol) },
-  { "retry_include_ip_address", opt_expand_bool,
-      (void *)offsetof(smtp_transport_options_block, retry_include_ip_address) },
-  { "serialize_hosts",      opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, serialize_hosts) },
-  { "size_addition",        opt_int,
-      (void *)offsetof(smtp_transport_options_block, size_addition) },
+      OPT_OFF(transport_instance, multi_domain) },
+  { "port",                 opt_stringptr, LOFF(port) },
+  { "protocol",             opt_stringptr, LOFF(protocol) },
+  { "retry_include_ip_address", opt_expand_bool, LOFF(retry_include_ip_address) },
+  { "serialize_hosts",      opt_stringptr, LOFF(serialize_hosts) },
+  { "size_addition",        opt_int,       LOFF(size_addition) },
 #ifdef SUPPORT_SOCKS
-  { "socks_proxy",          opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, socks_proxy) },
+  { "socks_proxy",          opt_stringptr, LOFF(socks_proxy) },
 #endif
 #ifndef DISABLE_TLS
-  { "tls_certificate",      opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, tls_certificate) },
-  { "tls_crl",              opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, tls_crl) },
-  { "tls_dh_min_bits",      opt_int,
-      (void *)offsetof(smtp_transport_options_block, tls_dh_min_bits) },
-  { "tls_privatekey",       opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, tls_privatekey) },
-  { "tls_require_ciphers",  opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, tls_require_ciphers) },
+  { "tls_certificate",      opt_stringptr, LOFF(tls_certificate) },
+  { "tls_crl",              opt_stringptr, LOFF(tls_crl) },
+  { "tls_dh_min_bits",      opt_int,       LOFF(tls_dh_min_bits) },
+  { "tls_privatekey",       opt_stringptr, LOFF(tls_privatekey) },
+  { "tls_require_ciphers",  opt_stringptr, LOFF(tls_require_ciphers) },
 # ifdef EXPERIMENTAL_TLS_RESUME
-  { "tls_resumption_hosts", opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, tls_resumption_hosts) },
+  { "tls_resumption_hosts", opt_stringptr, LOFF(tls_resumption_hosts) },
 # endif
-  { "tls_sni",              opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, tls_sni) },
-  { "tls_tempfail_tryclear", opt_bool,
-      (void *)offsetof(smtp_transport_options_block, tls_tempfail_tryclear) },
-  { "tls_try_verify_hosts", opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, tls_try_verify_hosts) },
-  { "tls_verify_cert_hostnames", opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block,tls_verify_cert_hostnames)},
-  { "tls_verify_certificates", opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, tls_verify_certificates) },
-  { "tls_verify_hosts",     opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, tls_verify_hosts) },
+  { "tls_sni",              opt_stringptr, LOFF(tls_sni) },
+  { "tls_tempfail_tryclear", opt_bool, LOFF(tls_tempfail_tryclear) },
+  { "tls_try_verify_hosts", opt_stringptr, LOFF(tls_try_verify_hosts) },
+  { "tls_verify_cert_hostnames", opt_stringptr, LOFF(tls_verify_cert_hostnames)},
+  { "tls_verify_certificates", opt_stringptr, LOFF(tls_verify_certificates) },
+  { "tls_verify_hosts",     opt_stringptr, LOFF(tls_verify_hosts) },
 #endif
 #ifdef SUPPORT_I18N
-  { "utf8_downconvert",        opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, utf8_downconvert) },
+  { "utf8_downconvert",        opt_stringptr, LOFF(utf8_downconvert) },
 #endif
 };