From 7eb0e5d2b8453f753bd2d8e2e77cf4b7e0b24b1b Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sun, 20 Aug 2017 22:09:15 +0100 Subject: [PATCH] Use bitfields for flags in the "addr" struct --- doc/doc-txt/ChangeLog | 4 ++ src/src/deliver.c | 47 +++++++------ src/src/filter.c | 27 ++++---- src/src/globals.c | 2 +- src/src/macros.h | 16 ++--- src/src/rda.c | 20 +++--- src/src/route.c | 2 +- src/src/routers/iplookup.c | 1 - src/src/routers/queryprogram.c | 4 +- src/src/routers/redirect.c | 13 ++-- src/src/routers/rf_get_errors_address.c | 2 +- src/src/routers/rf_queue_add.c | 12 ++-- src/src/sieve.c | 25 +++---- src/src/structs.h | 87 ++++++++++++------------- src/src/transports/smtp.c | 4 +- 15 files changed, 134 insertions(+), 132 deletions(-) diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index a8a93d5ed..abc4e9312 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -144,6 +144,10 @@ JH/23 DKIM: enforce the DNS pubkey record "h" permitted-hashes optional field, JH/24 Start using specified-initialisers in C structure init coding. This is a C99 feature (it's 2017, so now considered safe). +JH/25 Use one-bit bitfields for flags in the "addr" data structure. Previously + if was a fixed-sized field and bitmask ops via macros; it is now more + extensible. + Exim version 4.89 ----------------- diff --git a/src/src/deliver.c b/src/src/deliver.c index b4f7ad54d..2d2850cf5 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -1195,11 +1195,11 @@ else } #ifndef DISABLE_PRDR - if (addr->flags & af_prdr_used) + if (testflag(addr, af_prdr_used)) s = string_catn(s, &size, &ptr, US" PRDR", 5); #endif - if (addr->flags & af_chunking_used) + if (testflag(addr, af_chunking_used)) s = string_catn(s, &size, &ptr, US" K", 2); } @@ -1657,7 +1657,7 @@ else later (with a log entry). */ if (!*sender_address && message_age >= ignore_bounce_errors_after) - setflag(addr, af_ignore_error); + addr->prop.ignore_error = TRUE; /* Freeze the message if requested, or if this is a bounce message (or other message with null sender) and this address does not have its own errors @@ -1665,7 +1665,7 @@ else to ignore occurs later, instead of sending a message. Logging of freezing occurs later, just before writing the -H file. */ - if ( !testflag(addr, af_ignore_error) + if ( !addr->prop.ignore_error && ( addr->special_action == SPECIAL_FREEZE || (sender_address[0] == 0 && !addr->prop.errors_address) ) ) @@ -2777,7 +2777,8 @@ while (addr_local) BOOL ok = tp == next->transport && !previously_transported(next, TRUE) - && (addr->flags & (af_pfr|af_file)) == (next->flags & (af_pfr|af_file)) + && testflag(addr, af_pfr) == testflag(next, af_pfr) + && testflag(addr, af_file) == testflag(next, af_file) && (!uses_lp || Ustrcmp(next->local_part, addr->local_part) == 0) && (!uses_dom || Ustrcmp(next->domain, addr->domain) == 0) && same_strings(next->prop.errors_address, addr->prop.errors_address) @@ -3551,12 +3552,12 @@ while (!done) #ifndef DISABLE_PRDR case 'P': - addr->flags |= af_prdr_used; + setflag(addr, af_prdr_used); break; #endif case 'K': - addr->flags |= af_chunking_used; + setflag(addr, af_chunking_used); break; case 'D': @@ -4848,11 +4849,11 @@ for (delivery_count = 0; addr_remote; delivery_count++) } #ifndef DISABLE_PRDR - if (addr->flags & af_prdr_used) + if (testflag(addr, af_prdr_used)) rmt_dlv_checked_write(fd, 'P', '0', NULL, 0); #endif - if (addr->flags & af_chunking_used) + if (testflag(addr, af_chunking_used)) rmt_dlv_checked_write(fd, 'K', '0', NULL, 0); memcpy(big_buffer, &addr->dsn_aware, sizeof(addr->dsn_aware)); @@ -6013,11 +6014,11 @@ else if (system_filter && process_recipients != RECIP_FAIL_TIMEOUT) uschar *type; p->uid = uid; p->gid = gid; - setflag(p, af_uid_set | - af_gid_set | - af_allow_file | - af_allow_pipe | - af_allow_reply); + setflag(p, af_uid_set); + setflag(p, af_gid_set); + setflag(p, af_allow_file); + setflag(p, af_allow_pipe); + setflag(p, af_allow_reply); /* Find the name of the system filter's appropriate pfr transport */ @@ -6336,8 +6337,8 @@ while (addr_new) /* Loop until all addresses dealt with */ addr->local_part = addr->address; addr->message = US"filter autoreply generated syntactically invalid recipient"; - setflag(addr, af_ignore_error); - (void)post_process_one(addr, FAIL, LOG_MAIN, DTYPE_ROUTER, 0); + addr->prop.ignore_error = TRUE; + (void) post_process_one(addr, FAIL, LOG_MAIN, DTYPE_ROUTER, 0); continue; /* with the next new address */ } @@ -6831,15 +6832,14 @@ while (addr_new) /* Loop until all addresses dealt with */ addr2->host_list = addr->host_list; addr2->fallback_hosts = addr->fallback_hosts; addr2->prop.errors_address = addr->prop.errors_address; - copyflag(addr2, addr, af_hide_child | af_local_host_removed); + copyflag(addr2, addr, af_hide_child); + copyflag(addr2, addr, af_local_host_removed); DEBUG(D_deliver|D_route) - { debug_printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n" "routing %s\n" "Routing for %s copied from %s\n", addr2->address, addr2->address, addr->address); - } } } } /* Continue with routing the next address. */ @@ -7404,19 +7404,18 @@ while (addr_failed) if (sender_address[0] == 0 && !addr_failed->prop.errors_address) { if ( !testflag(addr_failed, af_retry_timedout) - && !testflag(addr_failed, af_ignore_error)) - { + && !addr_failed->prop.ignore_error) log_write(0, LOG_MAIN|LOG_PANIC, "internal error: bounce message " "failure is neither frozen nor ignored (it's been ignored)"); - } - setflag(addr_failed, af_ignore_error); + + addr_failed->prop.ignore_error = TRUE; } /* If the first address on the list has af_ignore_error set, just remove it from the list, throw away any saved message file, log it, and mark the recipient done. */ - if ( testflag(addr_failed, af_ignore_error) + if ( addr_failed->prop.ignore_error || ( addr_failed->dsn_flags & rf_dsnflags && (addr_failed->dsn_flags & rf_notify_failure) != rf_notify_failure ) ) diff --git a/src/src/filter.c b/src/src/filter.c index 24753a607..86232c187 100644 --- a/src/src/filter.c +++ b/src/src/filter.c @@ -1815,7 +1815,7 @@ while (commands != NULL) addr = deliver_make_addr(expargs[0], TRUE); /* TRUE => copy s */ addr->prop.errors_address = (s == NULL)? s : string_copy(s); /* Default is NULL */ - if (commands->noerror) setflag(addr, af_ignore_error); + if (commands->noerror) addr->prop.ignore_error = TRUE; addr->next = *generated; *generated = addr; } @@ -1855,8 +1855,9 @@ while (commands != NULL) mode value. */ addr = deliver_make_addr(s, TRUE); /* TRUE => copy s */ - setflag(addr, af_pfr|af_file); - if (commands->noerror) setflag(addr, af_ignore_error); + setflag(addr, af_pfr); + setflag(addr, af_file); + if (commands->noerror) addr->prop.ignore_error = TRUE; addr->mode = mode; addr->next = *generated; *generated = addr; @@ -1884,8 +1885,9 @@ while (commands != NULL) has been split up into separate arguments. */ addr = deliver_make_addr(s, TRUE); /* TRUE => copy s */ - setflag(addr, af_pfr|af_expand_pipe); - if (commands->noerror) setflag(addr, af_ignore_error); + setflag(addr, af_pfr); + setflag(addr, af_expand_pipe); + if (commands->noerror) addr->prop.ignore_error = TRUE; addr->next = *generated; *generated = addr; @@ -2220,7 +2222,7 @@ while (commands != NULL) uschar *to = commands->args[mailarg_index_to].u; int size = 0; int ptr = 0; - int badflag = 0; + BOOL badflag; if (to == NULL) to = expand_string(US"$reply_address"); while (isspace(*to)) to++; @@ -2292,16 +2294,15 @@ while (commands != NULL) while (isspace(*tt)) tt++; } - if (log_addr == NULL) - { + if ((badflag = !log_addr)) log_addr = string_sprintf(">**bad-reply**"); - badflag = af_bad_reply; - } - else log_addr[ptr] = 0; + else + log_addr[ptr] = 0; addr = deliver_make_addr(log_addr, FALSE); - setflag(addr, (af_pfr|badflag)); - if (commands->noerror) setflag(addr, af_ignore_error); + setflag(addr, af_pfr); + if (badflag) setflag(addr, af_bad_reply); + if (commands->noerror) addr->prop.ignore_error = TRUE; addr->next = *generated; *generated = addr; addr->reply = store_get(sizeof(reply_item)); diff --git a/src/src/globals.c b/src/src/globals.c index b9cdb88d4..7f6ce6d40 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -378,7 +378,7 @@ address_item address_defaults = { .dsn_aware = 0, .uid = (uid_t)(-1), .gid = (gid_t)(-1), - .flags = 0, + .flags = { 0 }, .domain_cache = { 0 }, /* domain_cache - any larger array should be zeroed */ .localpart_cache = { 0 }, /* localpart_cache - ditto */ .mode = -1, diff --git a/src/src/macros.h b/src/src/macros.h index 937722494..eaa7f21ef 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -27,20 +27,16 @@ a string as a text string. This is sometimes useful for debugging output. */ (running_in_test_harness? (test_harness_load_avg += 10) : os_getloadavg()) -/* The address_item structure has a word full of 1-bit flags. These macros +/* The address_item structure has a struct full of 1-bit flags. These macros manipulate them. */ -#define setflag(addr,flag) addr->flags |= (flag) -#define clearflag(addr,flag) addr->flags &= ~(flag) +#define setflag(addr, flagname) addr->flags.flagname = TRUE +#define clearflag(addr, flagname) addr->flags.flagname = FALSE -#define testflag(addr,flag) ((addr->flags & (flag)) != 0) -#define testflagsall(addr,flag) ((addr->flags & (flag)) == (flag)) +#define testflag(addr, flagname) (addr->flags.flagname) -#define copyflag(addrnew,addrold,flag) \ - addrnew->flags = (addrnew->flags & ~(flag)) | (addrold->flags & (flag)) - -#define orflag(addrnew,addrold,flag) \ - addrnew->flags |= addrold->flags & (flag) +#define copyflag(addrnew, addrold, flagname) \ + addrnew->flags.flagname = addrold->flags.flagname /* For almost all calls to convert things to printing characters, we want to diff --git a/src/src/rda.c b/src/src/rda.c index 995909b09..fb3edac17 100644 --- a/src/src/rda.c +++ b/src/src/rda.c @@ -715,30 +715,28 @@ if ((pid = fork()) == 0) yield == FF_FAIL || yield == FF_FREEZE) { address_item *addr; - for (addr = *generated; addr != NULL; addr = addr->next) + for (addr = *generated; addr; addr = addr->next) { int reply_options = 0; if ( rda_write_string(fd, addr->address) != 0 - || write(fd, &(addr->mode), sizeof(addr->mode)) - != sizeof(addr->mode) - || write(fd, &(addr->flags), sizeof(addr->flags)) - != sizeof(addr->flags) + || write(fd, &addr->mode, sizeof(addr->mode)) != sizeof(addr->mode) + || write(fd, &addr->flags, sizeof(addr->flags)) != sizeof(addr->flags) || rda_write_string(fd, addr->prop.errors_address) != 0 ) goto bad; - if (addr->pipe_expandn != NULL) + if (addr->pipe_expandn) { uschar **pp; - for (pp = addr->pipe_expandn; *pp != NULL; pp++) + for (pp = addr->pipe_expandn; *pp; pp++) if (rda_write_string(fd, *pp) != 0) goto bad; } if (rda_write_string(fd, NULL) != 0) goto bad; - if (addr->reply == NULL) + if (!addr->reply) { if (write(fd, &reply_options, sizeof(int)) != sizeof(int)) /* 0 means no reply */ goto bad; @@ -889,9 +887,9 @@ if (yield == FF_DELIVERED || yield == FF_NOTDELIVERED || /* Next comes the mode and the flags fields */ - if (read(fd, &(addr->mode), sizeof(addr->mode)) != sizeof(addr->mode) || - read(fd, &(addr->flags), sizeof(addr->flags)) != sizeof(addr->flags) || - !rda_read_string(fd, &(addr->prop.errors_address))) goto DISASTER; + if (read(fd, &addr->mode, sizeof(addr->mode)) != sizeof(addr->mode) || + read(fd, &addr->flags, sizeof(addr->flags)) != sizeof(addr->flags) || + !rda_read_string(fd, &addr->prop.errors_address)) goto DISASTER; /* Next comes a possible setting for $thisaddress and any numerical variables for pipe expansion, terminated by a NULL string. The maximum diff --git a/src/src/route.c b/src/src/route.c index a175407c6..bbaa5285d 100644 --- a/src/src/route.c +++ b/src/src/route.c @@ -1365,7 +1365,7 @@ new->prop.errors_address = parent->prop.errors_address; /* Copy the propagated flags and address_data from the original. */ -copyflag(new, addr, af_propagate); +new->prop.ignore_error = addr->prop.ignore_error; new->prop.address_data = addr->prop.address_data; new->dsn_flags = addr->dsn_flags; new->dsn_orcpt = addr->dsn_orcpt; diff --git a/src/src/routers/iplookup.c b/src/src/routers/iplookup.c index fe0f961ae..1af2a77b9 100644 --- a/src/src/routers/iplookup.c +++ b/src/src/routers/iplookup.c @@ -393,7 +393,6 @@ the chain of new addressess. */ new_addr = deliver_make_addr(reroute, TRUE); new_addr->parent = addr; -copyflag(new_addr, addr, af_propagate); new_addr->prop = addr->prop; if (addr->child_count == USHRT_MAX) diff --git a/src/src/routers/queryprogram.c b/src/src/routers/queryprogram.c index 5dac6580a..fc92835c0 100644 --- a/src/src/routers/queryprogram.c +++ b/src/src/routers/queryprogram.c @@ -123,12 +123,14 @@ add_generated(router_instance *rblock, address_item **addr_new, { while (generated != NULL) { + BOOL ignore_error = addr->prop.ignore_error; address_item *next = generated; + generated = next->next; next->parent = addr; - orflag(next, addr, af_propagate); next->prop = *addr_prop; + next->prop.ignore_error |= ignore_error; next->start_router = rblock->redirect_router; next->next = *addr_new; diff --git a/src/src/routers/redirect.c b/src/src/routers/redirect.c index cb5dc6b58..005ec6f47 100644 --- a/src/src/routers/redirect.c +++ b/src/src/routers/redirect.c @@ -348,7 +348,6 @@ while (generated) generated = next->next; next->parent = addr; - orflag(next, addr, af_ignore_error); next->start_router = rblock->redirect_router; if (addr->child_count == USHRT_MAX) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s router generated more than %d " @@ -388,8 +387,12 @@ while (generated) If so, we must take care to re-instate it when we copy in the propagated data so that it overrides any errors_to setting on the router. */ - next->prop = *addr_prop; - if (errors_address != NULL) next->prop.errors_address = errors_address; + { + BOOL ignore_error = next->prop.ignore_error; + next->prop = *addr_prop; + next->prop.ignore_error |= ignore_error; + } + if (errors_address) next->prop.errors_address = errors_address; /* For pipes, files, and autoreplies, record this router as handling them, because they don't go through the routing process again. Then set up uid, @@ -912,10 +915,8 @@ else next->next = *addr_new; *addr_new = next; - /* Copy relevant flags (af_propagate is a name for the set), and set the - data that propagates. */ + /* Set the data that propagates. */ - copyflag(next, addr, af_propagate); next->prop = addr_prop; DEBUG(D_route) debug_printf("%s router autogenerated %s\n%s%s%s", diff --git a/src/src/routers/rf_get_errors_address.c b/src/src/routers/rf_get_errors_address.c index d7172d7ac..d81f0e907 100644 --- a/src/src/routers/rf_get_errors_address.c +++ b/src/src/routers/rf_get_errors_address.c @@ -60,7 +60,7 @@ if (s == NULL) if (*s == 0) { - setflag(addr, af_ignore_error); /* For locally detected errors */ + addr->prop.ignore_error = TRUE; /* For locally detected errors */ *errors_to = US""; /* Return path for SMTP */ return OK; } diff --git a/src/src/routers/rf_queue_add.c b/src/src/routers/rf_queue_add.c index 784a5477f..1eb109c89 100644 --- a/src/src/routers/rf_queue_add.c +++ b/src/src/routers/rf_queue_add.c @@ -41,7 +41,7 @@ addr->prop.localpart_data = deliver_localpart_data; /* use in the transport */ /* Handle a local transport */ -if (addr->transport != NULL && addr->transport->info->local) +if (addr->transport && addr->transport->info->local) { ugid_block ugid; @@ -50,11 +50,13 @@ if (addr->transport != NULL && addr->transport->info->local) When getting the home directory out of the password information, set the flag that prevents expansion later. */ - if (pw != NULL) + if (pw) { addr->uid = pw->pw_uid; addr->gid = pw->pw_gid; - setflag(addr, af_uid_set|af_gid_set|af_home_expanded); + setflag(addr, af_uid_set); + setflag(addr, af_gid_set); + setflag(addr, af_home_expanded); addr->home_dir = string_copy(US pw->pw_dir); } @@ -65,12 +67,12 @@ if (addr->transport != NULL && addr->transport->info->local) otherwise use the expanded value of router_home_directory. The flag also tells the transport not to re-expand it. */ - if (rblock->home_directory != NULL) + if (rblock->home_directory) { addr->home_dir = rblock->home_directory; clearflag(addr, af_home_expanded); } - else if (addr->home_dir == NULL && testflag(addr, af_home_expanded)) + else if (!addr->home_dir && testflag(addr, af_home_expanded)) addr->home_dir = deliver_home; addr->current_dir = rblock->current_directory; diff --git a/src/src/sieve.c b/src/src/sieve.c index 033cbce52..635d57827 100644 --- a/src/src/sieve.c +++ b/src/src/sieve.c @@ -1046,30 +1046,33 @@ Arguments: Returns: nothing */ -static void add_addr(address_item **generated, uschar *addr, int file, int maxage, int maxmessages, int maxstorage) +static void +add_addr(address_item **generated, uschar *addr, int file, int maxage, int maxmessages, int maxstorage) { address_item *new_addr; for (new_addr=*generated; new_addr; new_addr=new_addr->next) - { - if (Ustrcmp(new_addr->address,addr)==0 && (file ? testflag(new_addr, af_pfr|af_file) : 1)) + if ( Ustrcmp(new_addr->address,addr) == 0 + && ( !file + || testflag(new_addr, af_pfr) + || testflag(new_addr, af_file) + ) + ) { if ((filter_test != FTEST_NONE && debug_selector != 0) || (debug_selector & D_filter) != 0) - { debug_printf("Repeated %s `%s' ignored.\n",file ? "fileinto" : "redirect", addr); - } + return; } - } if ((filter_test != FTEST_NONE && debug_selector != 0) || (debug_selector & D_filter) != 0) - { debug_printf("%s `%s'\n",file ? "fileinto" : "redirect", addr); - } -new_addr=deliver_make_addr(addr,TRUE); + +new_addr = deliver_make_addr(addr,TRUE); if (file) { - setflag(new_addr, af_pfr|af_file); + setflag(new_addr, af_pfr); + setflag(new_addr, af_file); new_addr->mode = 0; } new_addr->prop.errors_address = NULL; @@ -3346,7 +3349,7 @@ while (*filter->pc) addr = deliver_make_addr(string_sprintf(">%.256s", sender_address), FALSE); setflag(addr, af_pfr); - setflag(addr, af_ignore_error); + addr->prop.ignore_error = TRUE; addr->next = *generated; *generated = addr; addr->reply = store_get(sizeof(reply_item)); diff --git a/src/src/structs.h b/src/src/structs.h index 3de8f3d41..a17b50332 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -505,6 +505,7 @@ typedef struct address_item_propagated { #ifdef EXPERIMENTAL_SRS uschar *srs_sender; /* Change return path when delivering */ #endif + BOOL ignore_error:1; /* ignore delivery error */ #ifdef SUPPORT_I18N BOOL utf8_msg:1; /* requires SMTPUTF8 processing */ BOOL utf8_downcvt:1; /* mandatory downconvert on delivery */ @@ -512,50 +513,6 @@ typedef struct address_item_propagated { #endif } address_item_propagated; -/* Bits for the flags field below */ - -#define af_allow_file 0x00000001 /* allow file in generated address */ -#define af_allow_pipe 0x00000002 /* allow pipe in generated address */ -#define af_allow_reply 0x00000004 /* allow autoreply in generated address */ -#define af_dr_retry_exists 0x00000008 /* router retry record exists */ -#define af_expand_pipe 0x00000010 /* expand pipe arguments */ -#define af_file 0x00000020 /* file delivery; always with pfr */ -#define af_gid_set 0x00000040 /* gid field is set */ -#define af_home_expanded 0x00000080 /* home_dir is already expanded */ -#define af_ignore_error 0x00000100 /* ignore delivery error */ -#define af_initgroups 0x00000200 /* use initgroups() for local transporting */ -#define af_local_host_removed 0x00000400 /* local host was backup */ -#define af_lt_retry_exists 0x00000800 /* local transport retry exists */ -#define af_pfr 0x00001000 /* pipe or file or reply delivery */ -#define af_retry_skipped 0x00002000 /* true if retry caused some skipping */ -#define af_retry_timedout 0x00004000 /* true if retry timed out */ -#define af_uid_set 0x00008000 /* uid field is set */ -#define af_hide_child 0x00010000 /* hide child in bounce/defer msgs */ -#define af_sverify_told 0x00020000 /* sender verify failure notified */ -#define af_verify_pmfail 0x00040000 /* verify failure was postmaster callout */ -#define af_verify_nsfail 0x00080000 /* verify failure was null sender callout */ -#define af_homonym 0x00100000 /* an ancestor has same address */ -#define af_verify_routed 0x00200000 /* for cached sender verify: routed OK */ -#define af_verify_callout 0x00400000 /* for cached sender verify: callout was specified */ -#define af_include_affixes 0x00800000 /* delivered with affixes in RCPT */ -#define af_cert_verified 0x01000000 /* delivered with verified TLS cert */ -#define af_pass_message 0x02000000 /* pass message in bounces */ -#define af_bad_reply 0x04000000 /* filter could not generate autoreply */ -#ifndef DISABLE_PRDR -# define af_prdr_used 0x08000000 /* delivery used SMTP PRDR */ -#endif -#define af_chunking_used 0x10000000 /* delivery used SMTP CHUNKING */ -#define af_force_command 0x20000000 /* force_command in pipe transport */ -#ifdef EXPERIMENTAL_DANE -# define af_dane_verified 0x40000000 /* TLS cert verify done with DANE */ -#endif -#ifdef SUPPORT_I18N -# define af_utf8_downcvt 0x80000000 /* downconvert was done for delivery */ -#endif - -/* These flags must be propagated when a child is created */ - -#define af_propagate (af_ignore_error) /* The main address structure. Note that fields that are to be copied to generated addresses should be put in the address_item_propagated structure (see @@ -625,7 +582,47 @@ typedef struct address_item { uid_t uid; /* uid for transporting */ gid_t gid; /* gid for transporting */ - unsigned int flags; /* a row of bits, defined above */ + /* flags */ + struct { + BOOL af_allow_file:1; /* allow file in generated address */ + BOOL af_allow_pipe:1; /* allow pipe in generated address */ + BOOL af_allow_reply:1; /* allow autoreply in generated address */ + BOOL af_dr_retry_exists:1; /* router retry record exists */ + BOOL af_expand_pipe:1; /* expand pipe arguments */ + BOOL af_file:1; /* file delivery; always with pfr */ + BOOL af_gid_set:1; /* gid field is set */ + BOOL af_home_expanded:1; /* home_dir is already expanded */ + BOOL af_initgroups:1; /* use initgroups() for local transporting */ + BOOL af_local_host_removed:1; /* local host was backup */ + BOOL af_lt_retry_exists:1; /* local transport retry exists */ + BOOL af_pfr:1; /* pipe or file or reply delivery */ + BOOL af_retry_skipped:1; /* true if retry caused some skipping */ + BOOL af_retry_timedout:1; /* true if retry timed out */ + BOOL af_uid_set:1; /* uid field is set */ + BOOL af_hide_child:1; /* hide child in bounce/defer msgs */ + BOOL af_sverify_told:1; /* sender verify failure notified */ + BOOL af_verify_pmfail:1; /* verify failure was postmaster callout */ + BOOL af_verify_nsfail:1; /* verify failure was null sender callout */ + BOOL af_homonym:1; /* an ancestor has same address */ + BOOL af_verify_routed:1; /* for cached sender verify: routed OK */ + BOOL af_verify_callout:1; /* for cached sender verify: callout was specified */ + BOOL af_include_affixes:1; /* delivered with affixes in RCPT */ + BOOL af_cert_verified:1; /* delivered with verified TLS cert */ + BOOL af_pass_message:1; /* pass message in bounces */ + BOOL af_bad_reply:1; /* filter could not generate autoreply */ +#ifndef DISABLE_PRDR + BOOL af_prdr_used:1; /* delivery used SMTP PRDR */ +#endif + BOOL af_chunking_used:1; /* delivery used SMTP CHUNKING */ + BOOL af_force_command:1; /* force_command in pipe transport */ +#ifdef EXPERIMENTAL_DANE + BOOL af_dane_verified:1; /* TLS cert verify done with DANE */ +#endif +#ifdef SUPPORT_I18N + BOOL af_utf8_downcvt:1; /* downconvert was done for delivery */ +#endif + } flags; + unsigned int domain_cache[(MAX_NAMED_LIST * 2)/32]; unsigned int localpart_cache[(MAX_NAMED_LIST * 2)/32]; int mode; /* mode for local transporting to a file */ diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index 965ef79e4..3ed31d924 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -3121,9 +3121,9 @@ else addr->special_action = flag; addr->message = conf; #ifndef DISABLE_PRDR - if (sx.prdr_active) addr->flags |= af_prdr_used; + if (sx.prdr_active) setflag(addr, af_prdr_used); #endif - if (sx.peer_offered & OPTION_CHUNKING) addr->flags |= af_chunking_used; + if (sx.peer_offered & OPTION_CHUNKING) setflag(addr, af_chunking_used); flag = '-'; #ifndef DISABLE_PRDR -- 2.30.2